第1章 Windows编程开发环境 1
1.1 Windows操作系统及其内核 1
1.1.1 已有的Windows平台 1
1.1.2 新一代Windows平台——Windows XP 2
1.1.3 未来的Windows平台——64位Windows 3
1.2 集成性开发环境Developer Studio 5
1.2.1 Microsoft Visual C++和DeveloperStudio 5
1.2.2 新一代集成性开发环境Visual Studio.net 10
1.3 使用编程帮助 11
1.3.1 为什么需要帮助 11
1.3.2 如何使用帮助 11
1.4 自定义Developer Studio 13
1.4.1 自定义工具条和菜单栏 13
1.4.2 自定义快捷键 14
2.1.1 消息驱动机制 15
2.1 Windows程序设计的特点 15
第2章 Win32程序设计 15
2.1.2 图形输出及设备无关性 19
2.1.3 标准的用户界面对象 20
2.1.4 Windows资源的共享 24
2.2 Windows应用程序组成 25
2.3 用SDK进行Win32程序设计 27
2.3.1 Win32 API和SDK 27
2.3.2 Win32程序设计的特点 28
2.3.3 实例——禁止进程的多个实例存在 38
2.4 初识进程、线程和内存分配 42
2.4.1 进程与线程的问题 42
2.4.2 32位应用程序的内存分配 43
2.4.3 32位应用程序的内存管理模式 45
2.5 本章实例——消息监视专家Spy 51
3.1 控件 75
第3章 Windows用户界面 75
3.1.1 按钮 77
3.1.2 组合框 78
3.1.3 编辑控件 81
3.1.4 列表框 85
3.1.5 滚动条 88
3.1.6 静态控件 94
3.2 资源 96
3.2.1 光标 99
3.2.2 图标 103
3.2.3 菜单 104
3.2.4 字符串 104
3.3 用户输入 105
3.3.1 通用对话框 105
3.3.3 键盘输入 107
3.3.2 鼠标输入 107
3.4 窗口 111
3.5 实例1——迷你视频终端VideoTerminal 115
3.6 实例2——自定义资源的程序WinMainSample 130
第4章 Windows程序员基础 137
4.1 Windows对错误的处理 137
4.1.1 错误代码表 137
4.1.2 获取错误信息——GetLastError() 140
4.1.3 错误代码转换工具 140
4.1.4 自定义错误代码 142
4.2 Unicode编程与软件本地化 143
4.2.1 为什么要选择Unicode 143
4.2.2 如何编写Unicode源代码 146
4.2.3 使自己的应用程序符合Unicode规范 151
4.2.4 如何区分ANSI文本和Unicode文本 153
4.2.5 在多字节字符与宽字节字符之间转换 154
4.3 内核对象的概念 157
4.3.1 什么是内核对象 157
4.3.2 管理和操作内核对象 160
4.3.3 进程间共享内核对象 163
4.4 本章实例——Unicode转换大师UConvert 171
第5章 进程 186
5.1 进程的实例句柄 186
5.2 进程的命令行和环境变量 187
5.2.1 进程的命令行 187
5.2.2 进程的环境变量 188
5.3 进程的当前驱动器和当前目录 193
5.4 进程的亲缘性 195
5.5 进程的错误模式 196
5.6 创建进程与终止进程 196
5.6.1 创建进程函数CreateProcess() 196
5.6.2 终止进程 205
5.7 子进程 207
5.8 本章实例1——进程查看器ProcessView 208
5.9 本章实例2——事件调试浏览器Debug Event Browser 222
第6章 进程的作业 235
6.1 对作业进程的限制 235
6.2 将进程放入作业和终止作业 237
6.2.1 将进程放入作业 237
6.2.2 终止作业中的进程 238
6.3 查询作业信息 238
6.4 作业通知信息 241
第7章 线程基础 243
7.1 由进程到线程 243
7.2 线程的使用条件 244
7.2.1 何时能够使用线程 244
7.3.1 线程函数的编写 245
7.2.2 何时不能使用线程 245
7.3 线程的创建与终止 245
7.3.2 线程的创建 246
7.3.3 线程的终止 249
7.3.4 深入了解线程本质 251
7.4 C/C++运行时库与线程 254
7.4.1 C/C++运行时库的问题 254
7.4.2 C/C++运行时库函数与局部数据块tiddata 255
7.4.3 为什么不调用CreateThread()创建线程 259
7.4.4 不应该调用的C/C++运行时库函数 259
7.5 线程在系统中的ID 260
7.5.1 通过ID操作线程 260
7.5.2 将伪句柄转换为实句柄 261
7.6.1 工作线程 263
7.6.2 用户界面线程 263
7.6 线程分类 263
7.7 本章实例——文件比较工具WinDiff 264
第8章 线程的调度、优先级和亲缘性 288
8.1 线程的调度 288
8.1.1 系统对线程的调度过程 288
8.1.2 暂停和恢复线程的运行 290
8.1.3 睡眠方式 291
8.1.4 转换到另一个线程 291
8.1.5 线程的运行时间 292
8.1.6 CONTEXT结构 293
8.2 优先级 300
8.2.1 线程的优先级 300
8.2.2 优先级的抽象理解 301
8.2.3 使用优先级编程 304
8.3.1 软亲缘性和硬亲缘性 309
8.3 亲缘性 309
8.3.2 进程的亲缘性屏蔽 310
8.3.3 进程中线程的亲缘性屏蔽 311
8.4 本章实例——一个多线程程序MThread 312
第9章 线程的同步 322
9.1 用户模式中的线程同步 322
9.1.1 原子访问与互锁函数 322
9.1.2 高级线程同步 326
9.1.3 高速缓存行 328
9.1.4 临界代码区 329
9.2 线程与内核对象的同步 338
9.2.1 已通知状态与未通知状态 338
9.2.2 等待函数 339
9.2.3 事件(Event) 342
9.2.4 等待定时器(Waitable Timer) 346
9.2.5 信号量(Semaphore) 349
9.2.6 互斥对象(Mutex) 352
9.2.7 线程同步对象速查表 355
9.2.8 其他线程同步函数 356
9.3 线程池 358
9.4 本章实例——声音的获取与回放(AudioLoop) 368
第10章 线程的堆栈与纤程 382
10.1 线程的堆栈 382
10.1.1 Windows 2000下的线程堆栈 382
10.1.2 Windows 98下的线程堆栈 384
10.2 纤程 386
10.2.1 纤程的意义 386
10.2.2 纤程的使用 386
10.3 本章实例——基于纤程的文件拷贝器Fibers 388
11.1 系统信息 400
11.1.1 硬件配置 400
第11章 系统信息与注册表 400
11.1.2 操作系统版本 403
11.1.3 计算机名 406
11.1.4 操作系统配置 406
11.1.5 系统参数 409
11.1.6 系统尺寸 410
11.2 注册表 411
11.2.1 注册表结构 412
11.2.2 注册表存储空间 413
11.2.3 预定义的关键字 413
11.2.4 数据分类 414
11.2.5 关键字的打开、创建与关闭 415
11.2.6 注册表数据的添加和删除 416
11.2.7 注册表关键字的安全属性与访问权限 417
11.2.8 从注册表中检索数据 418
11.2.9 注册表文件 420
11.2.10 注册表的使用 421
11.3 本章实例——注册表读取专家Registry 424
第12章 虚拟内存 440
12.1 进程的虚拟地址空间 440
12.1.1 虚拟地址空间的分区 441
12.1.2 地址空间中区域的管理 442
12.1.3 地址空间区域中物理内存的占用 445
12.1.4 实例——创建保护页面 449
12.1.5 CPU的数据对齐特性 451
12.2 虚拟内存的状态 452
12.2.1 内存的使用状态 452
12.2.2 虚拟地址空间的状态 454
12.3 地址窗口扩展 456
12.4 本章实例——虚拟内存的管理员Walker 464
13.1 关于文件映射 492
第13章 文件映射 492
13.1.2 文件映射的优势 493
13.1.1 文件视图的数据一致性 493
13.2 使用文件映射 494
13.2.1 创建或打开文件内核对象 494
13.2.2 创建文件映射内核对象 495
13.2.3 创建文件视图 497
13.2.4 撤销文件视图 499
13.2.5 关闭文件映射对象和文件对象 500
13.2.6 两个文件映射的例子 501
13.3 几个不同类型文件的内存映射 505
13.3.1 EXE文件和DLL文件的映射 505
13.3.2 数据文件的映射 508
13.4 共享文件和内存 510
13.5 本章实例——实现命名共享内存的程序Memory 513
14.1.1 堆栈的概念 525
14.1.2 进程的默认堆栈 525
第14章 内存堆栈 525
14.1 关于内存堆栈 525
14.2 创建与使用内存堆栈 526
14.2.1 为什么要创建内存堆栈 526
14.2.2 如何使用内存堆栈 529
14.2.3 C++程序中如何使用堆栈 534
14.3 其他堆栈函数的使用 537
14.4 本章实例——多线程的堆栈管理器MpHeap 541
第15章 动态链接库 564
15.1 为什么要使用DLL 564
15.2 DLL在进程的地址空间 565
15.3 DLL的隐式链接 565
15.3.1 DLL模块的创建 567
15.3.2 EXE模块的创建 569
15.3.3 EXE模块的运行 570
15.4 DLL的显式链接 571
15.4.1 显式加载DLL模块 572
15.4.2 显式卸载DLL模块 573
15.4.3 DLL的使用计数 574
15.4.4 获得输出符号地址 575
15.5 DLL的进入点函数 575
15.5.1 DllMain()函数 575
15.5.2 C/C++运行时库的情况 579
15.6 DLL的高级使用 580
15.6.1 延迟加载DLL 580
15.6.2 操作系统的DLL 586
15.6.3 DLL的转移 587
15.6.4 模块的移位 588
15.6.5 模块的绑定 593
15.6.6 线程本地存储器 595
15.7 本章实例1——一个简单的动态链接库程序dll 600
15.8 本章实例2——标准DLL的创建实例SpinCube 612
第16章 结构化异常处理 632
16.1 关于结构化异常处理 632
16.1.1 异常处理 633
16.1.2 基于帧的异常处理 639
16.1.3 结束处理 640
16.1.4 处理器的文法结构 641
16.2 结构化异常处理的使用 644
16.2.1 使用异常处理器 645
16.2.2 使用结束处理器 649
16.3 结构化异常与C++异常的对比 650
16.4 本章实例——模式匹配查找工具Asyncio 654