MFC中App,Doc,MainFrame,View各指针的互相获取

2024-09-08 12:18

本文主要是介绍MFC中App,Doc,MainFrame,View各指针的互相获取,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

纸上得来终觉浅,为了熟悉获取方法,我建了个SDI。
首先说明这四个类的执行顺序是App->Doc->Main->View
另外添加CDialog类获得各个指针的方法。
多文档的获取有点小区别,有时间也总结一下。
复制代码
//  App
void CSDIApp::OnApp()
{
     //  App
    
//  Doc
    CDocument *pDoc = ((CFrameWndEx *)m_pMainWnd)->GetActiveDocument();
     //  Main 成员变量m_pMainWnd
    CFrameWndEx *pMain = (CFrameWndEx *)AfxGetMainWnd();
     //  View
    CView *pView = ((CFrameWndEx *)m_pMainWnd)->GetActiveView();
}
//  Doc
CSDIDoc::CSDIDoc()
{
     //  App
    CWinAppEx *pApp = (CWinAppEx *)AfxGetApp();
     //  Doc
    
//  Main
    
//  Doc的创建先于Main
    
//  View
    
//  Doc的创建先于View
}
void CSDIDoc::OnDoc()
{
     //  App
    
//  同构造函数
    
//  Doc
    
//  Main
    CFrameWndEx *pMain = (CFrameWndEx *)AfxGetMainWnd();
     //  View
    CView *pView= (CView *)pMain->GetActiveView();
  //

    POSITION pos = GetFirstViewPosition();   

pView = GetNextView(pos); 
}
//  Main
CMainFrame::CMainFrame()
{
    theApp.m_nAppLook = theApp.GetInt(_T( " ApplicationLook "), ID_VIEW_APPLOOK_VS_2005);
     //  App
    CWinAppEx *pApp = (CWinAppEx *)AfxGetApp();
     //  Doc
    
//  构造函数里无法得到当前激活的Doc
    
//  Main
    
//  View
    
//  构造函数里无法得到View指针,因为Main先于View创建。
}
void CMainFrame::OnMain()
{
     //  App
    
//  同构造函数
    
//  Doc
    CDocument *pDoc = (CDocument *)GetActiveDocument();
     //  Main
    
//  View
    CView *pView = (CView *)GetActiveView();
}
//  View
CSDIView::CSDIView()
{
     //  App
    CWinAppEx *pApp = (CWinAppEx *)AfxGetApp();
     //  Doc
     /*  无法在View的构造函数里得到Doc指针
       GetDocument();实际上是返回m_pDocument
       m_pDocument在OnCreate();里创建        
*/
     // CDocument *pDoc = GetDocument();
    
//  Main
    
//  构造函数里无法得到MainFrame指针
    
//  CFrameWndEx *pMain = (CFrameWndEx *)pApp->m_pMainWnd;
    
//  View
}
void CSDIView::OnView()
{
     //  App
    
//  同构造函数
    
//  Doc
    CDocument *pDoc = GetDocument();
     //  Main
    CFrameWndEx *pMain = (CFrameWndEx *)AfxGetMainWnd();
     //  View
}
//  Dlg
CDlg::CDlg(CWnd* pParent  /* =NULL */)
    : CDialog(CDlg::IDD, pParent)
{
     //  App
    CWinAppEx *pApp = (CWinAppEx *)AfxGetApp();
     //  Doc
    CDocument *pDoc = ((CFrameWndEx *)AfxGetMainWnd())->GetActiveDocument();
     //  Main
    CFrameWndEx *pMain = (CFrameWndEx *)AfxGetMainWnd();
     //  View
    CView *pView = ((CFrameWndEx *)AfxGetMainWnd())->GetActiveView();
}
复制代码
url: http://greatverve.cnblogs.com/archive/2012/11/02/mfc-app-doc-main-view.html 
参考:
MFC中Doc,View,MainFrmae,App各指针的互相获取

  1)   在View中获得Doc指针  

  2)   在App中获得MainFrame指针  

  3)   在View中获得MainFrame指针  

  4)   获得View(已建立)指针  

  5)   获得当前文档指针  

  6)   获得状态栏与工具栏指针  

  7)   获得状态栏与工具栏变量  

  8)   在Mainframe获得菜单指针  

  9)   在任何类中获得应用程序类  

  10)   从文档类取得视图类的指针(1)  

  11)   在App中获得文档模板指针  

  12)   从文档模板获得文档类指针  

  13)   在文档类中获得文档模板指针  

  14)   从文档类取得视图类的指针(2)  

  15)   从一个视图类取得另一视图类的指针  

    
  VC中编程对于刚刚开始学习的同学,最大的障碍和问题就是消息机制和指针获取与操作。其实这些内容基本上是每本VC学习工具书上必讲的内容,而且通过MSDN很多问题都能解决。下面文字主要是个人在编程中指针使用的一些体会,说的不当的地方请指正。一般我们使用的框架是VC提供的Wizard生成的MFC App Wizard(exe)框架,无论是多文档还是单文档,都存在指针获取和操作问题。下面这节内容主要是一般 的框架,然后再讲多线程中的指针使用。使用到的类需要包含响应的头文件。首先一般获得本类(视,文档,对话框都支持)实例指针this,用this的目的,主要可以通过类中的函数向其他类或者函数中发指针,以便于在非本类中操作和使用本类中的功能。

  1)   在View中获得Doc指针  

