【问题标题】:How to get the topmost window if it is modal and inactive如果它是模态且非活动的,如何获取最顶层的窗口
【发布时间】:2017-10-20 17:35:09
【问题描述】:

我想防止用户在同一台​​机器上多次运行我的应用程序,所以我使用了来自该线程的解决方案:What is the correct way to create a single-instance application?

这工作正常,但在打开模式窗口时显示我的应用程序时出现问题(例如使用view.ShowDialog();)。这是一个场景:

  1. 用户运行我的应用程序并打开一个模式窗口。
  2. 然后他再次尝试运行我的应用程序,该应用程序的第二个实例的启动过程中的代码发现另一个正在运行的应用程序并向其广播 WM_SHOWME 消息以显示它自己。然后应用程序的第二个实例终止。
  3. 第一个应用程序接收到 WM_SHOWME 消息(使用来自How to handle WndProc messages in WPF? 的解决方案)。现在它应该把最顶层的窗口放在前面,这是我的问题——如果最顶层的窗口是模态的,甚至没有激活,我怎么能得到我的应用程序的最顶层窗口?我尝试了Refer to active Window in WPF? 的解决方案,但当然我的窗口没有激活,所以这不起作用。

PS - 当应用程序正在运行并打开一个模式窗口并且当我将鼠标悬停在任务栏中的图标上时,我可以看到两个窗口 - 主窗口和一个模式窗口。我可以单击主窗口(这当然是禁用的,因为它上面有一个模态窗口),我也可以单击模态窗口。我的解决方案就像我单击主窗口一样工作,但我希望它能够激活最上面的窗口,在这种情况下是模态的。

那么,知道如何将最顶部的模态窗口(或主窗口,如果没有显示模态窗口)放在前面吗?

【问题讨论】:

  • 嗯,任务栏是否有意同时显示主窗口的图标和模式窗口(对话框)?这听起来像对话框不属于主窗口。如果您使对话框归主窗口所有,则该对话框将永远不会被主窗口覆盖。这也有这样的效果,当将主窗口带到前面时,模态窗口也将被带到前面。 (检查模态窗口的Owner property。它应该设置为主窗口。)
  • @elgonzo - 你是对的,我忘了设置 Owner 属性,谢谢!如果您发表评论作为答案,我会接受。
  • 完成了... :)

标签: c# .net wpf modal-dialog single-instance


【解决方案1】:

问题中描述的行为表明主窗口不拥有对话框。

请注意,当对话框由(主)窗口拥有时,窗口不能覆盖对话框(对话框通常始终位于窗口顶部)。 这也有这样的效果,当把窗口带到前面时,对话框也会被带到窗口顶部的前面——这很好地解决了你遇到的问题。

为您的对话框(模态窗口)设置所有者相当容易。只需在显示对话框之前将其 Owner 属性设置为您的主窗口,类似于此示例:

Window modalWindow = ... create modal window instance
modalWindow.Owner = mainWindow;
modalWindow.ShowDialog();

(旁注:如果还希望任务栏中只显示主窗口的图标/缩略图,则应将模态窗口的ShowInTaskbar属性设置为false。)

【讨论】:

  • 如前所述 - 您的解决方案有效。只是一个挑剔 - 即使您设置 Owner 属性,当您将鼠标悬停在任务栏上的图标上时,您仍然可以看到主窗口和对话框。但是 id 你点击哪个窗口并不重要,模态窗口总是在顶部。
  • @sventevit,哈哈,你是对的。模式窗口通常会显示在任务栏中。如果不需要,ShowInTaskbar 必须设置为 false。我习惯性地这样做。我猜我把我的习惯和 WPF 的习惯搞混了 :) 我马上会重写我的答案中受影响的部分......
【解决方案2】:

使您的应用程序成为给定机器上的单个实例的最佳解决方案是使用命名互斥锁

Mutex

这是同一文档的摘录

互斥体有两种类型:未命名的本地互斥体和命名的系统互斥体。本地互斥锁仅存在于您的进程中。它可以被进程中的任何线程使用,该线程引用了表示互斥体的 Mutex 对象。每个未命名的 Mutex 对象代表一个单独的本地互斥体。 命名系统互斥锁在整个操作系统中都是可见的,并且可以用于同步进程的活动。

您可以使用接受名称的构造函数来创建表示命名系统互斥体的互斥体对象。操作系统对象可以同时创建,也可以在 Mutex 对象创建之前存在。您可以创建多个 Mutex 对象来表示相同的命名系统互斥体,并且可以使用 OpenExisting 方法打开现有的命名系统互斥体。

而且,不管怎样,你已经处理了你想提出第一个实例的情况。

【讨论】:

    猜你喜欢
    • 2023-04-09
    • 2016-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多