2016-05-27 7 views
1

Я преобразующего UserControl из формы Windows к WPF, Вот мой Windows Formрабочий код:WPF Intercept движения глобальной мыши (как с помощью IMessageFilter в форме 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; 
    } 
} 

I использовал IMessageFilter, чтобы заставить мыши перемещаться и вызывать события в приложении и присоединяться к ним.

Теперь я знаю, что IMessageFilter is not available in WPF, но есть ли простой способ записи этих простых событий мыши в WPF?

ответ

2

Вы можете обрабатывать сообщения подобным образом (движение мыши, например):

Xaml:

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

Code-за:

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; 
    } 

Конечно, если вы не хотите (например, с левой кнопкой вверх):

<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 
} 
+0

Спасибо за быстрый ответ! У меня проблема: я не загружаю окно, а общий UserControl (System.Windows.Controls), поэтому я не могу передать окно в конструктор WindowInteropHelper. Есть ли способ использовать «текущее главное окно» или что-то в этом роде? – Rowandish

+0

Да, вы можете попробовать 'Window.GetWindow (this)' изнутри 'UserControl' – Sam