5

我正在开发 MDI 应用程序,它为每个创建的 MDI 子项分配一个选项卡。我需要在主(父)表单代码中“捕获”子表单的 OnActivate、OnCreate 和 OnDestroy 事件。简单地以子窗体调用代码对我来说是不可能的,因为有许多窗体的类用作 MDI 子窗体,插件也可以加载它自己的窗体...

所以,我的问题是:如何在不使用子表单事件的情况下捕获 MDI 子表单已被激活/停用?

4

2 回答 2

3

几年前我写了一个任务栏类型的组件,它就是做这种事情的。它被称为 TrmMDITaskbar。您可以在Torrys上找到它的副本,它是 rmControls 库包的一部分。它处理激活、最小化、最大化等。

它工作原理的要点是它挂钩 MDIParents 窗口句柄以查找 MDIChild 事件并根据这些事件执行操作。

如果您想编写自己的,我建议您从这里开始。

瑞安。

PS Torrys 上的版本有点旧,但应该仍然可以使用。我的支持网站上确实有更新的版本。(米尔斯企业

于 2009-09-15T13:53:30.963 回答
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(和链接对象)。

于 2009-09-15T16:21:45.513 回答