WINDOWS编程.pdf

上传人:asd****56 文档编号:70344377 上传时间:2023-01-19 格式:PDF 页数:19 大小:484.68KB
返回 下载 相关 举报
WINDOWS编程.pdf_第1页
第1页 / 共19页
WINDOWS编程.pdf_第2页
第2页 / 共19页
点击查看更多>>
资源描述

《WINDOWS编程.pdf》由会员分享,可在线阅读,更多相关《WINDOWS编程.pdf(19页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、目前世界上绝大部分的 PC 机都使用 Windows 操作系统,应用程序也基本是在该平台下运行的。基于这个原因,本书的全部实例都是采用 Windows API 开发的 Win32 应用程序。开发平台是 Microsoft VC 6.0。关于 Windows 程序设计,我想市面上有太多的相关书籍了,精通的人也不少。如果你是一个成熟的 Windows 程序员,那么你可以略去此节,直接进入基于 OpenGL 的 Windows程序部分学习。(可扩充?)在 VC 环境下的 Windows 应用程序开发一般来讲有两种模式。第一种是直接采用 Windows API 开发(优缺点?)。另一种是采用 MFC(

2、微软标准库),使用 C+的面向对象编程方式,可以最大限度地利用面向对象特性,提高开发效率。缺点是 MFC 太庞大,应用程序对它的依赖太严重,缺乏灵活性。我们的实例都采用 Windows API 来开发,原因是这些实例都很小,没必要去背上 MFC 这个大包袱。当然还有一个原因:就我目前所了解的情况来讲,大部分开发 3D 游戏的公司都没有采用 MFC 来做为游戏的应用框架,他们一般喜欢自己实现应用框架,做法当然是用 Windows API 和他们的智慧来搭建。以下是一个 Windows 窗口的实例程序 WinApplicationWinApplication,功能很简单,就是显示一个最基本的 Wi

3、ndows 窗口,在窗口中画了一个矩形。我将通过它来说明 Windows 程序的基本框架结构和工作过程。实例程序实例程序 WinApplicationWinApplication 的主文件的主文件 main.cppmain.cpp /*程序:Main.cpp *目的:显示一个简单窗口 */#include#include#include#define SCREEN_WIDTH 800 /屏幕宽度#define SCREEN_HEIGHT 600 /屏幕高度 /当前实例句柄,释放窗口类时使用 HINSTANCE g_hInstance;/声明窗口过程函数 LRESULT CALLBACK Win

4、Proc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);/CREATE MY WINDOW*/本函数负责创建窗口/CREATE MY WINDOW*HWND CreateMyWindow(LPSTR strWindowName,int width,int height,DWORD dwStyle,HINSTANCE hInstance)HWND hWnd;WNDCLASS wndclass;memset(&wndclass,0,sizeof(WNDCLASS);/初始化 wndclass wndclass.style=CS_HREDRA

5、W|CS_VREDRAW;/设置窗口风格 wndclass.lpfnWndProc=WinProc;/指定处理消息的窗口过程函数 wndclass.hInstance=hInstance;/指定窗口过程所在的实例 wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);/指定窗口图标 wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);/指定光标为常用的箭头光标 wndclass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);/指定窗口背景为白色 wndclass.lpszClassName

6、=3D Programming;/设置窗口类名称 RegisterClass(&wndclass);/注册窗口类 dwStyle=WS_OVERLAPPEDWINDOW|WS_CLIPSIBLINGS|WS_CLIPCHILDREN;g_hInstance=hInstance;/设置全局实例句柄 RECT rWindow;rWindow.left=0;/设置窗口区域的左边界值 rWindow.right=width;/设置窗口区域右边界值 rWindow.top=0;/设置窗口上边界值 rWindow.bottom=height;/设置窗口底边界值 AdjustWindowRect(&rWin

7、dow,dwStyle,false);/调整窗口到指定大小和风格 /创建窗口 hWnd=CreateWindow(3D Programming,strWindowName,dwStyle,0,0,rWindow.right -rWindow.left,rWindow.bottom-rWindow.top,NULL,NULL,hInstance,NULL);if(!hWnd)return NULL;/如果创建不成功,就返回 NULL ShowWindow(hWnd,SW_SHOWNORMAL);/显示窗口 UpdateWindow(hWnd);/更新窗口客户区 SetFocus(hWnd);/将

