《windows核心编程》读书笔记2-chapter2

《windows核心编程》读书笔记2-chapter2

如果调用任何windows函数,并传递给他一个ANSI字符串,系统会先将这个字符串转换为unicode字符串,然后将这个unicode字符串传递给操作系统。这样你就理解,为什么在windows平台上,使用unicode的效率要相对更高一些。

所以,我们可以通过在一开始就是用unicode开发应用程序,使程序执行更有效率。

 

1.1     Windows ceunicode

为了保持windows ce的精致,ms决定不支持ansiwindows函数。所以,如果要进行windows ce上的程序开发,必须了解并在整个应用程序中使用unicde

 

1.2     关于COM

Ms在将COM组建从16位移植到32位系统使,作出了一个决定:素有需要字符串的COM接口方法只支持unicode字符串。

 

1.3     如何编写unicode源代码

1.3.1  C运行库的unicode支持

标准cstring.h头文件中个定义了一个wchar_tunicode字符数据类型。

typdef unsigned long wchar_t;

标准c还专门为wchar_t定义了一组函数。

char* strcat(char*, const char*);

wchar_t* wcscat(wchat_t* , const wchar_t*);

 

size_t strlen(const char*);

size_t wcslen(const wchar_t*);

所有的unicode字符串都以wcs开头,代表宽字符。为了调用unicode,简单的将ansi字符串的str替换为wcs即可。

 

TChar.h头文件主要为为了帮助ANSI/Unicode通用源代码文件的编写,他主要由一系列的宏组成,在编写源代码时,可以使用这些宏来替代对strwcs函数直接的调用。

 

Msc++编译器将所有的字符串默认都认为是ansi字符串,而不是unicode字符串。所以,对于下面的这句话:

TCHAR *szError = “Error”;

如果没有定义_UNICODE宏,则能够编译通过,但是如果定义了该宏,则会出现编译错误。

为了生成一个UNICODE字符串而非一个ansi字符串,需要将以上的一句改为:

TCHAR *szError = L”Error”;

 

那么为了同时兼容上面的两种情况,我们定义一个宏

#ifdef _UNICODE

#define _TEXT(x) L ## x

#else

#define _TEXT(x) x

#endif

 

这样我们就可以重写以上的语句:

TCHAR* szError = _TEXT(“Error);

 

1.3.2  Windows定义的unicode数据类型

WCHAR  Unicode字符

PWSTR   指向Unicode字符串的 指针

PCWSTR  指向Unicode字符串常量的指针

 

Windows.h中同样定义了ansi/Unicode通用的数据类型

PTSTR

PCTSTR

在编译这个模块时,是否定义了UNICODE宏决定了这些数据类型指向ansi还是unicode

 

 

注意, _UNICODE是标准cunicode开关;

UNICODEwindowsunicode开关。

 

所以,一般来说,这两个宏要么同时定义,要么同时不定义。

 

 

1.3.3  Windows系统中的unicode函数和ansi函数

windows2000下,CreateWindowsExA只是一个简单的转换层,他实现内存分配并把ansi字符串转换为unicode字符串,然后调用CreateWindowsExW函数,把转换后unicode字符串传递给该函数。当CreateWindowsExW返回时,CreateWindowsExA释放内存缓冲区,并且返回其窗口句柄。

 

 

1.4     让应用程序符合ansiunicode规范

下面是一些基本规则:

l  对于文本字符和串使用通用数据类型;

l  对字节、字节指针和数据缓冲区使用显式数据类型;

l  对文字字符和字符串使用TEXT宏;

l  修改字符串运行问题, 使用sizeof(szbuffer)/sizeof(TCHAR)而不是sizeof(szbuffer);

l  分配内存时,使用malloc(len*sizeof(TCHAR)) 而不是malloc(len);

 

1.4.1  Windows字符串函数

第一个CompareString参数指定一个32位的位置IDLCID),用来识别具体的语言种类,CompareString使用LCID,通过检查适用于特定语言的字符的意义来比较字符串。

 

sprintf()系列函数的应用

 

char szA[100];

wchar_t szW[100];

 

//normal

sprintf(szA, “%s”, “ANSI Str”);

 

//convert Unicode to ansi

sprintf(szA, “%S”, L”ANSI Str”);

 

//normal

swprintf(szW, L“%s, L”ANSI Str”);

 

//convert Ansi To unicode

swprintf(szW, L”%S”, “ANSI Str”);

这里要注意格式化字符串的中s字符的大小写;

 

1.4.2  资源

Vc程序的内部资源字符串其实也是unicode的,在使用LoadString来加载资源时,如果是ansi,则其实是现将内部的unicode转换为ansi,然后在返回。

 

1.4.3  确定文本是ansi还是unicode

DWORD IsTextUnicode(CONST PVOID pvBuffer, int cb, PINT pResult);

用于判断指定的文本为ansi还是unicode

这个函数使用的是统计的方法论来分析缓冲区内的文本是ansi还是unicode,所以他也有可能返回一个错误的结果。

1.4.4  unicodeansi之间转换

这里其实就是涉及到两个函数

WideCharToMultiByte()

MultiByteToWideChar()

通过查看函数的原型,我们可以发现 WideCharToMulteByte MultiByteToWideChar 多了两个参数, pDefaultChar, pfUsedDefaultChar ,如果宽字符不能转换某字符,则函数应该使用参数 pDefaultChar 指向的字符,如果该参数为 NULL ,函数使用系统默认的字符。默认的字符为问号(这就是为什么在英文系统下,中文字符总是显示为问号的原因),问号用于文件名是危险的,因为问好是一种通配符。

你可能感兴趣的:(《windows核心编程》读书笔记2-chapter2)