UpdateWindow、Invalidate、UpdateData區別
按引:Invalidate在消息隊列中加入一條WM_PAINT消息,其無效區為整個客戶區。而UpdateWindow直接發送一個WM_PAINT消息,其無效區範圍就是消息隊列中WM_PAINT消息(最多只有一條)的無效區。效果很明顯,調用Invalidate之後,屏幕不一定馬上更新,因為WM_PAINT消息不一定在隊列頭部,而調用UpdateWindow會使WM_PAINT消息馬上執行的,繞過了消息隊列。如果你調用Invalidate之後想馬上更新屏幕,那就加上UpdateWindow()這條語句。
UpdateData():
當你使用了ClassWizard建立了控制項和變數之間的聯繫後:當你修改了變數的值,而希望對話框控制項更新顯示,就應該在修改變數後調用UpdateData(FALSE);如果你希望知道用戶在對話框中到底輸入了什麼,就應該在訪問變數前調用UpdateData(TRUE),將控制項的輸入映射到變數中。
Invalidate(): 該函數的作用是使整個窗口客戶區無效。窗口的客戶區無效意味著需要重繪。例如,如果一個被其它窗口遮住的窗口變成了前台窗口,那麼原來被遮住的部分就是無效的,需要重繪。這時Windows會在應用程序的消息隊列中放置WM_PAINT消息。MFC為窗口類提供了WM_PAINT的消息處理函數OnPaint,OnPaint負責重繪窗口。視圖類有一些例外,在視圖類的OnPaint函數中調用了OnDraw函數,實際的重繪工作由OnDraw來完成。參數bErase為TRUE時,重繪區域內的背景將被擦除,否則,背景將保持不變。
InvalidateRect(): 該函數的功能與Invalidate基本一樣,不同的是,它是使指定的某個區域無效,需要輸入一個區域,如果參數為NULL,則設置整個窗口為無效區。
UpdateWindow(): UpdateWindow( )的作用是使窗口立即重繪。調用Invalidate等函數後窗口不會立即重繪,這是由於WM_PAINT消息的優先順序很低,它需要等消息隊列中的其它消息發送完後才能被處理。調用UpdateWindow函數可使WM_PAINT被直接發送到目標窗口,從而導致窗口立即重繪。 UpdateWindow:如果有無效區,則馬上sending a WM_PAINT message到窗口處理過程,不進消息隊列進行排隊等待,立即刷新窗口,否則,什麼都不做。 InvalidateRect:設置無效區,如果為NULL參數,則設置整個窗口為無效區。當應用程序的那個窗口的消息隊列為空時,則sending a WM_PAINT message(即使更新區域為空).在sending a WM_PAINT message的所有InvalidateRect的更新區域會累加。
1:設置無效區 InvalidateRect 2:立即刷新 UpdateWindow() 如果不調用 InvalidateRect就調用 UpdateWindow,那麼UpdateWindow什麼都不做。 如果調用 InvalidateRect 後不調用UpdateWindow,則系統會自動在窗口消息隊列為空的時候,系統自動發送一WM_PAINT消息。
調用UpdateWindow()時將會發送一個WM_PAINT消息,而應用程序在接收到WM_PAINT消息後,將自動地調用Invalidate()。所以,在程序代碼中,不一定要出現Invalidate()!
UpdateWindow()就是立即發送WM_PAINT消息,updateWindow要求系統對區域進行立即重繪,其只對聲明為無效的區域起作用,而Invalidate()是聲明無效區域的方式之一。
Invalidate()表示客戶區域無效,在下次WM_PAINT發生時重繪。而WM_PAINT是由系統進行維護的,每當CWnd的更新區域不為空,並且在應用程序的窗口消息隊列中沒有其它消息時,Windows就發送一條WM_PAINT消息。
Invalidat最後也是調用InvalidatRect。
RedrawWindow 強制刷新,會調用WM_PAINT,但如果你強制刷新的部分不存在就不會調用WM_PAINT。若不帶任何參數,則本窗口全部刷新。
*****************************************************************************************************************************************
看到有人在網上提出問題,他在Invalidate後面又寫了繪圖的函數但是沒有執行,這是因為invalidate執行過以後就轉到PAINT命令了,所以後面的都沒有顯示。
也終於想通我繪的圖一直在閃啊閃,這是因為我在PAINT裡面用到了Invalidate()函數,所以他不停的自嵌套,導致繪的圖在不停的閃。
總之:Invalidate讓客戶區處於可以重畫的狀態,而UpdateWindow開始重畫,但是它首先需判斷客戶區是否為空,不空則UpdateWindow不執行,為空才執行重畫。
*********************************************************************************************************************************************
在刷新窗口時經常要調用重繪函數MFC提供了三個函數用於窗口重繪 InvalidateRect(&Rect) Invalidate() UpdateWindow() 當需要更新或者重繪窗口時,一般系統會發出兩個消息WM_PAINT(通知客戶區有變化)和WM_NCPAINT(通知非客戶區有變化)WM_NVPAINT系統會自己搞定WM_PAINT消息對應的函數是OnPaint(),它是系統默認的接受WM_PAINT消息的函數,但我們一般在程序中做重繪時都在OnDraw函數中進行的,因為在視圖類ONPAINT函數中調用了ONDRAW函數。 CView默認的標準的重畫函數 void CView::OnPaint() { CPaintDC dc(this); OnPreparDC(&dc); OnDraw(&dc); //調用了OnDraw
} 上面講到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處理函數中使用
OnDraw,一般是收到WM_PAINT消息時調用,所以應用程序一般通過Invalidate產生WM_PAINT消息來間接調用OnDraw。當窗體無效等情況下,window也會產生WM_PAINT消息,這時OnDraw 也被間接調用。 OnUpdate 是CView提供的一個方法,一般當文檔修改時調用,應用程序框架在CView::OnInitialUpdate 和CDocument::UpdateAllViews 的默認實現中都會調用 OnUpdate,OnUpdate的默認實現是通過Invalidate產生WM_PAINT,這時OnDraw又被調用了。 OnDraw除了你和應用程序框架間接調用外,window還可能間接調用它。 OnUpdate一般只有你的程序和應用程序框架會調用的。當然它的默認實現你可以改變的
**********************************************************************************************************************
OnInitUpdate是VIEW的初始化 OnUpdate是文檔多視時,響應其它視圖的改變 OnDraw和OnPaint都是繪圖。OnPaint調用OnDraw,並且調用OnPrepareDC ---------------------------------------------------------------


※MyBatis開發DAO的方式
※Linux 常用基本命令 ln
TAG:程序員小新人學習 |