2017-07-08 5 views
0

キープレス(たとえば、Ctrl + WinKeyまたはコンマのみ)をキャプチャします。私はWH_KEYBOARD_LLフックとGetAsyncKeyStateをC#で使用します。デバッガ(つまり、ブレークポイントが設定されていないデバッガが接続されている)で実行すると、すべて正常に動作します。しかし、デバッガなしで実行するとほとんど動作しません。ホットキーコードは呼び出されません。デバッガの下で動作するコードと同じコードです。GetAsyncKeyStateはリリースバージョンでランダムに動作します

ロギングコードを追加すると、デバッガなしでも動作することに気付きました。 これは通常、低速のPCでも動作します。

この問題を解決するにはどうすればよいですか?

フックハンドラ

private bool HotKeyHandler(WPARAM wParam, LPARAM lParam, WH_KEYBOARD_LL.KBDLLHOOKSTRUCT KeyInfo) { 

if ((WH_KEYBOARD_LL.GetAsyncKeyState(Keys.LWin) < 0 || WH_KEYBOARD_LL.GetAsyncKeyState(Keys.RWin) < 0)) { 
    if ((int)wParam == WH_KEYBOARD_LL.WM_KEYDOWN) { 
      if (WH_KEYBOARD_LL.GetAsyncKeyState(Keys.ControlKey) < 0) { 
       switch (KeyInfo.VkCode) { 
        case WH_KEYBOARD_LL.VK_OEM_COMMA: 
         // Some action - this doesn't work randomly ... 
        return true; 
... 
       } 
      } 

     } 
    } 
return false; 
} 


WH_KEYBOARD_LL.Initialize(HotKeyHandler); 

     public static void Initialize(Func<WPARAM, LPARAM, KBDLLHOOKSTRUCT, bool> Handler) { 
      HandlerI = Handler; 
      KeyboardHookProcedureHandle = NativeCalls.Hooks.SetWindowsHookEx(NativeCalls.Hooks.HookType.WH_KEYBOARD_LL, KeyboardLLHandler, IntPtr.Zero, 0); 
     } 

     private static NativeCalls.Hooks.Procedure KeyboardLLHandler = KeyboardProcedure; 

     private static LRESULT KeyboardProcedure(int MustProcessMessage, WPARAM wParam, LPARAM lParam) { 
      if (MustProcessMessage != HC_ACTION) { return NativeCalls.Hooks.CallNextHookEx(KeyboardHookProcedureHandle, MustProcessMessage, wParam, lParam); } 

      var KeyInfo = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT)); 
      return HandlerI(wParam, lParam, KeyInfo) ? (IntPtr)1 : NativeCalls.Hooks.CallNextHookEx(KeyboardHookProcedureHandle, MustProcessMessage, wParam, lParam); 
     } 

     [DllImport("user32.dll")] 
     public static extern short GetAsyncKeyState(System.Windows.Forms.Keys vKey); 

     [StructLayout(LayoutKind.Sequential)] 
     public struct KBDLLHOOKSTRUCT { 
      public DWORD VkCode; 
      public DWORD ScanCode; 
      public DWORD Flags; 
      public DWORD Time; 
      public ULONG_PTR DwExtraInfo; 
     } 

     public const int HC_ACTION = 0; 
     public const int WM_KEYDOWN = 0x0100; 
     public const int WM_KEYUP = 0x0101; 
     public const int WM_SYSKEYUP = 0x0105; 
     public const int VK_OEM_COMMA = 0xBC; 
     public const int VK_OEM_PERIOD = 0xBE; 
     public const int VK_TAB = 0x09; 
     public const int VK_ESCAPE = 0x18; 

     public const int VK_1 = 0x31; 
     public const int VK_2 = 0x32; 
     public const int VK_3 = 0x33; 
     public const int VK_4 = 0x34; 
     public const int VK_5 = 0x35; 
     public const int VK_6 = 0x36; 
     public const int VK_7 = 0x37; 
     public const int VK_8 = 0x38; 
     public const int VK_9 = 0x39; 

     public const int VK_N = 0x4E; 
     public const int VK_W = 0x57; // Virtual-Key Codes - https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx 
     public const int VK_Z = 0x5A; 

/* 
using DWORD = System.UInt32; 
using HHOOK = System.IntPtr; 
using LPARAM = System.IntPtr; 
using LRESULT = System.IntPtr; 
using ULONG_PTR = System.UIntPtr; 
using WPARAM = System.UIntPtr; 
*/ 

答えて

1

GetAsyncKeyStateから、次のコードの抜粋は、状態はあなたが気に他のキーと同期していない、右あなたがそれを呼び出す現時点での状態を取得します。あなたはすでにフックを持っているので、Ctrl & Winキーの状態をあなた自身がフックで追跡します。

関連する問題