VC++讲义第09单元WINDOWS编程

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

第9单元WINDOWS编程-174-第9单元WINDOWS编程教学目标介绍WINDOWS编程的基本思想和MFC程序的基本结构。学习要求理解WINDOWS的基本编程思想,特别是其消息传递机制,弄清MFC程序的组成及各部分的作用。授课内容MicrosoftWindows是广泛应用的台式机计算机操作系统,具有图形用户界面和多任务、多窗口等特点。目前Windows已成为微机上的主流操作系统,几乎一统天下,在Windows平台上进行软件开发也已成为程序设计的主流。9.1WINDOWS编程的基本思想Windows编程使用事件驱动的程序设计思想。在事件驱动的程序结构中,程序的控制流程不再由事件的预定发生顺序来决定,而是由实际运行时各种事件的实际发生来触发,而事件的发生可能是随机的、不确定的,并没有预定的顺序。事件驱动的程序允许用户用各种合理的顺序来安排程序的流程。对于需要用户交互的应用程序来说,事件驱动的程序设计有着传统程序设计方法无法替代的优点。事件驱动是一种面向用户的程序设计方法,在程序设计过程中除了完成所需要的程序功能之外,更多的考虑了用户可能的各种输入(消息),并有针对性地设计相应的处理程序。事件驱动程序设计也是一种“被动”式的程序设计方法,程序开始运行时,处于等待消息状态,然后取得消息并对其作出相应反键盘消息鼠标消息其他消息图9-1事件驱动原理应用程序取消息处理消息Windows消息队列第9单元WINDOWS编程-175-应,处理完毕后又返回处于等待消息的状态。使用事件驱动原理的程序的工作流程如图9-1所示。事件驱动围绕着消息的产生与处理展开,事件驱动是靠消息循环机制来实现的。消息是一种报告有关事件发生的通知。Windows应用程序的消息来源有以下四种:(1)输入消息:包括键盘和鼠标的输入。这一类消息首先放在系统消息队列中,然后由Windows将它们送入应用程序消息队列中,由应用程序来处理消息。(2)控制消息:用来与Windows的控制对象,如列表框、按钮、检查框等进行双向通信。当用户在列表框中改动当前选择或改变了检查框的状态时发出此类消息。这类消息一般不经过应用程序消息队列,而是直接发送到控制对象上去。(3)系统消息:对程序化的事件或系统时钟中断作出反应。一些系统消息,象DDE消息(动态数据交换消息)要通过Windows的系统消息队列,而有的则不通过系统消息队列而直接送入应用程序的消息队列,如创建窗口消息。(4)用户消息:这是程序员自己定义并在应用程序中主动发出的,一般由应用程序的某一部分内部处理。9.2MFC编程Microsoft提供了一个基础类库MFC(MicrosoftFoundationClass),其中包含用来开发C++应用程序和Windows应用程序的一组类。这些类用来表示窗口、对话框、设备上下文、公共GDI对象如画笔、调色板、控制框和其他标准的Windows部件,封装了大部分的WindowsAPI(ApplicationProgrammingInterface:应用程序接口)。使用MFC,可以大大简化Windows编程工作。MFC中的类可分为两种:CObject类的派生类及非CObject派生类。非CObject派生类数量不多,但大都很常用。几个常用的非CObject派生类如CTime,CTimeSpan,CString和CFile已分别在第7单元和第8单元中介绍过。CObject派生类的基本特征为:支持序列化(Serialize,应用见第13单元)、运行时类信息访问(Dynamic,应用见第12单元)、对象诊断输出(参看10.6.4:“CObject::Dump()成员函数”)和与集合类兼容(参看12.7:“集合类”)等。MFC将Windows应用程序从开始运行、消息传递到结束运行所需的各步骤均封装在CWinApp类中,CWinApp类表示MFC应用程序的应用对象。CWinApp类从CObject类的子类CWinThread类(定义MFC内的线程行为)派生。一个MFC应用程序必须有且只能有一个从WinApp类派生的全局应用程序对象,此对象在运行时刻控制应用程序中所有其他对象的活动。典型的Windows应用程序结构有以下四种:(1)控制台应用程序:在本教程第1单元到第8单元介绍的所有程序均为控制台应用程序。控制台应用程序结构简单,可以不使用MFC类库。(2)基于框架窗口的应用程序:某些应用程序仅需最小的用户界面和简单的窗口结构,这时可使用基于框架窗口的方案。在此方案中,主应用程序窗口为框架窗口,第9单元WINDOWS编程-176-CFrameWnd派生类对象附属于应用程序的CWinApp派生类对象的m_pMainWnd成员。第9单元到第11单元的例题程序均为基于框架窗口的程序。(3)基于对话框的应用程序:基于对话框的应用程序与基于框架窗口的应用程序差别不大,只是用CDialog派生类对象代替了CFrameWnd派生类对象作为应用程序的主窗口。基于对话框的应用程序框架可由VisualC++的应用向导自动生成,非常方便。第15单元介绍了基于对话框的应用程序。(4)基于文档/视图结构的应用程序:文档/视图应用具有较复杂的结构,当然其功能也相应增强。基于文档/视图结构的应用程序又可分为单文档界面(SDI,在第12单元介绍)和多文档界面(MDI,在第16单元介绍),后者更复杂些。MFC类的结构大都比较复杂,可能包含数十个至数百个成员函数,加上层次相当多的继承关系,很难把握。MFC程序的结构也因此变得难以详细分析。学习MFC,最重要的一点是要学会抽象地把握问题,不求甚解。不要一开始学习VisualC++就试图了解整个MFC类库,实际上那几乎是不可能的。一般的学习方法是,先大体上对MFC有个了解,知道它的概念、组成等之后,从较简单的类入手,由浅入深,循序渐进、日积月累的学习。一开始使用MFC提供的类时,只需要知道它的一些常用的方法、外部接口,不必要去了解它的细节和内部实现,把它当做一个模块或者说黑盒子来用,这就是一种抽象的学习方法。在学到一定程度时,再深入研究,采用继承的方法对原有的类的行为进行修改和扩充,派生出自己所需的类。在研究MFC的类时,要充分利用MSDN内的帮助信息。学习MFC,很重要的一点是理解MFC应用程序的框架结构,而不是强迫记忆大量的类成员、方法及其参数等细节。[例9-1]吹泡泡程序。每当用户在窗口客户区中按下鼠标左键时即可产生一个泡泡(灰色圆形)。设计思想:显示一个泡泡所需的数据包括其位置和大小,在MFC中可用其包含矩形表示。可设置一数组,每当用户按下鼠标左键时,就产生一个泡泡的数据存入数组中,再由框架窗口类的OnDraw()函数显示所有的泡泡。说明:参考9.8:“用VisualC++集成开发环境开发Win32应用程序”建立该项目。程序://Example9-1:吹泡泡程序#includeafxwin.h//框架窗口类#defineMAX_BUBBLE250classCMyWnd:publicCFrameWnd{CRectm_rectBubble[MAX_BUBBLE];intm_nBubbleCount;public:CMyWnd(){m_nBubbleCount=0;}protected:第9单元WINDOWS编程-177-afx_msgvoidOnLButtonDown(UINTnFlags,CPointpoint);afx_msgvoidOnPaint();DECLARE_MESSAGE_MAP()};//消息映射BEGIN_MESSAGE_MAP(CMyWnd,CFrameWnd)ON_WM_LBUTTONDOWN()ON_WM_PAINT()END_MESSAGE_MAP()//框架窗口类的成员函数voidCMyWnd::OnLButtonDown(UINTnFlags,CPointpoint){if(m_nBubbleCountMAX_BUBBLE){intr=rand()%50+10;CRectrect(point.x-r,point.y-r,point.x+r,point.y+r);m_rectBubble[m_nBubbleCount]=rect;m_nBubbleCount++;InvalidateRect(rect,FALSE);}}voidCMyWnd::OnPaint(){CPaintDCdc(this);dc.SelectStockObject(LTGRAY_BRUSH);for(inti=0;im_nBubbleCount;i++)dc.Ellipse(m_rectBubble[i]);}//应用程序类classCMyApp:publicCWinApp{public:BOOLInitInstance();};//应用程序类的成员函数BOOLCMyApp::InitInstance(){CMyWnd*pFrame=newCMyWnd;第9单元WINDOWS编程-178-pFrame-Create(0,_T(吹泡泡));pFrame-ShowWindow(m_nCmdShow);this-m_pMainWnd=pFrame;returnTRUE;}//全局应用程序对象CMyAppThisApp;输出:每在窗口客户区按一下鼠标左键,可绘出一个灰色泡泡,其大小是随机确定的。吹泡泡程序的运行情况见图9-2。分析:尽管这是一个非常简单的MFC程序,却也有几十行代码。这是因为Window应用程序要管理远比字符界面(如本教程前面所用的控制台界面)复杂的图形用户接口,而且要有多任务并行处理的能力。但是,随着程序规模的增大,用MFC编程的优点很快会显露:由于结构清晰,各部分功能明确,代码规范,编程和调试的工作量大为减少。该程序声明了两个类,一个是由应用程序类CWinApp中派生出来的CMyApp类,一个是从框架窗口CFrameWnd类派生出来的CMyWnd类。MFC的基本类名均以字母C打头,习惯上在为使用MFC编写的应用程序中的类起名时也这么做。除此而外,在程序中还声明了一个CMyApp类的全局对象ThisApp。仔细阅读程序还会发现,该程序似乎不完整,其中既没有主函数(在一般的Windows程序中应为WinMain()函数),也没有实现消息循环的程序段。然而,这是一种误解,因为MFC已经把它们封装起来了。在程序运行时,MFC应用程序首先调用由框架提供的标准的WinMain()函数。在WinMain()函数中,先初始化由CMyApp定义的唯一全局对象ThisApp(通过重载的虚函数InitInstance(),它构造并显示应用程序的主窗口),然后调用其由CWinApp类继承的Run()成员函数,进入消息循环。程序结束时时调用CWinApp的ExitInstance()函数退出。因此,应用程序框架不仅提供了构建应用程序所需要的类(CWinApp,CFrameWnd等),还规定了程序的基本执行结构。所有的应用程序都在这个基本结构的基础上完成不同的功能。MFC采用消息映射机制来决定如何处理特定的消息。这种消息映射机制包括一组宏,用于标识消息处理函数、映射类成员函数和对应的消息等。在类CMyWnd的声明中,前面有afx_msg标记的成员函数就是消息处理成员函数。如果在程序中用到了消息处理函数,那么还需对程序执行部分所定义的消息映射进行初始化,这项工作是通过消息映射宏完成的。消息映射宏就是程序中从BEGIN_MESSAGE_MAP()到END_MESSAGE_MAP()图9-2吹泡泡程序第9单元WINDOWS编程-179-的程序段。BEGIN_MESSAGE_MAP()宏包含两个参数CMyWnd和CFrameWnd,分别是当前定义的窗口类及其父类的名称。在BEGIN_MESSAGE_MAP()和END_MESSAGE_MAP()之间,含有该窗口类要处理的各种Windows消息的入口。MFC包含了大量的预定义消息映射宏,用来指定各种成员函数与各种形如WM_××××的消息相对应,

1 / 21
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功