ONERASEBKGND OnPaint OnDraw

來源:互聯網
上載者:User

ONERASEBKGND()是畫背景的,先與OnPaint()運行

OnPaint( )與OnDraw( )的區別:
OnPaint()是訊息響應函數,默認是WM_PAINT訊息的入口.
OnDraw()是虛函數,是被OnPaint( )調用的函數.
OnPaint( )優先於OnDraw( ),如果重載了OnPaint( ),則不會響應OnDraw( ).如果需要,則需明確調用OnDraw( )函數.   
   

都一樣的,OnDraw只不過是MFC和自己對OnPaint作了點手腳!
沒什麼和!
就是OnDraw裡面的東西按列印就會輸出到印表機!

樓上各位講的已經很明確,特別是Frank_Xu。
OnDraw()是虛函數,既然是虛函數,就可以被重載(重寫)。
的確,OnPaint()用來響應WM_PAINT訊息,視類的OnPaint()內部根據是列印還是螢幕繪製分別以不同的參數調用OnDraw()虛函數。
所以在OnDraw()裡你可以區別對待列印和螢幕繪製。
其實,MFC在進行列印前後還做了很多工作,調用了很多虛函數,比如OnPreparePrint()等。

在MFC程式設計中,按照傳統的設計,如果處理WM_PAINT訊息,一般會派生一個OnPaint函數,映射到WM_PAINT訊息上進行繪圖處理。但是很多程式中並沒有出現OnPaint,一個OnDraw函數做了更多的繪圖操作。而在訊息映射的列表中,也沒有見到WM_PAINT到OnDraw的映射。
實際上,OnDraw不是OnPaint的映射,出現OnDraw,是為了實現各種不同的裝置上的繪圖一致性。
首先,讀者需要明白的是,WM_PAINT訊息是為了繪製螢幕而出現的,因此,在OnPaint中,我們只能存取螢幕DC,進行繪製,常見的代碼是:
void MyWnd::OnPaint()
{
       CPaintDC dc(this);
     //draw code here
}
這裡的CPaintDC的建構函式會自動調用BeginPaint,獲得一個螢幕DC,並附加在dc對象上。當dc對象析構時,系統自動調用EndPaint並使invalidated rectangle變成validated狀態,從而結束繪製。(注意,重複建立CPaintDC執行個體會失敗也因為如此)

如果我們在OnPaint中繪製,那麼在印表機上繪製我們就需要再寫一個OnPrint函數,重新繪製。這樣,程式設計者就需要維護兩套代碼。為了簡化操作,MFC架構把大部分繪製操作都放在OnDraw中,OnPaint和OnPrint只構造相應的DC,然後分別調用OnDraw.也就是說,OnDraw適用於所有的裝置,而OnPaint只適用於螢幕。

大家在設計過程中必須注意:OnDraw是被基類的OnPaint主動調用的,如果你繼承了OnPaint,你應該要麼調用基類的OnPaint(此前不得建立CPaintDC執行個體,也不得調用BeginPaint),要麼自己建立CPaintDC執行個體,並調用OnDraw.

經常有朋友問雷神這樣的問題:我在視圖畫的圖象或者文字,當視窗改變後為什麼不見了?OnDraw()和OnPaint()兩個都是解決上面的問題,有什麼不同?

雷神在這裡一併解答一下吧。OnDraw()和OnPaint()好象兄弟倆,因為它們的工作類似。

至於不見了的問題簡單,因為當你的視窗改變後,會產生無效地區,這個無效的地區需要重畫。一般Windows回傳送兩個訊息WM_PAINT(通知客戶區有變化)和WM_NCPAINT(通知非客戶區有變化)。非客戶區的重畫系統自己搞定了,而客戶區的重畫需要我們自己來完成。這就需要OnDraw()或OnPaint()來重畫視窗。

OnDraw()和OnPaint()有什麼區別呢?首先:我們先要明確CView類派生自CWnd類。而OnPaint()是CWnd的類成員,同時負責響應WM_PAINT訊息。OnDraw()是CVIEW的成員函數,並且沒有響應訊息的功能。這就是為什麼你用VC成的程式碼時,在視圖類只有OnDraw沒有OnPaint的原因。

其次:我們在第《每天跟我學MFC》3的開始部分已經說到了。要想在螢幕上繪圖或顯示圖形,首先需要建立裝置環境DC。其實DC是一個資料結構,它包含輸出裝置(不單指你17寸的純屏顯示器,還包括印表機之類的輸出裝置)的繪圖屬性的描述。MFC提供了CPaintDC類和CWindwoDC類來即時的響應,而CPaintDC支援重畫。

當視圖變得無效時(包括大小的改變,移動,被遮蓋等等),Windows 將 WM_PAINT 訊息發送給它。該視圖的 OnPaint 處理函數通過建立 CPaintDC 類的DC對象來響應該訊息並調用視圖的 OnDraw 成員函數。通常我們不必編寫重寫的 OnPaint 處理成員函數。

///CView預設的標準的重畫函數

void CView::OnPaint()

{

    CPaintDC dc(this);

    OnPreparDC(&dc);

    OnDraw(&dc); //調用了OnDraw

}

既然OnPaint最後也要調用OnDraw,因此我們一般會在OnDraw函數中進行繪製。下面是一個典型的程式

///視圖中的繪圖代碼首先檢索指向文檔的指標,然後通過DC進行繪圖調用。void CMyView::OnDraw( CDC* pDC )

{

    CMyDoc* pDoc = GetDocument();

    CString s = pDoc->GetData(); // Returns a CString CRect rect;

    GetClientRect( &rect );

    pDC->SetTextAlign( TA_BASELINE | TA_CENTER );

    pDC->TextOut( rect.right / 2, rect.bottom / 2, s, s.GetLength() );

}

最後:現在大家明白這哥倆之間的關係了吧。因此我們一般用OnPaint維護視窗的客戶區(例如我們的視窗客戶區加一個背景圖片),用OnDraw維護視圖的客戶區(例如我們通過滑鼠在視圖中畫圖)。當然你也可以不按照上面規律來,只要達到目的並且沒有問題,怎麼幹都成。

補充:我們還可以利用Invalidate(),ValidateRgn(),ValidateRect()函數強制的重畫視窗,具體的請參考MSDN吧。本文完

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.