我正在开发 MDI 应用程序,它为每个创建的 MDI 子项分配一个选项卡。我需要在主(父)表单代码中“捕获”子表单的 OnActivate、OnCreate 和 OnDestroy 事件。简单地以子窗体调用代码对我来说是不可能的,因为有许多窗体的类用作 MDI 子窗体,插件也可以加载它自己的窗体...
所以,我的问题是:如何在不使用子表单事件的情况下捕获 MDI 子表单已被激活/停用?
我正在开发 MDI 应用程序,它为每个创建的 MDI 子项分配一个选项卡。我需要在主(父)表单代码中“捕获”子表单的 OnActivate、OnCreate 和 OnDestroy 事件。简单地以子窗体调用代码对我来说是不可能的,因为有许多窗体的类用作 MDI 子窗体,插件也可以加载它自己的窗体...
所以,我的问题是:如何在不使用子表单事件的情况下捕获 MDI 子表单已被激活/停用?
几年前我写了一个任务栏类型的组件,它就是做这种事情的。它被称为 TrmMDITaskbar。您可以在Torrys上找到它的副本,它是 rmControls 库包的一部分。它处理激活、最小化、最大化等。
它工作原理的要点是它挂钩 MDIParents 窗口句柄以查找 MDIChild 事件并根据这些事件执行操作。
如果您想编写自己的,我建议您从这里开始。
瑞安。
PS Torrys 上的版本有点旧,但应该仍然可以使用。我的支持网站上确实有更新的版本。(米尔斯企业)
您总是可以在运行时从代码中“事后”挂钩事件。基本上创建一个看起来像这样的通用 OnActivate:
type
TEventHolder = class
private
FSFActivate: TNotifyEvent;
published
property SavedFormActivate : TNotifyEvent
read FSFActivate write fSFActivate;
end;
type
TMainForm = class(Tform)
:
SavedEvents : tStringList;
procedure ChildFormActivate(Sender: TObject);
procedure InitChildForm(MdiForm:TForm);
end;
procedure TMainForm.ChildFormActivate(Sender: TObject);
var
i : integer;
begin
// your special processing here this is called for the child form.
i := SavedEvents.IndexOf(ClassName);
if i <> -1 then
tEventHolder(SavedEvents.Objects[i]).SavedFormActivate(Sender);
end;
procedure TMainForm.InitChildForm(MdiForm:TForm);
var
OrigEvents : TEventHolder;
begin
if not Assigned(SavedEvents) then
SavedEvents := tSTringlist.create;
if Assigned(MdiForm.OnActivate) then
begin
OrigEvents := tEventHolder.create;
OrigEvents.SavedFormActivate := MdiForm.OnActivate;
SavedEvents.AddObject(MdiForm.ClassName,OrigEvents);
end;
MdiForm.OnActivate := ChildFormActivate;
end;
然后调用 InitChildForm 在程序中的某个时间点将事件处理程序设置为您的通用版本(很可能在您创建表单之后)。当然,在主窗体关闭时,您将需要释放 SavedEvents(和链接对象)。