2013-05-23 9 views
6

Mam aplikację C# WPF. Mam podwójne ekrany i chcę anulować zdarzenie myszy na jednym z ekranów, ponieważ jest to ekran dotykowy, który wyłącza ekran główny, gdy tylko użytkownik go naciśnie. Chcę włączyć dotyk tylko przy pytaniu o dane od użytkownika, a następnie je zablokować.Wyłączanie zdarzeń urządzeń Mouse na ekranie dotykowym Korzystanie z setwindowshookex (user32.dll)

Znalazłem kilka dobrych przykładów na temat haków aplikacji za pomocą user32.dll, który pomaga mi przechwytywać dane wejściowe urządzeń. Jeden przykład pokazuje tutaj: http://www.pinvoke.net/default.aspx/user32.setwindowshookex. I jeszcze jedno, bardziej odpowiednie dla zdarzeń myszy, można pokazać tutaj: How to avoid mouse move on Touch

Mój problem polega nie na przechwytywaniu danych wejściowych urządzenia, ale na jego wyłączeniu. Pierwszy przykład powyżej pokazuje, jak wychwycić wejścia klawiatury i wyodrębnić klawisz wciśnięty, ale nie wyłączając go.

Drugi przykład nie działa tak dobrze. Łapie zarówno zdarzenia myszy, zwykłe urządzenie usb-mouse i urządzenie z ekranem dotykowym. Mogę powiedzieć, która jest która, ale nie mogę anulować urządzenia z ekranem dotykowym. W tym przykładzie zwracany jest numer new IntPtr(1); dla urządzenia dotykowego. Nie wpływa to na wejście urządzenia.

Z drugiej strony, gdy robię coś przeciwnego, oznacza to, że powracam do nowego IntPtr (1); w każdym zdarzeniu myszy, ALE zdarzenie dotykowe, wygląda na to, że moja zwykła mysz nie porusza się wcale (podczas gdy mysz urządzenia dotykowego porusza się).

Ta metoda może pomóc w blokowaniu zwykłej myszy, ale nie myszy dotykowej, ponieważ żaden kod, który zwrócę, nie zablokuje tej myszy (znalazłem tę mysz i zwróciłem kod, sprawdziłem to wiele razy. Kod nie robi nic).

Oto mój kod Bazując na powyższych przykładach:

static readonly LowLevelMouseProc hookCallback = HookCallback; 
     static IntPtr hookId = IntPtr.Zero; 

     public DisableTouchConversionToMouse() 
     { 
      hookId = SetHook(hookCallback); 
     } 

     static IntPtr SetHook(LowLevelMouseProc proc) 
     { 
      var moduleHandle = UnsafeNativeMethods.GetModuleHandle(null); 

      var setHookResult = UnsafeNativeMethods.SetWindowsHookEx(HookType.WH_MOUSE_LL, 
proc, moduleHandle, 0); 
      if (setHookResult == IntPtr.Zero) 
      { 
       throw new Win32Exception(); 
      } 
      return setHookResult; 
     } 

     delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam); 

     static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) 
     { 

      if (nCode >= 0) 
      { 
       var info = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT)); 

       var extraInfo = (uint)info.dwExtraInfo.ToInt32(); 

       // if ((extraInfo & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH) 
       if (extraInfo>0) 
       { 
       Console.WriteLine("TOUCH SCREEN FOUND!"); 
        return new IntPtr(1); 
       } 
      } 

      return UnsafeNativeMethods.CallNextHookEx(hookId, nCode, wParam, lParam); 
     } 
    public enum HookType : int 
     { 
      WH_JOURNALRECORD = 0, 
      WH_JOURNALPLAYBACK = 1, 
      WH_KEYBOARD = 2, 
      WH_GETMESSAGE = 3, 
      WH_CALLWNDPROC = 4, 
      WH_CBT = 5, 
      WH_SYSMSGFILTER = 6, 
      WH_MOUSE = 7, 
      WH_HARDWARE = 8, 
      WH_DEBUG = 9, 
      WH_SHELL = 10, 
      WH_FOREGROUNDIDLE = 11, 
      WH_CALLWNDPROCRET = 12, 
      WH_KEYBOARD_LL = 13, 
      WH_MOUSE_LL = 14 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     struct POINT 
     { 

      public int x; 
      public int y; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     struct MSLLHOOKSTRUCT 
     { 
      public POINT pt; 
      public uint mouseData; 
      public uint flags; 
      public uint time; 
      public IntPtr dwExtraInfo; 
     } 

     [SuppressUnmanagedCodeSecurity] 
     static class UnsafeNativeMethods 
     { 
      [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
      public static extern IntPtr SetWindowsHookEx(HookType code, LowLevelMouseProc lpfn, IntPtr hMod, 
       uint dwThreadId); 

      [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
      [return: MarshalAs(UnmanagedType.Bool)] 
      public static extern bool UnhookWindowsHookEx(IntPtr hhk); 

      [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
      public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, 
       IntPtr wParam, IntPtr lParam); 

      [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
      public static extern IntPtr GetModuleHandle(string lpModuleName); 
     } 

Odpowiedz