关于Unicode和多字节字符集

hideforever 2014-04-11 10:54:02
一个MFC对话框程序,将它的字符集设置成多字节字符集,::SetWindowTextW( m_hwnd, L"测试字符集ABC" )为什么也可以正常显示出来?还有一个问题:设置成多字节字符条件下,中文和日文能够同时正确显示吗?
...全文
272 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
hideforever 2014-04-16
  • 打赏
  • 举报
回复
引用 13 楼 CharlesSimonyi 的回复:
由于多字节字符集的存在,为了保持对多字节字符集的兼容性,所以才有SetWindowTextA这样的函数存在。 多字节字符集也有它的好处,Unicode出现之前用的就是多字节字符集,现在还不能把多字节字符集彻底抹杀掉,还在用,所有要保持兼容。
多谢Charles的解释,可惜已经结贴没有分了
encoderlee 版主 2014-04-15
  • 打赏
  • 举报
回复
由于多字节字符集的存在,为了保持对多字节字符集的兼容性,所以才有SetWindowTextA这样的函数存在。 多字节字符集也有它的好处,Unicode出现之前用的就是多字节字符集,现在还不能把多字节字符集彻底抹杀掉,还在用,所有要保持兼容。
BeanJoy 2014-04-14
  • 打赏
  • 举报
回复
引用 6 楼 hideforever 的回复:
[quote=引用 4 楼 BeanJoy 的回复:] 如2楼版主所说,windows api支持多字节和unicode。 实际windows在实现时,如果你调用的是多字节版本的api,则windows内部会先将相应的字符转换成unicode,然后再调用unicode版本的api。 比如你调用的是::SetWindowTextA(m_hwnd, "测试字符集ABC"),则windows会先将"测试字符集ABC"转换成unicode字符串,然后调用::SetWindowTextW。 你第二个问题是不行的。 多字节的显示是需要在某个代码页下而言的,一般我们用的简体中文的代码页为936,也就是我们常说的GBK。 在GBK环境中某个字符显示正常,那么拿到日文操作系统上,他们的代码页不为936,可能显示乱码。 UNICODE字符是最全的,包含了世界上所有的字符,代码中用UNICODE才能使你的程序无论在什么环境下都能显示正确。
对于第一个问题:如果使用多字节版本的api,windows会在内部转换成unicode版本。但是我现在工程是设置成了多字节版本,调用的是unicode版本的API,为什么还能正确显示呢?[/quote] 工程设置成多字节版本并不影响windows api的执行。若设置成UNICODE,只是预先定义了宏UNICODE,代码中调用SetWindowText时,预编译时,会将代码中所有的SetWindowText替换成SetWindowTextW,_T("")替换成L""而已。你在代码中还是可以直接调用SetWindowTextA或SetWindowTextW的。 工程是多字节还是UNICODE只是在编译阶段起作用。
encoderlee 版主 2014-04-14
  • 打赏
  • 举报
回复
简单来说SetWindowTextA内部的代码是这样的

SetWindowTextA(HWND hWnd,char* lpString)
{
      wchar_t *pwsz = 转换(lpString);
      return  SetWindowTextW(hWnd, pwsz);
}
所以无论你用的是什么字符集,无论调用SetWindowTextA还是SetWindowTextW 最终将字符显示到窗口上的还是SetWindowTextW这个函数
encoderlee 版主 2014-04-14
  • 打赏
  • 举报
回复
SetWindowTextA的内部也是将字符串转换为Unicode后调用SetWindowTextW。(参考《windows核心编程》) 无论你用的是什么字符集,在显示的时候,最终调用的都是SetWindowTextW,因为整个widnows操作系统内部用的都是Unicode字符集。 至于你将工程设置为多字节字符集还是Unicode字符集,影响的仅仅只是SetWindowText的意义,在多字节字符集下,SetWindowText=SetWindowTextA,在Unicode字符集下,SetWindowText=SetWindowTextW
hideforever 2014-04-14
  • 打赏
  • 举报
