我正在开发MDI应用程序,它为每个创建的MDI子项分配一个选项卡。我需要在主(父)表单代码中“捕获”子表单的OnActivate,OnCreate和OnDestroy事件。简单地调用子代码形式的代码对我来说是不可能的,因为有许多表单的类用作MDI子代,插件也可以加载它自己的形式......
所以,我的问题是:如何捕获MDI子表单已激活/停用而不使用子表单的事件?
答案 0 :(得分:3)
我在几年前编写了一个任务栏类型的组件,只做这种类型的事情。 它叫做TrmMDITaskbar。您可以在Torrys上找到它的副本,它是rmControls库包的一部分。它处理激活,最小化,最大化等。
它的工作原理是它挂钩MDIParents窗口句柄寻找MDIChild事件并根据这些事件做事。
如果你想写自己的话,我会建议你开个好地方。
瑞恩。
P.S。 Torrys上的版本有点旧,但应该仍然可以使用。我的支持网站上有更新的版本。 (Mills Enterprise)
答案 1 :(得分:1)
您总是可以在运行时从代码中“事后”挂钩事件。基本上创建一个通用的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(和链接对象)。