WM_CHAR,WM_UNICHAR,WM_IME_CHAR

一、WM_CHAR

1、如果窗口是unicode(IsWindowUnicode),WM_CHAR的wParam就是unicode字符。

2、如果窗口式ANSI,WM_CHAR的wParam是一个单字节的值。如果输入中文,则会得到2个WM_CHAR,把这两个单字节值合到一起就是输入的中文。

 

二、有一个额外的WM_UNICHAR,里面的wParam总是unicode32,但观察发现,输入法似乎并不用这个消息。如果其他程序想用这个消息给一个ANSI窗口发送消息,则应该先发一个WM_UNICHAR,并且wParam是UNICODE_NOCHAR,并且返回1。如果程序不处理,DefWndProc会返回0。如果输入法得到1,则认为该程序支持此消息,如果得到0,则认为该程序不支持此消息。如果是unicode window,DefWndProc会将WM_UNICHAR转换为WM_CHAR重新发出,如果是ansi,则会转换为1个或者2个WM_CHAR发出。

 

三、WM_IME_CHAR

1、如果是unicode window,则wParam就是unicode字符,此时和WM_CHAR没有任何区别。

2、如果是ansi window,则wParam是双字节的mbc编码。

如果程序忽略此消息,DefWndProc会转换为WM_CHAR(unicode window),或者1~2个WM_CHAR(ansi window)。注意一个细节,如果A要给B窗口发送WM_IME_CHAR,则应该postmsg(wm_ime_char,L’阿’,1),而不是postmsg(wm_ime_char,’阿’,1);如果B窗口是unicode窗口,则wParam=L”阿”。如果B窗口是ANSI窗口,则收到的wParam是’阿’,而不是L’阿’。这个转换甚至早于PreTranslateMessage。不知道系统在何时进行的转换。如果对ANSI窗口postmsg(wm_ime_char,’阿’,1),有时候也可以工作,但CEdit是不工作的。

也就是说,一般来说,如果是接收方,则不需要处理WM_IME_CHAR,直接交给DefWndProc即可。如果要处理,如果是unicode window,则和WM_CHAR处理方式一样,如果是ansi window,则需记住这个wParam是2个字节的MBC编码:

char Buffer[3] ={0};
Buffer[0] = wParam>>8;
Buffer[1] = (UCHAR)wParam;
Buffer[2] = 0;

如果是发送消息方,则应该总是使用wParam = unicode_char。

 

四、IME(Input Method Editor,输入法编辑器,简称输入法)的消息流程:

当用输入法输入时,首先发送WM_IME_COMPOSITION消息,在这个消息处理中,可以用ImmGetCompsitionString得到输入的字符串。如果不处理,则DefWndProc会针对每个字符串重新发送WM_IME_CHAR,如果WM_IME_CHAR也未处理,则DefWndProc会再次发送WM_CHAR。

假设用输入法输入“阿布”,

如果unicode window,则首先WM_IME_COMPOSITION,ImmGetCompsitionString得到的是2个unicode的wchar_t。然后2次WM_IME_CHAR,然后2次WM_CHAR。

如果ansi window,则首先WM_IME_COMPOSITION,ImmGetCompsitionString得到的是2个MBC的wchar_t。然后2次WM_IME_CHAR,然后4次WM_CHAR。

//游戏中这样处理

    case WM_CHAR:
case WM_SYSCHAR:
{
char cChar = (char)wParam;
printf( "汉字输入\n" );
static bool m_bDoubleChar = false;
static char m_sInpub[2] = { 0 };
if (m_bDoubleChar)
{
m_sInpub[1] = cChar;
printf( "%s\n", m_sInpub );
m_bDoubleChar = false;
m_sInpub[0] = 0;
m_sInpub[1] = 0;
}
else
{
if (IsDBCSLeadByte( cChar ))
{
//是双字节
m_bDoubleChar = true;
m_sInpub[0] = cChar;
}
else if (( cChar >= 32) && ( cChar <= 255))
{
m_sInpub[0] = cChar;
m_sInpub[1] = 0;
}
}
}

break;


转载自:http://st251256589.blog.163.com/blog/static/1648764492012013103021772/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值