8、输入焦点设置到本窗口 return hWnd;/MAIN GAME LOOP*/程序主循环/MAIN GAME LOOP*WPARAM MainLoop()MSG msg;while(1)/一直循环,直到程序退出 /拣取消息 if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)if(msg.message=WM_QUIT)/如果是退出消息,则退出循环 break;TranslateMessage(&msg);/翻译消息 DispatchMessage(&msg);/将消息分配到窗口过程中 return(msg.wParam);/退出程序 /WIN MAIN*/Win3

9、2 程序的主函数/WIN MAIN*int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hprev,PSTR cmdline,int ishow)HWND hWnd;/调用 CreateMyWindow 创建窗口 hWnd=CreateMyWindow(Windows Application,SCREEN_WIDTH,SCREEN_HEIGHT,0,hInstance);/如果窗口创建不成功,则退出程序 if(hWnd=NULL)return TRUE;/进入程序主循环 return MainLoop();/WIN PROC*/窗口过程函数,负责处

10、理消息/WIN PROC*LRESULT CALLBACK WinProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)LONG lRet=0;PAINTSTRUCT ps;switch(uMsg)/处理重画消息 case WM_PAINT:BeginPaint(hWnd,&ps);HBRUSH hOldBrush,hRedBrush;hRedBrush=CreateSolidBrush(RGB(255,0,0);hOldBrush=(HBRUSH)SelectObject(ps.hdc,hRedBrush);Rectangle(ps.hdc

11、,200,150,600,450);SelectObject(ps.hdc,hOldBrush);EndPaint(hWnd,&ps);break;/消息:本窗口正被摧毁 case WM_DESTROY:/释放窗口类 UnregisterClass(3D Programming,g_hInstance);/Free the window class /请求退出窗口和应用程序 PostQuitMessage(0);break;default:/调用默认窗口过程对未处理的消息进行必要的处理。lRet=DefWindowProc(hWnd,uMsg,wParam,lParam);break;retu

12、rn lRet;在本实例中,总共使用了四个函数,其中有两个函数是最为基本的和必不可少的,将出现在所有的 Windows 应用程序中。这两个基本函数,一个是 WinMain 函数,另一个是窗口过程函数。WinMain 函数是所有 Windows 应用程序的入口点,而窗口过程函数则用于接收和处理消息。Windows 事件和消息概述事件和消息概述 Windows 有时也被称为“基于事件的,消息驱动的”操作系统。在 Windows 程序的执行过程中,只要用户进行了影响窗口的动作如改变窗口大小或者移动、单击鼠标等,该支作就会触发一个相应的“事件”。每次检测到一个事件时,操作系统就给程序发送一个“消息”,

13、从而使程序可以处理该事件。每个 Windows 程序都是基于事件和消息的,而且包含一个主事件循环,它不停地反复地检测是否有用户事件发生。每次检测到一个用户事件,程序就对该事件作出响应。例如,如果用户在应用程序的执行过程中改变了窗口的大小,那么应用程序的消息循环就会检测到用户的动作并启动一系列事件,使得窗口在屏幕上被重新绘制。只要窗口大小修改完毕,应用程序就检测是否发生了另一个用户事件。如果发生了,应用程序就处理该事件,然后检测下一事件。应用程序重复这一过程,直至用户中止程序。消息和消息处理消息和消息处理 所有 Windows 应用程序都是消息驱动的,当 Windows 操作系统检测到一个用户生

14、成的事件并相应的生成一个消息时,它把这个消息放到一个属于正在运行的应用程序的“消息队列”中。消息主要有三种类型,即标准 Windows 消息、控件通知和命令消息。标准 Windows 消息由窗口和视图处理,这类消息通常含有用于确定如何对消息进行处理的一些参数。常见的标准 Windows 消息有 WM_CHAR 消息、鼠标消息、WM_PAINT 消息、WM_HSCROLL 消息,WM_VSCROLL 消息和 WM_TIMER 消息等。控件通知包含从控件和其他子窗口传送给 WM_COMMAND 通知消息。同标准Windows 消息一样,控件通知消息由窗口和视图处理。但是用户单击按钮控件时,发出的

15、BN_CLICKED 控件通知消息将作为命令消息来处理。命令消息包含来自用户界面对象(如菜单项、工具栏按钮和快捷键等)的WM_COMMAND 通知消息,命令消息的处理与其他消息的处理不同,它可以被更广泛的对象(如文档、文档模块、应用程序模块、窗口和视图等)处理。如果某条命令直接影响某个特定的对象,则应该让该对象来处理这条命令。应用程序每次从 Windows 操作系统收到消息时,应用程序的窗口过程函数都会确定如何处理该消息,然后应用程序将消息传递给一个消息处理过程。典型的 Windows 应用程序具有为处理各种消息而专门设计的各种消息处理器。在编写 Windows API 风格的应用程序时,不仅

16、要编写检测用户事件及将适当的消息发送到适当窗口的代码,还要编写消息处理器,使它实现适于每个事件的响应。窗口过程窗口过程 窗口过程又称为窗口函数,在这个过程中属于该窗口的不同消息将会得到相应的处理。在实例程序 WinApplicationWinApplication 中,窗口过程名为 WinProc。WinProc 明确处理两条消息:WM_PAINT 和 WM_DESTROY。当接收到 WM_PAINT 消息时,应用程序就在窗口工作区画一个矩形;当用户退出应用程序时,系统就向应用程序发送 WM_DESTROY 这条消息。应用程序接到 WM_DESTROY 消息时,调用 PostQuitMessa

17、ge()函数,使得系统向应用程序发送一条 WM_QUIT 消息,就会返回 False,从而结束消息循环。WinProc 不是一个 Windows API 过程,它是一个用户开发 Windows 应用程序必须提供的过程,而且过程名不一定非得是 WinProc,用户可以给窗口过程起任何名字。另外,一个应用程序可以有多个窗口过程,如果一个应用程序具有多个窗口,那么每个窗口都可以有它自己的窗口过程。窗口过程是由 DispatchMessage()函数调用的。DispatchMessage()函数是 Windows 事件处理机制的一个重要部分,它的主要工作就是调用窗口函数,当 DispatchMessa

18、ge()调用一个应用程序的 WinProc()函数时,它告诉 WinProc 发生的是何种事件,然后,WinProc 调用消息处理器来对该事件作出响应。下图说明了在 Windows 程序的执行过程中 GetMessage()函数、GetMessage()函数和窗口过程是如何协同工作的。Windows 程序中窗口过程的工作流程 其中 GetMessage()函数捡取由 Windows 操作系统发送的消息。WinApplication 程序的工作过程程序的工作过程 在实例程序 WinApplication 中,有两个必不可少的基本函数WinMain()函数和WinProc()函数。其中 WinPr

19、oc()是窗口过程函数,它用于接收和处理消息。WinMain()函数是所用应用程序开始执行时的入口点,通常也是应用程序结束任务退出时的出口点。WinMain()函数函数 大家都知道,每个传统的 DOS 程序都有且仅有一个名为 Main 的函数,在一个 Windows API 风格的程序中,WinMain()函数完成与传统 Main()函数一样的任务,只是加入了一些Windows 特有的功能。在 WinMain()函数体中,要完成以下几点工作:1.注册应用程序的窗口类。2.创建并显示窗口,同时进行其他必要的初始化处理。3.创建和启动应用程序的消息循环。4.如果接收到 WM_QUIT 消息,则退出

20、应用程序。WinMain()函数的原型如下:int WINAPI WinMain(HINSTANCE hInstance,/当前实例句柄 HINSTANCE hPrevInstance,/前一个实例句柄 LPSTR IpszCmdLine,/命令行 int nCmdShow)其中有四个参数传递给 WinMain()hInstance 是用来标识正在运行的应用程序的当前实例的句柄。hPrevInstance 用来标识正在运行的应用程序的前一个实例的句柄。对于基于 Win32的应用程序(包括 Windows 95/98 及以后的 Windows 版本)来说,这个参数总是NULL。这是因为在这些操作

21、系统中,每个应用程序都有各自独立的地址空间,各应用程序只有唯一的实例,不会有前一个实例存在的可能。所以,hPrevInstance参数可以不要,只是为了提供与 16 位 Windows 的应用程序形式上的兼容性,才保留了这个参数。IpezCmdLine 是指向应用程序命令行的指针,该命令可以被调用来启动应用程序。nCmdShow是一个用来指定窗口显示方式的整数。它可以是SW_SHOW,SW_HIDE,SW_SHOWMAXIMIZED 和 SW_SHOWMINIZED 等,作用是指定窗口大小,坐标以及其他一些说明窗口如何显示的属性。如果 WinMain()调用成功,那么将在接收到 WM_QUIT

22、 时退出,并在 wParam 参数中返回一个值。如果在进入消息循环前程序就结束了,那么 WinMain()将返回。定义和注册窗口类定义和注册窗口类 用户执行 WinApplication 程序时,程序要做的第一件事就是执行一个过程调用来注册一个窗口类,在创建 Windows 应用程序时,在应用程序中使用的每个窗口都属于某一个窗口类。WinMain()函数中,通常要对主窗口定义一个窗口类,然后进行注册,每个窗口都有一些基本的属性,如标题栏文字、窗口大小和位置、图标以及背景颜色等。窗口类就好像是定义这些属性的模板,利用它可以生成一个特定的窗口。WNDCLASS 和和 WNDCLASSEX 结构结构

23、 定义窗口类就是把窗口类的具体属性填入 WNDCLASS 或 WNDCLASSEX 结构的相应成员中。在 WINDOWS.H 文件中,有 WNDCLASS 结构的定义说明:typedef struct_WNDCLASS UNIT style;WNDPROC lpfnWndProc;int cbClsExtra;int cbWndExtra;HANDLE hInstance;HICON hIcon;HCURSOR hCursor;LPCTSTR lpszMenuName;LPCTSTR lpszClassName;WNDCLASS;在 Windows 95 和 Windows NT 操作系统中,

24、为了支持新的窗口界面特性,还有一种扩展的窗口类结构 WNDCLASSEX,它是这样定义的:typedef struct_WNDCLASSEX UINT cbSize;NINT style;WNDPROC lpfnWndProc;int cbClsExtra;int cbWndExtra;HANDLE hInstance;HICON hIcon;HCURSOR hCursor;HBRUSH hbrBackground;LPCTSTR lpszMenuName;LPCTSTR lpszClassName;HICON hIcoSm;WNDCLASSEX;WNDCLASS 和 WNDCLASSEX 这

25、两个结构基本上是一致的,只是 WINDCLASSEX 结构中多了 cbSize 和 hIconSm 这两个成员。下表简单地介绍了各成员所代表的含义。表 窗口类结构成员 结构成员 描述 cbSize 指定 WNDCLASSEX 结构的大小(以字节为单位)style 指定类的风格 lpfn WndProc 指向窗口过程的远指针 cbClsExtra 指定分配给窗口类结构之后的额外字节数 cbWndExtra 指定分配给窗口实例之后的额外字节数 hInstance 标识窗口过程所在的实例 hIcon 标识类的图标 hCursor 标识类的光标(鼠标指针)hbrBackground 标识类的背景画刷

26、lpszMenuName 指向标识类菜单资源名的字符串,字符串以空字符结构,一般出现在资源文件中 lpszClassName 指向一个以空字符结束的字符串,该字符串标识本类的名称 hIconSm 标识类的小图标 其中 hbrBackground 参数可以是用来绘制背景的物理画刷,也可以是一个标准的系统颜色值,通常取为 COLOR_BACKGROUND,表示采用标准的系统背景色。Style 参数表示窗口类的风格,它往往是由一些基本的风格通过“或”操作(操作符为“|”)组合而来。下表列出一些常用的基本窗口风格。表 常用的窗口风格 风格值 含义 CS_HREDRAW 如果窗口客户区宽度发生改变,那么

27、重绘整个窗口 CS_VREDRAW 如果窗口客户区高度发生改变,那么重绘整个窗口 CS_DBLCLKS 当用户在属于该窗口类的窗口中双击鼠标时,就向该窗口过程发送双击消息。CS_NOCLOSE 禁用窗口系统菜单中的【关闭】命令。CS_OWNDC 为该窗口类的各窗口分配各自独一的设备描述表 CS_CLASSDC 为该窗口类的各窗口分配一个共享的设备描述表 CS_PARENTDC 指定子窗口继承其父窗口的设备描述表 CS_SAVEBITS 把被窗口遮掩的屏幕图像部分作为位图保存起来,当该窗口被移走时,Windows 采用被保存的位图来重建屏幕图像。调用调用 RegisterClass 和和 Reg

28、isterClassEx 函数函数 在 WNDCLASS 或 WNDCLASSEX 结构中定义好窗口特性之后,应用程序调用RegisterClass()或 RegisterClassEx()函数注册窗口类。对于 WNDCLASS 结构,调用 RegisterClass()函数进行注册;对于 WNDCLASSEX 结构,则调用 RegisterClassEx()函数进行注册,它们的原型分别如下:ATOM RegisterClass(CONST WNDCLASS *lpWndClass);ATOM RegisterClassEx(CONST WNDCLASSEX *lpWndClassEx);该函

29、数如果调用成功,则返回标识已注册窗口类的原子值;如果没有调用成功,则返回0。在 WinApplication 应用程序中,我们把注册窗口类的工作放在了自定义的CreateMyWindow()函数里,对 WNDCLASS 窗口类是按如下方式进行定义和注册的:WNDCLASS wndclass;memset(&wndclass,0,sizeof(WNDCLASS);/初始化 wndclass wndclass.style=CS_HREDRAW|CS_VREDRAW;/设置窗口风格 wndclass.lpfnWndProc=WinProc;/指定处理消息的窗口过程函数 wndclass.hInsta

30、nce=hInstance;/指定窗口过程所在的实例 wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);/指定窗口图标 wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);/指定光标为常用的箭头光标 wndclass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);/指定窗口背景为白色 wndclass.lpszClassName=3D Programming;/设置窗口类名称 RegisterClass(&wndclass);/注册窗口类 1、设置窗口风格 在 WNDCLASS 结构中

