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

时间:2012-07-22 18:48:10

标签: c winapi user-interface

我在谈论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;
}

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

什么似乎是问题?

2 个答案:

答案 0 :(得分:5)

  

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

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

MessageBox()等一些标识符有两种版本:MessageBoxA()函数和MessageBoxW()MessageBoxA()是" ANSI"接受当前代码页中编码的字符串的版本,而MessageBoxW()是" wide"接受以UTF-16编码的字符串的版本(即" Unicode-aware")。 MessageBox()实际上是一个宏,根据是否定义了UNICODE宏来定义其中任何一个。 Windows API中没有实际的功能MessageBox() 本身

问题的关键在于:

MessageBox(NULL, (LPCWSTR) "Goodbye, cruel world!", (LPCWSTR) "Note", MB_OK); 

您的项目可能在某处#define UNICODE,导致MessageBox()标识符解析为MessageBoxW(),其中需要UTF-16编码的字符串。通常情况下,编译器会向你抱怨它(即编译错误),但LPCWSTR强制转换基本上会关闭编译器并强制它编译。<​​/ p>

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

solution that James propose使用_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;          
}         

请注意,字符串文字现在以L为前缀。这告诉Visual C ++编译器将文字解释为UTF-16编码的字符串(请注意,它可能会将其转换为其他C ++编译器上的不同编码;这仅适用于Visual C ++。)

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

答案 1 :(得分:1)

尝试:

MessageBox(NULL, _T("Goodbye, cruel world!"), _T("Note"), MB_OK);