第一章 Windows程序设计概述

  Windows和Windows应用程序最大的优点就是用户界面的一致性。因为大多数用户都在不同的软件包上工作,而每一个软件包都有自己的用户界面,所以用户界面一致性的设计就显得非常重要。Windows环境中的每一个窗口都包含了相同的基本特性,由于这些基本特性在应用程序中是一致的,因而用户能很容易地适应新的应用程序。
  对用户的另一个好处是使用了基于图形的图标来代表应用程序和数据。由于Windows是一个图形用户界面,因而采用了图形图像来代表诸如文件、应用程序、窗口和目录等物理数据结构。用户可以通过鼠标的单击、双击及拖动等操作来管理这些物理结构。例如,对用户来说,双击一个代表某一应用程序的图标比起在DOS中进入相应的目录,并键人相应的应用程序名来使之执行要容易得多。
   Windows操作系统提供的“所见即所得”也是一个非常友好的特点。Windows可以把文本文件等看作一串图形,而在屏幕上画出的图形,在打印的时候也将以同样形式出现。
  Windows操作系统还提供了多任务功能。多任务对于用户是很重要的,因为它允许同时运行几个应用程序,用户无需退出一个应用程序再进入另一个应用程序,而只需简单地在各个应用程序之间来回切换就可以了。
  Windows对于程序员的优越性: Windows中许多对用户的优越性也是对程序员的优越性,例如一致的用户界面。因为如果应用程序的界面对每一个应用程序都是相同的,程序员就可以建立一套基本的界面设计工具,用它们来生成应用程序的用户界面(这就是可视化编程的思想):而在解决了程序的用户界面后,程序员可以花更多的时间去进行应用程序的功能设计。Windows图形用户界面的基本元素也是其具有的另一个优点。程序员可以很容易地设计出代表诸如文件和目录物理结构的图形表示,并能提供这些元素所具有的特性。   Windows对存储器的管理也是一个很明显的优点。这个优点可以使应用程序能够存取更多的内存资源,同时能保持系统设计中的灵活性。
  Windows提供了开发独立于设备的图形的能力。一个设计良好的Windows应用程序并不对硬件直接存取图形,这意味着程序并不依赖于某一确定的系统配置,所以,每一个程序员不需要为所有可能的显示器、适配卡和打印机开发设备驱动程序。

Windows 发展历程

  Microsoft Windows是一个应用于微型计算机上的基于图形用户界面的操作系统。它为应用程序提供了一个由一致的图形用户界面构成的多任务环境。由于应用程序之间的界面是一致的,因而对于用户来说,Windows应用程序相对于基于DOS的应用程序更容易学习和使用。多任务Windows系统的好处在于允许同时运行几个应用程序,特别是运行几个专为Windows环境而创建的应用程序。当然,Windows也提供了运行非Windows的MS-DOS应用程序的机制。
  Microsoft公司早在1983年就开始了Windows操作系统第一版的研制工作,并于1985年发布了Windows的1.l版。该版本的Windows支持自动的拼接式应用程序窗口及弹出式窗口。Windows经过不断升级换代,现在最新版本是 Windows 2000,它基于网络环境。本课件将结合 Windows 98系统平台,全面介绍 Windows API程序设计。

Windows 程序工作原理

  Windows 程序设计是一种完全不同于传统的DOS方式的程序设计方法,它是一种事件驱动方式的程序设计模式。在程序提供给用户的界面中有许多可操作的可视对象。用户从所有可能的操作中任意选择,被选择的操作会产生某些特定的事件,这些事件发生后的结果是向程序中的某些对象发出消息,然后这些对象调用相应的消息处理函数来完成特定的操作。Windows应用程序最大的特点就是程序没有固定的流程,而只是针对某个事件的处理有特定的子流程,Windows应用程序就是由许多这样的子流程构成的。
  从上面的讨论中可以看出,Windows应用程序在本质上是面向对象的。程序提供给用户界面的可视对象在程序的内部一般也是一个对象,用户对可视对象的操作通过事件驱动模式触发相应对象的可用方法。程序的运行过程就是用户的外部操作不断产生事件,这些事件又被相应的对象的过程处理。 一般的程序流程如图l-l所示。
