How to handle WndProc messages in WPF?

前端 未结 9 1019
不知归路
不知归路 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:18

    If you don't mind referencing WinForms, you can use a more MVVM-oriented solution that doesn't couple service with the view. You need to create and initialize a System.Windows.Forms.NativeWindow which is a lightweight window that can receive messages.

    public abstract class WinApiServiceBase : IDisposable
    {
        /// 
        /// Sponge window absorbs messages and lets other services use them
        /// 
        private sealed class SpongeWindow : NativeWindow
        {
            public event EventHandler WndProced;
    
            public SpongeWindow()
            {
                CreateHandle(new CreateParams());
            }
    
            protected override void WndProc(ref Message m)
            {
                WndProced?.Invoke(this, m);
                base.WndProc(ref m);
            }
        }
    
        private static readonly SpongeWindow Sponge;
        protected static readonly IntPtr SpongeHandle;
    
        static WinApiServiceBase()
        {
            Sponge = new SpongeWindow();
            SpongeHandle = Sponge.Handle;
        }
    
        protected WinApiServiceBase()
        {
            Sponge.WndProced += LocalWndProced;
        }
    
        private void LocalWndProced(object sender, Message message)
        {
            WndProc(message);
        }
    
        /// 
        /// Override to process windows messages
        /// 
        protected virtual void WndProc(Message message)
        { }
    
        public virtual void Dispose()
        {
            Sponge.WndProced -= LocalWndProced;
        }
    }
    

    Use SpongeHandle to register for messages you're interested in and then override WndProc to process them:

    public class WindowsMessageListenerService : WinApiServiceBase
    {
        protected override void WndProc(Message message)
        {
            Debug.WriteLine(message.msg);
        }
    }
    

    The only downside is that you have to include System.Windows.Forms reference, but otherwise this is a very encapsulated solution.

    More on this can be read here

提交回复
热议问题