WindowsAPI_第1页
WindowsAPI_第2页
WindowsAPI_第3页
WindowsAPI_第4页
WindowsAPI_第5页
已阅读5页,还剩584页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、一、理解Windows消息机制 Wndows系统是通过消息驱动的。消息的组成如下: 消息名称(UINT)和两个参数(WPARAM,LPARAM)。,当用户进行了输入或是窗口的状态发生改变时,系统都会发送消息到某一个窗口。例如当选中某菜单命令之后会发送WM_COMMAND消息,WPARAM的高字(HIWORD(wParam)中是命令的ID号,对菜单来讲就是菜单ID。当然用户也可以定义自己的消息名称,并利用自定义消息来发送通知和传送数据。 一个消息必须由一个窗口接收。在窗口的过程( WNDPROC)中可以对消息进行分析,对自己感兴趣的消息进行处理。例如你希望对菜单选择进行处理,那么你可以定义对WM

2、_ COMMAND消息进行处理的代码;如果希望在窗口中进行图形输出,就必须对WM_PAINT消息进行处理。 Microsoft为窗口编写了默认的窗口过程,该过程负责处理那些你不处理的消息。正因为有了这个默认窗口过程,我们才可以利用Windows的窗口进行开发而不必过多关注窗口各种消息的处理。例如窗口在被拖动时会发送很多消息,而我们都可以不予理睬,让系统自己去处理。 说到消息就不能不说窗口句柄。系统通过窗口句柄在整个系统中唯一标识一个窗口,发送一个消息时必须指定一个窗口句柄,表明该消息由那个窗口接收。每个窗口都有自己的窗口过程,所以用户的输入就会被正确地处理。,下面有一段伪代码演示如何在窗口过程

3、中处理消息: LONG WndProc(HWND hwnd , UINT MessageType ,WPARAM , LPARAM) switch(MessageType) / 使用SWITCH语句将各种消息分开 case(WM_PAINT): doYourWindow (); / 在窗口需要重新绘制时进行输出 break ; case (WM_LBUTTONDOWN): doYourWork()/ 在鼠标左键被按下时进行处理 break ; default: callDefaultWndProc() ; / 对于其他情况就让系统自己处理 break; ,系统将维护一个或多个消息队列,所有产生

4、的消息都会被放入或是插入队列中。系统会在队列中取出每一条消息,根据消息的接收句柄将该消息发送给拥有该窗口的程序的消息循环。每一个运行的程序都有自己的消息循环,在循环中得到属于自己的消息并根据接收窗口的句柄调用相应的窗口过程。而在没有消息时消息循环就将控制权交给系统,所以Windows可以同时进行多个任务。下面的伪代码演示了消息循环的用法: While(1) idgetMessage(); if(id=quit) break; translateMessage(); 当该程序没有消息通知时,getMessage就不会返回,也就不会占用系统的CPU时间。,二、协同式多任务与抢先式多任务系统 在16

5、位的操作系统中只有一个消息队列,所以系统必须等待当前任务处理消息后才可以发送下一消息到相应程序,如果一个程序陷入死循环或是操作超时,系统就得不到控制权。这种多任务系统被称为协同式多任务系统。 Windows 3.x就是这种系统。 而32位的系统中每一个运行的程序都会有一个消息队列,所以系统可以在多个消息队列中转换,而不必等待当前程序完成消息处理才可以得到控制权。这种多任务系统就是所谓的抢先式多任务系统。 Wndows 2000系列以及以前的Wndows 9598NT都属于这种系统。,第三节 Windows应用程序设计特点,在过去,进行Windows程序设计是一件痛苦异常的事情,原因是那时候还没

6、有现在这些设计精美的应用程序开发工具。在今天,即便是一个对Windows程序内部运行机制几乎一无所知的初学者,只需要通过不到一天的学习,也可以使用如 Visual Basic之类的程序开发工具创建出功能完整的Windows应用程序来。从某种角度说,Windows程序不是编出来的,而是由程序员画出来的。但是要知道,一个出色的Windows的应用程序并不仅在于在屏幕上绘出程序的各个窗口和在窗口中恰当地安排每一个控件。对于具有一定基础的程序员而言,更重要的内容在于知道Windows和Windows应用程序的运行机制,以及它们之间以何种方式来进行通信。换句话说,我们需要透过Windows漂亮的图形用户

7、界面,认清在底层所发生的每一件事情。,Windows应用程序是事件驱动(或称作消息驱动)的应用程序。而 Windows 是一个多任务的操作系统,也就是说,在同一时刻,在Windows中有着多个应用程序的实例正在运行,例如我在打开字处理软件Notepad键人纯文本的同时,还打开了Winmap来播放歌曲。在这样的一个操作系统中,不可能像过去的DOS那样,由一个应用程序来享用所有的系统资源,这些资源是由Windows统一管理的。那么,特定的应用程序如何获得用户输入的信息呢?事实上,Windows时刻监视着用户的一举一动,并分析用户的动作与哪一个应用程序相关,然后,将用户的动作以消息的形式发送给该应用

8、程序,应用程序时刻等待着消息的到来,一旦发现它的消息队列中有未处理的消息,就获取并分析该消息,最后,应用程序根据消息所包含的内容采取适当的动作来响应用户所作的操作。 Windows为每一个应用程序,确切地说是每一个线程维护相应的消息队列。应用程序的任务就是不停地从它的消息队列中获取消息,分析和处理消息,直到接到一条叫作WM_QUIT消息为止,这个过程通常是由一种叫作消息循环的程序结构来实现的。,Windows能向应用程序发送的消息多达数百种,但是,对于一般的应用程序来说,只是其中的一部分有意义,如果你的应用程序只使用鼠标,那么如 WM_KEYUP、WM_KEYDOWN和WM_CHAR等消息就没

9、有任何意义,也就是说,应用程序中事实上不需要处理这些事件,对于这些事件,只需要交给Windows作默认的处理即可。因此,在应用程序中,我们需要处理的事件只是所有事件中的一小部分。 事件驱动围绕着消息的产生与处理展开,一条消息是关于发生的事件的消息。事件驱动是靠消息循环机制来实现的。,Windows 应用程序的消息来源有以下 4种: (l)输入消息:包括键盘和鼠标的输入。这一类消息首先放在系统消息队列中,然后由Windows将它们送入应用程序消息队列中,由应用程序来处理消息。 (2)控制消息:用来与Windows的控制对象,如列表框、按钮、检查框等进行双向通信。当用户在列表框中改动当前选择或改变

10、了检查框的状态时发出此类消息。这类消息一般不经过应用程序消息队列,而是直接发送到控制对象上去。 (3)系统消息:对程序化的事件或系统时钟中断作出反应。一些系统消息,像DDE消息(动态数据交换消息)要通过Windows的系统消息队列,而有的则不通过系统消息队列而直接送入应用程序的消息队列,如创建窗口消息。 (4)用户消息:这是程序员自己定义并在应用程序中主动发出的,一般由应用程序的某一部分内部处理。 Windows程序在处理消息时使用了一种叫作回调函数(Callback Function)的特殊函数。 回调函数由应用程序定义,但是,在应用程序中并没有调用回调函数的代码,回调函数是供操作系统或者其

11、子系统调用的,这种调用通常在某一事件发生,或者在窗口或字体被枚举时。典型的回调函数有窗口过程、对话框过程和钩子函数。,第四节 Windows API和 SDK,一、Windows API 说到 Windows编程,就不能不谈到 Windows API(Windows Application Programming Interface,Windows应用程序编程接口),它是所有 Windows应用程序的根本之所在。简单地说,API就是一系列的例程,应用程序通过调用这些例程来请求操作系统完成一些低级服务。在Windows这样的图形用户界面中,应用程序的窗口、图标、菜单和对话框等就是由API来管理和

12、维护的。在DOS应用程序下,可以通过getchar ()等函数直接等待键盘输入,并直接向屏幕输出。而在Windows下,由于允许多个任务同时运行,应用程序的输入输出是由Windows来统一管理的。 Windows 操作系统包括 3个内核基本元件: GDI,KERNEL,USER。其中 GDI(图形设备接口)负责在屏幕上绘制像素、打印硬拷贝输出、绘制用户界面(包括窗口、菜单。对话框)等。系统内核KERNEL支持与操作系统密切相关的功能:如进程加载,文本切换、文件I/O,以及内存管理、线程管理等。USER为所有的用户界面对象提供支持,它用于接收和管理所有输入消息、系统消息并把它们发给相应的窗口的消

13、息队列。消息队列是一个系统定义的内存块,用于临时存储消息;或是把消息直接发给窗口过程。每个窗口维护自己的消息队列,并从中取出消息,利用窗口函数进行处理。,Windows API具有两种基本类型: Winl6 API和Win32 API。两者在很多方面非常相像,但是Win32 API除了几乎包括了Winl6 API中的所有内容以外,还包括很多的其他内容。Windows API依靠 3个主要的核心组件提供 Windows的大部分函数,在Winl6和 Win32中,它们具有不同的名称,如表l一1所示。 虽然Winl6 API组件带有EXE的扩展名,但是它们事实上都是动态链接库(.DLL),不能单独运

14、行。其他一些非核心的Windows API由其他组件所提供的DLL来实现,这些组件包括通用对话框、打印、文件压缩、版本控制以及多媒体支持等。,二、Windows SDK Windows SDK(Windows Software Development Kit, Windows软件开发工具包)和Windows API紧密联系,它是一套帮助 C语言程序员创建Windows应用程序的工具,在Windows SDK中包括了以下几个组成部分: 大量的在线帮助,这些帮助描述了Windows编程所可能用到的函数、消息、结构、宏及其他资源。 各种编程工具,如对话框编辑器及图像编辑器等。 Windows库及头文

15、件。 使用C语言编写的示例程序。 该工具包的最新版本就是我们正在使用的 Win32 SDK。在安装 Visual C+的同时,Win32 SDK也安装到你的计算机上了。尽管MFC提供了对Win32 API的比较完整的封装,但是,在某些情况下,我们更倾向于直接调用 Win32 API,因为这有时候可以获得更高的效率,并且有着更大的自由度。而且,使用MFC编写的新风格的Windows应用程序的工作方式基本上与使用SDK编写的程序一样,它们往往有着很多的共同之处,只是使用MFC更加方便,因为它隐藏了大量的复杂性。 面向对象的编程方式是当前最流行的程序设计方法,但是, Win32 API本身却是基于C

16、语言的过程式编程的,SDK和MFC的最主要的不同之处也就是C与C十之间的差别,使用MFC进行Windows应用程序设计需要面向对象的编程思想和方法,,三、使用 SDK编写 Windows应用程序 传统的DOS程序以main() 函数作为进入程序的初始人口点,在Windows应用程序中,main函数被WinMain函数取而代之,WinMain函数的原型如下: int WINAPI WinMain(HINSTANCE hInstance, / 当前实例句柄; HINSTANCE hPrevInstance, / 前一实例句柄; LPSTR lpCmdLine, / 指向命令行参数的指针; int

17、nCmdshow) / 窗口的显示状态。 所谓的句柄是一个标识对象的变量,或者是一个对操作系统资源的间接引用。句柄是指向一个“无类型对象”(Void*)的指针,也就是一个4字节长的数据。其声明是这样的: typedef void *HANDLE Windows是一个多任务操作系统,它可以同时运行多个程序或一个程序的多个副本。为了对同一程序的多个副本进行管理,Windows引入了实例句柄。Windows为每个应用程序建立一张表,实例句柄就好像是这张表的一个索引。Windows不仅使用句柄来管理实例,也用它来管理窗口、位图、字体、元文件、图标等系统资源。 一般情况下,我们应该在WinMain函数中

18、完成下面的操作: (l)注册窗口类。 (2)创建应用程序主窗口。 (3)进入应用程序消息循环。,第五节 Windows API程序设计基础知识,要在Windows上开发应用程序,就必须对Windows程序设计有所了解。 在编程时,变量、函数的命名是一个极其重要的问题。好的命名方法使变量易于记忆且程序可读性大大提高。 Microsoft采用匈牙利命名法来命名 Windows API函数和变量。匈牙利命名法是由Microsoft的著名开发人员,Excel的主要设计者查尔斯西蒙尼在他的博士论文中提出来的,由于西蒙尼的国籍是匈牙利,所以这种命名法叫匈牙利命名法。 匈牙利命名法为C标识符的命名定义了一种

19、非常标准化的方式,这种命名方式是以下面两条规则为基础的: 标识符的名字以一个或者多个小写字母开头,用这些字母来指定数据类型。表l-2列出了常用的数据类型的标准前缀。 在标识符内,前缀以后就是一个或者多个第一个字母大写的单词,这些单词清楚地指出了源代码内那个对象的用途。比如,m_szStudentName表示一个学生名字的类成员变量,数据类型是字符串型,第六节 Windows API程序的开发步骤,开发基于 Windows API的应用程序一般可以参考下面的步骤。启动Visual C+编译器后,选择 File菜单下的 New菜单项,在列表框中选择 Win32 Application项。然后在 P

20、roject name文本框中输入新建的项目名,再在Location文本框中输入新建项目所在的路径。 可用如下三种方式的任意一种创建 Windows API应用程序。 An empty project一个空项目; A simpla Win32 application 一个简单的Win32应用程序 A typical Hello World”application一个典型的“Hello Word”应用程序。 如果选择A simple Win32 application项, Visual C+ 编译器将自动为用户生成项目的框架文件。 对初学 Windows API程序设计的程序员来说,“Hello

21、 World!”应用程序是一个很好的范例。当选择了 A typical Hello World!”application这一项后,Visual C+编译器会自动创建一个完整的应用程序,这个程序将在弹出的窗口中显示 Hello World!。 如果希望直接键人源程序,可以选择 An empty project这一项。 项目框架建立起来后,需要向其中加入相关的文件,这些文件可能是已经存在的,也可能是需要重新编辑建立的。 要向项目中加入文件,可以单击Visual C+编译器中Project菜单下的Add To Project级联菜单下的Files菜单项, 选择需要插入到项目中的文件,然后单击OK按钮

22、,相应的文件就会被插入到项目中。 单击 Visual C+编译器中File菜单下的 New菜单项,列表框中列出了所有可以新建的文件类型,这些文件中用得最为频繁的是C+ Source File。首先选中列表框中的C+ Source File项,然后在File文本框中键入文件名,再单击OK按钮。这样就可以在Visual C+编译器中键人相应的源文件了。其他类型的文件可以参照 C+ Source File的建立步骤。,第二章 WINDOWS应用程序框架,创建窗口只需调用CreateWindow 函数即可,但实际上并不这么简单。 但实际上并非真得这么简单。虽然创建窗口的函数确实被命名为CreateWi

23、ndow, 但您将发现 CreateWindow的第一个参数就是所谓的“窗口类名称”,并且该窗口类连接所谓的“窗口过程”。在我们调用CreateWindow之前,有一点背景知识会对您大有帮助。,第一节 WINDOWS应用程序的基本结构,进行Windows程序设计,实际上是在进行一种面向对象的程序设计(OOP)。这一点在Windows中使用得最多的对象身上表现最为明显。 这种对象正是Windows之所以命名 为“Windows”的原因,它具有人格化的特征,这就是那个叫做“窗口”的对象。,一、总体结构,桌面上最明显的窗口就是应用程序窗口。这些窗口含有显示程序名称的标题栏、菜单,甚至可能还有工具栏和

24、滚动条。另一类窗口是对话框,它可以有标题栏也可以没有标题栏。 装饰对话框表面的还有各式各样的按钮、单选钮、复选框、列表框、滚动条和文本输入区域。其中每一个小的可视对象都是一个窗口。更确切地说,这些都称为“子窗口”或“控件窗口”或“子窗口控件”。,作为对象,用户会在屏幕上看到这些窗口, 并通过键盘和鼠标直接与它们进行交互操 作。更有趣的是,程序员的观点与用户的 观点极其类似。窗口以“消息”的形式接收 窗口的输入,窗口也用消息与其他窗口通 讯。对消息的理解将是学习如何编写 Windows程序必须逾越的障碍之一。 这有一个windows的消息示例:我们知道,大多数的windows程序都有大小合适的应

25、用程序窗口。也就是说,您能够通过鼠标拖动窗口的边框来改变窗口的大小。通常,程序将通过改变窗口中的内容来响应这种大小的变化。是Windows本身而不是应用程序正在处理与用户重新调整窗口大小相关的全部代码。由于应用程序能改变其显示的格式,所以它也“知道”窗口大小改变了。,应用程序是如何知道用户改变了窗口的大小的呢? 由于程序员习惯了常规的字符模式程序,操作系统 没有设置将此类消息通知给用户的机制。问题的关 键在于理解Windows所使用的体系结构。当用户改 变窗口的大小时,Windows给程序发送一条消息指 出新窗口的大小。然后程序就可以调整窗口中的内 容,以反映大小的变化。 “Windows给程

26、序发送消息。”我们希望读者不要对这句话视而不见。它到底表达了什么意思呢?我们在这里讨论的是程序代码,而不是一个电子邮件系统。操作系统怎么给程序发送消息呢?其实,所谓“Windows给程序发送消息”,是指Windows调用程序中的一个函数,该函数的参数描述了这个特定消息。这种位于Windows程序中的函数被称为“窗口过程”。 无疑,读者对程序调用操作系统的思路是很熟悉的。例如,程序在打开磁盘文件时就要使用有关的系统调用。读者所不习惯的,可能是操作系统调用程序,而这正是Windows面向对象体系结构的基础。,程序创建的每一个窗口都有相关的窗口过程。这个 窗口过程是一个函数,既可以在程序中,也可以

27、在动态链接库中。Windows通过调用窗口过程来 给窗口发送消息。窗口过程根据此消息进行处理, 然后将控制返回给Windows。 更确切地说,窗口 通常是在“窗口类”的基础上创建的。窗口类标识 了处理窗口消息的窗口过程。使用窗口类使多个窗口能够基于同 一个窗口类,并且使用同一个窗口过程。例如,所有Windows程序中的所有按钮均基于同一个窗口类。这个窗口类与一个位于Windows动态链接库(处理所有的按钮窗口消息)的窗口过程相联系。在面向对象的程序设计中,对象是代码与数据的组合。窗口是一种对象,其代码是窗口过程。数据是窗口过程保存的信息,以及Windows为每个窗口系统中那个窗口类保存的信息。

28、窗口过程处理给窗口发送的消息。这些消息经常是告知窗口,用户正使用键盘或鼠标进行输入。这正是按钮窗口知道它被“按下”的奥妙所在。在窗口大小改变或窗口表面需要重画时,由其他消息通知窗口。,Windows程序开始执行后,Windows为该 程序创建一个“消息队列”。这个消息队列 用来存放该程序可能创建的各种不同窗口 的消息。程序中有一小段代码,叫做“消息 循环”,用来从队列中取出消息,并且将它 们发送给相应的窗口过程。有些消息直接发送给窗口过程,不用放人消息队列中。如果您对这段有关Windows体系结构的过于简略的描述将信将疑,就让我们去看看在实际的程序中,窗口、窗口类、窗口过程、消息队列、消息循环

29、和窗口消息是如何相互配合的。这或许对您会有些帮助。创建一个窗口首先需要注册一个窗口类,那需要一个窗口过程来处理窗口消息。这包 括一段几乎出现在每一个Window程序中的固定代码。程序2.1所示的HELLOWIN程序就是一个包括这段固定代码的简单程序。,吉林大学远程教育课件,Windows A P I编 程,(第三讲),主讲人 : 翟慧杰,学 时:48,第三讲),二、程序2.1,#include LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINS

30、TANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) static TCHAR szAppName = TEXT (HelloWin) ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ;,wndclass.hInstance = hInstance ; wnd

31、class.hIcon=LoadIcon(NULL, IDI_APPLICATION) ; wndclass.hCursor= LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass ( ,hwnd = CreateWindow (szAppName, / window class nam

32、e TEXT (The Hello Program), / window caption WS_OVERLAPPEDWINDOW, / window style CW_USEDEFAULT, / initial x position CW_USEDEFAULT, / initial y position CW_USEDEFAULT, / initial x size CW_USEDEFAULT, / initial y size NULL, / parent window handle NULL, / window menu handle hInstance, / program instan

33、ce handle NULL) ; / creation parameters,ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage ( ,LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) HDC hdc ; PAINTSTRUCT ps ; RECT rect ; switch (message) case WM_CREATE: PlaySound (TEXT (hellowin.wav), NU

34、LL, SND_FILENAME | SND_ASYNC) ; return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, ,三、总体考虑,实际上,每一个Windows程序代码中都包括 HELLOWINC程序的大部分。没人能真正记 住编写此代码的全部语法;通常,Windows程 序员在开始一个新程序时总是复制一个 现有的 程序,然后再做相应的修改。上面提到, HELLOWIN将在其窗口的中央显示文本串。 那不完全正确。文本实际显示在程序客户区的中央,它在图中是标题栏和边界范围内的大片白色区域。这种特性对我们很重要;客户区就是程序自由绘图并且向用户交付可观

35、输出的窗口区域。如果您认真思考一下,将会发现虽然只有80行代码,这个窗口却令人惊讶地具有许多功能。您可以用鼠标按住标题栏,在屏幕上移动窗口;可以按住边框,改变窗口的大小。在窗口大小改变时,程序自动地将“hello,windows 98!”文本串重新定位在客户区域的中央。您可以按最大化按钮,放大HELLOWIN以充满整个屏幕;也可以按最小化按钮,将程序压缩为一个图标。,您可以从系统菜单(标题栏最左端的小图际)中 执行所有选项;也可以通过从系统莱单中选择 Close选项,或者通过单未标题栏最右端的关闭 按钮,或者通过双击标题栏最左端的图标来关闭 窗口以终止程序的执行。 当然,我们首先要从整体上看一

36、下。HELLOWINC也有一个WinMain函数,但它还有另外一个函数,名为WndProc。这就是窗口过程。注意,在HELLOWIN,C中没有调用 WndProc的代码。然而,在 WinMain中有对WndProc的声明,这就是函数要在程序顶部附近声明的原因。,1. Windows 函数调用 HELLOWIN至少调用了18个Windows函数。下面以它们在 HELLOWIN,C中出现的次序列出这些函数以及各自的简明描述: LoadIcon 加载图标供程序使用; LodCursor 加载鼠标指针供程序使用; GetStockObject 获取一个图形对象,在这个例子中,是获取绘制窗口背景的刷子;

37、 RegisterClass为程序窗口注册窗口类; MessageBox 显示消息框; CreateWindow 根据窗口类创建一个窗口; ShowWindow 在屏幕上显示窗口; UpdateWindow 指示窗口刷新自身; GetMessage 从消息队列中获取消息; TranslateMessage转换某些键盘消息; DispatchMessage将消息发送给窗口过程; PlaySound 播放一个声音文件; BeginPaint 开始窗口绘制; GetClientRect 获取窗口客户区的尺寸; DrawText 显示文本串; EndPaint 结束窗口绘制; PostQuitMess

38、age 在消息队列中插入一条“退出”消息; DefWindowProc 执行默认的消息处理。 这些函数均在平台SDK文档中说明,并在不同的头文件中声明,其中绝大多数在 WINUSERH中声明。,2. 大写的标识符 大家可能注意到,在IIELIDWINC中有很多大写 的标识符,这些标识符都是在Windows的头文件 中定义的。其中有些标识符包含由两个字母或者 三个字母组成并后跟一个下划线的前缀: CS_HREDRAW CS_VREDRAW IDI_APPLICATION IDC_ARROW MB_ICONERROR WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_U

39、SEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 这些都是简单的数值常量。前缀指示该常量所属的类别,如下页 表所示。,在编写Windows程序时,不用去记这些数值常量。实际上,Windows中使用的每个数值常量在头文件中均有相应的标识符定义。,3. 新的数据类型 HELLOWINC中的其他标识符是新的数据类型, 也在Window头文件中使用 typedef 语句或者 define语句加以定义。这最初是为了便于将 Windows程序从原来的16位系统上移植到本 来的基于32位(或者其他)技术的操作系统上。 这种作法并不如当时每个人想象的那样顺利,但是这种概念基本上

40、是正确的。 有时这些新的数据类型只是为了方便起见的一个缩写。例如,用于WinProc的第二个参数的 UINT数据类型只是一个 unsigned int (无符号整数),在 Windows 98中,这是一个32位的值。 用于WinMain的第三个参数的PSTR数据类型是指向一个字符串的指针,即是一个char*。,其他数据类型的含义不太明显。例如,WndProc 的第三和第四个参数分别被定义WPARAM和LPARAM, 这些名字的来源有点历史背景:当Window是一种 16位系统时,WndProc的第三个参数被定义为一 个WORD,这是一个历位的无符号短整数,而第四个参数被定义为一个LONG,这是

41、一个32位有符号的长整数,从而导致了对单词“PARAM”加前缀“W”和“L”。当然,在32位的Windows中,WPARAM被定义为一个UINT,而LPARAM被定义为一个LONG (就是C中的long数据类型),因此窗口过程的这两个参数都是 32位的值。这也许有点奇怪,因为 WORD数据类型在 Windows 98中仍然被定义为16位的无符号整数,因此“PARAM”的“W”在某种意义上是不正确的名字。 WndProc函数返回一个类型为LRESULT的值,该值简单地被定义为一个LONG。WinMain函数被指定为一个WINAPI类型(在头文件中定义的所有Windows函数都被指定这种类型),而

42、WndProc函数被指定为一个CALLBACK类型。这两个标识符都被定义为_stdcall,指在Windows本身和用户的应用程序之间发生的函数调用的特殊调用序列。,HELLOWIN还使用了Windows头文件中定义的4种 数据结构(我们将在本章稍后加以讨论)。这些 数据结构如表所示。 表中前面两个数据结构在WinMain中使用,分别 定义了两个名为msg和wndclass的结构,后面两 个数据结构在WndProc中使用,分别定义了ps和rect结构。,4. 句柄简介 最后,还有3个大写标识符(见表),用于不同 类型的“句柄”。 句柄在Windows中使用非常频繁。 在本章结束之前,我们将遇到

43、HICON(图标句柄)、 HCURSOR鼠标指针句柄)和HBRUSH(图形刷句 柄)。 句柄是一个数(通常为32位),它代表一个 对象。Windows中的句柄类似传统C或者MSDOS程序设计中使 用的文件句柄。程序几乎总是通过调用Windows函数获取句柄。程序在其他Window函数中使用这个句柄,以引用它代表的对象。句柄的实际值对程序来说是无关紧要的。但是,向您的程序提供句柄的Windows模块知道如何使用它来引用相应的对象。,5匈牙利表示法 要在Windows上开发应用程序,就必须对Windows 程序设计有所了解。 在编程时,变量、函数的命名是一个极其重要 的问题。好的命名方法使变量易于

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