CYouSDIDoc   *pDoc=GetDocument();一个视只能有一个文档。  

   2)   在App中获得MainFrame指针  

  CWinApp   中的   m_pMainWnd变量就是MainFrame的指针   
  也可以:   CMainFrame   *pMain   =(CMainFrame   *)AfxGetMainWnd();

    3)   在View中获得MainFrame指针

  CMainFrame   *pMain=(CmaimFrame   *)AfxGetApp()->m_pMainWnd;

   4)   获得View(已建立)指针

  CMainFrame   *pMain=(CmaimFrame   *)AfxGetApp()->m_pMainWnd;   
  CyouView   *pView=(CyouView   *)pMain->GetActiveView();

  5)   获得当前文档指针

  CDocument   *   pCurrentDoc   =(CFrameWnd   *)m_pMainWnd->GetActiveDocument();

  6)   获得状态栏与工具栏指针

  CStatusBar   *   pStatusBar=(CStatusBar   *)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_STATUS_BAR);   
  CToolBar   *   pToolBar=(CtoolBar   *)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_TOOLBAR);   

  7)   如果框架中加入工具栏和状态栏变量还可以这样    

  (CMainFrame   *)GetParent()->m_wndToolBar;   
  (CMainFrame   *)GetParent()->m_wndStatusBar;   

  8)   在Mainframe获得菜单指针

  CMenu   *pMenu=m_pMainWnd->GetMenu();

  9)   在任何类中获得应用程序类  

  用MFC全局函数AfxGetApp()获得。  

 10)   从文档类取得视图类的指针  

  从文档获得视图类指针目的一般为了控制同一文档的多个视图的定位问题,我的体会   
  特别是文字处理CEditView当产生多个视图类时,这个功能是非常需要的。     
  CDocument类提供了两个函数用于视图类的定位:   
  GetFirstViewPosition()和GetNextView()     
  virtual   POSITION   GetFirstViewPosition()   const;   
  virtual   CView*   GetNextView(POSITION&   rPosition)   const;   
    
  注意:GetNextView()括号中的参数用的是引用方式,因此执行后值可能改变。   
  GetFirstViewPosition()用于返回第一个视图位置(返回的并非视图类指针,而是一   
  个POSITION类型值),GetNextView()有两个功能:返回下一个视图类的指针以及用   
  引用调用的方式来改变传入的POSITION类型参数的值。很明显,在Test程序中,只有   
  一个视图类,因此只需将这两个函数调用一次即可得到CTestView的指针如下(需定   
  义一个POSITION结构变量来辅助操作):     
  CTestView*   pTestView;   
  POSITION   pos=GetFirstViewPosition();   
  pTestView=GetNextView(pos);   
    
  这样,便可到了CTestView类的指针pTestView.执行完几句后,变量pos=NULL,因为没   
  有下一个视图类,自然也没有下一个视图类的POSITION.但是这几条语句太简单,不   
  具有太强的通用性和安全特征;当象前面说的那样,当要在多个视图为中返回某个指   
  定类的指针时,我们需要遍历所有视图类,直到找到指定类为止。判断一个类指针指   
  向的是否某个类的实例时,可用IsKindOf()成员函数时行检查,如:   
    pView->IsKindOf(RUNTIME_CLASS(CTestView));   
  即可检查pView所指是否是CTestView类。   
    
  有了以上基础,我们已经可以从文档类取得任何类的指针。为了方便,我们将其作   
  为一个文档类的成员函数,它有一个参数,表示要获得哪个类的指针。实现如下:    

复制代码
CView*   CTestDoc::GetView(CRuntimeClass*   pClass)  
  {  
  CView*   pView;  
  POSITION   pos=GetFirstViewPosition();  
   
   while(pos!=NULL){  
  pView=GetNextView(pos);  
   if(!pView->IsKindOf(pClass))  
   break;  
  }  
   
   if(!pView->IsKindOf(pClass)){  
  AfxMessageBox( " Connt   Locate   the   View./r/n   http://www.VCKBASE.com ");  
   return   NULL;  
  }  
   
   return   pView;  
  }   
