获得各种视图指针如下P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户
1) 在View中获得Doc指针WWW_PLCJS※COM-PLC-技×术_网(可编程控※制器技术门户)
2) 在App中获得MainFrame指针WWW_PLCJS_COM-PLC-技.术_网
3) 在View中获得MainFrame指针——可——编——程——控-制-器-技——术——门——户
4) 获得View(已建立)指针WWW_PLCJS※COM-PLC-技×术_网(可编程控※制器技术门户)
5) 获得当前文档指针WWW_PLCJS_COM-PLC-技.术_网
6) 获得状态栏与工具栏指针P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户
7) 获得状态栏与工具栏变量WW.W_PLCJS_COM-PLC-技.术_网
8) 在Mainframe获得菜单指针WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)
9) 在任何类中获得应用程序类WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)
10) 从文档类取得视图类的指针(1) WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)
11) 在App中获得文档模板指针WWW_PL※CJS_COM-PLC-技.术_网
12) 从文档模板获得文档类指针WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)
13) 在文档类中获得文档模板指针WWW_PLC※JS_COM-PmLC-技.术_网
14) 从文档类取得视图类的指针(2) WWW_P※LCJS_COM-PLC-)技.术_网
15) 从一个视图类取得另一视图类的指针WWW※PLCJS_COM-PL#C-技.术_网(可编※程控※制器技术门户)
16)获取分割视图中各个视图的指针W1WW_P4LCJS_COM-PLC-技.术_网
WWW※PLCJS_COM-PL#C-技.术_网(可编※程控※制器技术门户)
VC中编程对于刚刚开始学习的同学,最大的障碍和问题就是消息机制和指针获取与操作。其实这些内容基本上是每本VC学习工具书上必讲的内容,而且通过MSDN很多问题都能解决。下面文字主要是个人在编程中指针使用的一些体会,说的不当的地方请指正。WWW_PLCJS@_COM%-PLC-技.术_网
WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)
一般我们使用的框架是VC提供的Wizard生成的MFC App Wizard(exe)框架,无论是多文档还是单文档,都存在指针获取和操作问题。下面这节内容主要是一般的框架,然后再讲多线程中的指针使用。使用到的类需要包含响应的头文件。——可——编——程——控-制-器-技——术——门——户
WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)
首先一般获得本类(视,文档,对话框都支持)实例指针this,用this的目的,主要可以通过类中的函数向其他类或者函数中发指针,以便于在非本类中操作和使用本类中的功能。WWW※PLCJS_COM-PL#C-技.术_网(可编※程控※制器技术门户)
WWW_PLCJS_COM-PLC-技.术_网
1)在View中获得Doc指针plcjs.技.术_网
CYouSDIDoc *pDoc=GetDocument() //一个视只能有一个文档。P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户
2) 在App中获得MainFrame指针W1WW_P4LCJS_COM-PLC-技.术_网
CWinApp 中的 m_pMainWnd变量就是MainFrame的指针也可以:WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)
WWW_PL※CJS_COM-PLC-技.术_网
CMainFrame *pMain =(CMainFrame *)AfxGetMainWnd(); W1WW_P4LCJS_COM-PLC-技.术_网
WWW_PL※CJS_COM-PLC-技.术_网
4) 获得View(已建立)指针WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)
CMainFrame *pMain=(CmaimFrame *)AfxGetApp()->m_pMainWnd; WWW_PLCJ-S_COM-PLC-技.术_网(可-编程控-制器技术-门户)
P.L.C.技.术.网——可编程控制器技术门户
CyouView *pView=(CyouView *)pMain->GetActiveView(); WWW_PL※CJS_COM-PLC-技.术_网
WWW_PL※CJS_COM-PLC-技.术_网
WWW_P※LCJS_COM-PLC-)技.术_网
5) 获得当前文档指针WWW_P※LCJS_CO※M-PLC-技-.术_网
CDocument * pCurrentDoc =(CFrameWnd *)m_pMainWnd->GetActiveDocument();WWW_PLCJ-S_COM-PLC-技.术_网(可-编程控-制器技术-门户)
WW.W_PLCJS_COM-PLC-技.术_网
6) 获得状态栏与工具栏指针WWW_PLCJS@_COM%-PLC-技.术_网
CStatusBar * pStatusBar=(CStatusBar *)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_STATUS_BAR); WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)
WW.W_PLC※JS_C,OM-PL,C-技.术_网
CToolBar * pToolBar=(CtoolBar *)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_TOOLBAR); WWW_PLCJ-S_COM-PLC-技.术_网(可-编程控-制器技术-门户)
WWW_PLCJS@_COM%-PLC-技.术_网
7) 如果框架中加入工具栏和状态栏变量还可以这样WWW_PLC※JS_COM-PmLC-技.术_网
(CMainFrame *)GetParent()->m_wndToolBar; (CMainFrame *)GetParent()->m_wndStatusBar; P.L.C.技.术.网——可编程控制器技术门户
——可——编——程——控-制-器-技——术——门——户
8) 在Mainframe获得菜单指针——可——编——程——控-制-器-技——术——门——户
CMenu *pMenu=m_pMainWnd->GetMenu(); ——可——编——程——控-制-器-技——术——门——户
WW.W_PLCJS_COM-PLC-技.术_网
9) 在任何类中获得应用程序类用MFC全局函数AfxGetApp()获得。WWW_PLCJS※COM-PLC-技×术_网(可编程控※制器技术门户)
WWW_P※LCJS_CO※M-PLC-技-.术_网
10)从文档获得视图类指针目的一般为了控制同一文档的多个视图的定位问题,我的体会特别是文字处理CEditView当产生多个视图类时,这个功能是非常需要的。WWW_PLCJS※COM-PLC-技×术_网(可编程控※制器技术门户)
W1WW_P4LCJS_COM-PLC-技.术_网
CDocument类提供了两个函数用于视图类的定位: GetFirstViewPosition()和GetNextView()WWW_PLCJS_COM-PLC-技.术_网
WWW_PLCJS_COM-PLC-技.术_网
virtual POSITION GetFirstViewPosition() const; virtual CView* GetNextView(POSITION& rPosition) const; P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户
——可——编——程——控-制-器-技——术——门——户
注意:GetNextView()括号中的参数用的是引用方式,因此执行后值可能改变。 GetFirstViewPosition()用于返回第一个视图位置(返回的并非视图类指针,而是一个POSITION类型值),GetNextView()有两个功能:返回下一个视图类的指针以及用引用调用的方式来改变传入的POSITION类型参数的值。很明显,在Test程序中,只有一个视图类,因此只需将这两个函数调用一次即可得到CTestView的指针如下(需定义一个POSITION结构变量来辅助操作):WWW.PLCJS.COM——可编程控制器技术门户
P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户
CTestView* pTestView; W1WW_P4LCJS_COM-PLC-技.术_网
WWW_P※LCJS_CO※M-PLC-技-.术_网
POSITION pos=GetFirstViewPosition(); WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)
WWW_PLC※JS_COM-PmLC-技.术_网
pTestView=GetNextView(pos); P.L.C.技.术.网——可编程控制器技术门户
P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户
这样,便可到了CTestView类的指针pTestView.执行完几句后,变量pos=NULL,因为没有下一个视图类,自然也没有下一个视图类的POSITION.但是这几条语句太简单,不具有太强的通用性和安全特征;当象前面说的那样,当要在多个视图为中返回某个指定类的指针时,我们需要遍历所有视图类,直到找到指定类为止。判断一个类指针指向的是否某个类的实例时,可用IsKindOf()成员函数时行检查,如: pView->IsKindOf(RUNTIME_CLASS(CTestView)); 即可检查pView所指是否是CTestView类。有了以上基础,我们已经可以从文档类取得任何类的指针。为了方便,我们将其作为一个文档类的成员函数,它有一个参数,表示要获得哪个类的指针。WWcW_PLCJS_COM-PLC-技.术_网
P.L.C.技.术.网——可编程控制器技术门户
实现如下:plcjs.技.术_网
WWW_PLC※JS_COM-PmLC-技.术_网
CView* CTestDoc::GetView(CRuntimeClass* pClass) WWW_PLCJS@_COM%-PLC-技.术_网
WWW_PLCJS※COM-PLC-技×术_网(可编程控※制器技术门户)
{ CView* pView; POSITION pos=GetFirstViewPosition(); while(pos!=NULL)WWW.PLCJS.COM——可编程控制器技术门户
WWW_PLCJS※COM-PLC-技×术_网(可编程控※制器技术门户)
{ pView=GetNextView(pos); if(!pView->IsKindOf(pClass)) break; } if(!pView-WWW_PLCJ-S_COM-PLC-技.术_网(可-编程控-制器技术-门户)
WW.W_PLCJS_COM-PLC-技.术_网
>IsKindOf(pClass)){ AfxMessageBox("Connt Locate the View.\r\n http://www.VCKBASE.com"); return NULL; } return pView; } WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)
WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)
其中用了两次视图类的成员WWW.PLCJS.COM——可编程控制器技术门户
WWW_P※LCJS_CO※M-PLC-技-.术_网
函数IsKindOf()来判断,是因为退出while循环有三种可能:WWW※PLCJS_COM-PL#C-技.术_网(可编※程控※制器技术门户)
WWW_P※LCJS_COM-PLC-)技.术_网
1.pos为NULL,即已经不存在下一个视图类供操作;WWW_PLCJ-S_COM-PLC-技.术_网(可-编程控-制器技术-门户)
WWW.PLCJS.COM——可编程控制器技术门户
2.pView已符合要求。WWW_PLCJ-S_COM-PLC-技.术_网(可-编程控-制器技术-门户)
WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)
1和2同是满足。这是因为GetNextView()的功能是将当前视图指针改变成一个视图的位置同时返回当前视图指针,因此pos是pView的下一个视图类的POSITION,完全有可能既是pos==NULL又是pView符合需要。当所需的视图是最后一个视图是最后一个视图类时就如引。因此需采用两次判断。使用该函数应遵循如下格式(以取得CTestView指针为例):WWW_P※LCJS_CO※M-PLC-技-.术_网
——可——编——程——控-制-器-技——术——门——户
CTestView* pTestView=(CTestView*)GetView(RUNTIME_CLASS(CTestView)); plcjs.技.术_网
W1WW_P4LCJS_COM-PLC-技.术_网
RUNTIME_CLASS是一个宏,可以简单地理解它的作用:将类的名字转化为CRuntimeClass为指针。至于强制类型转换也是为了安全特性考虑的,因为从同一个基类之间的指针类型是互相兼容的。这种强制类型转换也许并不必要,但能避免一些可能出现的麻烦。WWW_PLCJS※COM-PLC-技×术_网(可编程控※制器技术门户)
WWW_PL※CJS_COM-PLC-技.术_网
3.从一个视图类取得另一视图类的指针综合1和2,很容易得出视图类之间互相获得指针的方法:就是用文档类作中转,先用1的方法得到文档类的指针,再用2的方法,以文档类的视图定位函数取得另一个视图类。同样,可以实现成一个函数:(假设要从CTestA V i ew中取得指向其它视图类的指针)WW.W_PLCJS_COM-PLC-技.术_网
WWW.PLCJS.COM——可编程控制器技术门户
CView* CTestA V i ew::GetView(CRuntimeClass* pClass) { WWW_PL※CJS_COM-PLC-技.术_网
WWW_PLCJS_COM-PLC-技.术_网
CTestDoc* pDoc=(CTestDoc*)GetDocument(); P.L.C.技.术.网——可编程控制器技术门户
WWcW_PLCJS_COM-PLC-技.术_网
CView* pView; POSITION pos=pDoc->GetFirstViewPosition(); WWW.PLCJS.COM——可编程控制器技术门户
WWW_PL※CJS_COM-PLC-技.术_网
while(pos!=NULL)WWW※PLCJS_COM-PL#C-技.术_网(可编※程控※制器技术门户)
WWW_PLCJS_COM-PLC-技.术_网
{ WW.W_PLC※JS_C,OM-PL,C-技.术_网
WWW_PLC※JS_COM-PmLC-技.术_网
pView=pDoc->GetNextView(pos); WWW_PLCJS※COM-PLC-技×术_网(可编程控※制器技术门户)
WWW_PLC※JS_COM-PmLC-技.术_网
if(!pView->IsKindOf(pClass)) break; WWcW_PLCJS_COM-PLC-技.术_网
WWW_P※LCJS_COM-PLC-)技.术_网
}WWW_PL※CJS_COM-PLC-技.术_网
P.L.C.技.术.网——可编程控制器技术门户
if(!pView->IsKindOf(pClass))WWW.PLCJS.COM——可编程控制器技术门户
WWW.PLCJS.COM——可编程控制器技术门户
{ ——可——编——程——控-制-器-技——术——门——户
WW.W_PLCJS_COM-PLC-技.术_网
AfxMessageBox("Connt Locate the View."); WWW_PLCJ-S_COM-PLC-技.术_网(可-编程控-制器技术-门户)
WWW※PLCJS_COM-PL#C-技.术_网(可编※程控※制器技术门户)
return NULL; P.L.C.技.术.网——可编程控制器技术门户
WWW_PLCJS@_COM%-PLC-技.术_网
} WWW_P※LCJS_CO※M-PLC-技-.术_网
WWW_P※LCJS_CO※M-PLC-技-.术_网
return pView; plcjs.技.术_网
——可——编——程——控-制-器-技——术——门——户
} WW.W_PLCJS_COM-PLC-技.术_网
P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户
这个函数和2中的GetView()相比,一是多了第一句以取得文档类指针,二是在GetFirstViewPosition()和GetNextView()前加上了文档类指针,以表示它们是文档类成员函数。有了此函数;当要从CTestA V i ew中取得CTestBView的指针时,只需如下:CTestBView* pTestbView=(CTestView*)GetView(RUNTIME_CLASS(CTestBView)); WWW_PLCJS@_COM%-PLC-技.术_网
WWW※PLCJS_COM-PL#C-技.术_网(可编※程控※制器技术门户)
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。WWW_PLCJ-S_COM-PLC-技.术_网(可-编程控-制器技术-门户)
WWW_PL※CJS_COM-PLC-技.术_网
12)一个文档模板可以有多个文档,每个文档模板都保留并维护了一个所有对应文档的指针列表。用CDocTemplate::GetFirstDocPosition函数获得与文档模板相关的文档集合中第一个文档的位置,并用POSITION值作为CDocTemplate::GetNextDoc的参数来重复遍历与模板相关的文档列表。函数原形为: viaual POSITION GetFirstDocPosition( ) const = 0; visual CDocument *GetNextDoc(POSITION & rPos) const = 0; 如果列表为空,则rPos被置为NULL. P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户
plcjs.技.术_网
13)在文档中可以调用CDocument::GetDocTemplate获得指向该文档模板的指针。函数原形如下: CDocTemplate * GetDocTemplate ( ) const; 如果该文档不属于文档模板管理,则返回值为NULL。W1WW_P4LCJS_COM-PLC-技.术_网
P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户
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.plcjs.技.术_网
WWW_PL※CJS_COM-PLC-技.术_网
15)从一个视图类取得另一视图类的指针这个应用在多视的应用程序中很多见,一般如果自己在主程序或者主框架中做好变量记号,也可以获得,还有比较通用的就是用文档类作中转,以文档类的视图遍历定位,取得另一个视图类。这个功能从本文第10项中可以得到。WW.W_PLC※JS_C,OM-PL,C-技.术_网
P.L.C.技.术.网——可编程控制器技术门户
16)获取分割视图中各个视图的指针WW.W_PLCJS_COM-PLC-技.术_网
WWW_PLCJS_COM-PLC-技.术_网
CSplitterWnd m_wndSplitter;WWW_PLCJS_COM-PLC-技.术_网
WW.W_PLCJS_COM-PLC-技.术_网
m_wndSplitter.CreateStatic(this, 1, 2);//分割成一行两列WWcW_PLCJS_COM-PLC-技.术_网
WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)
m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CLeftPaneView), CSize(10, 10), pContext);WWW.PLCJS.COM——可编程控制器技术门户
WWW_P※LCJS_COM-PLC-)技.术_网
m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CRightPaneFrame), CSize(0, 0), pContext); //获取左边视图的两种方法WWW.PLCJS.COM——可编程控制器技术门户
WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)
CLeftPaneView* pLeftPaneView = (CLeftPaneView*) m_wndSplitter.GetPane(0,0); //上一句可以用下句代替: //P.L.C.技.术.网——可编程控制器技术门户
W1WW_P4LCJS_COM-PLC-技.术_网
CLeftPaneView* pLeftPaneView = (CLeftPaneView *)GetActiveView(); //获取右边视图P.L.C.技.术.网——可编程控制器技术门户
WWW.PLCJS.COM——可编程控制器技术门户
pLeftPaneView->m_pRightPaneFrame = (CRightPaneFrame*) m_wndSplitter.GetPane(0,1); plcjs.技.术_网
WWcW_PLCJS_COM-PLC-技.术_网
在View中获得MainFrame指针——可——编——程——控-制-器-技——术——门——户
CMainFrame *pMain=(CmaimFrame *)AfxGetApp()->m_pMainWnd; or ((CMainFrame *)GetParent())->