这有什么错我的字符集(Win32 API的)
我使用的 本教程 目前正在学习Win32和我也很难与我显示的字符。
I'm currently learning Win32 using this tutorial, and I have a hard time with my displayed characters.
就拿这块code的这在创建时增加了一个菜单,我的窗口:
Take for instance this piece of code which adds a menu to my window upon creation:
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
函数中块处理消息循环收到的Windows消息
That is inside of a switch
block within my WndProc
function that handles the Windows Messages received from the Message Loop.
每个字符串是要被显示:
Each string that is to be displayed:
"Exit"
"File"
"&GO"
"&Stuff"
因为它们显示为小广场,就像codePAGE不正确的或类似的东西
在运行时读取。当我运行教程,所有的字符串正确显示。我倾向于正是坚持教程说什么,帮我把事情做好,而其教学好。反正!...
Is unreadable at runtime as they are displayed as little squares, just like the codepage was not the right one or something like that. When I run the tutorial, all the strings are correctly displayed. I tend to stick exactly to what the tutorial says to help me get the thing right, and its pedagogy is good. Anyway!...
我使用的是:
- 微软的Visual Studio 2008 Team System中;
- 的Microsoft Windows Server 2003中使用RDP;
- 本地操作系统是Windows Vista旗舰版。
任何人有一个关于它的线索?
Anyone has a clue about it?
您有统一code与ANSI的Windows字符编码的问题。以往,Windows中使用的扩展ASCII它们误命名ANSI。这带来了为code页面的需要,因为即使是8位字符没有提供足够的code点再present所有欧洲书写系统,更不用说在世界的其他地方。当Win32的开发,他们定居在统一code为preferred字符集。 (事实上,他们定居在UNI code字符集的UTF-16LE编码,但细节现在也不是完全相关的。)但是,有太多的现有code考虑要求,从移植的Win16到Win32也需要改变所有字符串的字符编码。
You have an issue with Unicode vs. Windows ANSI character encoding. Historically, Windows used an extended ASCII that they mis-named ANSI. This brought with it the need for code pages because even an 8-bit character does not provide enough code points to represent all of the European writing systems, let alone the rest of the world. When Win32 was developed, they settled on Unicode as the preferred character set. (Actually, they settled on the UTF-16LE encoding of the Unicode Character Set, but that detail isn't entirely relevant right now.) However, there was too much existing code to consider requiring that porting from Win16 to Win32 would also need to change the character encoding of all strings.
他们的解决方案是很聪明(有些人认为这是太聪明了)。每个Win32 API的入口点,需要一个字符串有两种风格。第一香味需要ANSI字符串和内部处理转换为UTF-16LE。第二个(现在preferred)香精采用UTF-16LE字符串直接。他们还与Visual c队密谋定义 wchar_t的
作为一个16位的类型,以确保 L
字符串使用从ASCII文本转换为UTF-16LE的映射。
Their solution was clever (some have argued that it was too clever). Every Win32 API entry point that takes a string comes in two flavors. The first flavor takes ANSI strings and handles the conversion to UTF-16LE internally. The second (and now preferred) flavor takes UTF-16LE strings directly. They also conspired with the Visual C team to define wchar_t
as a 16-bit type, and to assure that L""
string literals use the mapping from ASCII text to UTF-16LE.
若要从现有的Win16 code容易,的MessageBox
函数和所有其他的Win32 API,通过宏需要串在编译时被映射移植为 MessageBoxA
或 MessageBoxW
根据是否不preprocessor符号 UNI code
定义。
To make porting from existing Win16 code easy, the MessageBox
function and every other Win32 API that takes strings is mapped at compile time by a macro to either MessageBoxA
or MessageBoxW
depending on whether or not the preprocessor symbol UNICODE
is defined.
这映射不能修复的字符串,所以他们也推出了宏指定字符串是要要么窄或宽视 UNI code
和匹配的类型定义,这样的变量可以声明持有指向他们。
This mapping can't fix the string literals, so they also introduced a macro to designate string literals that are to be either narrow or wide depending on UNICODE
, and a matching typedef so that variables can be declared to hold pointers to them.
所以,最好的便携性和Win16的,你会的#include< TCHAR.H>
,使用 TCHAR
代替字符
或 wchar_t的
,包所有包含文本字符串中的 _T()
宏,并在Win32 API的像的MessageBox
。
So, for best portability to and from Win16, you would #include <tchar.h>
, use TCHAR
in place of char
or wchar_t
, wrap all text-containing string literals in the _T()
macro, and call on the Win32 APIs with the non-suffixed names like MessageBox
.
这是不是一个完美的解决方案,但是。您code需要处理或计算将显示给用户的字符串的那一刻,你会发现,这是很难写code,它是在 TCHAR $完美的便携C $ C>制度。还有所有的操纵
TCHAR
S上的标准字符串函数替换,但很难与自动化测试,以验证您正确地使用它们,这样的code会编译使用和不使用 UNI code
定义。
This isn't a perfect solution, however. The moment your code needs to manipulate or compute a string that will be displayed to a user, you discover that it is difficult to write code that is perfectly portable in the TCHAR
regime. There are replacements for all of the standard string functions that manipulate TCHAR
s, but it is difficult to verify with automated testing that you correctly used them such that the code would compile and work correctly both with and without UNICODE
defined.
如果今天写新的Win32 code,我的建议是定义UNI code项目,加上它是在一个共同的头文件真正定义了检查,并使用 L
串并明确所有包裹的呼叫是W
味道。
If writing new Win32 code today, my advice would be to define UNICODE in the project, add a check that it is really defined in a common header file, and use L""
strings and the W
flavors of all wrapped calls explicitly.
最后,这整个文章是由您的code,显示缺少的字符字形提示(空方盒子的性格是当字体缺少特定字符显示的字形)。这是发生在Win32的code PTED,好像他们是UTF-16LE因为你的ASCII字符串正在跨$ P $,所以该字符串退出将被视为两个单向code字, U + 7845
和 U + 7469
,这两者都是统一的韩表意文字。除非你已经安装了汉字体,都是极不可能在你的系统上的任何字体present让您得到缺少的字符字形,而不是
Finally, this whole essay is prompted by your code that displays the missing character glyph (the empty square box character is the glyph that displays when a font is missing a particular character). That is occuring because your ASCII string literals are being interpreted by the Win32 code as if they were UTF-16LE, so that the string "Exit" would be taken to be two Unicode characters, U+7845
and U+7469
, which are both Unified Han ideographs. Unless you have Han fonts installed, both are highly unlikely to be present in any font on your system so you get the missing character glyph instead.
这是发生,因为你是一个用ASCII字符串字面混合包装宏。您有:
This is happening because you are mixing the wrapper macro with an ASCII string literal. You have:
AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, "Exit");
但你应该具备以下之一:
but you should have one of the following:
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");
在这里我preFER推荐的最后一个例子。
where I prefer to recommend the last example.