一、理解Windows消息机制
  Wndows系统是通过消息驱动的。消息的组成如下:
  消息名称(UINT)和两个参数(WPARAM,LPARAM)。

第一章 Windows程序设计概述_第1张图片

  当用户进行了输入或是窗口的状态发生改变时,系统都会发送消息到某一个窗口。例如当选中某菜单命令之后会发送WM_COMMAND消息,WPARAM的高字(HIWORD(wParam)中是命令的ID号,对菜单来讲就是菜单ID。当然用户也可以定义自己的消息名称,并利用自定义消息来发送通知和传送数据。
  一个消息必须由一个窗口接收。在窗口的过程( WNDPROC)中可以对消息进行分析,对自己感兴趣的消息进行处理。例如你希望对菜单选择进行处理,那么你可以定义对WM_ COMMAND消息进行处理的代码;如果希望在窗口中进行图形输出,就必须对WM_PAINT消息进行处理。
  Microsoft为窗口编写了默认的窗口过程,该过程负责处理那些你不处理的消息。正因为有了这个默认窗口过程,我们才可以利用Windows的窗口进行开发而不必过多关注窗口各种消息的处理。例如窗口在被拖动时会发送很多消息,而我们都可以不予理睬,让系统自己去处理。
  说到消息就不能不说窗口句柄。系统通过窗口句柄在整个系统中唯一标识一个窗口,发送一个消息时必须指定一个窗口句柄,表明该消息由那个窗口接收。每个窗口都有自己的窗口过程,所以用户的输入就会被正确地处理。
  下面有一段伪代码演示如何在窗口过程中处理消息:
LONG WndProc(HWND hwnd , UINT MessageType ,WPARAM , LPARAM)

  switch(MessageType)
    {// 使用SWITCH语句将各种消息分开
      case(WM_PAINT):
      doYourWindow (…); // 在窗口需要重新绘制时进行输出
      break ;
      case (WM_LBUTTONDOWN):
      doYourWork(…)// 在鼠标左键被按下时进行处理
      break ;
      default:
      callDefaultWndProc(…) ; // 对于其他情况就让系统自己处理
      break;
    }

  系统将维护一个或多个消息队列,所有产生的消息都会被放入或是插入队列中。系统会在队列中取出每一条消息,根据消息的接收句柄将该消息发送给拥有该窗口的程序的消息循环。每一个运行的程序都有自己的消息循环,在循环中得到属于自己的消息并根据接收窗口的句柄调用相应的窗口过程。而在没有消息时消息循环就将控制权交给系统,所以Windows可以同时进行多个任务。下面的伪代码演示了消息循环的用法:
While(1)

  id=getMessage(…);
  if(id==quit)
  break;
  translateMessage(…);

当该程序没有消息通知时,getMessage就不会返回,也就不会占用系统的CPU时间。
二、协同式多任务与抢先式多任务系统
  在16位的操作系统中只有一个消息队列,所以系统必须等待当前任务处理消息后才可以发送下一消息到相应程序,如果一个程序陷入死循环或是操作超时,系统就得不到控制权。这种多任务系统被称为协同式多任务系统。 Windows 3.x就是这种系统。
  而32位的系统中每一个运行的程序都会有一个消息队列,所以系统可以在多个消息队列中转换,而不必等待当前程序完成消息处理才可以得到控制权。这种多任务系统就是所谓的抢先式多任务系统。 Wndows 2000系列以及以前的Wndows 95/98/NT都属于这种系统。

Windows应用程序设计特点

  在过去,进行Windows程序设计是一件痛苦异常的事情,原因是那时候还没有现在这些设计精美的应用程序开发工具。在今天,即便是一个对Windows程序内部运行机制几乎一无所知的初学者,只需要通过不到一天的学习,也可以使用如 Visual Basic之类的程序开发工具创建出功能完整的Windows应用程序来。从某种角度说,Windows程序不是编出来的,而是由程序员画出来的。但是要知道,一个出色的Windows的应用程序并不仅在于在屏幕上绘出程序的各个窗口和在窗口中恰当地安排每一个控件。对于具有一定基础的程序员而言,更重要的内容在于知道Windows和Windows应用程序的运行机制,以及它们之间以何种方式来进行通信。换句话说,我们需要透过Windows漂亮的图形用户界面,认清在底层所发生的每一件事情。
  Windows应用程序是事件驱动(或称作消息驱动)的应用程序。而 Windows 是一个多任务的操作系统,也就是说,在同一时刻,在Windows中有着多个应用程序的实例正在运行,例如我在打开字处理软件Notepad键人纯文本的同时,还打开了Winmap来播放歌曲。在这样的一个操作系统中,不可能像过去的DOS那样,由一个应用程序来享用所有的系统资源,这些资源是由Windows统一管理的。那么,特定的应用程序如何获得用户输入的信息呢?事实上,Windows时刻监视着用户的一举一动,并分析用户的动作与哪一个应用程序相关,然后,将用户的动作以消息的形式发送给该应用程序,应用程序时刻等待着消息的到来,一旦发现它的消息队列中有未处理的消息,就获取并分析该消息,最后,应用程序根据消息所包含的内容采取适当的动作来响应用户所作的操作。
  Windows为每一个应用程序,确切地说是每一个线程维护相应的消息队列。应用程序的任务就是不停地从它的消息队列中获取消息,分析和处理消息,直到接到一条叫作WM_QUIT消息为止,这个过程通常是由一种叫作消息循环的程序结构来实现的。
  Windows 能向应用程序发送的消息多达数百种,但是,对于一般的应用程序来说,只是其中的一部分有意义,如果你的应用程序只使用鼠标,那么如 WM_KEYUP 、 WM_KEYDOWN 和 WM_CHAR 等消息就没有任何意义,也就是说,应用程序中事实上不需要处理这些事件,对于这些事件,只需要交给 Windows 作默认的处理即可。因此,在应用程序中,我们需要处理的事件只是所有事件中的一小部分。事件驱动围绕着消息的产生与处理展开,一条消息是关于发生的事件的消息。事件驱 动是靠消息循环机制来实现的。
Windows 应用程序的消息来源有以下 4种:
(l)输入消息:包括键盘和鼠标的输入。这一类消息首先放在系统消息队列中,然后由Windows将它们送入应用程序消息队列中,由应用程序来处理消息。
(2)控制消息:用来与Windows的控制对象,如列表框、按钮、检查框等进行双向通信。当用户在列表框中改动当前选择或改变了检查框的状态时发出此类消息。这类消息一般不经过应用程序消息队列,而是直接发送到控制对象上去。
(3)系统消息:对程序化的事件或系统时钟中断作出反应。一些系统消息,像DDE消息(动态数据交换消息)要通过Windows的系统消息队列,而有的则不通过系统消息队列而直接送入应用程序的消息队列,如创建窗口消息。
(4)用户消息:这是程序员自己定义并在应用程序中主动发出的,一般由应用程序的某一部分内部处理。
  Windows程序在处理消息时使用了一种叫作回调函数(Callback Function)的特殊函数。
  回调函数由应用程序定义,但是,在应用程序中并没有调用回调函数的代码,回调函数是供操作系统或者其子系统调用的,这种调用通常在某一事件发生,或者在窗口或字体被枚举时。典型的回调函数有窗口过程、对话框过程和钩子函数。

Windows API和SDK

一、Windows API
  说到 Windows编程,就不能不谈到 Windows API(Windows Application Programming Interface,Windows应用程序编程接口),它是所有 Windows应用程序的根本之所在。简单地说,API就是一系列的例程,应用程序通过调用这些例程来请求操作系统完成一些低级服务。在Windows这样的图形用户界面中,应用程序的窗口、图标、菜单和对话框等就是由API来管理和维护的。在DOS应用程序下,可以通过getchar ()等函数直接等待键盘输入,并直接向屏幕输出。而在Windows下,由于允许多个任务同时运行,应用程序的输入输出是由Windows来统一管理的。 Windows 操作系统包括 3个内核基本元件: GDI,KERNEL,USER。其中 GDI(图形设备接口)负责在屏幕上绘制像素、打印硬拷贝输出、绘制用户界面(包括窗口、菜单。对话框)等。系统内核KERNEL支持与操作系统密切相关的功能:如进程加载,文本切换、文件I/O,以及内存管理、线程管理等。  USER为所有的用户界面对象提供支持,它用于接收和管理所有输入消息、系统消息并把它们发给相应的窗口的消息队列。消息队列是一个系统定义的内存块,用于临时存储消息;或是把消息直接发给窗口过程。每个窗口维护自己的消息队列,并从中取出消息,利用窗口函数进行处理。
  Windows API具有两种基本类型: Winl6 API和Win32 API。两者在很多方面非常相像,但是Win32 API除了几乎包括了Winl6 API中的所有内容以外,还包括很多的其他内容。Windows API依靠 3个主要的核心组件提供 Windows的大部分函数,在Winl6和 Win32中,它们具有不同的名称,如表l一1所示。

表1.1 Win16和Win32
Win16 API
Win32 API
USER.EXE
USER32.DLL
GDI.EXE
GDI32.DLL
KRNL386.EXE
KERNEL32.DLL

  虽然Winl6 API组件带有.EXE的扩展名,但是它们事实上都是动态链接库(.DLL),不能单独运行。其他一些非核心的Windows API由其他组件所提供的DLL来实现,这些组件包括通用对话框、打印、文件压缩、版本控制以及多媒体支持等。
二、Windows SDK 
  Windows SDK(Windows Software Development Kit, Windows软件开发工具包)和Windows API紧密联系,它是一套帮助 C语言程序员创建Windows应用程序的工具,在Windows SDK中包括了以下几个组成部分:
(1)大量的在线帮助,这些帮助描述了Windows编程所可能用到的函数、消息、结构、宏及其他资源。
(2)各种编程工具,如对话框编辑器及图像编辑器等。
(3)Windows库及头文件。
(4)使用C语言编写的示例程序。
  该工具包的最新版本就是我们正在使用的 Win32 SDK。在安装 Visual C++的同时,Win32 SDK也安装到你的计算机上了。尽管MFC提供了对Win32 API的比较完整的封装,但是,在某些情况下,我们更倾向于直接调用 Win32 API,因为这有时候可以获得更高的效率,并且有着更大的自由度。而且,使用MFC编写的新风格的Windows应用程序的工作方式基本上与使用SDK编写的程序一样,它们往往有着很多的共同之处,只是使用MFC更加方便,因为它隐藏了大量的复杂性。 
  面向对象的编程方式是当前最流行的程序设计方法,但是, Win32 API本身却是基于C语言的过程式编程的,SDK和MFC的最主要的不同之处也就是C与C+十之间的差别,使用MFC进行Windows应用程序设计需要面向对象的编程思想和方法,
三、使用 SDK编写 Windows应用程序
  传统的DOS程序以main() 函数作为进入程序的初始人口点,在Windows应用程序中,main函数被WinMain函数取而代之,WinMain函数的原型如下:
int WINAPI WinMain(HINSTANCE hInstance, // 当前实例句柄;
HINSTANCE hPrevInstance, // 前一实例句柄;
LPSTR lpCmdLine, // 指向命令行参数的指针;
int nCmdshow) // 窗口的显示状态。
  所谓的句柄是一个标识对象的变量,或者是一个对操作系统资源的间接引用。句柄是指向一个“无类型对象”(Void*)的指针,也就是一个4字节长的数据。其声明是这样的: typedef void *HANDLE
  Windows是一个多任务操作系统,它可以同时运行多个程序或一个程序的多个副本。为了对同一程序的多个副本进行管理,Windows引入了实例句柄。Windows为每个应用程序建立一张表,实例句柄就好像是这张表的一个索引。Windows不仅使用句柄来管理实例,也用它来管理窗口、位图、字体、元文件、图标等系统资源。
一般情况下,我们应该在WinMain函数中完成下面的操作:
(l)注册窗口类。
(2)创建应用程序主窗口。
(3)进入应用程序消息循环。

Windows API程序设计基础知识

  要在Windows上开发应用程序,就必须对Windows程序设计有所了解。
  在编程时,变量、函数的命名是一个极其重要的问题。好的命名方法使变量易于记忆且程序可读性大大提高。 Microsoft采用匈牙利命名法来命名 Windows API函数和变量。匈牙利命名法是由Microsoft的著名开发人员,Excel的主要设计者查尔斯·西蒙尼在他的博士论文中提出来的,由于西蒙尼的国籍是匈牙利,所以这种命名法叫匈牙利命名法。
匈牙利命名法为C标识符的命名定义了一种非常标准化的方式,这种命名方式是以下面两条规则为基础的:
(1)标识符的名字以一个或者多个小写字母开头,用这些字母来指定数据类型。表l-2列出了常用的数据类型的标准前缀。
(2)在标识符内,前缀以后就是一个或者多个第一个字母大写的单词,这些单词清楚地指出了源代码内那个对象的用途。比如,m_szStudentName表示一个学生名字的类成员变量,数据类型是字符串型

表1.2 在Windows里定义数据类型的一此标准前缀
前缀
数据类型
c
字符(char)
s
短整数(short)
cb
用于定义对象(一般为一个结构)尺寸的整数
n
整数(integer)
sz
以'\0'结尾的字符串
b
字节
i
int(整数)
x
短整数(坐标X)
y
短整数(坐标Y)
f
BOOL
w
字(WORD,无符号短整数)
l
长整数(long)
h
HANDLE(无符号int)
m_
类成员变量
fn
函数(function)
dw
双字(DWORD,无符号长整数)

Windows API程序的开发步骤

  开发基于 Windows API的应用程序一般可以参考下面的步骤。启动Visual C++编译器后,选择 File菜单下的 New菜单项,在列表框中选择 Win32 Application项。然后在 Project name文本框中输入新建的项目名,再在Location文本框中输入新建项目所在的路径。 可用如下三种方式的任意一种创建 Windows API应用程序。
(1)An empty project一个空项目;
(2)A simpla Win32 application 一个简单的Win32应用程序
(3)A typical" Hello World”application一个典型的“Hello Word”应用程序。
  如果选择A simple Win32 application项, Visual C++ 编译器将自动为用户生成项目的框架文件。
  对初学 Windows API程序设计的程序员来说,“Hello World!”应用程序是一个很好的范例。当选择了 A typical "Hello World!”application这一项后,Visual C++编译器会自动创建一个完整的应用程序,这个程序将在弹出的窗口中显示 Hello World!。 如果希望直接键人源程序,可以选择 An empty project这一项。
  项目框架建立起来后,需要向其中加入相关的文件,这些文件可能是已经存在的,也可能是需要重新编辑建立的。
  要向项目中加入文件,可以单击Visual C++编译器中Project菜单下的Add To Project级联菜单下的菜单项, 选择需要插入到项目中的文件,然后单击OK按钮,相应的文件就会被插入到项目中。 单击Visual C++编译器中File菜单下的 New菜单项,列表框中列出了所有可以新建的文件类型,这些文件中用得最为频繁的是C++ Source File。首先选中列表框中的C++ Source File项,然后在File文本框中键入文件名,再单击OK按钮。这样就可以在Visual C++编译器中键人相应的源文件了。其他类型的文件可以参照 C++ Source File的建立步骤。

你可能感兴趣的:(第一章 Windows程序设计概述)