MFC 知识总结<2>MFC CView

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》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值