InvalidateRect(轉)


 ///===================該段是自己總結的一個小結=================================

InvalidateRect()函數的作用是設置一個無效區域,並發送一個WM_PAINT消息到消息隊列中,不過這個消息在眾多的消息之中優先級比較級。

在VC++編程中,對無效區域的處理方式是:

OnPaint()中繪圖,不管它繪制了什么圖形,有一點應該明白,有效區域是繪制不上去圖形的,或者是盡管繪制上去了,但也不會顯示出來。總之就是在有效區域上繪制的圖形不能生效。

換一種說法就是:在OnPaint()中繪圖,不管它繪制了什么圖形,只有設置為無效區域的區域才會顯示它所繪制的圖形。

 ///====================================================

 

InvalidateRect(&Rect)和Invalidate()兩個函數形式和功能差不多,但Invalidate是使得整個窗口無效,形成無效矩形,而InvalidateRect(&Rect)是使得指定的區域無效。如果你的OnPaint比較簡單時,InvalidateRect(&Rect)和Invalidate()區別不是很大,因為相對重繪量少,所以整個重繪和局部重繪區別不是很明顯。當你界面比較復雜時,重繪全部和重繪局部的量就比較明顯,InvalidateRect(&Rect)明顯效率高於Invalidate()。但是InvalidateRect(&Rect)需要你自己判斷哪些區域是無效,而Invalidate()不需要(因為它是全部重繪)。所以當全部重繪的計算量高於判斷局部無效的計算量時,更適合使用InvalidateRect(&Rect)。 多個WM_PAINT消息之間通過InvalidateRect使之失效的區域就會被累加起來,然后在一個WM_PAINT消息中一次得到更新,不僅能避免多次重復地更新同一區域,也優化了應用的更新操作。像這種通過InvalidateRect和InvalidateRgn來使窗口區域無效,依賴於系統在合適的時機發送WM_PAINT消息的機 制實際上是一種異步工作方式,也就是說,在無效化窗口區域和發送WM_PAINT消息之間是有延遲的。  

InvalidateRect(HWND) 使窗口無效 產生消息WM_PAINT;  
ValidateRect(HWND)使窗口有效 清除消息隊列中的WM_PAINT消息


在編程的時候經常把UpdateData、Invalidate、InvalidateRect和UpdateWindow四個函數混淆,在這里將簡單介紹它們的區別。
UpdateData():
    當你使用了ClassWizard建立了控件和變量之間的聯系后:當你修改了變量的值,而希望對話框控件更新顯示,就應該在修改變量后調用UpdateData(FALSE);如果你希望知道用戶在對話框中到底輸入了什么,就應該在訪問變量前調用UpdateData(TRUE),將控件的輸入映射到變量中。

Invalidate():
     該函數的作用是使整個窗口客戶區無效。窗口的客戶區無效意味着需要重繪,例如,如果一個被其它窗口遮住的窗口變成了前台窗口,那么原來被遮住的部分就是無效的,需要重繪。這時Windows會在應用程序的消息隊列中放置WM_PAINT消息。MFC為窗口類提供了WM_PAINT的消息處理函數OnPaint,OnPaint負責重繪窗口。視圖類有一些例外,在視圖類的OnPaint函數中調用了OnDraw函數,實際的重繪工作由OnDraw來完成。參數bErase為TRUE時,重繪區域內的背景將被擦除,否則,背景將保持不變。
   Invalidate標記一個需要重繪的無效區域,並不意味着調用該函數后就立刻進行重繪。 Invalidate只是放一個WM_PAINT消息在隊列里,不做別的,所以只有當當前函數返回后,進入消息循環,取出WM_PAINT,才執行PAINT,所以不管Invalidate放函數哪個地方,(作用相當於)都是(放在)最后的(但並不是推薦你一律放在函數最后一行)。


InvalidateRect():
    該函數的功能與Invalidate基本一樣,不同的是,它是使指定的某個區域無效,需要輸入一個區域。

