如果给控件的事件多添加一个参数?

zzzzzzzzz04 2012-06-05 03:18:33

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传进去,应该涉及到消息处理什么的。。
...全文
162 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
kuangning 2012-06-06
  • 打赏
  • 举报
回复
不知道这样能满足你的需要不

unit Unit1;

interface

uses
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.
s11ss 2012-06-05
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]
看了下底层的Click貌似是私有方法,不能覆盖,所以实现这个貌似很困难~~
[/Quote]Controls.pas:
  TControl = class(TComponent)
...
protected
...
procedure Click; dynamic;
天涯倦客 2012-06-05
  • 打赏
  • 举报
回复
delphi2006后可以用ClassHelper..
山东蓝鸟贵薪 2012-06-05
  • 打赏
  • 举报
回复
好像D7已受到限制了吧
kaikai_kk 2012-06-05
  • 打赏
  • 举报
回复
你只能使用形参与目标函数参数(实际是指向对象方法的指针)一致的方法,不能额外的增加或者减少参数,或者改变参数类型

比如Button的onclick事件,它是TNotifyEvent即:
TNotifyEvent = procedure(Sender: TObject) of object;

你不能搞一个参数不同的另类方法赋值给onClick,所以另想它法吧...
zzzzzzzzz04 2012-06-05
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

引用 4 楼 的回复:
首先,那段汇编没有调用MyClickWrapper成功。

最重要的是,我的目的是让事件对应的过程多一个参数,跟你的想法完全不一样。
想达到你这段代码的效果很简单:
var
Event: TNotifyEvent;
begin
integer(@Event) := integer(@MyClickWrapper);
btn1.OnClick := Ev……
[/Quote]

很感谢你的回复,汇编没有作用可能是Delphi版本不一样,汇编不怎么懂,也不会改。

ShowMessage(O.ClassName)错误的原因大概是没有传递Self,如果用我前面提到的ReSetObjEvent函数就没有问题了。
参考:http://www.cnpack.org/showdetail.php?id=628&lang=zh-cn

看了下底层的Click貌似是私有方法,不能覆盖,所以实现这个貌似很困难~~
cdchq 2012-06-05
  • 打赏
  • 举报
回复
感觉应该从TButton继承一个控件出来
s11ss 2012-06-05
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
首先,那段汇编没有调用MyClickWrapper成功。

最重要的是,我的目的是让事件对应的过程多一个参数,跟你的想法完全不一样。
想达到你这段代码的效果很简单:
var
Event: TNotifyEvent;
begin
integer(@Event) := integer(@MyClickWrapper);
btn1.OnClick := Event;
end;[/Quote]
首先,那段汇编在我这边的delphi2007环境下调用MyClickWrapper成功了。
其次,你的那段模拟的代码是有问题的,不信你可以在MyClickWrapper中调用ShowMessage(O.ClassName)试试!
「已注销」 2012-06-05
  • 打赏
  • 举报
回复
貌似很深奥
s11ss 2012-06-05
  • 打赏
  • 举报
回复
不如在TButton的基础上封装个控件!
zzzzzzzzz04 2012-06-05
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

delphi2007测试通过!
Delphi(Pascal) code
procedure MyClick(Sender: TObject;s:string);
begin
showmessage((Sender as Tbutton).Caption+'____'+ s);
end;

procedure MyClickWrapper(O, Sender: TObject);
begi……
[/Quote]

首先,那段汇编没有调用MyClickWrapper成功。

最重要的是,我的目的是让事件对应的过程多一个参数,跟你的想法完全不一样。
想达到你这段代码的效果很简单:
var
Event: TNotifyEvent;
begin
integer(@Event) := integer(@MyClickWrapper);
btn1.OnClick := Event;
end;
s11ss 2012-06-05
  • 打赏
  • 举报
回复
delphi2007测试通过!
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;
zzzzzzzzz04 2012-06-05
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

可以用(Sender as Tbutton).Hint来保存信息
showmessage((Sender as Tbutton).Caption+'____'+ (Sender as Tbutton).Hint);
[/Quote]

类似传信息的方法很多,甚至可以用控件的指针指向一个对象。

我的目的是额外的传入一个参数,因为控件是生成的,事件对应的函数已经有一些,想把这些函数绑定到这个事件上去,但是函数参数不一样~~
我看见佛 2012-06-05
  • 打赏
  • 举报
回复
可以用(Sender as Tbutton).Hint来保存信息
showmessage((Sender as Tbutton).Caption+'____'+ (Sender as Tbutton).Hint);

5,386

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