第2章windows程序设计教案_第1页
第2章windows程序设计教案_第2页
第2章windows程序设计教案_第3页
第2章windows程序设计教案_第4页
第2章windows程序设计教案_第5页
已阅读5页,还剩51页未读 继续免费阅读

下载本文档

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

文档简介

1、第2章 Windows程序的基本框架(教材P.136)2.1 Windows程序的进入点 WinMain()函数2.1.1 回顾DOS程序的框架 它包括一个include声明、程序的进入点、一个对执行期链接库函数的调用和一个return语句。2.1.2 Windows程序的进入点 Windows关于“hello, world”程序的等价程序有和DOS版本完全相同的组件,也包括一个include声明、一个程序进入点、一个函数调用和一个return语句。 从结构上说,Windows程序与DOS程序是相同的。表头文件stdio.h已被windows.h所代替,进入点main被WinMain所代替,而

2、且C语言执行时期链接库函数printf被Windows API函数MessageBox()所代替。然而,在程序中有许多新东西,包括几个陌生的大写标识符。 (1) 表头文件表头文件 在每个用C/C+编写的Windows程序的开头都以一个预处理命令开始:#include windows.h是主要的包含文件,其中包括大约800个API函数,2000个宏,200个数据类型。它又包含了一些其它Windows表头文件。这些表头文件中最重要的和最基本的是:WINDEF.H 基本类型定义。WINNT.H 支持Unicode的类型定义。WINBASE.H Kernel函数。WINUSER.H 用户接口函数。WI

3、NGDI.H 图形设备接口函数。 这些表头文件定义了Windows的所有数据类型、函数调用、数据结构和常数标识符,它们是Windows文件中的一个重要部分。 (2) 程序进入点 正如在C程序中的进入点是函数main一样,Windows程序的进入点是WinMain,总是像这样出现: int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance , PSTR szCmdLine, int iCmdShow) WINAPI标识符在WINDEF.H定义,语句如下:#define WINAPI _stdcall 该语句指定了一个调用约定,

4、相当于PASCAL调用协议,包括如何在堆栈中放置函数调用的参数。许多Windows函数调用都声明为WINAPI。 WinMain的第一个参数hInstace是可执行文件的实例句柄。这个句柄通常用于加载资源的函数调用。例如后面会看到,可以从可执行文件的映象中来加载图标资源。 WinMain的第二个参数hPrevInstance只用于16位Windows程序中,在32位Windows版本中,该概念已被抛弃。传给WinMain的第二个参数总是NULL(定义为0)。 WinMain的第三个参数是用于执行程序的命令行。某些Windows应用程序利用它在程序启动时将文件加载内存。 WinMain的第四个参

5、数指出程序最初显示的方式,可以是正常的或者是最大化地充满整个屏幕,或者是最小化显示在状态栏中。 (3) MessageBox()函数函数 MessageBox的第一个参数是窗口句柄,代表该消息框从属的窗口,如果为NULL则不属于任何窗口。第二个参数是在消息框主体中显示的字符串,第三个参数是出现在消息框标题栏上的字符串。在上面的例子中,这些文字字符串都被封装在一个TEXT宏中。通常不必将所有字符串都封装在TEXT宏中,除非想将你的程序中的字符串转换为Unicode字符集。MessageBox的第四个参数可以是在WINUSER.H中定义的一组以前缀MB_开始的常数的组合,例如MB_ICONINFO

6、RMATION | MB_OKCANCEL。2.1.3 关于Windows程序进入点的说明 其实Windows程序的进入点函数不止WinMain(),可以使用的进入点函数有4个:2.2 WinMain()函数的几个任务 如果程序不只是对话框那么简单,例如要创建一个标准窗口,则需要一些其他工作。2.2.1 注册窗口类 窗口依照某一窗口类来建立。建立一个窗口首先需要注册一个窗口类。窗口类定义了窗口消息处理函数和依据此类建立的窗口的其它特征。在建立窗口时,通常要定义一些该窗口所独有的特征。 注册窗口类的函数如下:typedef struct UINT style; / 窗口风格;窗口风格; WNDP

