雖然Gilbert之前介紹過CWnd和HWnd的區別, 但是這里和其他幾個CDC, HDC放在一起重申一下其中的區別和關系.
1.對象和句柄
CWnd是類, HWnd是句柄, CWnd封裝了HWnd
CWnd wnd;
HWnd hWnd;
wnd.Attach(hWnd);//句柄到對象
wnd->m_hWnd;// 對象到句柄
當然一般在程序中是這樣獲得句柄:
AfxGetMainWnd()->m_hwnd;
同樣的, CDC和HDC也是這樣的關系:
CDC *pDC=new CDC;
HDC hdc;
pDC->GetSafeHdc();//通過對象獲得句柄:
pDC->Attach(hdc); //通過句柄獲得對象:
HWND是SDK定義的類型,是一個無確切意義的32-bit值,在調用API時用于指代窗體。
CWnd*是一個有確切意義的指針,指向一個MFC窗體類CWnd的實例。因為MFC對SDK做了封裝,大部分調用都可以用CWnd*作為參數,所以很容易混淆。從一個CWnd*獲取句柄的方法是pWnd->GetSafeHwnd(),他比 pWnd->m_hWnd安全,因為前者在pWnd == NULL的時候返回NULL而后者出現access violation.
2. CWnd和CDC, hwnd和hdc
所有跟窗口相關的操作都被封裝在CWnd類中; 所有跟繪圖相關的操作都被封裝在CDC類中.
hwnd句柄是描述一個窗口的形狀、位置、大小、是否顯示、它的父窗口、兄弟窗口、等等的一組數據結構;hdc句柄是一個實實在在的用于具體表現這個窗口時,需要對這個窗口有個場合來實現的地方。
3. 使用不同的CDC繪圖
CClientDC 客戶區dc;
CWindowDC 整窗口dc;
CDC 任何dc;
/*
CDC *pDC=CWnd::GetDC();
//此處直接使用CWnd類的GetDC,其返回值為CDC*
//SDK中的同名函數使用返回的是HDC
*/
pDC->MoveTo(m_ptOrigin);
pDC->LineTo(point);
CWnd::ReleaseDC(pDC);
/*//使用CClientDC繪圖
CClientDC派生自CDC,在構造的時候調用GetDC,
在析構的時候調用ReleaseDC。使得我們不必
顯示調用GetDC與ReleaseDC。
*/
CClientDC dc(this);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
/*//使用CWindowDC繪圖
同樣派生自CDC,構造調用GetWindowDC,
析構時調用ReleaseDC()。
可以訪問整個屏幕區域,包括客戶區和非客戶區。
*/
CWindowDC dc(this);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
所有知識來自于互聯網.