UpdateWindow():
     UpdateWindow( )的作用是使窗口立即重繪。調用Invalidate等函數后窗口不會立即重繪,這是由於WM_PAINT消息的優先級很低,它需要等消息隊列中的其它消息發送完后才能被處理。調用UpdateWindow函數可使WM_PAINT被直接發送到目標窗口,從而導致窗口立即重繪。


只將窗口顯示區域標記為無效以產生WM_PAINT消息,對於某些應用程序來說也許不是完全令人滿意的選擇。在呼叫InvalidateRect之后,Windows將WM_PAINT消息放入消息隊列中,最后由窗口消息處理程序處理它。然而,Windows將WM_PAINT消息當成低優先級消息,如果系統有許多其它的動作正在發生,那么也許會讓您等待一會兒工夫。這時,當對話框消失時,將會出現一些空白的「洞」,程序仍然等待更新它的窗口。

如果您希望立即更新無效區域,可以在呼叫InvalidateRect之后呼叫UpdateWindow:

UpdateWindow (hwnd) ;
如果顯示區域的任一部分無效,則UpdateWindow將導致Windows用WM_PAINT消息呼叫窗口消息處理程序(如果整個顯示區域有效,則不呼叫窗口消息處理程序)。這一WM_PAINT消息不進入消息隊列,直接由Windows呼叫窗口消息處理程序。窗口消息處理程序完成更新后立即退出,Windows將控制傳回給程序中UpdateWindow呼叫之后的敘述。

您可能注意到,UpdateWindow與WinMain中用來產生第一個WM_PAINT消息的函數相同。最初建立窗口時,整個顯示區域內容變為無效,UpdateWindow指示窗口消息處理程序繪制顯示區域。

-----------------------------------------------------------------------

1. UpdateWindow:如果有無效區,則馬上sending a WM_PAINT message到窗口處理過程,不進消息隊列進行排隊等待,立即刷新窗口,否則,什么都不做。

2. InvalidateRect:設置無效區,如果為NULL參數,則設置整個窗口為無效區。當應用程序的那個窗口的消息隊列為空時,則sending a WM_PAINT message(即使更新區域為空).在sending a WM_PAINT message的所有InvalidateRect的更新區域會累加。

3. 如果不調用 InvalidateRect就調用 UpdateWindow,那么UpdateWindow什么都不做。 ??????

4. 如果調用 InvalidateRect 后不調用UpdateWindow,則系統會自動在窗口消息隊列為空的時候,系統自動發送一WM_PAINT消息。

5. 調用UpdateWindow()時將會發送一個WM_PAINT消息,而應用程序在接收到WM_PAINT消息后,將自動地調用Invalidate(),所以,在程序代碼中,不一定要出現Invalidate()!

6. UpdateWindow()就是立即發送WM_PAINT消息,只對聲明無效的區域起作用。Invalidate()則是聲明無效的方式之一。

7. Invalidate()表示客戶區域無效,在下次WM_PAINT發生時重繪。而WM_PAINT是由系統進行維護的,每當CWnd的更新區域不為空,並且在應用程序的窗口消息隊列中沒有其它消息時,Windows就發送一條WM_PAINT消息。   
   Invalidate里面有個bool型的參數,用來標識重繪的時候是否用背景色填充。

8. updateWindow則是要求系統對區域進行立即重繪。

    看到有人在網上提出問題,他在Invalidate后面又寫了繪圖的函數但是沒有執行,因為invalidate執行過以后轉到PAINT命令了。所以后面的都沒有顯示。
    也終於想通我繪的圖一直在閃啊閃,因為我在PAINT里面用到Invalidate()函數,所以他不停的自嵌套,倒是繪的圖不停的閃。

9. Invalidate讓客戶區處於可以重畫的狀態,而UpdateWindow開始重畫,但是它先判斷客戶區是否為空,不空UpdateWindow不執行,為空才執行重畫。

10.Invalidat最后也是調用InvalidatRect,在windows API里只有InvalidatRect的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM