先声明下,这篇文章是翻译其他地方的,也不知道作者允不允许翻译,在文章页面没找到相关说明。只是原文是英文版本的。如若,原作者看到,不希望这个存在,可以联系我或者平台删除此文。
在使用Microsoft基础类(MFC)库创建的单文档界面(SDI)应用程序中,每种文档类型都与单个视图类型相关联。在某些情况下,希望能够使用新视图切换文档的当前视图。
您可以通过添加新的CView
类和用于将视图动态切换到现有MFC应用程序的其他代码来实现此功能。
步骤如下:
本主题的其余部分假定以下内容:
-
-Derived
CWinApp
对象的名称是CMyWinApp
,并CMyWinApp
在MYWINAPP.H和MYWINAPP.CPP中声明和定义。 -
CNewView
是新CView
起源对象的名称,CNewView
在NEWVIEW.H和NEWVIEW.CPP中声明和定义。
修改现有的应用程序类
要使应用程序在视图之间切换,您需要通过添加成员变量来存储视图以及切换它们的方法来修改应用程序类。
下面的代码添加到的声明CMyWinApp
中MYWINAPP.H:
CView *m_pOldView;
CView *m_pNewView;
CView *SwitchView();
新成员变量,m_pOldView
并m_pNewView
指向当前视图和新创建的变量。新方法(SwitchView
)在用户请求时切换视图。该方法的主体将在本主题后面的“ 实现切换功能”中讨论。
对应用程序类的最后一次修改需要包含一个新的头文件,该文件定义了在切换函数中使用的Windows消息(WM_INITIALUPDATE)。
在MYWINAPP.CPP的include部分插入以下行:
#include <AFXPRIV.H>
保存更改并继续下一步。
创建和修改新视图类
使用Class View中提供的New Class命令可以轻松创建新的视图类。这个类的唯一要求是它来源于CView
。将此新类添加到应用程序。有关向项目添加新类的特定信息,请参阅添加类。
将类添加到项目后,需要更改某些视图类成员的可访问性。
通过将构造函数和析构函数的访问说明符从protected更改为public来修改NEWVIEW.H。这允许动态创建和销毁类,并在视图外观可见之前修改它。
保存更改并继续下一步。
创建并附加新视图
要创建和附加新视图,您需要修改InitInstance
应用程序类的功能。修改补充说,创建一个新的查看对象,然后初始化两个新的代码m_pOldView
和m_pNewView
与两个现有的查看对象。
由于新视图是在InitInstance
函数内创建的,因此新视图和现有视图在应用程序的生命周期内都会持续存在。但是,应用程序可以轻松地动态创建新视图。
调用ProcessShellCommand
后插入此代码:
CView *pActiveView = ((CFrameWnd *)m_pMainWnd)->GetActiveView();
m_pOldView = pActiveView;
m_pNewView = (CView *)new CNewView;
if (NULL == m_pNewView)
return FALSE;
CDocument *pCurrentDoc = ((CFrameWnd *)m_pMainWnd)->GetActiveDocument();
// Initialize a CCreateContext to point to the active document.
// With this context, the new view is added to the document
// when the view is created in CView::OnCreate().
CCreateContext newContext;
newContext.m_pNewViewClass = NULL;
newContext.m_pNewDocTemplate = NULL;
newContext.m_pLastView = NULL;
newContext.m_pCurrentFrame = NULL;
newContext.m_pCurrentDoc = pCurrentDoc;
// The ID of the initial active view is AFX_IDW_PANE_FIRST.
// Incrementing this value by one for additional views works
// in the standard document/view case but the technique cannot
// be extended for the CSplitterWnd case.
UINT viewID = AFX_IDW_PANE_FIRST + 1;
CRect rect(0, 0, 0, 0); // Gets resized later.
// Create the new view. In this example, the view persists for
// the life of the application. The application automatically
// deletes the view when the application is closed.
m_pNewView->Create(NULL, _T("AnyWindowName"), WS_CHILD, rect, m_pMainWnd, viewID, &newContext);
// When a document template creates a view, the WM_INITIALUPDATE
// message is sent automatically. However, this code must
// explicitly send the message, as follows.
m_pNewView->SendMessage(WM_INITIALUPDATE, 0, 0);
保存更改并继续下一步。
实现切换功能
在上一步中,您添加了创建和初始化新视图对象的代码。最后一个主要部分是实现切换方法SwitchView
。
在应用程序类(MYWINAPP.CPP)的实现文件的末尾,添加以下方法定义:
CView *CMyWinApp::SwitchView()
{
CView *pActiveView = ((CFrameWnd *)m_pMainWnd)->GetActiveView();
CView *pNewView = NULL;
if (pActiveView == m_pOldView)
pNewView = m_pNewView;
else
pNewView = m_pOldView;
// Exchange view window IDs so RecalcLayout() works.
#ifndef _WIN32
UINT temp = ::GetWindowWord(pActiveView->m_hWnd, GWW_ID);
::SetWindowWord(pActiveView->m_hWnd, GWW_ID, ::GetWindowWord(pNewView->m_hWnd, GWW_ID));
::SetWindowWord(pNewView->m_hWnd, GWW_ID, temp);
#else
UINT temp = ::GetWindowLong(pActiveView->m_hWnd, GWL_ID);
::SetWindowLong(pActiveView->m_hWnd, GWL_ID, ::GetWindowLong(pNewView->m_hWnd, GWL_ID));
::SetWindowLong(pNewView->m_hWnd, GWL_ID, temp);
#endif
pActiveView->ShowWindow(SW_HIDE);
pNewView->ShowWindow(SW_SHOW);
((CFrameWnd *)m_pMainWnd)->SetActiveView(pNewView);
((CFrameWnd *)m_pMainWnd)->RecalcLayout();
pNewView->Invalidate();
return pActiveView;
}
保存更改并继续下一步。
添加对切换视图的支持
最后一步涉及添加SwitchView
在应用程序需要在视图之间切换时调用该方法的代码。这可以通过多种方式完成:通过添加新菜单项供用户选择或在满足某些条件时在内部切换视图。
示例下载
附加了一个示例小程序,但是不是根据这篇文章写的,但是大致思路是一致的,只是细节有些区分。下载地址https://download.csdn.net/download/yishang44/11686130