全部控件類都是CWnd類的派生類,CWnd的全部成員函數在控件類中均可以使用。在MFC中,CWnd類是一個很重要的類,它封裝了Windows的窗口句柄HWND。在Windows編程中,每個窗口都是有窗口句柄標識的。可是,類CWnd的對象和窗口句柄之間的概念並非等同的。CWnd對象的建立和銷燬,是由類CWnd的構造函數和析構函數完成的,而Windows窗口是Windows內部的一種數據結構,它由類CWnd的Create成員函數建立,由析構函數銷燬。除此以外,成員函數DestroyWindow能夠銷燬Windows窗口,而不會銷燬CWnd對象。編程
通常狀況下,他建立一個窗口須要兩步:首先,調用類CWnd的構造函數,構造一個CWnd對象,而後調用CWnd的成員函數Create,建立窗口。當用戶要關閉該窗口時,能夠銷燬與窗口有關的CWnd對象,或者調用CWnd對象的成員函數DestoryWindow,刪除窗口並銷燬其數據結構。安全
HWND是Windows系統中對全部窗口的一種標識,即窗口句柄。這是一個SDK概念。數據結構
CWnd是MFC類庫中全部窗口類的基類。在MFC中將全部窗口的通用操做都封裝到了這個類中,如:ShowWindow等等,同時它也封保存了窗口句柄即在m_hWnd成員。函數
1.由一個HWND變量hWnd實例化一個CWnd*對象:this
CWnd *pWnd; HWND hWnd;.net
獲得hWnd的方式:1.從參數得到 2.從CreateWindow(…..)返回指針
pWnd->Attach(hWnd); //pWnd對象和窗口資源關聯對象
用staticCWnd* CWnd::FromHandle(HWND hWnd) ; blog
若是一個CWnd對象沒有和這個hWnd綁定,一個臨時的CWnd對象將被構造,而且和hWnd綁定。若是綁定了就不是一個臨時CWnd對象。返回的這個指針多是臨時的,因此最好不要保存用於後來使用。資源
用staticCWnd* CWnd::FromHandlePermanent(HWND hWnd);
若是CWnd對象沒有和hWnd綁定,返回NULL,而不會構造一個臨時對象。
2.由CWnd獲取HWnd
CWnd的一個成員m_hWnd就是其所對應窗口的句柄:hWnd = pWnd->m_hWnd;
用hWnd = pWnd->GetSafeHwnd() 比pWnd->m_hWnd 安全,由於:
由於前者在 pWnd == NULL 的時候返回 NULL 不易察覺,然後者出現 access violation。
1. 得到父窗體的控件或子窗體的「窗口句柄—hWnd」
HWND hWnd = ::GetDlgItem(this->m_hWnd,IDC_XXXX_SIZE); //參數1:父窗口的句柄
CWnd *CWnd::GetDlgItem( int nID ); // 返回控件/子窗體對象
void GetDlgItem( int nID, HWND*phWnd ); //得到控件/子窗體的句柄
總結:綜上可知在MFC概念下,hWnd只是CWnd對象的一個成員變量,表明與這個對象綁定的窗口;在SDK下hWnd本來就是用來表明一個窗口。hWnd在SDK和MFC概念都是一致的。而CWnd類是MFC將除了hWnd外的其它許多屬性和操做進行封裝的結果。
補充:
MFC中的每個窗口類型(從CWnd直接/間接派生)對象fromWnd,在實例化以前,其
fromWnd.m_hWnd一定爲NULL。
CButton button; //此時button.m_hWnd ==NULL
button.Create(「按鈕」,BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD,
CRect(0,0,100,50),this,123); //此時button.m_hWnd != NULL