MFC应用程序中指针的使用

MFC应用程序中指针的使用  
   
  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.\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,(如下四个内容(十一、十二、1三、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。  
   
    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)从一个视图类取得另外一视图类的指针  
  这个应用在多视的应用程序中不少见,通常若是本身在主程序或者主框架中作好变  
  量记号,也能够得到,还有比较通用的就是用文档类做中转,以文档类的视图遍历  
  定位,取得另外一个视图类。这个功能从本文第10项中能够获得。
 

 _______________________________________________________________html

  访问应用程序的其它类  
   
  得到CWinApp:  
  -在CMainFrame,CChildFrame,CDocument,CView中直接调用AfxGetApp()或用theApp  
  -在其它类中只能用AfxGetApp()  
   
  得到CMainFrame:  
  -在CMinApp中用AfxGetMainWnd()或者m_pMainWnd  
  -在CChildFrame中可用GetParentFrame()  
  -在其它类中用AfxGetMainWnd()  
   
  得到CChildFrame:  
  -在CView中用GetParentFrame()  
  -在CMainFrame中用MDIGetActive()或GetActiveFrame()  
  -在其它类中用AfxGetMainWnd()->MDIGetActive()或AfxGetMainWnd()->GetActiveFrame()  
   
  得到CDocument:  
  -在CView中用GetDocument()  
  -在CChildFrame中用GetActiveView()->GetDocument()  
  -在CMainFrame中用  
  -if   SDI:GetActiveView()->GetDocument()  
  -if   MDI:MDIGetActive()->GetActiveView()->GetDocument()  
  -在其它类中  
  -if   SDI:AfxGetMainWnd()->GetActiveView()->GetDocument()  
  -if   MDI:AfxGetMainWnd()->MDIGetActive()->GetActiveView()->GetDocument()  
   
  得到CView:  
  -在CDocument中   POSITION   pos   =   GetFirstViewPosition();GetNextView(pos)  
  -在CChildFrame中   GetActiveView()  
  -在CMainFrame中  
  -if   SDI:GetActiveView()  
  -if   MDI:MDIGetActive()->GetActiveView()  
  -在其它类中  
  -if   SDI:AfxGetMainWnd()->GetActiveView()  
  -if   MDI:AfxGetMainWnd()->MDIGetActive()->GetActiveView()程序员

相关文章
相关标签/搜索