编程技巧与范例详解_第1页
编程技巧与范例详解_第2页
编程技巧与范例详解_第3页
编程技巧与范例详解_第4页
编程技巧与范例详解_第5页
已阅读5页,还剩355页未读, 继续免费阅读

下载本文档

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

文档简介

1MFC引C++C++MFC(FoundationClass,微软基本类库)的内容和MFC的层次结构,该层次结构封装视图等框架体系以及消息机制。MFCWindows平台建立应用程序时,程序员都有两种选择:C面是由几C函数组成的,这些WindowsAPI参考手册中都有介绍。但显然这口以及消息响应非常麻烦,所以程序员希望有更好地选择。WindowsAPI的基MFC2233每一个低层类都是从类中派生出来的,因此继承了类的行为,例如CWnd类是实现以及鼠标指针的移动等。CSplitterWnd类实现一种可拆分的特殊窗口,它将主窗口拆MFC还为程序的开发提供了其他方便之处。MFCWindows相关的任务,例如在进行消息处理以及路由选择时,无须在所开发的每一个应用程序中编写相同的消息处理循环,MFC可自动实现这一消息循环,并提供易学易用的成员函数,例如除类的层次结构外,MFC也提供一个应用程序的开发模型。此模型称为文档-视图模MFCSDK编程时所有最难做的工作。MFC中包含了成千上万行正确、优化和功能强大的Windows代码。所调用的很多成员函数可以完成用户自己可能很难完成的工作。从这点上讲,MFC极大地加快了程序开发速度。OLE2MFC的基本概 常用的类有CObject、CCmd、CWinThread、CWinApp、CWnd、CFrameWnd MFCCObjectMFC类所通CWinApp类是在建立应用程序时需要用到的,并且在任何程序中都只用一次。CWnd类汇集了Windows中的所有通用特性、框和控制。CFrameWnd类是CWnd中继承的,并实现了标准的框架应用程序。CDialog可分别处理无模式和有模式两种类型的框。CView用于让用户通过窗口来文档。列表框和组合框(一种扩展的列表框。了解了以上内容,可对掌握MFC有很大帮助。C++提供更简单的编程界面,并将WindowsAPI的一些复杂特性隐。C++框架的依赖语言都具有这种扩展性能,但是仅仅依赖语言特征是不够的,框架的MFC应该为Windows操作系统提供一个面象的接口第一个目标的实现可通过编写类来封装窗口、框及其他对象,并引入某些关键的虚函数来完成。第二个目标要求MFC设计尽早地就如何将窗口、菜单及其他对象被MFC(如CWnd和C等)封装进行选择。在Windows中,有关窗口特性和目前状态的信息被保存在操作系统拥有的44些信息对应用程序是隐藏的,应用程序只能处理窗口句柄或HWND。MFC并没有在通过某些类型的句柄展示一个对象,那么相应的MFC类就会包含那个句柄的数据成员。多文档界面(MDI)Internet(TCP/IP)使得调试程序变得非常,所以传统的Windows编程是需要极大的耐心和丰富的编程经一个具体的对象可以有许多的属性和方法,面象技术的重要特点就是对象的封装性,对多的使用、数据库的等方面,这也是微软提供MFC类库最重要的原因,在这个类库MFCMFC的基本概 Windows程序的工作原理、建立应用程序、程序结构剖析、MFC的基本类、其他的用户界面类、绘图类、其他的MFC类等7个方面讲解MFC类的分层结构。Windows应用程序就是由许多这样的子流程构成的。从上面的中可以看出,Windows应用程序在本质上是面象的。程序提供给用户界面的可视对象在程序的一般也是一个对象,用户对可视对象的操作通过事件驱动文件的源代码,并且生成可执行的应用程序。按Ctrl+F5快捷键后,应用程序将开始MFC提供了许多设计好的类来满足广泛的需要。MFC的对象层次类似于结构的的。CObject为那些继承的类提供了3个重要的特性:PAGE17PAGE17串行化是对象的数据流出或流入介质(如磁盘文件)的进程。把CObject作允许在运行时检索对象的类名称及对象的其他信息(RTCIRTTI机制,因为它比RTTI要早出现好多年。嵌入在CObject中的和调试支持允许对CObject派生类CObject派生类创建了一个对象,而没有在应用程序结束前删除它,那么MFC将会在调试输出窗口中写一条警告信息。MFC提供了文档-SDKWindowProc消息处理在应用程序中有一个重要的函数WinMain(),该函数是应用程序的基础,用户操作所产生的消息正是经过该函数的处理派送到对应的对象中进行处理的。在MFC方式的下面就从CWinApp类开始介绍应用程序的框架。类CWinApp是应用程序运行的基础,是由MFC中的类CWnd派生的。在该类中除了newAddDocTemplate函数把这个文档程序用到的框架窗口CMainFrameCMyDocCMyView与应用对象CWinApp类CMainFrame是由MFC中的CFrameWnd派生的,所以它也是一个框架窗口。CMyViewCMyViewCMyDoc类放在一起进行介绍,是因为这两个类是密切相关系的视窗对象来、管理应用程序中的数据,用户与文档之间的交互是通过与文档相关MFCCObject类:CObjectCObject类为每个派CCmd类:从CCmd类派生的类可以接收并处理由应用程序的菜单或者发出令消息。类派生于CCmd类,因此能够接收和处理命令消息。所有其他控件窗口的MFC类都由该类派生。控件条类(ControlBarClass):封装了、框和状态栏等控件一种都将使用一种通用控件窗口类,如当CButton通用控件类创建一个按钮时,将使用BUTTON窗口类来创建实际的窗口,代码如下: 1.1MFCMFCWindowsAnimation动画控msctls上/(续表MFC 通用控 Windows 控 日期/时间获取控 日历控 热键控 msctls 工具提示控 3MFC1.2MFCMFC MFC继承 新增的功

类封装了创建和菜单的WindowsAPI。C 和Detach()。这两个函数允许程序员采用类似于CWnd类对象包含一个已有窗口的方法包CStatusBar和CStatusBarCtrl类用于创建并状态栏CRebar和CRebarCtrl类用于创建并伸缩条WindowsAPI。属性表由一个或CDC类封装了设备环境以及所有需要设备环境的绘图函数。除CDC类以外,还由另外4种从CDC类派生的MFC类提供附加功能。CClientDC类:一般用来方便地创建和销毁一个设备环境。CClientDC通常在堆栈当子程序返回时,CClientDCCDC::ReleaseDC()函数销毁该设备环境。这样将不会存在忘记设备环境的问题,从而也不会导致内存资源CPaintDCCWnd::BeginPaint()函数,这种情况下的设备环境仅允许绘制无效的窗口客户区而不是绘制整个窗口。销毁CPaintDC类时将调用CWnd::EndPaint()函数。CMetaFileDC类:用于创建元文件,元文件是一种磁盘文件,它包含了所有的绘MFC使用类来封装绘图工具,CPen代表画笔,CBrush代表画刷,CFont代表字体,CPalette代表调色板,CBitmaps代表位图,CRegion代表区域。这些类用于创建相关联的CFileCMemFileCMemClass对象同,这使它可以通过剪贴板与DDE共享。CArchiveCArchive类在序列化的过程中使用CFile类将文档的类对象存入磁盘。采用序列ODBC(OpenDatabaseConnectivity)类封装了大多数数据库开发商所支持的ODBCAPIMFCODBCODBCDAO(DataAccessObjects)类支持由Jet数据库引擎所优化的更新数据库API。使用该引擎仍然可以ODBC兼容数据库或者其他数据库。CDatabase类使用ODBCAPIDBMSCDatabase对象以CRecordset类用于通过数据库连接来和接收记录CDaoWorkSpace类用于管理数据库会话,该会话允许执行事务(到数据库)CMap数据对象所组成,它们在内存中相邻,因而可以利用简单的索引来。CArray几种CList类的派生类允许创建安全类型链表。值下一个或者一个以上同样类型的数据对象。可以使用该键值接收数据。例如,因为Windows并不哪个MFCCWnd对象属于哪个窗口,应用程序就可CMapCWnd对象相关联。CMap类有几种派生类(CMapWordToPtr、CObToString等)允许创建保护类型的字典。MFCWindows消息,相反,它通过一些宏来将特定的消息到派生类中相应的成员函数内。库类应用框架没有采用虚函数,这主要140条消息分别定义一个虚否在派生类中被重新定义,vtable都必不可少。这样,对于每个特定类型的窗口或控件,应用都需要一个2.8KB大小的表来支持虚消息的控制函数。窗口类(如文档类和应用类)来控制命令消息。这种消息体制同Borland作为OWL的MFC库消息的控制函数要求提供函数原型、函数体以及在消息中的,而ID,ClassWizard就会自动产生具有正确参数及返回值的代码。MFCWindowsAPIWindows控件,使得程序的开发变得简单,极大地缩短了程序的开发周期。MFC独创的/View框架结构,能够将管理数据的代码和显示数据的程序代码分开,并且设计了一套方便的消息和命令传递机制,方便程序员的开发使用。其中消息机制本身比较庞大和复杂,对它的分析和了解无疑有助于程序员写出更为合理的高效程序。这里将对MFC的消息机制进行分析,从而了解MFC是如何对Windows的消息加以封装的。SDKWindows程序的。Windows程序的运行是依while语句实现消息循环:{MSGmsg;{///////// }return }其中,msgGetMessage函数从于某个线程相对应的消息队列中msgTranslateMessage函数把键盘消息转换并存ClassWizard方便地使用和Windows的各的。一旦消息发生,Framework就可以根据消息表格来进行消息和命令传递。首classclassCScribbleDoc:public DECLAREMESSAGECPPBEGIN_MESSAGE_MAP(CInheritClass,BEGIN_MESSAGE_MAP(CInheritClass,//{{AFX_MSG_MAP(CInheritClass)…//END_MESSAGE_MAP#define#definestaticconstAFX_MSGMAP_ENTRY_messageEntries[];static onstAFX_MSGMAPvirtualconstAFX_MSGMAP*GetMessageMap()structstruct UINTnCode;UINTnID;UINTnLastID;UINTnSig;structstruct constAFX_MSGMAP*constAFX_MSGMAP_ENTRY*AFX_MSGMAP_ENTRY结构中包含了一个消息的所有相关信息,而以上溯到基类的消息表寻找对应的消息响应。为AfxWndProc。原来的窗口过程保存在成员变量m_pfnSuper中。AfxWndProcWindows操作系统发柄的操作转换成对CWnd对象的操AfxCallWndProcCWnd类的方WindowProc进行消息处理。WindowProcOnWndMsg进行正式的消息处理,即把消息派送到相关的方法中去处理。在CWnd类中都保存了一个AFX_MSGMAP的结构,而在AFX_MSGMAP结构中保存所有用于ClassWizard生成的消息的数组,把传统是通过函数AfxFindMessageEntry实现这能的。AFX_MSGMAP_ENTRY结构,然后可以根据消息的动作标识调用相关的执行函数,而这个执行函数实际上就是通过程。用户面对的消息参数将不再是固定的ram和lParam,而是和消息类型具个参数是nFlags和point。MFCSDIMDI(Window窗体的常用事件有:WM_LBUTTONDOWN、WM_KEYDOWN、WM_CHARWM_CREATE、WM_CLOSE、WM_DESTORY、WM_QUIT和WM_PAINT等MDI结构(多文档视图窗体)和Dialog结构(基于框的窗体SDI结构(单文档视图窗体单文档界面是类似于NotePad(记事本)或Paint(画笔)的窗体。它一次Window菜单。与基于框的应用程序相似,单文档应用程序也可以创建成OLE服务器。实际上,这类简单的Web浏览器。但是,单文档界面的应用程序与基于框的应用程序有相同的问题,运用起来太复身的使用规则也减少了用户本身多个数据库的可能性。在正常情况下,需要以可编程MDI结构(多文档视图窗体例如,Word和Excel都是多文档应用程序的示例。文本编辑器具备有限简单的Web浏览器。WordOLE服务器,在另一户和服务器。通过让服务器接管客户端窗口的方法,已经降低了这类内存需求,Dialog结构(基于框的窗体一般情况下,人们只会把配置屏幕参数、About框之类的应用与基于框的应用程序联系起来。实际上,基于框的应用程序在编程世界中也占有重要的地位。它们基于框的应用程序比基于窗口的全功能应用程序更好,最重要的原因之一是程序规模。创建同一个应用程序时有两种版本,一种使用框界面,另一种使用窗口界面。每次做这样的实验时都会发现框版本的程序更小一些。除了节省资源外,框版本的应用程序的加载速度也更快些。基于框的应用程序比完成相同功能的基于窗口的应基于框的应用程序并不一定要承受缺乏重要特性的遗憾,如程序员可以把基于对因此,在应用程序中添加OLE支持只需要多做一点工作即可。MFCAppWizardMFC的单文档界面(SDI)应用程序,启动VisualStudio6.0,选择File|New命令,在弹出的New框中打输入工程的名称test,如图1.1所示。图1.1New单击OK按钮,弹出MFCAppWizard-Step1框,选中Single 钮,如图1.2所示。图1.2MFCAppWizard-Step1MFCMFC的基本概 中s中s 图1.3MFCAppWizard-Step2of604单击Next按钮,弹出MFCAppWizard-Step3of6框,如图1.4所示。在这一OLEOLE选项的复合文档类型。因为本例中不需要使用OLE特征,所以选择默认值None即可。图1.4MFCAppWizard-Step3of6图1.5MFCAppWizard-Step4of6图 TemplateStrings选项1.7所示。Usesplitwindow复选框用来设置是否使用拆Close按钮关闭AdvancedOptions框即可,返回到如图1.5所示的框中。1.7WindowStyles1.5NextMFCAppWizard-Step5of6对1.8所示。Whatstyleofprojectwouldyoulike选项组用于设置工程的生成方式;Wouldyouliketogeneratesourcefilecomments选项组用于设置是否为生成的源代码添加必要的注释说明;HowwouldyouliketousetheMFClibrary选MFCAsasharedDLLMFC的类均存放须提供必要的动态库;选中Asastaticallylinkedlibrary单选按钮时(静态库方图1.8MFCAppWizard-Step5of6(Cestiew(CestApp(CestDoc话框下面的几个编辑框可以修改默认的类名、类的头文件名文件名。对于视图类,可以修改其基类名称,默认的基类是CView,其他可选的基类有CTreeView。这里使用默认设置。图1.9MFCAppWizard-Step6of6单击Finish按钮,弹出NewProjectInformation框,如图1.10所示。在该对Cancel按钮返回到上一步,这里单击OK按钮即可生成一个新工程。图1.10NewProjectInformation题将显示为打开的项目名TestMFC。1.11在利用AppWizard创建的工程中包含了框架程序所有的类、全局变量的和定义。WindowsAppWizard工具自动创建的工作,可以发现该下会生成十几个文件和两个,其中Res用于存放工程的资源文件。Debug用VisualC++中,一个工程文件可以产生两种不同版本的可执行程序:Debug版本和根据选项设置的不同,AppWizardAppWizard文总MFC200MSDNMFCWindows应用程序开发的程序员来说,MSDN是必不可少的参考资料。2 引MFC程序向导创建一个程序框架并包含了文档类和视图类。MFC把数据管理的任务交给了两个类:文档类负责数据、管理并更新数据的视图;视图类负责显示数类C(或COle表2.1C类的主要方函 描 POSITIONGetNextView函数以遍历和文档关联的 CView OnUpdate文档和视 表2.2C类的主要可覆盖函函 描 CView最常用的函数是Get,这个函数用于返回与此视图关联的文档。同时CView具有窗口类的功能,可以方便的定义消息处理函数,MFC定义了一个非常好的、在“文档-视图-框架”之间的消息传递机制。CView类的主要可覆盖函数如表2.3所示。2.3CView函 描 CFrameWndSDI程序只使用一个框架窗口—CFrameWnd类作为程序的顶层窗口提供视图的框架。一个MDI程序使用两种不同类型的框架窗口—CMDIFrameWnd作为顶层窗口,CMDIChildWnd作为浮动窗口,为程序文档提供框架。为了管理创建文档、视图和框架窗口的复杂过程,MFC框架使用两种文档模板类:文档)程序提供支持。一个CSingleDocTemplate类可以一次创建和一个类型的文档。文档对象由程序对象创建并,在程序的InitInstance方法中完成的一个关键任务是创建一个或多个适当类型的文档模板,程序对象为模板列表中的每个文档模板一个指针,提供一个接口用来添加文档模板。如果需要支持两个或的文档类型,就应该为每种文档类型添加一个AddDocTemplate的调用。过程。表2.4总结了对象之间的创建关系。2.4创建 被创建的对程序对 文档模文档模 文文档模 框架窗框架窗 视文档-MFCSplitter与SDI程序一样,MDI文档-视图程序基于C 类在文档对象中数据,基于CView和它的继承类显示数据的多种视图。MDI程序和SDI程序的主要不同如下:MDI程序从CMDIFrameWnd类继承顶层框架窗口,而不是CFrameWnd类MDI程序使用基于CMDIChildWndMDICMultiDocTemplateCSingleDocTemplate来创建文档模板。在CMultiDocTemplate类中的框架窗口是子框架窗口类而不是顶层框架窗口。MFCSDIMDI程序的“文档-视图-框架”之间的关系在函数生成的InitInstance函数。BOOLBOOL{//OLE#ifdef_AFXDLL文档和视文档和视 //程序用 配置信息 表SetRegistryKey(T("LocalAppWizard-Generated//加载标准的INI文件选项(MRU) CSingleDocTemplate*pDocTemplate;pDocTemplate=newCSingleDocTemplate( // //文档 //主要的SDI框架窗口 //视图// //解析命令行完成如标准 命令、DDE、文件打开操CCommandLineInfo//处理命令行 if( returnFALSE;return}BOOLBOOL{//OLE#ifdef_AFXDLL//3DMFC//3D//程序用 配置信息 表SetRegistryKey(_T("LocalAppWizard-Generated//加载标准的INI文件选项(MRU)//CMultiDocTemplate*pDocTemplate;pDocTemplate=newCMultiDocTemplate(MDIMDIMDIMDI// //创建MDICMainFrame*pMainFrame=new//returnFALSE;m_pMainWnd=//解析命令行完成如标准 命令、DDE、文件打开操CCommandLineInfo//处理命令行 if( returnFALSE;mpMainWnd->UpdateWindow();return}面。程序演示了简单的MDI程序的编写过程。问★★MFC程序提供了对MDI程序的良好支持,MDI程序的主框架窗口继承自自C,并利用Serialize方法实现了对文档的保存,程序的视图类选择的是2.1MFC编译项目并运行程序,效果如图2.2所示。图 总本实例将实现一个MDI程序,它可以管理多个文档和多个视图,每个文档对应一问现两个独立的文档模板——一个简单的oWorld文档模板和一个比较复杂的跳动的弹(程序主框架类CoFrame(子框架窗口类CoDoc(文档类C(视图类ea加资源项NewBounce、Newo。为CMDIApp::InitInstance()函数添加如下代BOOLBOOL{//添加自动生成的 o文档模板CMultiDocTemplate*pDocTemplate;pDocTemplate=newCMultiDocTemplate( ////customMDIchild//添加新的Bounce文档模板CMultiDocTemplate*pBounceTemplate;pBounceTemplate=new////RUNTIMECLASS(CBounceFrame),//customMDIchildframeRUNTIMECLASS(CBounceView)); //…return}为CMDIApp类中菜单消息的处理函数 voidvoid{//打 o文//POSITIONcurTemplatePos=Get while(curTemplatePos!=NULL){//CDocTemplate*curTemplateGetNextDocTemplate(curTemplatePos);CStringstr; //curTemplate->GetDocString(str,C if(str==_T(" {curTemplate-//}}}void{//得到程序的第一个文档模板位置POSITIONcurTemplatePos=Getwhile(curTemplatePos!=NULL){////打开BounceCDocTemplate*curTemplateGetNextDocTemplate(curTemplatePos);CString //curTemplate->GetDocString(str,C if(str==_T("Bounce")){curTemplate-curTemplate-//}}}在C 在CoView类中添加消息处理,然后定义如下消息处理函数:voidvoid oDoc*pDoc=ASSERTif(dlgColor.DoModal()==IDOK){pDoc->mclrText=dlgColor.GetColor();pDoc->mbCustom=TRUE;}}void{CoDoc*pDoc=//UINTmm_nIDColorIDmnIDColor=LOWORD(GetCurrentMessage()-> {casepDoc-caseIDpDoc-…//////////} //混合}重写视图类的虚函数OnDraw()MFC通过WM_PAINT消息的处理函数OnPaint() ovoid{CoView::OnDraw(CDC*oDoc*pDoc=CRectCStringtmpStr=pDoc->m_str;pDC-//////pDC->SetBkColor(::GetSysColor(COLOR_WINDOW));//背景颜色为窗体颜//pDC->DrawText(tmpStr,-1,rect,DT_SINGLELINE|DT_CENTER|}图 总MFC程序不仅可以支持一个文档模板,还可以一个文档模板链表,默认的MFC问CWinApp类的AddDocTemplate方法,其中每个文档模板的文档类必须相同,而视图类和m_strData表示要显示的文本,m_colorData表示要显示的文本颜色在ClassView中添加一个文本视图类CTextView,基类为CViewCTextView::OnDraw()方法,源代码voidCTextView::OnDraw(CDC*{CMainDoc*pDoc=Get CRectrect;

//////pDC-pDC- //pDC->TextOut(rect.Width(2,rect.Height() }CColorView::OnDraw()方法,源代码如下voidvoidCColorView::OnDraw(CDC*{CMainDoc*pDoc=Get CRectrect;pDC->FillRect(rect,&br);////////} 框资源,添加类CInputiew基类为CFormView。继承CMDIChildWndCSplitterFrameOnCreateClient函数(框BOOLBOOLCSplitterFrame::OnCreateClient(LPCREATESTRUCT,CCreateContext*{//1行、2if(!mwndSplitter.CreateStatic(this,1,{TRACE0("FailedtoCreateStaticSplitter\n");returnFALSE;}//1if(!mwndSplitter.CreateView(0,0,pContext->mpNewViewClass,{TRACE0("Failedtocreate returnFALSE;}//2个视图,CInputViewif(!mwndSplitter.CreateView(0,1,RUNTIMECLASS(CInputView),CSize(0,0),pContext)){TRACE0("Failedtocreatesecondpane\n");returnFALSE;}//激活输入视图CInputViewreturnreturn}BOOLBOOLC3WaySplitterFrame::OnCreateClient(LPCREATESTRUCTlpcs,CCreateContext*pContext){//1行、2if(!mwndSplitter.CreateStatic(this,1,{TRACE0("FailedtoCreateStaticSplitter\n");returnFALSE;}//1if(!mwndSplitter.CreateView(0,pContext->mpNewViewClass,CSize(200,50),{TRACE0("Failedtocreate returnFALSE;}//22if(!m //12, //2行、1WS_CHILD|WS_VISIBLE|WS_BORDER,//mwndSplitter.IdFromRowCol(0,//12列{TRACE0("Failedtocreatenestedsplitter\n");returnFALSE;}intcyTextmax(lpcs->cy70, ////1if(!mwndSplitter2.CreateView(0,0,RUNTIME_CLASS(CTextView),CSize(0,cyText),pContext)){TRACE0("Failedtocreatesecondpane\n");returnFALSE;}//2if(!m_wndSplitter2.CreateView(1,RUNTIMECLASS(CColorView),CSize(0,0),{TRACE0("Failedtocreatethirdpane\n");returnFALSE;}}return}BOOLBOOL{//AddDocTemplate(newCMultiDocTemplate(IDRTEXTTYPE,RUNTIMECLASS(CMainDoc), //文本//AddDocTemplate(newCMultiDocTemplate(IDRCOLORTYPE,RUNTIMECLASS(CMainDoc),RUNTIME //颜色//AddDocTemplate(newCMultiDocTemplate(IDRINPUTTYPE,RUNTIMECLASS(CMainDoc),RUNTIME //输入//AddDocTemplate(newCMultiDocTemplate(IDRSPLIT2TYPE,RUNTIMECLASS(CMainDoc), 可分割窗RUNTIME//RUNTIMECLASS(CMainDoc),RUNTIME_CLASS(C3WaySplitterFrame),//可分割窗RUNTIME//CMDIFrameWnd*pMainFrame=newCMDIFrameWnd;if(!pMainFrame->LoadFrame(IDR_MAINFRAME))returnpMainFrame->ShowWindow(mnCmdShow);m_pMainWnd //设置程序的主框架窗return}总

图 单文档、多视图程序的运行效间的关系,同时可以方便的使用MFC类库中丰富的视图类。问文档和视文档和视 ClassView中添加视图类CMyView,基类为CViewOnDraw()方法void//初始化OpenGL mpDC=newvoid//初始化OpenGL mpDC=newCClientDC(this);mhRC=wglCreateContext(mpDC-wglMakeCurrent(mpDC->GetSafeHdc(),mglClearColor(0.0f,0.0f,0.0f,0.0f);GLfloatcolor[4]={1.0f,1.0f,1.0f,1.0f};GLfloatlightPos[4]={3.0f,3.0f,3.0f,1.0f};//////////OpenGL。OpenGL3D程序接口,是一个3D图形库。OpenGLSGI公司为其图形IRISGL。IRISGL3D图形接口,功能虽OpenGLOpenGraphicsLibrary,即开放的图形程序接口。虽然DirectX在家用市场全面领先,但在专业高端绘图领域,OpenGL是不能被取OpenGL是与硬件无关的接口,可以在不同的平Windows2000、WindowsXP、Unix、Linux、MacOS、OS2OpenGL的具有很好的移植性,可以获得非常广泛的应用。(接上页(接上页void ype,intcx,int CMyView::OnSize(nType,cx,wglMakeCurrent(mpDC->GetSafeHdc(),mglViewport(0,0,cx,cy); (45.0,(double)cx/(double)cy,0.1,1000.0); gluLookAt(0.0,0.0,3.0,0.0,0.0,0.0,0.0,1.0,}glLightfv(GL_LIGHT0,GL_SPECULAR,color); glLightfv(GL_LIGHT0,GL_POSITION,lightPos);//设置光的位置for(inti=0;i<3;i++) m_rotation[i]=(((double)rand()/(double)RAND_MAX)*2.0)-}SetTimer(m_idView,10, }//选 void {CMyView*pViewSelected=POSITIONpos=//隐藏所有 选while(pos!={

//CMyView*pView=(CMyView*)pView- //隐藏视if(pView->m_idViewnTab)pViewSelectedpView;//}文档和视文档和视 if(pViewSelected!=pViewSelected-}//{intidNewView=m_listViews.GetCount();CRectclientRect;clientRect.DeflateRect(10,30);CMyView*mpNewView;{casem_pNewView=new////2DtabCaption.Format("View%d(2D)",idNewView);case //OpenGLm_pNewView=newCOpenGLView(); 创建视图tabCaption.Format("View%d(OpenGL)",idNewView);}//为新创建的视图添加新的m_tabCtrl.InsertItem(idNewView,tabCaption);m_pNewView->m_idView=idNewView;//创建视图窗口,父窗口为选中 clientRect,&m_tabCtrl,ID_VIEW_BASE+idNewView)){TRACE("Failedviewcreation\n"}////选择新创建 和视//}总

2.5问ShowWindow(SW_HIDE)SetWindowLong()函数将主在类CMainFrame中添加如下成员函数和voidFullScreenModeOn();void////boolm_bFullScreenMode;boolm_bToolBarWasVisible;CRectm_mainRect;CToolBar*//bool

////////////void //CMDIChildWnd*pChild=//m_bToolBarWasVisible=(m_wndToolBar.IsWindowVisible()!=0);mwndToolBar.ShowWindow(SWHIDE);m_bStatusBarWasVisible=(m_wndStatusBar.IsWindowVisible()!=0);mwndStatusBar.ShowWindow(SWHIDE);//m_pwndFullScreenBar=newCToolBar;//m_pwndFullScreenBar-//m_pwndFullScreenBar->SetBarStyle(m_pwndFullScreenBar->GetBarStyle()|CBRSTOOLTIPS|CBRSFLYBY|CBRSSIZEDYNAMIC);mpwndFullScreenBar->EnableDocking(0);//将工具条放在某个位置CPointpt(300,200);////style&=~WSCAPTION;//intscreenx=GetSystemMetrics(SM_CXSCREEN);intscreeny=GetSystemMetrics(SM//SetWindowPos(NULL,-4,-4,screenx+8,screeny+8,SWPNOZORDER);if(pChild){//m_bChildMax=(style& IZE)?true////注意:当原来主窗口就是全屏幕显示(最大化)//pChild- }//m_bFullScreenMode=true;//}同时该函数还在给定窗口的附加窗口内存中的指定偏移量处设置一个32位 LONGSetWindowLong(HWNDhWnd,intnIndex,LONG 12个或个字节,值83个dwNewLongGetWindowLong函数用于获得有关指定窗口的信息以及在额外窗口内存中指定偏移位地址的32位(长)值。函数原型如下: LONGGetWindowLong(HWNDhWnd,int SetWindowLong相同,这里不再赘述。该函数返回值成功时,返回一个请求的32位的值,失败时,则返回0。函数GetSystemMetrics()用来获取当前系统的一些参数。函数原型 intGetSystemMetrics(int SetWindowLong相同,这里不再赘述,该函数返回值成功时,返回一个请求的32位的值,失败时,则返回0。函数GetSystemMetrics()用来获取当前系统的一些参数。函数原型 intGetSystemMetrics(int nIndex表示要获取系统的哪50余种选择2.5只列出一些(接上页2.5取 描

Windows窗口边框的宽度和高度函数FullScreenModeOff()用来关闭、打开全屏幕模式,源代码如voidvoid{//delete//style|=WS_CAPTION;//mwndToolBar.ShowWindow(SWSHOW);mwndStatusBar.ShowWindow(SW//MoveWindow(&m////CMDIChildWnd*pChild=//pchildNULL{ }//mbFullScreenMode=}ID_VIEW_FULL_SCREEN,添加该菜voidvoid{}////总

图2.63框 引实际上框(Dialog)也是一个窗口,分为有模式框和无模式框两种。大部分用户都会有这样的经历,当通过选择File|Open命令打开一个文件框后,再用鼠标去选择菜单将会发出嘟嘟声,这是因为文件框是一个有模式框。有模式框了用户的输入,当一个有模式框打开时,用户只能与该框进行交互,而其他用户界面对象收不到输入信息。平时所遇到的大部分框都是有模式框。无模式对话框则不然,该框并不用户的输入。无模式框的典型应用是Windows提供的在MFC中将有模式和无模式框的功能都封装在CDialog类中。CDialog类使在利用MFC编写框程序时非常容易。CDialog类是CWnd类的派生类,类中定义了两个构造函数:一个构造函数的参数是字符串的框模板资源ID和拥有该框的窗口的CWnd指针;另一个构造函数的参数是整型的框模板资源ID和拥有该框的窗口的可以利用函数GetParent()来获得拥有者的窗口指针。 始化,为使用框进行准备工作。该函数的原型为:virtualvoidOnInitDialog();而且CDialogCDialog的派生类中将根据需要决定是否重写该CDialogOnOK()OnCancel(),这两个函数用于响应单击OK按钮(IDIDOK)Cancel按钮(IDIDCANCEL)的消息,这些消息也不用添加到消息表里。两个函数都用于关闭框并返回框拥有者的窗口,但返回结果不同。OnOK()函数返回IDOK,并把框输入的数据结果提供给框的拥有者,而OnCancel()函数返回IDCANCEL,但并不把框输入的数据结果提供给框的框的和数据校函数中创建DDX(一组“DDX_”打头的函数)和DDV(一组“DDV_”打头的函数在CDialogOnInitDialog()FALSE的UpdateData()函利用成员变量的值初始化控件,所以当重写虚函数OnInitDialog()时,需要调用函数将控件中的值到成员变量,而DDV函数会检验控件的输入是否合法,所以当重写虚函数OnOK()时也需要调用CDialog::OnOK()或者显式调用UpdateData(TRUE)。DDXDDVVisualC++ClassWizard就可以完成所有的工所有进行关联的框控件的ID列表,双击一个ID会弹出一个添加与控件ID关联的成在umCharacters文本框中输入检验条件,如图3.3所示。3.1ID3.2ID

图 此一般需要从CDialog类派生一个新类,以完成特定的功能。调用CDialog::DoModal()显示框。调用CDialog::Create()显示框。才返回,而Create()是立刻返回并窗口保持显示。利用DestroyWindow()清除无模式框,而利用EndDialog()清除有模式框以要自己调用delete来清除框。若要确保清除无模式框,一般是在MFC中还提供了一些公用框:CColorDialog、CFileDialog、CFontDialog、CPrintDialog、CPageSetupDialog等。CColorDialog用来选择颜色值;CFileDialog用来选择要打开或保存文件的名称;CFontDialog用来选择字体;CPrintDialog用来进行打印和打印的设置;CPageSetupDialog用来进行打印页面的设置。问★★在派生的框类中创建一个提示信息控件(CoolipDlgGetWindow()函数获得框里所有控件的窗口指针LoadString()函数获得提示信息字符串,然后把对应的窗口指针和提示信息添加到CToolTipDlg控件中。在消息的预处理函数PreTranslateMessage()中调用CToolTipDlg::RelayEvent()函数,用于将鼠标的消息发送给CToolTipDlg控件,由CToolTipDlg控件处理是否显示相应的提示信息。择框模式,而后使用默认值来创建,最后获得一个框的应用程序,在对ClassView中添加新的类CToolTipDlg的类型为MFCClass,基类CDialog。得到两个新文件ToolTipDlg.cpp和ToolTipDlg.h。改为CToolTipDlg(UINTuID,CWnd*pParent=NULL)BOOLBOOL{//创建提示信息控件 //获 CWnd*pWndChild=GetWindow(GWCHILD);CStringstrToolTip;//while{intnID=pWndChild-//IDif{{//将控件对应的提示信 到提示信息控件m_wndToolTip.AddTool(pWndChild,}//获 }return} HWNDGetWindow(HWNDhWnd,UNIT hWndnCmd参数值相对于这以是表3.1中的任一个。3.1取 描 如果指定窗口是父窗口,则获得的是在z序顶端的子窗口的句柄,否则为NULL。函数仅检查指定父窗口的子窗口, 返回的句柄标识了在z序最高端的相同类型的窗口 返回的句柄标识了在z序最 返回的句柄标识了在z序中指定窗口下的相同类型的窗口GWHWNDPREV 返回的句柄标识了在z序中指定窗口上的相同类型的窗口GWOWNER 存在,则返回值为NULL。将前面添加框的对应类CDlgExampleDlg从CToolTipDlg中继承,在BOOLCToolTipDlg::PreTranslateMessage(MSG*{ WM_MOUSELASTif(pMsg->message>=WM &&pMsg-<=WM{MSG// //判断父窗口句柄是否 框句// //保证消息结构中窗口句柄 框的控件句while(hWndParent&&hWndParent{} //若 框控件的消息,将鼠标消息发送给CToolTipCtrl控//if(msg{m}}return}总

3.4法也可实现此功能,有的读者可以参考MSDN或者其他资料。在默认情况下,一般只有单文档或多文档窗口才有菜单、工具条和状态条,而框问C、CToolBar、CStatusBarCreate()函数动态创建菜单、工具条和状态条,这时在得到两个新文件DialogEx.cpp和DialogEx.h。类代码也放在文件DialogEx.cpp和DialogEx.h中。在ClassView中添加新的类CStatusBarEx,类的类型为MFCClass,基类为CStatusBar。类代码也放在文件DialogEx.cpp和DialogEx.h中。在CToolBarEx类中利用ClassWizard添加消息处理WM_IDLEUPDATECMDUI,WM_IDLEUPDATECMDUI消息的处理函数用于保持 MAND_UI是一个消息宏,它将在CToolBarEx类中添加以下代码到消息处理函数OnIdleUpdateCmdUI()中:LRESULTLRESULT{ram, ifif{if{CFrameWnd*pParent=(CFrameWndifOnUpdateCmdUI(pParent, //}}if{ //获 POSITION MapIDintid;//while(pos{ //获 mButtonStates.GetNextAssoc(pos,id,val);//ID}}return}CStatusBarExOnIdleUpdateCmdUI(),代码和上面的CToolBarEx类相似。 在CDialogEx类中利用ClassWizard添加消息WM_INIT POPUP、 消息TTN_NEEDTEXTW、TTN_NEEDTEXTA以及WM_KICKIDLE。在CDialogEx类中添加成员函数,即GetStatusBar()、GetToolBar()、Get BOOLBOOLCDialogEx::InitDialog(UINTID,BOOLbToolTips,BOOLUINT*pIndicators,UINTnIndicators,UINTuiToolBar,DWORD{if( ID>0{ =new - (m }if{//m}if{if{//if(!m_StatusBar.Create(this)||!m_StatusBar.SetIndicators(pIndicators,nIndicators)){return//}}{if(!mStatusBar.Create(this)||!m{return//}}OnSetMessageString(AFXIDSmStatusBar.SetPaneInfo(0,mStatusBar.GetItemID(0),SBPSSTRETCH,NULL);}if{if(m{if(m_bToolTips) ////}{return//}} //重新安 框控件的位if{CRect//m_ToolBar.GetWindowRect() RepositionBars(AFXIDWCONTROLBAR AFX_IDW_CONTROLBAR_LAST,0,reposQuery,rcClientNow); //CPointptOffset(rcClientNow.left- -rcClientStart.top+ CRectCWnd*//while{pwndChild-//获得控件原来的位置大小//CRectpwndChild->MoveWindow(rcChild,//pwndChild=pwndChild-//}//修改 CRectrcWindow;rcWindowright+=rcClientStart.Width()-rcClientNow.Width();rcWindow.bottom+=rcClientStart.Height()-rcClientNow.Height()+ MoveWindow(rcWindow,FALSE);m_StatusBar.GetWindowRect()////SetTimer(0x3333,10,}if(!m{//无模 框定义一个定时器,定时处理空闲状m_Timer=SetTimer(TIMER_ID,100,}return//}为CDialogEx类的消息处理函数添加相关代码。当有模式框或菜单进入空闲voidvoidCDialogEx::OnEnterIdle(UINTnWhy,CWnd*{//给状态条和工具条发送WM_IDLEUPDATECMDUI消if(AfxGetApp()->m_pMainWnd{if(m_bStatusBar)if}//若不是菜单发送的消息 的菜单或工具条ID没有变化则返if(nWhy!=MSGF_ //ID}WM_KICKIDLEOnIdle(),用于保证在有模式框的消LRESULTLRESULT RAM,LPARAM{//给状态条和工具条发送WM_IDLEUPDATECMDUI消if(m_bStatusBar)if(mmToolBar.SendMessage(WMIDLEUPDATECMDUI,TRUE);return(lCount<=2);}当一个下拉菜单或子菜单将要被激活时发送消息WM_InitPopup,它的处理函数用于菜单项的状态更新,在该处理函数中使用到的类CCmdUI是被应用在一个CCmd派生类中的 MAND_UI处理程序内,而类CCmd是MFC类库中消息体系的一个基类。消息把命令或消息引CWnd和CFrameWnd。如果想生成一个处理按键消息的类,可以选择其中的一个 void * ,UINTnIndex,BOOL { ,nIndex, //只处理自己添加 框的菜 if {CCmdUICCmdUI state // state - for(statem_nIndex=0;statem_nIndex<statem_nIndexMax;state{ if(state.m_nID==0)( //{ if(state - //}{}}}}

state.DoUpdate(this,FALSE);//更新状//函数发 MAND_UI消//从而利 MAND_UI处理机制更新菜单项状 state.DoUpdate(this,state.m_nID< //voidvoid Select(UINTnItemID,UINTnFlags,{) //if{ASSERT(mnIDTracking==mnIDLastMessage);}//elseif{}//IDafxpriv.hif(nItemID>=0xF000&&nItemID<{mnIDTracking=IDCOMMANDFROM}ID{}}的定义TTN_GETDISPINFO消息,{//提示信息需要ASCII字符(Windows95)//提示信息需要宽字符(WindowsCStringstrTipText;CStringstrPromtpText;TTF_IDISHWND表示pNMHDR->idFrom为工具条的HWNDif(pNMHDR->code==TTN_NEEDTEXTA&&pNMHDR->code==TTNNEEDTEXTW&&{//获得工具条上按钮的ID}//不是分隔符,ID=0if(nID{//AfxExtractSubString(strTipText,szFullText,1,AfxExtractSubString(strPromtpText,szFullText,0,//if{if(::IsWindow(m_StatusBar.m_hWnd))}} //将提示信 到TOOLTIPTEXT结构的提示信息#ifndef//if(pNMHDR-lstrcpyn(pTTTA->szText,strTipText,(sizeof(pTTTA-/sizeof(pTTTA- // ASCII_mbstowcsz(pTTTW->szText,strTipText, 宽字符串到ASCIIif(pNMHDR-_wcstombsz(pTTTA-strTipText,(sizeof(pTTTA->szText)/sizeof(pTTTA-typedeftypedef{//LPSTRchar////UINT//hdridFrom#if(_WIN32_IE>=LPARAM//}NMTTDISPINFOA,FAR*LPNMTTDISPINFOA;//ASCIItypedef{NMHDRhdr;LPWSTRlpszText;HINSTANCEhinst;UINTuFlags;#if(_WIN32_IE>=//Unicode UnicodeTOOLTIPTEXTA、TOOLTIPTEXTW是数据lstrcpyn(pTTTW->szText,(sizeof(pTTTW->szText)/sizeof(pTTTW-//::SetWindowPos(pNMHDR->hwndFrom,HWND_TOP,0,0,0,0,return} 件件(接上页(接上页idFrom:发送消息的控件标识符(ID) 码之一,如表3.2所示。3.2 和IDR_TOOLBAR是预 ,typedefstruct{UINTidFrom;UINTcode;}总

图 带有菜单、工具条和状态条的图也添加到框中,有的读者可以去参考一些相关资料。源时,可在框属性设置中选择要添加的菜单资源ID,如图3.6所示。添加到框的菜单资源图3.6添加菜单资源到带预览的文件经常会利用框来打开各种格式的图像文件,但有时用户在选择要打开的图像文件望能预览图像。MFCCFileDialog类不具备这种特殊功能,所以本实例将通过扩展CFileDialog来实现这能。问 择框模式,而后使用默认值来创建,最后得到一个框的应用程序。在ClassView中添加新的类CDIBStatic,类的类型为MFCClass,基类为CStatic。获得两个新文件DIBStatip和DIBStatic.h。ClassViewCPreviewFileDlgMFCClass,基类为CFileDlg。获得两个新文件PreviewFileDlg.cpp和PreviewFileDlg.h。CDIBStaticCPictureObj*m_pPicObj,该成员变量用于和显示图像文件。CPictureObjCPictureHolderCPictureHolder类中MSDNBOOLIsValidDib()const//BOOLLoadDib(LPCTSTR//voidRemoveDib()//voidSetPreview(BOOLbPreview)//void//voidPaintDib(BOOL//{{//CFilefile(lpszFileName,CFile://m_pPicObj=newif(!mpPicObj-{//deletempPicObj;//return}returnTRUE;}catch(CFileException*{ returnFALSE;}}函数voidvoidCDIBStatic::PaintDib(BOOL{//CRect//获得显示区域CClientDCdc(this);if(bDibValid&&m//{CSizesize=m_pPicObj-intnDestX,nDestY,nDestWidth,if((DWORD)size.cx<(DWORD)PaintRect.Width()&&(DWORD)size.cy<(DWORD)PaintRect.Height()){//nDestX=PaintRect.left+(PaintRect.Width()-size.cx)/2;nDestY=PaintRect.top+(PaintRect.Height()-}{//if((PaintRect.Width()/(float)size.cx){//宽度限制nDestHeight=(nDestWidth*size.cysize.cx;nDestY=PaintRect.top+(PaintRect.Height()-nDestHeight)}{//高度限制nDestWidth=(nDestHeight*size.cx)size.cy;nDestX=PaintRect.left+(PaintRect.Width()-nDestWidth)/2;}}//CRectRectDest(nDestX,nDestY,nDestX+nDestWidth,//m_pPicObj-CBrush*pOldBrush=(CBrush*)dc.SelectStockObject(NULL_BRUSH);if(NULL!=pOldBrush){dc.SelectObject(pOldBrush);}{CStringstrText="不能识别的文件格式if(m_lpszFileName==NULL||strlen(m_lpszFileName)=0dc.DrawText(strText,strText.GetLength(),&PaintRect,}}CPreviewFileDlg::CPreviewFileDlg(BOOLbOpenFileDialog,LPCTSTRlpszDefExt,LPCTSTRCPreviewFileDlg::CPreviewFileDlg(BOOLbOpenFileDialog,LPCTSTRlpszDefExt,LPCTSTRlpszFileName,DWORDdwFlags,LPCTSTRlpszFilter,CWnd*pParentWnd):CFileDialog(bOpenFileDialog,lpszDefExt,lpszFileName,dwFlags,lpszFilter,{//添加 框的资源模板,该模板上有一静//CDIBStaticmofn.Flags|=(OFNEXPLORER|OFN//intDWORDdwVersion,dwWindowsMajorVersion,dwWindwosMinorVersion;dwWindowsMajorVersion=(DWORD)(LOBYOWORD(dwVersion)));dwWindwosMinorVersion=(DWORD)(HIBYOWORD(dwVersion)));if(dwVersion<0x80000000){Windows2000XP}{//Windows98}//根据操作系统的版本信息决 框风//}CPreviewFileDlgOnInitDialog()、OnFileNameChange()、定CDIBStatic对象用来显示图像,源代码如下:BOOLBOOL{//绑定CDIBStatic对象到静态对象CWnd*pParent=GetParent();CRectpParent-IDC_PREVIEW是一多选控件//CRectCRectCRectrc;mCDIBStatic对象新的位置大小rc.top=rcPrev.bottom+10;rc.bottom=rc.top+rc.Height();rcright=rcParent.Width()-rc.left-CDIBStatic对象的位置和大小m_DIBStaticCtrl.MoveWindow(&rc,true);mDIBStaticCtrl.SetPreview(mbPreview);(BM_SETCHECK,(m_bPreview)?1:0);//return} 的文件名称传给CDIBStatic对象,并显示文件对应的图像,源代码如下:voidvoid{if(m_bPreview){//m}}OnFolderChange()函数在文 voidvoid{//} 建),在框中选择图像文件,效果如图3.7所示。总

图 带预览的文件本实例实现了对文件框的扩展,此方法也可应用在其他公用框的扩展上。在其他的公用框里也存在类似于OPENFILENAME的结构,并在结构内均存在lptemplateName变量,如CFontDialog的CHOOSEFONT结构、CColorDialog的CHOOSECOLOR结构等。当然扩展后要实现的功能不同。问对象。MCI(MediaControlInterface)控制接口是 等多设备,如MCIWndOpen()用于打开多文件、MCIWndPlay()用于多 本实例将利用多控件实现音频文件的。需要注意的是使用MCI接口时必须在工程里添加Vfw32.lib,这个库是于1992年推出的数字包中的一个组成部分,它不依赖于的硬件设备,提供了通用的数字开发方案。这个库包含了与一 相关的接口函数,函数可以参见Vfw.h。 获得两个新文件SoundWnd.cpp、SoundWnd.h。ClassViewCSoundFileDialogMFCClass,基类为CFileDialog。获得两个新文件SoundFileDialog.cpp、SoundFileDialog.h。virtualBOOLCreate(CWnd*pParentWnd,DWORDdwStyle,constRECT&rect,LPCSTRszFile=NULL); //

温馨提示

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

评论

0/150

提交评论