请注意,以下内容并没有明确回答此处的问题。这更是一个概念重新设计的提议(重定向OnClick事件而不是添加额外的OnMouseUp)。它涉及如何将所有组件(如果需要可以进行过滤)的OnClick事件处理程序重定向到另一个(通用的)OnClick事件处理程序(如果已分配某些)。它还包括一种将它们恢复到原始状态的方法。
在下面的示例中,我将尝试向您展示如何替换然后选择性地恢复具有特定事件处理程序的OnClick事件处理程序(如果组件已编写)。这是针对所有发布了OnClick事件的组件完成的,因此您无需事先知道组件类是否可用OnClick事件(但可以非常简单地修改为仅使用特定类)。
代码由以下部分组成:
- OnSpecialClick - 这是当您调用ReplaceOnClickEvents过程时所有OnClick事件将绑定到的事件处理程序,请注意,它必须发布以便RTTI可见!!!
- Button1Click - 在此表示应该被替换的旧事件处理程序,它绑定在设计时的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.
OnMouseUp
时,也要取消分配OnClick
。 - Ondrej Kelle