先上个图,July 早期版本的“运行”对话框。

其实在我最初的构想中,这个对话框的提示文字并不是系统默认的文字,而应该是我写上去的——最起码把“Windows”替换成 “July”。
但是我最后放弃了,因为我写上去的字到最后显示出来是乱码。由于 RunFileDlg 这个 API 并没有详细的文档支持,而且其时的我也没有任何逆向的能力,所以干脆把文本参数给了个 NULL,直接用默认提示算球了。
现在回想起来其实是 TCHAR 惹的祸。在当时,我从网上得到的 RunFileDlg 声明是类似这个样子:
1 2 3 4 5 6 7 8 | int WINAPI RunFileDlg( HWND hwndParent, HICON hIcon, LPCTSTR pszWorkingDir, LPCTSTR pszTitle, LPCTSTR pszPrompt, DWORD dwFlags ); |
我的开发环境是 VC6,工程设置没改过。于是一调用,乱码个球了。因为 RunFileDlg 的字符串参数实际上是 LPCWSTR,而 VC6 默认会把 LPCTSTR 定义为 LPCSTR。
我想,现在该重新审视一下 TCHAR 的意义了。它,以及 LPTSTR、LPCTSTR 都是一个 typedef,而并非一个具体的类型。它会随着编译器是否定义了 UNICODE 宏而指向真正的类型,也就是 WCHAR 或 char。换句话说,TCHAR 的确实现了 Unicode 和 ANSI 编码的兼容,但这种兼容是在源代码一级的,在编译好的 PE 可执行映像中,该是什么还是什么。考虑下面的代码:
1 2 | char str[32]; lstrcpy(str, "Hello, World"); |
我曾见过无数类似的代码,甚至我也这么写过。在 ANSI 的编译环境下,这么写是没问题的,但是如果定义了 UNICODE,那么这段代码就会收到编译错误,因为 lstrcpy 将会被定义成 lstrcpyW,需求的参数类型是 LPWSTR 和 LPCWSTR。
也许你会说:我自己有能力控制我的源代码,知道自己用的是 lstrcpyA 还是 lstrcpyW,你管得着么?
的确,这是你的自由,我也不会干涉你的代码风格,更不会质疑你对代码的控制力。
但是,如果你的代码要提供给别人,而且你提供的只是一个接口;甚至,这个接口跨越了 PE 边界,那你总应该负点责吧?
别让你那含混不清的 TCHAR 给你们双方都带来麻烦。
TCHAR 可以在源代码一级达到编码兼容的效果,但如果这个接口跨越了 PE 的边界,这个 TCHAR 就可能会给调用者造成误解。
如果我提供给你一个 .dll 和一个 .h,而这个 .h 中的接口定义是用 TCHAR 来描述的,那会发生什么事?
1. 你分别写 A 和 W 的两套代码来测试这个 TCHAR 到底代表 char 还是 WCHAR。这麻烦了你。
2. 你直接问我这个 TCHAR 代表什么。这麻烦了我们俩。
所以,何必呢?
写的不错!
非常同意!
恩,仔细想了一下,你说的很有道理。呵呵,请无视我的回复吧。谢谢。
学习了,收藏~~~
很多地方都说Unicode好,但是我自己还没有亲身体验过,lima能否举例说明一下?
我自己碰到的情况是,使用printf函数无法输出unicode的中文字符,例如这样:
wchar_t szBuf[] = L”你好”;
wprintf(L”%s\n”,szBuf);
或者用printf输出也不行,但是使用ANSI编码中文就可以输出,是否有什么解决方法可以用printf函数输入unicode的中文呢?
谢谢
至于好处就不多说了,在《Windows 程序设计》的第二章,有很详细的论述。
至于你所说的 CRT 对 Unicode 中文的支持,可以参考下面的文章:http://blog.csdn.net/fengzhijiaxu/archive/2009/11/18/4829229.aspx
你好,我对你提到的文章三种方法,后面两种我不是很懂,就第一种方法来说,即是如下:
TCHAR szBuf[MAX_PATH] = _T(“测试test”) ;
_tprintf ( _T( “%s\n”), szBuf ) ;
依然对中文的显示是有问题的,只能显示问号
看一下第三种方法,应该是你要的。
谢谢,已经理解^_^