45、entName表示一个学生名字的类成员变量,数据类型是字符串型。,6. 头包含 Windows应用程序中使用的各种Windows API函数声明,宏定义,数据类型定义,windows.h是主要的包含文件,它包含了其他windows的头文件,这些头文件的某些也包含了其他头文件。这些头文件中最重要的和最基本的是: WINDEF.H :基本类型定义; WINNT.H :支持Unicode 的类型定义; WINBASE.H :内核函数; WINUSER.H :用户接口函数 WINGDU.H :图形设备接口函数。 这些头文件定义了Windows 的所有数据类型、函数调用、数据结构和常数标识符,它是Win

46、dows文档中的一个重要部分。使用 Visual C+ Developer Studio 的Edit 菜单中的Find in Files 搜索这些头文件非常方便。还可以在 Developer Studio中打开这些头文件,并直接阅读它们。,吉林大学远程教育课件,Windows A P I编 程,(第四讲),主讲人 : 翟慧杰,学 时:48,第四讲),第二节 注册窗体类函数,窗口总是在窗口类的基础上创建的,窗口类用以标识处理窗口消息的窗口过程。可以在单个窗口类的基础上创建多个窗口。例如,Windows中的所有按钮窗口包括下压按钮。复选框,以及单选按钮都是基于同一窗口类创建的。窗口类定义了窗口过程