31、,有些成员是用来设置窗口风格的;wndclass.style 被设为值 CS_HREDRAW|CS_VREDRAW,表示只要窗口工作区的宽度或高度有所改变,就会重画整个窗口。wndclass.hbrBackground 用来定义窗口的背景画刷颜色。在 WinApplication 应用程序中,窗口的背景采用了白色。2、调入应用程序资源 在 WNDCLASS 结构中,可以调用 Windwos API 函数 LoadIcon()和 LoadCursor(),用来填充正在登记的窗口类的 hIcon 与 hCursor。wndclass.hIcon 是 通 过 LoadIcon()函 数 调 出 一个

32、 图 标 句柄 来 赋值 的。在WinApplication 应用程序中,LoadIcon(NULL.IDI_APPLICATION)语句调取系统内部预先定义好的标识为 IDI_APPLICATION 的图标作为应用程序图标。wndclass.hCursor 是通过 LoadCursor()函数调出一个鼠标光标的句柄来赋值的。在WinApplication 应用程序中,LoadCursor(NULL,IDC_ARROW)语句调取系统内部预选定义好的标识为 IDC_ARROW 的鼠标指针。3、WNDCLASS 结构中其他成员 WNDCLASS 结构中其他成员分别描述如下:lpfnWndProc

33、应设为处理窗口消息的窗口过程指针,窗口过程的参数是固定的,但其名称由用户自己定义。hInstance 应赋值为正在运行的应用程序的当前实例句柄。lpszClassName 应赋值为窗口类的一个名称或原子值。WinApplication 程序中的窗口类名称为“3D Programming”,在后面创建主窗口时将会用到这个名称。4、注册窗口类 WinApplication 程序是这样来注册窗口类的:RegisterClass(&wndclass);创建和显示窗口创建和显示窗口 在窗口类定义和注册完毕后,就可以调用 Windows API 函数 CreateWindows()和ShowWindows

