获取方向键的正确键盘扫描码
Get correct keyboard scan code for arrow keys
我正在尝试使用 MapVirtualKey
Windows 函数从 Windows Forms
应用程序中的虚拟键码获取键盘扫描码。 P/Invoke 东西的声明是:
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);
我已经覆盖了我的应用程序 main window class 的 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。
看来,这个问题只属于增强型键盘。 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来计算。
我正在尝试使用 MapVirtualKey
Windows 函数从 Windows Forms
应用程序中的虚拟键码获取键盘扫描码。 P/Invoke 东西的声明是:
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);
我已经覆盖了我的应用程序 main window class 的 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。
看来,这个问题只属于增强型键盘。 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来计算。