在线时间 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,即双字节版本)。
6 d- o* @+ \$ r4 w - y# p1 p1 H/ d ^7 \
1.关于UNICODE: h& S1 E6 G: u( ?$ @& p
首先,UNICODE主要使用的字符类型是WCHAR,定义是unsigned short。从定义我们可以看出这是一个双字节的类型,就是每一个字符占2个字节。这样的话,可以表示的字符类型就可以多达6万多。所有之前的ASCII码分布在0x0000-0x00ff之间,而汉字(包括big5)分布在0x4e00到0x9fff之间。整个unicode包含了几乎世界上所有的文字。关于UNICODE的细节,可以参看以下网页
% S- J6 L7 g8 l: a <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>( B9 s. b E- Z& v- W% h+ m2 |
' g! Z. r* K# S 2.为什么要使用UNICODE
: R5 ]1 M% S% a( t 1) COM:在COM规范中,明确指定了必须使用UNICODE类型,这正是微软充分考虑了跨平台的结果。这也是为什么经常在COM中可以看到BSTR(WCHAR*)类型
, d9 C1 w; k5 F" j
# P5 h: o$ u% r' c, J0 g 2)WIN2000和WINNT:在这两个平台中,默认的字符处理方式是UNICODE。即使你写了一个非UNICODE(multibyte)的程序,系统在执行的时候仍然会对你的字符进行一次转换,这样无疑浪费了CPU时间,使用UNICODE可以有效的提高程序的运行效率(仅使用于这两个平台)。当然将来的XP也会如此。
! p0 y+ n! i4 h; ^
! Y* u' W5 P! n8 U w' ? 3)通用性:使用UNICODE可以使我们不在为汉字和英文字符的判断而烦恼(都是2个字节)。
! U) B- h- `0 Q; f# x4 C) U * c. B1 \+ U" c& |# f' F4 E
3.如何使用UNICODE ; R8 _) L9 k0 q( h& ?/ R
1)首先推荐的类型是TCHAR(通用字符类型)。当你定义了_UNICODE宏的时候,TCHAR就是WCHAR,当你没有定义这个宏的时候,TCHAR就是char,很不可思议吧,我们可以来看一下TCHAR的定义:4 Y& g) d& C! f* ]) I5 u
* J2 C- ^8 j, | N) ~6 i
#ifdef UNICODE // r_winnt4 l$ V& c" k' c% Y. a, ~5 q9 U- ~
typedef WCHAR TCHAR, *PTCHAR;
) S0 _! q9 H- @$ `0 u #else /* UNICODE */ // r_winnt
) c; _- `. m( u3 K3 E0 y+ X% E typedef char TCHAR, *PTCHAR;9 l. e1 u0 B. A1 d# o8 H* z
#endif /* !_TCHAR_DEFINED */
1 e6 G% ]; W: }( U4 _; C
6 F# J' d1 `1 [" o% @& Q) f 上面的代码来自WINNT.H,我剔除了一些无关的部分。5 ?% J- f; |( R! @
现在一切都显而易见了。% H: b8 z, ]# F# N
通过TCHAR,我们只需要这样一段代码:
3 X* ?/ U' E3 b: R2 G h$ u8 O TCHAR tStr[] = _T("t code");
* P* e. t* C! B2 O$ i' T MessageBox(tStr);- `, j, `7 V5 y6 w7 T0 N% _
就可以支持UNICODE和MULTIBYTE两种版本。_T宏的作用就是转换成TCHAR。
_2 A' v# Y1 \0 y$ w2 a
4 [. i6 m0 r/ c2 h! E5 X7 N 2)关于其他的处理4 U) F& o- Q+ m5 z$ L
首先是常用的CString,它本身就支持UNICODE。下面的例子说明了用法:8 q% R! s3 g7 D( y% K3 D" ^/ ~+ q$ `
$ B+ Z& N- H: M( A. M" ~ CString *pFileName = new CString("c:\\tmpfile.txt");
1 t4 b+ p; P8 j8 N; a6 y; v 8 o M! ~9 X; Q7 N$ W% Y
#ifdef _UNICODE
6 I8 i. V% @) \) d I5 C
2 M0 F7 z, Y4 p# ^+ D8 P1 H( S m_hFile = CreateFile(pFileName->AllocSysString(),
7 V! I& v7 K7 x2 ]6 T9 ]# O8 | GENERIC_READ | GENERIC_WRITE,
" r) z w* d, e$ O" r& C4 \ FILE_SHARE_READ,
) S# _0 [% M3 I0 y$ {% P6 v4 T& z2 L NULL,
6 Y' N% o* [% l5 ]6 l OPEN_EXISTING,
, ]- F* V! Y( m* @4 m6 t" I FILE_ATTRIBUTE_NORMAL,
- E( N1 R; V3 v9 { NULL);1 E5 n3 ]. j* a$ y( [7 N( Q2 L
#else) }; Z0 x8 o& Q
m_hFile = CreateFile(pFileName->GetBuffer(pFileName->GetLength()), ! c+ g" c1 C% o# {" i( T* I
GENERIC_READ | GENERIC_WRITE, " c: [( M% j2 i- [
FILE_SHARE_READ,
( F3 L4 ?0 a; Y& f NULL,
4 k& K( v( {3 w OPEN_EXISTING,2 P" N+ p0 D+ W8 U7 Q5 w# ^
FILE_ATTRIBUTE_NORMAL, 3 l+ x/ o7 q1 Y, Q8 ]( R
NULL);
; F: N/ g" z. t+ f4 @. t #endif# ?' S4 r* G- H' W$ d
6 s6 ^5 t1 y( m& Z& a
3) 当我们在UNICODE方式中需要为一个字串常量赋值时可以使用L宏,如:
/ `' z; q) D& p9 B$ @ BSTR wcsStr = L"unicode";
0 m$ q" C! Q! I! y# m6 f( B 这样的附值很简便,但是,经过L宏处理后的字串一定是UNICODE,如果你把它赋给一个MULTIBYTE的字串,字符将可能会被截断。/ [' }7 _1 x4 @6 a; t+ F y% `
, |) `" |# E' V) ^9 X# h% g 另外,VC还提供了一些函数如WideCharToMultiByte和MultiByteToWideChar还有另外的一些宏来支持转换。大家可以看MSDN。 8 m/ v P3 ]1 P0 L `
; I; N c7 \" Q) b3 c3 k
7 G3 K! v0 r T% m( t 3.编译器的设置:
" P t0 S1 C% g0 k. K6 Q& ]& u4 s/ N 首先我们需要在project->settings->C/C++的属性页中的Preprocessor中写入_UNICODE,然后在link属性页中Category中选择output,在Entry-Point symbol 中添加wWinMainCRTStartup,这样,我们的UNICODE工程便大功告成。</FONT></P>
zan