34、()来创建一个用户所指定的类的窗口,并在屏幕上显示该窗口,在窗口需要更新时,可以调用 UpdateWindows()函数。创建窗口创建窗口 创建窗口的工作是通过调用 CreateWindows()函数来完成的。CreateWindows()函数可以创建一个重叠窗口、弹出窗口或子窗口,这取决于传给它的参数,当调用 CreateWindows()函数时,可以指定正在创建的那个窗口的类、标题、风格、初始位置和大小。还可以指定窗口的父窗口和新窗口的菜单。CreateWindows()函数的原型为:HEND CreatWindows(LPCSTR lpszClassName,LPCSTR lpszWin

35、dowsName,DWORD dwStyle,int x,Int y,int nWidth,int nHeight,HWND hwndParent,HMENU hmenu,HINSTANCE hinst,void FAR*lpvParam)其中各参数的含义如下:lpszClassName 是在窗口类定义和注册中已定义好的窗口类名称。lpszWindowsName 是应用程序窗口标题栏显示的作为标题的字符串。dwStyle 用于说明窗口的各个属性,若该参数为 WC_OVERLAPPEDWINDOW,表示窗口的风格是一种标准的窗口风格即有标题栏、系统菜单图标、【最小化】按钮、【还原】/【最大化】按

36、钮和【关闭】按钮且边框较粗的一种覆盖式窗口。X 和 Y 分别表示正在创建的窗口的水平和垂直位置。nWidth 和 nHeight 分别表示正在创建的窗口的宽度和高度。hWndParent 表示正在创建的窗口的父窗口的句柄。如果没有父窗口,则句柄为NULL。hmenu 表示正在创建的窗口的菜单句柄。如果使用窗口类的缺省菜单,那么该值可以为 NULL。hinst 表示当前应用程序实例的句柄。lpvParam 表示指向一个值的指针,该值由被 WM-CREATE 消息的 lparam 参数引用的 CREATESTRUCT 结构传递给窗口。在 WinApplication 示范程序中,是采用下列方式来创

