久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

深入了解CCtrlView

 紫殿 2011-08-21

 如果我們要將一個控件轉(zhuǎn)換成視圖類,,我們一般會想到CCtrlView,,用它實現(xiàn)的控件視圖一般添加一個GetXXXCtrl函數(shù),函數(shù)的作用是返回視圖中控件的引用,,如果在MFC程序中跟蹤它的調(diào)用我們會發(fā)現(xiàn)它的實現(xiàn)是這樣的(以CEdit控件為例)

_AFXEXT_INLINE   CEdit&   CEditView::GetEditCtrl()   const 
{   return   *(CEdit*)this;   }

這個轉(zhuǎn)換讓人覺得很疑惑,,因為CEdit和CEditView是來自兩條不同繼承鏈上的類,一般來說這樣的轉(zhuǎn)換是要出問題的,,但是為什么可以進行這種轉(zhuǎn)換,?MSDN上有一篇文章對這種轉(zhuǎn)換做了比較深入的解釋,下面把這篇文章翻出來給大家看看,。

問題:
我設(shè)計了一個從CWnd派生而來的自定義控件,,現(xiàn)在我想把它當成視圖來使用。我想到的的第一個辦法是把控件嵌入到視圖中然后操控視圖中的OnSize函數(shù)以使控件覆蓋客戶區(qū),。但問題是傳給控件的鼠標消息無法在視圖中重載,。而傳給視圖的擊鍵消息必須手動傳遞給控件。我了解到CCtrlView可以作為公用控件的基類,。于是我試圖圍繞著它設(shè)計視圖(我記得你在MSJ的某一期上討論了這個問題),,但是我無法讓它與我自定義的CWnd派生控件類一起工作。請問這樣做可以嗎,?應(yīng)該怎樣做,?

Mateo Anderson(回答者)

回答:
CCtrlView是一個MFC將控件類轉(zhuǎn)換為視圖類的技巧。比如從CTreeCtrl轉(zhuǎn)換成CTreeView或者從CListCtrl轉(zhuǎn)換成CListView,。在CCtrlView的文
檔注釋中提到:“CCtrlView幾乎允許把任何控件轉(zhuǎn)換成視圖,?!?。不幸的是,說“幾乎”稍微有些夸大其詞了,,除非作者所說的“任何控件”只是關(guān)于像CEdit和CTreeCtrl這樣的Windows內(nèi)建控件,。CCtrlView用了一個只能在特定環(huán)境下工作的技巧。要理解CCtrlView如何工作,,首先讓我們看看CTreeView,,CTreeView派生于CCtrlView。其中有三個重要的函數(shù)需要考慮:構(gòu)造函數(shù),PreCreateWindow函數(shù)和GetTreeCtrl函數(shù),。構(gòu)造函數(shù)告訴CCtrlView要創(chuàng)建哪種Windows控件,。

CTreeView::CTreeView() : 
  CCtrlView(WC_TREEVIEW, dwStyle)

在這個例子中,WC_TREEVIEW(在commctrl.h中定義)是樹型控件類的類名,,也就是“SysTreeView32”,。CCtrlView會將此類名保存在一個數(shù)據(jù)成員中稍后使用:

CCtrlView::CCtrlView(LPCTSTR lpszClass, 
  DWORD dwStyle)
{
  m_strClass = lpszClass;
  m_dwDefaultStyle = dwStyle;
}

下一個起作用的函數(shù)是PreCreateWindows,這是一個CTreeCtrl從CCtrlView繼承來的函數(shù),。CCtrlView::PreCreateWindow在窗口剛好創(chuàng)建完成之前使用m_strClass在CREATESTRUCT種設(shè)置類名,。

// CCtrlView uses stored class name
BOOL CCtrlView::PreCreateWindow(CREATESTRUCT& cs)
{
  cs.lpszClass = m_strClass;
 
  return CView::PreCreateWindow(cs);
}

現(xiàn)在創(chuàng)建的窗口就是使用所期望的類創(chuàng)建的了-在這個例子中就是SysTreeView32。到目前為止,,一切都很好,。但是如果CTreeCtrl派生于CCtrlView,而CCtrlView又派生于CView,,那么它為什么能又派生于CTreeCtrl,?難道是MFC類封裝了樹型控件?CTreeView和CTreeCtrl是完全獨立的,,有著不同的繼承鏈,。CTreeCtrl直接派生于CWnd,而CTreeView派生于CCtrlView/CView,。這就是技巧發(fā)生作用的地方了,。要讓樹型視圖像樹型控件一樣操控,CCtreeView提供了特殊的函數(shù)GetTreeCtrl來獲得樹型控件,。

