以下は、ここでの質問に明示的に回答していないことに注意してください。これは、コンセプトの再設計への提案です (OnMouseUp を追加する代わりに、OnClick イベントをリダイレクトします)。すべてのコンポーネント (必要に応じてフィルタリングされる可能性があります) の 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.