好的我有一个函数可以返回 TMouseEvent 类型
我需要执行返回的TMouseEvent,但我不知道如何。
返回事件的简单函数:
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;
我想要实现的目标:
获取按钮默认OnMouseDown事件并将其存储在某些记录数据中
将ONMouseDown事件更改为自定义
在自定义事件过程中有一个条件 - 如果鼠标按下是拖动,我执行拖动代码,如果不是我继续进行常见的点击
要通过常规点击进行操作,我想恢复默认事件并重新执行,以便点击可以执行
多数民众赞成
答案 0 :(得分:3)
直接通过param调用它:
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;
您可能需要更改Button,Shift,X,Y,但如果您在OMDOld中使用它们,则需要除dragEvent中的当前值以外的值,例如删除ssShift左右。
如果您的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.
答案 1 :(得分:0)
阻止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)
会运行点击。
答案 2 :(得分:0)
分别处理所有问题部分:
获取按钮默认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;
将这一切结合在一起是您的下一个挑战。这尤其取决于如何实现拖动stuf,但您可以查看this answer,其中我还暂时交换OnMouseUp
事件以撤消所有更改。