在VB6中,UserControl或Form或PictureBox是区域设置英语1033中的ANSI窗口(可在区域和语言设置中配置)。当我通过MS IME或百度输入键入Unicode时,我看到wParam在WM_IME_CHAR或WM_UNICHAR或WM_CHAR中总是63(Char'?')。
对于比较,我创建了一个SDK TextBox,由CreateWindowExW API使用,IsWindowUnicode API显示它是Unicode窗口,因为它是Unicode Window,我可以看到wParam是Unicode Keycode当我子类WM_IME_CHAR和WM_UNICHAR和WM_CHAR时。所以我可以轻松获得Unicode Char。
我猜OS操作系统处理ANSI窗口和Unicode窗口是不同的。获取IME Unicode Char的解决方法是什么?
C#中的相同代码适用于1033(英国美国)或2052(中国PRC)的任何语言环境,因为C#窗口始终是Unicode。
protected override void WndProc(ref Message m)
int msg = m.Msg;
if (msg == WM_IME_SETCONTEXT) //associated IME with our UserControl
{
if (!m.WParam.Equals(IntPtr.Zero))
{
bool flag = ImmAssociateContextEx(m.HWnd, IntPtr.Zero, 16);
IntPtr hIMC = ImmGetContext(m.HWnd);
flag = ImmSetOpenStatus(hIMC, true);
flag = ImmReleaseContext(m.HWnd, hIMC);
}
}
}
else
if (msg == WM_IME_CHAR) //Intercept Message to get Unicode Char
{
KeyPress(this, new KeyPressEventArgs(Strings.ChrW(m.WParam.ToInt32())));
return;
}
}
base.WndProc(ref m);
}
In VB6 UserControl:
Private Function WindowProcUserControl(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Select Case wMsg
Case WM_IME_SETCONTEXT '//associated IME with our UserControl
If Not wParam = 0 Then
Dim flag As Boolean
flag = ImmAssociateContextEx(hWnd, 0, 16)
If flag Then
Dim hIMC As Long
hIMC = ImmGetContext(hWnd)
flag = ImmSetOpenStatus(hIMC, True)
flag = ImmReleaseContext(hWnd, hIMC)
End If
End If
Case WM_IME_CHAR '//Intercept Message to get Unicode Char
Call KeyPress(ChW$(wParam And &HFFFF&))
Exit Function
End Select
End Function

答案 0 :(得分:0)
我发现这篇文章与您的问题有关:http://support.microsoft.com/kb/193540/en-us。
答案 1 :(得分:0)
我认为根本问题是VB6窗口是ANSI,当一个IME窗口附加到它们时,VB6只是通过ANSI API处理(可能会说“VB的ANSI泵会吃掉它”)。由于这个问题超出了我和大多数程序员的能力,我让这个线程“错误地解决了”。