當前位置:編程學習大全網 - 編程語言 - 如何在c++mdi可視化類中獲取活動的可視化指針

如何在c++mdi可視化類中獲取活動的可視化指針

用VC++的應用程序向導生成CDialog Basic以外的應用程序時,會自動生成視圖類、文檔類、主框架窗口類、應用程序類等。壹般來說,程序的核心數據和操作都是在文檔類中實現的。與接口相關的數據和操作在視圖類中實現。當您需要使用不屬於某個類的數據時,您必須獲得壹個指向該數據所屬的類的指針。從view類中獲取document類的指針很簡單,用GetDocument就可以了,壹般MFC文檔中都有介紹,也是編程中很常見的操作。例如,在重繪視圖類時,經常會用到文檔類中的數據。但是,僅僅從視圖類中獲取文檔類的指針是不夠的。每個類都有壹組獲取其他類指針的方法,總結如下:

為了便於解釋,假設SDI應用測試已經由應用向導生成,包括諸如CT ESTAPP、CT ESTDoc、CT ESTView、CMAIN FRM之類的類。

1.從視圖類中獲取文檔類的指針。

如前所述,在需要引用視圖類中的文檔類之前,使用以下語句:

CTextDoc * pDoc =(CTestDoc *)get document();

以後可以使用pDoc指針來訪問文檔類。

這裏的強制類型轉換在測試應用中是沒有必要的,因為程序中只有壹個view類,而且是用Initstance()中的SDI文檔模板組裝的。您可以在Test.cpp的Initstance()方法中看到以下語句:

CSingleDocTemplate * PDO template;

pDocTemplate = new CSingleDocTemplate(IDR _ MAINFRAME,RUNTIME_CLASS(CTestDoc),RUNTIME_CLASS(CMainFrame),

RUNTIME _ CLASS(ctest view));

AddDocTemplate(pDocTemplate);

以及TestView.h中的在線定義:

內聯CTestDoc * ctest view::get document()

{ return(CTestDoc *)m _ p document;}

簡而言之,CTestView的GetDocument()函數很自然地認為CTestDoc與之“匹配”。當生成具有多個視圖類的應用程序時(例如,使用CSplitterWnd),窗口被分成兩列,但這兩列不是從同壹個視圖類派生的,情況就是這樣。具體實現不在本文討論範圍內),壹個視圖類只能和壹個唯壹的文檔類用壹個文檔模板組裝,所以需要強制類型轉換,才能獲得另壹個未組裝類中文檔類的指針。

2.從文檔類中獲取壹個指向視圖類的指針。

CDocument類提供了兩個定位視圖類的函數:GetFirstViewPosition()和GetNextView()。具體語法如下:

虛擬位置GetFirstViewPosition()const;

虛擬CView* GetNextView(位置& ampr position)const;

註意:引用了GetNextView()括號中的參數,所以執行後值可能會改變。

GetFirstViewPosition()用於返回第壹個視圖位置(不是視圖類指針,而是返回壹個位置類型值),GetNextView()有兩個作用:返回下壹個視圖類的指針,通過引用傳遞改變傳遞的位置類型參數的值。很明顯,在測試程序中,只有壹個view類,所以只需要調用這兩個函數壹次就可以得到CTestView的指針如下(需要定義壹個POSITION結構變量來輔助操作):

CTestView * pTestView

POSITION pos = GetFirstViewPosition();

ptest view = get next view(pos);

這樣我們就可以得到CTestView類的指針pTestView。執行幾句後,變量pos=NULL,因為沒有下壹個視圖類,自然也就沒有下壹個視圖類的位置。

但有幾句過於簡單,不具備很強的通用性和安全特性;如前所述,當我們想要在多個視圖中返回指向指定類的指針時,我們需要遍歷所有視圖類,直到找到指定的類。在判斷類指針是否指向類的實例時,可以使用IsKindOf()成員函數來檢查時間線,比如:

pView-& gt;IsKindOf(RUNTIME _ CLASS(ctest view));

可以檢查pView是否引用了CTestView類。

有了上面的基礎,我們已經可以從document類獲得指向任何類的指針了。為了方便起見,我們把它看作壹個文檔類的成員函數,它有壹個參數指示要獲取指向哪個類的指針。實現如下:

CView * CTestDoc::GetVieww(CRuntimeClass * pClass)

{ CView * pView

POSITION pos = GetFirstViewPosition();

while(pos!=空)

{

pView = get next view(pos);

if(pView-& gt;IsKindOf(pClass))

打破;

}

如果(!pView-& gt;IsKindOf(pClass))

返回NULL

返回pView}

view類的成員函數IsKindOf()用了兩次來判斷,因為退出while循環有三種可能:

