【问题标题】:WPF Intercept global mouse movements (like using IMessageFilter in Windows Form)WPF 拦截全局鼠标移动(如在 Windows 窗体中使用 IMessageFilter)
【发布时间】:2016-09-25 21:19:32
【问题描述】:

我正在将 UserControl 从 Windows 窗体 转换为 WPF,这是我的 Windows 窗体 工作代码:

GlobalMouseHandler mouseHandler = new GlobalMouseHandler();
mouseHandler.MouseMove += OnGlobalMouseMove;
mouseHandler.MouseButtonUp += OnGlobalMouseButtonUp;

public class GlobalMouseHandler : IMessageFilter, IDisposable
{
    public event MouseMovedEvent MouseMove;
    public event MouseButtonUpEvent MouseButtonUp;

    public GlobalMouseHandler(){
        Application.AddMessageFilter(this);
    }

    public bool PreFilterMessage(ref Message m)
    {
        switch (m.Msg)
        {
            case WM_MOUSEMOVE:
                MouseMove?.Invoke();
                break;
            case WM_LBUTTONUP:
                MouseButtonUp?.Invoke();
                break;
        }
        return false;
    }
}

我使用IMessageFilter 在我的应用程序中获取鼠标移动和鼠标向上事件并附加到它们。

现在,我知道IMessageFilter is not available in WPF,但是有没有一种简单的方法可以在 WPF 中记录这些简单的鼠标事件?

【问题讨论】:

    标签: c# wpf mouseevent imessagefilter


    【解决方案1】:

    您可以类似的方式处理消息(例如鼠标移动):

    Xaml:

    <Window ... Loaded="Window_OnLoaded">
        ...
    </Window>
    

    代码隐藏:

        using System.Windows.Interop;
    
        ...
    
        private const int WM_MOUSEMOVE = 0x0200;
    
        private void Window_OnLoaded(object sender, RoutedEventArgs e)
        {
            HwndSource.FromHwnd(new WindowInteropHelper(this).Handle)?.AddHook(this.WndProc);
        }
    
        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            switch (msg)
            {
                case WM_MOUSEMOVE:
                    // MouseMove?.Invoke();
                    break;
            }
    
            return IntPtr.Zero;
        }
    

    当然,如果您不想以原生 WPF 方式进行操作(例如左键向上):

    <Window ... PreviewMouseLeftButtonUp="Window_OnPreviewMouseLeftButtonUp">
        ...
    </Window>
    
    private void Window_OnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        // e.Handled = true if you want to prevent following MouseLeftButtonUp event processing
    }
    

    【讨论】:

    • 感谢您的快速答复!我有一个问题:我没有加载一个窗口,而是一个通用的 UserControl (System.Windows.Controls),所以我不能将一个 Window 传递给 WindowInteropHelper 构造函数。有没有办法使用“当前主窗口”或类似的东西?
    • 是的,您可以在UserControl 中尝试Window.GetWindow(this)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多