MFC重繪

Invalidate()與 UpdateAllViews()有什麼分別

Invalidate()是讓程序重畫窗口。

UpdateAllViews()是在DOC/VIEW結構中,

當一個視圖的數據改變後,

通知所有視圖作相應的改變,

和重畫毫無關係。

Invalidate()是使窗口無效,使系統向其發WM_PAINT消息,使的程序的OnPaint被調用重畫客戶區。

而UpdateAllViews()是文檔與視之間的聯繫,調用從它會使程序與此文檔相關的所有視的UpdateView被調用至於是否重畫以及怎麼畫是由各視的UpdateView來決定的。

Invalidate()是Cwnd的成員函數,與DOC-VIEW無關;

UpdateAllViews是CDocument的成員函數,具體體現DOC-VIEW的精神。

如果僅重畫當前窗口用 this->Invalidate();

如果通知所有和當前文檔相關的窗口重畫用GetDocument()->UpdateAllViews()(在View中)或this->UpdateAllViews()(在Doc中)。

Invalidate()函數產生一條WM_PAINT消息,並送入windows消息隊列中,是窗口產生重畫。

而,UpdateAllViews 並不進入windows消息隊列中,直接產生重畫

Invalidate函數的總結

InvalidateRect只是增加重繪區域,在下次WM_PAINT的時候才生效

InvalidateRect函數中的參數TRUE表示系統會在你畫之前用背景色將所選區域覆蓋一次,默認背景色爲白色,可以通過設置BRUSH來改變背景色。

Invalidate()之後:(MFC的,順便了)

OnPaint()->OnPrepareDC()->OnDraw()

所以只是刷新在OnPaint()和OnDraw()函數中的繪圖語句。其它地方沒有影響。

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

Invalidate只是放一個WM_PAINT消息在隊列裏,不做別的,所以只有噹噹前函數返回後,進入消息循環,取出WM_PAINT,才執行PAINT,所以不管Invalidate放哪裏,都是最後的。

InvalidateRect(hWnd,&rect,TRUE);向hWnd窗體發出WM_PAINT的消息,強制客戶區域重繪製,

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

UpdateWindow只向窗體發送WM_PAINT消息,在發送之前判斷GetUpdateRect(hWnd,NULL,TRUE)看有無可繪製的客戶區域,如果沒有,則不發送WM_PAINT

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

UpdateData()順便說下,這個函數不是刷新界面用的。

UpdateData();參數爲FALSE時,將界面上控件綁定的變量的數據導到控件內,參數爲TRUE時,導入方向則相反。


void UpdateAllViews( CView* pSender, LPARAM lHint = 0L, CObject* pHint = NULL );

NULL if all views are to be updated.

Remarks

Call this function after the document has been modified. You should call this function after you call the member function. This function informs each view attached to the document, except for the view specified by pSender, that the document has been modified. You typically call this function from your view class after the user has changed the document through a view.

參數: pSender 修改文檔的視圖的指針。如果所有視圖都被更新,則返回NULL。 
lHint 包含修改的信息。 
pHint 包含修改信息的對象指針。 
說明:
在文檔修改之後調用這個函數。應在調用SetModifiedFlag之後調用。除了pSender指定的視圖之外,函數通知與文檔連接的各個視圖   文檔已被修改的消息。通常在用戶通過視圖改動文檔後調用該函數。
除了發送視圖外,這個函數爲每個文檔視圖調用CView::OnUpdate ,並傳遞lHint和pHint值,使用這些參數將文檔的修改情況傳遞給視圖。可以使用lHint爲信息編碼,(或者)定義一個CObject派生類保存修改信息,並使用pHint傳遞一個該類對象。爲優化視圖更新,在CView派生類中可覆蓋CView::OnUpdate成員函數。


在Doc類中調用Invalidate重繪mfc窗口!

獲取視圖指針,再用Invalidate即可重繪mfc窗口。

代碼如下:

  CUABApp   *pApp=(CUABApp   *)AfxGetApp();   

  CMainFrame   *pMainFrame=(CMainFrame   *)pApp->m_pMainWnd;   

  CChildFrame   *pFrame=(CChildFrame   *)pMainFrame->GetActiveFrame();   

  CView   *pView=(CView   *)pFrame->GetActiveView();   

  pView->Invalidate();  

方法二:

POSITION pos = GetFirstViewPosition();

CView* pView = GetNextView(pos);

pView->Invalidate();


onDraw和onPaint函數的區別

CWnd::OnPaint() 是CWnd類的成員函數,是WM_PAINT 消息的響應函數.當你調用CWnd::UpdateWindow(),CWnd::RedrawWindow()時, 或者窗口被其他窗口覆蓋,改變大小等事件就會產生WM_PAINT 消息. 你可以在CWnd派生的子類中使用它.

CView::OnDraw()是CView類的一個純虛函數.你要使用,必須重載它.

CView::OnPaint()會調用它.

OnPaint是收到WM_PAINT消息時所調用的,OnPaint調用OnDraw函數,而由於OnDraw是虛擬函數,你可以自己改寫,所以就實現了,不同的繪圖目的

ondraw用於cview,而onpaint用於cdialog

onpait 響應WM_PAINT消息,在CView中,它接着調用OnDraw

CPaintDC響應wm_paint消息,自動完成繪製

ClientDC實時繪製

一般情況下,你看不到兩個函數有什麼太大區別,因爲一般情況下,它們的任務都是重畫窗口。

在CView及其子類中,恰如浪刀所言,OnDraw是由OnPaint調用的,也就是你可以像在窗口類中一樣,調用Invalidate函數導致,OnDraw的調用(當然,Invalidate是先導致OnPaint的調用)。

要說OnDraw和OnPaint有什麼區別,那就是它除了可以把畫畫到屏幕外,還可以把它畫到其它任何標準輸出設備,如打印機


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章