我明白楼主你的意思了,你需要的是从一个已经设定的列表中,根据操作的名称(字符串)来找到应该由哪个类的成员方法进行处理,当然这个类必须是已经实例化的,否则你将得到AV错误。
这个很好做,你可以用任意一种容器来包装这个事件函数表,在C++里我们可以用stl的map或hash_map,在Delphi里也可以自己建立一个哈希表(比如说照着TIniFile.pas里的那个TStringHash类改一个)或其它的容器,这里我省点事,用一个TList做容器,然后用顺序搜索法进行搜索(强烈建议你采用可以高效检索的数据结构来实现这个容器):
在例程中放一个输入框名为Edit1,再放一个按钮名为btnDoAction即可,此时你在Edit1中输入Login,点btnDoAction按钮,OnLogin方法就会被调用;输入Logout并点btnDoAction按钮,OnLogout方法就会被调用。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, Forms,
Dialogs, StdCtrls;
type
TEventProc = procedure of object;
TEventPair = record //用于保存函数对照关系的对象
FuncName: string;
FuncPointer: TEventProc; //指向函数的指针
end;
PEventPair = ^TEventPair;
TForm1 = class(TForm)
Edit1: TEdit;
btnDoAction: TButton;
procedure FormCreate(Sender: TObject);
procedure btnDoActionClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
FFuncTable: TList; //用于保存函数对照表,如果需要高效检索,可采用散列表
procedure OnLogin;
procedure OnLogout;
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var pItem: PEventPair;
begin
FFuncTable := TList.Create;
//建立函数对应关系
New(pItem);
pItem.FuncName := 'Login';
pItem.FuncPointer := OnLogin;
FFuncTable.Add(pItem);
New(pItem);
pItem.FuncName := 'LogOut';
pItem.FuncPointer := OnLogout;
FFuncTable.Add(pItem);
end;
procedure TForm1.OnLogin;
begin
ShowMessage('登录成功!');
end;
procedure TForm1.OnLogout;
begin
ShowMessage('退出登录!');
end;
procedure TForm1.btnDoActionClick(Sender: TObject);
var
Index: Integer;
pItem: PEventPair;
begin
//从函数对照表中检索对应关系,这里采用的是顺序摸索,要高效检索可改用散列表
for Index := 0 to FFuncTable.Count-1 do
begin
pItem := FFuncTable.Items[Index];
if CompareText(pItem.FuncName, Edit1.Text)=0 then
begin
pItem.FuncPointer;
Break;
end;
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
i: Integer;
pItem: PEventPair;
begin
for i:=0 to FFuncTable.Count-1 do
begin
pItem := FFuncTable.Items;
Dispose(pItem);
end;
end;
end.