37、建窗口的。dwStyle=WS_OVERLAPPEDWINDOW|WS_CLIPSIBLINGS|WS_CLIPCHILDREN;RECT rWindow;rWindow.left=0;/设置窗口区域的左边界值 rWindow.right=width;/设置窗口区域右边界值 rWindow.top=0;/设置窗口上边界值 rWindow.bottom=height;/设置窗口底边界值 AdjustWindowRect(&rWindow,dwStyle,false);/调整窗口到指定大小和风格 /创建窗口 hWnd=CreateWindow(3D Programming,strWindowNam

38、e,dwStyle,0,0,rWindow.right -rWindow.left,rWindow.bottom-rWindow.top,NULL,NULL,hInstance,NULL);首先为 dwStyle 设置窗口属性,而后定义了一个 RECT 结构变量 rWindow,用该变量来设置窗口位置和大小,通过调用 Windows API 函数 AdjustWindowRect()根据 rWindow 的值调整窗口属性。最后通过调用 API 函数 CreateWindow()创建窗口。如果窗口创建成功,那么返回值是新窗口的句柄,否则返回 NULL。显示和更新窗口显示和更新窗口 窗口创建后,并

39、不会立即在屏幕上显示出来,要真正把窗口显示在屏幕上,还得调用ShowWindows()函数。其函数原型为:BOOL ShowWindws(HWND hWnd,int nCmdShow);其中,参数 hWnd 指定要显示的窗口的句柄,nCmdShow 表示窗口的显示方式,WinApplication 示范程序中指定为 SW_SHOWNORMAL 显示方式,既普通方式,不极大化也不极小化。如果要更新窗口,就要调用 UpdateWindows()函数。其函数原型为:BOLL UpdateWindow(HWND hWnd);其中参数 hWnd 指定需要更新的窗口的句柄。消息循环消息循环 在 WinMa

