gpt4 book ai didi

delphi - Delphi 是否提供用于表单创建通知的事件处理程序?

转载 作者:行者123 更新时间:2023-12-03 15:26:07 25 4
gpt4 key购买 nike

Delphi 是否提供某种用于表单创建的事件或 Hook (或者更一般地说,表单生命周期事件)?

因此,如果在代码中的某处创建并显示表单(模态或非模态、动态或在通常的应用程序启动阶段),Delphi 会调用一个事件处理程序,该处理程序允许在其之前记录/分析/修改表单显示了吗?

我知道有一些选项涉及引入基本表单类或自定义表单创建过程,但对于已经拥有许多表单的现有应用程序来说,“最好”有一个非侵入性选项来添加类似于交叉的内容-消除面向方面编程(AOP)中的担忧。

例如,如果我有一些用于使用情况统计跟踪的代码,它会注入(inject)额外的事件处理程序,我可以简单地为每个表单添加此功能,开发人员不必更改应用程序代码,只需添加与此类似的代码

...
Application.OnNewForm := MyNewFormCreated;
...

procedure TMyApp.MyNewFormCreated(Sender: TCustomForm);
begin
// iterate over components and do other stuff with the new form
...
end;

最佳答案

在运行时,您可以重写 TCustomForm.DoCreateTCustomFrame.Create 方法,如下所示:

type
THookedForm = class(TCustomForm)
procedure HookedDoCreate;
end;

THookedFrame = class(TCustomFrame)
constructor Create(AOwner: TComponent); override;
end;

var
OriginalForm, OriginalFrame: TPatchCode;

procedure PatchCreate;
begin
if OriginalForm[0]<>0 then
exit; // patch once
RedirectCode(@THookedForm.DoCreate,@THookedForm.HookedDoCreate,@OriginalForm);
RedirectCode(@THookedFrame.Create,@THookedFrame.Create,@OriginalFrame);
end;


// hook logic was inspired from GetText()

{ THookedForm }

procedure THookedForm.HookedDoCreate;
// translate form contents just before an OnCreate handler would be called
begin
try
try
if Language<>nil then begin
DisableAlign;
DisableAutoRange;
try
Language.FormTranslateOne(self); // translate form
finally
EnableAlign;
EnableAutoRange;
end;
end;
finally
RedirectCodeRestore(@THookedForm.DoCreate,OriginalForm); // disable Hook
try
DoCreate; // call normal DoCreate event
finally
RedirectCode(@THookedForm.DoCreate,@THookedForm.HookedDoCreate);
end;
end;
except
on Exception do; // ignore all raised exception
end;
end;

{ THookedFrame }

constructor THookedFrame.Create(AOwner: TComponent);
// translate frame contents just after constructor has been called
begin
RedirectCodeRestore(@THookedFrame.Create,OriginalFrame); // disable Hook
try
inherited Create(AOwner); // call normal constructor
finally
RedirectCode(@THookedFrame.Create,@THookedFrame.Create);
end;
if Language=nil then exit;
DisableAlign;
DisableAutoRange;
try
Language.FormTranslateOne(self); // translate frame
finally
EnableAlign;
EnableAutoRange;
end;
end;


....

initialization
PatchCreate;

因此,每次创建 TForm 实例时都会调用您自己的 DoCreate 事件。

此代码摘自mORMoti18n.pas您可以在 SynCommons.pas 中找到补丁例程(适用于 Windows 和 Linux/BSD) .

关于delphi - Delphi 是否提供用于表单创建通知的事件处理程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6387226/

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