在MFC类中各种类的指针的获取和应用 (2)

news/2024/7/8 11:44:30


 关于MFC下的文档和视图以及框架之间的访问, 这些问题已经是老生常谈了,但我觉得还是都没有详细的说明,特
  
  别是对于英语较差的人,我查看了一些blog,总结了一下!希望对和我一样的人有点帮助!
  
  1:  因为对于SDI程序,主框架窗口就是文档框窗(如果这个也不知道,就要查看一下MFC下的单文档的构成原理了).
  下面所说的是关于单文档的.
  
  例子: 在CMainFrame框架中如何得到视图类的指针.
  可以 先得到框架指针,然后调用 GetActiveView 函数指向当前活动视.
  
  C **View * pView;
  pView=(C**View*)((CFrameWnd*)AfxGetApp()->m_pMainWnd)->GetActiveView();
  
  当然这些也许都知道是这么用的,但真正的m_pMainWnd和AfxGetApp()是什么意思也许有的人不明白.
  大家也许都知道如何在App中获得MainFrame指针(框架类): CWinApp 中的 m_pMainWnd变量就是CMainFrame的指针.
  
  所以在别的类下也可以先得到m_pMainWnd,就得到了MainFrame的指针. 所以得到视图类的指针,必先 得到CFrameWnd的指针m_pMainWnd,然后在调用FrameWnd下的GetActiveView 就指向当前活动视.
  m_pMainWnd的由来:
  每一个MFC应用程序都有一个CWinApp派生类的对象。这个对象对应着程序的主线程。而 CWinApp 类中有一个 CWnd * m_pMainWnd 成员变量。这个成员变量记录了应用程序的主窗口。
  当你新建一个MFC应用程序的时候,在 InitInstance虚函数里都会出现对 m_pMainWnd 赋值的语句.唯一的例外是单文档界面的MFC应用程序,你无法在 InitInstance 函数里看到这段代码,因为它已经被隐藏在 ProcessShellCommand 这个函数里了。由此你就可以下结论了:只要创建自己的窗口类,就要把这个类的对象赋值给 m_pMainWnd .而这个成员只能在C**APP类中才可以使用,所以怎样使用这个CWinApp类里的CWnd 类型的变量来得到主框架窗口的指针呢??
  AfxGetApp函数才可以 , 因为AfxGetApp()得到的是CWinApp类的对象,且AfxGetApp返回值为CWinApp对象指针,就是MFC生成的C**App.cpp中定义的那个对象(对象theApp的指针)。
  
  因为你是在自己创建的项目中得到CWndApp成员函数或者成员变量,所以你必须强制转换为你自己的项目中的类,才能找到成员函数或者变量.
  注: 在单文档中,获得视指针的最简单的方法还是
  ((C**View *)CFrameWnd::GetActiveView())
  
  2:   当然在FrameWnd中也可以得到文档类的指针:
  CMyDocument* pDoc;
  pDoc=(CMyDocument*)((CFrameWnd*)AfxGetApp()->m_pMainWnd)->GetActiveDocument();
  
  3:   由上面可以知道:在View中怎样获得MainFrame指针
  CMainFrame *pMain=(CMainFrame *)AfxGetApp()->m_pMainWnd;
  
  注: 从视图类中获得主帧窗口类指针:用函数:CWnd::GetParentFrame()或AfxGetMainWnd()也
  可达到目的。GetParentFrame()的工作原理是在父窗口链中搜索,直到找到CFrameWnd或其派生类为止,并返回其指针。
  
  ((CMainFrame *)CWnd::GetParentFrame())
  或者
  ((CMainFrame *)AfxGetMainWnd())
  
  当然对于MDI程序,由于子窗口才是文档框窗,因此首先要用GetActiveFrame()取得活动子框架窗口,然后通过该子窗口获取活动视图和文档:
  
  CMDIChildWnd* pChild=(CMDIChildWnd*)((CFrameWnd*)AfxGetApp()->m_pMainWnd)-
  
  >GetActiveFrame();
  
  取得活动视图:
  CMyView* pView=(CMyView*)pChild->GetActiveView();
  
  取得活动文档:
  CMyDocument* pDoc=pChild->GetActiveDocument();
  
  注: 也可以用这种方法来得到多文档中的视指针
  //获得活动子框架窗口
  CMDIChildWnd* pChild=(CMDIChildWnd*)GetActiveFrame();
  //或:
  CMDIChildWnd* pChild=MDIGetActive();
  //获得活动子帧窗口的活动视图
  CMyView* pView=(CMyView*)pChild->GetActiveView();
  
  1.  从视图类获得文档类的指针
  在视图类中需要引用文档类的地方之前,使用以下语句:
  C*Doc *pDoc=(C*Doc*)GetDocument();
  以后便可使用pDoc指针访问文档类。
  2.  从文档类取得视图类的指针 CDocument类提供了两个函数用于视图类的定位:
  
  GetFirstViewPosition()和GetNextView()
  
  注意:GetNextView()括号中的参数用的是引用方式,因此执行后值可能改变.GetFirstViewPosition()用于
  
  返回第一个视图位置(返回的并非视图类指针,而是一个POSITION类型值),GetNextView()有两个功能:返回下一个视图类的指针以及用引用调动的方式来改变传入的POSITION类型参数的值。很明显,在Test程序中,只有一个视图类,因此只需将这两个函数调用一次即可得到CTestView的指针如下(需定义一个POSITION结构变量来辅助操作):
  
  C*View* pView;
  POSITION pos=GetFirstViewPosition();
  pView=GetNextView(pos);
  
  这样,便可到了C*View类的指针pView.执行完成几句后,变量pos=NULL,因为没有下一个视图类,自然也没有下一个视图类的POSITION.但是之几条语句太简单,不具有太强的通用性和安全特征;当象前面说的那样,当要在多个视图为中返回某个指定类的指针时,我们需要遍历所有视图类,直到找到指定类为止。判断一个类指针指向的是否某个类的实例时,可用IsKindOf()成员函数时行检查.
  
  如:
  pView->IsKindOf(RUNTIME_CLASS(C*View));
  即可检查pView所指是否是C*View类。
  有了以上基础,我们已经可以从文档类取得任何类的指针。为了方便,我们将其作为一个文档类的成员函数,它有一个参数,表示要获得哪个类的指针。实现如下:
  CView* C*Doc::GetVieww(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.");
  return NULL;}
  return pView;}
  其中用了两次视图类的成员函数IsKindOf()来判断,是因为退出while循环有三种可能:
  1.pos为NULL,即已经不存在下一个视图类供操作;
  2.pView已符合要求。
  3.1和2同是满足。这是因为GetNextView()的功能是将当前视图指针改变成一个视图的位置同时返回当前视图指针,因此pos是pView的下一个视图类的POSITION,完全有可能既是pos==NULL又是pView符合需要。当所需的视图是最后
  
  一个视图是最后一个视图类时就如引。因此需采用两次判断。
  使用该函数应遵循如下格式(以取得CTestView指针为例):
  CTestView* pTestView=(CTestView*)GetView(RUNTIME_CLASS(CTestView));
  RUNTIME_CLASS是一个宏,可以简单地理解它的作用:将类的名字转化为CRuntimeClass为指针。
  至于强制类型转换也是为了安全特性考虑的,因为从同一个基类之间的指针类型是互相兼容的。这种强制类型转换也许并不必要,但能避免一些可能出现的麻烦。  

 


