Delphi 赢得';t刹住咔嗒声
好的,我有一个函数,它向我返回TMouseEvent类型 我需要执行返回的tmouse事件,但我不知道如何执行 返回事件的简单函数:Delphi 赢得';t刹住咔嗒声,delphi,events,Delphi,Events,好的,我有一个函数,它向我返回TMouseEvent类型 我需要执行返回的tmouse事件,但我不知道如何执行 返回事件的简单函数: function OMDold(obj: TObject): TMouseEvent begin ... //some operations on obj result := obj.OnMouseDown; //there is casting necessary, I skip it for simplify end; 当前事件设置为OMDn
function OMDold(obj: TObject): TMouseEvent
begin
... //some operations on obj
result := obj.OnMouseDown; //there is casting necessary, I skip it for simplify
end;
当前事件设置为OMDnew,如下所示:
procedure TfmAPRBasedForm.TSDragEvent(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if something then dosomething
else
begin
Sender.OnMouseDOwn := OMDold // OMDold in most cases returns null but its ok I just want to clear custom event from the object
//line below is a point of my question - the one I used doesnt work
TButton(Sender).OnMouseDown(Sender,Button,Shift,X,Y) //this line throws Access viloation at me
end;
end;
我正在努力实现的目标:
就是这样只需通过参数直接调用它:
procedure TfmAPRBasedForm.TSDragEvent(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if something then dosomething
else
begin
TButton(Sender.OnMouseDOwn) := OMDold // OMDold in most cases returns nil (not null) but its ok I just want to clear custom event from the object
//line below is a point of my question - the one I used doesnt work
If Assigned(TButton(Sender).OnMouseDown) then // Check if there is really an TMouseEvent
TButton(Sender).OnMouseDown(Sender,Button,Shift,X,Y) //Call only when Event exist
end;
end;
如果您在OMDOld中使用按钮、Shift、X、Y,并且需要dragEvent中当前值以外的值,例如删除ssShift等等,则可能需要更改按钮、Shift、X、Y
如果您的OMDold存储为TMethod,则可以使用:
TMouseEvent(OMDOld)(Sender,Button,Shift,X,Y);
下面是一个经过调整的完整测试示例,以显示您希望以类似方式实现的目标:
Unit Unit4;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm4 = class(TForm)
btn1: TButton;
btn2: TButton;
procedure FormCreate(Sender: TObject);
procedure btn1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure btn2MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
procedure NewMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
public
{ Public declarations }
OMDold : TMouseEvent;
IsNew : Boolean;
end;
var
Form4: TForm4;
implementation
{$R *.dfm}
procedure TForm4.FormCreate(Sender: TObject);
begin
OMDold := btn1.OnMouseDown;
btn1.OnMouseDown := NewMouseDown;
IsNew := True;
end;
procedure TForm4.NewMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if IsNew then
ShowMessage('New Method!')
else if Assigned(OMDold) then
OMDold(Sender,Button,Shift,X,Y);
end;
procedure TForm4.btn1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ShowMessage('Original Method!');
end;
procedure TForm4.btn2MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
IsNew := not IsNew;
end;
end.
只需通过参数直接调用它:
procedure TfmAPRBasedForm.TSDragEvent(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if something then dosomething
else
begin
TButton(Sender.OnMouseDOwn) := OMDold // OMDold in most cases returns nil (not null) but its ok I just want to clear custom event from the object
//line below is a point of my question - the one I used doesnt work
If Assigned(TButton(Sender).OnMouseDown) then // Check if there is really an TMouseEvent
TButton(Sender).OnMouseDown(Sender,Button,Shift,X,Y) //Call only when Event exist
end;
end;
如果您在OMDOld中使用按钮、Shift、X、Y,并且需要dragEvent中当前值以外的值,例如删除ssShift等等,则可能需要更改按钮、Shift、X、Y
如果您的OMDold存储为TMethod,则可以使用:
TMouseEvent(OMDOld)(Sender,Button,Shift,X,Y);
下面是一个经过调整的完整测试示例,以显示您希望以类似方式实现的目标:
Unit Unit4;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm4 = class(TForm)
btn1: TButton;
btn2: TButton;
procedure FormCreate(Sender: TObject);
procedure btn1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure btn2MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
procedure NewMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
public
{ Public declarations }
OMDold : TMouseEvent;
IsNew : Boolean;
end;
var
Form4: TForm4;
implementation
{$R *.dfm}
procedure TForm4.FormCreate(Sender: TObject);
begin
OMDold := btn1.OnMouseDown;
btn1.OnMouseDown := NewMouseDown;
IsNew := True;
end;
procedure TForm4.NewMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if IsNew then
ShowMessage('New Method!')
else if Assigned(OMDold) then
OMDold(Sender,Button,Shift,X,Y);
end;
procedure TForm4.btn1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ShowMessage('Original Method!');
end;
procedure TForm4.btn2MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
IsNew := not IsNew;
end;
end.
停止OnMouseDown运行CLick事件的示例过程:
procedure TForm1.CustomowyEvent(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if (DragDetectPlus(TWinControl(Sender))) then ShowMessage('detected drag!')
else
begin
TButton(Sender).OnMouseDown := DME;
TButton(Sender).OnClick(Sender);
end;
end;
TButton(Sender)。OnClick(Sender)
运行单击,因此如果我们不想拖动它,基本上可以单击 停止OnMouseDown运行CLick事件的示例过程:
procedure TForm1.CustomowyEvent(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if (DragDetectPlus(TWinControl(Sender))) then ShowMessage('detected drag!')
else
begin
TButton(Sender).OnMouseDown := DME;
TButton(Sender).OnClick(Sender);
end;
end;
TButton(Sender)。OnClick(Sender)
运行单击,因此如果我们不想拖动它,基本上可以单击 分别解决所有问题部分:
OnMouseDown
事件并将其存储在一些记录数据中
将专用字段添加到表单声明中,并将旧事件分配给它:
private
FOldButtonOnMouseDown: TMouseEvent;
end;
...
FOldButtonOnMouseDown := Button.OnMouseDown;
OnMouseDown
事件更改为自定义
将自定义事件处理程序分配给OnMouseDown
属性:
private
procedure NewButtonMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
end;
...
Button.OnMouseDown := NewButtonMouseDown;
procedure TForm1.NewButtonMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if DragCondition then
ExecuteDragCode
else
if Assigned(FOldButtonOnMouseDown) then
FOldButtonOnMouseDown(Sender, Button, Shift, X, Y);
end;
Button.OnMouseDown := FOldButtonOnMouseDown;
将这一切结合在一起是您的下一个挑战。这尤其取决于drag stuf的实现方式,但您可以看看我在其中临时交换了
OnMouseUp
事件以撤消所有更改。分别解决所有问题部分:
OnMouseDown
事件并将其存储在一些记录数据中
将专用字段添加到表单声明中,并将旧事件分配给它:
private
FOldButtonOnMouseDown: TMouseEvent;
end;
...
FOldButtonOnMouseDown := Button.OnMouseDown;
OnMouseDown
事件更改为自定义
将自定义事件处理程序分配给OnMouseDown
属性:
private
procedure NewButtonMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
end;
...
Button.OnMouseDown := NewButtonMouseDown;
procedure TForm1.NewButtonMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if DragCondition then
ExecuteDragCode
else
if Assigned(FOldButtonOnMouseDown) then
FOldButtonOnMouseDown(Sender, Button, Shift, X, Y);
end;
Button.OnMouseDown := FOldButtonOnMouseDown;
将这一切结合在一起是您的下一个挑战。这尤其取决于drag stuf是如何实现的,但您可以看看我在其中还临时交换了
OnMouseUp
事件以撤消所有更改。为什么不直接调用OMDnew
。你可以这样做,你知道。直接调用OMDnew(发送者、按钮、shift、x、y)
有什么问题吗?我的描述不够清楚。Justmake可能给了我正确的答案。不过,为了进一步使用,我编辑了我的帖子:)正如您所说,Sender.OnMouseDOwn:=OMDold通常返回nil(非null)。这意味着Sender.OnMouseDOwn也是零。这就是为什么调用它会得到AV。在调用TButton(Sender.OnMouseDOwn)之前,您需要添加If Assigned(Sender.OnMouseDOwn),以便在Sender.OnMouseDOwn为空时跳过它。我已经回答了您最初的问题,但它可能实际上并没有解决您的问题,因为您没有清楚地指出您的问题。不断改变问题并不是获得更多帮助的好方法。如果你的新问题确实与原来的问题大不相同,你最好问一个新问题。为什么不直接打电话给OMDnew
。你可以这样做,你知道。直接调用OMDnew(发送者、按钮、shift、x、y)
有什么问题吗?我的描述不够清楚。Justmake可能给了我正确的答案。不过,为了进一步使用,我编辑了我的帖子:)正如您所说,Sender.OnMouseDOwn:=OMDold通常返回nil(非null)。这意味着Sender.OnMouseDOwn也是零。这就是为什么调用它会得到AV。在调用TButton(Sender.OnMouseDOwn)之前,您需要添加If Assigned(Sender.OnMouseDOwn),以便在Sender.OnMouseDOwn为空时跳过它。我已经回答了您最初的问题,但它可能实际上并没有解决您的问题,因为您没有清楚地指出您的问题。不断改变问题并不是获得更多帮助的好方法。如果你的新问题确实与原来的问题大不相同,那你就更好了