《Windows核心编程》读书笔记_第1页
《Windows核心编程》读书笔记_第2页
《Windows核心编程》读书笔记_第3页
《Windows核心编程》读书笔记_第4页
《Windows核心编程》读书笔记_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Windows核心编程读书笔记第一部分程序员必读Szq整理使用第1章对程序错误的处理 (1)常见的Windows函数的返回类型:VOID: 无返回值型,该函数的运行不可能失败。Windows函数很少此类型BOOL:函数运行失败则返回0,否则返回非0HANDLE:失败则返回NULL,否则返回一个可操作的对象的Handle。注:有些函数会返回一个句柄值INVALID_HANDLE_VALUE,?它被定义为-1。函数的Platform? SDK文档将会清楚地说明该函数运行失败时返回的是NULL还是INVALID_HANDLE_VALIDPVOID :函数运行失败,则返回值是NULL,否则返回PVOI

2、D,以标识数据块的内存地址LONG/DWORD: 这是个难以处理的值。返回数量的函数通常返LONGDWORD。如果由于某种原因,函数无 法对想要进行计数的对象进行计数,那么该函数通常返回0或-1(根据函数而定)。如果调用的函数返回了LONG/DWORD,那么请认真阅读 Platform SDK文档以确保能正确?检查潜在的错误。 (2)当某Windows函数运行错误时,可以通过调用 DWORD GetLast Error()函数获取调用该函数的关联线程的32位错误代码。其具体的错误文本以列表形式存放于WinError.h头文件中,在VC中调试时,也可以 通过在Watch窗口键入“err,hr”来

3、获取所调用函数的运行错误代码和具体的错误文本。 (3)Windows还提供了一个函数,可以将错误代码转换成它的文本描述。该函数称为FormatMessage,该函数的格式如下: DWORD FormatMessage( DWORD dwFlags, LPCVOID pSource, DWORD dwMessageID, DWORD dwLanguageID, PTSTR pszBuffer, DWORD nSize, va_list *Argument ); 2004年11月8号Trackback: 第一章 程序员必读1.1定义自己的错误代码 若你编写了一个希望其他人调用的函数,你的函数可能因

4、为这样或那样的原因而运行失败,你必须向函数的调用者说明它已经运行失败。若要指明函数运行失败,只 需要设定线程的最后的错误代码,然后让你的函数返回FALSE、INVALID_HANDLE_VALUE、NULL或者返回任何合适的信息。可以用 Viod SetLastError(DWORD dwErrCode)设定线程的最后错误代码;1.2 ErrorShow示例小程序 FormatMessage函数的用法 /获取错误代码 DWORD dwError = GetDlgItemInt(hwnd , IDC_ERRORCODE , NULL , FALSE); HLOCAL hlocal = NULL

5、; /创建存放错误文本的缓冲区并初始化; /获取错误代码的文字描述 BOOL fOK = 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)

6、 ); LocalFree(hlocal); else SetDlgItemText(hwnd , IDC_ERRORTEXT , TEXT(Error number not found) ); 当调用FormatMessage函数时,传递了FORMAT_MESSAGE_FROM_SYSTEM标志。该标志告诉FormatMessage函 数,我们想要系统定义的错误代码的字符串。还传递FORMAT_MESSAGE_ALLOCATE_BUFFER标志,告诉该函数为错误代码的文本描述分 配足够大的内存块。该内存块的句柄将hlocal变量中返回。第三个参数指明想要查找的错误代码的号码,第四个参数指明想

7、要文本描述使用什么语言。 2004年11月9日 第二章 Unicode Unicode宽字节字符集是是为了解决软件本地化(多语言版本化)而定制的一项技术标准。Unicode字符串中的所有字符都是16位的(两个字 节),程序员只需要对指针进行递增或者递减,就可以遍历字符串中的各个字符,不在需要像单字节字符一样去判断下一字节是属于同一字符的组成部分还是一个新 字符。 使用Unicode,有几个好处,可以很容易地在不同语言之间进行数据交换、使你能够分配支持所有语言的单个二进制.exe文件或DLL文件、提高应用程序的运行效率。 各Windows操作系统对Unicode的支持: Windows 2000

