【问题标题】:How can I Activate/Focus a Modal Form如何激活/聚焦模态表单
【发布时间】:2013-08-08 17:56:36
【问题描述】:

我有一个带有TTrayIcon 组件的应用程序,我用它来“隐藏”和“恢复”我的 MainForm。这是我用来“隐藏”的(OnTrayClick)

procedure TMainWindow.TrayIcon1Click(Sender: TObject);
var
  I : Integer;
begin
  if Application.MainForm.Visible then begin
    { Hide }
    Application.MainForm.Visible := FALSE;
  end else begin
    { Restore }
    Application.MainForm.Visible := TRUE;
    WindowState := wsNormal;
    Application.BringToFront();
    { Workaround for ModalForms }
    for I := 0 to Screen.FormCount-1 do begin
      if (fsModal in Screen.Forms[I].FormState) then begin
        Screen.Forms[I].BringToFront;
        Screen.Forms[I].SetFocus;
        break; // Stop looking for more ModalForms
      end;
    end;
  end;
end;

如果没有打开其他(模态)表单,则此示例可以正常工作。 但是如果有一个 ModalForm 打开并恢复我的 MainForm,ModalForm 似乎在 MainForm 后面,我无法访问它。恢复 MainForm 后,如何激活/聚焦 ModalForm 并将其放在 MainForm 前面?我的Application.MainFormOnTaskbar 设置为False

编辑: 如果一个 ModalForm 打开并且我恢复了我的 MainForm,那么这两个表单都不会聚焦。

【问题讨论】:

  • @KenWhite 对不起。我改变了我的问题。 Restore 是错误的术语。我不隐藏任何模态表单。
  • 本杰明,这更清楚了。我将删除我的 cmets,因为它们不再适用。 :-)
  • 为什么 MainFormOnTaskbar 是假的?
  • @DavidHeffernan 因此,当它“最小化”到托盘时,我可以将其从任务栏中删除。
  • 没有。您将 MainFormOnTaskbar 设置为 True,并通过隐藏表单从任务栏中删除按钮。就像我们在上一个问题中所做的那样。

标签: delphi vcl delphi-xe4


【解决方案1】:

MainFormOnTaskbar 的设置似乎是导致问题的原因。您确实需要将其设置为 true。

如果有模态窗口,您可以选择不隐藏任何表单。在这种情况下,请检查隐藏代码中的 Application.ModalLevel > 0。您甚至可以显示一个气球提示,说明在关闭消息之前无法最小化应用程序。

否则,如果您真的想最小化所有窗口,下面的代码对我来说效果很好。隐藏所有打开的窗口,包括模态窗口。这将导致主任务栏图标消失,一切都在屏幕外。您需要做的一件事是跟踪哪些窗口刚刚打开。我通过在刚刚隐藏的表单上设置标签值来做到这一点。然后在恢复代码中,您可以将这些窗口的可见性设置回 true。

唯一没有处理的情况是隐藏主窗口但让模态窗口可见。我不确定您为什么要这样做,而且我个人会觉得作为用户感到困惑。

procedure TForm1.TrayIcon1Click(Sender: TObject);
var
  I : Integer;
begin

  if Application.MainForm.Visible then
  begin
    //  Hide
    for I := 0 to Screen.FormCount-1 do
    begin
      if Screen.Forms[i].Visible = true then
      begin
        Screen.Forms[i].Visible := false;
        Screen.Forms[i].Tag := 1;
      end;
    end;

  end
  else
  begin
    // Restore
    for I := 0 to Screen.FormCount-1 do
    begin
      if Screen.Forms[i].Tag = 1 then
      begin
        Screen.Forms[i].Visible := true;
        Screen.Forms[i].Tag := 0;
      end;
    end;

    Application.BringToFront();

  end;
end;

您可能需要将模态表单上的 PopupParent 属性设置为您的主表单。对于新表单,这设置为 pmAuto,但如果这是一个旧项目,它可能是 pmNone。

这是 Allen 在 PopupMode and PopupParent 上的博客文章的链接,这是另一个 Stackoverflow 问题,涉及主题 Newly created modal window loses focus and become inacessible in Windows Vista

我通常使用这样的东西:

MyPopupForm := TMyForm.Create(Owner);
MyPopupForm.PopupMode := pmAuto;
MyPopupForm.PopupParent := Owner;
MyPopupForm.ShowModal;

【讨论】:

  • 我试过了,但似乎不起作用。重新创建我的示例。也许这是一个 XE4 缺陷?!
  • 这是问题所在,这将是令人惊讶的。 pmAuto 肯定会得到相同的最终结果。
  • @Mark 通过隐藏表单来移除任务栏按钮。改变窗口样式不是办法。
  • @DavidHeffernan 由于 Benjamin 将 Application.MainFormOnTaskbar 设置为 False 我假设他不想要任务栏上的图标,即使表单可见。
  • @Mark 这不是该属性的作用。它确定任务栏上的按钮是与主窗体相关联,还是与隐藏的应用程序窗口相关联。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-05
  • 2018-10-21
  • 2021-05-08
  • 2011-09-13
  • 2014-12-20
相关资源
最近更新 更多