How to handle WndProc messages in WPF?

前端 未结 9 1015
不知归路
不知归路 2020-11-22 10:46

In Windows Forms, I\'d just override WndProc, and start handling messages as they came in.

Can someone show me an example of how to achieve the same thi

9条回答
  •  醉酒成梦
    2020-11-22 11:02

    Here is a link on overriding WindProc using Behaviors: http://10rem.net/blog/2010/01/09/a-wpf-behavior-for-window-resize-events-in-net-35

    [Edit: better late than never] Below is my implementation based on the above link. Although revisiting this I like the AddHook implementations better. I might switch to that.

    In my case I wanted to know when the window was being resized and a couple other things. This implementation hooks up to the Window xaml and sends events.

    using System;
    using System.Windows.Interactivity;
    using System.Windows; // For Window in behavior
    using System.Windows.Interop; // For Hwnd
    
    public class WindowResizeEvents : Behavior
        {
            public event EventHandler Resized;
            public event EventHandler Resizing;
            public event EventHandler Maximized;
            public event EventHandler Minimized;
            public event EventHandler Restored;
    
            public static DependencyProperty IsAppAskCloseProperty =  DependencyProperty.RegisterAttached("IsAppAskClose", typeof(bool), typeof(WindowResizeEvents));
            public Boolean IsAppAskClose
            {
                get { return (Boolean)this.GetValue(IsAppAskCloseProperty); }
                set { this.SetValue(IsAppAskCloseProperty, value); }
            }
    
            // called when the behavior is attached
            // hook the wndproc
            protected override void OnAttached()
            {
                base.OnAttached();
    
                AssociatedObject.Loaded += (s, e) =>
                {
                    WireUpWndProc();
                };
            }
    
            // call when the behavior is detached
            // clean up our winproc hook
            protected override void OnDetaching()
            {
                RemoveWndProc();
    
                base.OnDetaching();
            }
    
            private HwndSourceHook _hook;
    
            private void WireUpWndProc()
            {
                HwndSource source = HwndSource.FromVisual(AssociatedObject) as HwndSource;
    
                if (source != null)
                {
                    _hook = new HwndSourceHook(WndProc);
                    source.AddHook(_hook);
                }
            }
    
            private void RemoveWndProc()
            {
                HwndSource source = HwndSource.FromVisual(AssociatedObject) as HwndSource;
    
                if (source != null)
                {
                    source.RemoveHook(_hook);
                }
            }
    
            private const Int32 WM_EXITSIZEMOVE = 0x0232;
            private const Int32 WM_SIZING = 0x0214;
            private const Int32 WM_SIZE = 0x0005;
    
            private const Int32 SIZE_RESTORED = 0x0000;
            private const Int32 SIZE_MINIMIZED = 0x0001;
            private const Int32 SIZE_MAXIMIZED = 0x0002;
            private const Int32 SIZE_MAXSHOW = 0x0003;
            private const Int32 SIZE_MAXHIDE = 0x0004;
    
            private const Int32 WM_QUERYENDSESSION = 0x0011;
            private const Int32 ENDSESSION_CLOSEAPP = 0x1;
            private const Int32 WM_ENDSESSION = 0x0016;
    
            private IntPtr WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, ref Boolean handled)
            {
                IntPtr result = IntPtr.Zero;
    
                switch (msg)
                {
                    case WM_SIZING:             // sizing gets interactive resize
                        OnResizing();
                        break;
    
                    case WM_SIZE:               // size gets minimize/maximize as well as final size
                        {
                            int param = wParam.ToInt32();
    
                            switch (param)
                            {
                                case SIZE_RESTORED:
                                    OnRestored();
                                    break;
                                case SIZE_MINIMIZED:
                                    OnMinimized();
                                    break;
                                case SIZE_MAXIMIZED:
                                    OnMaximized();
                                    break;
                                case SIZE_MAXSHOW:
                                    break;
                                case SIZE_MAXHIDE:
                                    break;
                            }
                        }
                        break;
    
                    case WM_EXITSIZEMOVE:
                        OnResized();
                        break;
    
                    // Windows is requesting app to close.    
                    // See http://msdn.microsoft.com/en-us/library/windows/desktop/aa376890%28v=vs.85%29.aspx.
                    // Use the default response (yes).
                    case WM_QUERYENDSESSION:
                        IsAppAskClose = true; 
                        break;
                }
    
                return result;
            }
    
            private void OnResizing()
            {
                if (Resizing != null)
                    Resizing(AssociatedObject, EventArgs.Empty);
            }
    
            private void OnResized()
            {
                if (Resized != null)
                    Resized(AssociatedObject, EventArgs.Empty);
            }
    
            private void OnRestored()
            {
                if (Restored != null)
                    Restored(AssociatedObject, EventArgs.Empty);
            }
    
            private void OnMinimized()
            {
                if (Minimized != null)
                    Minimized(AssociatedObject, EventArgs.Empty);
            }
    
            private void OnMaximized()
            {
                if (Maximized != null)
                    Maximized(AssociatedObject, EventArgs.Empty);
            }
        }
    
    
    
        
            
        
    
        ... 
    
    
    

提交回复
热议问题