2013-05-23 15 views
6

Ho un'applicazione C# WPF. Ho due schermi e voglio annullare l'evento del mouse su uno degli schermi, poiché si tratta di uno schermo tattile e sposta lo stato attivo fuori dalla schermata principale quando un utente lo preme. Voglio abilitare il tocco solo quando chiedi i dati all'utente e poi lo blocco.Disattivazione degli eventi del dispositivo Touch Screen per il mouse Utilizzo di setwindowshookex (user32.dll)

Ho trovato alcuni buoni esempi di hook dell'applicazione utilizzando user32.dll, che mi aiuta a catturare l'input dei dispositivi. Un esempio mostra qui: http://www.pinvoke.net/default.aspx/user32.setwindowshookex. E un altro, che è più adatto per gli eventi del mouse può essere mostrato qui: How to avoid mouse move on Touch

Il mio problema non è quello di catturare l'input del dispositivo, ma con disabilitarlo. Il primo esempio sopra mostra come catturare gli input da tastiera ed estrarre il tasto premuto, ma non disabilitarlo.

Il secondo esempio non funziona pure. Cattura sia gli eventi del mouse, il normale dispositivo mouse USB e il dispositivo touch screen. Posso dire quale è quale, ma non posso cancellare il dispositivo touch-screen. Nell'esempio, viene restituito un new IntPtr(1); per il dispositivo touch. Questo non fa nulla per l'input del dispositivo.

D'altra parte, quando faccio il contrario, vale a dire il ritorno nuova IntPtr (1); su ogni evento del mouse MA l'evento di tocco, sembra che il mio mouse normale non si muova affatto (mentre il mouse del dispositivo touch si muove).

Questo metodo può aiutare a bloccare il mouse normale, ma non il touch mouse, poiché nessun codice restituisco bloccherà questo mouse (trovo questo mouse e restituisco un codice, l'ho controllato molte volte, Il codice non fa nulla).

Ecco il mio codice basato sugli esempi di cui sopra:

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

risposta

2

Se il vostro obiettivo principale è quello di evitare l'attenzione viene spostata dalla finestra principale di poi c'è una soluzione più semplice utilizzando WS_EX_NOACTIVATE

vedi: Not take focus, but allow interaction?

+0

questo non è quello che mi serve – Programer