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

kev*_*rpe 4 .net c# wpf xaml

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

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

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

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

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

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

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

MBe*_*Ben 6

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

Window myWindow = new Window();
myWindow .Loaded += delegate
{
    HwndSource source = (HwndSource)PresentationSource.FromDependencyObject(myWindow );
    source.AddHook(WindowProc);
};
Run Code Online (Sandbox Code Playgroud)

并且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;
    }
Run Code Online (Sandbox Code Playgroud)

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

WM_SYSCOMMND的wParam值

希望这可以帮助.