复制代码
其中用了两次视图类的成员函数IsKindOf()来判断,是因为退出while循环有三种可能:   
  1.pos为NULL,即已经不存在下一个视图类供操作;   
  2.pView已符合要求。   
    
  1和2同是满足。这是因为GetNextView()的功能是将当前视图指针改变成一个视图   
  的位置同时返回当前视图指针,因此pos是pView的下一个视图类的POSITION,完全   
  有可能既是pos==NULL又是pView符合需要。当所需的视图是最后一个视图是最后一   
  个视图类时就如引。因此需采用两次判断。   
  使用该函数应遵循如下格式(以取得CTestView指针为例):   
  CTestView*   pTestView=(CTestView*)GetView(RUNTIME_CLASS(CTestView));   
  RUNTIME_CLASS是一个宏,可以简单地理解它的作用:将类的名字转化为   
  CRuntimeClass为指针。至于强制类型转换也是为了安全特性考虑的,因为从同一个   
  基类之间的指针类型是互相兼容的。这种强制类型转换也许并不必要,但能避免一   
  些可能出现的麻烦。   
    
  3.从一个视图类取得另一视图类的指针   综合1和2,很容易得出视图类之间互相获得   
  指针的方法:就是用文档类作中转,先用1的方法得到文档类的指针,再用2的方法,   
  以文档类的视图定位函数取得另一个视图类。同样,可以实现成一个函数:   
  (假设要从CTestAView中取得指向其它视图类的指针)    
复制代码
CView*   CTestAView::GetView(CRuntimeClass*   pClass)  
  {  
  CTestDoc*   pDoc=(CTestDoc*)GetDocument();  
  CView*   pView;  
  POSITION   pos=pDoc->GetFirstViewPosition();  
   while(pos!=NULL){  
  pView=pDoc->GetNextView(pos);  
   if(!pView->IsKindOf(pClass))  
   break;  
  }  
   if(!pView->IsKindOf(pClass)){  
  AfxMessageBox( " Connt   Locate   the   View. ");  
   return   NULL;  
  }  
   
   return   pView;  
  }   
复制代码

 这个函数和2中的GetView()相比,一是多了第一句以取得文档类指针,二是在   
  GetFirstViewPosition()和GetNextView()前加上了文档类指针,以表示它们是文档   
  类成员函数。有了此函数;当要从CTestAView中取得CTestBView的指针时,只需如   
  下:CTestBView*   pTestbView=(CTestView*)GetView(RUNTIME_CLASS(CTestBView));

  11)对于单文档中也可以加入多个文档模板

但是一般的开发就使用MDI方式开发   
  多文档模板,其方法与上述视图的获取方法很接近,这里稍做解释,如果不清楚,   
  请查阅MSDN,(以下四个内容(11、12、13、14)来源:   
    
  可以用CWinApp::GetFirstDocTemplatePostion获得应用程序注册的第一个文档模板   
  的位置;利用该值来调用CWinApp::GetNextDocTemplate函数,获得第一个   
  CDocTemplate对象指针。   POSITION   GetFirstDocTemplate(   )   const;     
  CDocTemplate   *GetNextDocTemplate(   POSITION   &   pos   )   const;   
    
  第二个函数返回由pos   标识的文档模板。POSITION是MFC定义的一个用于迭代或对象   
  指针检索的值。通过这两个函数,应用程序可以遍历整个文档模板列表。如果被检索   
  的文档模板是模板列表中的最后一个,则pos参数被置为NULL。   

  12)一个文档模板可以有多个文档,每个文档模板都保留并维护了一个所有对应文档的指针列表。    

  用CDocTemplate::GetFirstDocPosition函数获得与文档模板相关的文档集合中第一   
  个文档的位置,并用POSITION值作为CDocTemplate::GetNextDoc的参数来重复遍历与   
  模板相关的文档列表。函数原形为:   
  viaual   POSITION   GetFirstDocPosition(   )   const   =   0;     
  visual   CDocument   *GetNextDoc(POSITION   &   rPos)   const   =   0;       
    
  如果列表为空,则rPos被置为NULL.     

 13)在文档中可以调用CDocument::GetDocTemplate获得指向该文档模板的指针。  

  函数原形如下:   CDocTemplate   *   GetDocTemplate   (   )   const;     
  如果该文档不属于文档模板管理,则返回值为NULL。     

  14)一个文档可以有多个视。每一个文档都保留并维护一个所有相关视的列表。  

  CDocument::AddView将一个视连接到文档上,将该视加入到文档相联系的视的列表   
  中,并将视的文档指针指向该文档。当有File/New、File/Open、Windows/New或   
  Window/Split的命令而将一个新创建的视的对象连接到文档上时,   MFC会自动调用   
  该函数,框架通过文档/视的结构将文档和视联系起来。当然,程序员也可以根据自   
  己的需要调用该函数。   
  Virtual   POSITION   GetFirstViewPosition(   )   const;     
  Virtual   CView   *   GetNextView(   POSITION   &rPosition)   cosnt;     
    
  应用程序可以调用CDocument::GetFirstViewPosition返回与调用文档相联系的视的   
  列表中的第一个视的位置,并调用CDocument::GetNextView返回指定位置的视,并将   
  rPositon的值置为列表中下一个视的POSITION值。如果找到的视为列表中的最后一个   
  视,则将rPosition置为NULL.     

  15)从一个视图类取得另一视图类的指针  

  这个应用在多视的应用程序中很多见,一般如果自己在主程序或者主框架中做好变   
  量记号,也可以获得,还有比较通用的就是用文档类作中转,以文档类的视图

