没有合适的资源?快使用搜索试试~ 我知道了~
Windows核心编程-第五版(中文前六章)
需积分: 10 1 下载量 78 浏览量
2014-01-16
16:30:56
上传
评论
收藏 2.03MB PDF 举报
温馨提示
Windows核心编程-第五版(中文前六章)
资源推荐
资源详情
资源评论
继往开来创新高,推陈出新品佳酿
1993 年,本书第 1 版 Advanced NT 出版的时候,我和三个朋友一起成立了一个“四喜工作
室”。由于四个人只有一台计算机,所以我们几个每天一睁眼,第一件事情便是抢占计算机,
这台 386 配置简单,根本无法与现在的计算机相提并论,而且当时也没有网络,所以计算机
的用途非常有限,主要也就是文字处理,玩游戏,编简单程序等,但它带给我们的乐趣至今
难以忘怀。受限于当时的环境,数据和游戏的交换也基本上在圈内好友之间进行,就像搞地
下活动一样约好时间地点碰头。幸运的是,由此结交了一大批计算机爱好者,后来他们大多
成为 IT 届的领军人物。
其时,从大环境看,我国网络也开始悄然起步。1993 年年初,中国科学院高能物理研究所
接入斯坦福大学线性加速器中心的 64K 专线开通,国内科学家开始在国内使用电子邮件。
随后几个月的时间,金桥工程和域名体系的确立和部署,三大院校网的连接,最终将我国带
入信息高速公路,推动我国 IT 业的迅猛发展。
由此而来的便是计算机类图书和报纸期刊的炙手可热,《电脑报》等 IT 媒体相继崛起,计
算机图书更是出现供不应求的现象,在当时,即便是国外引进翻译出版的图书,也能轻松突
破几万册的销量,计算机图书的发展达到全盛时期。
在这个时期,国内开发人员先后成为 Jeffrey 和 McConell 等大师的拥趸。因为在 IT 界,虽
然资深程序员不胜枚举,但同时又是深受程序员喜爱的技术图书作家的乏善可陈。而像他们
那样,曾经写过多部书,部部都引人入胜,令人醍醐灌顶,就更是凤毛麟角。他们是 Windows
编程世界中的中流砥柱,也是 Windows 技术当之无愧的布道者。曾有不少读者放言,只要
是 Jeffrey 的书,他们必定会花时间研读,并加以收藏。这一点都不夸张,我们同时代的很
多人都是在这批书的滋润下成长起来的。他们熟读了 Advanced NT 之后,又如痴如狂地捧起
了 Advanced Windows 和 Programming Application for Microsoft Windows 等续作。他们是
Jeffrey 的粉丝,同时也是微软开发阵营的主力军。
随着微软宣布放弃对 Windows XP 以及以前版本的支持,Windows Vista 的普及势在必行,
迟早会安装到普通用户的计算机上。Windows Vista 有很多吸引人的新特性,相信大家不用
不知道,一用忘不了。(在翻译 Microsoft Press 的 Windows Vista Inside Out 一书的过程中,
我已经深切体会到她的妙处)。作为一名程序员,有必要在第一时间适应在新的操作系统下
的编程。历经 15 年,本书也随着 Windows 操作系统的“改朝换代”,升级到第 5 版,即
Windows via C/C++。如果您要用 C/C++开发 Windows 应用程序,那就不要走弯路,直接让
Jeffrey 告诉您如何利用 Windows 的新特性和新函数来编写出高效、优美的 Windows 应用程
序。
对于本书的学习,谨以《史记 孔子世家》中孔子学琴一文与大家共勉(请原谅,这里引用
了我另一本书的译序,其寓意深刻,忍不住又拿出来与大家分享☺):
孔子学鼓琴师襄子,十日不进。师襄子曰:
“
可以益矣。
”
孔子曰:
“
丘已习其曲矣,未得其
数也。
”
有间,曰:
“
已习其数,可以益矣。
”
孔子曰:
“
丘未得其志也。
”
有间,曰:
“
已习
其志,可以益矣。
”
孔子曰:
“
丘未得其为人也。
”
有间,有所穆然深思焉,有所怡然高望而
远志焉。曰:
“
丘得其为人,黯然而黑,几然而长,眼如望羊,如王四国,非文王其谁能为
此也!
”
师襄子辟席再拜,曰:
“
师盖云文王操也。
”
期望读者朋友也能达到学习的三大境界:学习掌握演奏(编程)的技巧;领会其中的志趣;
熟悉乐曲(程序)的作者。
翻译过程中,感谢我的家人和朋友的诸多帮助和理解,尤其
要感谢我的乖女儿。这个暑假,
她的成长令人激赏!
最后,欢迎读者指出本书的疏漏和不足之处 ,如果你对我翻译的部分(1~6 章)有什么意
见和建议,请访问我的博客(transbot.blog.163.com)指出,那里为我翻译的一些图书开辟了
专栏,专门用于和读者们分享勘误和其他有用的信息。
周 靖
Beijing 2008 前夕
第Ⅰ部分程序员必读
本部分内容包括:
第 1 章错误处理
第 2 章字符和字符串处理
第 3 章内核对象
第 1 章错误处理
本章内容包括:
1.1定义自己的错误代码
1.2ErrorShow 示例程序
在深入讨论 Microsoft Windows 提供的诸多特性之前,应该先理解各个 Windows 函数是如
何进行错误处理的。
调用 Windows 函数时,它会先验证你传给它的参数,然后再开始执行任务。如果传入的参
数无效,或者由于其他原因导致操作无法执行,则函数的返回值将指出函数在某个方面失败
了。表 1-1 展示了大多数 Windows 函数使用的返回值的数据类型。
表 1-1 常见的 Windows 函数返回值数据类型
数据类型 指出函数调用失败的值
VOID 这个函数不可能失败。只有极少数 Windows 函数的返回值类型为 VOID。
BOOL 如果函数失败,返回值为 0;否则,返回值是一个非零值。应避免测试返
回值是否为 TRUE;最稳妥的做法是检查它是否不为 FALSE。
HANDLE 如果函数失败,则返回值通常为 NULL;否则,HANDLE 将标识一个你
可以操纵的对象。请注意这种返回值,因为某些函数会返回为
INVALID_HANDLE_VALUE 的一个句柄值,它被定义为–1。函数的
Platform SDK 文档清楚说明了函数是返回 NULL 还是
INVALID_HANDLE_VALUE 来标识失败。
PVOID 如果函数调用失败,返回值为 NULL;否则,PVOID 将标识一个数据块
的内存地址。
LONG/DWORD 这种类型比较棘手。返回计数的函数通常会返回一个 LONG 或 DWORD。
如果函数出于某种原因不能对你想要计数的东西进行计数,它通常会返回
0 或–1(具体取决于函数)。如果要调用一个返回 LONG/DWORD 的函
数,务必仔细阅读 Platform SDK 文档,确保你将正确地检查可能出现的
错误。
如果一个 Windows 函数能返回错误代码,通常有助于我们理解函数调用为什么会失败。
Microsoft 编辑了一个列表,其中列出了所有可能的错误代码,并为每个错误代码都分配了
一个 32 位的编号。
在内部,当一个 Windows 函数检测到错误时,它会使用一个名为“线程本地存储区”
(thread-local storage)的机制将恰当的错误代码与“主调线程”(或者说发出调用的线程,
即 calling thread)关联到一起(线程本地存储区的详情将在第 21 章讨论)。这个机制使不
同的线程能独立运行,不会出现相互干扰对方的错误代码的情况。函数返回时,其返回值会
指出已发生一个错误。要查看具体是什么错误,请调用 GetLastError 函数:
DWORD GetLastError();
它的作用很简单,就是返回由上一个函数调用设置的线程的 32 位错误代码。
有了 32 位错误代码之后,接着需要把它转换为更有用的信息。WinError.h 头文件包含了
Microsoft 定义的错误代码列表。为便于你体验,下面摘录了其中的一部分:
// MessageId: ERROR_SUCCESS
//
// MessageText:
//
// The operation completed successfully.
//
#define ERROR_SUCCESS 0L
#define NO_ERROR 0L // dderror
#define SEC_E_OK ((HRESULT)0x00000000L)
//
// MessageId: ERROR_INVALID_FUNCTION
//
// MessageText:
//
// Incorrect function.
//
#define ERROR_INVALID_FUNCTION 1L // dderror
//
// MessageId: ERROR_FILE_NOT_FOUND
//
// MessageText:
//
// The system cannot find the file specified.
//
#define ERROR_FILE_NOT_FOUND 2L
//
// MessageId: ERROR_PATH_NOT_FOUND
//
// MessageText:
//
// The system cannot find the path specified.
//
#define ERROR_PATH_NOT_FOUND 3L
//
// MessageId: ERROR_TOO_MANY_OPEN_FILES
//
// MessageText:
//
// The system cannot open the file.
//
#define ERROR_TOO_MANY_OPEN_FILES 4L
//
// MessageId: ERROR_ACCESS_DENIED
//
// MessageText:
//
// Access is denied.
//
#define ERROR_ACCESS_DENIED 5L
可以看出,每个错误都有三种表示:一个消息 ID(一个可在源代码中使用的宏,用于与
GetLastError 的返回值进行比较)、消息文本(描述错误的英文文本)和一个编号(应该避免
使用此编号,尽量使用消息 ID)。注意,我只摘录了 WinError.h 头文件的极小一部分,整
个文件的长度超过 39 000 行!
一个 Windows函数失败之后,应该马上调用 GetLastError,因为假如又调用了另一个 Windows
函数,则此值很可能被改写。注意,成功调用的 Windows 函数可能用 ERROR_SUCCESS
改写此值。
一些 Windows 函数调用成功可能是缘于不同的原因。例如,创建一个命名的事件内核对象
时,以下两种情况均会成功:对象实际地完成创建,或者存在一个同名的事件内核对象。应
用程序也许需要知道成功的原因。为返回这种信息,Microsoft 选择采用“上一个错误代码”
(last error code)机制。所以,当特定函数成功时,你可以调用 GetLastError 来确定额外的
信息。对于具有这种行为的函数,Platform SDK 文档会清楚指明能以这种方式使用
GetLastError。文档中提供了 CreateEvent 函数的一个例子;如果存在命名的事件,它会返回
ERROR_ALREADY_EXISTS。
调试程序时,我发现对线程的“上一个错误代码”进行监视是相当有用的。在 Microsoft Visual
Studio 中,Microsoft 的调试器支持一个很有用的功能——你可以配置 Watch 窗口,让它始
终显示线程的上一个错误代码和错误的文本描述。具体的做法是:在 Watch 窗口中选择一
行,然后输入$err,hr。来看看图 1-1 的例子。在这个例子中,我已经调用了 CreateFile 函数。
该函数返回值为 INVALID_HANDLE_VALUE (–1)的一个 HANDLE,指出它无法打开指定
文件。但是 Watch 窗口指出,上一个错误代码(也就是调用 GetLastError 函数返回的错误代
码)是 0x00000002。多亏有了,hr 限定符,Watch 窗口进一步指出错误代码 2 是“ The system
cannot find the file specified”(系统找不到指定文件)。这就是在 WinError.h 头文件中为错
误代码 2 列出的消息文本。
剩余149页未读,继续阅读
资源评论
iHornet
- 粉丝: 0
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功