CTreeCtrl& CTreeView::GetTreeCtrl() const

  return *(CTreeCtrl*)this; 
}

GetTreeCtrl只是簡單的將CtreeView轉(zhuǎn)換為CTreeCtrl,。但是等等-怎么會發(fā)生這么詭異的事?這兩個類完全不同,,有著不同的數(shù)據(jù)成員和虛函數(shù)表-你根本無法將一個轉(zhuǎn)換成另一個同時還指望著能夠正常工作,!答案就是:CTreeCtrl沒有虛函數(shù)也沒有數(shù)據(jù)成員。你可以把它稱為一個純包裝類,。CTreeCtrl不對它的基類CWnd添加任何東西(不添加數(shù)據(jù)成員也不添加虛函數(shù)),,所有添加的內(nèi)容只是一些包裝函數(shù),一些將消息發(fā)送給內(nèi)在HWND的有形函數(shù),。

HTREEITEM CTreeCtrl::InsertItem(...)

  return (HTREEITEM)::SendMessage(m_hWnd, 
    TVM_INSERTITEM, ...);
}

InsertItem訪問的唯一數(shù)據(jù)成員是m_hWnd,,所有的CWnd派生類都有該成員。InsertItem和所有其它的包裝函數(shù)只是將它們的參數(shù)傳遞給了內(nèi)在的HWND,,將C++風格的成員函數(shù)轉(zhuǎn)換成Windows風格的SendMessage調(diào)用,。對象本身(“this”指針)可以是任何CWnd派生類的實例,只要m_hWnd處于正確的位置(也即是類的第一個數(shù)據(jù)成員),,并且HWND(實際上就是如此)是一個樹型控件的句柄,。相同的原因發(fā)生在下面的寫法中:
 
pEdit = (CEdit*)GetDlgItem(ID_FOO);

即便在這里GetDlgItem返回的是一個指向CWnd的指針,,不是CEdit。但是這樣是允許的,,因為CEdit也是一個包裝類,,而且對于它從CWnd繼承來的內(nèi)容沒有添加額外的數(shù)據(jù)和虛函數(shù)。所以注釋中“CCtrlView幾乎允許將任何控件轉(zhuǎn)換為視圖”的說法中所說的“幾乎任何”意思是特指對CWnd沒有添加數(shù)據(jù)成員和虛函數(shù)的這些控件,,也就是我所說的“純包裝類,。”如果你的控件類有它自己的數(shù)據(jù)或虛函數(shù),,你無法使用CCtrlView,,因為在CCtrlView/CView中不存在這些額外的數(shù)據(jù)成員和虛函數(shù)。

舉例來說,,CView中的第一個虛函數(shù)是CView::IsSelected,。如果你的控件類有其它虛函數(shù),在你把CCtrlView類轉(zhuǎn)換成你的CFooCtrl類調(diào)用那個虛函數(shù)的時候就肯定會爆發(fā)問題了,,因為這個函數(shù)根本不存在,。類似的,CView中的第一個數(shù)據(jù)成員是m_pDocument,。如果你的控件類需要一些其它的數(shù)據(jù)成員,,那你在訪問它們的時候就要倒霉了,因為對象事實上調(diào)用的是CCtrlView,,而不是CFooCtrl,。多么糟糕,多么令人沮喪,。


簡而言之,,唯一可以使用CCtrlView技巧的時候是CWnd派生控件類沒有它自己的虛函數(shù)和數(shù)據(jù)成員之時。這就是生活,。


看到這里,,大家應(yīng)該就很明白了,這里的轉(zhuǎn)換有一個與普通類類型之間的轉(zhuǎn)換有一個重要區(qū)別,,控件類中沒有虛函數(shù)和新的數(shù)據(jù)成員,,因此控件類具有和CWnd一樣的虛函數(shù)表和數(shù)據(jù)擺放,所謂將CEditView轉(zhuǎn)換成CEdit控件,,實際CEdit控件對象只會調(diào)用CEditView中CWnd那部分的成員,,因而這種調(diào)用是可行的。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多