2013-05-23 34 views
6

Tôi có một ứng dụng WPF C#. Tôi có màn hình kép và tôi muốn hủy sự kiện chuột trên một trong các màn hình vì đây là màn hình cảm ứng và lấy nét ở màn hình chính khi người dùng nhấn nó. Tôi chỉ muốn kích hoạt tính năng chạm khi yêu cầu dữ liệu từ người dùng và sau đó chặn nó.Tắt các sự kiện Thiết bị Chuột Màn hình Sử dụng setwindowshookex (user32.dll)

Tôi đã tìm thấy một số ví dụ điển hình về móc ứng dụng bằng cách sử dụng user32.dll, giúp tôi nắm bắt đầu vào của thiết bị. Một ví dụ hiển thị ở đây: http://www.pinvoke.net/default.aspx/user32.setwindowshookex. Và một tùy chọn khác phù hợp hơn với các sự kiện chuột có thể được hiển thị tại đây: How to avoid mouse move on Touch

Vấn đề của tôi không phải là bắt đầu nhập thiết bị nhưng vô hiệu hóa nó. Ví dụ đầu tiên ở trên cho thấy cách bắt đầu bàn phím và trích xuất phím, nhưng không tắt nó.

Ví dụ thứ hai cũng không hoạt động. Nó bắt cả hai sự kiện chuột, thiết bị chuột usb thông thường và thiết bị màn hình cảm ứng. Tôi có thể biết cái nào, nhưng tôi không thể hủy thiết bị màn hình cảm ứng. Trong ví dụ này, một new IntPtr(1); được trả lại cho thiết bị cảm ứng. Điều này không có gì với đầu vào của thiết bị.

Mặt khác, khi tôi làm ngược lại, có nghĩa là trả về IntPtr mới (1); trên mọi sự kiện chuột NHƯNG sự kiện cảm ứng, có vẻ như con chuột thông thường của tôi không di chuyển chút nào (trong khi con chuột của thiết bị cảm ứng di chuyển).

Phương pháp này có thể giúp chặn chuột thông thường, nhưng không phải chuột cảm ứng, vì không có mã tôi trả về sẽ chặn con chuột này (tôi tìm thấy con chuột này và trả về mã, tôi đã kiểm tra nhiều lần).

Đây là mã của tôi dựa trên các ví dụ trên:

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

Trả lời

2

Nếu mục tiêu chính của bạn là để tránh sự tập trung được chuyển từ cửa sổ chính của bạn sau đó có một cách giải quyết đơn giản bằng WS_EX_NOACTIVATE

see: Not take focus, but allow interaction?

+0

đây không phải là những gì tôi cần – Programer

Các vấn đề liên quan