各种类和视图之间相互调用的总结

转载 2013年12月02日 18:51:49

转自:http://blog.163.com/qiang_zx/blog/static/43219342010826125993/

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) 从文档类取得视图类的指针
我是从http://download.cqcnc.com/soft/program/article/vc/vc405.html学到的,从文档获得视图类指针目的一般为了控制同一文档的多个视图的定位问题,我的体会特别是文字处理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. 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)来源:http://sanjianxia.myrice.com/vc/vc45.htm

可以用CWinApp::GetFirstDocTemplatePostion获得应用程序注册的第一个文档模板的位置;
利用该值来调用CWinApp::GetNextDocTemplate函数,获得第一个CDocTemplate对象指针。 POSITION GetFirstDocTemplate( ) const; 
CDocTemplate *GetNextDocTemplate( POSITION & pos ) const;

第二个函数返回由pos 标识的文档模板。POSITION是MFC定义的一个用于迭代或对象指针检索的值。通过这两个函数,应用程序可以遍历整个文档模板列表。如果被检索的文档模板是模板列表中的最后一个,则pos参数被置为NULL。


相关文章推荐

各种类和视图之间相互调用的总结

各种类和视图之间相互调用的总结 1) 在View中获得Doc指 针 2) 在App中获得MainFrame指针 3) 在View中获得MainFrame指针 4) 获得View...

文档、视图、框架窗口、文档模板之间的相互关系

要了解 文档、视图、框架窗口、文档模板之间的相互关系,关键要理解他们的结构 1、首先应该对 CWinApp类有充分的了解 它包含并管理着应用程序的文档/视窗的所有信息。它有一个成员变量 ...

文档、视图、框架窗口、文档模板之间的相互关系

1) 在View中获得Doc指针 2) 在App中获得MainFrame指针 3) 在View中获得MainFrame指针 4) 获得View(已建立)指针 5) 获得当前文档指针 6) 获...
  • fly_q
  • fly_q
  • 2011年04月09日 10:24
  • 404

SpringMVC——Controller和视图之间数据的相互传递

Spring接收请求参数的三种方法:1.使用HttpServletRequest获取@RequestMapping("/login.do") public String login(HttpSer...

MFC中文档/视图类结构内的相互调用方法总结

1) 在View中获得Doc指 针 2) 在App中获得MainFrame指针 3) 在View中获得MainFrame指针 4) 获得View(已建立)指针 5) 获得当前文档指针 6) ...
  • ROVAST
  • ROVAST
  • 2014年04月24日 15:19
  • 815

多Activity之间相互调用方法总结

本文对多个Activity之间的相互调用做个z

mfc与duilib之间控件相互调用

  • 2017年06月04日 22:04
  • 3MB
  • 下载

框架、文档、视图类之间的调用关系

在多文档MFC应用程序执行过程中,创建了多于一个的文档类、视图类、子框架类对象和一个主框架类、应用类对象。这些对象之间是通过一定的方式联系在一起的,在应用程序设计中,时常需要通过这些对象之间的关系来实...
  • whatday
  • whatday
  • 2012年04月22日 12:49
  • 1039
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:各种类和视图之间相互调用的总结
举报原因:
原因补充:

(最多只允许输入30个字)