在线时间 0 小时 最后登录 2005-9-21 注册时间 2004-4-27 听众数 1 收听数 0 能力 0 分 体力 1027 点 威望 0 点 阅读权限 40 积分 385 相册 0 日志 0 记录 0 帖子 153 主题 43 精华 0 分享 0 好友 0
升级 28.33%
该用户从未签到
国际赛参赛者
< ><FONT face=宋体>这是一个许多人(包括我自己)曾经或至今仍疑惑的问题(这里我们只讨论UTF-16,即双字节版本)。# K) a! ?, m8 S! {7 b
* P. _- L# ~& g% v
1.关于UNICODE2 @! {/ J, }; ]. ^; I/ h
首先,UNICODE主要使用的字符类型是WCHAR,定义是unsigned short。从定义我们可以看出这是一个双字节的类型,就是每一个字符占2个字节。这样的话,可以表示的字符类型就可以多达6万多。所有之前的ASCII码分布在0x0000-0x00ff之间,而汉字(包括big5)分布在0x4e00到0x9fff之间。整个unicode包含了几乎世界上所有的文字。关于UNICODE的细节,可以参看以下网页% g2 ^0 N8 D8 U% e4 {: J9 ]
<a href="http://www.unicode.org/unicode/standard/translations/s-chinese.html" target="_blank" >http://www.unicode.org/unicode/standard/translations/s-chinese.html</A><a href="http://www.unicode.org/unicode/standard/translations/s-chinese.html" target="_blank" ><FONT color=#000020></FONT></A>% l/ x; g8 v' M
F O" Y8 H) b; w$ n H+ L 2.为什么要使用UNICODE
; }# n8 B; X& s! D 1) COM:在COM规范中,明确指定了必须使用UNICODE类型,这正是微软充分考虑了跨平台的结果。这也是为什么经常在COM中可以看到BSTR(WCHAR*)类型 s1 [0 W' [: H
3 {" Y3 J8 {4 g3 u( E5 N
2)WIN2000和WINNT:在这两个平台中,默认的字符处理方式是UNICODE。即使你写了一个非UNICODE(multibyte)的程序,系统在执行的时候仍然会对你的字符进行一次转换,这样无疑浪费了CPU时间,使用UNICODE可以有效的提高程序的运行效率(仅使用于这两个平台)。当然将来的XP也会如此。9 V- _6 ?$ [2 G/ U
, i9 L1 R. s( j+ T. l4 }
3)通用性:使用UNICODE可以使我们不在为汉字和英文字符的判断而烦恼(都是2个字节)。' K5 f9 Z6 c5 l
: o0 I- H2 a" [# I' N7 A e7 U 3.如何使用UNICODE 4 D8 ]0 F t! s- ~* q& N
1)首先推荐的类型是TCHAR(通用字符类型)。当你定义了_UNICODE宏的时候,TCHAR就是WCHAR,当你没有定义这个宏的时候,TCHAR就是char,很不可思议吧,我们可以来看一下TCHAR的定义:4 Y* r3 z& Q/ l" y+ g
$ n: G' s8 \7 T9 \
#ifdef UNICODE // r_winnt! P6 L4 Z9 L+ Y, o0 R4 P. Z- s; M
typedef WCHAR TCHAR, *PTCHAR;
( O9 K' e, O4 x #else /* UNICODE */ // r_winnt% ~- D4 u' {' k9 { q
typedef char TCHAR, *PTCHAR;1 I, I9 z$ a1 C/ c0 [5 W3 J
#endif /* !_TCHAR_DEFINED */: ]) w% ^* e& g
8 F; C; D& W2 G0 |! p
上面的代码来自WINNT.H,我剔除了一些无关的部分。) s2 I; L+ g( k! t% @$ K
现在一切都显而易见了。
) g1 U' v# z$ g5 h1 L: q9 Z 通过TCHAR,我们只需要这样一段代码:
7 m( J& W1 t$ @2 k% C1 q( {( H TCHAR tStr[] = _T("t code");
# L1 k2 K4 X& U8 t5 j( C) z MessageBox(tStr);
0 y" C" S: @. |+ s 就可以支持UNICODE和MULTIBYTE两种版本。_T宏的作用就是转换成TCHAR。" F4 m% j# S- ^
, U$ d3 @: p: p' J
2)关于其他的处理! `3 G& p' p& N. z
首先是常用的CString,它本身就支持UNICODE。下面的例子说明了用法:6 x' f: i; ] s# l, v5 ] M
" X) g, y' b" B. K3 x$ T8 [ CString *pFileName = new CString("c:\\tmpfile.txt");
) q; t! x7 z: O3 L7 G 1 C: S' ]3 T; g- d; l6 w" ?9 K d! `
#ifdef _UNICODE+ k: d1 }# c$ j, i1 h; }
8 Q6 O2 o* K$ n8 p5 z m_hFile = CreateFile(pFileName->AllocSysString(), 0 s1 k! P$ d. H: W0 ~
GENERIC_READ | GENERIC_WRITE,
2 y" Y8 |2 U2 |+ u$ e( Y! i FILE_SHARE_READ,
9 n( L% g0 { T4 y# h; W- V5 ` NULL,% T" F9 [4 u% X9 j2 l6 I# Z% `: n
OPEN_EXISTING,9 l4 T% L/ w) @$ c2 Y0 {+ b
FILE_ATTRIBUTE_NORMAL,
3 N4 B2 q- k& b; o/ v6 j NULL);% F- L8 ]' a4 v# Y/ h# K
#else3 g# |" k: d. ^8 c% u" F) G
m_hFile = CreateFile(pFileName->GetBuffer(pFileName->GetLength()),
3 J7 K3 r. g3 h* S( F" E GENERIC_READ | GENERIC_WRITE,
1 e0 A/ i( |$ A0 f. h- r9 D FILE_SHARE_READ,
5 z" u0 A! a1 z- y( G' @$ Y NULL,$ W0 M9 m) r, u9 C
OPEN_EXISTING,
# `, p% W* Y! ?& y" ~5 S( @$ ^ FILE_ATTRIBUTE_NORMAL,
+ R. Z! x5 e4 y" Z0 H NULL);( V# d1 [ K7 X! _4 q' |" s
#endif
5 _9 P7 A( |" {
2 o6 x7 h( b' W1 `; | 3) 当我们在UNICODE方式中需要为一个字串常量赋值时可以使用L宏,如: }% o; D3 x" [& `% y5 O* Q' ~
BSTR wcsStr = L"unicode";
1 ?! P& Q4 b; P- U7 E4 T/ Z 这样的附值很简便,但是,经过L宏处理后的字串一定是UNICODE,如果你把它赋给一个MULTIBYTE的字串,字符将可能会被截断。
/ ?3 I, }" d8 W! y2 K3 I ( Y }7 P; B2 \/ p1 k) H% Q" l
另外,VC还提供了一些函数如WideCharToMultiByte和MultiByteToWideChar还有另外的一些宏来支持转换。大家可以看MSDN。
6 Z, e: R+ x* b; `( q1 n+ {8 f9 i S7 A & Q O: @( i& o) |
/ j1 @* F. u. O/ Z 3.编译器的设置:
- y# V* X1 ]$ y0 N9 H; h 首先我们需要在project->settings->C/C++的属性页中的Preprocessor中写入_UNICODE,然后在link属性页中Category中选择output,在Entry-Point symbol 中添加wWinMainCRTStartup,这样,我们的UNICODE工程便大功告成。</FONT></P>
zan