SDK编程.doc_第1页
SDK编程.doc_第2页
SDK编程.doc_第3页
SDK编程.doc_第4页
SDK编程.doc_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

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

文档简介

什么是WinSDK:大致说来windows编程有两种方法:1.windwosc方式(SDK),2.c+方式:即对SDK函数进行包装,如VC的MFC,BCB的OWL等,如果要深入下去,还是要熟悉SDK。两种方法有哪些区别呢:SDK编程就是直接调用windows的API进行编程,但是有上千个API组成(win95的API有两千多个),这种数目太大了,对于编程显然不利。而MFC把这些API封闭起来,共有一百多个类组成。一般只需20多个windows类和另外20多个通用的非windows类就可干活了,这一改变无疑是有很大好处的。尽管MFC如此方便,但是要学VC,直接去学MFC却是不明智的选择。只有在熟悉了MFC的运行机制的情况下,才有可能深入下去。那些如多少天精通什么什么的书籍其实讲的全是些如怎么使用VC这种工具的话题,学来学去学会了怎么会使用VC这种工具,而不能深入MFC编程。象VB这类工具就更令人感觉到太闷了,不过各有各的好处。MFC虽然提高了程序员编程的效率,但是也失去了SDK编程的灵活性.不好意思,跑题了.本专题假定:C语言是windows的源语言,用C进行SDK编程是最合适的,你应该至少学过C语言,知道C语言的各种语法等,当我说到指针等类似概念的时候,你不至于茫然就行了。你还应该安装了VisualC+6.0,低版本的就不用用了吧,D版的才几块钱吗?推荐与参考资料:1.Petzold的programmingwindowsbypetzold,这是我看过的一本书(电子书),不过是E文的,我只看了一半,下载空间一栏能供了该电子书。中文版的是Windows程序设计(包括上,下卷),CharlesPetzold著,北京博彦发展有限公司译,北京大学出版社出版,本书唯一的缺点就是太贵,价格是160元。一些朋友让我多推荐一些这方面的书,我也没办法,一是这类书目前本就很少,二是如果你非要买的话,肯定要买这本书了,可是经典呢!2.还有一本老书值得一提,可能市面上已经买不到了,书名Windows编程,刘振安著,人民邮电出版社出版发行。一个朋友曾借给我看了几天我又还了,很容易读懂的,不过一看日期,95年出版,得!没希望了。我们学校图书馆好像也有几本,不过好像都很烂。3.VC的在线帮助MSDN,有关SDK的资料在PlatformSDK一栏中。下面再加深几点概念:什么是API:什么是API,有必要再谈一下,特别对于从TC过来的朋友和初学编程的朋友。API,全称applicationprograminterface,意思是应用程序编程接口(说起API并不仅仅指windows而言,windows支持的API叫winapi)。winapi就是应用程序和windows之间通讯的一个编程界面。windows提供了上千个API函数,以方便程序员来编写应用程序。做数据库管理系统是很少和API打交道的,我以前学PB,看的十几本书都没有专门的章节来介绍API的。只有到网上看那些PB技巧之类的文章才谈及API,不过还要加入一大堆声明之类的东东。好像VB也是这样。总之,进行系统编程,API是必不可少的。API是每个VC高手的必过的一关。什么是WinSDK编程:WinSDK程序设计就是API方式的windows程序设计。SDK,全称SoftwareDevelopersKit,意思是软件开发工具箱。它是在windows程序设计早期,程序员进行windows程序设计所必须购买的一个软件包(不知道那时候有没有D版的)。我两个月前见SDK还不知所云。开始进行WinSDK编程用C语言最好,可以撇开C+的特性专心熟悉一下Win32编程的思路以及了解windows的消息运行机制。等把这些有所了解后,慢慢转向C+和MFC编程。不过我的观点是WinSDK编程永远要慢慢进行下去,直接接触底层代码对MFC源码的理解是有很大好处的。上周开始用MFC时,按F11进行单步跟踪,一开始见到_tWinMain这样古怪的东东也没有感觉到太大的迷惑,不就是相当于SDK编程中的WinMain函数吗?什么是MFC:MFC,全称MicrosoftFoundationClasses,伪软把WinAPI进行封装的类库。它是一个类的集合,通过覆盖WinAPI,为编程提供了一个面向对象的界面。它使windows程序员能够利用C+面象对象的特性进行编程,类似BCB的OWL,Delphi的VCL组件。它把那些进行SDK编程时最繁琐的部分提供给程序员,使之专注于功能的实现。你不妨把它想象成类似TC提供的函数库吧。用VisualC+这种开发工具编程时,可以用MFC,也可以不用,但MFC是VC的精华所在,从某种意义上来说,不会MFC就是不会使用VC。研究MFC源代码是件既快乐又痛苦的事情,不过,阵痛之后,嘻嘻,.怎么进行WinSDK编程:VisualC+6.0:File-new-Projects-Win32Application(projectname)-.我们既然用C语言进行,就选第一项Anemptyproject.SDK编程讲座 之 第二讲:WinMain与两只小板凳的故事(转载)第一只小板凳:打开anemptyproject后,在VC的IDE中,打开文本编辑器。输入以下内容:#includewindows.hintWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,PSTRszCmdLine,intiCmdShow)MessageBox(NULL,TEXT(你好,欢迎来到VC之路),TEXT(欢迎),0);return0;把它保存成以.c为扩展名的文件,并加入空项目中。编译.看到了吧,这就我们的第一只小板凳。它就类似于TC下的helloworld吧!虽然什么功能也没实现,但它比helloworld强多了,因为它向我们展示了一个小窗口。支解第一只小板凳:像TC一样,它包含一个头文件windows.h,这是一个最基本的头文件,它包含其它的windows头文件.在你的X:ProgramFilesMicrosoftVisualStudioVC98Include目录下,打开windows.h这个文件,你就知道它包含什么东东了。像dos下的C编程的main()一样,windows下的入口是WinMain()函数。把光标放在WinMain()上,按F1键。启动MSDN,如果你没安装的话,一定要安装一下,MSDN是最好的学习VC的资料,当然,对于我们入门者,有一本书从头到尾学一下最好。第一个参数:应用程序的当前实例句柄。第二个参数:应用程序的前一个实例句柄,别管它,对于Win32位而言,它一般是NULL.第三个参数:指向任何传给程序的命令行参数。PSTR代表指向字符串的指针。第四个参数:它告诉应用程序如何初始化窗口,如最大化,最小化等状态。WinMain()所起的作用:初始化,展示,销毁应用程序等。MessageBox(),如果大家在windows下编程,这是一个很常用的API,不用我费话了吧!几个要点:1.句柄(handle):在标准C库中句柄用来对文件输入输出。如下面的代码:inthandle;handle=open(filename,r)if(handle)read(handle,block,bytesToread);close(handle);在文件被成功打开后,open()返回一个句柄,在read()中使用这个句柄来阅读这个文件。句柄不是指针。程序不能直接使用句柄来阅读文件中的信息。如果不能把它传送给输入输出函数调用的话,句柄就没有用了。句柄不返回零。句柄命名以h开始。这是匈牙利表示法的规定。2.匈牙利表示法:初开始看到这个程序时,你一定感觉到很怪,我当时就是这样的。不知道那些字母怎么回事。因为所有的命名采用了,匈牙利表示法。如消息的前缀使用msg.句柄使用h.函数使用fn等。多说了,习惯了就好了.3.有效使用MSDN:想成为VC高手,还要强迫自己习惯于使用MSDN,看得多了,不怕看不懂,如果仅仅知道功能不知道具体的函数,可用类似的英语单词去搜索。我平时就用金山词霸一点点的啃。唉,说起来惭愧,本人英语四级没过,这学期连报考都没有。以后努力了,总感觉到大学的教育很有问题,好像每个人都在为四六级而奔忙。呵呵,说了这些,真怀疑对你真的有用。有不对的地方,请指出。希望大家共同进步,把VC活吃了.第二只小板凳打开VC,file-new-progects-win32application,并在projectname中输入hello.顺路走下来,选择第二项。在编辑器中输入以下程序覆盖向导产生的代码:#includestdafx.h/注意,这个向导产生的头文件不能去掉#includeLRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,PSTRszCmdLine,intiCmdShow)staticTCHARszAppName=TEXT(HelloWin);HWNDhwnd;MSGmsg;WNDCLASSwc;wc.style=CS_HREDRAW|CS_VREDRAW;wc.lpfnWndProc=WndProc;wc.cbClsExtra=0;wc.cbWndExtra=0;wc.hInstance=hInstance;wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);wc.hCursor=LoadCursor(NULL,IDC_ARROW);wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);wc.lpszMenuName=NULL;wc.lpszClassName=szAppName;if(!RegisterClass(&wc)MessageBox(NULL,TEXT(ThisprogramrequiresWindowsNT!),szAppName,MB_ICONERROR);return0;hwnd=CreateWindow(szAppName,/windowclassnameTEXT(欢迎你的到来!),/windowcaptionWS_OVERLAPPEDWINDOW,/windowstyleCW_USEDEFAULT,/initialxpositionCW_USEDEFAULT,/initialypositionCW_USEDEFAULT,/initialxsizeCW_USEDEFAULT,/initialysizeNULL,/parentwindowhandleNULL,/windowmenuhandlehInstance,/programinstancehandleNULL);/creationparametersShowWindow(hwnd,iCmdShow);UpdateWindow(hwnd);while(GetMessage(&msg,NULL,0,0)TranslateMessage(&msg);DispatchMessage(&msg);returnmsg.wParam;LRESULTCALLBACKWndProc(HWNDhwnd,UINTmessage,WPARAMwParam,LPARAMlParam)HDChdc;PAINTSTRUCTps;RECTrect;switch(message)caseWM_PAINT:hdc=BeginPaint(hwnd,&ps);GetClientRect(hwnd,&rect);DrawText(hdc,TEXT(你好,欢迎你来到VC之路!),-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);EndPaint(hwnd,&ps);return0;caseWM_DESTROY:PostQuitMessage(0);return0;returnDefWindowProc(hwnd,message,wParam,lParam);按前两节讲的方法编译后,就见到我们的第二只小板凳了,可别小看它,对它的全面理解对于学习MFC的封装是有很大好处的。windows的消息循环机制等都可通过这个东东解释出来。好了,咱们年后继续努力吧,应该应付一下该死的考试了.SDK编程讲座 之 第三讲:Windows消息机制(1)Dos的过程驱动与Windows的事件驱动在讲本程序的消息循环之前,我想先谈一下Dos与Windows驱动机制的区别:DOS程序主要使用顺序的,过程驱动的程序设计方法。顺序的,过程驱动的程序有一个明显的开始,明显的过程及一个明显的结束,因此程序能直接控制程序事件或过程的顺序。虽然在顺序的过程驱动的程序中也有很多处理异常的方法,但这样的异常处理也仍然是顺序的,过程驱动的结构。而Windows的驱动方式是事件驱动,就是不由事件的顺序来控制,而是由事件的发生来控制,所有的事件是无序的,所为一个程序员,在你编写程序时,你并不知道用户先按哪个按纽,也不知道程序先触发哪个消息。你的任务就是对正在开发的应用程序要发出或要接收的消息进行排序和管理。事件驱动程序设计是密切围绕消息的产生与处理而展开的,一条消息是关于发生的事件的消息。Windows编程的特点:C语言编程至少有一个主程序,其名字是main()。Windows程序则至少两个主程序,一个是WinMain(),intWINAPIWinMain(HINSTANCEhInstance,/handletocurrentinstanceHINSTANCEhPrevInstance,/handletopreviousinstanceLPSTRlpCmdLine,/commandlineintnCmdShow/showstate);另一个是窗口过程函数WndProc,它的函数原型为:longFARPASCALWndProc(HWNDhWnd,WORDmessage,WORDwParam,LONGlParam);Windows应用程序的编程就围绕这两个部份进行的。其中WinMain函数为应用程序的入口点,它的名字一定要是WinMain。在Windows中,应用程序通过要求Windows完成指定操作,而承担这项通信任务的API函数就是Windows的相应窗口函数WndProc。在dos里,程序能直接控制事件的发生顺序,结果等。而在Windows里,应用程序不直接调用任何窗口函数,而是等待Windows调用窗口函数,请求完成任务或返回信息。为保证Windows调用这个窗口函数,这个函数必须先向Windows登记,然后在Windows实施相应操作时回调,所以窗口函数又称为回调函数。WndProc是一个主回调函数,Windows至少有一个回调函数。回调函数WndProc在哪里定义的呢,请看这个语句:wc.lpfnWndProc=WndProc;将在第七讲里详谈.实例:在Windows中,能多次同时运行同一个应用程序,即运行多个副本,每个副本叫做一个“实例”。现在让我们把这个程序层层剥解开来,我把自己的理解慢慢地展示给你:我把这个程序支解为四块:(一)建立,注册窗口类.(二)创建窗口.(三)显示和更新窗口.(四)创建消息循环.(五)终止应用程序.(六)窗口过程.(七)处理消息.(一)注册窗口类:(1)建立窗口类WinMain()是程序的入口,它相当于一个中介人的角色,把应用程序(指小窗口)介绍给windows.首要的一步是登记应用程序的窗口类.窗口种类是定义窗口属性的模板,这些属性包括窗口式样,鼠标形状,菜单等等,窗口种类也指定处理该类中所有窗口消息的窗口函数.只有先建立窗口种类,才能根据窗口种类来创建Windows应用程序的一个或多个窗口.创建窗口时,还可以指定窗口独有的附加特性.窗口种类简称窗口类,窗口类不能重名.在建立窗口类后,必须向Windows登记.建立窗口类就是用WNDCLASS结构定义一个结构变量,在这个程序中就是指WNDCLASSwc;然后用自己设计的窗口属性的信息填充结构变量wc的域.要WinMain登记窗口类,首先要填写一个WNDCLASS结构,其定义如下所示:typedefstruct_WNDCLASSAUINTstyle;/窗口类风格WNDPROClpfnWndProc;/指向窗口过程函数的指针intcbClsExtra;/窗口类附加数据intcbWndExtra;/窗口附加数据HINSTANCEhInstance;/拥有窗口类的实例句柄HICONhIcon;/最小窗口图标HCURSORhCursor;/窗口内使用的光标HBRUSHhbrBackground;/用来着色窗口背景的刷子LPCSTRlpszMenuName;/指向菜单资源名的指针LPCSTRlpszClassName;/指向窗口类名的指针在VC6.0里面,把光标定位在WNDCLASS上,按F1,即可启动MSDN,在MSDN里你可看到这个结构原形.在下节讲解这些参数在本程序中的具体用法.(2)注册窗口类(1)第一个参数:成员style控制窗口的某些重要特性,在WINDOWS.H中定义了一些前缀为CS的常量,在程序中可组合使用这些常量.也可把sytle设为0.本程序中为wc.style=CS_HREDRAW|CS_VREDRAW,它表示当窗口的纵横坐标发生变化时要重画整个窗口。你看:无论你怎样拉动窗口的大小,那行字都会停留在窗口的正中部,而假如把这个参数设为0的话,当改动窗口的大小时,那行字则不一定处于中部了。(2)第二个参数:lpfnWndProc包括一个指向该窗口类的消息处理函数的指针,此函数称为窗口过程函数。它将接收Windows发送给窗口的消息,并执行相应的任务。其原型为:longFARPASCALWndProc(HWND,unsigned,WORD,LONG);并且必须在模快定义中回调它。WndProc是一个回调函数(见第五节),如果暂时无法理解这个模糊的概念意味着什么,可先放过,等到讲消息循环时再详谈。(3)第三,四个参数:cbWndExtra域指定用本窗口类建立的所有窗口结构分配的额外字节数。当有两个以上的窗口属于同一窗口类时,如果想将不同的数据和每个窗口分别相对应。则使用该域很有用。这般来讲,你只要把它们设为0就行了,不必过多考虑。(4)第五个参数:hInstance域标识应用程序的实例hInstance,当然,实例名是可以改变的。wc.hInstance=hInstance;这一成员可使Windows连接到正确的程序。(5)第六个参数:成员hIcon被设置成应用程序所使用图标的句柄,图标是将应用程序最小化时出现在任务栏里的的图标,用以表示程序仍驻留在内存中。Windows提供了一些默认图标,我们也可定义自己的图标,VC里面专有一个制作图标的工具。(6)第七个参数:hCursor域定义该窗口产生的光标形状。LoadCursor可返回固有光标句柄或者应用程序定义的光标句柄。IDC_ARROW表示箭头光标.(7)第八个参数:wc.hbrBackground域决定Windows用于着色窗口背景的刷子颜色,函数GetStockObject返回窗口的颜色,本程序中返回的是白色,你也可以把它改变为红色等其他颜色.试试看(8)第九个参数:lpszMenuName用来指定菜单名,本程序中没有定义菜单,所以为NULL。(9)第十个参数:lpszClassName指定了本窗口的类名。当对WNDCLASS结构域一一赋值后,就可注册窗口类了,在创建窗口之前,是必须要注册窗口类的,注册窗口类用的API函数是RegisterClass,注册失败的话,就会出现一个对话框如程序所示,函数RegisterClass返回0值,也只能返回0值,因为注册不成功,程序已经不能再进行下去了。在本程序中注册窗口类如下:if(!RegisterClass(&wc)MessageBox(NULL,TEXT(ThisprogramrequiresWindowsNT!),szAppName,MB_ICONERROR);return0;SDK编程讲座 之 第三讲:Windows消息机制(2)(二)创建窗口注册窗口类后,就可以创建窗口了,本程序中创建窗口的有关语句如下:hwnd=CreateWindow(szAppName,/windowclassnameTEXT(欢迎你的到来!),/windowcaptionWS_OVERLAPPEDWINDOW,/windowstyleCW_USEDEFAULT,/initialxpositionCW_USEDEFAULT,/initialypositionCW_USEDEFAULT,/initialxsizeCW_USEDEFAULT,/initialysizeNULL,/parentwindowhandleNULL,/windowmenuhandlehInstance,/programinstancehandleNULL);/creationparameters参数1:登记的窗口类名,这个类名刚才咱们在注册窗口时已经定义过了。参数2:用来表明窗口的标题。参数3:用来表明窗口的风格,如有无最大化,最小化按纽啊什么的。参数4,5:用来表明程序运行后窗口在屏幕中的坐标值。参数6,7:用来表明窗口初始化时(即程序初运行时)窗口的大小,即长度与宽度。参数8:在创建窗口时可以指定其父窗口,这里没有父窗口则参数值为0。参数9:用以指明窗口的菜单,菜单以后会讲,这里暂时为0。最后一个参数是附加数据,一般都是0。CreateWindow()的返回值是已经创建的窗口的句柄,应用程序使用这个句柄来引用该窗口。如果返回值为0,就应该终止该程序,因为可能某个地方出错了。如果一个程序创建了多个窗口,则每个窗口都有各自不同的句柄.(三)显示和更新窗口API函数CreateWindow创建完窗口后,要想把它显示出现,还必须调用另一个API函数ShowWindows.形式为:ShowWindow(hwnd,iCmdShow);其第一个参数是窗口句柄,告诉ShowWindow()显示哪一个窗口,而第二个参数则告诉它如何显示这个窗口:最小化(SW_MINIMIZE),普通(SW_SHOWNORMAL),还是最大化(SW_SHOWMAXIMIZED)。WinMain在创建完窗口后就调用ShowWindow函数,并把iCmdShow参数传送给这个窗口。你可把iCmdShow改变为这些参数试试。WinMain()调用完ShowWindow后,还需要调用函数UpdateWindow,最终把窗口显示了出来。调用函数UpdateWindow将产生一个WM_PAINT消息,这个消息将使窗口重画,即使窗口得到更新.(四)创建消息循环主窗口显示出来了,WinMain就开始处理消息了,怎么做的呢?Windows为每个正在运行的应用程序都保持一个消息队列。当你按下鼠标或者键盘时,Windows并不是把这个输入事件直接送给应用程序,而是将输入的事件先翻译成一个消息,然后把这个消息放入到这个应用程序的消息队列中去。应用程序又是怎么来接收这个消息呢?这就讲讲消息循环了。应用程序的WinMain函数通过执行一段代码从她的队列中来检索Windows送往她的消息。然后WinMain就把这些消息分配给相应的窗口函数以便处理它们,这段代码是一段循环代码,故称为消息循环。这段循环代码是什么呢?好,往下看:在咱们的第二只小板凳中,这段代码就是:.MSGmsg;/定义消息名while(GetMessage(&msg,NULL,0,0)TranslateMessage(&msg);/翻译消息DispatchMessage(&msg);/撤去消息returnmsg.wParam;MSG结构在头文件中定义如下:typedefstructtagMSGHWNDhwnd;UINTmessage;WPARAMwParam;LPARAMlParam;DWORDtime;POINTpt;MSG,*PMSG;MSG数据成员意义如下:参数1:hwnd是消息要发送到的那个窗口的句柄,这个窗口就是咱们用CreateWindows函数创建的那一个。如果是在一个有多个窗口的应用程序中,用这个参数就可决定让哪个窗口接收消息。参数2:message是一个数字,它唯一标识了一种消息类型。每种消息类型都在Windows文件中定义了,这些常量都以WM_开始后面带一些描述了消息特性的名称。比如说当应用程序退出时,Windows就向应用程序发送一条WM_QUIT消息。参数3:一个32位的消息参数,这个值的确切意义取决于消息本身。参数4:同上。参数5:消息放入消息队列中的时间,在这个域中写入的并不是日期,而是从Windows启动后所测量的时间值。Windows用这个域来使用消息保持正确的顺序。参数6:消息放入消息队列时的鼠标坐标.消息循环以GetMessage调用开始,它从消息队列中取出一个消息:GetMessage(&msg,NULL,0,0),第一个参数是要接收消息的MSG结构的地址,第二个参数表示窗口句柄,NULL则表示要获取该应用程序创建的所有窗口的消息;第三,四参数指定消息范围。后面三个参数被设置为默认值,这就是说你打算接收发送到属于这个应用程序的任何一个窗口的所有消息。在接收到除WM_QUIT之外的任何一个消息后,GetMessage()都返回TRUE。如果GetMessage收到一个WM_QUIT消息,则返回FALSE,如收到其他消息,则返回TRUE。因此,在接收到WM_QUIT之前,带有GetMessage()的消息循环可以一直循环下去。只有当收到的消息是WM_QUIT时,GetMessage才返回FALSE,结束消息循环,从而终止应用程序。均为NULL时就表示获取所有消息。消息用GetMessage读入后(注意这个消息可不是WM_QUIT消息),它首先要经过函数TranslateMessage()进行翻译,这个函数会转换成一些键盘消息,它检索匹配的WM_KEYDOWN和WM_KEYUP消息,并为窗口产生相应的ASCII字符消息(WM_CHAR),它包含指定键的ANSI字符.但对大多数消息来说它并不起什么作用,所以现在没有必要考虑它。下一个函数调用DispatchMessage()要求Windows将消息传送给在MSG结构中为窗口所指定的窗口过程。我们在讲到登记窗口类时曾提到过,登记窗口类时,我们曾指定Windows把函数WindosProc作为咱们这个窗口的窗口过程(就是指处理这个消息的东东)。就是说,Windows会调用函数WindowsProc()来处理这个消息。在WindowProc()处理完消息后,代码又循环到开始去接收另一个消息,这样就完成了一个消息循环。SDK编程讲座 之 第三讲:Windows消息机制(3)(五)终止应用程序:Windows是一种非剥夺式多任务操作系统。只有的应用程序交出CPU控制权后,Windows才能把控制权交给其他应用程序。当GetMessage函数找不到等待应用程序处理的消息时,自动交出控制权,Windows把CPU的控制权交给其他等待控制权的应用程序。由于每个应用程序都有一个消息循环,这种隐式交出控制权的方式保证合并各个应用程序共享控制权。一旦发往该应用程序的消息到达应用程序队列,即开始执行GetMessage语句的下一条语句。当WinMain函数把控制返回到Windows时,应用程序就终止了。应用程序的启动消息循环前要检查引导出消息循环的每一步,以确保每个窗口已注册,每个窗口都已创建。如存在一个错误,应用程序应返回控制权,并显示一条消息。但是,一旦WinMain函数进入消息循环,终止应用程序的唯一办法就是使用PostQuitMessage把消息WM_QUIT发送到应用程序队列。当GetMessage函数检索到WM_QUIT消息,它就返回NULL,并退出消息外循环。通常,当主窗口正在删除时(即窗口已接收到一条WM_DESTROY消息),应用程序主窗口的窗口函数就发送一条WM_QUIT消息。虽然WinMain指定了返回值的数据类型,但Windows并不使用返回值。不过,在调试一应用程序时,返回值地有用的。通常,可使用与标准C程序相同的返回值约定:0表示成功,非0表示出错。PostQuitMessage函数允许窗口函数指定返回值,这个值复制到WM_QUIT消息的wParam参数中。为了的结束消息循环之后返回这个值,我们的第二只小板凳中使用了以下语句:returnmsg.wParam;/表示从PostQuitMessage返回的值例如:当Windows自身终止时,它会撤消每个窗口,但不把控制返回给应用程序的消息循环,这意味着消息循环将永远不会检索到WM_QUIT消息,并且的循环之后的语句也不能再执行。Windows的终止前的确发送一消息给每个应用程序,因而标准C程序通常会的结束前清理现场并释放资源,但Windows应用程序必须随每个窗口的撤消而被清除,否则会丢失一些数据。(六)窗口过程,窗口过程函数如前所述,函数GetMessage负责从应用程序的消息队列中取出消息,而函数DispatchMessage()要求Windows将消息传送给在MSG结构中为窗口所指定的窗口过程。然后出台的就是这个窗口过程了,这个窗口过程的任务是干什么呢?就是最终用来处理消息的,就是消息的处理器而已,那么这个函数就是WindowProc,在VisualC+6.0中按F1启动MSDN,按下面这个路径走下来:PlatFormSDK-UserInterfaceservices-WindowsuserInterface-Windowing-WindowProcedures-WindowProcedureReference-WindowsProcedureFunctions-WindowProc啊,太累了,不过我们终于的MSDN中找到了这个函数,前几次我讲解这些API函数的时候,都是的知道的情况下搜索出来的,所以没有详细给出每个函数的具体位置,而这次我却是一点点去找的,还好,没被累死,体会到MSDN的庞大了吧,不过我用的是MSDN2000,是D版的,三张光盘装。你用的MSDN如果按这个路径走下去的话,可能会找不到,不过我想大致也是在这个位置了,找找看!LRESULTCALLBACKWindowProc(HWNDhwnd,/handletowindowUINTuMsg,/messageidentifierWPARAMwParam,/firstmessageparameterLPARAMlParam/secondmessageparameter);这个函数我们的第二只小板凳里被我们称为WndProc.下面讲解:不知你注意到了没有,这个函数的参数与刚刚提到的GetMessage调用把返回的MSG结构的前四个成员相同。如果消息处理成功,WindowProc的返回值为0.Windows的启动应用程序时,先调用WinMain函数,然后调用窗口过程,注意:在我们的这个程序中,只有一个窗口过程,实际上,也许有不止一个的窗口过程。例如,每一个不同的窗口类都有一个与之相对应的窗口过程。无论Windows何时想传递一个消息到一窗口,都将调用相应的窗口过程。当Windows从环境,或从另一个应用程序,或从用户的应用程序中得到消息时,它将调用窗口过程并将信息传给此函数。总之,窗口过程函数处理所有传送到由此窗口类创建的窗口所得到的消息。并且窗口过程有义务处理Windows扔给它的任何消息。我们在学习Windows程序设计的时候,最主要的就是学习这些消息是什么以及是什么意思,它们是怎么工作的。令我们不解的是,在程序中我们看不出来是哪一个函数在调用窗口过程。它其实是一个回调函数.前面已经提到,Windows把发生的输入事件转换成输入消息放到消息队列中,而消息循环将它们发送到相应的窗口过程函数,真正的处理是在窗口过程函数中执行的,在Windows中就使用了回调函数来进行这种通信。回调函数是输出函数中特殊的一种,它是指那些在Windows环境下直接调用的函数。一个应用程序至少有一个回调函数,因为在应用程序处理消息时,Windows调用回调函数。这种回调函数就是我们前面提到的窗口过程,它对对应于一个活动的窗口,回调函数必须向Windows注册,Windows实施相应操作即行回调。每个窗口必须有一个窗口过程与之对应,且Windows直接调用本函数,因此,窗口函数必须采用FARPASCAL调用约定。在我们的第二只小板凳中,我们的窗口函数为WndProc,必须注意这里的函数名必须是前面注册的窗口类时,向域wc.lpfnWndProc所赋的WndProc。函数WndProc就是前面定义的窗口类所生成的所有窗口的窗口函数。在我们的这个窗口函数中,WndProc处理了共有两条消息:WM_PAINT和WM_DESTROY.窗口函数从Windows中接收消息,这些消息或者是由WinMain函数发送的输入消息,或者是直接来自Windows的窗口管理消息。窗口过程检查一条消息,然后根据这些消息执行特定的动作未被处理的消息通过DefWindowProc函数传回给Windows作缺海上处理。可以发送窗口函数的消息约有220种,所有窗口消息都以WM_开头,这些消息在头文件中被定义为常量。引起Windows调用窗口函数的原因有很多,如改变窗口大小啊,改变窗口在屏幕上的位置啊什么的。Windows已经把任务扔给窗口过程了,窗口过程是怎么处理消息的呢?稍息一下,让我们进行下一节:处理消息.SDK编程讲座 之 第三讲:Windows消息机制(4)(七)处理消息窗口过程处理消息通常以switch语句开始,对于它要处理的每一条消息ID都跟有一条case语句。大多数windowsproc都有具有下面形式的内部结构:switch(uMsgId)caseWM_(something):/这里此消息的处理过程return0;caseWM_(somethingelse):/这里是此消息的处理过程ruturn0;default:/其他消息由这个默认处理函数来处理returnDefWindowProc(hwnd,uMsgId,wParam,lParam);在处理完消息后,要返回0,这很重要-它会告诉Windows不必再重试了。对于那些在程序中不准备处理的消息,窗口过程会把它们都扔给DefWindowProc进行缺省处理,而且还要返回那个函数的返回值。在消息传递层次中,可以认为DefWindowProc函数是最顶层的函数。这个函数发出WM_SYSCOMMAND消息,由系统执行Windows环境中多数窗口所公用的各种通用操作,例如,画窗口的非用户区,更新窗口的正文标题等等等等。再提示一下,以WM_的消息在Windows头文件中都被定义成了常量,如WM_QUIT=XXXXXXXXXXX,但我们没有必要记住这个数值,也不可能记得住,我们只要知道WM_QUIT就OK了。在第二只小板凳中我们只让窗口过程处理了两个消息:一个是WM_PAINT,另一个是WM_DESTROY,先说说第一个消息-WM_PAINT.关于WM_PAINT:无论何时Windows要求重画当前窗口时,都会发该消息。也可以这样说:无论何时窗口非法,都必须进行重画。哎呀,什么又是非法窗口?什么又是重画啊?你这人有没有完,嗯?稍安勿燥,我比你还烦呢?我午饭到现在还没吃呢!你有点耐心,来点专业精神好不好?我开始在MSDN里面找有关这个方面的内容了,别急,我找找看:PlatformSDK-GraphicsandMultimediaServices-WindowsGDI-PaintingandDrawing-UsingtheWM_PAINTMessage-终于找到了。下面是一大套理论:让我们把Windows的屏幕想像成一个桌面,把一个窗口想像成一张纸。当我们把一张纸放到桌面上时,它会盖住其他的纸,这样被盖住的其他纸上的内容都看不到了。但我们只要把这张纸移开,被盖住的其他纸上的内容就会显示出来了-这是一个很简单的道理,谁都明白。对于我们的屏幕来说,当一个窗口被另一窗口盖住时,被盖住的窗口的某些部分就看不到了,我们要想看到被盖住的窗口的全部面貌,就要把另一个窗口移开,但是当我们移开后,事情却起了变化-很可能这个被盖住的窗口上的信息被擦除了或是丢失了。当窗口中的数据丢失或过期时,窗口就变成非法的了-或者称为无效。于是我们的任务就来了,我们必须考虑怎样在窗口的信息丢失时重画窗口-使窗口恢复成以前的那个样子。这也就

温馨提示

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

评论

0/150

提交评论