40、in()函数中,创建和显示窗口之后要完成的任务主要是处理消息。Windows应用程序接受各种形式的消息输入,包括键盘、鼠标动作和计时器等产生的消息,也可以是其他应用程序发来的消息。Windows 监控所有的设备,并将消息放在消息队列中。应用程序的消息循环从应用程序的消息队列中检索并将每一条消息发送到相应的窗口函数中,下面列出的是消息循环的一般形式:While(GetMessage(&msg,NULL,0,0)TranslateMessage(&msg);DispatchMessage(&msg);这个消息循环反复地调用 GetMessage(),TranslateMessage()和 Disp

41、atchMessage()函数,从而管理应用程序的运行。当 WinMain()函数收到 PostQuitMessage()函数发送的一个WM_QUIT 消息时,循环终止,然后 WinMain()函数结束,应用程序的当前实例终止。其中 GetMessage()函数用来从应用程序的消息循环中获取消息。&msg 是指向消息结构体的指针,获取的消息将复制到 msg 中,MSG 结构在 WINDOWS.H 文件中定义如下:type struct tagMsg HWND hWnd;UNIT message;Wparam wParam;LPARAM lParam;DWORD time;POINT pt;MS

42、G;NULL 参数表示 GetMessage()将检索从属于该应用程序的所有窗口的消息,而最后两个为 0 的参数则表明 GetMessage()不会过滤任何消息。TranslateMessage()函数的作用是把虚拟键消息转换到字符消息,以满足键盘输入的需要。DispatchMessage()函数所完成的工作是把当前消息发送到对应的窗口过程中去。在 WinApplication 示范程序中,消息循环被放到了自定义的 MainLoop()函数里。当WinMain()函数调用自定义函数 CreateMyWindow()函数创建窗口成功后,就调用 MainLoop()函数。该函数是这样实现的:WPA

43、RAM MainLoop()MSG msg;while(1)/一直循环,直到程序退出 /拣取消息 if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)if(msg.message=WM_QUIT)/如果是退出消息,则退出循环 break;TranslateMessage(&msg);/翻译消息 DispatchMessage(&msg);/将消息分配到窗口过程中 return(msg.wParam);/退出程序 它和一些 Windows 程序员熟悉的消息循环的一般形式不太一样,但都达到同样的效果。while 的循环条件为 1 意味着永远持续消息循环处理,直到接收到WM

