关于某单文档多视与MFC地初始化过程

上传人:痛*** 文档编号:86544863 上传时间:2022-05-07 格式:DOC 页数:43 大小:2.77MB
收藏 版权申诉 举报 下载
关于某单文档多视与MFC地初始化过程_第1页
第1页 / 共43页
关于某单文档多视与MFC地初始化过程_第2页
第2页 / 共43页
关于某单文档多视与MFC地初始化过程_第3页
第3页 / 共43页
资源描述:

《关于某单文档多视与MFC地初始化过程》由会员分享,可在线阅读,更多相关《关于某单文档多视与MFC地初始化过程(43页珍藏版)》请在装配图网上搜索。

1、word单文档多视的实现多视图是VC开发中经常要用到的技术之一,一般地实现单文档多视图有两种方式1通过视图分割的技术使用CSplitterWnd实现,将窗口分割为多个局部,每个局部显示各自显示不同的视图,这种技术实现起来比拟简单,并且相关的资料也很多。2通过一个文档关联多个视图,窗口显示整个视图。第二种实现较第一种复杂,这里给出详细的实现方法。Step 1:使用VC 6.0新建一个Project,命名为:MultiView。除选择单文档属性外,一切使用“默认方式。于是你可以获得五个类:CMainFrame,CMultiViewApp,CMultiViewDoc,CMultiViewView,和

2、CAboutDlg;Step 2:新建一个新的视图View,添加一个新的MFC ClassInsertNew Class,基类为CView或者CView的派生子类,如CEditView等。类的名字为CAnotherView,这就是新的视图;并为CAnotherView添加GetDocument的实现:CMultiViewDoc* CAnotherView:GetDocument()return (CMultiViewDoc*)m_pDocument;Step 3:在CMultiViewApp添加成员变量记录这两个视图:private:CView* m_pFirstView;CView* m_p

3、AnotherView;给程序菜单IDR_MAINFRAME添加一个菜单项目“视图,该菜单项有两个子菜单“视图一和“视图二,添加相应函数:voidCMultiViewApp:OnShowFirstview和voidCMultiViewApp:OnShowSecondview;注意这里将菜单消息的响应都放在app对象里面,而不是放到MainFrame对象中进展。Step 4:创建新的视图:在BOOLCMultiViewApp:InitInstance()中添加代码:./创建一个新的视图CView* m_pActiveView = (CFrameWnd*)m_pMainWnd)-GetActive

4、View();m_pFirstView = m_pActiveView;m_pAnotherView = new CAnotherView();/文档和视图关联CDocument* m_pDoc = (CFrameWnd*)m_pMainWnd)-GetActiveDocument();CCreateContext context;context.m_pCurrentDoc = m_pDoc;/创建视图UINT m_IDFORANOTHERVIEW = AFX_IDW_PANE_FIRST + 1;CRect rect;m_pAnotherView-Create(NULL,NULL,WS_CH

5、ILD,rect,m_pMainWnd,m_IDFORANOTHERVIEW,&context);Step 5:现在已经创建了视图,并且都和文档关联起来了。现在要作的就是视图间的转换。在voidCMultiViewApp:OnShowFirstview中添加实现代码:void CMultiViewApp:OnShowFirstview()/ TODO: Add your mand handler code hereUINT temp = :GetWindowLong(m_pAnotherView-m_hWnd, GWL_ID);:SetWindowLong(m_pAnotherView-m_h

6、Wnd, GWL_ID, :GetWindowLong(m_pFirstView-m_hWnd, GWL_ID);:SetWindowLong(m_pFirstView-m_hWnd, GWL_ID, temp);m_pAnotherView-ShowWindow(SW_HIDE);m_pFirstView-ShowWindow(SW_SHOW);(CFrameWnd*)m_pMainWnd)-SetActiveView(m_pFirstView);(CFrameWnd*) m_pMainWnd)-RecalcLayout();m_pFirstView-Invalidate();在voidCM

