FUNCTION POINTER This is what I came up with when building a simple states machine:This is a very simple example of using function pointers under Borland Delphi to control program flow. Just create a simple form with one button and add the code from Unit1 to the unit created. Add Unit2 to the project and compile. Give me a yell if you have any problems.interfaceuses 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;implementationuses Unit2;{$R *.DFM}procedure TForm1.Button1Click(Sender: TObject); var NewProc : LongInt; MyString : string; begin CurrProc := 2; { beginning point in proc table } MyVal := 0; { dummy variable } NewProc := 0; { return value for next index in proc table } while CurrProc < 6 do begin { execute the current index in the proc table and get the next proc } NewProc := ProcTable[CurrProc](MyVal); { this is just to track the values of NewProc and CurrProc } FmtStr(MyString, 'NewProc [%d] CurrProc [%d]', [NewProc, CurrProc]); MessageDlg(MyString, mtInformation, [mbOK], 0); { set the current proc to the returned proc } CurrProc := NewProc; end;end;end.{ This is a simple example of defining an array of function pointers }interfacetype { define Procs as a function } Procs = function(var ProcNum : LongInt): LongInt;var { declare the array of function pointers } ProcTable : Array [1..5] of Procs;{ function interface definitions } 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; implementationuses Dialogs;function Proc1(var MyVal : LongInt) : LongInt; begin MessageDlg('Proc 1', mtInformation, [mbOK], 0); Proc1 := 6; end;function Proc2(var MyVal : LongInt) : LongInt; begin MessageDlg('Proc 2', mtInformation, [mbOK], 0); Proc2 := 3; end;function Proc3(var MyVal : LongInt) : LongInt; begin MessageDlg('Proc 3', mtInformation, [mbOK], 0); Proc3 := 4; end;function Proc4(var MyVal : LongInt) : LongInt; begin MessageDlg('Proc 4', mtInformation, [mbOK], 0); Proc4 := 5; end;function Proc5(var MyVal : LongInt) : LongInt; begin MessageDlg('Proc 5', mtInformation, [mbOK], 0); Proc5 := 1; end;initialization { initialize the contents of the array of function pointers } @ProcTable[1] := @Proc1; @ProcTable[2] := @Proc2; @ProcTable[3] := @Proc3; @ProcTable[4] := @Proc4; @ProcTable[5] := @Proc5;end.I think I would do something like this: Declare in each form procedures that handle the buttonpresses, like procedure CutButtonPressed(Sender:TObject) of Object; Then I would simply assign the buttons' OnClick events to these procedures in the forms OnActivate event. This would be the oop way to do it, but if you don't like it, I think Delphi still has function pointers.Define a base class form with an abstract function declaration for each of the functions you want to call from your toolbar. Then derive each of your forms from that base class form, and provide definitions for those functions.Eg: (There might be a couple of syntax errors here - I haven't compiled it) 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;{To call the function from your toolbar, get the currently active form and call Method1} procedure OnButtonClick; var AForm: TBaseForm; begin AForm := ActiveForm as TBaseForm; AForm.Method1; end
BOOL EnumWindows( WNDENUMPROC lpEnumFunc, // pointer to callback function
LPARAM lParam // application-defined value
);
**为红星而努力**
***************函数指针:在动态调用DLL中的函数时,就会用到函数指针。假设用C写的一段
代码如下:
typedef int (*PVFN)(int); //定义函数指针类型
int main()
{
HMODULE hModule = LoadLibrary("test.dll");
PVFN pvfn = NULL;
pvfn = (PVFN) GetProcAddress(hModule, "Function1");
pvfn(2);
FreeLibrary(hModule);
}
就我个人感觉来说,C语言中定义函数指针类型的typedef代码的语法有些晦涩,
而同样的代码在 Object Pascal中却非常易懂:
type PVFN = Function (para : Integer) : Integer;
var fn : PVFN;
//也可以直接在此处定义,如:fn : function (para:Integer):Integer;
hm : HMODULE;
begin
hm := LoadLibrary('test.dll');
fn := GetProcAddress(hm, 'Function1');
fn(2);
FreeLibrary(hm);
end;
This is what I came up with when building a simple states machine:This is a very simple example of using function pointers under Borland Delphi to control program flow. Just create a simple form with one button and add the code from Unit1 to the unit created. Add Unit2
to the project and compile. Give me a yell if you have any problems.interfaceuses
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;implementationuses Unit2;{$R *.DFM}procedure TForm1.Button1Click(Sender: TObject);
var
NewProc : LongInt;
MyString : string;
begin
CurrProc := 2; { beginning point in proc table }
MyVal := 0; { dummy variable }
NewProc := 0; { return value for next index in proc
table }
while CurrProc < 6 do
begin
{ execute the current index in the proc table and get the next proc
}
NewProc := ProcTable[CurrProc](MyVal); { this is just to track the values of NewProc and CurrProc }
FmtStr(MyString, 'NewProc [%d] CurrProc [%d]', [NewProc,
CurrProc]);
MessageDlg(MyString, mtInformation, [mbOK], 0); { set the current proc to the returned proc }
CurrProc := NewProc;
end;end;end.{ This is a simple example of defining an array of function pointers }interfacetype
{ define Procs as a function }
Procs = function(var ProcNum : LongInt): LongInt;var
{ declare the array of function pointers }
ProcTable : Array [1..5] of Procs;{ function interface definitions }
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;
implementationuses Dialogs;function Proc1(var MyVal : LongInt) : LongInt;
begin
MessageDlg('Proc 1', mtInformation, [mbOK], 0);
Proc1 := 6;
end;function Proc2(var MyVal : LongInt) : LongInt;
begin
MessageDlg('Proc 2', mtInformation, [mbOK], 0);
Proc2 := 3;
end;function Proc3(var MyVal : LongInt) : LongInt;
begin
MessageDlg('Proc 3', mtInformation, [mbOK], 0);
Proc3 := 4;
end;function Proc4(var MyVal : LongInt) : LongInt;
begin
MessageDlg('Proc 4', mtInformation, [mbOK], 0);
Proc4 := 5;
end;function Proc5(var MyVal : LongInt) : LongInt;
begin
MessageDlg('Proc 5', mtInformation, [mbOK], 0);
Proc5 := 1;
end;initialization { initialize the contents of the array of function pointers }
@ProcTable[1] := @Proc1;
@ProcTable[2] := @Proc2;
@ProcTable[3] := @Proc3;
@ProcTable[4] := @Proc4;
@ProcTable[5] := @Proc5;end.I think I would do something like this: Declare in each form procedures that handle the buttonpresses, like procedure CutButtonPressed(Sender:TObject) of Object; Then I would simply assign the buttons' OnClick events to these procedures in the forms OnActivate event. This would be the oop way to do it, but if you don't like it, I think Delphi still has function pointers.Define a base class form with an abstract function declaration for each of the functions you want to call from your toolbar. Then derive each of your forms from that base class form, and provide definitions for those functions.Eg: (There might be a couple of syntax errors here - I haven't compiled it)
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;{To call the function from your toolbar, get
the currently active form and call Method1}
procedure OnButtonClick;
var
AForm: TBaseForm;
begin
AForm := ActiveForm as TBaseForm;
AForm.Method1;
end