44、_QUIT消息,break 退出。注意到拣取消息用的是 PeekMessage()函数而非 GetMessage()函数。PeekMessage()函数和 GetMessage()函数功能差不多,只不过它到消息队列中拣取消息时如果有消息就拣取,如果没有消息就直接返回,返回值为 0 表示没拣取到消息。而 GetMessage()函数则一定要从消息队列中拣取到消息才返回,如果没有消息就等待,直到有消息可拣为止,如果拣取到的消息不是 WM_QUIT 它的返回值是非零,如果是 WM_QUIT 消息,返回值为零。(这里采用 PeekMessage 与我们将来要在消息处理的间隙渲染 3D 图形有关)绘图绘

45、图 在以往的 MS-DOS 环境中,与图形相关的应用程序往往要考虑各种特殊的硬件配置,比如需要考虑图形适配器的类型是 CGA、EGA 还是 VGA、SVGA,而 Windows 环境的图形设备接口(GDI)就是为了开发图形应用程序时不去考虑那些特殊的硬件配置而提供的,即提供图形系统的设备无关性。此外,在 DOS 环境中,一个 DOS 应用程序总是独占整个显示屏幕、打印机和其他设备,而在 Windows 环境下,这些输出设备是系统中的共享资源,这也就要求有一个统一的图形设备接口来支持各种应用程序,实现与图形有关的功能。设备描述表设备描述表 设备描述表(Device Context)是用来定义图形

