数据类型的转换(100分)

  • 主题发起人 主题发起人 hhi179
  • 开始时间 开始时间
H

hhi179

Unregistered / Unconfirmed
GUEST, unregistred user!
如何把字符型 转换成 TNotifyEvent
如:
var
mchar:string;
mclick:TNotifyEvent;
begin
mchar:='TForm2.OKBtnClick'
///转换
mclick:=转换后为数据;//意义跟:mclick:=TForm2.OKBtnClick;一样
end;
 
以前用Tmethod传事件的写法,看有没有帮助,(未测试),
A: TMethod

a.Data := self; //
a.Code := MethodAddress('OKBtnClick');

mclick = TNotifyEvent(a);
 
string 转换成 TNotifyEvent 肯定要失败!!!

TNotifyEvent类型是事件方法指针类型,它内部包含2个指针:过程的内存地址指针和所属对象指针(也就指示该方法属于哪个对象);而string类型是简单类型,所以它怎么能转换成功呢?

一般TNotifyEvent类型是事件方法指针的使用都是动态的在程序将一个过程赋给它,比如一个菜单项的过程等等都是可以的.
 
我明白楼主你的意思了,你需要的是从一个已经设定的列表中,根据操作的名称(字符串)来找到应该由哪个类的成员方法进行处理,当然这个类必须是已经实例化的,否则你将得到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.
 
var
mstr:string;
FOnClick: TNotifyEvent;
mAdd:TMethod;
begin
try
screen.Cursor := crHourGlass;
mstr :='OKBtnClick';
mAdd.Data := self;
mAdd.Code := From1.MethodAddress(mstr);
FOnClick := TNotifyEvent(mAdd);
FOnClick(self);
finally
screen.Cursor := crDefault;
end;
 
多人接受答案了。
 
后退
顶部