我正在寻找创建TNotifyEvent钩子/包装器的简单方法 所以我有一个想法是创建它作为对象,使事情更容易
但我不知道如何正确附加/交换方法指针...:/
也许你们中的任何人以前做过类似的事情?
这是我班级的骨架
TNotifyEventHook = class
private
NotifyEvent: ???????;
OldProc, NewProc: ???????;
FContinueEventChain: Boolean;
procedure Wrapper(Sender: TObject);
public
constructor Create(OriginalNotifyEvent: ???????; ChainNotifyEvent???????);
destructor Destroy; override;
property ContinueEventChain: Boolean read FContinueEventChain write FContinueEventChain default True;
end;
constructor TNotifyEventHook.Create(OriginalNotifyEvent: ???????; ChainNotifyEvent: ???????);
begin
NotifyEvent := ??????? // save
OldProc := ???????
NewProc := ???????
NotifyEvent := ??????? // redirect NotifyEvent to Wrapper
end;
destructor TNotifyEventHook.Destroy;
begin
??????? // detach chain
end;
procedure TNotifyEventHook.Wrapper(Sender: TObject);
begin
if Assigned(NewProc) then
NewProc(Sender);
if FContinueEvenChain and Assigned(OldProc) then
OldProc(Sender);
end;
我真的很感激帮助......或者只是更好的想法?
答案 0 :(得分:0)
这不会起作用,因为您无法在变量或参数中存储对事件属性本身的引用。 NotifyEvent ís OldProc / NewProc。换句话说:存储在事件属性中的事物是从对象内部触发属性时调用的事件处理程序。因此,有效的TNotifyEvent
实例只会告诉调用哪个例程,而不是例程链接到哪个对象或属性。
如果您的问题仅限于一个特定事件,例如TControl.OnClick
,然后以下工作。否则,我建议您使用多播事件模型,例如像TApplicationEvents
那样。
type
TOnClickRedirector = class
private
FControl: TControl;
FFireOriginalToo: Boolean;
FOriginal: TNotifyEvent;
FRedirect: TNotifyEvent;
procedure Fire(Sender: TObject);
public
constructor Create(Control: TControl; OnClick: TNotifyEvent);
destructor Destroy; override;
property FireOriginalToo: Boolean read FFireOriginalToo
write FFireOriginalToo default True;
end;
TControlAccess = class(TControl);
{ TOnClickRedirector }
constructor TOnClickRedirector.Create(Control: TControl; OnClick: TNotifyEvent);
begin
FControl := Control;
FOriginal := TControlAccess(FControl).OnClick;
FRedirect := OnClick;
TControlAccess(FControl).OnClick := Fire;
FFireOriginalToo := True;
end;
destructor TOnClickRedirector.Destroy;
begin
TControlAccess(FControl).OnClick := FOriginal;
inherited Destroy;
end;
procedure TOnClickRedirector.Fire(Sender: TObject);
begin
if Assigned(FRedirect) then
FRedirect(Sender);
if FFireOriginalToo and Assigned(FOriginal) then
FOriginal(Sender);
end;
为您要拦截的每个特定事件复制此内容。请注意,此代码示例无法保证FControl
在此对象的销毁中不再存在的可能性。因此,最好从TComponent
下降并使用FreeNotification
。