2015-01-17 38 views
1

我正尝试使用MapVirtualKey Windows函数从Windows Forms应用程序中的虚拟键代码中获取键盘扫描代码。在P的声明/调用的东西是:获取箭头键的正确键盘扫描代码

private const uint MAPVK_VK_TO_VSC = 0; 

[DllImport("user32.dll", 
    CallingConvention = CallingConvention.StdCall, 
    CharSet = CharSet.Unicode, 
    EntryPoint = "MapVirtualKey", 
    SetLastError = true, 
    ThrowOnUnmappableChar = false)] 
private static extern uint MapVirtualKey(
    uint uCode, 
    uint uMapType); 

我已重写我的申请主窗口类的OnPreviewKeyDown方法(从System.Windows.Forms.Form衍生);在这里,我将给定PreviewKeyDownEventArgs对象的KeyCode属性的值并将其传递给MapVirtualKey方法(我假定该值实际上是一个虚拟键代码)。

protected override void OnPreviewKeyDown(PreviewKeyDownEventArgs e) 
{ 
    uint uCode = (uint)e.KeyCode; 
    uint scanCode = MapVirtualKey(uCode, MAPVK_VK_TO_VSC); 

    this.HandleScanCode(scanCode); 

    base.OnPreviewKeyDown(e); 
} 

问题是我收到了箭头键的错误扫描码(我接受了数字键盘箭头键的扫描码)。例如,如果向上箭头键被按下,我期望扫描码是200而不是72.

+0

等待,你在哪里得到200计算出来的?无论您是按下实际的上键还是数字键盘键,上箭头键的扫描码都是0x48(十进制72)。 (区别在于前者的前缀是一个0xE0,Windows在各种低级别Windows API键盘消息的wParam中变成了一点).Windows始终使用scancode set 1; 200(0xC8)似乎没有映射到任何扫描码。或者我错过了在这种情况下应该设置高位的东西? – andlabs

+1

@andlabs看看这个:http://minecraft.gamepedia.com/Key_codes – Matze

+0

@Matze我找不到这些代码超出这个答案,但奇怪的是,他们用于GTAV。 –

回答

0

看来,这个问题只属于增强型键盘。 MapVirtualKey方法与左手和右手键码无关。这意味着,键码38 Up和104 NumPad8产生相同的扫描码,因为Up键是增强键。

我决定直接拦截WM_KEYDOWN消息,因为该消息的参数lParam既包含所需的扫描码,也包含指示密钥是否为增强密钥的位。这解决了我的问题......

protected override void WndProc(ref Message m) 
{ 
    base.WndProc(ref m); 

    switch (m.Msg) 
    { 
     case WM_KEYDOWN: 
     { 
      int lParam = m.LParam.ToInt32(); 
      int scanCode = (lParam >> 16) & 0x000000ff; // extract bit 16-23 
      int ext = (lParam >> 24) & 0x00000001; // extract bit 24 
      if (ext == 1) 
       scanCode += 128; 

      this.HandleScanCode(scanCode); 
      break; 
     } 
    } 
} 

如果密钥的增强密钥想扫描码,可以通过增加128

+0

我试过这个,并能够捕获各种消息,但不是WM_KEYDOWN或任何其他键盘消息。我正在Windows 10下运行一个C#WinForms应用程序。我需要做什么来捕获这些消息? –

+0

此消息仅发送到聚焦/选定的窗口;因此请确保该窗口保持焦点,或者使用键盘钩子代替:https://msdn.microsoft.com/en-us/library/windows/desktop/ms644985(v=vs.85).aspx – Matze