为什么输入法输出的是CP936而不是UNICODE?

iamjerrychu 2008-04-25 04:54:34
我用 谷歌拼音、微软拼音2003、极点五笔测试,发现两个问题,比较困惑,望高手解答。
1.输入法输出的字符是什么格式?在记事本、VC6的.cpp文件中输入字符通过ultraedit查看得到的都是CP936的代码,这是因为输入法直接输出的就是CP936还是因为编辑器改的?

2.在如下程序中,
int main ()
{
unsigned short* str = L"ÎÒû×í!";
//char* str = "ÎÒû×í!";
return 0;
}
注:这是直接从VC6贴进来的 乱码处为“我没醉!”,最后一个感叹号用英文输入法输入的。

我看了str的汇编,
在str为unsigned short*和char*时,汇编代码是一样的,但是内存却不一样:

在str为unsigned short*时:
asm:
40: unsigned short* str = L"ÎÒû×í!";
00401668 mov dword ptr [ebp-4],offset string L"\x6211\x6ca1\x9189!" (0042f020) //UNICODE
memory:
0042F020 11 62 A1 6C 89 91 21 .b¡l‰‘! //UNICODE
0042F027 00 00 00 00 00 50 08 .....P.

在str为char* 时:
asm:
41: char* str = "ÎÒû×í!";
00401668 mov dword ptr [ebp-4],offset string L"\x6211\x6ca1\x9189!" (0042f020) //UNICODE
memory:
0042F020 CE D2 C3 BB D7 ED 21 ÎÒû×í! //CP936
0042F027 00 00 00 00 00 50 08 .....P.


在1中我说过.cpp里面也是CP936,可是这里在asm里面都是UNICODE了,为什么?内存为什么又会是这样?

谢谢!!
...全文
189 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
iamjerrychu 2008-05-04
  • 打赏
  • 举报
回复
从<<Programming windows>>的第6章找的:
How does the window procedure know whether this character data is 8-bit ANSI or 16-bit Unicode? It's simple: Any window procedure associated with a window class that you register with RegisterClassA (the ANSI version of RegisterClass) gets messages that contain ANSI character codes. Messages to window procedures that were registered with RegisterClassW (the wide-character version of RegisterClass) come with Unicode character codes. If your program registers its window class using RegisterClass, that's really RegisterClassW if the UNICODE identifier was defined and RegisterClassA otherwise.

cnzdgs 2008-05-03
  • 打赏
  • 举报
回复
差不多是这样,不过我感觉应该不是与RegisterClass有关,而是与CreateWindow有关,只是感觉而已,没有验证过。
iamjerrychu 2008-05-03
  • 打赏
  • 举报
回复
不好意思各位,兄弟我不会忘记散分的。
这几天我查阅了一些资料,在这里打算做个总结,有说的不对的地方请指出:
Windows程序的窗口(控件)在注册的时候使用RegisterClass函数:
如果使用的是RegisterClassA,则在窗口处理函数中WM_CHAR消息的参数中,将会包含代码页相应的字符,如果换了代码页,则按下同一个键,收到的字符也会不同。当然,收到的虚拟键码(VK)是不会变化的,变化的只是VK到字符映射关系的改变。比如在代码页P0中,虚拟键码V0映射到字符C0,在P0中编码为0xXX,而在代码页P1中,V0映射到字符C1,在P1中编码为0xYY。
如果使用RegisterClassW函数注册的,则在WM_CHAR消息的参数中,将会是UNICDOE相应的字符,此时更换代码页是不会影响的。
我没有研究过WM_IME消息,我猜想是当前代码页为中日韩文时候,接收双字节字符用的吧,而此时WM_CHAR接收这些代码页中单字节的字符,如0-127编码的字符和代码页ISO-8859-1(ASCII的美国英语扩展)是兼容的。
所以,对于问题(1.)如果记事本、VC编辑器等都是使用RegisterClassA注册的,则直接将WM_CHAR和WM_IME过来的字符保存到文件;否则,得到当前系统的代码页,将受到的UNICODE字符转换到代码页中的编码,保存。
对于问题(2.)我要say sorry了,这是vc的一个BUG,我后来又恢复正常了,在str为char* 时,asm也是CP936.

顺便我要指出:char* str = L"ÎÒû×í!"; 是编译不过的,因为L会把后面的字符串转成unsigned short*类型,类型不匹配。
UltraBejing 2008-05-01
  • 打赏
  • 举报
回复
接分是王道!
Mr-Chen 2008-04-30
  • 打赏
  • 举报
回复
[Quote=引用楼主 iamjerrychu 的帖子:]
我用 谷歌拼音、微软拼音2003、极点五笔测试,发现两个问题,比较困惑,望高手解答。
1.输入法输出的字符是什么格式?在记事本、VC6的.cpp文件中输入字符通过ultraedit查看得到的都是CP936的代码,这是因为输入法直接输出的就是CP936还是因为编辑器改的?

2.在如下程序中,
int main ()
{
unsigned short* str = L"ÎÒû×í!";
//char* str = "ÎÒû×í!";
return 0;
}
注:这是直接从VC6贴进来的 乱码处为“我…
[/Quote]

1、和具体的编辑器有关
2、你确定?
int main ()
{
unsigned short* str = L"ÎÒû×í!";
char* str = L"ÎÒû×í!";
return 0;
}
看看
daohua 2008-04-29
  • 打赏
  • 举报
回复
MARK,对自己有用
iamjerrychu 2008-04-29
  • 打赏
  • 举报
回复
谢谢二楼的回答,不过我还是没有完全搞清楚,能解释详细点么?尤其是输入法输出
谢谢!
cnzdgs 2008-04-29
  • 打赏
  • 举报
回复
输入法会向控件发送WM_CHAR、WM_IME_XXX等消息,如果控件使用的是Unicode,则收到的字符也是Unicode形式的;如果使用的是多字节,收到的字符就是多字节形式的。你可以自己调试跟踪一下这些消息。
scq2099yt 2008-04-28
  • 打赏
  • 举报
回复
up
cnzdgs 2008-04-26
  • 打赏
  • 举报
回复
1、程序内部会自动转换成自己需要的代码页。
2、是你看错了,或者是调试器的问题。

16,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