mjn*_*mjn 5 forms delphi aop dynamic
Delphi 是否提供某种用于表单创建的事件或挂钩(或者更一般地说,表单生命周期事件)?
因此,如果在代码中的某处创建并显示表单(模态或非模态,动态或在通常的应用程序启动阶段),Delphi 会调用一个事件处理程序,该处理程序允许在显示之前记录/分析/修改表单?
我知道有一些选项涉及引入基本表单类或自定义表单创建过程,但对于已经拥有许多表单的现有应用程序来说,“最好”有一个非侵入性选项来添加类似于横切关注点的内容在面向方面编程(AOP)中。
例如,如果我有一些用于注入额外事件处理程序的使用情况统计跟踪代码,我可以简单地为每个表单添加此功能,开发人员不必更改应用程序代码,只需添加与此类似的代码
...
Application.OnNewForm := MyNewFormCreated;
...
procedure TMyApp.MyNewFormCreated(Sender: TCustomForm);
begin
// iterate over components and do other stuff with the new form
...
end;
Run Code Online (Sandbox Code Playgroud)
在运行时,您可以重写TCustomForm.DoCreate和TCustomFrame.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;
Run Code Online (Sandbox Code Playgroud)
因此,DoCreate每次创建 TForm 实例时都会调用您自己的事件。
此代码是从mORMoti18n.pas中提取的,您可以在SynCommons.pas中找到补丁例程(适用于 Windows 和 Linux/BSD)。
| 归档时间: |
|
| 查看次数: |
1842 次 |
| 最近记录: |