47、和基于此类创建的窗口的其他一些特征。在创建窗口时,要定义一些窗口所独有的特征。 在为程序创建窗口之前,必须首先调用RegisterClass注册一个窗口类。该函数只需要一个参数,即一个指向类型为WNDCLASS的结构指针。,一注册窗体类函数声明 建立窗体之前,首先要对决定窗体显示风格的窗体类进行注册。 注册窗体类函数声明如下: ATOM RegisterClassEx(CONST WNDCLASSEX *lpwcx); 二形参 lpwcx 是一个指向窗体类结构类型的指针变量。 窗体类结构类型定义如下: typedef struct _WNDCLASSEX UINT cbSize; / 窗体类结

48、构类型长度; UINT style; / 窗体风格; WNDPROC lpfnWndProc; / 窗体过程指针; int cbClsExtra; / 系统保留; int cbWndExtra; / 系统保留; HANDLE hInstance; / 实例句柄; HICON hIcon; / 窗体图标; HCURSOR hCursor; / 窗体光标; HBRUSH hbrBackground; / 窗体客户区背景色; LPCTSTR lpszMenuName; / 窗体菜单指针; LPCTSTR lpszClassName; / 窗体类名称; HICON hIconSm; / 窗体小图标。

49、WNDCLASSEX;,1窗体风格选项: 窗体风格各个选项可以用 OR (|) 运算符联合表示。 CS_BYTEALIGNCLIENT CS_BYTEALIGNWINDOW CS_CLASSDC CS_DBLCLKS CS_GLOBALCLASS CS_HREDRAW CS_NOCLOSE CS_OWNDC CS_PARENTDC CS_SAVEBITS CS_VREDRAW 2窗体客户区背景色选项: COLOR_ACTIVEBORDER COLOR_ACTIVECAPTION COLOR_APPWORKSPACE COLOR_BACKGROUND COLOR_BTNFACE,COLOR_BT

