您好,欢迎访问三七文档
当前位置:首页 > IT计算机/网络 > 软件工程 > 《Windows核心编程》读书笔记
第一部分程序员必读Szq整理使用第1章对程序错误的处理(1)常见的Windows函数的返回类型:VOID:无返回值型,该函数的运行不可能失败。Windows函数很少此类型BOOL:函数运行失败则返回0,否则返回非0HANDLE:失败则返回NULL,否则返回一个可操作的对象的Handle。注:有些函数会返回一个句柄值INVALID_HANDLE_VALUE,?它被定义为-1。函数的Platform?SDK文档将会清楚地说明该函数运行失败时返回的是NULL还是INVALID_HANDLE_VALIDPVOID:函数运行失败,则返回值是NULL,否则返回PVOID,以标识数据块的内存地址LONG/DWORD:这是个难以处理的值。返回数量的函数通常返LONGDWORD。如果由于某种原因,函数无法对想要进行计数的对象进行计数,那么该函数通常返回0或-1(根据函数而定)。如果调用的函数返回了LONG/DWORD,那么请认真阅读PlatformSDK文档以确保能正确?检查潜在的错误。(2)当某Windows函数运行错误时,可以通过调用DWORDGetLastError()函数获取调用该函数的关联线程的32位错误代码。其具体的错误文本以列表形式存放于WinError.h头文件中,在VC中调试时,也可以通过在Watch窗口键入“@err,hr”来获取所调用函数的运行错误代码和具体的错误文本。(3)Windows还提供了一个函数,可以将错误代码转换成它的文本描述。该函数称为FormatMessage,该函数的格式如下:DWORDFormatMessage(DWORDdwFlags,LPCVOIDpSource,DWORDdwMessageID,DWORDdwLanguageID,PTSTRpszBuffer,DWORDnSize,va_list*Argument);2004年11月8号Trackback:=174570第一章程序员必读1.1定义自己的错误代码若你编写了一个希望其他人调用的函数,你的函数可能因为这样或那样的原因而运行失败,你必须向函数的调用者说明它已经运行失败。若要指明函数运行失败,只需要设定线程的最后的错误代码,然后让你的函数返回FALSE、INVALID_HANDLE_VALUE、NULL或者返回任何合适的信息。可以用ViodSetLastError(DWORDdwErrCode)设定线程的最后错误代码;1.2ErrorShow示例小程序FormatMessage函数的用法//获取错误代码DWORDdwError=GetDlgItemInt(hwnd,IDC_ERRORCODE,NULL,FALSE);HLOCALhlocal=NULL;//创建存放错误文本的缓冲区并初始化;//获取错误代码的文字描述BOOLfOK=ForMatMessage(FORMAT_MASSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER,NULL,dwError,MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),(LPTSTR)&hlocal,0,NULL);...........if(hloca!=NULL){SetDlgItemText(hwnd,IDC_ERRORTEXT,(PCTSTR)LocalLock(hlocal));LocalFree(hlocal);}else{SetDlgItemText(hwnd,IDC_ERRORTEXT,TEXT(Errornumbernotfound));}当调用FormatMessage函数时,传递了FORMAT_MESSAGE_FROM_SYSTEM标志。该标志告诉FormatMessage函数,我们想要系统定义的错误代码的字符串。还传递FORMAT_MESSAGE_ALLOCATE_BUFFER标志,告诉该函数为错误代码的文本描述分配足够大的内存块。该内存块的句柄将hlocal变量中返回。第三个参数指明想要查找的错误代码的号码,第四个参数指明想要文本描述使用什么语言。2004年11月9日第二章UnicodeUnicode-宽字节字符集是是为了解决软件本地化(多语言版本化)而定制的一项技术标准。Unicode字符串中的所有字符都是16位的(两个字节),程序员只需要对指针进行递增或者递减,就可以遍历字符串中的各个字符,不在需要像单字节字符一样去判断下一字节是属于同一字符的组成部分还是一个新字符。使用Unicode,有几个好处,可以很容易地在不同语言之间进行数据交换、使你能够分配支持所有语言的单个二进制.exe文件或DLL文件、提高应用程序的运行效率。各Windows操作系统对Unicode的支持:Windows2000既支持Unicode,也支持ANSI,因此可以为任意一种开发应用程序。Windows98只支持ANSI,只能为ANSI开发应用程序。WindowsCE只支持Unicode,只能为Unicode开发应用程序。因为COM通常用于使不同的组件能够互相进行通信,而Unicode则是传递字符串的最佳手段。所以需要字符串的所有COM接口方法都只能接受Unicode字符串。2.8如何编写Unicode源代码C对Unicode的支持定义一个名字为wchar_t的数据类型,它便是一个Unicode字符的数据类型。Forexample,如果想要创建一个缓存,用于存放最多为99个字符的Unicode字符串和一个结尾为零的字符,可以使用下面这个语句:wchar_tszBuffer[100];当然,C里面的字符串函数,如strcpy、strchr、strcat等,只能对ANSI字符串进行操作,不能正确处理Unicode,因此,ANSIC补充了一组函数:ANSI:char*strchr(constchar*,int);Unicode:wchar_t*wcschr(constwchar_t*,wchar_t);ANSI:intstrcmp(constchar*,constchar*);Unicode:intwcscmp(constwchar_t*,constwchar_t*);ANSI:char*strcpy(char*,constchar*);Unicode:wchar_t*wcscpy(wchar_t*,constwchar_t*);ANSI:size_tstrlen(constchar*);Unicodesize_twcslen(constwchar_t*);请注意,所有的Unicode函数均以wcs开头,wcs是宽字符串的英文缩写。若要调用Unicode函数,只需用前缀wcs来取代ANSI字符串函数的前缀str即可。一般情况下,对ANSI和Unicode字符操作的函数不要写在同一个源代码文件中,这会给编译器编译带来很多麻烦(编译错误),但实在有必要的时候,也可以将他们放在同一个源代码文件中,这时候就需要包含一个头文件TChar.h。TChar.h头文件的唯一作用是就是帮助创建ANSI/Unicode通用的源代码文件。它的工作机制是,通过一组宏,来决定调用的是str函数还是wcs函数。Forexample,在TChar.h中定义有一个宏为_tcscpy,如果在包含该头文件时没有定义_UNICODE,那_tcscpy就想当于ANSI的strcpy,如果定义了_UNICODE,则_tcscpy想当于wcscpy函数。还有一个值得注意的是,使用了TChar.h中的宏的时候,若要生成一个Unicode字符串而不是一个ANSI字符串,则必须在字符串前加上一个大写字符L,Forexample:TCHAR*szError=LError;大写字母L的用意是告诉编译器,该字符串应该作为Unicode字符来编译。此举随之带来的问题是,我们还需要定义个宏来动态添加大写字母L,以适应Unicode/ANSI通用源代码文件。这个宏便是_TEXT。TCHAR*szError=_TEXR(Error);如上这样定义的话,就不论源代码文件中是否定义了_UNICODE,编译器都能够正确辨认并编译。此外,_TEXT宏还可以用于检验字符串的首字母。Forexample:if(szError[0]==_TEXT('J')){//首字母为J时的处理}else{//首字母不是J的时候}2004年11月9日Trackback:=174586第二章UnicodeWindows中的UnicodeWindows头文件定义了几种关于Unicode的数据类型:WCHARUnicode字符PWSTR指向Unicode字符串的指针PCWSTR指向一个恒定的Unicode字符串的指针同时Windows头文件也定业了ANSI/Unicode的通用数据类型,PTSTR和PCTSTR,这类数据指向那一种字符,取决于当编译程序模块时是否定义了UNICODE宏。这里这个宏UNICODE没有下划线前缀,带前缀的宏_UNICODE用于C运行期头文件。当编译源代码模块时,通常必须同时定义这两个宏。Windows中的函数CreatWindowsEx有两个版本,一个是接受Unicode字符串的,为CreatWindowsExW;一个接受ANSI字符串的,为CreatWindowsExA。我们在代码中,通常只包括了对CreatWindowsEx的调用,而不是直接调用这两者,因为在WinUser.h文件中,CreatWindowsEx实际上是定义为一个宏。故编译源代码模块时,调用的是哪CreatWindowsEx版本,取决于你是否已作了UNICODE的定义。若要创建供其它开发人员使用的DLL,DLL中最好提供两个输出函数,一个ANSI版本,一个Unicode版本,在ANSI版本中,只需要分配内存,执行必要的字符串转换,然后调用该函数的Unicode版本即可。Windows的一些老函数存在一个大问题,它们不接受Unicode字符串。这时候应该避免使用这些函数。所有新的和未过时的函数在Windows2000中都同时拥有ANSI和Unicode两个版本。Windows字符串函数Windows提供了一组范围很广的字符串操作函数,它们是操作系统的一个组成部分,常常被大型应用程序所使用。由于这些函数使用得比较多,故在你的应用程序运行时,它们可能被装进RAM,所以调用它们而不是使用C运行期库,会有助于稍稍提高你的运行性能。要使用经典的操作系统函数样式中的操作字符串的函数,必须加上ShlWApi.h头文件。这些字符串函数,既有ANSI版,也有Unicode版本,因此,当创建应用程序时,如果定义了Unicode,那么它们会自动扩展为宽字符版本。成为符合ANSI和Unicode的应用程序要使你的应用程序符合Unicode,应该遵循下面一些基本原则:1.将文本串视为字符数组,而不是chars数组或字节数组。2.将通用数据类型(如TCHAR和PTSTR)用于文本字符和字符串。3.将显式数据类型(如BYTE和PBYTE)用于字节、字节指针和数据缓存。4.将TEXT宏用于原义字符和字符串。5.执行全局性替换(例如用PTSTR替换PSTR)。6.修改字符串运算问题。例如函数通常希望你在字符中传递一个缓存的大小,而不是字节。这意味着你不应该传递sizeof(szBuffer),而应该传递(sizeof(szBuffer)/sizeof(TCHAR)。另外,如果需要为字符串分配一个内存块,并且拥有该字符串中的字符数目,那么请记住要按字节来分配内存。这就是说,应该调用malloc(nCharacters*sizeof(TCHAR)),而不是调用malloc(nCharacters)。在上面所说的所有原则中,这是最难记住的一条原则,如果操作错误,编译器将不发出任何
本文标题:《Windows核心编程》读书笔记
链接地址:https://www.777doc.com/doc-7037637 .html