在刷新窗口時經常要調用重繪函數
MFC提供了三個函數用於窗口重繪
InvalidateRect(&Rect)
Invalidate()
UpdateWindow()
當需要更新或者重繪窗口時,一般系統會發出兩個消息WM_PAINT(通知客戶區有變化)和WM_NCPAINT(通知非客戶區有變化)
--WM_NVPAINT系統會自己搞定
--WM_PAINT消息對應的函數是OnPaint(),它是系統默認的接受WM_PAINT消息的函數,但我們一般在程序中做重繪時都在OnDraw函數中進行的,因爲在ONPAIN函數中調用了ONDRAW函數。
///CView默認的標準的重畫函數
void CView::OnPaint()
{
CPaintDC dc(this);
OnPreparDC(&dc);
OnDraw(&dc); //調用了OnDraw
}
InvalidateRect(&Rect)
Invalidate()兩個函數形式和功能差不多,但Invalidate是使得整個窗口無效,形成無效矩形,而InvalidateRect(&Rect)是使得指定的區域無效。
UpdateWindow()會立即發送WM_PAINT,不過在它發送前,先調用GetUpdateRect(hWnd,NULL,TRUE)看有無可繪製區域,如果沒有則不發送消息RedrawWindow()RedrawWindow()則是具有Invalidate()和UpdateWindow()的雙特性。聲明窗口的狀態爲無效,並立即更新窗口,立即調用WM_PAINT消息處理。
BeginPaint和WM_PAINT消息緊密相關。試一試在WM_PAINT處理函數中不寫BeginPaint會怎樣?程序會像進入了一個死循環一樣達到驚人的CPU佔用率,你會發現程序總在處理一個接 一個的WM_PAINT消息。這是因爲在通常情況下,當應用收到WM_PAINT消息時,窗口的Update Region都是非空的(如果爲空就不需要發送WM_PAINT消息了),BeginPaint的一個作用就是把該Update Region置爲空,這樣如果不調用BeginPaint,窗口的Update Region就一直不爲空,如前所述,系統就會一直髮送WM_PAINT消息。
該函數的作用是使整個窗口客戶區無效。窗口的客戶區無效意味着需要重繪,例如,如果一個被其它窗口遮住的窗口變成了前臺窗口,那麼原來被遮住的部分就是無效的,需要重繪。這時Windows會在應用程序的消息隊列中放置WM_PAINT消息。MFC爲窗口類提供了WM_PAINT的消息處理函數OnPaint,OnPaint負責重繪窗口。視圖類有一些例外,在視圖類的OnPaint函數中調用了OnDraw函數,實際的重繪工作由OnDraw來完成。參數bErase爲TRUE時,重繪區域內的背景將被擦除,否則,背景將保持不變。
和 UpdateWindow( )區別在於:UpdateWindow( )的作用是使窗口立即重繪。調用Invalidate等函數後窗口不會立即重繪,這是由於WM_PAINT消息的優先級很低,它需要等消息隊列中的其它消息發送完後才能被處理。調用UpdateWindow函數可使WM_PAINT被直接發送到目標窗口,從而導致窗口立即重繪.