50、NSHADOW COLOR_BTNTEXT COLOR_CAPTIONTEXT COLOR_GRAYTEXT COLOR_HIGHLIGHT COLOR_HIGHLIGHTTEXT COLOR_INACTIVEBORDER COLOR_INACTIVECAPTION COLOR_MENU COLOR_MENUTEXT COLOR_SCROLLBAR COLOR_WINDOW COLOR_WINDOWFRAME COLOR_WINDOWTEXT 三返回值 如果成功返回非0值,否则返回0。,第三节 建立窗体函数,窗口类定义了窗口的一般特征,因此可以使用同一 窗口类创建许多不同的窗口。实际调用Cre

51、ateWindow 创建窗口时,可能指定有关窗口的更详细的信息。 新的Window程序员有时会混淆窗口类和窗口之间的 区别,以及为什么一个窗口的所有特征不能被一步到位地指定。实际上,以这种方式分开这些风格信息是非常方便的。例如,所有的按钮窗口都可以基于同样的窗口类来创建。与这个窗口类相关的窗口过程位于Windows内部。由窗口类来负责处理按钮的键盘和鼠标输入,并定义按钮在屏幕上的外观形象。从这一点看来,所有的按钮都是以同样的方式工作的。但是并非所有的按钮都是一样的。它们可以有不同的大小,不同的屏幕位置,以及不同的正文串。后面的这样一些特征是窗口定义的一部分,而不是窗口类定义的。 建立窗体函数用

52、于建立平铺式,弹出式或子窗体。,一、函数声明 HWND CreateWindowEx(DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam);,形参: 1dwExStyle:扩展窗体风格; 扩展窗体风格各个选项可以用 OR (|) 运算符联合表示, 各个选项如下: WS_EX_ACCEPTFI

53、LES WS_EX_APPWINDOW WS_EX_CLIENTEDGE WS_EX_CONTEXTHELP WS_EX_CONTEXTHELP WS_EX_CONTROLPARENT WS_EX_DLGMODALFRAME WS_EX_LEFT WS_EX_LEFTSCROLLBAR WS_EX_LTRREADING WS_EX_MDICHILD WS_EX_NOPARENTNOTIFY WS_EX_OVERLAPPEDWINDOW WS_EX_PALETTEWINDOW WS_EX_RIGHT WS_EX_RIGHTSCROLLBAR WS_EX_RTLREADING WS_EX_STAT

54、ICEDGE WS_EX_TOOLWINDOW WS_EX_TOPMOST WS_EX_TRANSPARENT WS_EX_WINDOWEDGE,2lpClassName:窗体类名称; 3lpWindowName:窗体名称; 如果窗体名称用下列选项之一,则建立的是控件窗体。 BUTTON COMBOBOX EDIT LISTBOX MDICLIENT RichEdit RICHEDIT_CLASS SCROLLBAR STATIC,4dwStyle:窗体风格; 窗体风格各个选项可以用 OR (|) 运算符联合表示, 各个选项如下: WS_BORDER WS_CAPTION WS_CHILD W

