1.MFC CView
MFC提供了CView类的多种派生类,以提供对多种控件的支持。为用户提供多元化的显示界面。
CScrollView 提供滚动支持。
CCtrlView 支持tree,list,rich edit。
CDaoRecordView 在Dialog-box控件中显示数据库记录。
CEditView 提供了一个简单的多行文本编辑器视图。
CFormView 包含Dialog-box控件,可滚动,基于对话框模版资源。
CListView 支持列表控件视图
CRecordView 在Dialog-box控件中显示数据库记录。
CRichEditView 支持富文本编辑的控件视图
CTreeView 支持重点在树控件的文档/视图结构的视图。
2.MFC 文档
1. 应用程序对象保存了一个文档模板的列表。在任何对象中调用全局函数AfxGetApp都可以获得应用程序对象的指针。通过调用CWinAppEx::GetFirstDocTemplatePosition、CWinAppEx::GetNextDocTemplate函数可以遍历所有的文档模板。
2. 文档模板对象用于维护文档、视图和框架窗口的映射关系,它包含有一个已打开文档的列表。我们可以通过调用CDocTemplate::GetFirstDocPosition、CDocTemplate::GetNextDoc来遍历该文档模板对应的所有文档。
3. 框架窗口对象中包含有指向当前活动视图对象的指针。AfxGetApp()->m_pMainWnd即为主框架窗口对象的指针。我们可以通过调用CFrameWndEx::GetActiveView来获取当前活动视图对象的指针,并且使用CFrameWndEx::GetActiveDocument函数可以获得当前活动视图对应的文档。
4. 文档对象中维护着该文档的视图列表,以及创建该文档的文档模板对象的指针。我们可以通过调用CDocument::GetFirstViewPosition,CDocument::GetNextView来遍历该文档关联的所有视图,调用CDocument::GetDocTemplate获取创建该文档的文档模板对象的指针。
5. 视图是框架窗口的子窗口,它保存有指向对应的文档对象的指针。我们可以通过调用CView::GetParentFrame获取其所属的框架窗口对象的指针,调用CView::GetDocument获取该视图对应的文档对象的指针。
另外,在MDI多文档程序中,调用CMDIFrameWnd::MDIGetActive可以获取当前活动的MDI子窗口。
文档和视图的关系
应用程序可以是单文档程序也可以是多文档程序。单文档程序中主框架窗口和文档框架窗口重合,而多文档程序的主框架窗口中有客户窗口,客户窗口中又包含了多个文档框架窗口。
文档和视图是一对多的关系。一个文档可以对应多个视图,例如在Word中一个文档有普通视图、大纲视图、Web版式视图、阅读版式视图等多种视图。而一个视图只能属于一个文档。最简单的应用程序是单文档单视图程序,除此之外还有单文档多视图程序、多文档程序等。
每个文档对象都保存着一个视图列表,可以通过CDocument::AddView函数添加视图,通过CDocument::RemoveView函数删除视图,在数据发生变化时调用CDocument::UpdateAllViews函数更新所有视图。
在MFC中文档可以有三种视图模式:
1. 文档有多个视图对象,它们是同一个视图类的对象,每个视图对象位于一个独立的文档框架窗口中。
2. 文档的基于同一个视图类的多个视图对象,位于同一个文档框架窗口中。Word的子窗口就是这种视图模式。
3.文档的视图对象属于不同的视图类,但所有的视图对象位于同一文档框架窗口中。
3.MFC 视图切换
比如:
class CTestView1 : public CFormView
{
//....
}
class CTestView2 : public CView
{
//....
}
2–然后在xx.cpp文件中(XX代表工程名)即CxxApp类的cpp文件中
包含切换的两个类的头文件,如:
#include "TestView1.h"
#include "TestView2.h"
3–在 CxxApp的头文件里申请两个CMultiDocTemplate 指针如:
CMultiDocTemplate * m_pTemplateTestView1;
CMultiDocTemplate * m_pTemplateTestView2;
4–在CxxApp的InitInstance()函数内,创建上面两个指针指向的实例
BOOL CXXApp::InitInstance()
{
...
m_pTemplateTestView1= new CMultiDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CTestViewDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CTestView1));
AddDocTemplate(m_pTemplateTestView1);
m_pTemplateTestView2= new CMultiDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CTestViewDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CTestView2));
AddDocTemplate(m_pTemplateTestView2); //添加到此app的模板管理类中
...
}
注意CMultiDocTemplate()内第一个参数指向一个字符串的资源ID,如果存在多个字符串,则在开始时会弹出对话框让你选择采用哪个模板,这时可以将其中一个ID换为不指向字符串资源的id,屏蔽此对话框,也可重载app里的OnFileNew()函数,在里面选择自己需要一开始创建的模板
如:
void CXXApp::OnFileNew()
{
CDocTemplate * pTemplate=NULL;
int i;
pTemplate=m_pTemplateTestView1;
ASSERT(pTemplate != NULL);
ASSERT_KINDOF(CDocTemplate, pTemplate);
//创建doc,创建frame,创建view
return pTemplate->OpenDocumentFile(NULL);
}
注意CMultiDocTemplate()内第二个参数必为CChildFrame
注意CMultiDocTemplate()内第三个参数为你创建需要切换的view视图类
5、在CMainFrame的InitializeRibbon里面注释掉其他没有用的界面设置,比如“剪贴板”面板,“窗口”面板,‘右侧选项卡’等,但是留下定义的东西。
然后,确定初始化主页
// 初始主按钮:
m_MainButton.SetImage(IDB_MAIN); m_MainButton.SetText(_T("\nf"));
strTemp = "主页";//这句自己添自己添的东西
m_MainButton.SetToolTipText(strTemp);
//然后添加自己的面板,定义留着,
CMFCRibbonCategory* pCategoryHome =
m_wndRibbonBar.AddCategory(
strTemp, IDB_WRITESMALL,IDB_WRITELARGE);
strTemp = "导入图像视图面板";)
CMFCRibbonPanel *pPanelView =pCategoryHome->AddPanel(
strTemp,m_PanelImages.ExtractIcon(1));
strTemp = "导入图像"; pPanelView->Add(new CMFCRibbonButton(ID_IMAGE_OPEN,strTemp,0,0));
strTemp = "点选图像标志点"; pPanelView->Add(new CMFCRibbonButton(ID_SELECT_POINT,strTemp,0,1));
strTemp = "图像校正"; pPanelView->Add(new CMFCRibbonButton(ID_IMAGE_ADJUST,strTemp,0,2));
5–此时程序已经包含多个视图的模板,切换是在Mainframe类中实现。在mainframe添加下面这个函数
void CMainFrame::SwitchToView(CDocTemplate * pTemplate, CRuntimeClass * pViewClass)
{
//获得活动子窗口
CMDIChildWnd *pMDIActive = MDIGetActive();
//获得活动doc
CDocument *pDoc = pMDIActive->GetActiveDocument();
CView *pView;
POSITION pos = pDoc->GetFirstViewPosition();
//查询此doc下的所有已创建view
while (pos != NULL)
{
pView = pDoc->GetNextView(pos);
if (pView->IsKindOf(pViewClass))
//如果已创建此view 则设其为活动
{
// the requested view class has already been created; show it
pView->GetParentFrame()->ActivateFrame();
//pView->UpdateWindow();//视图更新显示;
return;
}
pView->UpdateWindow();
}
CMDIChildWnd *pNewFrame = (CMDIChildWnd *)
(pTemplate->CreateNewFrame(pDoc, NULL));
// 如果没有创建,则创建此view的childframe及view
if (pNewFrame == NULL)
return;
pTemplate->InitialUpdateFrame(pNewFrame, pDoc);
}
6 在mainframe中响应你的切换按钮,调用switchtoView如
void CMainFrame::OnViewTestView1()
{
SwitchToView(theApp.m_pVideoTemplate, RUNTIME_CLASS(CTestView1)); //第一个为app里你的模板指针,第二个为ctestview1类的类型识别宏。
}
解释:
RUNTIME_CLASS为一个宏,其返回一个CRuntimeClass *指针,可进行类的类型识别。
详细定义请见《深入浅出mfc》