MFC初学者:MFC程序中类之间的相互访问的常规方法。

         这是本人在学习MFC的过程中整理的,其实就是一小篇学习笔记,算不得什么文章,共享出来只是希望能够给那些MFC初学者一点点帮助,并且希望得到老鸟们的指正。呵呵,闲话不说进入正文。
         基于文档-视图结构的应用程序,可以将数据从用户对数据的观察中分离起来。在此类应用程序中,数据一般放在文档类中,而应用的显示一般由视图视图类负责。以显示图像为例,图像的数据存放在文档类中,要在试图类中显示图像则要获得文档类中的数据。如果利用AppWizard创建的应用程序,在视图类中有一个GetDocument()的成员函数可以获得文档类的指针,利用文档类的指针就可以获得文档类的数据。但在MFC程序中类之间变量的互相访问并不仅限于此,以多文档界面应用程序为例,程序中主要包含试图类 、文档类、 MDI子框架类 、MDI父框架类和应用类。另外还有用户生成的其他对话框类等等。如何实现这些类之间的变量的互相访问,是MFC编程初学者应该要搞懂的问题,也是本文要讨论的问题。

         一般来说,要想在一个类中访问到另外一个类中的变量(Public),最容易想到的就是得到想要访问类的指针。想要访问类的指针的获取一般采用的方法是利用特定的全局API函数和各个类(访问类)提供的成员函数。在获取特定类指针的函数中最主要的两个函数就是:获取应用类指针的AfxGetApp()函数和获取主框架类指针的AfxGetMainWnd()函数。只要灵活的应用好这两个函数,遍基本上就可以实现类之间变量的相互访问。具体讨论如下:
1.主框架类访问其他类变量的方法
可以用函数AfxGetApp()获取应用类的指针,代码如下:
CClass***App *m_pApp=(CClass***App *)AfxGetApp();
为了获取当前活动的子框架类的指针,主框架类主要提供了两个成员函数:MDIGetActive()和GetActiveFrame().两个函数应用的代码如下:
CChildFrame *m_pChildFrm=(CChildFrame *)MDIGetActive();
CChildFrame *m_pChildFrm=(CChildFrame *)GetActiveFrame();
获得子框架类的指针,就可以用子框架类提供的两个成员函数GetActiveDocument()和GetActiveView()函数来获取当前活动的文档类和视图类的指针。代码如下:
CClass***Doc *m_pDoc=(CClass***Doc *)m_pChildFrm->GetActiveDocument();
CClass***View *m_pView=(CClass***View *)m_pChildFrm->GetActiveView();
2.应用类访问其他类变量的方法
由上面的介绍可以知道,只要获取了主框架类的指针,其余子框架类 文档类 视图类的指针就可以获取。一种获取主框架类指针的方法就是使用AfxGetMainWnd()函数,代码如下:
CMainFrame *m_pMianFrm=(CMainFrame *)AfxGetMainWnd();
另外,我们知道应用类中有一个CWnd*类型的没m_pMainWnd变量,用来存放应用程序主框架类的指针。因此利用它同样可以获取主框架类的指针,代码如下:
CMainFrame *m_pMainFrm = (CMainFrame *)m_pMainWnd;
余下的就可以参考1了。
3.子框架类访问其他类的方法
获得应用程序类和主框架类的指针可以用全局函数AfxGetApp()和AfxGetMainWnd(),获取文档类和视图类的指针可以用其成员函数GetActiveDocument()和GetActiveView(),具体代码可以参考上面两条。
4.视图类访问其他类的方法
获得应用程序类和主框架类的指针可以用全局函数AfxGetApp()和AfxGetMainWnd(),获取子框架类指针可以用其成员函数GetParent()来完成,代码如下:
CChildFrame *m_pChildFrm=(CChildFrame *)GetParent();
获取文档类指针可以间接用子框架类的成员函数GetActiveDocument()来进行,但是从效率的角度出发最好用视图类的成员函数GetDocument()来完成。
5.文档类访问其他类的方法
获得应用程序类和主框架类的指针可以用全局函数AfxGetApp()和AfxGetMainWnd(),获得子框架类可以通过主框架类的成员函数GetActiveFrame()来间接获得。在许多应用程序中,获得视图类中的变量是比较重要的,如保存鼠标的位置,选择区域的大小及位置等。由于一个文档类可以对应多个视图类,因此文档类有一个CPtrList类型的变量m_viewList来保存多个视图类的指针,并且提供了两个成员函数:
GetFirstViewPosition()和GetNextView()来访问对应视图类的指针。
下面就给出两种种可以获得视图类指针的方法。
方法一:间接通过子框架的成员函数GetActiveView()来完成。
方法二:应用文档类的GetFirstViewPosition()和GetNextView()来完成,具体代码如下:
POSITION pos=GetFirstViewPositon();//获得并保存第一个视图类的指针的位置
CClass***View *m_pView=(CClass***View *)GetNextView(pos);//获得第一个视图类的指针,位置变量pos向下移向下一个视图类的指针
如果是单视图的情况,则第一次调用GetNextView()即可获得视图类的指针,若是多个视图类则可以用while循环语句配合MFC基类中的IsKindOf()来识别出所需要的视图指针。代码如下:
CWantView *m_pWantView;//想要获取的视图类的指针变量
CView *lpView;//临时的视图类指针
POSITION pos=GetFirstViewPositon();//获得并保存第一个视图类的指针的位置
while(pos!=NULL)
{
 lpView=GetNextView(pos);//获得第一个视图类的指针,位置变量pos向下移向下一个视图类的指针
 if(lpView->IsKindOf(RUNTIME_CLASS(CWantView)))//判断是否为指向所要类的指针
 {
  m_pWantView=(CWantView *)lpView;//得到想要类的指针
 }
}
提醒一点在文档类头文件中类的定义前面,增加CView类的说明class CClass***View;如果没有预先说明,编译时会出现麻烦,因为不这样做,会引起循环包含。类说明避免不必要的#include指令,但是它津津适合类指针。
6.其他类访问上述类的方法
大多数应用程序中除了上述常见的几个类,还有很多不同对话框类,对话条类等,有时候这些类同样需要文档类的数据,视图类的鼠标位置、 图像的滚动大小等信息。综上所述,只要用全局函数AfxGetApp()和AfxGetMainWnd()获得了应用类和主框架类的指针,就可以获得活动的子框架类的指针,进而文档类和视图类的指针也可以很方便的获得。
下面给出一个应用上面方法的简单的例子。我们知道对于一个多文档的应用程序,如果打开的子窗口比较的多,而有时候想把这些子窗口一下子全部关闭,利用主框架类的MDIGetActive()函数就可以达到目的。具体的方法就是:添加一个菜单,将消息映射函数映射到主框架类中,在该消息的映射函数中就可以加入如下的代码就可以实现将子窗口全部关闭的功能。
CMIChildWnd *pChild;
while((pChild=MDIGetActive())!=NULL)
{
 pChild->SendMessage(WM_CLOSE);
}
上面就是一些类之间变量互相访问常常采用的方法,注意定义指针变量一定要把相应的类定义的头文件包含进来,否则编译会出错。
当然类之间变量互相访问除了上述的常规方法外,还有很多非常规的方法,比如静态变量,全局变量等等。这些我还正在学习整理中,整理好了就共享给大家看看。

你可能感兴趣的:(MFC初学者:MFC程序中类之间的相互访问的常规方法。)