gpt4 book ai didi

c - 我的字符集有什么问题(Win32 API)

转载 作者:太空宇宙 更新时间:2023-11-04 00:22:42 25 4
gpt4 key购买 nike

我目前正在使用 this tutorial 学习 Win32 ,而且我很难处理显示的字符。

以这段代码为例,它在创建时向我的窗口添加了一个菜单:

    case WM_CREATE: {
HMENU hMenu, hSubMenu;
HICON hIcon, hIconSm;

hMenu = CreateMenu();
hSubMenu = CreatePopupMenu();

AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, "Exit");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "File");

hSubMenu = CreatePopupMenu();
AppendMenu(hSubMenu, MF_STRING, ID_STUFF_GO, "&GO");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&Stuff");

SetMenu(hwnd, hMenu);

hIcon = LoadImage(NULL, "Stuff.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE);

if (hIcon)
SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
else
MessageBox(hwnd, "Could not load large icon!", "Load Error", MB_OK | MB_ICONERROR);

hIconSm = LoadImage(NULL, "Stuff.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE);

if(hIconSm)
SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm);
else
MessageBox(hwnd, "Could not load small icon!", "Load Error", MB_OK | MB_ICONERROR);
}
break;

它位于我的 WndProc 函数中的 switch block 内,该函数处理从消息循环接收到的 Windows 消息。

要显示的每个字符串:

"Exit"
"File"
"&GO"
"&Stuff"

在运行时不可读,因为它们显示为小方 block ,就像代码页不正确或类似的东西一样。当我运行教程时,所有字符串都正确显示。我倾向于严格按照教程所说的来帮助我把事情做好,而且它的教学法很好。无论如何!...

我正在使用:

  1. Microsoft Visual Studio 2008 团队系统;
  2. 使用 RDP 的 Microsoft Windows Server 2003;
  3. 本地操作系统是 Windows Vista Ultimate。

有人知道吗?

最佳答案

您遇到了 Unicode 与 Windows ANSI 字符编码的问题。过去,Windows 使用扩展的 ASCII,但他们将其错误命名为 ANSI。这带来了对代码页的需求,因为即使是 8 位字符也无法提供足够的代码点来表示所有欧洲书写系统,更不用说世界其他地区了。开发 Win32 时,他们将 Unicode 作为首选字符集。 (实际上,他们选择了 Unicode 字符集的 UTF-16LE 编码,但这个细节现在并不完全相关。)但是,现有代码太多需要考虑要求从 Win16 移植到 Win32 也需要更改所有字符串的字符编码。

他们的解决方案很聪明(有些人认为它太聪明了)。每个采用字符串的 Win32 API 入口点都有两种形式。第一种风格采用 ANSI 字符串并在内部处理到 UTF-16LE 的转换。第二种(现在首选)风格直接采用 UTF-16LE 字符串。他们还与 Visual C 团队合谋定义 wchar_t作为 16 位类型,并确保 L""字符串文字使用从 ASCII 文本到 UTF-16LE 的映射。

为了简化从现有 Win16 代码的移植,MessageBox函数和所有其他采用字符串的 Win32 API 在编译时由宏映射到 MessageBoxAMessageBoxW取决于预处理器符号是否为 UNICODE已定义。

此映射无法修复字符串文字,因此他们还引入了一个宏来指定根据 UNICODE 变窄或变宽的字符串文字。 , 以及一个匹配的 typedef,以便可以声明变量以保存指向它们的指针。

因此,为了与 Win16 之间的最佳可移植性,您需要 #include <tchar.h> , 使用 TCHAR代替 charwchar_t , 将所有包含文本的字符串文字包装在 _T() 中宏,并使用非后缀名称调用 Win32 API,例如 MessageBox .

但这并不是一个完美的解决方案。当您的代码需要操作或计算将显示给用户的字符串时,您会发现很难编写在 TCHAR 中完全可移植的代码。政权。所有操作 TCHAR 的标准字符串函数都有替代品s,但是很难通过自动化测试验证您是否正确使用了它们,以便代码在使用和不使用 UNICODE 的情况下都能正常编译和工作。定义。

如果今天编写新的 Win32 代码,我的建议是在项目中定义 UNICODE,添加一个检查它是否真的在一个公共(public)头文件中定义,并使用 L""字符串和 W明确所有包装调用的风格。

最后,整篇文章都由显示缺失字符字形的代码提示(空方框字符是字体缺失特定字符时显示的字形)。发生这种情况是因为您的 ASCII 字符串文字被 Win32 代码解释为好像它们是 UTF-16LE,因此字符串“Exit”将被视为两个 Unicode 字符,U+7845U+7469 , 都是统一的汉字表意文字。除非您安装了汉字字体,否则这两种字体都不太可能出现在您系统上的任何字体中,因此您会得到缺失的字符字形。

发生这种情况是因为您将包装器宏与 ASCII 字符串文字混合在一起。你有:

AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, "Exit");

但你应该有以下之一:

AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, _T("Exit"));
AppendMenuA(hSubMenu, MF_STRING, ID_FILE_EXIT, "Exit");
AppendMenuW(hSubMenu, MF_STRING, ID_FILE_EXIT, L"Exit");

我更愿意推荐最后一个例子。

关于c - 我的字符集有什么问题(Win32 API),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4433542/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com