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有什么區別,那就是它除了可以把畫畫到屏幕外,還可以把它畫到其它任何標准輸出設備,如打印機


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM