Windows编程和面向对象技术

1.1 Windows发展历史

    Windows起源可以追溯到Xerox公司进行的工作。1970年,美国Xerox公司成立了著名的研究机构Palo Alto Research Center(PARC),从事局域网、激光打印机、图形用户接口和面向对象技术的研究,并于1981年宣布推出世界上第一个商用的GUI(图形用户接口)系统:Star 8010工作站。但如后来许多公司一样,由于种种原因,技术上的先进性并没有给它带来它所期望的商业上的成功。

    当时,Apple Computer公司的创始人之一Steve Jobs,在参观Xerox公司的PARC研究中心后,认识到了图形用户接口的重要性以及广阔的市场前景,开始着手进行自己的GUI系统研究开发工作,并于1983年研制成功第一个GUI系统:Apple Lisa。随后不久,Apple又推出第二个GUI系统Apple Macintosh,这是世界上第一个成功的商用GUI系统。当时,Apple公司在开发Macintosh时,出于市场战略上的考虑,只开发了Apple公司自己的微机上的GUI系统,而此时,基于Intel x86微处理器芯片的IBM兼容微机已渐露峥嵘。这样,就给Microsoft公司开发Windows提供了发展空间和市场。

    Microsoft公司早就意识到建立行业标准的重要性,在1983年春季就宣布开始研究开发Windows,希望它能够成为基于Intel x86微处理芯片计算机上的标准GUI操作系统。它在1985年和1987年分别推出Windows 1.03版和Windows2.0版。但是,由于当时硬件和DOS操作系统的限制,这两个版本并没有取得很大的成功。此后,Microsoft公司对Windows的内存管理、图形界面做了重大改进,使图形界面更加美观并支持虚拟内存。Microsoft于1990年5月份推出Windows3.0并一炮打红。这个“千呼万唤始出来”的操作系统一经面世便在商业上取得惊人的成功:不到6周,Microsoft公司销出50万份Windows3.0拷贝,打破了任何软件产品的6周销售记录,从而一举奠定了Microsoft在操作系统上的垄断地位。

    一年之后推出的Windows3.1对Windows 3.0作了一些改进,引入TrueType字体技术,这是一种可缩放的字体技术,它改进了性能;还引入了一种新设计的文件管理程序,改进了系统的可靠性。更重要的是增加对象链接合嵌入技术(OLE)和多媒体技术的支持。Windows3.0和Windows3.1都必须运行于MS DOS操作系统之上。

    随后,Microsoft借Windows东风,于1995年推出新一代操作系统Windows95(又名Chicago),它可以独立运行而无需DOS支持。Windows95是操作系统发展史上一个里程碑式的作品,它对Windows3.1版作了许多重大改进,包括:更加优秀的、面向对象的图形用户界面,从而减轻了用户的学习负担;全32位的高性能的抢先式多任务和多线程;内置的对Internet的支持;更加高级的多媒体支持(声音、图形、影像等),可以直接写屏并很好的支持游戏;即插即用,简化用户配置硬件操作,并避免了硬件上的冲突;32位线性寻址的内存管理和良好的向下兼容性等等。以后我们提到的Windows一般均指Windows95。 

 


1.2  Windows操作系统特点

           Windows之所以取得成功,主要在于它具有以下优点:

直观、高效的面向对象的图形用户界面,易学易用:

从某种意义上说,Windows用户界面和开发环境都是面向对象的。用户采用“选择对象-操作对象”这种方式进行工作。比如要打开一个文档,我们首先用鼠标或键盘选择该文档,然后从右键菜单中选择“打开”操作,打开该文档。这种操作方式模拟了现实世界的行为,易于理解、学习和使用。

用户界面统一、友好、漂亮:

Windows应用程序大多符合IBM公司提出的CUA (Common User Acess)标准,所有的程序拥有相同的或相似的基本外观,包括窗口、菜单、工具条等。用户只要掌握其中一个,就不难学会其他软件,从而降低了用户培训学习的费用。

丰富的设备无关的图形操作:

Windows的图形设备接口(GDI)提供了丰富的图形操作函数,可以绘制出诸如线、圆、框等的几何图形,并支持各种输出设备。设备无关意味着在针式打印机上和高分辨率的显示器上都能显示出相同效果的图形。

多任务:

Windows是一个多任务的操作环境,它允许用户同时运行多个应用程序,或在一个程序中同时做几件事情。每个程序在屏幕上占据一块矩形区域,这个区域称为窗口,窗口是可以重叠的。用户可以移动这些窗口,或在不同的应用程序之间进行切换,并可以在程序之间进行手工和自动的数据交换和通信。

虽然同一时刻计算机可以运行多个应用程序,但仅有一个是处于活动状态的,其标题栏呈现高亮颜色。一个活动的程序是指当前能够接收用户键盘输入的程序。


1.3 Windows应用程序设计的特点

    如前所述,Windows操作系统具有MS-DOS操作系统无可比拟的优点,因而受到了广大软件开发人员的亲睐。但是,熟悉DOS环境下软件开发的程序员很快就会发现,Windows编程与DOS环境下编程相比有很大的不同。Windows要求以一种全新的思维方式进行程序设计,主要表现为以下几点:

1.3.1事件驱动的程序设计

    传统的MS-DOS程序主要采用顺序的、关联的、过程驱动的程序设计方法。一个程序是一系列预先定义好的操作序列的组合,它具有一定的开头、中间过程和结束。程序直接控制程序事件和过程的顺序。这样的程序设计方法是面向程序而不是面向用户的,交互性差,用户界面不够友好,因为它强迫用户按照某种不可更改的模式进行工作。它的基本模型如图1.1所示。
    事件驱动程序设计是一种全新的程序设计方法,它不是由事件的顺序来控制,而是由事件的发生来控制,而这种事件的发生是随机的、不确定的,并没有预定的顺序,这样就允许程序的的用户用各种合理的顺序来安排程序的流程。对于需要用户交互的应用程序来说,事件驱动的程序设计有着过程驱动方法无法替代的优点。它是一种面向用户的程序设计方法,它在程序设计过程中除了完成所需功能之外,更多的考虑了用户可能的各种输入,并针对性的设计相应的处理程序。它是一种“被动”式程序设计方法,程序开始运行时,处于等待用户输入事件状态,然后取得事件并作出相应反应,处理完毕又返回并处于等待事件状态。它的框图如图1.2所示:
    在图中,输入界面1-4并没有固定的顺序,用户可以随机选取,以任何合理的顺序来输入数据。

图1.1 过程驱动模型

1.2事件驱动程序模型

1.3.2 消息循环与输入

    事件驱动围绕着消息的产生与处理展开,一条消息是关于发生的事件的消息。事件驱动是靠消息循环机制来实现的。
    消息是一种报告有关事件发生的通知。
    消息类似于DOS下的用户输入,但比DOS的输入来源要广,Windows应用程序的消息来源有以下四种:
    (1)输入消息:包括键盘和鼠标的输入。这一类消息首先放在系统消息队列中,然后由Windows将它们送入应用程序消息队列中,由应用程序来处理消息。
    (2)控制消息:用来与Windows的控制对象,如列表框、按钮、检查框等进行双向通信。当用户在列表框中改动当前选择或改变了检查框的状态时发出此类消息。这类消息一般不经过应用程序消息队列,而是直接发送到控制对象上去。
    (3)系统消息:对程序化的事件或系统时钟中断作出反应。一些系统消息,象DDE消息(动态数据交换消息)要通过Windows的系统消息队列,而有的则不通过系统消息队列而直接送入应用程序的消息队列,如创建窗口消息。
    (4)用户消息:这是程序员自己定义并在应用程序中主动发出的,一般由应用程序的某一部分内部处理。
    在DOS应用程序下,可以通过getchar()、getch()等函数直接等待键盘输入,并直接向屏幕输出。而在Windows下,由于允许多个任务同时运行,应用程序的输入输出是由Windows来统一管理的。
    Windows操作系统包括三个内核基本元件:GDI, KERNEL ,USER。其中GDI(图形设备接口)负责在屏幕上绘制像素、打印硬拷贝输出,绘制用户界面包括窗口、菜单、对话框等。系统内核KERNEL支持与操作系统密切相关的功能:如进程加载,文本切换、文件I/O,以及内存管理、线程管理等。USER为所有的用户界面对象提供支持,它用于接收和管理所有输入消息、系统消息并把它们发给相应的窗口的消息队列。消息队列是一个系统定义的内存块,用于临时存储消息;或是把消息直接发给窗口过程。每个窗口维护自己的消息队列,并从中取出消息,利用窗口函数进行处理。框图如下:

图1.3 消息驱动模型

 

 

1.3.3 图形输出

    Windows程序不仅在输入上与DOS程序不同,而且在程序输出上也与DOS有着很大不同,主要表现为:
    1.DOS程序独占整个显示屏幕,其他程序在后台等待。而Windows的每一个应用程序对屏幕的一部分进行处理。DOS程序可以直接往屏幕上输出,而Windows是一个多窗口的操作系统,由操作系统来统一管理屏幕输出;每个窗口要输出内容时,必须首先向操作系统发出请求(GDI请求),由操作系统完成实际的屏幕输出工作。
    2.Windows程序的所有输出都是图形。Windows提供了丰富的图形函数用于图形输出,这对输出图形是相当方便的,但是由于字符也被作为图形来处理,输出时的定位要比DOS复杂的多。
    比如,在DOS字符方式下,我们可以写出如下程序用于输出两行文字:
printf(“Hello,/n”);
printf(“This is DOS program./n”);
    而在Windows下要输出这两行文字所做的工作要复杂的多。因为Windows输出是基于图形的,它输出文本时不会象DOS那样自动换行,而必须以像素为单位精确定位每一行的输出位置。另外,由于Windows提供了丰富的字体,所以在计算坐标偏移量时还必须知道当前所用字体的高度和宽度。
    3.Windows下的输出是设备无关的。在DOS下编写过Foxpro程序的读者常常会有这样的体会,在编写打印报表程序时,要针对不同的打印机在程序中插入不同的打印控制码,用以控制换页、字体设置等选项。这样的程序编写起来繁琐,而且不容易移植(因为换一台不同型号的打印机就要重新修改程序)。而Windows下的应用程序使用图形设备接口(GDI)来进行图形输出。GDI屏蔽了不同设备的差异,提供了设备无关的图形输出能力,Windows应用程序只要发出设备无关的GDI请求(如调用Rectangle画一个矩形),由GDI去完成实际的图形输出操作。对于一台具有打印矩形功能的PostScript打印机来说,GDI可能只需要将矩形数据传给驱动程序就可以了,然后由驱动程序产生PostScript命令绘制出相应的矩形;而对于一台没有矩形输出功能的点阵打印机来说,GDI可能需要将矩形转化为四条线,然后向驱动程序发出画线的指令,在打印机上输出矩形。当然,这两种输出在用户看来并没有什么区别。
    Windows的图形输出是由图形设备接口(GDI)来完成的,GDI是系统原始的图形输出库,它用于在屏幕上输出像素、在打印机上输出硬拷贝以及绘制Windows用户界面。
    GDI提供两种基本服务:创建图形输出和存储图象。GDI提供了大量用于图形输出的函数,这些函数接收应用程序发出来的绘图请求、处理绘图数据并根据当前使用设备调用相应的设备驱动程序产生绘图输出。这些绘图函数分为三类:一是文字输出,二是矢量图形函数,用于画线、圆等几何图形,三是光栅(位图)图形函数,用于绘制位图。
    GDI识别四种类型的设备:显示屏幕、硬拷贝设备(打印机、绘图机)、位图和图元文件。前两者是物理设备,后两者是伪设备。一个伪设备提供了一种在RAM里或磁盘里存储图象的方法。位图存放的是图形的点位信息,占用较多的内存,但速度很快。图元文件保存的是GDI函数的调用和调用参数,占用内存较少,但依赖于GDI,因此不可能用某个设备来创建图元文件,而且速度比位图要慢。
    GDI的图形输出是面向窗口的,面向窗口包含两层含义:
    (1)每个窗口作为一个独立的绘图接口来处理,有它自己的绘图坐标。当程序在一个窗口中绘图时,首先建立缺省的绘图坐标,原点(0,0)位于窗口用户区的左上角。每个窗口必须独立的维护自己的输出。
    (2)绘图仅对于本窗口有效,图形在窗口边界会被自动裁剪,也就是说窗口中的每一个图形都不会越出边界。即使想越出边界,也是不可能的,窗口会自动的防止其他窗口传过来的任何像素。这样,你在窗口内绘图时,就不必担心会偶然覆盖其他程序的窗口,从而保证了Windows下同时运行多个任务时各个窗口的独立性。

1.3.4 用户界面对象

    Windows支持丰富的用户接口对象,包括:窗口、图标、菜单、对话框等等。程序员只需简单的几十行代码,就可以设计出一个非常漂亮的图形用户界面。而在DOS环境下,则需要大量的代码来完成同样的工作,而且效果也没有Windows提供的那么好。下面我们介绍一下用户界面对象中的一些术语和相关概念。

窗口

    窗口是用户界面中最重要的部分。它是屏幕上与一个应用程序相对应的矩形区域,是用户与产生该窗口的应用程序之间的可视界面。每当用户开始运行一个应用程序时,应用程序就创建并显示一个窗口;当用户操作窗口中的对象时,程序会作出相应反应。用户通过关闭一个窗口来终止一个程序的运行;通过选择相应的应用程序窗口来选择相应的应用程序。一个典型的窗口外观如图1.4所示。

图1.4 窗口

边框

    绝大多数窗口都有一个边框,用于指示窗口的边界。同时也用来指明该窗口是否为活动窗口,当窗口活动时,边框的标题栏部分呈高亮显示。用户可以用鼠标拖动边框来调整窗口的大小。

系统菜单框

    系统菜单框位于窗口左上角,以当前窗口的图标方式显示,用鼠标点一下该图标(或按ALT+空格键)就弹出系统菜单。系统菜单提供标准的应用程序选项,包括:Restore(还原窗口原有的大小),Move(使窗口可以通过键盘上的光标键来移动其位置),Size(使用光标键调整窗口大小),Minimize(将窗口缩成图标),Maximize(最大化:使窗口充满整个屏幕)和Close(关闭窗口)。

标题栏

    标题栏位于窗口的顶部,其中显示的文本信息用于标注应用程序,一般是应用程序的名字,以便让用户了解哪个应用程序正在运行。标题栏颜色反映该窗口是否是一个活动窗口,当为活动窗口时,标题栏呈现醒目颜色。鼠标双击标题栏可以使窗口在正常大小和最大化状态之间切换。在标题栏上按下鼠标器左键可以拖动并移动该窗口,按右键弹出窗口系统菜单。

菜单栏

    菜单栏位于标题栏下方,横跨屏幕,在它上面列出了应用程序所支持的命令,菜单栏中的项是命令的主要分类,如文件操作、编辑操作。从菜单栏中选中某一项通常会显示一个弹出菜单,其中的项是对应于指定分类中的某个任务。通过选择菜单中的一个项(菜单项),用户可以向程序发出命令,以执行某一功能。如选择“文件->打开...”菜单项会弹出一个打开文件对话框,让用户选择一个文件,然后打开这个文件。
    一般的,以“...”结尾的菜单项文本表明选择该项时会弹出一个对话框,让用户输入信息,然后执行操作,如“文件->打开...”。若不以“...”结尾,则表明选择该菜单项直接执行一个动作,如“编辑”菜单下的“粘贴”菜单项。若一个菜单项呈现灰色,则表明该菜单当前不可用。有时菜单项上还有加速键,加速键是一种键盘组合,它是菜单项的一种替代方式,可以让用户通过键盘直接发出命令;在键盘上按下这一键盘组合,就等效于选择了相应的菜单。如“粘贴(P) CTRL+V”,就表示粘贴操作的加速键是CTRL+V,按下CTRL+V就执行粘贴操作。

工具条

    工具条一般位于菜单栏下方,在它上面有一组位图按钮,代表一些最常用的命令。工具条可以显示或隐藏。让鼠标在某个按钮上停一会儿,在按钮下方会出现一个黄色的小窗口,里面显示关于该按钮的简短说明,叫做工具条提示(ToolTip)。用户还可以用鼠标拖动工具条将其放在窗口的任何一侧。

客户区

    客户区是窗口中最大的一块空白矩形区域,用于显示应用程序的输出。例如,字处理程序在客户区中显示文档的当前页面。应用程序负责客户区的绘制工作,而且只有和该窗口相对应的应用程序才能向该用户区输出。

垂直滚动条和水平滚动条

    垂直滚动条和水平滚动条分别位于客户区的左侧和底部,它们各有两个方向相反的箭头和一个深色的长度可变的滚动块。可以用鼠标选中滚动条的箭头上下卷滚(选中垂直滚动条时)或水平卷滚(选中水平滚动条时)客户区的内容。滚动块的位置表示客户区中显示的内容相对于要显示的全部内容的位置,滚动块的长度表示客户区中显示的内容大小相对于全部内容大小的比例。

状态栏

    状态栏是一般位于窗口底部,用于输出菜单的说明和其他一些提示信息(如鼠标器位置、当前时间、某种状态等)。

图标

    图标是一个用于提醒用户的符号,它是一个小小的图象,用于代表一个应用程序。当一个应用程序的主窗口缩至最小时,就呈现为一个图标。

光标

    Windows的光标是显示屏上的一个位图,而不是DOS下的一条下划线。光标用于响应鼠标或其他定位设备的移动。程序可以通过改变光标的形状来指出系统中的变化。例如,程序常显示一个计时的光标,用于指示用户一些漫长的操作正在进行之中。程序也可以通过改变光标让用户知道程序进入了一种特殊模式,例如,绘图程序经常改变光标来反映被绘制对象的类型,是直线还是圆或其他。

插入符

    插入符(caret)是一个微小并闪烁的位图,作为一个键盘控制的指针。控制键盘输入的窗口可以创建一个插入符去通知用户:窗口现在可以进行键盘输入。在DOS环境下,一般使用“光标”作为键盘指针,而在Windows中,“光标”被作为鼠标指针。
    应用程序必须维护这个插入符。在Windows中,在一个时间只允许有一个插入符存在。因此,要使用插入符号作为键盘指针的应用程序必须在取得焦点时创建一个插入符号,并在失去焦点后删除它。

对话框

    对话框是一种特殊的窗口,它提供了一种接收用户输入、处理数据的标准方法。特别的,当用户输入了一个需要附加信息     的命令时,对话框是接收输入的标准方法。比如,假设用户要求系统打开一个文件,对话框就可以提供一个让用户从一组文件中选择一个文件的标准方法。如前所述,在一般情况下,在选择菜单名字后面跟着省略号(...)的菜单项通常会弹出一个对话框。图1.5给出了查找对话框的一个例子。

图1.5 查找对话框

控件

    在图1.5中,查找对话框是一个独立的窗口,它显示信息并接收用户的输入。在对话框中,还包含了许多小的窗口,这些窗口被称为控件。控件是应用程序用来获得用户特定信息的窗口,比如要打开文件的名字或自动换行的设置等。应用程序也会通过控件获取所需的信息,以便控制程序的某种属性,如自动换行特性的开关。
    控件总是与其他窗口连用,典型的是对话框,但也可以用在普通窗口之中。常见的控件有:按钮、编辑框、列表框、组合框、静态文本等等。

消息框

    消息框是用于给用户一些提示或警告的窗口。例如,消息框能够在应用程序执行某项任务过程中出现问题时通知用户。下图所示的对话框警告用户输入了一个不合法的文件名。

图1.6

 

1.3.5 资源共享

    对于DOS程序来说,它运行时独占系统的全部资源,包括显示器、内存等,在程序结束时才释放资源。而Windows是一个多任务的操作系统,各个应用程序共享系统提供的资源,常见的资源包括:设备上下文,画刷,画笔,字体,对话框控制,对话框,图标,定时器,插入符号,通信端口,电话线等。
    Windows要求应用程序必须以一种能允许它共享Windows资源的方式进行设计,它的基本模式是这样的:
1.向Windows系统请求资源;
2.使用该资源;
3.释放该资源给Windows以供别的程序使用。
    即使最有经验的Windows程序员也常常会忽略第三步。如果忽略了这一步,轻则当时不出错,但过一会儿出现程序运行出现异常情况,或干扰别的程序正常运行;重则立即死机,比如设备上下文没有释放时。
    在Windows应用程序设计中,CPU也是一种非常重要的资源,因此应用程序应当避免长时间的占用CPU资源(如一个特别长的循环);如果确实需要这样做,也应当采取一些措施,以让程序能够响应用户的输入。主存也是一个共享资源,要防止同时运行的多个应用程序因协调不好而耗尽内存资源。
    应用程序一般不要直接访问内存或其他硬件设备,如键盘、鼠标、计数器、屏幕或串口、并口等。Windows系统要求绝对控制这些资源,以保证向所有的应用程序提供公平的不中断的运行。如果确实要访问串并口,应当使用通过Windows提供的函数来安全的访问。

1.3.6 Windows应用程序组成

    前面介绍了Windows应用程序的特点,现在让我们看看编写一个Windows程序需要做哪些工作。编写一个典型的Windows应用程序,一般需要:
    1.C,CPP源程序文件:源程序文件包含了应用程序的数据、类、功能逻辑模块(包括事件处理、用户界面对象初始化以及一些辅助例程)的定义。
    2.H,HPP头文件:头文件包含了CPP、C源文件中所有数据、模块、类的声明。当一个CPP、C源文件要调用另一个CPP、C中所定义的模块功能时,需要包含那个CPP、C文件对应的头文件。
    3.资源文件:包含了应用程序所使用的全部资源定义,通常以.RC为后缀名。注意这里说的资源不同与前面提到的资源,这里的资源是应用程序所能够使用的一类预定义工具中的一个对象,包括:字符串资源、加速键表、对话框、菜单、位图、光标、工具条、图标、版本信息和用户自定义资源等。
    其中CPP、C和头文件同DOS下的类似,需要解释的是资源文件。在DOS程序设计过程中,所有的界面设计工作都在源程序中完成。而在Windows程序设计过程中,象菜单、对话框、位图等可视的对象被单独分离出来加以定义,并存放在资源源文件中,然后由资源编译程序编译为应用程序所能使用的对象的映象。资源编译使应用程序可以读取对象的二进制映象和具体数据结构,这样可以减轻为创建复杂对象所需要得程序设计工作。
    程序员在资源文件中定义应用程序所需使用的资源,资源编译程序编译这些资源并将它们存储于应用程序的可执行文件或动态连接库中。在Windows应用程序中引入资源有以下一些好处:
    1.降低内存需求:当应用程序运行时,资源并不随应用程序一起装入内存,而是在应用程序实际用到这些资源时才装入内存。在资源装入内存时,它们拥有自己的数据段,而不驻留于应用程序数据段中;当内存紧张时,可以废弃这些资源,使其占用的内存空间供他用,而当应用程序用到这些资源时才自动装入,这种方式降低了应用程序的内存需求,使一次可运行更多的程序,这也是Windows内存管理的优点之一。
    2.便于统一管理和重复利用:将位图、图标、字符串等按资源文件方式组织便于统一管理和重用。比如,将所有的错误信息放到资源文件里,利用一个函数就可以负责错误提示输出,非常方便。如果在应用程序中要多次用到一个代表公司的徽标位图,就可以将它存放在资源文件中,每次用到时再从资源文件中装入。这种方式比将位图放在一个外部文件更加简单有效。
    3.应用程序与界面有一定的独立性,有利于软件的国际化:由于资源文件独立于应用程序设计,使得在修改资源文件时(如调整对话框大小、对话框控制位置),可以不修改源程序,从而简化了用户界面的设计。另外,目前所提供的资源设计工具一般都是采用“所见即所得”方式,这样就可以更加直观、可视的设计应用程序界面。由于资源文件的独立性,软件国际化工作也非常容易。比如,现在开发了一个英文版的应用程序,要想把它汉化,只需要修改资源文件,将其中的对话框、菜单、字符串资源等汉化即可,而无需直接修改源程序。
    但是,应用程序资源只是定义了资源的外观和组织,而不是其功能特性。例如,编辑一个对话框资源,可以改变对话框的安排和外观,但是却没有也不可能改变应用程序响应对话框控制的方式。外观的改变可以通过编辑资源来实现,而功能的改变却只能通过改变应用程序的源代码,然后重新编译来实现。
    Windows应用程序的生成同DOS下类似,也要经过编译、链接两个阶段,只是增加了资源编译过程,基本流程如下图:

图1.7 应用程序生成过程

    C、CPP编译器将C源程序编译成目标程序,然后使用连接程序将所有的目标程序(包括各种库)连接在一起,生成可执行程序。在制作Windows应用程序时,编译器还要为引出函数生成正确的入口和出口代码。
    连接程序生成的可执行文件还不能在Windows环境下运行,必须使用资源编译器对其进行处理。资源编译器对可执行文件的处理是这样的:如果该程序有资源描述文件,它就把已编译为二进制数据的资源加入到可执行文件中;否则,仅对该可执行文件进行相容性标识。应用程序必需经过资源编译器处理才可以在Windows环境下运行。

1.4 Windows应用程序的开发工具

    由于Windows是Microsoft的产品,因而在早期阶段,开发工具只有Microsoft C和SDK(Software Developer Kit:软件开发工具包)可供使用。利用SDK进行Windows程序的设计开发非常繁琐、复杂,代码可重用性差,工作量大,即便一个简单的窗口也需要几百行程序,令开发人员望而生畏。
    随着Windows的逐渐普及,各大软件公司纷纷推出自己的Windows软件开发工具。国内用户比较熟悉的有Borland C++2.0以上版本以及用于数据库开发的Foxpro等等。其中Borland C++支持面向对象的开发,在我国具有广大的用户群。
    可视化技术和CASE技术研究的深入为我们带来了支持可视化编程特性的第三代开发工具,这一代开发工具有:Visual Basic,Visual C++,Borland C++ Builder,Delphi和用于数据库开发的PowerBuilder、Visual Foxpro等等。
    其中,Visual C++是美国Microsoft公司推出的4GL软件开发工具,目前已成为国内应用最广泛的高级程序设计语言之一,最新版本为5.0版。同其他软件开发工具相比,Visual C++具有以下优点:

面向对象、可视化开发:提供了面向对象的应用程序框架MFC(Microsoft Foundation Class:微软基础类库),大大简化了程序员的编程工作,提高了模块的可重用性。Visual C++还提供了基于CASE技术的可视化软件自动生成和维护工具AppWizard、ClassWizard、Visual Studio、WizardBar等,帮助用户直观的、可视地设计程序的用户界面,可以方便的编写和管理各种类,维护程序源代码,从而提高了开发效率。用户可以简单而容易地使用C/C++编程。

众多的开发商支持以及业已成为工业标准的MFC类库:MFC类库已经成为事实上的工业标准类库,得到了众多开发商和软件开发工具的支持;另外,由于众多的开发商都采用Visual C++进行软件开发,这样用Visual C++开发的程序就与别的应用软件有许多相似之处,易于学习和使用。

Visual C++封装了Windows的API(应用程序接口)函数、USER、KERNEL、GDI函数,帮助我们弄清了许多函数的组织方法,隐去了创建、维护窗口的许多复杂的例行工作,简化了编程。

        但是,由于C/C++本身的复杂性,Visual C/C++对编程人员要求还是相当高的。它首先要求编程者要具有丰富的C/C++语言编程经验,了解面向对象编程的基本概念,同时还必须掌握复杂的MFC类库。

1.5 面向对象和Windows编程

  面向对象技术是目前流行的系统设计开发技术,它包括面向对象分析和面向对象程序设计。面向对象程序设计技术的提出,主要是为了解决传统程序设计方法——结构化程序设计所不能解决的代码重用问题。

  结构化程序设计从系统的功能入手,按照工程的标准和严格的规范将系统分解为若干功能模块,系统是实现模块功能的函数和过程的集合。由于用户的需求和软、硬件技术的不断发展变化,按照功能划分设计的系统模块必然是易变的和不稳定的。这样开发出来的模块可重用性不高。

  面向对象程序设计从所处理的数据入手,以数据为中心而不是以服务(功能)为中心来描述系统。它把编程问题视为一个数据集合,数据相对于功能而言,具有更强的稳定性。

  面向对象程序设计同结构化程序设计相比最大的区别就在于:前者首先关心的是所要处理的数据,而后者首先关心的是功能。

  面向对象程序设计是一种围绕真实世界的概念来组织模型的程序设计方法,它采用对象来描述问题空间的实体。关于对象这一概念,目前还没有统一的定义。一般的认为,对象是包含现实世界物体特征的抽象实体,它反映了系统为之保存信息和(或)与它交互的能力。它是一些属性及服务的一个封装体,在程序设计领域,可以用“对象=数据+作用于这些数据上的操作”这一公式来表达。

  类是具有相同操作功能和相同的数据格式(属性)的对象的集合。类可以看作抽象数据类型的具体实现。抽象数据类型是数据类型抽象的表示形式。数据类型是指数据的集合和作用于其上的操作的集合,而抽象数据类型不关心操作实现的细节。从外部看,类型的行为可以用新定义的操作加以规定。类为对象集合的抽象,它规定了这些对象的公共属性和方法;对象为类的一个实例。苹果是一个类,而放在桌上的那个苹果则是一个对象。对象和类的关系相当于一般的程序设计语言中变量和变量类型的关系。

  消息是向某对象请求服务的一种表达方式。对象内有方法和数据,外部的用户或对象对该对象提出的服务请求,可以称为向该对象发送消息。合作是指两个对象之间共同承担责任和分工。

  面向对象的编程方法具有四个基本特征:

