ToUnicodeEx 函数失败,键盘布局与我的不同

ToUnicodeEx function fails with any keyboard layout different than mine

我正在使用 ToUnicodeEx 函数将按下的键的虚拟键码转换为其 unicode 字符,

这是函数定义:

<DllImport("user32.dll", CharSet:=CharSet.Auto, ExactSpelling:=True, CallingConvention:=CallingConvention.Winapi)>
Friend Shared Function ToUnicodeEx(
                       ByVal wVirtKey As UInteger,
                       ByVal wScanCode As UInteger,
                       ByVal lpKeyState As Byte(),
                       <Out, MarshalAs(UnmanagedType.LPWStr)>
                       ByVal pwszBuff As StringBuilder,
                       ByVal cchBuff As Integer,
                       ByVal wFlags As UInteger,
                       ByVal dwhkl As IntPtr
) As Integer
End Function

该功能非常适合我的文化 es-ES 和我的键盘布局 3082,但是,如果指定 3082 我尝试使用下面的代码指定 1033 键盘布局来模拟 en-US 文化或其他文化的按键不同于 3082 的任何其他键盘布局,则 ToUnicodeEx 函数将失败并且 returns 0,其中 return 值为 0 意味着:

The specified virtual key has no translation for the current state of the keyboard. Nothing was written to the buffer specified by pwszBuff.

Dim buf As New StringBuilder(256)
Dim keyboardState As Byte() = New Byte(255) {}

If shift Then
    keyboardState(CInt(Keys.ShiftKey)) = &HFF
End If

If altGr Then
    keyboardState(CInt(Keys.ControlKey)) = &HFF
    keyboardState(CInt(Keys.Menu)) = &HFF
End If

InputDevice.NativeMethods.ToUnicodeEx(CUInt(Keys.A), 0UI, keyboardState,  buf,  256,  0UI, 
                                      New IntPtr(1033))

我哪里做错了?我该如何解决?

您不能简单地传递一个数字 (IntPtr) 作为最后一个参数...如 MSDN

中所写

dwhkl [in, optional] Type: HKL The input locale identifier used to translate the specified code. This parameter can be any input locale identifier previously returned by the LoadKeyboardLayout function.

您必须首先使用 LoadKeyboardLayout 加载布局。

通过试验、研究和一些失败,我在 .Net 框架 class 库中找到了不涉及 P/Invoking.

的最佳和更简单的解决方案

只知道一个文化名称,例如 en-USes-ESSystwm.Windows.Forms.InputLanguage class我们可以检索布局的句柄(HKL)

InputLanguage.FromCulture(New CultureInfo("en-US")).Handle

然后,可以为 ToUnicodeEx 函数的 dwHKL 参数设置该值,并且完美运行!