WPF:如何区分Window.Close()调用和系统菜单关闭操作?

可能重复:
如何在关闭处理程序中区分“窗口关闭按钮单击(X)”与window.Close()

在WPF中,以下是关闭Window不同方法:

1) Window.Close()
2)从Window系统菜单中选择’Close’(左上角)
3)单击窗口标题栏上的“X”按钮(右上角)
4)键盘快捷键:Alt + F4

所有这些操作都会触发WPF事件Window.Closing

我如何区分这两种类型的行为?

在Excel / VBA中,这是可能的: VBA.VbQueryClose.vbFormCode vs VBA.VbQueryClose.vbFormControlMenu

这个相关的问题/答案说系统菜单操作将生成Windows事件WM_CLOSE 。 也许有一种方法可以从WPF中看到底层的Windows事件。

您可以调用HwndSource.AddHook来处理Win32消息以获取Window的原因。 就像是:

 Window myWindow = new Window(); myWindow .Loaded += delegate { HwndSource source = (HwndSource)PresentationSource.FromDependencyObject(myWindow ); source.AddHook(WindowProc); }; 

而WindowProc的实现:

  private static IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled){ switch (msg) { case: 0x10: Console.WriteLine("Close reason: Clicking X"); case 0x11: case 0x16: Console.WriteLine("Close reason: WindowsShutDown"); break; case 0x112: if (((ushort)wParam & 0xfff0) == 0xf060) Console.WriteLine("Close reason: User closing from menu"); break; } return IntPtr.Zero; } 

并且您有所有Windows消息的列表

WM_SYSCOMMND的wParam值

希望这可以帮助。

一个简单的选择是在调用Window.Close之前设置一些标志。

当然,按Alt +F4也可能会发生这种情况;
如果您正在处理鼠标事件,那么检查并查看鼠标是哪个元素。