winprog.org第一个例子奇怪的行为?

and*_*ari 1 c user-interface winapi

我在谈论winprog.org的Windows GUI教程,因为StackO上的许多用户都推荐它.

我基本上尝试了这个例子:

#include "stdafx.h"
#include "winapiTest1.h"


int WINAPI _tWinMain(HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPTSTR    lpCmdLine,
        int       nCmdShow)
{
    MessageBox(NULL, (LPCWSTR) "Goodbye, cruel world!", (LPCWSTR) "Note", MB_OK);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是当我运行它时,它会显示消息框,但它中的每个字符串(甚至是标题)都用中文字符表示.

什么似乎是问题?

In *_*ico 5

但是当我运行它时,它会显示消息框,但它中的每个字符串(甚至是标题)都用中文字符表示.

之所以如此,是因为操作系统将您的字符串文字解释为使用UTF-16进行编码,即使它们不是.

一些标识符MessageBox()有两种形式:一个MessageBoxA()函数和一个MessageBoxW().MessageBoxA()是"ANSI"版本,它接受在当前代码页中编码的字符串,并且MessageBoxW()是接受以UTF-16编码的字符串的"宽"版本(即它是"支持Unicode的").MessageBox()实际上是一个宏,根据是否定义了宏来定义其中任何一个UNICODE.没有Windows的API,被称为中没有实际功能MessageBox() 本身.

问题的关键在于:

MessageBox(NULL, (LPCWSTR) "Goodbye, cruel world!", (LPCWSTR) "Note", MB_OK); 
Run Code Online (Sandbox Code Playgroud)

你的项目可能有一个#define UNICODE地方,导致MessageBox()标识符解析MessageBoxW(),这需要一个UTF-16编码的字符串.通常情况下,编译器会向你抱怨它(即编译错误),但是转换LPCWSTR器基本上会关闭编译器并强制它编译.

你不能只是随机投射,总是希望它能够发挥作用.遗憾的是,许多Windows API教程(以及一些一般的C++教程)在没有必要时甚至在它们不合适的时候滥用了所有地方.

James建议解决方案使用_T()宏,这有助于设置它,以便字符串文字被正确编码,而不需要强制转换.但是,新应用程序的优秀解决方案是忘记函数的ANSI版本,并且只需要在整个Unicode中使用它.该_T()宏是用于应用程序过渡到支持Unicode的API的一个权宜之计.

#include "stdafx.h"   // Make sure UNICODE is defined before windows.h       
#include "winapiTest1.h"          

int WINAPI WinMain(HINSTANCE hInstance,          
        HINSTANCE hPrevInstance,          
        LPCSTR    lpCmdLine,          
        int       nCmdShow)          
{          
    MessageBox(NULL, L"Goodbye, cruel world!", L"Note", MB_OK);          
    return 0;          
}         
Run Code Online (Sandbox Code Playgroud)

请注意,字符串文字现在有一个L前缀.这告诉Visual C++编译器来解释文本作为UTF-16编码字符串(请注意,它可能会变成其他C++编译器不同的编码,这适用于Visual C++只).

另请注意,上述建议仅适用于仅使用Windows API的情况.包装Windows API的一些框架和库有自己的处理Unicode字符串的规定.如果您使用的是框架/库,请关注它们.

  • @Andrew GH不,这不是同样的效果.如果您的应用程序使用支持Unicode的API,那么您可以"免费"获得Unicode支持,这意味着它可以在任何地方正确处理非英语语言的文本.使用ANSI API意味着您将受到机器设置的任何区域设置的支配,这可能导致[mojibake](http://en.wikipedia.org/wiki/Mojibake). (2认同)