Fed*_*can 6 delphi delphi-7 event-handling mouseevent
我在Delphi 7中遇到了关于事件传播的问题(由于我的无知).
我被要求OnMouseUp
在表单上的某些控件上动态附加一个事件处理程序(我对那件事很好)但是如果OnMouseUp
存在,则OnClick
不能处理该控件上的事件.
如果你问这背后的原因,那么,我负责修改一个旧的生产监控应用程序(叹气),从现在开始必须适应某些控件的条件行为,直接响应之前点击特殊功能按钮.
其中一些控件已经有一个OnClick
事件处理程序; 团队提出的第一个解决方案是准时干预每个OnClick
处理程序并管理与特殊功能按钮状态相关的上下文操作.
我建议利用已经适用于应用程序表单的面向对象设计:它们都继承自相同的自定义祖先对象,因此我计划在那里插入一个初始化方法,将OnMouseUp
事件动态附加到声明支持的控件它在子类中.
我不是要求对所有这些(可能缺乏)设计优点进行验证或质疑(顺便说一下,经过大量的思考和推理,它似乎是我们可以轻松走路的路径); 我的问题是,为了进行这样的设计,我必须让动态连接的OnMouseUp
事件处理程序停止事件传播到OnClick
这些控件上的预先存在的事件.
Delphi 7有可能吗?
请注意,以下内容未明确回答此问题.这是对概念重新设计的一个提议(重定向OnClick事件而不是添加额外的OnMouseUp).它是关于如何将OnClick事件处理程序(如果已分配一些)重定向到另一个(公共)OnClick事件处理程序的所有组件(可能会被过滤,如果需要).它还包括将它们恢复到原始状态的方法.
在下面的示例中,我将尝试向您展示如何替换然后可选地还原特定的OnClick事件处理程序(如果组件已编写一些).对已发布OnClick事件的所有组件执行此操作,因此您无需事先知道组件类是否具有可用的OnClick事件(但可以非常简单地将其修改为仅使用特定类).
代码包括以下内容:
OnSpecialClick - 当您调用ReplaceOnClickEvents过程时,它是所有OnClick事件将被绑定的事件处理程序,请注意它必须发布为RTTI可见!
Button1Click - 在这里表示应该替换的旧事件处理程序,它在设计时绑定到Button1.OnClick事件
ReplaceOnClickEvents - 方法,它遍历表单上的所有组件,并检查
当前迭代的组件是否已分配OnClick事件处理程序; 如果是这样,它会将其存储到备份集合中,并通过OnSpecialClick替换此事件处理程序
RestoreOnClickEvents - 方法,用于恢复原始OnClick事件处理程序; 它遍历备份集合并将事件方法分配给其存储的组件实例
CheckBox1Click - 这个复选框click事件是指在公共模式和特殊模式之间切换(CheckBox1检查状态意味着是特殊模式),只有这个OnClick事件不会被ReplaceOnClickEvents调用替换(因为你不会能够将模式恢复正常)
这是:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, TypInfo, StdCtrls, Contnrs;
type
TEventBackup = class
Component: TComponent;
OnClickMethod: TMethod;
end;
type
TForm1 = class(TForm)
Button1: TButton;
CheckBox1: TCheckBox;
procedure Button1Click(Sender: TObject);
procedure CheckBox1Click(Sender: TObject);
private
procedure ReplaceOnClickEvents;
procedure RestoreOnClickEvents;
published
procedure OnSpecialClick(Sender: TObject);
end;
var
Form1: TForm1;
EventBackupList: TObjectList;
implementation
{$R *.dfm}
procedure TForm1.OnSpecialClick(Sender: TObject);
begin
ShowMessage('Hi, I''m an OnSpecialClick event message!');
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage('Hi, I''m just that boring original OnClick event message!');
end;
procedure TForm1.ReplaceOnClickEvents;
var
I: Integer;
Component: TComponent;
EventMethod: TMethod;
EventBackup: TEventBackup;
begin
for I := 0 to ComponentCount - 1 do
begin
Component := Components[I];
if Component = CheckBox1 then
Continue;
if IsPublishedProp(Component, 'OnClick') then
begin
EventMethod := GetMethodProp(Component, 'OnClick');
if Assigned(EventMethod.Code) and Assigned(EventMethod.Data) then
begin
EventBackup := TEventBackup.Create;
EventBackup.Component := Component;
EventBackup.OnClickMethod := EventMethod;
EventBackupList.Add(EventBackup);
EventMethod.Code := MethodAddress('OnSpecialClick');
EventMethod.Data := Pointer(Self);
SetMethodProp(Component, 'OnClick', EventMethod);
end;
end;
end;
end;
procedure TForm1.RestoreOnClickEvents;
var
I: Integer;
EventBackup: TEventBackup;
begin
for I := 0 to EventBackupList.Count - 1 do
begin
EventBackup := TEventBackup(EventBackupList[I]);
SetMethodProp(EventBackup.Component, 'OnClick', EventBackup.OnClickMethod);
end;
EventBackupList.Clear;
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
if CheckBox1.Checked then
ReplaceOnClickEvents
else
RestoreOnClickEvents;
end;
initialization
EventBackupList := TObjectList.Create;
EventBackupList.OwnsObjects := True;
finalization
EventBackupList.Free;
end.
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2149 次 |
最近记录: |