3

我希望防止在创建第二个 MDI 子项时发生 MDI 子项 WindowState 更改...

我有一个我正在开发的应用程序,用 Delphi 编写。通过一点 Delphi/Windows 魔术,应用程序有多个 MDI 父级和多个 MDI 子级。

我可以创建一个表单(子 A1),并在 MDI 父级(父级 A)中最大化它。我可以创建第二个表单(子 B1)并在第二个 MDI 父级(父级 B)中最大化它。两种形式都将在单独的 MDI 父母中进行最大化。到现在为止还挺好。我有这个工作。

但是,当我在第一个 MDI 父级(父级 A)中创建第二个 MDI 子级(子级 A2)时,第一个子级(子级 A1)的 WindowState(wsMaximized)会在创建第二个子级(子级 A2)时发生变化。我希望第一个孩子(孩子 A1)保持最大化,并创建第二个孩子(孩子 A2)并将其放置在第一个孩子之上......

如何防止第一个 MDI 子项的状态发生变化,同时又创建第二个 MDI 子项?有什么提示吗?

好的 - 现在我已经吃过午饭了,也许我可以更好地解释一下……这是第二次尝试……

所描述的行为可以在一个简单的 MDI 应用程序中重现(我用来创建多个 MDI 父级的魔法不会影响我的问题)

创建一个新的表单应用程序,将 formstyle 更改为 fsMdiForm 创建第二个表单,将其样式更改为 fsMDIChild 创建第三个表单,将其样式更改为 fsMDIChild

运行应用程序。实例化第二个表单,然后最大化(按预期工作 - 在 MDI Parent 中最大化) 实例化第三个表单,第三个表单以窗口状态 wsNormal 打开。但是当第三个窗体创建时,第二个窗体的窗口状态发生了变化——它不再被最大化,变成了wsNormal,就好像你点击了restore一样!

我想在打开第三个表单时避免恢复第二个表单...(所有表单的初始 WindowState 为 wsNormal...

非常感谢任何提示!

4

3 回答 3

1

在我的应用程序中,我还使用了多个 MDI 父级。下面是我的魔法代码,不同的孩子在每个父母中都有不同的状态。

此代码来自:ID: 23574, Multiple MDI Parent Forms in a single Application

//Add multiple MDIForm support
TFormMDIEnhance = class(TForm)
  private
    _mdiClientHandle: HWND;
    function GetMDIClientHandle: HWND;
  protected
    procedure CreateWindowHandle(const Params: TCreateParams); override;
    procedure DestroyWindowHandle; override;
  end;

procedure TFormMDIEnhance.CreateWindowHandle(const Params: TCreateParams);
var
  mdiStruct: MDICREATESTRUCT;
begin
  _mdiClientHandle := GetMDIClientHandle;

  if (FormStyle = fsMDIChild) then
  begin
    mdiStruct.szClass := Params.WinClassName;
    mdiStruct.szTitle := Params.Caption;
    mdiStruct.hOwner := HInstance;
    mdiStruct.x := Params.X;
    mdiStruct.y := Params.Y;
    mdiStruct.cx := Params.Width;
    mdiStruct.cy := Params.Height;
    mdiStruct.style := Params.Style;
    mdiStruct.lParam := LPARAM(Params.Param);

    WindowHandle := SendStructMessage(_mdiClientHandle, WM_MDICREATE, 0, mdiStruct);
    Include(FFormState, fsCreatedMDIChild);
  end
  else
    inherited CreateWindowHandle(Params);
end;

procedure TFormMDIEnhance.DestroyWindowHandle;
begin
  if fsCreatedMDIChild in FFormState then
    SendMessage(_mdiClientHandle, WM_MDIDESTROY, Handle, 0)
  else
    inherited DestroyWindowHandle;

  _mdiClientHandle := 0;
end;

function TFormMDIEnhance.GetMDIClientHandle: HWND;
var
  fm: TForm;
begin
  result := 0;

  if Owner is TForm then
  begin
    fm := Owner as TForm;
    if Assigned(fm) then
      Result := fm.ClientHandle;
  end;

  if (Result = 0) and Assigned(Application.MainForm) then
    Result := Application.MainForm.ClientHandle;

  if Result = 0 then
    raise EInvalidOperation.Create(SNoMDIForm);

end;

从该基本表单继承您的表单,然后您可以创建多个 MDI 父级。也许这有帮助。

于 2011-12-20T15:21:48.570 回答
0

我花了很长时间才弄清楚你真正在问什么,但我认为这可以归结为这个评论。

我希望 MDI 子项的 WindowState 行为在父项中有所不同。所以第一个 MDI Child 是 wsMax'd,第二个是 wsNormal。

这在 MDI 中是不可能的。当 MDI 子窗口最大化时,这是唯一可见的子窗口。

于 2011-12-20T19:07:14.543 回答
0

Remy 和 David 都是正确的,因为这是 MDI 限制。

最后,我的解决方案确实有效,它是在每个子窗体上维护一个 ChildWindowState(这只是一个 WindowState),然后在 ChildWindowState 更改时处理子窗口的大小/定位......这不是一个漂亮的答案,但它确实提供我在我的应用程序中需要的功能。

感谢所有的答案 :)

于 2011-12-29T17:13:36.990 回答