Windows编程中UNICODE和_UNICODE定义问题

先转一篇文章:

初学Windows SDK编程时碰到过这个问题,相信很多初学Windows编程的人也都碰到过,后来慢慢搞明白些了,但有时别人问到自己也说不太 清楚。今天借此机会,我也好好整理一下自已的思路,用下面这篇文章详细点地解释下这个问题,希望能帮助到有此疑问的朋友。



UNICODE和_UNICODE并不是在头文件中“定义”的,而是程序员通过以下方法之一定义的:

1、用代码定义的,就像你上面的一样;

2、编译选项中指定。比如在VC中是:



Project->Settings->C/C++->Category->Preprocessor->Preprocessor definitions



这里是预处理指令,还有一些其它常见的常量如:WIN32,_DEBUG,NDEBUG,_WINDOWS等。



所以你在头文件中找不到它的定义(注意是定义,不是使用,使用的地方则很多)。



但这两个符号对Windows程序却是有特定含义的,也就是说你不能将UNICODE定义为:Unicode,unicode,UseUnicode...否则毫无作用。因为在很多的头文件中,这两个符号用来判断:



1、用那一种编码方式,即Unicode和单字节;

2、一些Windows中特定的类型的含义;

3、根据即Unicode和单字节编码的不同而选择不同组的字符处理函数。



例如_UNICODE的例子你可以在TCHAR.H中找到,它用来解析TCHAR等类型是宽字符还是单字节字符,以及一些字符串宏的处理结果是宽字符还是单字节,比如:



#ifdef  _UNICODE                   

typedef wchar_t TCHAR ;

#else 

typedef char TCHAR ;

#endif



还有类似的方式定义的宏:

_TEXT ("Hello!") , _T ("Hello!") , TEXT ("Hello!") , L ("Hello!") 



上面的宏全是一个意思:如果是UNICODE,则算是是宽字符;否则处理为传统单字节ASCII字符。



UNICODE在很多头文件中和_UNICODE一样用来解析TCHAR等类型是宽字符还是单字节字符,例如WINNT.H中:



#ifdef  UNICODE                   

typedef WCHAR TCHAR, * PTCHAR ;

typedef LPWSTR LPTCH, PTCH, PTSTR, LPTSTR ;

typedef LPCWSTR LPCTSTR ;

#else 

typedef char TCHAR, * PTCHAR ;

typedef LPSTR LPTCH, PTCH, PTSTR, LPTSTR ;

typedef LPCSTR LPCTSTR ;

#endif



同时用来选择字符处理函数,例如WINUSER.H中:



#ifdef UNICODE

#define MessageBox  MessageBoxW

#else

#define MessageBox  MessageBoxA

#endif 



这 样,我们只用一种类型(比如TCHAR)和一组函数(比如MessageBox)就方便地可以处理两种编码的程序,而不用去条件判断应该用char还是 wchar_t,应该用MessageBoxA还是MessageBoxW。这些细节Windows.h等头文件中已经为我们考虑了,我们要做的只是在需 要用Unicode时定义两个符号。



而另一方面,Windows.h经过辗转#include,又将WINNT.H、WINUSER.H 等很多头文件包含了进去,很多地方还有重复交叉的(当然用条件编译过滤过了),所以两个符号(UNICODE、_UNICODE)都要定义,否则像上面少 定义了一个的话,结果将很难预料。
总结:有了这些以就可以通过宏(也就是像:_T,LPTSTR,LPCTRSTR之类的带有T这个标志的)来再ASCII和UNICODE之间转换了。程序可移植性很强了。