http://www.niftyadmin.cn/n/1997374.html

相关文章

零元学Expression Design 4 - Chapter 3 看小光被包围了!!如何活用「Text On Path」设计效果...

原文:零元学Expression Design 4 - Chapter 3 看小光被包围了!!如何活用「Text On Path」设计效果本章将教大家如何活用「Text On Path」,做出文绕图以及文字线性排列的效果 也可以学到如何使用Polyline以及B-Spline ? 本章将教大家如何活用「Text On Path」&#…

关于CString

关于CString 通过阅读本文你可以学习如何有效地使用 CString。  CString 是一种很有用的数据类型。它们很大程度上简化了MFC中的许多操作,使得MFC在做字符串操作的时候方便了很多。不管怎样,使用CString有很多特殊的技巧,特别是对于纯C背景…

iOS__Cocoapods 安装第三方框架 pod install 报Generating Pods project Abort trap

在开发iOS程序经常会使用到第三方开源的框架,在是使用Cocoapods时,如果遇到pod install 报如下错误: $ pod install Generating Pods project Abort trap: 6 复制代码 ####解决办法: 1.首先需要执行如下命令 (注意:一个一个的执行,且每个命令都要执行) sudo gem uninstall coc…

matlab 把数存入数组,求助:如何将带有符号变量的运算结果储存到数组中

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼问题:在使用 MATLAB 去做 Nevilles Algorithm 的时候,因为要涉及到参数(符号变量)的保存,所以要把运算结果储存到一个数组当中。代码如下:% num of interpolation points and curve f…

php技术的概念特点,基本概念

## **class**每个类的定义都以关键字class开头,后面跟着类名,后面跟着一对花括号,里面包含有类的属性与方法的定义。类名可以是任何非 PHP[保留字](https://www.php.net/manual/zh/reserved.php)的合法标签。一个合法类名以字母或下划线开头&…

python存入mysql数据库乱码_Python中MYSQLdb出现乱码的解决方法

本文实例讲述了Python中MYSQLdb出现乱码的解决方法,分享给大家供大家参考。具体方法如下:一般来说,在使用mysql最麻烦的问题在于乱码。查看mysql的编码:命令:show variables like character_set_%;可以看到如下结果&am…

Visual C++(包含Windows API和MFC)开发中常见问题的答案

Visual C(包含Windows API和MFC)开发中常见问题的答案 1.简述VC6下如何进行程序的调试。在主菜单"Build"中,有一个Start Build的子菜单,它下面包含了Go菜单(快捷键为F5),选择后,程序将从当前语句…

《js随机数》系列技术文章整理

《js随机数》系列技术文章整理收藏,希望大家能用得上,大家喜欢就点个赞吧。1、js生成随机颜色值http://www.512pic.com/174/2101-0.html 2、js生成不重复的随机数http://www.512pic.com/174/2098-0.html 3、js生成随机整数http://www.512pic.com/174/209…