gpt4 book ai didi

delphi - Delphi 7 中停止事件传播

转载 作者:行者123 更新时间:2023-12-03 15:00:11 32 4
gpt4 key购买 nike

我在 Delphi 7 中遇到了一个关于事件传播的问题(由于我的无知)。

我被要求在表单上的某些控件上动态附加一个 OnMouseUp 事件处理程序(我对此很满意),但是如果 OnMouseUp 存在,不得处理该控件上的 OnClick 事件。

背景

如果您问这背后的原因,那么,我负责修改一个旧的生产监控应用程序(叹气),从现在开始,该应用程序必须适应某些控件的条件行为,以直接响应以前的点击特殊功能按钮。

其中一些控件已经有一个 OnClick 事件处理程序;该团队提出的第一个解决方案是准时干预每个 OnClick 处理程序并管理与特殊功能按钮状态相关的上下文操作。

我建议利用应用程序表单已有的面向对象设计:它们都继承自同一个自定义祖先对象,因此我计划在那里插入一个初始化方法来动态附加OnMouseUp 事件到在子类中声明支持它的控件。

需要

我并不是特此对这一切的设计优点(可能缺乏)进行验证或质疑(顺便说一句,经过大量思考和推理,这似乎是我们可以少走一些痛苦的道路) ;我的问题是,要进行这样的设计,我必须让动态附加的 OnMouseUp 事件处理程序停止将事件传播到这些控件上预先存在的 OnClick 事件。

Delphi 7 可以吗?

最佳答案

请注意,以下内容并未明确回答此处的问题。它更多的是概念重新设计的建议(重定向 OnClick 事件而不是添加额外的 OnMouseUp)。它是关于如何将所有组件(如果需要,可能会被过滤)的 OnClick 事件处理程序(如果分配了一些)重定向到另一个(公共(public))OnClick 事件处理程序。它还包括将它们恢复到原始状态的方法。

在下面的示例中,我将尝试向您展示如何用特定的事件处理程序替换并选择性地恢复 OnClick 事件处理程序(如果组件已编写一些事件处理程序)。这是对所有发布了 OnClick 事件的组件执行的,因此您不需要提前知道组件类是否具有可用的 OnClick 事件(但可以非常简单地将其修改为仅使用特定类)。

代码由以下部分组成:

  • OnSpecialClick - 它是当您调用 ReplaceOnClickEvents 过程时将绑定(bind)所有 OnClick 事件的事件处理程序,请注意 它必须发布才能对 RTTI 可见!!!

  • Button1Click - 此处表示应替换的旧事件处理程序,它在设计时绑定(bind)到 Button1.OnClick 事件

  • ReplaceOnClickEvents - 方法,迭代表单上的所有组件并检查
    当前迭代的组件是否分配了 OnClick 事件处理程序;如果是这样,它将其存储到备份集合中,并用 OnSpecialClick 替换此事件处理程序

  • RestoreOnClickEvents - 方法,恢复原始的 OnClick 事件处理程序;它迭代备份集合并将事件方法分配给其存储的组件实例

  • CheckBox1Click - 此复选框点击事件是普通模式和特殊模式之间的切换(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.

关于delphi - Delphi 7 中停止事件传播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10496557/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com