46、对象及其属性,并且影响 GDI 输出图形方式的一种结构。这些图形对象包括画线用的画笔和填充图形所用的画刷等。应用程序并不能直接访问设备描述表。但可以通过函数调用检取设备描述表的句柄,从而间接地访问设备描述表。关于图形对象及其属性,将在下面各节中陆续介绍。Windows 中的设备描述表可分为四种类型:显示器型、打印机型、内存型和信息型。每种类型的设备描述表都有各自的特定用途,见表。表 设备描述表的类型和用途 设备描述表设备描述表 用途用途 显示器型 支持视频显示器上的绘图操作 打印机型 支持打印机和绘图仪上的绘图操作 内存型 支持位图上的绘制操作 信息型 支持设备数据的访问 最常用的设备描述表是

47、显示器设备描述表,还可更进一步地分为公共设备描述表和私有设备描述表。通过对函数 GetDC(),GetDCEx()或 BeginPaint()的调用,应用程序就可以检取指定窗口的工作区的显示器设备描述表的句柄,接下去可在后续的 GDI 函数中使用显示器设备描述表在窗口工作区中画图。当完成绘图操作之后,应用程序应该调用 ReleaseDC()或 EndPaint()函数来释放设备描述表。对于打印机设备描述表,应用程序通过调用 CreateDC()函数来创建,打印完毕后,应调用 DeleteDC()函数来删除。内存设备描述表是通过调用 GreateCompatibleDC()函数而创建出来的。它将

48、创建一个与指定设备有兼容颜色格式的位图,因为这种位图与指定设备相兼容,所以内存设备描述表也常称为兼容设备描述表。下面列出了与设备描述表有关的常用函数。1、GetDC()函数 GetDC()函数用于获取指定窗口的工作区的显示器设备描述表。其原型如下:HDC GetDC(HWND hWnd);其中参数 hWnd 为给定窗口的句柄。返回值为给定窗口的客户区的设备描述表的句柄。如果调用失败,返回值为 NULL。对于公共设备描述表,每次调用 GetDC()函数,都会给设备描述表赋予默认属性;而对于私有设备描述表,则保留以前赋予的属性不变。提示:如果有特殊情况,需要在窗口的非工作区(如标题栏、菜单栏和滚动

49、条等)进行画图操作,那么就应该使用 GetWindwoDC()函数来获取整个窗口的设备描述表,而窗口非用 户区域中各元件(如标题栏、菜单栏和滚动条等)的几何尺寸可通过调用 GetSystemMetrics()函数检取。2、ReleaseDC()函数 ReleaseDC()函数用来释放设备描述表。其原型如下:int ReleaseDC(HWND hWnd,HDC hDC);其中 hWnd 参数为窗口句柄,hDC 参数表示设备描述表句柄。如果设备描述表被释放,则返回 1,否则返回 0。3、BeginPaint()函数 BeginPaint()函数为在指定窗口中画图做准备工作,并且把与画图有关的信息

50、填写到PAINTSTRUCT 结构中。其原型如下:HDC BeginPaint(HWND hWnd,LPPAINTSTRUCT lpPaint);其中 hWnd 参数为窗口句柄,lpPaint 参数是指向 PAINTSTRUCT 结构的指针。若函数调用成功,就返回指定窗口的显示器设备描述表句柄;否则就返回 NULL。PAINTSTRUCT结构包括了对画图操作有用的各种信息,它在Winuser.h头文件中定义。Typedef struct tagPAINTSTRUCT HDC hdc;BOOL fErase;RECT rcPaint;BOOL fRestore;BOOL fIncUpdate;B

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 其他杂项

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com