Note that the following here does not explicitly answer the question. It is rather a proposal to redesign the concept (redirect OnClick events instead of adding additional OnMouseUp). This is about how to redirect the OnClick event handler (if assigned) of all components (can be filtered, if necessary) to another (regular) OnClick event handler. It also includes a way to restore them to their original state.
In the following example, I will try to show you how to replace, and then additionally restore the OnClick event handlers (if the component wrote several) to a specific one. This is done for all components in which the OnClick event is published, so you do not need to know in advance if the component class has an OnClick event, available or not (but you can simply change it to use only a specific class).
The code consists of the following:
OnSpecialClick is an event handler in which all OnClick events will be bound when the ReplaceOnClickEvents procedure is called, note that it must be published in order to be visible to RTTI !!!
Button1Click - is an old event handler that needs to be replaced, attached to the Button1.OnClick event during development
ReplaceOnClickEvents - a method that iterates through all components of the form and checks whether the current iterative event handler has OnClick; if so, it saves it to the backup collection and replaces this event handler with OnSpecialClick
RestoreOnClickEvents - a method that restores the original OnClick event handlers; it iterates through a collection of backups and assigns event methods to its instances of stored components.
CheckBox1Click - this click event flag means switching between normal and special modes (CheckBox1 checks the status means special mode), only this OnClick event is not replaced by a call to ReplaceOnClickEvents (because you cannot restore normal mode)
And here he is:
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.
TLama source share