55、S_CHILDWINDOW WS_CLIPCHILDREN WS_CLIPSIBLINGS WS_DISABLED WS_DLGFRAME WS_GROUP WS_HSCROLL WS_ICONIC WS_MAXIMIZE WS_MAXIMIZEBOX WS_MINIMIZE WS_MINIMIZEBOX WS_OVERLAPPED WS_OVERLAPPEDWINDOW WS_POPUP WS_POPUPWINDOW WS_SIZEBOX WS_SYSMENU WS_TABSTOP WS_THICKFRAME WS_TILED WS_TILEDWINDOW WS_VISIBLE WS_VSC

56、ROLL,5x:窗体左上角X坐标; 6y:窗体左上角Y坐标; 7nWidth:窗体宽度; 8nHeight:窗体高度; 9hWndParent:父窗体句柄; 10hMenu:菜单句柄; 11hInstance:实例句柄; 12lpParam:系统保留。 返回值 如果成功返回新窗体句柄,否则返回NULL。,二、实例分析 传递给 RegisterClass函数的信息在一个数据结构中说明,而传递给CreateWindow函数的信息作为函数的单独参数来说明。下面是HELLOWIN. C中的CreateWindow调用,每一个域都做了完整的注释: 此程序创建的窗口是一个普通的重叠式窗口。它含有一个标题栏

