C++ MFC CEdit将非ascii字符转换为ascii字符

C++ MFC CEdit将非ascii字符转换为ascii字符,c++,visual-c++,unicode,mfc,mbcs,C++,Visual C++,Unicode,Mfc,Mbcs,我们有一个MFC Windows应用程序,最初是用VC++6编写的,多年来为更新的IDE进行了更新,目前是在VS2017中开发的 应用程序是用MBCS(而不是unicode)构建的。尝试切换到Unicode会导致3806个编译错误,这可能只是冰山一角 但是,我们希望能够使用不同的代码页运行应用程序,即1250(中欧) 我试图构建一个小的测试应用程序,并设法让它与特殊字符一起工作(楓đž)。我用代码页1250将dialog字体设置为Microsoft Sans Serif。 在我们的应用程序中,相

我们有一个MFC Windows应用程序,最初是用VC++6编写的,多年来为更新的IDE进行了更新,目前是在VS2017中开发的

应用程序是用MBCS(而不是unicode)构建的。尝试切换到Unicode会导致3806个编译错误,这可能只是冰山一角

但是,我们希望能够使用不同的代码页运行应用程序,即1250(中欧)

我试图构建一个小的测试应用程序,并设法让它与特殊字符一起工作(楓đž)。我用代码页1250将dialog字体设置为Microsoft Sans Serif。 在我们的应用程序中,相同的方法不起作用。注意:应用程序中的对话框是动态创建的,字体是使用SetFont设置的

在这两个应用程序中,特殊字符的处理方式有所不同

  • 在测试应用程序中,特殊字符显示在编辑控件中,GetWindowsText检索正确的字节。但是,尝试从其他语言编写一些字符时,会将它们呈现为“?”
  • 在我们的应用程序中,所有特殊字符都正确呈现,但是GetWindowText(或WMđGETTEXT)将特殊字符转换为类似的ascii对应字符(čćđ->ccd)
我相信应用程序中的编辑控件显示Unicode文本,但GetWindowText将其转换为ascii

有人知道这里发生了什么吗?我该如何解决


注意:我知道如何将project转换为Unicode。我们现在选择不向它投入资源,因为它可能需要数周或数月才能实施。问题是我如何让它与MBSC一起工作,以及为什么编辑控制将Č转换为C。

我相信完全可以将应用程序移植到其他语言/代码页,您只需要修改.rc(资源)文件,基本上每种语言都有一个资源文件,您可能更愿意这样做,菜单和/或字符串表中的字符串将使用不同的语言。就应用程序部分而言,这实际上是唯一需要的更改

另一部分是运行它的系统。窗口可以是unicode或非unicode。您可以通过Spyxx实用程序看到这一点,它告诉您窗口(过程)是否为unicode(窗口属性,常规选项卡)。虽然unicode窗口可以正常工作,但非unicode窗口在获取或设置文本时必须将编码从/更改为unicode和mbcs。转换基于系统(默认)代码页。这只能全局设置(对于整个机器),而不是每个应用程序或窗口。当然,设置字体的代码页是不够的(在我看来,如果你在一台有“正确”代码页的机器上运行应用程序,根本不需要设置)。也就是说,对于非unicode应用程序,只有一个代码页可以正常工作,而其他代码页不能正常工作

我可以看到两种选择:

  • 如果只需要更新少量控件,则可以仅将这些控件更改为unicode,并使用“宽”版本的get/set窗口测试函数或消息-您必须在unicode和所需代码页之间转换文本。它需要编写一些代码,但具有转换独立于系统默认代码页的优点,例如,您可以在某些配置文件、注册表中或作为命令行选项(在应用程序的快捷方式中)使用代码页。有些控件类型可以更改为unicode,有些则不能,因此请查看文档。在mbcs应用程序中成功地使用了这项技术,以多种不同的语言显示/编辑翻译的字符串,但我只有一个控件,一个列表视图,顺便说一句,它提供了
    LVM_setunicat
    消息,从而允许使用unicode文本,即使在mbcs应用程序中也是如此
  • 最简单的方法是按原样运行应用程序,但它只能在具有适当默认代码页的计算机上工作,就像大多数非unicode应用程序一样
系统默认代码页可以通过设置“非Unicode程序的语言”选项来更改,该选项位于“区域设置”、“管理”选项卡中,需要重新启动。更改Windows UI语言也会更改此选项,但通过设置此选项,您无需更改UI语言,例如,您可以使用英语UI和东欧代码页


看到一个非常相似的帖子。

如果这是你第一次尝试用自己的窗口API来访问代码页,那么也许你可以考虑UTF-8。或者,值得坚持使用unicode构建。使用char的任何错误只需更改为tchar。但是代码页是一种糟糕的方式,因为你一次只支持一种语言,而且你所有的鸭子都必须按正确的顺序匹配。将应用程序转换为UNICODE肯定是最好的选择,但这取决于你的代码,可能会有点麻烦。您可以做的第一件事是将所有字符串文本替换为
“Abc”
,并将所有
'X'
替换为
\T('X')
。这可能已经消除了许多错误。然后去掉所有
char xx[yy]
并用
CString
替换它们。有时,您可能希望保留字符xx[yy],将其替换为
TCHAR xx[yy]
。同时用
\u tcslen
\u tcscpy
等替换所有剩余的
字符串
\u tcscpy
等。用
TCHAR
替换
char
。通常尽量少使用原始字符数组。的“备注”部分可能会解释,为什么会看到不同的结果。@IInspectable这听起来很有趣,我将在代码中调用IsWindowUnicode来检查这一点。