回复
引用 4 楼 BeanJoy 的回复:
如2楼版主所说,windows api支持多字节和unicode。 实际windows在实现时,如果你调用的是多字节版本的api,则windows内部会先将相应的字符转换成unicode,然后再调用unicode版本的api。 比如你调用的是::SetWindowTextA(m_hwnd, "测试字符集ABC"),则windows会先将"测试字符集ABC"转换成unicode字符串,然后调用::SetWindowTextW。 你第二个问题是不行的。 多字节的显示是需要在某个代码页下而言的,一般我们用的简体中文的代码页为936,也就是我们常说的GBK。 在GBK环境中某个字符显示正常,那么拿到日文操作系统上,他们的代码页不为936,可能显示乱码。 UNICODE字符是最全的,包含了世界上所有的字符,代码中用UNICODE才能使你的程序无论在什么环境下都能显示正确。
对于第一个问题:如果使用多字节版本的api,windows会在内部转换成unicode版本。但是我现在工程是设置成了多字节版本,调用的是unicode版本的API,为什么还能正确显示呢?
hideforever 2014-04-14
  • 打赏
  • 举报
回复
引用 8 楼 CharlesSimonyi 的回复:
简单来说SetWindowTextA内部的代码是这样的

SetWindowTextA(HWND hWnd,char* lpString)
{
      wchar_t *pwsz = 转换(lpString);
      return  SetWindowTextW(hWnd, pwsz);
}
所以无论你用的是什么字符集,无论调用SetWindowTextA还是SetWindowTextW 最终将字符显示到窗口上的还是SetWindowTextW这个函数
有一点不明白:既然归根结底都是调用SetWindowTextW,那还要SetWindowTextA干什么呢?
hideforever 2014-04-14
  • 打赏
  • 举报
回复
多谢各位的解答,以前的概念都是混淆的,现在清楚了
  • 打赏
  • 举报
回复
举个例子,用MessageBox来显示一段文字 多字节字符集下显示一段日文,在日文操作系统上显示日文,中文系统乱码 多字节字符集下显示一段中文,在中文操作系统上显示中文,日文系统乱码 unicode符集下显示一段日文,在日文操作系统上显示日文,中文系统也显示日文 unicode符集下显示一段中文,在日文操作系统上显示中文,中文系统也显示中文
BeanJoy 2014-04-11
  • 打赏
  • 举报
回复
如2楼版主所说,windows api支持多字节和unicode。 实际windows在实现时,如果你调用的是多字节版本的api,则windows内部会先将相应的字符转换成unicode,然后再调用unicode版本的api。 比如你调用的是::SetWindowTextA(m_hwnd, "测试字符集ABC"),则windows会先将"测试字符集ABC"转换成unicode字符串,然后调用::SetWindowTextW。 你第二个问题是不行的。 多字节的显示是需要在某个代码页下而言的,一般我们用的简体中文的代码页为936,也就是我们常说的GBK。 在GBK环境中某个字符显示正常,那么拿到日文操作系统上,他们的代码页不为936,可能显示乱码。 UNICODE字符是最全的,包含了世界上所有的字符,代码中用UNICODE才能使你的程序无论在什么环境下都能显示正确。
hideforever 2014-04-11
  • 打赏
  • 举报
回复
没有回答我的问题啊
oyljerry 2014-04-11
  • 打赏
  • 举报
回复
API有两套,支持多字节和Unicode 如果想显示多种语言,建议用Unicode字符
BeanJoy 2014-04-11
  • 打赏
  • 举报
回复
::SetWindowText是一个宏,根据是否定义UNICODE选择SetWindowTextA或SetWindowTextW。 程序中使用SetWindowTextA和SetWindowTextW都可。 SetWindowTextA(""); SetWindowTextW(L""); 或者 SetWindowText(_T("")); 用_T("")能根据是否定义UNICODE选择是""还是L“”。
kuankuan_qiao 2014-04-11
  • 打赏
  • 举报
回复
引用 4 楼 BeanJoy 的回复:
如2楼版主所说,windows api支持多字节和unicode。 实际windows在实现时,如果你调用的是多字节版本的api,则windows内部会先将相应的字符转换成unicode,然后再调用unicode版本的api。 比如你调用的是::SetWindowTextA(m_hwnd, "测试字符集ABC"),则windows会先将"测试字符集ABC"转换成unicode字符串,然后调用::SetWindowTextW。 你第二个问题是不行的。 多字节的显示是需要在某个代码页下而言的,一般我们用的简体中文的代码页为936,也就是我们常说的GBK。 在GBK环境中某个字符显示正常,那么拿到日文操作系统上,他们的代码页不为936,可能显示乱码。 UNICODE字符是最全的,包含了世界上所有的字符,代码中用UNICODE才能使你的程序无论在什么环境下都能显示正确。

16,472

社区成员

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

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

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