2012-03-12 23 views
0

我需要製作某種虛擬鍵盤,將鍵盤信號發送到其他應用程序,但我無法模擬組合鍵。任何WM_KEYDOWN或WM_KEYUP消息均可用作keydown和keyup。我發現了WM_HOTKEY消息,但它沒有任何作用。怎麼了?winapi postmessage WM_HOTKEY

if (shift) 
    mod |= MOD_SHIFT; 
if (control) 
    mod |= MOD_CONTROL; 
if (alt) 
    mod |= MOD_ALT; 
if (win) 
    mod |= MOD_WIN; 
if(!shift && !win && !alt && !control) 
    PostMessage(hFocus, WM_KEYDOWN, (UIntPtr)key, 1); 
else 
    PostMessage(hWindow, WM_HOTKEY, (UIntPtr)key, mod); 

WM_KEYDOWN工作正常,但WM_HOTKEY沒有任何影響

使用SendInput solwed我poblem。這裏是我的課程發送的關鍵事件

class input 
    { 
     public IntPtr focus; 
     public Form1 _this; 

     [DllImport("User32.dll")] 
     public static extern uint SendInput(uint numberOfInputs, [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] INPUT[] input, int structSize); 

     [DllImport("user32.dll")] 
     public static extern IntPtr GetMessageExtraInfo(); 


     public struct KEYBDINPUT 
     { 
      public ushort wVk; 
      public ushort wScan; 
      public uint dwFlags; 
      public long time; 
      public uint dwExtraInfo; 
     }; 
     [StructLayout(LayoutKind.Explicit, Size = 28)] 
     public struct INPUT 
     { 
      [FieldOffset(0)] 
      public uint type; 
      [FieldOffset(4)] 
      public KEYBDINPUT ki; 
     }; 



     public const int INPUT_MOUSE = 0; 
     public const int INPUT_KEYBOARD = 1; 
     public const int INPUT_HARDWARE = 2; 
     public const uint KEYEVENTF_EXTENDEDKEY = 0x0001; 
     public const uint KEYEVENTF_KEYUP = 0x0002; 
     public const uint KEYEVENTF_UNICODE = 0x0004; 
     public const uint KEYEVENTF_SCANCODE = 0x0008; 
     public const uint XBUTTON1 = 0x0001; 
     public const uint XBUTTON2 = 0x0002; 
     public const uint MOUSEEVENTF_MOVE = 0x0001; 
     public const uint MOUSEEVENTF_LEFTDOWN = 0x0002; 
     public const uint MOUSEEVENTF_LEFTUP = 0x0004; 
     public const uint MOUSEEVENTF_RIGHTDOWN = 0x0008; 
     public const uint MOUSEEVENTF_RIGHTUP = 0x0010; 
     public const uint MOUSEEVENTF_MIDDLEDOWN = 0x0020; 
     public const uint MOUSEEVENTF_MIDDLEUP = 0x0040; 
     public const uint MOUSEEVENTF_XDOWN = 0x0080; 
     public const uint MOUSEEVENTF_XUP = 0x0100; 
     public const uint MOUSEEVENTF_WHEEL = 0x0800; 
     public const uint MOUSEEVENTF_VIRTUALDESK = 0x4000; 
     public const uint MOUSEEVENTF_ABSOLUTE = 0x8000; 

     public void SetFocus(IntPtr windowFocus) 
     { 
      uint id = 0; 
      focus = windowFocus; 

     } 

     public input(IntPtr windowFocus) 
     { 
      SetFocus(windowFocus); 
     } 


     public bool KeyDown(ushort key) 
     { 
      INPUT[] inputs = new INPUT[1]; 
      inputs[0].type = INPUT_KEYBOARD; 
      inputs[0].ki.dwFlags = 0; 
      inputs[0].ki.wVk = key; 
      return (SendInput(1, inputs, System.Runtime.InteropServices.Marshal.SizeOf(inputs[0])) == 1); 
     } 


     public bool KeyUp(ushort key) 
     { 
      INPUT[] inputs = new INPUT[1]; 
      inputs[0].type = INPUT_KEYBOARD; 
      inputs[0].ki.dwFlags = KEYEVENTF_KEYUP; 
      inputs[0].ki.wVk = key; 
      return (SendInput(1, inputs, System.Runtime.InteropServices.Marshal.SizeOf(inputs[0])) == 1); 
     } 

     public bool KeyPress(ushort key) 
     { 
      return KeyDown(key) && KeyUp(key); 

     } 

     public bool HotKey(ushort key, bool ctrl, bool shift, bool alt, bool win, bool caps) 
     { 
      bool r = false; 
      //KeyUp(0); 
      if (ctrl) KeyDown((ushort)((uint)Keys.LControlKey & 0xff)); 
      if (shift) KeyDown((ushort)((uint)Keys.LShiftKey & 0xff)); 
      if (alt) KeyDown((ushort)((uint)Keys.Menu & 0xff)); 
      if (win) KeyDown((ushort)((uint)Keys.LWin & 0xff)); 
      if (caps) KeyPress((ushort)((uint)Keys.CapsLock & 0xff)); 
      r = KeyPress(key); 
      if (caps) KeyPress((ushort)((uint)Keys.CapsLock & 0xff)); 
      if (win) KeyUp((ushort)((uint)Keys.LWin & 0xff)); 
      if (alt) KeyUp((ushort)((uint)Keys.Menu & 0xff)); 
      if (shift) KeyUp((ushort)((uint)Keys.LShiftKey & 0xff)); 
      if (ctrl) KeyUp((ushort)((uint)Keys.LControlKey & 0xff)); 
      return r; 
     } 
    } 
} 

回答

4

在Windows上合成輸入的正確方法是呼叫SendInput

您有時可以通過PostMessage取得有限的成功。至於WM_HOTKEY,這與你正在嘗試做的事完全無關。

1

爲什麼你發送WM_HOTKEY消息?根據MSDN它是不同的...

+0

呀,這是錯誤的方式。 Thx,我會更便宜地找到爲什麼任何keydown發送密碼信息 – 2012-03-12 16:22:18

+0

爲什麼不呢?你看看WinSpy ++會發生什麼嗎? – 2012-03-12 16:27:58