http://blog.csdn.net/ljbkiss/article/details/8284652

關於Invalidate、InvalidateRect和UpdateWindow

   // 轉載,這個資料對我很有幫助。
(1)Invalidate

       Invalidate標記一個需要重繪的無效區域,並不意味着調用該函數後就立刻進行重繪。類似於PostMessage(WM_PAINT),需要處理到WM_PAINT消息時才真正重繪。以爲您Invalidate之後還有其他的語句正在執行,程序沒有機會去處理WM_PAINT消息,但當函數執行完畢後,消息處理才得以進行。

       Invalidate只是放一個WM_PAINT消息在隊列裏,不做別的,所以只有噹噹前函數返回後,進入消息循環,取出WM_PAINT,才執行PAINT,所以不管Invalidate放函數哪個地方,(作用相當於)都是(放在)最後的(但並不是推薦你一律放在函數最後一行)。

       Invalidate()之後:...OnPaint()->OnPrepareDC()->OnDraw(),所以只是刷新在OnPaint()和OnDraw()函數中的繪圖語句。其它地方沒有影響。

(2)InvalidateRect

       InvalidateRect只是增加重繪區域,在下次WM_PAINT的時候才生效,InvalidateRect函數中的參數TRUE表示系統會在你畫之前用背景色將所選區域覆蓋一次,默認背景色爲白色,可以通過設置BRUSH來改變背景色。

       InvalidateRect(hWnd,&rect,TRUE);向hWnd窗體發出WM_PAINT的消息,強制客戶區域重繪製,rect是你指定要刷新的區域,此區域外的客戶區域不被重繪,這樣防止客戶區域的一個局部的改動,而導致整個客戶區域重繪而導致閃爍,如果最後的參數爲TRUE,則還向窗體發送WM_ERASEBKGND消息,使背景重繪,當然在客戶區域重繪之前。

(3)UpdateWindow

       UpdateWindow只向窗體發送WM_PAINT消息,在發送之前判斷GetUpdateRect(hWnd,NULL,TRUE)看有無可繪製的客戶區域,如果沒有,則不發送WM_PAINT。如果希望立即刷新無效區域,可以在調用InvalidateRect之後調用UpdateWindow,如果客戶區的任一部分無效,則UpdateWindow將導致Windows用WM_PAINT消息調用窗口過程(如果整個客戶區有效,則不調用窗口過程)。這一WM_PAINT消息不進入消息隊列,直接由WINDOWS調用窗口過程。窗口過程完成刷新以後立刻退出,WINDOWS將控制返回給程序中UpdateWindow調用之後的語句。(windows程序設計第5版 P98)

三,問題

    初學者很容易碰到下面這個問題:(其中m_nEdit是一個編輯框的int型成員變量)

void CTestDlg::OnButton1() 
{
       // TODO: Add your control notification handler code here

       for(int i=0;i<10;i++)
       {
              m_nEdit=i;
              UpdateData(FALSE);
       }
}

    程序運行的結果是,編輯框裏面直接就顯示了9,是程序運行太快了看不清楚嗎?改:

void CTestDlg::OnButton1() 
{
       // TODO: Add your control notification handler code here
       for(int i=0;i<10;i++)
       {
              m_nEdit=i;
              Sleep(1000);
              UpdateData(FALSE);
       }
}

    程序開始沒有變化,靜靜運行了一會,直接顯示9!看來不是顯示太快的原因。

四,思考

    因爲UpdateData(FALSE)是更新窗口(編輯框也是窗口)的內容,當然也會更新窗口的“畫面”,那麼,是不是也是跟Invalidate、InvalidateRect一樣的問題呢?嘗試一下:

void CTestDlg::OnButton1() 
{
       // TODO: Add your control notification handler code here
       for(int i=0;i<10;i++)
       {
              m_nEdit=i;
              Sleep(100);//去掉這一句在這裏確實因爲顯示太快而看不清。
              UpdateData(FALSE);
              UpdateWindow();
      }
}
發佈了2 篇原創文章 · 獲贊 11 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章