7、ROC lpfnWndProc; / 窗口过程指针;窗口过程指针; int cbClsExtra; / 系统保留;系统保留; int cbWndExtra; / 系统保留;系统保留; HANDLE hInstance; / 实例句柄;实例句柄; HICON hIcon; / 窗口图标;窗口图标; HCURSOR hCursor; / 窗口光标;窗口光标; HBRUSH hbrBackground; / 窗口客户区背景色;窗口客户区背景色; LPCTSTR lpszMenuName; / 窗口菜单指针;窗口菜单指针; LPCTSTR lpszClassName; / 窗口类名称;窗口类名称; W

8、NDCLASS, *PWNDCLASS ; 在WNDCLASS结构体中最重要的两个字段是第二个和最后一个。第二个字段(lpfnWndProc)是依据这个窗口类来建立的所有窗口所使用的窗口消息处理函数的地址。最后一个字段(lpszClassName)是窗口类的文字名称。程序员可以随意定义其名称。在只建立一个窗口的程序中,窗口类名称通常设定为程序名称。 例如,可以这样初始化一个WNDCLASS结构体变量:WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; .w

9、ndclass.lpszClassName = TEXT( “HelloWin”) ; 2.2.2 创建窗口 窗口类定义了窗口的一般特征,因此可以使用同一窗口类建立许多不同的窗口,创建窗口这个步骤就是完成这个工作。创建窗口时,可能指定有关窗口的更详细的信息,这些信息是具体窗口的一部分,而不是窗口类定义的,例如窗口的特定风格、大小、屏幕位置等。 创建窗口的函数如下: 如果创建成功则返回新窗口的句柄,否则返回NULL。句柄通常要保存起来,供以后的函数使用。 例如,可以这样创建一个窗口:HWND hwnd = CreateWindow (szAppName, / window class name

10、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 instanc

11、e handle NULL) ; / creation parameters 2.2.3 显示窗口 在CreateWindow()调用之后,Windows内部已经建立了这个窗口。这就是说,Windows已经配置了一块内存,用来保存在CreateWindow()调用中指定窗口的全部信息和一些其它信息,而Windows稍后依据窗口句柄找到这些信息。 然而,光是这样子,窗口并不会出现在显示器上。还需要调用的函数是: 第一个参数是刚刚用CreateWindow()建立的窗口句柄。第二个参数是作为参数传给WinMain()的iCmdShow。它确定最初在屏幕上显示窗口时,是一般大小、最小化还是最大化。

12、如果窗口是可见的,返回TRUE,否则返回FALSE。2.2.4. 更新窗口客户区 ShowWindow()只是显示了框架,我们还需要处理客户区。通过更新窗口客户区,发送一个WM_PAINT消息给窗口消息处理函数就可以做到这一点。 更新窗口客户区的函数为: 如果成功返回TRUE,否则返回FALSE。2.2.5 建立消息循环 调用了UpdateWindow()之后,窗口和客户区就出现在屏幕上。并且Windows已经为这个程序创建了一个消息队列。在发生一个事件之后,Windows将事件转换为一个“消息”并将消息放入程序的消息队列中。 程序通过执行一块称之为“消息循环”的程序代码从消息队列中取出消息:

13、 GetMessage()函数的声明为:lpMsg: 消息结构体变量的指针;hWnd: 将要获取消息的窗口的句柄; wMsgFilterMin:消息值下限过滤器; wMsgFilterMax:消息值上限过滤器。返回值:2.2.6 实例2.3 消息处理函数 窗口过程WndProc()2.3.1 消息处理函数的作用和形式 对消息的处理发生在窗口消息处理函数中。窗口消息处理函数确定了窗口怎样响应用户的输入以及在窗口的客户区中显示些什么。 在前面的例子中,窗口消息处理函数是命名为WndProc()的函数,但是可任意命名(只要求不和其它名字发生冲突)。 一个Windows程序可以注册多个窗口类,每个窗口

14、类和一个窗口消息处理函数相关联,所以,一个Windows程序可以有多个窗口消息处理函数。 窗口消息处理程序总是定义为如下形式: 注意,窗口消息处理函数的四个参数与MSG结构体的前四个字段是相同的。第一个参数hwnd是接收消息的窗口的句柄,它与CreateWindow()函数的传回值相同。对于只建立一个窗口的程序,这个参数是程序所知道的唯一窗口句柄。如果程序是依据同一窗口类(同时也是同一窗口消息处理函数)建立多个窗口,则hwnd标识接收消息的特定窗口。 第二个参数与MSG结构体中的message字段相同,它是标识消息的数值。最后两个参数都是32位的消息参数,提供关于消息的更多信息。2.3.2 消

