Указатель на функцию |
Previous Top Next |
Это то, что я нашел при создании простой машины состояний:
Ниже приведен простой пример для Borland Delphi, использующий указатели функций для управления программным потоком. Просто создайте простую форму с единственной кнопкой и скопируйте код из Unit1 во вновь созданный модуль. Добавьте к проекту Unit2 и скомпилируйте проект. Дайте мне знать, если у вас возникнут какие-либо проблемы.
Code: |
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;
var
Form1: TForm1; CurrProc: LongInt; MyVal: LongInt;
implementation
uses Unit2;
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject); var
NewProc: LongInt; MyString: string; begin
CurrProc := 2; { начальная точка в таблице методов } MyVal := 0; { вспомогательная переменная } NewProc := 0; { возвращаемое значение для следующего индекса в таблице методов } while CurrProc < 6 do begin { выполняем текущий индекс в таблице методов и получаем следующую процедуру } NewProc := ProcTable[CurrProc](MyVal);
{ просто показываем значения NewProc и CurrProc } FmtStr(MyString, 'NewProc [%d] CurrProc [%d]', [NewProc, CurrProc]); MessageDlg(MyString, mtInformation, [mbOK], 0);
{ присваиваем текущую процедуру возвращаемой процедуре } CurrProc := NewProc; end;
end;
end. |
Code: |
{ Это простой пример, определяющий массив указателей на функции }
interface
type
{ определяем Procs как функцию } Procs = function(var ProcNum: LongInt): LongInt;
var
{ объявляем массив указателей на функции } ProcTable: array[1..5] of Procs;
{ определения интерфейсов функций } function Proc1(var MyVal: LongInt): LongInt; far; function Proc2(var MyVal: LongInt): LongInt; far; function Proc3(var MyVal: LongInt): LongInt; far; function Proc4(var MyVal: LongInt): LongInt; far; function Proc5(var MyVal: LongInt): LongInt; far;
implementation
uses Dialogs;
function Proc1(var MyVal: LongInt): LongInt; begin
MessageDlg('Процедура 1', mtInformation, [mbOK], 0); Proc1 := 6; end;
function Proc2(var MyVal: LongInt): LongInt; begin
MessageDlg('Процедура 2', mtInformation, [mbOK], 0); Proc2 := 3; end;
function Proc3(var MyVal: LongInt): LongInt; begin
MessageDlg('Процедура 3', mtInformation, [mbOK], 0); Proc3 := 4; end;
function Proc4(var MyVal: LongInt): LongInt; begin
MessageDlg('Процедура 4', mtInformation, [mbOK], 0); Proc4 := 5; end;
function Proc5(var MyVal: LongInt): LongInt; begin
MessageDlg('Процедура 5', mtInformation, [mbOK], 0); Proc5 := 1; end;
initialization
{ инициализируем содержание массива указателей на функции } @ProcTable[1] := @Proc1; @ProcTable[2] := @Proc2; @ProcTable[3] := @Proc3; @ProcTable[4] := @Proc4; @ProcTable[5] := @Proc5;
end. |
Я думаю это можно сделать приблизительно так: объявите в каждой форме процедуры, обрабатывающие нажатие кнопки, типа процедуры CutButtonPressed(Sender:TObject) of Object; затем просто назначьте события кнопок OnClick этим процедурам при наступлении событий форм OnActivate. Этот способ соответствует концепции ОО-программирования, но если вам не нравится это, то вы все еще можете воспользоваться указателями функций, которая предоставляет Delphi.
Объявите базовый класс формы с объявлениями абстрактных функций для каждой функции, которую вы хотите вызывать из вашего toolbar. Затем наследуйте каждую вашу форму от базового класса формы и создайте определения этих функций.
Пример: (Здесь может встретиться пара синтаксических ошибок - я не компилил это)
Code: |
type TBaseForm = class(TForm) public procedure Method1; virtual; abstract; end;
type TDerivedForm1 = class(TBaseForm) public procedure Method1; override; end;
TDerivedForm2 = class(TBaseForm) public procedure Method1; override; end;
procedure TDerivedForm1.Method1; begin .... end;
procedure TDerivedForm2.Method1; begin .... end;
{Для вызова функции из вашего toolbar, получите активную в настоящий момент форму и вызовите Method1}
procedure OnButtonClick; var AForm: TBaseForm; begin AForm := ActiveForm as TBaseForm; AForm.Method1; end;
|
©Drkb::00835
DelphiWorld 6.0