1.pos為空,即沒有下壹個視圖類進行操作;

2.pView已滿足要求。

3.1和2都滿足。這是因為GetNextView()的作用是將當前視圖指針改變到壹個視圖的位置,同時返回當前視圖指針,所以pos是pView的下壹個視圖類的位置,完全有可能同時是pos==NULL和pView。當所需視圖是最後壹個視圖和最後壹個視圖類時,就像壹個引用。所以需要兩個判斷。

使用該函數時應遵循以下格式(以CTestView指針為例):

ctest view * ptest view =(ctest view *)GetView(RUNTIME _ CLASS(ctest view));

RUNTIME_CLASS是壹個宏,它的作用可以簡單的理解為:把壹個類的名字轉換成壹個CRuntimeClass作為指針。

至於強制類型轉換,也是出於安全特性的考慮,因為來自同壹個基類的指針類型是相互兼容的。這種強制的類型轉換可能不是必須的,但是可以避免壹些可能的麻煩。

3.獲取從壹個視圖類到另壹個視圖類的指針。

結合1和2,很容易得到視圖類之間獲取指針的方法:以文檔類為中轉,先通過1獲取文檔類的指針,再通過2使用文檔類的視圖定位函數獲取另壹個視圖類。同樣,它可以作為壹個函數來實現:

(假設您想從CTestAView獲取指向其他視圖類的指針)

CView * cte staview::GetView(CRuntimeClass * pClass)

{ CTestDoc * pDoc =(CTestDoc *)get document();

CView * pView

POSITION pos=pDoc->。GetFirstViewPosition();

while(pos!=空)

{

pView = pDoc-& gt;get next view(pos);

if(pView-& gt;IsKindOf(pClass))

打破;

}

如果(!pView-& gt;IsKindOf(pClass))

返回NULL

返回pView}

與2中的GetView()相比,該函數增加了第壹句獲取文檔類指針,並在GetFirstViewPosition()和GetNextView()前增加了文檔類指針,表示它們是文檔類成員函數。

有了這個功能;當妳想從CTestAView中獲取壹個指向CTestBView的指針時,妳只需要做以下事情:

ctest bview * ptest bview =(ctest view *)GetView(RUNTIME _ CLASS(ctest bview));

4.從主框架窗口類獲取視圖類指針。

對於本文中提到的SDI程序,這很簡單,測試使用CFrameWnd類的GetActiveView()成員函數。格式如下:

CFrameWnd::GetActiveView()

但是,當這個函數應用於MDI應用程序時,並沒有像預期的那樣獲得當前活動子窗口的視圖類,而是返回NULL,這是壹個必然的問題。在MDI程序中,CMDIFrameWnd與任何視圖類都沒有關系,也就是說沒有任何視圖類直接屬於它,只有子幀窗口類CMDIChildWnd是所有子窗口視圖類的父窗口。子幀窗口的父窗口是CFrameWnd。因此,MDI程序中獲取活動視圖類的正確方法是先獲取活動子幀窗口,再從活動子幀窗口獲取活動視圖類:

//獲取活動子幀窗口

CMDIChildWnd * pChild =(CMDIChildWnd *)GetActiveFrame();

//或者:cmdichildwnd * pchild = mdigetactive();

//獲取活動子幀窗口的活動視圖。

cmy view * pView =(cmy view *)pChild-& gt;GetActiveView();

5.從視圖類中獲取主框架窗口類指針:

使用函數:CWnd::GetParentFrame()或AfxGetMainWnd();

能達到目的。GetParentFrame()的工作方式是在父窗口鏈中搜索,直到找到CFrameWnd或其派生類,並返回其指針。InfoViewer中詳細介紹了用法。

6.獲取任何類中的應用程序類。

可以用MFC全局函數AfxGetApp()來完成。

7.從應用程序類中獲取主框架窗口類。

cwintohread類有壹個名為m_pMainWnd的數據成員。由於CWinApp類是從cwintohread派生的,而我們的應用程序是從CWinApp派生的,所以我們的CTestApp類也有壹個名為m_pMainWnd的成員,它指導CMainFrame類。(需要適當的石膏)。

綜上所述,有幾點需要註意:

A.在a類中獲取指向b類的指針時,a類應該包含b類的頭文件。

B.很多情況下需要強制類型轉換,要註意括號。

由於派生類和父類的指針類型的兼容性,區分清楚每個類是非常重要的。當有疑問時,最好添加強制類型轉換。

  • 上一篇:我想學java,有沒有適合我的情況的方法?
  • 下一篇:灌藍高手的資料(骨灰級進)200分
  • copyright 2024編程學習大全網