15、息处理函数中怎样处理消息 一般来说,Windows程序员使用switch和case结构来确定窗口消息处理函数接收的是什么消息,以及如何适当地处理它。窗口消息处理函数在处理消息后,必须传回0。窗口消息处理函数不予处理的所有消息必须被传给名为DefWindowProc()的Windows函数,不然一般动作,如终止程序,将不会正常执行。从DefWindowProc()传回的值必须由窗口消息处理函数传回。 每个消息均是用一个无符号整数来标识的,也就是传给窗口消息处理函数的message参数。为了方便记忆,Windows为每个消息的整数值定义了一个以“WM_” 为前缀开头的标识符。 例:前面的例子中,W

16、ndProc只选择处理三种消息:WM_CREATE、WM_PAINT和WM_DESTROY。窗口消息处理函数的结构如下:2.3.3 详细研究三种消息及其处理 WM_CREATE 窗口消息处理函数接收的第一个消息是WM_CREATE。在WinMain ()中调用CreateWindow()时,Windows将做一些它必须做的工作,包括发出WM_CREATE消息。具体做法是,调用WndProc(),将第一个参数设定为窗口句柄,第二个参数设定为WM_CREATE,然后等待WndProc()返回。WndProc处理WM_CREATE消息,然后将控制传回给Windows。 Windows就可以从Crea

17、teWindow()调用中回到WinMain()中进行下一步的处理。 在我们的例子中,对这个消息的处理为播放一个名为HELLOWIN.WAV的声音文件。它简单地使用PlaySound()函数来做到这一点。然后,从窗口消息处理函数中传回0,结束了整个WM_CREATE的处理。 WM_PAINT 这个消息在Windows程序设计中非常重要。当窗口客户区的一部分显示内容或者全部变为“无效”时,系统将发出这条消息,通知程序重绘客户区。 客户区的显示内容什么时候会变得无效呢?第一,在最初建立窗口的时候,整个客户区都是无效的,因为程序还没有在窗口上画什么东西。第一条WM_PAINT消息(通常发生在WinM

18、ain()中调用UpdateWindow()时)指示窗口消息处理函数在客户区上画一些东西。 另外,当用户改变窗口的大小时、当用户将窗口最小化然后再次将窗口恢复为以前的大小时、在移动窗口时、当窗口客户区被其它窗口遮住后再次显示时,以及程序强制使客户区无效时,客户区内容都会变成无效,窗口消息处理函数将收到一条WM_PAINT消息。 对WM_PAINT的处理几乎总是从一个BeginPaint()调用开始, 而以一个EndPaint()调用结束。 在我们的例子中,要求在客户区的中央输出一个字符串,然后返回。 WM_DESTROY 这个消息表示,Windows正在根据用户的指示关闭窗口。该消息是用户单击

19、“关闭”按钮或者在程序的系统菜单上选择“关闭”时发生的。 我们的例子中,通过调用PostQuitMessage()以标准方式响应WM_DESTROY消息: 该函数在程序的消息队列中插入一个WM_QUIT消息。前面提到过,GetMessage()对于除了WM_QUIT之外的从消息队列中取出的所有消息都传回非0值,而当得到一个WM_QUIT消息时,它传回0。这将导致消息循环的退出,并终止程序。 前面的例子对应的消息处理函数的完整形式为:2.3.4 为什么不直接调用消息处理函数 程序通常不直接调用窗口消息处理函数,窗口消息处理函数通常由Windows本身调用,这就是“回调”(CALLBACK)的含义

20、。但是有时也可由程序直接调用,例如前面的例子中,可将消息循环改为: 但是在有些时候不能直接调用,例如WndProc()的返回值对Windows有某种意义时,或者处理消息需要其它回调函数时(例如WM_TIMER)。2.4 Windows应用程序的组成 编写一个典型的Windows应用程序一般需要创建几种文件: 1. C、CPP源程序文件:源程序文件包含了应用程序的数据、类、功能逻辑模块的定义。 2. H头文件:头文件包含了CPP、C源文件中所有数据、模块、类的声明。当一个CPP、C源文件要调用另一个CPP、C源文件中所定义的模块功能时,需要包含那个CPP、C文件对应的头文件。 3. RC资源文件:包含了应用程序所使

温馨提示

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

评论

0/150

提交评论