【问题标题】:Hide form when application is minimized最小化应用程序时隐藏表单
【发布时间】:2011-09-11 19:48:45
【问题描述】:

我有一个主表单和一个状态表单,当我在我的应用程序中进行工作时会显示它们。如果工作完成,我只需在状态表上调用Hide,状态表就会消失。

当我最小化主窗体而等待窗体可见时,就会出现我的问题。然后这两种形式都被隐藏了,这就是我想要的。但是,如果在主窗体最小化时工作完成,那么当我恢复它时,状态窗体也会恢复,即使在最小化时调用了Hide

Visible 似乎是False 用于应用程序最小化时的状态表单,因此调用Hide 似乎没有效果(帮助说它只是将Visible 设置为False)。

这些观察正确吗?当应用程序再次获得焦点时,表单的可见性如何恢复?如何在应用程序最小化时隐藏我的表单?

【问题讨论】:

  • 在 'CreateParams' 中覆盖 'WndParent' 用于这个显示表单?
  • +1 听起来你正在做一些非标准的窗口所有权
  • @David:不,这是一个空的 VCL 项目的工作方式。自己试试吧!
  • @so 有多少种形式,其中任何一种是模态的?
  • 我现在终于明白了这个问题,并编辑了这个问题,希望能更清楚。

标签: windows delphi delphi-xe


【解决方案1】:

警告:我不能 100% 确定以下方法是否安全。

如果您不需要相同的表单对象在应用程序的生命周期内保持活动状态(您很可能不需要),那么您可以尝试禁用弹出表单的自动创建(项目/选项)然后创建并显示它

Application.CreateForm(TForm2, Form2);
Form2.Show;

然后释放它

Form2.Release;

这样表单不可能和主表单一起恢复。

【讨论】:

  • 我不会说这是唯一正确的做事方式,但绝对是一种很常见的方式。至少,这是我们项目中大多数弹出窗口的处理方式。
  • 谢谢!由于这个对话框经常出现(大部分时间间隔很短),我宁愿只创建一次表单。
  • 也许状态窗口可能是您的主窗体的子窗体? (简而言之:在主窗体上用TPanel 替换Form2 状态窗口。)
  • 主窗体不是唯一需要这个窗体的窗体。可以是显示它的模态对话框或非模态编辑器窗口。
【解决方案2】:

显示表单的Visible 确实是假的,当应用程序最小化时调用Hide 没有任何作用,因为它作为最小化机制的一部分被应用程序隐藏了。

代码调用ShowOwnedPopups,首先在应用程序最小化时将“False”作为“bShow”,然后在应用程序恢复时将“True”作为“bShow”。由于该函数显示之前调用隐藏的所有窗口,因此更改表单的可见性 中间没有效果。

现在,请参阅函数文档的备注部分中的引用,

如果使用隐藏弹出窗口 ShowWindow 函数,随后 使用 fShow 调用 ShowOwnedPopups 参数设置为 TRUE 不会导致 要显示的窗口

因此,一种解决方案是在应用程序隐藏表单之前将其隐藏,这样在恢复时它就不会显示。但是接下来我们必须知道,当我们恢复时,显示表单是真的要隐藏还是显示。这可以通过在显示表单上放置属性或使用全局变量来实现。在下面,“ShouldBeVisible”是一个假设的属性,如果我们要显示信息,它将返回 true:

type
  TForm1 = class(TForm)
  ..
  private
    procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
  ...

procedure TForm1.WMSysCommand(var Msg: TWMSysCommand);
begin
  if (Msg.CmdType = SC_MINIMIZE) and Assigned(Form2) and Form2.Visible then
    Form2.Hide;
  inherited;
  if (Msg.CmdType = SC_RESTORE) and Assigned(Form2) and Form2.ShouldBeVisible then
    Form2.Show;
end;

【讨论】:

  • 这个想法+1。一个问题:只有主窗体接收这些事件吗?我从多种形式中使用这些,所以我想将该机制集成到状态形式本身中。似乎这个表单没有收到事件。
  • 刚刚尝试在主窗体中捕获事件。不幸的是,当我在 Windows 7 上重新打开窗口时,我的主窗体不会触发 SC_RESTORE
  • @Smasher - 我觉得有点奇怪,窗口应该已经恢复以响应 WM_SYSCOMMAND。我想知道窗口是否收到包含 SC_RESTORE 变体的消息。您是否愿意按照WM_SYSCOMMAND 的备注部分中的说明使用 $FFF0 对消息的 wParam 进行“按位和”? “ApplicationEvents”的“OnRestore”事件会起作用吗?
  • 是的,Application.OnRestore 按预期工作。如果您单击 Windows 7 中的任务栏图标,SC_MINIMIZE 不会触发(这实际上也是最小化)。请参阅我的答案以了解适合我的解决方案。感谢您的帮助!
【解决方案3】:

我现在使用以下适合我的解决方案:

  1. Application.OnRestore 恢复事件处理程序中,我调用StatusForm.NotifyRestored。如果状态表单不可见,则显式隐藏它。
  2. 在我的状态表单中,我在布尔字段FShouldDisplay 中跟踪可见性。这是在 ShowStatusFormHideStatusForm 方法中设置的。

procedure TMainForm.OnApplicationRestore(Sender : TObject);
begin
StatusForm.NotifyRestored;
end;

procedure TStatusForm.NotifyRestored;
begin
if not FShouldDisplay then
  ShowWindow(Handle, SW_HIDE);
end;

procedure TStatusForm.ShowStatusForm;
begin
FShouldDisplay := True;
Show;
end;

procedure TStatusForm.HideStatusForm;
begin
FShouldDisplay := False;
Hide;
end;

【讨论】:

  • 既然您解决了 ApplicationEvents 组件的问题,我想知道该组件是否可以在状态表单本身上工作..
  • @Sertac:你说得对,这样可以节省我的委托部分。谢谢,我试试看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-07
  • 1970-01-01
  • 2019-06-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多