2012-07-06 5 views
2

[편집] 여기까지 마우스 입력 처리에 대해 수집 한 내용이 있습니다. 1) 마우스 이벤트는 마우스 이동으로 발생합니다. 2) SetWindowsHookEx (WH_MOUSE_LL) 처리기 LowLevelMouseProc가 먼저 이벤트를 확인합니다. 3) OS/app 프레임 워크는 일부 상위 레벨에서 마우스 이벤트를 처리합니다 (마우스 커서 이동) 4) WM_INPUT 이벤트는 앱 이벤트 대기열에 의해 선택되고 WndProc에 의해 처리됩니다 (이 시점에서 처리하면 3 단계에서 마우스 커서가 이동하지 않습니다). 5) 메시지가 ComponentDispatcher 을 통해 전달됩니다. 6) PreviewMouseMove 및 MouseMove 이벤트가 트리거되어 앱에서 처리 할 수 ​​있습니다.내 WPF 앱에서 WndProc가 WM_INPUT 이벤트를 처리하지 않습니다.

이것을 바탕으로 마우스 커서가 이동하지 않도록하는 유일한 방법은 WH_MOUSE_LL을 통해 필터링하는 것입니다. 물론이 포스트의 앞부분에서 언급했듯이이 마우스 이벤트가 어느 장치에서 발생하는지 알기에는이 시점에서 정보가 충분하지 않으므로 필자의 요구 사항을 충족시키지 못하거나 전혀 필터링하지 않습니다.


내가 WH_MOUSE_LL를 후킹 핸들러에서보다 큰 값 0을 반환하여 이벤트를 제거 할 수있어 것을 확인했습니다 [편집]. 이제 WH_MOUSE_LL 수준에서 생성 된 마우스 이벤트를 내 장치에서 오는 이벤트와 일치시키는 방법을 알아야합니다. ...

WndProc에서 0보다 큰 값을 반환하려고 시도했습니다. 이벤트는 여전히 내 앱에서 처리되었습니다.


기계식 USB 마우스의 Y 축을 기반으로하는 회전식 입력 장치를 통합하려고합니다. 이 장치가 원시 입력 장치로만 작동하고 장치에서 생성 된 일반적인 마우스 이동 이벤트 (적어도 응용 프로그램과 관련하여)를 삭제하려고합니다.

지금까지 WndProc을 WindowIteropHandler 및 AddHook을 사용하여 WPF 응용 프로그램 MainWindow에 연결할 수있었습니다. WM_INPUT 이벤트를 수신하고 내 특정 USB VID/PID 장치에서 마우스 이벤트에 대한 필터를 필터링 할 수 있습니다 (필자의 요구에 충분 함).

메시지를 처리 ​​된 것으로 표시하고 0을 반환하면 메시지가 나머지 WPF 창으로 전파되지 않을 것으로 예상되지만, 그렇지는 않습니다 ... 이동하면 MouseMove 이벤트가 계속 발생합니다. 나의 기기. 여기에 내 코드의합니다 (WM_INPUT 메시지를 처리 ​​제거하는 간단하지만 여전히 같은 문제를 전시) :

public partial class MainWindow : Window 
{ 
    private const int WM_INPUT = 0x00FF; 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    public IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
    { 
     if (msg == WM_INPUT) 
     { 
      // TODO - figure out why this doesn't halt further processing of this handled event 
      handled = true; 
     } 
     return IntPtr.Zero; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    internal struct RAWINPUTDEVICE 
    { 
     [MarshalAs(UnmanagedType.U2)] 
     public ushort usUsagePage; 
     [MarshalAs(UnmanagedType.U2)] 
     public ushort usUsage; 
     [MarshalAs(UnmanagedType.U4)] 
     public int dwFlags; 
     public IntPtr hwndTarget; 
    } 

    private const int RIDEV_INPUTSINK = 0x00000100; 

    [DllImport("User32.dll")] 
    extern static bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevice, uint uiNumDevices, uint cbSize); 

    private void Window_SourceInitialized(object sender, EventArgs e) 
    { 
     WindowInteropHelper helper = new WindowInteropHelper(this); 
     HwndSource source = HwndSource.FromHwnd(helper.Handle); 
     RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[1]; 

     rid[0].usUsagePage = 0x01; 
     rid[0].usUsage  = 0x02; 
     rid[0].dwFlags  = RIDEV_INPUTSINK; 
     rid[0].hwndTarget = source.Handle; 
     RegisterRawInputDevices(rid, (uint)rid.Length, (uint)Marshal.SizeOf(rid[0])); 

     source.AddHook(WndProc); 
    } 

    private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     e.Handled = true; 
    } 

    private void button1_MouseMove(object sender, MouseEventArgs e) 
    { 
     e.Handled = true; 
    } 
} 

누구나 큐에서 제거하거나 내가 MainWindow를 전파되는 것을의 WndProc에서 처리 한 마우스 이벤트를 차단하는 방법을 알고 ?

TIA! 내가 기대했다 http://oblita.com/Interception

내가하지 않았을 : 다른 사람이 이미 설명과 나는 UMDF를 사용하여이 작업을 수행하기 위해 노력하고있어 해결 것처럼

- 매트

인터넷 검색의 긴 시간 후
+0

MainWindow에서 PreviewMouseMove를 사용하고'e.Handled = true'를 설정하는 방법은 어떻습니까? – Michael

+0

감사합니다. PreviewMouseMove 이벤트를 처리하면 모든 마우스 이벤트를 필터링 할 수 있다고 생각합니다.나는 여전히 일반적인 마우스 이벤트를 처리하고 싶지만 특정 마우스 장치에서 오는 이벤트를 필터링합니다. – Matt

+0

아, 맞아요. 나는 RawInputDevice를 사용하여 몇 시간 전에 여러 개의 마우스를 사용하여 작업을 수행했습니다. 내가 그것을 다시 파낼 수 있는지 알 것이다. – Michael

답변

2

, 그것은 보인다 거기로 가야하지만, 특정 장치에서 오는 이벤트를 실제로 가로 챌 수있는 유일한 방법 인 것처럼 보입니다.

+0

나는 몇 달 동안 내 머리를 두드리고 있었고 당신과 같은 도로 블록에 도착했습니다. 나는 그들을 일치시키기 위해 이벤트를 대기열에 넣으려고했으나 작동하지 않을 것이 확실하므로이 스레드를 읽었 기 때문에 기쁩니다. 나는 희망이있다. 당신이 제공 한 링크가 내가 찾고있는 대답 일 것이다 - 확실히 가장 가까운 것이 지금까지있다. – ChronoFish