Windows编程中UNICODE和_UNICODE定义问题的更多相关文章

  1. Windows 编程中恼人的各种字符以及字符指针类型

    在Windows编程中,很容易见到这些数据类型:LPSTR,LPTSTR,LPCTSTR... 像很多童鞋一样,当初在学Windows编程的时候,对着些数据类型真的是丈二和尚,摸不着头脑,长时间不用就 ...

  2. windows编程中的数据类型

    在windows编程中,有许多奇怪的数据类型,初学者不知道这些代表什么,下面就把一些数据类型列出如下: ATOM 原子(原子表中的一个字符串的参考) BOOL 布尔变量 BOOLEAN 布尔变量 BY ...

  3. Windows编程中的若干难点 - Windows程序设计(SDK)007

    Windows编程中的若干难点 让编程改变世界 Change the world by program 一个窗口的生与死 我记得有童鞋会问:如果我的程序需要在关闭前让用户判断是否确定要关闭窗口,我应该 ...

  4. Windows编程中char*转LPCWSTR解决的方法总结

    Windows编程中常常涉及到的一个问题是字符串之间的转换,开发过程总是遇到编译器提示无法格式转换的问题.于是自己总结了几种解决的方法. 1.通过T2W转换宏 char* szStr = " ...

  5. Windows编程中各种操作文件的方法

    windows编程中文件操作有以下几种常见方法:1.C语言中文件操作.2.C++语言中的文件操作.3.Win32 API函数文件操作.4.MFC CFile类文件操作.5.MFC CFileDialo ...

  6. 资源在windows编程中的应用----菜单

    资源在Windows编程中的应用 资源 加速键.位图.光标.对话框.菜单.字符串.工具条 1.菜单的创建 菜单由以下组成部分: (1)窗口主菜单条 (2)下拉式菜单框 (3)菜单项热键标识 (4)菜单 ...

  7. Windows编程中回调函数的使用心得(MFC篇)

    回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数.回调函数不是由该函数的实现方直接调用,而是在特定 ...

  8. Windows 编程中的字符串(2)

    (1)windows写日志系统 void writeDebugEventLog(TCHAR* pszMessage, WORD wType) { //#ifdef _DEBUG HANDLE hEve ...

  9. windows编程中关于“关闭窗口无法退出进程”的解决方法

    一般会出现如下两种情况 1.WinMain函数中,最后阶段接收消息队列循环中,调用的GetMessage函数参数提供错误 如: while (GetMessage(&msg,hwnd, 0, ...

随机推荐

  1. 【整理】--linux指令

    1.压缩 解压 .tar 解包:tar xvf FileName.tar打包:tar cvf FileName.tar DirName(注:tar是打包,不是压缩!)———————————————.g ...

  2. python easy_install pip django

    1. install python (2.7.8) 2. set PATH, add python27 3. python easy_install.py 4. easy_install pip 5. ...

  3. PCFG -- 基于统计方法生成语法树

    语法树的作用 一棵语法树不仅包括了词性(part of speech), 还包括了短语(如名词短语, 动词短语)和结构化的信息(如主语, 谓语和宾语). 这些信息是进行机器翻译所必须的, 例如机器翻译 ...

  4. centos6 一个vlan配置多ip地址

    添加vlan [root@localhost network-scripts]# vconfig add eth1 109 配置文件,此处配置了vlan109使用子接口进行多ip配置: [root@l ...

  5. System.DateTimeOffset 中新增的Unix 时间戳方法

    // System.DateTimeOffset [__DynamicallyInvokable] public static DateTimeOffset FromUnixTimeMilliseco ...

  6. DWZ错误的解决:0x800a13af - Microsoft JScript 运行时错误: 重新声明常量“document”

    在写完Login后,需要跳转到Index中,就是DWZ的主界面,结果出现如下问题: 0x800a13af - Microsoft JScript 运行时错误: 重新声明常量“document” 费了很 ...

  7. 使用F#来实现哈夫曼编码吧

    最近算法课要求实现哈夫曼编码,由于前面的问题都是使用了F#来解决,偶然换成C#也十分古怪,报告也不好看,风格差太多.一开始是打算把C#版本的哈夫曼编码换用F#来写,结果写到一半就觉得日了狗了...毕竟 ...

  8. 使用SQLIO测试磁盘性能

    SQLIO 是一个用于测试存储系统能力的命令行工具,用以获取存储系统相关的性能指标,以判断系统的 I/O 处理能力. 在微软的网站可以下载 SQLIO 的安装包,安装后目录中会出现如下文件: EULA ...

  9. require、module、exports dojo中的三个特殊模块标识

    查看dojo源码过程中,发现这三个模块名并不以dojo.dijit.dojox开头,在dojo加载器中属于特殊模块名. require 这是一个上下文智能的加载器. 我们通过dojoConfig配置了 ...

  10. SQL Server 性能优化之——T-SQL TVF和标量函数

    阅读导航 1. TVF(表-值行数Table-Valued Functions)         a. 创建TVF         b. 使用TVF的低性能T-SQL         c. 使用临时表 ...