2009-09-15 95 views
5

我正在开发为每个创建的MDI子窗体分配一个选项卡的MDI应用程序。我需要在主(父)表单代码中“捕获”子表单的OnActivate,OnCreate和OnDestroy事件。简单地调用儿童形式的代码对我来说是不可能的,因为有很多形式的类被用作MDI儿童,插件也可以加载它自己的形式...德尔福MDI - 处理打开/关闭/激活子窗体

所以,我的问题是:如何捕捉MDI子窗体已被激活/取消激活未使用子窗体事件

回答

3

我写了一堆年前一个任务栏类型的组件,不只是这种类型的东西。 它被称为TrmMDITaskbar。你可以在Torrys上找到它的副本,它是rmControls库包的一部分。它处理激活的,最小化,最大化等

它的工作原理是,它挂钩MDIParents窗口句柄寻找MDIChild事件并不会基于这些事件东西的要点。

如果你正在寻找写自己的,我建议,作为一个良好的开端。

Ryan。

P.S. Torrys上的版本有点旧,但仍然可以工作。我的支持网站上有更新的版本。 (Mills Enterprise

+0

谢谢。最后我用它代码SpTBXLib鱼钩使用WH_CBT标志... :) – migajek 2009-09-15 19:55:19

+0

喜瑞安,我心底喜欢尝试该组件,但支持网站给了我一个错误403解决 - 禁止(您试图访问为其文档你没有特权。) – 2010-07-24 08:32:13

+0

@Alin Sfetcu,我最近改变了我的托管服务,但还没有得到我所有的链接和论坛重新安装。说实话,我认为我的支持论坛已经运作。我会尽快研究。对不起。正如我所说Torry网站的副本应该仍然有效。 – 2010-07-26 15:38:48

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(和链接的对象)。