重繪閃爍問題總結
阿新 • • 發佈:2019-01-04
重繪閃爍,通常,首先需要懷疑的是WM_ERASEBKGND訊息。當一個視窗的背景需要被擦除時,這個訊息會被髮送。這是因為視窗的繪畫通常經歷了兩個過程
WM_ERASEBKGND: 清除背景
WM_PAINT: 在上面繪製內容
這兩個過程讓窗體在繪製內容時變得很簡單,即:每次當收到WM_PAINT訊息時,你知道已經有了一個新畫布等待去繪製。然而,畫視窗兩次(一次是通過WM_ERASEBKGND畫背景,另外一次是WM_PAINT)將會導致窗口出現比較糟糕的閃爍現象。只要看看標準的編輯框-開啟Windows的寫字板並改變視窗大小,就可以看到那種閃爍的效果。
那麼,如何避免視窗背景的重刷呢?有如下兩種方法:
1、
2、在WM_ERASEBKGND訊息處理時 返回非零值
以上任何一種方法都可以阻止WM_ERASEBKGND 訊息去清除視窗。其中,第二個方案的通常可以以如下程式碼實現:
case WM_ERASEBKGND:
return 1;
3、當你標記視窗內容無效並試圖更新時,還有如下辦法可以防止WM_ERASEBKGND訊息:InvalidateRect函式的最後一個引數可以指明在下一次視窗重畫時,是否視窗的部分背景會被重刷。將該引數置為False可以防止當視窗需要重畫時系統發出WM_ERASEBKGND訊息。
InvalidateRect(hwnd, &rect, FALSE);
4、剪下子窗體屬性中的Clip children Clip Sibling 兄弟姐妹視窗
有時,閃爍的原因是因為當重畫時,父窗體沒有剪下其子窗體區域。這樣的結果導致,整個父視窗內容被重畫,而子窗體又被顯示在了上面(造成閃爍)。這個可以通過在父窗體上設定WS_CLIPCHILDREN 來解決。當這個標誌被設定時,被子窗體佔據的任何區域將會被排除在更新區域外。因此,即使你嘗試在子窗體所在的位置上繪製(父視窗的內容),BeginPaint中的剪下區域也會阻止其繪製效果。
5、雙緩衝
CRectrt; GetClientRect6、不該畫的時候一定不要畫