procedure ReSetObjEvent(OldEventAddr: pointer;NewEventValue: pointer;ReSetObject: TObject);
begin
TMethod(OldEventAddr^).Code := NewEventValue;
TMethod(OldEventAddr^).Data := ReSetObject;
end;
通过上面的一个函数可以给事件绑定相应的处理函数,比如按钮的OnClick事件
procedure MyClick(Sender: TObject);我可以替换成为procedure MyClick(Sender: TObject;s:string);
begin
showmessage((Sender as Tbutton).Caption+'____'+ s);
end;问题是:我怎么才能把MyClick的s传进去,应该涉及到消息处理什么的。。
showmessage((Sender as Tbutton).Caption+'____'+ (Sender as Tbutton).Hint);
procedure MyClick(Sender: TObject;s:string);
begin
showmessage((Sender as Tbutton).Caption+'____'+ s);
end;procedure MyClickWrapper(O, Sender: TObject);
begin
MyClick(Sender, 'abcd');
end;procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage('');
end;procedure TForm1.FormCreate(Sender: TObject);
begin
asm//将MyClickWrapper赋给Button1.OnClick
mov edx,[eax+Button1]
mov [edx+$110], offset MyClickWrapper
mov [edx+$114], eax
end;end;
首先,那段汇编没有调用MyClickWrapper成功。最重要的是,我的目的是让事件对应的过程多一个参数,跟你的想法完全不一样。
想达到你这段代码的效果很简单:
var
Event: TNotifyEvent;
begin
integer(@Event) := integer(@MyClickWrapper);
btn1.OnClick := Event;
end;
其次,你的那段模拟的代码是有问题的,不信你可以在MyClickWrapper中调用ShowMessage(O.ClassName)试试!
很感谢你的回复,汇编没有作用可能是Delphi版本不一样,汇编不怎么懂,也不会改。ShowMessage(O.ClassName)错误的原因大概是没有传递Self,如果用我前面提到的ReSetObjEvent函数就没有问题了。
参考:http://www.cnpack.org/showdetail.php?id=628&lang=zh-cn看了下底层的Click貌似是私有方法,不能覆盖,所以实现这个貌似很困难~~
TNotifyEvent = procedure(Sender: TObject) of object;你不能搞一个参数不同的另类方法赋值给onClick,所以另想它法吧...
TControl = class(TComponent)
...
protected
...
procedure Click; dynamic;
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TMyClick=procedure(sender:TObject;Text:string) of object;
TButton= class (StdCtrls.TButton)
private
FMyClick: TMyClick;
FOldCilck:TNotifyEvent;
procedure SetMyClick(const Value: TMyClick);
procedure OnclickEx(sender:TObject); published
public
procedure DefaultMyclick(sender:TObject;Text:string);
property OnMyClick: TMyClick read FMyClick write SetMyClick; end; TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}{ TButton }procedure TButton.DefaultMyclick(sender: TObject; Text: string);
begin
ShowMessage(Text);
end;procedure TButton.OnclickEx(sender: TObject);
begin
if Assigned(FOldCilck) then
begin
FOldCilck(sender); end;
if Assigned(FMyClick) then
FMyClick(sender,'fdsfds');
end;procedure TButton.SetMyClick(const Value: TMyClick);
begin FMyClick := Value;
if Assigned(OnClick) then
begin
FOldCilck := OnClick;
OnClick :=OnclickEx;
end;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage('old');
end;procedure TForm1.FormCreate(Sender: TObject);
begin
Button1.OnMyClick:= Button1.DefaultMyclick;
end;end.