这篇关于MFC中App,Doc,MainFrame,View各指针的互相获取的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1148088

相关文章

Python获取浏览器Cookies的四种方式小结

《Python获取浏览器Cookies的四种方式小结》在进行Web应用程序测试和开发时,获取浏览器Cookies是一项重要任务,本文我们介绍四种用Python获取浏览器Cookies的方式,具有一定的... 目录什么是 Cookie?1.使用Selenium库获取浏览器Cookies2.使用浏览器开发者工具

Java获取当前时间String类型和Date类型方式

《Java获取当前时间String类型和Date类型方式》:本文主要介绍Java获取当前时间String类型和Date类型方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录Java获取当前时间String和Date类型String类型和Date类型输出结果总结Java获取

C#监听txt文档获取新数据方式

《C#监听txt文档获取新数据方式》文章介绍通过监听txt文件获取最新数据,并实现开机自启动、禁用窗口关闭按钮、阻止Ctrl+C中断及防止程序退出等功能,代码整合于主函数中,供参考学习... 目录前言一、监听txt文档增加数据二、其他功能1. 设置开机自启动2. 禁止控制台窗口关闭按钮3. 阻止Ctrl +

一文详解如何使用Java获取PDF页面信息

《一文详解如何使用Java获取PDF页面信息》了解PDF页面属性是我们在处理文档、内容提取、打印设置或页面重组等任务时不可或缺的一环,下面我们就来看看如何使用Java语言获取这些信息吧... 目录引言一、安装和引入PDF处理库引入依赖二、获取 PDF 页数三、获取页面尺寸(宽高)四、获取页面旋转角度五、判断

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

MySQL 获取字符串长度及注意事项

《MySQL获取字符串长度及注意事项》本文通过实例代码给大家介绍MySQL获取字符串长度及注意事项,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql 获取字符串长度详解 核心长度函数对比⚠️ 六大关键注意事项1. 字符编码决定字节长度2

python3如何找到字典的下标index、获取list中指定元素的位置索引

《python3如何找到字典的下标index、获取list中指定元素的位置索引》:本文主要介绍python3如何找到字典的下标index、获取list中指定元素的位置索引问题,具有很好的参考价值,... 目录enumerate()找到字典的下标 index获取list中指定元素的位置索引总结enumerat

SpringMVC高效获取JavaBean对象指南

《SpringMVC高效获取JavaBean对象指南》SpringMVC通过数据绑定自动将请求参数映射到JavaBean,支持表单、URL及JSON数据,需用@ModelAttribute、@Requ... 目录Spring MVC 获取 JavaBean 对象指南核心机制:数据绑定实现步骤1. 定义 Ja

C++中RAII资源获取即初始化

《C++中RAII资源获取即初始化》RAII通过构造/析构自动管理资源生命周期,确保安全释放,本文就来介绍一下C++中的RAII技术及其应用,具有一定的参考价值,感兴趣的可以了解一下... 目录一、核心原理与机制二、标准库中的RAII实现三、自定义RAII类设计原则四、常见应用场景1. 内存管理2. 文件操

SpringBoot服务获取Pod当前IP的两种方案

《SpringBoot服务获取Pod当前IP的两种方案》在Kubernetes集群中,SpringBoot服务获取Pod当前IP的方案主要有两种,通过环境变量注入或通过Java代码动态获取网络接口IP... 目录方案一:通过 Kubernetes Downward API 注入环境变量原理步骤方案二:通过