當窗口發生改變后,會產生無效區域,這個無效的區域需要重畫。
一般Windows會發送兩個消息WM_PAINT(通知客戶區 有變化)和WM_NCPAINT(通知非客戶區有變化)。
非客戶區的重畫系統自己搞定了,而客戶區的重畫需要我們自己來完成。這就需要OnDraw()或 OnPaint()來重畫窗口。
CView類派生自CWnd類。而OnPaint()是CWnd的類成員,同時負責響應WM_PAINT消息。OnDraw()是CVIEW的成員函數,並且沒有響應消息的功能。
當視圖變得無效時(包括大小的改變,移動,被遮蓋等等),Windows 將 WM_PAINT 消息發送給它(可以利用Invalidate(),ValidateRgn(),ValidateRect()函數強制的重畫窗口)。
該視圖的 OnPaint 處理函數通過創建 CPaintDC 類的DC對象來響應該消息並調用視圖的 OnDraw 成員函數。通常我們不必編寫重寫的 OnPaint 處理成員函數。
void CView::OnPaint()
{
// standard paint routine
CPaintDC dc(this);
OnPrepareDC(&dc);
OnDraw(&dc);
}
void CView::OnDraw(CDC*)
{
}
既然OnPaint最后也要調用OnDraw,因此我們一般會在OnDraw函數中進行繪制。
void CMyView::OnDraw( CDC* pDC )
{
CGdiDrawDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
CDC* pDc = GetDC(); // 注意:CPaintDC只能用於OnPaint
CRect rect;
GetClientRect( &rect );
pDC->SetTextAlign( TA_BASELINE | TA_CENTER );
pDC->TextOut( rect.right / 2, rect.bottom / 2, s, s.GetLength() );
}
注意:如果CMyView重載了CView的OnPaint消息處理函數,此時子類的OnDraw函數是不響應的,只能將自己的繪圖寫在OnPaint函數中。