Windows 如何在Delphi中隐藏MDI子窗体?

Windows 如何在Delphi中隐藏MDI子窗体?,windows,delphi,winapi,mdi,Windows,Delphi,Winapi,Mdi,如何在Delphi中隐藏MDIChild窗口 我在MDI子项的FormClose()事件中使用此代码,但它似乎不起作用: procedure TfrmInstrument.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caNone; ShowWindow(Handle, SW_HIDE); frmMainForm.MDIChildClosed(Handle); end; “我的子窗口”被最

如何在Delphi中隐藏MDIChild窗口

我在MDI子项的FormClose()事件中使用此代码,但它似乎不起作用:

procedure TfrmInstrument.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caNone;
  ShowWindow(Handle, SW_HIDE);
  frmMainForm.MDIChildClosed(Handle);
end;

“我的子窗口”被最小化而不是隐藏。

您不能隐藏MDI子窗口。这是Win32限制。

TCustomForm
中有一个受保护的过程定义为:

procedure TCustomForm.VisibleChanging;
begin
  if (FormStyle = fsMDIChild) and Visible and (Parent = nil) then
    raise EInvalidOperation.Create(SMDIChildNotVisible);
end;
在MDI子窗口中将其覆盖为:

procedure TMDIChildForm.VisibleChanging;
begin
  // :-P
end;

在阅读了Jeroen的评论后,我尝试了另一种同样有效的解决方案,但有点闪烁:

procedure TMDIChildForm.VisibleChanging;
begin
  if Visible then
    FormStyle := fsNormal
  else
    FormStyle := fsMDIChild;
end;
也许这适用于所有Windows版本


PS:我没有发现Windows 2k3SP2 x86和Windows 7 Ultimate x86上的第一个解决方案有任何问题当我单击红十字时,默认行为是最小化Delphi中的mdi子窗口。我想把窗户藏起来。伊曼:说得好。现在我明白你的意思了。你不想最小化,也不想破坏。您希望暂时隐藏它,以便以后可以再次显示它。我不知道这是否可能。[显而易见的解决方案是销毁它,然后在需要时创建一个新的类似窗口。]@AndreasRejbrand我不想销毁并重新创建一个类似的窗口,因为每个子窗口都会加载一些库,打开一个串行端口,以及一些其他需要几秒钟的初始化内容。因此,我在启动时创建所有子窗体,使用
ShowWindow
隐藏它们,具有讽刺意味的是,它在那里工作,当用户选择一个窗体时显示它们,并希望在用户关闭时再次隐藏它们them@iManBiglari:如果将所有组件和相应代码移动到每个MDI子窗口的数据模块中,并将MDI子窗口视为简单视图(可以随意打开和关闭),则无需与MDI Windows子系统对抗。我敢说这样的改变也会改善程序设计。@mghie我不明白为什么需要数据模块来实现这种分离。我想这样可以省去编写实例化组件的样板代码,但我从未发现这一点特别引人注目。但mdi子窗口为什么会抵制
ShowWindow()
API调用?因为这样的窗口不是设计为隐藏的?我相信Andreas是正确的,但我不确定为什么会做出这样的设计决定。毫无疑问,您已经尝试调用
Hide
,然后在VCL引发“无法隐藏MDI子窗口”错误时放弃。但这是VCL告诉您这是不受支持的方式。@DavidHeffernan我在VCL.Forms.pas`中瞥了一眼,发现了这个过程:
procedure TCustomForm.VisibleChanging;开始if(FormStyle=fsMDIChild)和Visible and(Parent=nil),然后引发EInvalidOperation.Create(SMDIChildNotVisible);结束我在mdi子窗体中覆盖了它,并且我的窗体第一次被隐藏。但第二次它又把自己最小化了。所以我想我走对了不,我不这么认为。这个例外是因为MDI和隐藏子窗体不混合。删除引发异常的代码不会改变这一基本问题。Windows中的MDI支持包含许多错误(至少在90年代我看到这些错误时是这样),这些错误在Microsoft的“无法修复”列表中。这是几乎没有任何看起来像MDI的Microsoft应用程序实际使用Windows MDI代码的原因之一。VisibleChanging正在阻止这些bug露出丑陋的头部。所以你的建议可能会导致你的应用程序在某些版本的Windows上失败。@JeroenviertLuimers然后看看另一个答案。也许这将绕过所有这些bug+1;另一个答案(设置
FormStyle
)确实可以绕过这些bug。我敢肯定,从Windows3.0到Windows2000,这些漏洞都存在。之后,我只使用SDI和Outlook风格的应用程序。我会在所有目标操作系统版本上广泛测试解决方案1。如果成功的话,我会说去做。我的猜测是
TCustomForm.VisibleChanging
背后的原因在时间的深处消失了。也许你可以在Emba论坛上问一下,看看以前的Emba开发人员是否还记得原因。我甚至经常在工业领域看到DOS、Windows95和WindowsNT4解决方案。大多数都是与机械接口的独立系统。