你們想過這個問題嗎??關於invalidaterect()函數的一個問題


函數invalidaterect()會使一個小於客戶區的矩形無效,從而引起那一部分矩形的重畫。但是有一個問題,就是調用這個函數會使得發送WM_PAINT消息,而我們所用的畫圖操作都是在處理這個消息時進行的,這樣的話出現無效矩形,而不管這個矩形多小,就必須處理WM_PAINT消息,也就是必須進行所有的畫圖操作。那又怎樣實現只重畫無效矩形的功能呢?

8 个解决方案

#1


是這樣的,也就是說你的繪制所有代碼都要執行,但繪制結果(比如一條直接)只有當落在invalidaterect指定的矩形里,才會送到顯卡顯示,其它的直接丟棄。

這個問題沒有辦法徹底解決,想以考慮這樣:
把屏幕分為10個區域,然后寫10個函數來分別繪制他們,這樣如果矩形區域落在這10個區域的某一個時,就只需要調用那個函數就行。可是把屏幕分為10個區域,是很難分的,由其是如果一個大區域實現一個功能,很難將它分開。

#2


必須進行所有的畫圖操作

這是不對,比如一條直接,繪制之前你可以判斷,如果落在無效區域之外,你大可以不必繪制!
但是否落在區域之外這個判斷是必需要做的。另外,如果你的直接的坐標是臨時計算出來的,那么這個計算也是必需要浪費的(不計算你無法比較它是落在區域之外)。

要做出高效率的GDI操作,是很麻煩的。GDI操作就是這樣,如果做的不好,就會閃爍!

#3


謝謝兄弟!小弟還有一個問題想請教一下:把一個區域變成有效的,即調用validaterect函數,其中發生了什么事?會不會發生什么畫圖操作顯示以前所畫?或者是用背景話刷刷除背景什么的?

#4


調用了InvalidateRect,不會產生WM_PAINT消息。記得這個問題我回答過了,好好看看MSDN上的說明。只有當消息隊列空閑,並且存在無效矩形的時候,系統才會產生WM_PAINT消息。而且WM_PAINT消息根據無效矩形實現了剪裁,無效矩形外面的區域是不會更新的,很容易用代碼來試驗證明。

#5


消息隊列中應是合並無效區域的,,,不會有多余的重繪吧.

#6


Mackz(在相互) ( ) 信譽:115    Blog   加為好友  2007-6-10 22:16:41  得分: 0  
    
調用了InvalidateRect,不會產生WM_PAINT消息。
------------------------------------------
調用InvalidateRect肯定會產生WM_PAINT,你說的應該是UpdateWindow這個函數.

看看<<Window程序設計>>第4章,有這樣一段:

在第三章的HELLOWIN程式中,我們並不關心處理WM_PAINT訊息時的無效矩形。如果文字顯示區域恰巧在無效矩形內,則由DrawText恢復之。否則,在處理DrawText呼叫的某個時刻,Windows會確定它無須向顯示器上輸出。不過,這一決定需要時間。關心程式性能和速度的程式寫作者希望在處理WM_PAINT期間使用無效矩形范圍,以避免不必要的GDI呼叫。如果繪制時需要存取例如點陣圖這樣的磁片檔案,則這就顯得尤其重要。

如果要看怎樣提高畫圖性能的例子,則可以參考<<深入淺出MFC>>的第十一章:利用hint增加重繪效率一節


  
 

#7


只有當消息隊列空閑,並且存在無效矩形的時候,系統才會產生WM_PAINT消息。

#8


ls說的非常好,我仔細看了MSDN的解釋.
調用了InvalidateRect函數后,肯定有一塊區域變得無效了,
至於會不會發出WM_PAINT消息,
就要看有沒有在調用InvalidateRect后再調用其它使得無效區域變為有效的函數。
如果沒有,即存在無效區域,則等到窗口消息隊列為空時,系統才會發送一個WM_PAINT消息。
這種情況下,可以把WM_PAINT看作一個優先級比較低的消息

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com