How to distinguish 'Window close button clicked (X)' vs. window.Close() in closing handler

前端 未结 2 1232
旧巷少年郎
旧巷少年郎 2020-12-19 02:03

Is there a clever way to detect whether a window was closed by

  • A user pressing the (X) button in the upper right corner of the window or
  • window.Close(
2条回答
  •  轮回少年
    2020-12-19 02:43

    The difference is the following:

    Window.Close() causes WM_CLOSE to be send to window.

    Alt+F4 and X button causes WM_SYSCOMMAND message with SC_CLOSE type. You can decide if you wish to route this message further ( and cause WM_CLOSE in the end ).

    Here's a piece of code to catch this message. Return "True" from delegate if you wish to cancel default behaviour:

    class SystemMenu : IDisposable
    {
        const int WM_SYSCOMMAND = 0x0112;
        const int SC_CLOSE = 0xF060;
    
        public delegate bool HandleSystemCommand();
        HwndSource _source;
        HandleSystemCommand _handler;
    
        public SystemMenu(Window window, HandleSystemCommand handler )
        {
            _handler = handler;
            _source  = HwndSource.FromHwnd(new WindowInteropHelper( window ).Handle);
            _source.AddHook(WndProc);
        }
    
        public void Dispose() {
            _source.RemoveHook(WndProc);
        }
    
        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            switch (msg)
            {
                case WM_SYSCOMMAND:
                    int command = wParam.ToInt32() & 0xfff0;
                    if (command == SC_CLOSE)
                        handled = _handler();
                    break;
                default:
                    break;
            }
            return IntPtr.Zero;
        }
    }
    

提交回复
热议问题