視窗重繪的函數的心得

來源:互聯網
上載者:User

在重新整理視窗時京城要調用重繪函數
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)是
使得指定的地區無效

Invalidate()申明無效,等待WM_PAINT訊息以便重繪,隊列中無其他訊息時系統會自動發送
UpdateWindow()會立即發送WM_PAINT,不過在它發送前,先調用GetUpdateRect(hWnd,NULL,TRUE)看有無可繪製地區,如果沒有
則不發送訊息

RedrawWindow()RedrawWindow()則是具有Invalidate()和UpdateWindow()的雙特性。聲明視窗的狀態為無效,並立即更新視窗,立

即調用WM_PAINT訊息處理。

系統為什麼不在調用Invalidate時發送WM_PAINT訊息呢?又為什麼非要等應用訊息佇列為空白時才發送WM_PAINT訊息呢?這是因為系

統把在視窗中的繪製操作當作一種低優先順序的操作,於是盡 可能地推後做。不過這樣也有利於提高繪製的效率:兩個WM_PAINT訊息

之間通過InvalidateRect和InvaliateRgn使之失效的地區就會被累加起來,然後在一個WM_PAINT訊息中一次得到 更新,不僅能避免

多次重複地更新同一地區,也最佳化了應用的更新操作。像這種通過InvalidateRect和InvalidateRgn來使視窗地區無效,依賴於系統

在合適的時機發送WM_PAINT訊息的機 制實際上是一種非同步工作方式,也就是說,在無效化視窗地區和發送WM_PAINT訊息之間是有延

遲的;有時候這種延遲並不是我們希望的,這時我們當然可以在無效化視窗地區後利用SendMessage 發送一條WM_PAINT訊息來強制

立即重畫,但不如使用Windows GDI為我們提供的更方便和強大的函數:UpdateWindow和RedrawWindow。UpdateWindow會檢查視窗的

Update Region,當其不為空白時才發送WM_PAINT訊息;RedrawWindow則給我們更多的控制:是否重畫非客戶區和背景,是否總是發送

WM_PAINT訊息而不管Update Region是否為空白等。

BeginPaint和WM_PAINT訊息緊密相關。試一試在WM_PAINT處理函數中不寫BeginPaint會怎樣?程式會像進入了一個死迴圈一樣達到

驚人的CPU佔用率,你會發現程式總在處理一個接 一個的WM_PAINT訊息。這是因為在通常情況下,當應用收到WM_PAINT訊息時,窗

口的Update Region都是非空的(如果為空白就不需要發送WM_PAINT訊息了),BeginPaint的一個作用就是把該Update Region置為空白

,這樣如果不調用BeginPaint,視窗的Update Region就一直不為空白,如前所述,系統就會一直發送WM_PAINT訊息。

BeginPaint和WM_ERASEBKGND訊息也有關係。當視窗的Update Region被標誌為需要擦除背景時,BeginPaint會發送WM_ERASEBKGND消

息來重畫背景,同時在其返回資訊裡有一個標誌表明視窗背景是否被重畫過。當我們用InvalidateRect和InvalidateRgn來把指定區

域加到Update Region中時,可以設定該地區是否需要被擦除背景,這樣下一個BeginPaint就知道是否需要發送WM_ERASEBKGND訊息

了。

另外要注意的一點是,BeginPaint只能在WM_PAINT處理函數中使用。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.