MFC的視窗重繪

2021-07-25 12:48:56 字數 2091 閱讀 9051

在重新整理視窗時經常要呼叫重繪函式

mfc提供了三個函式用於視窗重繪

invalidaterect(&rect)

invalidate()

updatewindow()

當需要更新或者重繪視窗時,一般系統會發出兩個訊息wm_paint(通知客戶區有變化)和wm_ncpaint(通知非客戶區有變化)

wm_nvpaint系統會自己搞定

wm_paint訊息對應的函式是onpaint(),它是系統預設的接受wm_paint訊息的函式,但我們一般在程式中做重繪時都在ondraw函式中進行的,因為在onpain函式中呼叫了ondraw函式。

///cview預設的標準的重畫函式

void cview::onpaint()

上面講到

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處理函式中使用。

VS2010 視窗重繪

孫鑫老師的vc 深入詳解中,第6.5章 本示例程式中再次輸入的文字是在上次輸入的文字之上顯示的,書上的 不能解決這個問題 void cmenu7view onchar uint nchar,uint nrepcnt,uint nflags m strline.empty invalidate els...

視窗重繪一點通

視窗重繪函式心得 在重新整理視窗時經常要呼叫重繪函式 mfc提供了三個函式用於視窗重繪 invalidaterect rect invalidate updatewindow 當需要更新或者重繪視窗時,一般系統會發出兩個訊息wm paint 通知客戶區有變化 和wm ncpaint 通知非客戶區有變...

視窗重繪一點通

視窗重繪函式心得 在重新整理視窗時經常要呼叫重繪函式 mfc提供了三個函式用於視窗重繪 invalidaterect rect invalidate updatewindow 當需要更新或者重繪視窗時,一般系統會發出兩個訊息wm paint 通知客戶區有變化 和wm ncpaint 通知非客戶區有變...