Wil*_*ler 1 c winapi menu windows-messages
我目前正在使用本教程学习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;
Run Code Online (Sandbox Code Playgroud)
这是switch
我的WndProc
函数中的一个块内部,它处理从消息循环接收的Windows消息.
要显示的每个字符串:
"Exit"
"File"
"&GO"
"&Stuff"
Run Code Online (Sandbox Code Playgroud)
在运行时是不可读的,因为它们显示为小方块,就像代码页不是正确的那样或类似的东西.当我运行教程时,所有字符串都正确显示.我倾向于完全坚持教程所说的内容,以帮助我把事情做好,而且它的教学法很好.无论如何!...
我正在使用:
任何人都有关于它的线索?
您对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在编译时由宏映射到MessageBoxA
或者MessageBoxW
取决于是否UNICODE
定义了预处理器符号.
这种映射无法修复字符串文字,因此它们还引入了一个宏来指定字符串文字,这些文字要么是窄的,要么是宽的UNICODE
,以及匹配的typedef,这样可以声明变量来保存指向它们的指针.
因此,为了获得Win16的最佳可移植性,您可以#include <tchar.h>
使用TCHAR
代替char
或wchar_t
包装_T()
宏中包含所有包含文本的字符串文字,并使用非后缀名称调用Win32 API MessageBox
.
然而,这不是一个完美的解决方案.在您的代码需要操作或计算将向用户显示的字符串的那一刻,您会发现编写在该TCHAR
机制中完全可移植的代码是很困难的.所有操作TCHAR
s 的标准字符串函数都有替换,但很难通过自动化测试验证您是否正确使用它们,以便代码可以编译并在有UNICODE
定义和无定义的情况下正常工作.
如果今天编写新的Win32代码,我的建议是在项目中定义UNICODE,添加一个检查,它确实在一个公共头文件中定义,并明确使用L""
字符串和W
所有包装调用的风格.
最后,整个文章是由显示缺失字符字形的代码提示的(空方框字符是字体缺少特定字符时显示的字形).这是因为您的ASCII字符串文字被Win32代码解释为好像它们是UTF-16LE,因此字符串"Exit"将被视为两个Unicode字符,U+7845
并且U+7469
它们都是统一汉字表意文字.除非您安装了Han字体,否则两者都不太可能以系统中的任何字体出现,因此您将获得缺少的字符字形.
发生这种情况是因为您正在将包装器宏与ASCII字符串文字混合.你有:
AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, "Exit");
Run Code Online (Sandbox Code Playgroud)
但是您应该具有以下之一:
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");
Run Code Online (Sandbox Code Playgroud)
在哪里我更喜欢推荐最后一个例子.