整理编撰:Defoe.Tu tyysoft@yahoo.com.cn
Windows程序设计
原著: Charles Petzold
翻译: 余孟学
CHM: 壹佰软件开发小组
PDF 整理: 涂燕翼
整理编撰:Defoe.Tu tyysoft@yahoo.com.cn
基础篇
第一章 开始
本书介绍了在Microsoft Windows 98、Microsoft Windows NT 4.0和Windows NT 5.0
下程序写作的方法。这些程序用C语言编写并使用原始的Windows Application
Programming Interface(API)。如在本章稍后所讨论的,这不是写作Windows程序的唯
一方法。然而,无论最终您使用什么方式写作程序,了解Windows API都是非常重要的。
正如您可能知道的,Windows 98已成为使用Intel 32位微处理器(例如486和Pentium)
的IBM兼容型个人计算机环境上最新的图形操作系统之代表。Windows NT是IBM PC兼容
机种以及一些RISC(精简指令集计算机)工作站上使用的Windows工业增强型版本。
使用本书有三个先决条件。首先,您应该从使用者的角度熟悉Windows 98。不要期望可以
在不了解Windows使用者接口的情形下开发其应用程序。因此,我建议您在开发程序(或
在进行其它工作)时使用执行Windows的机器来跑Windows应用程序。
第二,您应了解C语言。如果要写Windows程序,一开始却不想了解C语言,那不是一个好
主意。我建议您在文字控制台环境中,例如在Windows 98 MS-DOS命令提示窗口下提供
的环境中学习C语言。Windows程序设计有时包括一些非文字模式程序设计的C语言部分;
在这些情况下,我将针对这些问题提供讨论。但大多数情况下,您应非常熟悉该语言,特别
是C语言的结构和指针。了解标准C语言执行期链接库的一些相关知识是有帮助的,但不是
必要的。
第三,您应该在机器上安装一个适于进行Windows程序设计的32位C语言编译器和开发环
境。在本书中,假定您正在使用Microsoft Visual C++ 6.0,该软件包可独立购买,也可
作为Visual Studio 6.0软件包的一部分购买。
到此为止,我将不再假设您具有任何图形使用者接口(如Windows)的程序写作经验。
WINDOWS环境
Windows几乎不需要介绍。然而人们很容易忘记Windows给办公室和家庭桌上型计算机所
带来的重大改变。Windows在其早期曾经走过一段坎坷的道路,征服桌上型计算机市场的
前途一度相当渺茫。
Windows简史
在1981年秋天IBM PC推出之后不久,MS-DOS就已经很明显成为PC上的主流操作系统。
MS-DOS代表Microsoft Disk Operating System(磁盘操作系统)。MS-DOS是一个小
型的操作系统。MS-DOS提供给用户一种命令列接口,提供如DIR和TYPE的命令,也可以
将应用程序加载内存执行。对于应用程序写作者,它提供了一组函数呼叫,进行文件的输入
输出(I/O )。对于其它的外围处理-尤其是将文字或图形写到显示器上-应用程序可以直
整理编撰:Defoe.Tu tyysoft@yahoo.com.cn
接存取PC的硬件。
由于内存和硬件的限制,成熟的图形环境缓慢地才到来。当苹果计算机公司不幸的Lisa计算
机在1983年1月发表时,它提供了不同于文字模式环境的另一种选择,并在1984年1月成
为Macintosh上图形环境的一种标准。尽管Macintosh的市场占有率在下降,但是它仍然
被认为是衡量所有其它图形环境的标准。包括Macintosh和Windows的所有图形环境,其
实都要归功于Xerox Palo Alto Research Center(PARC)在70年代中期所作的开拓性研
究工作。
Windows是由微软在1983年11月(在Lisa之后,Macintosh之前)宣布,并在两年后(1985
年11月)发行。在此后的两年中,紧随着Microsoft Windows早期版本1.0之后,又推出了
几种改进版本,以支持国际商业市场,并提供新型视讯显示器和打印机的驱动程序。
Windows版本2.0是在1987年11月正式在市场上推出的。该版本对使用者接口做了一些改
进。这些改进中最有效的是使用了可重迭式窗口,而Windows 1.0中使用的是并排式窗口。
Windows 2.0还增强了键盘和鼠标接口,特别是加入了菜单和对话框。
至此,Windows还只要求Intel 8086或者8088等级的微处理器,以「实际模式」执行,只
能存取地址在1MB以下的内存。Windows/386(在Windows 2.0之后不久发行的)使用
Intel 386微处理器的「虚拟8086」模式,实现将直接存取硬件的多个MS-DOS程序窗口
化和多任务化。为了统一起见,Windows版本2.1被更名为Windows/286。
Windows 3.0是在1990年5月22日发表的。它将Windows/286和Windows/386结合到
同一种产品中。Windows 3.0有了一个很大的改变,这就是对Intel的286、386和486微
处理器保护模式的支持。这能使Windows和Windows应用程序能存取高达16MB的内存。
Windows用于执行程序和维护文件的「外壳」程序得到了全面的改进。Windows 3.0是第
一个在家用和办公室市场上取得立足点的版本。
任何Windows的历史介绍都必须包括一些OS/2的说明,OS/2是对DOS和Windows的另
一种选择,最初是由Microsoft和IBM合作开发的。OS/2版本1.0(只有文字模式)在Intel
286(或者后来的)微处理器上运行,在1987年末发布。在1988年10月的OS/2版本1.1
中出现了管理图形使用者接口的PM(Presentation Manager)。PM最初的设计构想是成
为Windows的一种保护模式版本,但是图形API改变程度太大,致使软件生产厂商很难提供
对这两种平台的支持。
到1990年9月,IBM和Microsoft之间的冲突达到了高峰,导致这两个公司最后分道扬镳。
IBM接管了OS/2,而Microsoft明确表示Windows将是他们操作系统策略的中心。虽然
OS/2仍然拥有一些狂热的崇拜者,但是它远不及Windows这样的普及程度。
Microsoft Windows版本3.1是1992年4月发布的,其中包括的几个重要特性是TrueType
字体技术(给Windows带来可缩放的轮廓字体)、多媒体(声音和音乐)、对象连结和嵌入
(OLE:Object Linking and Embedding)和通用对话框。跟OS/2一样,Windows 3.1
只能在保护模式下运作,并且要求至少配置了1MB内存的286或386处理器。
在1993年7月发表的Windows NT是第一个支持Intel 386、486和Pentium微处理器32位
保护模式的Windows版本。Windows NT提供32位平坦寻址,并使用32位的指令集。(本
章后面我会谈到一些寻址空间的问题)。Windows NT还可以移植到非Intel处理器上,并在
几种使用RISC芯片的工作站上执行。
Windows 95是在1995年8月发布的。和Windows NT一样,Windows 95也支持Intel 386
或更高等级处理器的32位保护模式。虽然它缺少Windows NT中的某些功能,诸如高安全
整理编撰:Defoe.Tu tyysoft@yahoo.com.cn
性和对RISC机器的可移植性等,但是Windows 95具有需要较少硬件资源的优点。
Windows 98在1998年6月发布,具有许多加强功能,包括执行效能的提高、更好的硬件
支持以及与因特网和全球信息网(WWW)更紧密的结合。
Windows方面
Windows 98和Windows NT都是支持32位优先权式多任务(preemptive multitasking)
及多线程的图形操作系统。Windows拥有图形使用者接口(GUI ),这种使用者界面也称作
「可视化接口」或「图形窗口环境」。有关GUI的概念可追溯至70年代中期,在Alto和Star
等机器上以及SmallTalk等环境中由Xerox PARC所作的研究工作。该项研究的成果后来被
Apple Computer和Microsoft引入主流并流行起来。虽然有一些争议,但现在已非常清楚,
GUI是(Microsoft的Charles Simonyi的说法)一个在个人计算机工业史上集各方面技术
大成于一体的最重要产物。
所有GUI都在点矩阵对应的视讯显示器上处理图形。图形提供了使用屏幕的最佳方式、传递
信息的可视化丰富多彩环境,以及能够WYSIWYG(what you see is what you get:所
见即所得)的图形视讯显示和为书面文件准备好格式化文字输出内容。
在早期,视讯显示器仅用于响应使用者通过键盘输入的文字。在图形使用者接口中,视讯显
示器自身成为使用者输入的一个来源。视讯显示器以图标和输入设备(例如按钮和滚动条)
的形式显示多种图形对象。使用者可以使用键盘(或者更直接地使用鼠标等指向设备)直接
在屏幕上操纵这些对象,拖动图形对象、按下鼠标按钮以及滚动滚动条。
因此,使用者与程序的交流变得更为亲密。这不再是一种从键盘到程序,再到视讯显示器的
单向信息流动,使用者已经能够与显示器上的对象直接交互作用了。
使用者不再需要花费长时间学习如何使用计算机或掌握新程序了。Windows让这一切成真,
因为所有应用程序都有相同的基本外观和感觉。程序占据一个窗口-屏幕上的一块矩形区
域。每个窗口由一个标题列标识。大多数程序功能由程序的菜单开始。用户可使用滚动条观
察那些无法在一个屏幕中装下的信息。某些菜单项目触发对话框,用户可在其中输入额外的
信息。几乎在每个大的Windows程序中都有一个用于开启文件的特殊对话框。该对话框在
所有这些Windows程序中看起来都一样(或接近相同),而且几乎总是从同一菜单选项中启
动。
一旦您了解使用一个Windows程序的方法,您就非常容易学习其它的Windows程序。菜单
和对话框允许用户试验一个新程序并探究它的功能。大多数Windows程序同时具有键盘接
口和鼠标接口。虽然Windows程序的大多数功能可通过键盘控制,但使用鼠标要容易得多。
从程序写作者的角度看,一致的使用者接口来自于Windows建构菜单和对话框的内置程序。
所有菜单都有同样的键盘和鼠标接口,因为这项工作是由Windows处理,而不是由应用程
序处理。
为便于多个程序的使用,以及这些程序间信息的交换,Windows支持多任务。在同一时刻
能有多个Windows程序显示并运行。每个程序在屏幕上占据一个窗口。用户可在屏幕上移
动窗口,改变它们的大小,在不同程序间切换,并从一个程序向另一个程序传送数据。因为
这些窗口看起来有些像桌面上的纸(当然,这是计算机还未占据办公桌之前的年代),
Windows有时被称作:一个显示多个程序的「具象化桌面」。
Windows的早期版本使用一种「非优先权式(non-preemptive)」的多任务系统。这意味
整理编撰:Defoe.Tu tyysoft@yahoo.com.cn
着Windows不使用系统定时器将处理时间分配给系统中运行的多个应用程序,程序必须自
愿放弃控制以便其它程序运行。在Windows NT和Windows 98中,多任务是优先权式的,
而且程序自身可分割成近乎同时执行的多个执行绪。
操作系统不对内存进行管理便无法实现多任务。当新程序启动、旧程序终止时,内存会出现
碎裂空间。系统必须能够将闲置的内存空间组织在一起,因此系统必须能够移动内存中的程
序代码和数据块。
即使是在8088微处理器上跑的Windows 1.0也能进行这类内存管理。在实际模式限制下,
这种能力被认为是软件工程一个令人惊讶的成就。在Windows 1.0中,PC硬件结构的
640KB内存限制,在不要求任何额外内存的情况下被有效地扩展了。但Microsoft并未就此
停步:Windows 2.0允许Windows应用程序存取扩充内存(EMS);Windows 3.0在保护
模式下,允许Windows应用程序存取高达16MB的扩展内存。Windows NT和Windows 98
通过成熟的32位操作系统及平坦寻址空间,摆脱了这些旧的限制。
Windows上执行的程序可共享在称为「动态链接库」的文件中的例程。Windows包括一个
机制,能够在执行时连结使用动态链接库中例程的程序。Windows自身基本上就是一个动
态链接库的集合。
Windows是一个图形接口,Windows程序能够在视讯显示器和打印机上充分利用图形和格
式化文字。图形接口不仅在外观上更有吸引力,而且还能够让使用者传递高层次的信息。
Windows应用程序不能直接存取屏幕和打印机等图形显示设备硬件。相反,Windows提供
一种图形程序语言(称作图形设备接口,或者GDI),使显示图形和格式化文字更容易。
Windows虚拟化了显示硬件,使为Windows编写的程序可使用任何具有Windows设备驱
动程序的视频卡或打印机,而程序无需确定系统相连的设备类型。
对Windows开发者来说,将与设备无关的图形接口输出到IBM PC上不是件轻松的事。PC
的设计是基于开放式架构的原则,鼓励第三方硬件制造商为PC开发接口设备,而且开发了
大量这样的设备。虽然出现了多种标准,PC上的传统MS-DOS程序仍不得不各自支持许多
不同的硬设备。这对MS-DOS字处理软件来说非常普遍,它们连同1到2张有许多小文件的
磁盘一同销售,每个文件支持一种特定的打印机。Windows程序不要求每个应用程序都自
行开发这些驱动程序,因为这种支持是Windows的一部分。
动态链接
Windows运作机制的核心是一个称作「动态链接」的概念。Windows提供了应用程序丰富
的可呼叫函数,大多数用于实作其使用者接口和在视讯显示器上显示文字和图形。这些函数
采用动态链接库(Dynamic Linking Library,DLL)的方式撰写。这些动态链接库是些
具 有 .DLL 或 者 有 时 是 .EXE 扩 展 名 的 文 件,在Windows 98中通常位于
\WINDOWS\SYSTEM子目录中,在Windows NT中通常位于\WINNT\SYSTEM和
\WINNT\SYSTEM32子目录中。
在早期,Windows的主要部分仅通过三个动态链接库实作。这代表了Windows的三个主要
子系统,它们被称作Kernel、User和GDI。当子系统的数目在Windows最近版本中增多时,
大多数典型的Windows程序产生的函数呼叫仍对应到这三个模块之一。Kernel(日前由16
位的KRNL386.EXE和32位的KERNEL32.DLL实现)处理所有在传统上由操作系统核心
处理的事务-内存管理、文件I/O和多任务管理。User(由16位的USER.EXE和32位的
USER32.DLL实作)指使用者接口,实作所有窗口运作机制。GDI(由16位的GDI.EXE