Delphi MDI - 处理打开/关闭/激活子窗体

发布于 2024-08-05 15:15:49 字数 221 浏览 5 评论 0原文

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

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

I'm developing MDI application which assigns a tab for each created MDI child. I need to "catch" OnActivate, OnCreate and OnDestroy events of child form in the main (parent) form code. Simply calling the code in children form is impossible for me, as there are many form's classes that are used as MDI children, also the plugin can load it's own form...

So, my question is: how to catch that MDI child form has been activated/deactivated without using child form's events ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

魂牵梦绕锁你心扉 2024-08-12 15:15:49

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

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

如果您想自己编写,我建议您将其作为一个很好的起点。

瑞安.

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

I wrote a Taskbar type of component a bunch of years ago that does just this type of thing.
It's called TrmMDITaskbar. You can find a copy of it on Torrys, it's a part of the rmControls library package. It handles activation, minimizing, maximizing etc.

The gist of how it works is that it hooks the MDIParents window handle looking for MDIChild events and does stuff based on those events.

If you're looking to write your own I would suggest that as a good place to start.

Ryan.

P.S. The version on Torrys is a little older but should still work. I do have a newer version available on my support website. (Mills Enterprise)

黑凤梨 2024-08-12 15:15:49

您始终可以在运行时从代码中“事后”挂钩事件。基本上创建一个看起来像这样的通用 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(和链接的对象)。

You could always hook the events "after the fact" from your code at runtime. Basically create a generic OnActivate that looks something like this:

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;

Then call the InitChildForm to set the event handlers to your generic versions at some point in your program (most likely right after you create the form). Of course upon main form closure you will want to free the SavedEvents (and linked objects).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文