我有一个带有多个无关Windows的WPF应用程序,即总有一个MainWindow和可选的许多其他没有所有者的。 如果这些窗口在任务栏中分组,则窗口将在任务栏上下文菜单中提供“关闭所有Windows”操作。 如果单击它,我的应用程序的每个窗口都会按照我无法控制的顺序获得单独的关闭命令。
问题: 如果可以取消挂起的更改,我的一些窗口可能会在关闭之前询问。如果有很多这样的话,这很令人讨厌和困惑。
我想要的是:如果要求关闭MainWindow,我想提示一次,如果没关系的话。如果是,所有窗口应该静默关闭,否则保持打开状态。 但我的MainWindow不是第一个处理结束程序的人。
我已经发现,我可能需要使用wparam SC_CLOSE检查我的MainWindow的Windows消息循环中的某些WM_SYSCOMMAND。 (见How can I distinguish between "Close All Windows" and "Close" individual windows in MFC with Windows 7?)
但是,在执行任何其他窗口的结束例程之前,我该如何评估呢?
在我的主窗口中ComponentDispatcher.ThreadPreprocessMessage
来得太晚了,它在其他窗口开始关闭程序后触发。
这个问题与此有关: Odd form closing behavior when using taskbar's Close All Windows
答案 0 :(得分:2)
就个人而言,我会把事情保留原样。我可以看到有几个提示保存/取消更改可能很烦人,但它似乎并不让我感到困惑。虽然很烦人,但这似乎是一个小麻烦,坦率地说,它可能教会用户不要使用"关闭所有窗口"当他们把一堆这些窗户打开时,选项。那说......
正如您所发现的问题所指出的那样,没有内置的方法来区分"关闭所有窗口"来自常规"关闭窗口"命令。系统只是按顺序将消息发送到窗口。
在MFC中(即其他问题的上下文),您可以调用AfxGetCurrentMessage()
来检索有关实际发起SC_CLOSE
消息的内容的信息。如果是转换为关闭命令的用户输入,则会有某种类型的用户输入(键盘,鼠标等)作为当前消息。否则,您只会看到WM_SYSCOMMAND
本身。
但是你不能在WPF中应用相同的方法,因为WPF不提供GetCurrentMessage()
方法或其等价方法(据我所知)。您获得的窗口消息的唯一访问权是覆盖Control.WndProc()
方法,当您获得关闭命令时,最新的窗口消息将始终为SC_CLOSE
。
在我看来,您可以做的最好的事情是使用WndProc()
覆盖来跟踪传入的消息,以便在非关闭命令消息进入时重置标记。
然后,当您获得关闭命令并显示用户提示时,您可以检查该标志。如果设置为true,则可以忽略该提示,只使用最近选择的用户。由于您在非关闭命令消息进入时都会清除该标志,因此收到的第一个关闭命令将始终显示提示。
另一种选择是先发制人地关闭所有剩余的窗户。在这里你仍然有提示有某种"适用于所有其他窗口"用户的选项,但您可以实际上明确地关闭所有其他窗口,而不是仅仅依赖于标志的设置。
从用户界面的角度来看,这些都不是理想的。主要问题是当用户尝试关闭一个窗口时。在第一种方法中,用户将看到"适用于所有其他窗口"即使没有任何其他窗口关闭,提示中的选项也会出现。第二种方法更加自我一致,但添加了一个您可能想要或不想要的功能:用户可以在关闭一个窗口时关闭程序中的所有窗口。
这些行为都不是标准的Windows用户界面行为。即在试图为用户节省一些烦恼(和混淆,虽然就像我说的那样,我不认为那部分是这样的),你介绍了本身可能会让用户感到困惑的事情。
鉴于它涉及额外的工作编码,并且可能只是将一个恼人/混乱的结果交换给另一个,最好的解决办法可能就是根本不试图解决问题。