8、既支持Unicode,也支持ANSI,因此可以为任意一种开发应用程序。 Windows 98只支持ANSI,只能为ANSI开发应用程序。 Windows CE只支持Unicode,只能为Unicode开发应用程序。 因为COM通常用于使不同的组件能够互相进行通信,而Unicode则是传递字符串的最佳手段。所以需要字符串的所有COM接口方法都只能接受Unicode字符串。2.8 如何编写Unicode源代码 C对Unicode的支持 定义一个名字为wchar_t的数据类型,它便是一个Unicode字符的数据类型。For example,如果想要创建一个缓存,用于存放最多为99个字符的Unicod

9、e字符串和一个结尾为零的字符,可以使用下面这个语句: wchar_t szBuffer100; 当然,C里面的字符串函数,如strcpy、strchr、strcat等,只能对ANSI字符串进行操作,不能正确处理Unicode,因此,ANSI C补充了一组函数: ANSI: char * strchr(const char * , int); Unicode: wchar_t * wcschr(const wchar_t * , wchar_t); ANSI: int strcmp(const char * , const char *); Unicode: int wcscmp(const w

10、char_t * , const wchar_t *); ANSI: char * strcpy(char * , const char *); Unicode: wchar_t * wcscpy(wchar_t * , const wchar_t *); ANSI: size_t strlen(const char *); Unicode size_t wcslen(const wchar_t *);请注意,所有的Unicode函数均以wcs开头,wcs是宽字符串的英文缩写。若要调用Unicode函数,只需用前缀wcs来取代ANSI字符串函数的前缀str即可。 一般情况下,对ANSI和Uni

11、code字符操作的函数不要写在同一个源代码文件中,这会给编译器编译带来很多麻烦(编译错误),但实在有必要的时候,也可以将他们放在同一个源代码文件中,这时候就需要包含一个头文件 TChar.h 。 TChar.h头文件的唯一作用是就是帮助创建ANSI/Unicode通用的源代码文件。它的工作机制是,通过一组宏,来决定调用的是str函数还是 wcs函数。For example ,在TChar.h中定义有一个宏为_tcscpy,如果在包含该头文件时没有定义_UNICODE,那_tcscpy就想当于ANSI的strcpy, 如果定义了_UNICODE,则_tcscpy想当于wcscpy函数。 还有一个

12、值得注意的是,使用了TChar.h中的宏的时候,若要生成一个Unicode字符串而不是一个ANSI字符串,则必须在字符串前加上一个大写字符L,For example : TCHAR * szError LError;大写字母L的用意是告诉编译器,该字符串应该作为Unicode字符来编译。此举随之带来的问题是,我们还需要定义个宏来动态添加大写字母L,以适应Unicode/ANSI通用源代码文件。这个宏便是_TEXT。 TCHAR *szError = _TEXR(Error);如上这样定义的话,就不论源代码文件中是否定义了_UNICODE,编译器都能够正确辨认并编译。此外,_TEXT宏还可以用于