7、ultiViewApp:OnShowSecondview中添加实现代码:void CMultiViewApp:OnShowSecondview()/ TODO: Add your mand handler code hereUINT temp = :GetWindowLong(m_pAnotherView-m_hWnd, GWL_ID);:SetWindowLong(m_pAnotherView-m_hWnd, GWL_ID, :GetWindowLong(m_pFirstView-m_hWnd, GWL_ID);:SetWindowLong(m_pFirstView-m_hWnd, GWL_

8、ID, temp);m_pFirstView-ShowWindow(SW_HIDE);m_pAnotherView-ShowWindow(SW_SHOW);(CFrameWnd*)m_pMainWnd)-SetActiveView(m_pAnotherView);(CFrameWnd*) m_pMainWnd)-RecalcLayout();m_pAnotherView-Invalidate();Step 6:为了演示,这里将不同的视图给予一个标记,在CMultiViewView和CAnotherView的OnDraw方法中分别添加以下代码:pDC-TextOut(400,300,First

9、View);pDC-TextOut(400,320,pDoc-GetTitle();和pDC-TextOut(400,300,Another View);pDC-TextOut(400,320,pDoc-GetTitle();至此就大功告成了,但是实现过程中有4点说明:1实现中由于使用到相关的类,因此在必要的地方要include相关的头文件,这里省略;CAnotherView的默认构造函数是Protected的,需要将其改为Public,或者提供一个产生CAnotherView对象的方法因要创建视图对象;2这里给出的是一个示例代码,实际开发中可以通过参考实现获得自己想要实现的具体应用情况例如视

10、图类的不同、数量不同,更重要的还有业务逻辑的不同实现等;3本文的示例代码已上传到Blog,可以通过下面的地址获得代码。MFC程序总体的架构CWinApp取代WinMain的地位。CFrameWnd取代WndProc的地位在MFC里面,似乎应该是在CWnd类里有一个WindowProc这个类,应该就是这个函数来作为窗口回调函数,因为所有的窗口回调函数都继承自CWnd类,CFrame类也是的。在MFC中,为了让程序更加结构化,更容易理解和维护,利用了两个宏来处理消息映射:DECLARE_MESSAGE_MAP和BEGIN_MESSAGE_MAP,见前面第三章。程序运行第一步:引爆器Applicat

11、ion Object从这一节以下,将以此图解释MFC程序的激活,运行与完毕,不同小节的图将标示出当时的程序进展状况程序运行第二步:隐晦不明的WinMain主要动作:tWinMain调用AfxWinMain,AfxWinMain调用AfxWinInit在这个过程中, tWinMain的参数hInstance经过AfxWinMain传给AfxWinInit,然后在AfxWinInit中利用传进来的参数对theApp对象进展初始化利用全局函数AfxGetApp在AfxWinInit中除了对theApp对象进展初始化之处,还调用AfxInitThread函数对线程进展初始化。程序运行第三步:AfxWi

12、nInitAFX内部初始化动作程序运行第四步:CWinApp:InitApplication程序运行第五步:CMyWinApp:InitInstance程序运行第六步:CFramWnd:Create产生主窗口并先注册窗口类别小结:在MFC中,应用程序窗口的产生,必须经历窗口类的注册创建显示。这一系列的动作是通过theApp-InitInstance函数来组织调用的。PS:即在InitInstance里做了好多的工作,调用了相关的函数,这些函数就有窗口类的注册,窗口的创建和窗口的显示工作。窗口类的注册动作,MFC给我们提供的接口是各个窗口类的PreCreateWindow函数,BOOL CStu

13、dentInfoView:PreCreateWindow(CREATESTRUCT& cs)利用这个结构体参数,对窗口的样式进展设定,这个结构体如下:typedef struct tagCREATESTRUCT LPVOID lpCreateParams; HANDLE hInstance; HMENU hMenu; HWND hwndParent; int cy;int cx; int y; int x;LONG style; LPCSTR lpszName; LPCSTR lpszClass; DWORD dwExStyle; CREATESTRUCT;怎么让一个窗口居中显示?利用cy,c

14、x参数?程序运行第七步:窗口显示与更新程序运行第八步:CWinApp:Run程序生命的活水源头把消息与处理函数串接在一起:Message Map机制消息流动是个颇为复杂的机制,它和Document/View,动态生成Dynamic Creation,文件读写Serialization一样,都是需要特别留心的地方。来龙去脉总整理MFC骨干程序关于文档视图结构的创建这里的所谓的MFC应用程序骨干,批的是由AppWizard产生出来的MFC程序,也就是像第四章所产生的Scribble step0那样的程序。不二法门:熟记MFC类别阶层架构MFC程序的UI新风貌Document/View支撑你的应用程

15、序一个问题:文档关于Document/View的配合:为什么要用Document/View机制?骨干程序使用哪些MFC类别?应用程序各显身手的地方只是各个可能改写的虚拟函数。Document Template的意义为什么要有Document Template?Document Template对象的构造函数:Document Template构造函数的参数说明:对于我们的Scrible应用程序,它的相关代码如下:Document TemplateCDocTemplate管理CDocument/CView/CFrameWnd关于File/New与File/Open按钮动作的响应过程重要,重要,很

16、重要,台面下的File/New动作。关键的技术是产生Document/View/Frame三口组总体概览:上图的灰色局部,正是Document Template动态产生“三位一体的Document/View/Frame的行动。注意这里的CWinApp选择适当的Document Tempate:由于打开一个文件需要依赖于Document Tempate,而Document Tempate实例创建是在CMultiViewApp:InitInstance()里:CSingleDocTemplate* pDocTemplate;pDocTemplate = new CSingleDocTemplate

17、(IDR_MAINFRAME,RUNTIME_CLASS(CMultiViewDoc),RUNTIME_CLASS(CMainFrame), / main SDI frame windowRUNTIME_CLASS(CMultiViewView);AddDocTemplate(pDocTemplate);需要提供四样东西:其中第一样就是打开文档所需要的资源IDR_MAINFRAME,资源中包含了文档的后缀,文档类型的信息,所以当我们选择打开一个文件的时候,CSingleDocTemplate会自动根据文档的后缀类型来选择不同的CSingleDocTemplate实例进展三口组的创建CDocTe

18、mplate类如何创建三口组:File/New与File/Open消息的总结关于重要,重要,很重要!MFC主框架的类图:主要的类:CWinApp,CMainFrame, DocTemplete, CDocument, CView框架类之间的关系:CWinApp与CMainFrame与DocTemplete之间的关系:CWinApp有两个成员变量:CMainFrame和DocTemplete,在CWinApp被CMyApp所继承的OnInitInstance方法中:创建一个CSingleDocTemplate,将文档,框架窗口和视图联系了在一起,所以我们点文件打开一个文件的时候,它会显示这三口组

19、将Doc放在View中,然后View再嵌入到Frame中,由于程序运行的时候就应该显示一个文档,而文档需要通过三口组来显示,所以这里在CWinApp的派生对象中需要有这么一个三口组数组作为成员变量。CSingleDocTemplate* pDocTemplate;pDocTemplate = new CSingleDocTemplate(IDR_MAINFRAME,/这里是RUNTIME_CLASS(CMultiViewDoc),RUNTIME_CLASS(CMainFrame), / main SDI frame windowRUNTIME_CLASS(CMultiViewView);Add

20、DocTemplate(pDocTemplate);/这里将这个新生成的DocTemplet放到自己的DocTemplete列表中。/按照深入浅出的理论是在这个OnInitInstance中对CMainFrame成员变量进展了初始化调用构造函数,然后就引出了CMainFrame的初始化过程。/ The one and only window has been initialized, so show and update it.m_pMainWnd-ShowWindow(SW_SHOW);/将三口组给显示出来,而不是只是只显示一个框架m_pMainWnd-UpdateWindow();retu

21、rn TRUE;CDocument与CView之间的关系:是组合关系!而且是一对多的组合关系,一个CDocument可以有多个CView,而一个CView只能对应一个CDocument参见前面的单文档多视的实现中的第四步:Step 4:创建新的视图:在BOOLCMultiViewApp:InitInstance()中添加代码:./创建一个新的视图CView* m_pActiveView = (CFrameWnd*)m_pMainWnd)-GetActiveView();m_pFirstView = m_pActiveView;m_pAnotherView = new CAnotherView(

22、);/文档和视图关联CDocument* m_pDoc = (CFrameWnd*)m_pMainWnd)-GetActiveDocument();CCreateContext context;context.m_pCurrentDoc = m_pDoc;/创建视图UINT m_IDFORANOTHERVIEW = AFX_IDW_PANE_FIRST + 1;CRect rect;m_pAnotherView-Create(NULL,NULL,WS_CHILD,rect,m_pMainWnd,m_IDFORANOTHERVIEW,&context);注意这里的m_pAnotherView-C

23、reate(NULL,NULL,WS_CHILD,rect,m_pMainWnd,m_IDFORANOTHERVIEW,&context);/一个View的创建必须与一个CMainFrame和一个context(里面有Doc)相关联可见一个CView与CMainFrame, CDoc都有联系!CMultiViewView中的成员方法:CMultiViewDoc* CMultiViewView:GetDocument() / non-debug version is inlineASSERT(m_pDocument-IsKindOf(RUNTIME_CLASS(CMultiViewDoc);re

24、turn (CMultiViewDoc*)m_pDocument;由于前面CView在创建的时候将CMainFrame和CDoc作为它创建的参数,所以这里m_pDocument;代表的是前面传递进来的文档的指针。看到了吧,只返回一个指针,所以应该是一个CView只对应一个CDoc。CMultiViewDoc类中的成员方法:POSITION CMultiViewDoc:GetFirstViewPosition() const/ TODO: Add your specialized code here and/or call the base classreturn CDocument:GetFi

25、rstViewPosition();CView* CMultiViewDoc:GetNextView(POSITION& rPosition) const/ TODO: Add your specialized code here and/or call the base classreturn CDocument:GetNextView(rPosition);由此可见一个CDoc可以有多个CViewCFrameWnd与CDoc之间的关系:对于单文档程序来说一个CFrameWnd只有一个CDoc,而多文档应用程序如此可以有多个CDocCFrameWnd中的成员方法:CDocument* CMa

26、inFrame:GetActiveDocument() / TODO: Add your specialized code here and/or call the base classreturn CFrameWnd:GetActiveDocument();一个CFrameWnd可以返回一个CDocCFrameWnd与CView之间的关系好似没有什么关系,不过可能通过CFrameWnd获得CDoc之后,然后再由CDoc获得CView对象。关于源码CWinApp:Public:/ AttributesCWnd* m_pMainWnd; / main window (usually same A

27、fxGetApp()-m_pMainWnd)CWnd* m_pActiveWnd; / active main window (may not be m_pMainWnd)。CDocManager* m_pDocManager;/这个就是用来管理CDocTemplet一个实例代表的是一个三口组实例的了。CWnd源码:/ for child windows, views, panes etcvirtual BOOL Create(LPCTSTR lpszClassName,LPCTSTR lpszWindowName, DWORD dwStyle,const RECT& rect,CWnd* p

28、ParentWnd, UINT nID,CCreateContext* pContext = NULL);前面的CView在创建的时候就利用了这个方法:m_pAnotherView-Create(NULL,NULL,WS_CHILD,rect,m_pMainWnd,m_IDFORANOTHERVIEW,&context);CView源代码:成员变量:protected:CDocument* m_pDocument;CDocument源代码:成员变量:protected:/ default implementation。CDocTemplate* m_pDocTemplate;CPtrList m_viewList; / list of viewsBOOL m_bModified; / changed since last savedCWinFrame源码:Protected:CView* m_pViewActive; / current active view源代码图解

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

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


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