【问题标题】:winprog.org first example strange behavior?winprog.org 第一个例子奇怪的行为?
【发布时间】:2012-07-22 18:48:10
【问题描述】:

我说的是 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;
}

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

似乎是什么问题?

【问题讨论】:

  • @BrookMiles 如果代码是在 Unicode 之前编写的,为什么它使用 _tWinMain 宏作为入口点、LPTSTR 宏,并错误地将窄字符串文字转换为宽字符串指针?
  • @Cody Gray,例子是我修改的,不是原来的。我不知道 C++ 的编码属性。
  • @CodyGray 正如 Andrew 所说,这不是教程中的实际代码。

标签: c winapi user-interface


【解决方案1】:

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

原因是操作系统将您的字符串文字解释为好像它们是使用UTF-16 编码的一样,即使它们不是。

MessageBox() 这样的一些标识符有两种形式:MessageBoxA() 函数和MessageBoxW()MessageBoxA() 是接受以当前代码页编码的字符串的“ANSI”版本,MessageBoxW() 是接受以 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 强制转换基本上会关闭编译器并强制它编译。

你不能只是随机投掷并总是期望它起作用。不幸的是,很多 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 字符串的规定。如果您使用的是框架/库,请遵循这些。

【讨论】:

  • 你有关于这个主题和 GUI 的阅读推荐吗?
  • @AndrewG.H.:MSDN page 关于字符串在 Windows API 中的工作方式是一个很好的起点。
  • 或者我可以使用 MessageBoxA() ,效果一样。
  • @Andrew G.H.不,效果不一样。如果您的应用程序使用支持 Unicode 的 API,那么您将“免费”获得 Unicode 支持,这意味着它可以在任何地方正确处理非英语语言的文本。使用 ANSI API 意味着您将受制于机器设置的任何语言环境,这可能导致 mojibake
【解决方案2】:

试试:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多