Delphi多个MDI子项导致窗口状态更改

时间:2011-12-20 13:29:30

标签: forms delphi mdi mdiparent

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

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

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

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

如何防止第一个MDI Child的状态发生变化,还可以创建第二个MDI子项?任何提示?

好的 - 现在我已经吃了一些午餐,也许我可以更好地解释一下......这是第二次去...

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

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

运行该应用。实例化第二个表单,然后最大化(按预期工作 - 在MDI Parent中最大化) 实例化第三种形式,第三种形式打开,窗口状态为wsNormal。但是当创建第三个窗体时,第二个窗体的窗口状态会发生变化 - 它会停止最大化,并且变得非常正常,就像你点击了恢复一样!

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

任何提示都非常感谢!

3 个答案:

答案 0 :(得分:1)

在我的应用程序中,我还使用多个MDI父母。下面是我的魔术代码,其中不同的Childs在每个Parent中都有不同的状态。

此代码摘自: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;

从该Base表单继承表单,然后您可以创建多个MDI Parents。 也许这有帮助。

答案 1 :(得分:0)

我花了很多时间来研究你真正想要的东西,但我认为这归结为这个评论。

  

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

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

答案 2 :(得分:0)

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

我的解决方案最终确实起作用,就是在每个子窗体上维护一个ChildWindowState(它只是一个WindowState),然后在ChildWindowState更改时处理子窗口的大小调整/定位......这不是一个很好的答案但是它确实提供了我在我的应用程序中所需的功能。

感谢所有答案:)