57、,标题栏左边有一个系统菜单框,标题栏右边有缩小、放大和关闭图标,四周还有一个表示窗口大小的边框。这是标准风格的窗口,名为WS_OVERLAPPEDWINDOW,该参数按“窗口风格”出现在CreateWindow中。 当创建一个“最高级”窗口,如应用程序窗口时,注释为“父窗口句柄”的参数设置为NULL。通常,如果有窗口之间存在父子关系,则子窗口总是出现在父窗口的上面。应 用程序窗口出现在桌面窗口的上面,但不必为调用CreateWindow而找出桌面窗口的句柄。,因为窗口没有菜单,所以“窗口菜单句柄”也设置为NULL。“程序实例句柄”设置为实例句柄,它是作为WinMain的参数传递给这个程序的。最

58、后,“创建参数”指针设置为NULL,可以用这个指针访问以后想要引用的程序中的数据。 CreateWindow调用返回被创建的窗口的句柄,该句柄存放在变量hwnd中,后者被定义为HWND类型(“窗口句柄类型”)。Windows中的每个窗口都有一个句柄,程序用句柄来引用窗口。许多Windows函数需要使用hwnd作为参数,这样,Window才能知道函数是针对哪个窗口的。如果一个程序创建了许多窗口,则每个窗口均有一个句柄。窗口句柄是Windows程序处理的最重要的句柄之一。,第四节 显示和更新窗体函数,在CreateWindow调用返回之后,Window内部已经 创建了这个窗口。这就是说,Windows 已经分配了 一块内存,用来保存关于在CleateWindow调用中指定 窗口的全部信息,再加 上Windows在随后所能找到 的所有其他信息。 然而,窗口并未在视频显示器上出现,这就需要再来两个调用,它们是:ShowWindow 和 UpdateWindow。 一、显示窗体客户区函数声明 BOOL ShowWindow (HWND hWnd, int nCmdShow); 形参:

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论