13、检验字符串的首字母。For example : if(szError0 =_TEXT(J) /首字母为J时的处理 else /首字母不是J的时候 2004年11月9日Trackback: 第二章 UnicodeWindows 中的Unicode Windows头文件定义了几种关于Unicode的数据类型: WCHAR Unicode字符 PWSTR 指向Unicode字符串的指针 PCWSTR 指向一个恒定的Unicode字符串的指针同 时Windows头文件也定业了ANSI/Unicode的通用数据类型,PTSTR和PCTSTR,这类数据指向那一种字符,取决于当编译程序模块时是 否定义了UN

14、ICODE宏。这里这个宏UNICODE没有下划线前缀,带前缀的宏_UNICODE用于C运行期头文件。当编译源代码模块时,通常必须同时 定义这两个宏。 Windows中的函数CreatWindowsEx有两个版本,一个是接受Unicode字符串的,为CreatWindowsExW;一个接受 ANSI字符串的,为CreatWindowsExA。我们在代码中,通常只包括了对CreatWindowsEx的调用,而不是直接调用这两者,因为在 WinUser.h文件中,CreatWindowsEx实际上是定义为一个宏。故编译源代码模块时,调用的是哪CreatWindowsEx版本,取决 于你是否已作了UN

15、ICODE的定义。 若要创建供其它开发人员使用的DLL,DLL中最好提供两个输出函数,一个ANSI版本,一个Unicode版本,在ANSI版本中,只需要分配内存,执行必要的字符串转换,然后调用该函数的Unicode版本即可。 Windows的一些老函数存在一个大问题,它们不接受Unicode字符串。这时候应该避免使用这些函数。所有新的和未过时的函数在Windows2000中都同时拥有ANSI和Unicode两个版本。Windows字符串函数 Windows提供了一组范围很广的字符串操作函数,它们是操作系统的一个组成部分,常常被大型应用程序所使用。由于这些函数使用得比较多,故在你的应用 程序运行

16、时,它们可能被装进RAM,所以调用它们而不是使用C运行期库,会有助于稍稍提高你的运行性能。要使用经典的操作系统函数样式中的操作字符串的函 数,必须加上ShlWApi.h头文件。这些字符串函数,既有ANSI版,也有Unicode版本,因此,当创建应用程序时,如果定义了Unicode, 那么它们会自动扩展为宽字符版本。成为符合ANSI和Unicode的应用程序 要使你的应用程序符合Unicode,应该遵循下面一些基本原则: 1.将文本串视为字符数组,而不是chars数组或字节数组。 2.将通用数据类型(如TCHAR和PTSTR)用于文本字符和字符串。 3.将显式数据类型(如BYTE和PBYTE)用

17、于字节、字节指针和数据缓存。 4.将TEXT宏用于原义字符和字符串。 5.执行全局性替换(例如用PTSTR替换PSTR)。 6.修改字符串运算问题。例如函数通常希望你在字符中传递一个缓存的大小,而不是字节。这意味着你不应该传递sizeof(szBuffer) ,而应该传递(sizeof(szBuffer)/sizeof(TCHAR )。另外,如果需要为字符串分配一个内存块,并且拥有该字符串中的字符数目,那么请记住要按字节来分配内存。这就是说,应该调用malloc (nCharacters *sizeof(TCHAR), 而不是调用malloc(nCharacters)。在上面所说的所有原则中,

18、这是最难记住的一条原则,如果操作错误,编译器将不发出任何警告。 Windwos提供了如下一组对Unicode字符串进行操作的函数: lstrcat 将一个字符串置于另一个字符串的结尾处 lstrcmp 对两个字符串进行区分大小写的比较 lstrcmpi 对两个字符串进行不区分大小写的比较 lstrcpy 将一个字符串拷贝到内存中的另外一个位置 lstrlen 返回字符串的长度这些函数都是作为宏来实现的,即是说它们可作为Unicode/ANSI的通用版本,会根据是否定义了UNICODE而自动扩展。 Windows提供了两个函数,以便转换Unicode字符串的大小写字母: PTSTR CharLo

19、wer(PTSTR pszString); PTSTR CharUpper(PTSTR pszString);既可以转换单个字符,也可以转换以0结尾的整个字符串。若要转换整个字符串,只需要传递字符串的地址即可。若要转换单个字符,则必须像下面这样传递各个字符: TCHAR cLowerCaseChar = CharLower(PTSTR) szString0;将单个字符转换成一个PTSTR,便可调用该函数,将一个值传递给它,在这个值中,较低的16位包含了该字符,较高的16位包含0。当该函数看到较高位是0时,该函数就知道你想要转换单个字符,而不是整个字符串。返回的值是个32位值,较低的16位中是已

20、经转换的字符。 当资源编译器对你的所有资源进行编译时,输出文件是资源的二进制文件。资源(字符串表、对话框模板和菜单等)中的字符串值总是写Unicode字符串。 Windows用IsTextUnicode函数来区分所打开文本是ANSI字符还Unicode字符。 DWORD IsTextUnicode(CONST PVOID pvBuffer , int cb , PINT pResult);文 本文件存在的问题是,它们的内容没有严格和明确的规则,因此很难确定该文件是包含ANSI字符还是Unicode字符。IsTextUnicode使用一 系列统计方法和定性方法,以便猜测缓存的内容。由于这不是一种

21、确切的科学方法,因此IsTextUnicode有可能返回不正确的结果。 2004年11月11日Trackback: 第三章 内核对象 一个内核对象就是一个由内核分配的内存块,该内存块是一种数据结构,只能由该内核访问。它的成员负责维护该对象的各种信息,有些数据成员是所有对象类型中 相同的,但大多数数据成员属于特定的对象类型。比如存取符号对象、事件对象、文件对象、文件映射对象、I/O完成端口对象、作业对象、信箱对象、互斥对 象、管道对象、进程对象、信标对象、线程对象和等待计时器对象等。这些都是一个内核对象。 由于内核对象的数据结构只能被内核访问,因此应用程序无法在内存中找到这些数据结构并直接改变它们的内容,只能通过Windows提供的一组函数来对待这些结构进行操作。内核对象的使用计数 内核对象由内核所拥有,而不是由进程所拥有。换句话说,内核对象不一定

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论