当前位置:文档之家› 关于单文档多视与MFC的初始化过程

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

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

Step 2:新建一个新的视图View,添加一个新的MFC Class(Insert->New Class),基类为CView(或者CView的派生子类,如CEditView等)。类的名字为CAnotherView,这就是新的视图;并为CAnotherView添加GetDocument的实现: CMultiViewDoc* CAnotherView::GetDocument() { return (CMultiViewDoc*)m_pDocument; }

Step 3:在CMultiViewApp添加成员变量记录这两个视图: private: CView* m_pFirstView; CView* m_pAnotherView; 给程序菜单IDR_MAINFRAME添加一个菜单项目“视图”,该菜单项有两个子菜单“视图一”和“视图二”,添加相应函数:(voidCMultiViewApp::OnShowFirstview()和voidCMultiViewApp::OnShowSecondview()); 注意这里将菜单消息的响应都放在app对象里面,而不是放到MainFrame对象中进行。

Step 4:创建新的视图:在BOOLCMultiViewApp::InitInstance()中添加代码: „„. //创建一个新的视图 CView* m_pActiveView = ((CFrameWnd*)m_pMainWnd)->GetActiveView(); 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_CHILD,rect,m_pMainWnd, m_IDFORANOTHERVIEW,&context); „„

Step 5:现在已经创建了视图,并且都和文档关联起来了。现在要作的就是视图间的转换。在voidCMultiViewApp::OnShowFirstview()中添加实现代码: void CMultiViewApp::OnShowFirstview() { // TODO: Add your command handler code here UINT 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_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(); }

在voidCMultiViewApp::OnShowSecondview()中添加实现代码: void CMultiViewApp::OnShowSecondview() { // TODO: Add your command handler code here UINT 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_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 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) 这里给出的是一个示例代码,实际开发中可以通过参考实现获得自己想要实现的具体应用情况(例如视图类的不同、数量不同,更重要的还有业务逻辑的不同实现等); 3) 本文的示例代码已上传到Blog,可以通过下面的地址获得代码。

MFC程序总体的架构 CWinApp――取代WinMain的地位 。。。。。。。

。。。。。 CFrameWnd――取代WndProc的地位

在MFC里面,似乎应该是在CWnd类里有一个WindowProc这个类,应该就是这个函数来作为窗口回调函数,因为所有的窗口回调函数都继承自CWnd类,CFrame类也是的。 在MFC中,为了让程序更加结构化,更容易理解和维护,利用了两个宏来处理消息映射:DECLARE_MESSAGE_MAP和BEGIN_MESSAGE_MAP,见前面第三章。

程序运行第一步:引爆器――Application Object 从这一节以下,将以此图解释MFC程序的激活,运行与结束,不同小节的图将标示出当时的程序进行状况 程序运行第二步:隐晦不明的WinMain 主要动作: tWinMain调用AfxWinMain,AfxWinMain调用AfxWinInit 在这个过程中, tWinMain的参数hInstance经过AfxWinMain传给AfxWinInit,然后在AfxWinInit中利用传进来的参数对theApp对象进行初始化(利用全局函数AfxGetApp) 在AfxWinInit中除了对theApp对象进行初始化之处,还调用AfxInitThread函数对线程进行初始化。 程序运行第三步:AfxWinInit――AFX内部初始化动作 程序运行第四步:CWinApp::InitApplication 程序运行第五步:CMyWinApp::InitInstance 程序运行第六步:CFramWnd::Create产生主窗口(并先注册窗口类别) 小结: 在MFC中,应用程序窗口的产生,必须经历窗口类的注册-》创建-》显示。 这一系列的动作是通过theApp->InitInstance()函数来组织调用的。PS:即在InitInstance里做了好多的工作,调用了相关的函数,这些函数就有窗口类的注册,窗口的创建和窗口的显示工作。 窗口类的注册动作,MFC给我们提供的接口是各个窗口类的PreCreateWindow()函数, BOOL CStudentInfoView::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,cx参数??

相关主题