这有什么错我的字符集(Win32 API的) [英] What's wrong with my character set (Win32 API)

查看:158
本文介绍了这有什么错我的字符集(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!...

我使用的是:


  1. 微软的Visual Studio 2008 Team System中;

  2. 的Microsoft Windows Server 2003中使用RDP;

  3. 本地操作系统是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 制度。还有所有的操纵 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 TCHARs, 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.

这篇关于这有什么错我的字符集(Win32 API的)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