1.抽象:
  抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。比如,我们要设计一个学生成绩管理系统,考察学生这个对象时,我们只关心他的班级、学号、成绩等,而不用去关心他的身高、体重这些信息。抽象包括两个方面,一是过程抽象,二是数据抽象。过程抽象是指任何一个明确定义功能的操作都可被使用者看作单个的实体看待,尽管这个操作实际上可能由一系列更低级的操作来完成。数据抽象定义了数据类型和施加于该类型对象上的操作,并限定了对象的值只能通过使用这些操作修改和观察。

2.继承:
  继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。这也体现了大自然中一般与特殊的关系。继承性很好的解决了软件的可重用性问题。比如说,所有的Windows应用程序都有一个窗口,它们可以看作都是从一个窗口类派生出来的。但是有的应用程序用于文字处理,有的应用程序用于绘图,这是由于派生出了不同的子类,各个子类添加了不同的特性。

3.封装:
  封装是面向对象的特征之一,是对象和类概念的主要特性。封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。一旦定义了一个对象的特性,则有必要决定这些特性的可见性,即哪些特性对外部世界是可见的,哪些特性用于表示内部状态。在这个阶段定义对象的接口。通常,应禁止直接访问一个对象的实际表示,而应通过操作接口访问对象,这称为信息隐藏。事实上,信息隐藏是用户对封装性的认识,封装则为信息隐藏提供支持。封装保证了模块具有较好的独立性,使得程序维护修改较为容易。对应用程序的修改仅限于类的内部,因而可以将应用程序修改带来的影响减少到最低限度。

4. 多态性:
  多态性是指允许不同类的对象对同一消息作出响应。比如同样的加法,把两个时间加在一起和把两个整数加在一起肯定完全不同。又比如,同样的选择编辑-粘贴操作,在字处理程序和绘图程序中有不同的效果。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。

  面向对象程序设计具有许多优点:

开发时间短,效率高,可靠性高,所开发的程序更强壮。由于面向对象编程的可重用性,可以在应用程序中大量采用成熟的类库,从而缩短了开发时间。

应用程序更易于维护、更新和升级。继承和封装使得应用程序的修改带来的影响更加局部化。

  Windows的最初开发是在80年代早期,在C++出现之前,但是当时已经提出了面向对象式的程序设计思想。Windows的开发者们已经意识到将界面上不同的项看作对象的好处,但是他们仍然被迫采用传统的C语言来处理这些对象。在Windows的界面设计和软件开发环境中,可以说处处贯穿着面向对象的思想。

  在Windows中,程序的基本单位不是过程和函数,而是窗口。一个窗口是一组数据的集合和处理这些数据的方法和窗口函数。从面向对象的角度来看,窗口本身就是一个对象。Windows程序的执行过程本身就是窗口和其他对象的创建、处理和消亡过程。Windows中的消息的发送可以理解为一个窗口对象向别的窗口对象请求对象的服务过程。因此,用面向对象方法来进行Windows程序的设计与开发是极其方便的和自然的。

  采用面向对象的方法来进行Windows程序设计还可以简化对资源的管理。当我们将资源映射成一个C++对象时,对资源的使用可以翻译成以下C++顺序:

1.创建一个对象:如定义一个画笔对象

2.使用对象:用画笔绘图

3.撤消该对象

  一个对象的创建是对一个对象的定义过程,可以由对象的构造函数处理对资源的请求过程。当某一个对象退出活动范围时,它的撤消可以由编译器来自动管理。各种资源和Windows结构都能以这种方式处理,如设备上下文、画笔、字体、画刷等等。

你可能感兴趣的:(Useful,Texts,My,Notes,Books,etc.,VC++)