青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

牽著老婆滿街逛

嚴以律己,寬以待人. 三思而后行.
GMail/GTalk: yanglinbo#google.com;
MSN/Email: tx7do#yahoo.com.cn;
QQ: 3 0 3 3 9 6 9 2 0 .

OnPaint()函數(shù)的作用原理

轉(zhuǎn)載自:http://blog.sina.com.cn/s/blog_4b3c1f950100dmhm.html

WM_PAINT是窗口每次重繪都會產(chǎn)生的一個消息。

OnPaint是對這個消息的反應(yīng)函數(shù)

 

mfc 的 CWnd::OnPaint 沒做什么,只是丟給系統(tǒng)處理。

一 :

   先執(zhí)行OnEraseBkgnd,擦除背景(如果想自繪控件,這個函數(shù)直接return TRUE就可以了,這樣就不會擦除背景,不會閃)

 

OnEraseBkGnd與OnPaint的區(qū)別與聯(lián)系

在OnEraseBkGnd中,如果你不調(diào)用原來缺省的OnEraseBkGnd只是重畫背景則不會有閃爍.而在OnPaint里面,由于它隱含的調(diào)用了OnEraseBkGnd,而你又沒有處理OnEraseBkGnd 函數(shù),這時就和窗口缺省的背景刷相關(guān)了.缺省的 OnEraseBkGnd操作使用窗口的缺省背景刷刷新背景(一般情況下是白刷),而隨后你又自己重畫背景造成屏幕閃動.

OnEraseBkGnd不是每次都會被調(diào)用的.如果你調(diào)用Invalidate的時候參數(shù)為TRUE,那么在OnPaint里面隱含調(diào)用BeginPaint的時候就產(chǎn)生WM_ERASEBKGND消息,如果參數(shù)是FALSE,則不會重刷背景.

ZYP解釋:void Invalidate( BOOL bErase = TRUE ); 該函數(shù)的作用是使整個窗口客戶區(qū)無效。窗口的客戶區(qū)無效意味著需要重繪,參數(shù)bErase為TRUE時,重繪區(qū)域內(nèi)的背景將被重繪即擦除,否則,背景將保持不變。調(diào)用Invalidate等函數(shù)后窗口不會立即重繪,這是由于WM_PAINT消息的優(yōu)先級很低,它需要等消息隊列中的其它消息發(fā)送完后才能被處理。

OnPaint里面會調(diào)用BeginPaint函數(shù)自動設(shè)置顯示設(shè)備內(nèi)容的剪切區(qū)域而排除任何更新區(qū)域外的區(qū)域更新區(qū)域。如果更新區(qū)域被標記為可擦除的,BeginPaint發(fā)送一個WM_ERASEBKGND消息給窗口。WM_ERASEBKGND消息的響應(yīng)函數(shù)既是OnEraseBkGnd()

所以解決方法有三個半:
1.用OnEraseBkGnd實現(xiàn),不要調(diào)用原來的OnEraseBkGnd函數(shù).
2.用OnPaint實現(xiàn),同時重載OnEraseBkGnd,其中直接返回.
3.用OnPaint實現(xiàn),創(chuàng)建窗口時設(shè)置背景刷為空
4.用OnPaint實現(xiàn),但是要求刷新時用Invalidate(FALSE)這樣
的函數(shù).(不過這種情況下,窗口覆蓋等造成的刷新還是要閃一
下,所以不是徹底的解決方法)
都挺簡單的.


在MFC中 任何一個window元件的繪圖 都是放在這兩個member function中
在設(shè)定上 OnEraseBkgnd()是用來畫底圖的 而OnPaint()是用來畫主要物件的
舉例說明 一個按鈕是灰色的 上面還有文字
則OnEraseBkgnd()所做的事就是把按鈕畫成灰色
而OnPaint()所做的事 就是畫上文字


既然這兩個member function都是用來畫出元件的
那為何還要分OnPaint() 與 OnEraseBkgnd() 呢
其實OnPaint() 與 OnEraseBkgnd() 特性是有差的
1. OnEraseBkgnd()的要求是快速在裡面的繪圖程式最好是不要太耗時間
因為每當window元件有任何小變動都會馬上呼叫OnEraseBkgnd()
2. OnPaint() 是只有在程式有空閒的時候才會被呼叫
3. OnEraseBkgnd() 是在 OnPaint() 之前呼叫的
所以 OnPaint()被呼叫一次之前 可能會呼叫OnEraseBkgnd()好幾次

如果我們是一個在做圖形化使用者介面的人
常會需要把一張美美的圖片設(shè)為我們dialog的底圖
把繪圖的程式碼放在OnPaint() 之中 可能會常碰到一些問題
比方說拖曳一個視窗在我們做的dialog上面一直移動
則dialog會變成灰色 直到動作停止才恢復(fù)
這是因為每次需要重繪的時候 程式都會馬上呼叫OnEraseBkgnd()
OnEraseBkgnd()就把dialog畫成灰色
而只有動作停止之後 程式才會呼叫OnPaint() 這時才會把我們要畫的底圖貼上去

這個問題的解法 比較差點的方法是把OnEraseBkgnd() 改寫成不做事的function
如下所示

BOOL CMyDlg::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}


以上本來是會呼叫CDialog::OnEraseBkgnd() 但是如果我們不呼叫的話
程式便不會畫上灰色的底色了

Q:基于對話框的程序中如何重載OnEraseBkGnd()函數(shù)

A:這是一個消息WM_ERASEBKWND  
  在CLASS   WIZARD中  
  選擇CLASSINFO頁面  
  在MESSAGEFILTER中的選項設(shè)在WINDOW就可以看到這個消息了.


比較好的做法是直接將繪圖的程式從OnPaint()移到OnEraseBkgnd()來做
如下所示

// m_bmpBKGND 為一CBitmap物件 且事先早已載入我們的底圖
// 底圖的大小與我們的視窗client大小一致


BOOL CMyDlg::OnEraseBkgnd(CDC
* pDC)
{
CRect rc;
GetUpdateRect(
&rc);
CDC srcDC;
srcDC.CreateCompatibleDC(pDC);
srcDC.SelectObject(m_bmpBKGND);

pDC
->BitBlt(rc.left,rc.top,rc.GetWidth(),
rc.GetHeight(),
&srcDC,rc.left,rc.top,SRCCOPY);
return TRUE;
}

特別要注意的是 取得重畫大小是使用GetUpdateRect() 而不是GetClientRect()
如果使用GetClientRect() 會把不該重畫的地方重畫
來自:http://hi.baidu.com/%BF%AA%D0%C4_%D0%D6%B5%DC/blog/item/2f6d3b10b6c622fac2ce79a5.html
   

二 :

     系統(tǒng)的Onpaint中調(diào)用了OnDraw,但如果我們自己繼承了一個OnPaint函數(shù)又沒有顯式調(diào)用OnDraw,則OnDraw就不會被調(diào)用,OnInitialUpdate在OnDraw之前,是窗口被創(chuàng)建以后調(diào)用的第一個函數(shù)。

 

MFC中OnDraw與OnPaint的區(qū)別

在OnPaint中調(diào)用OnDraw,一般來說,用戶自己的繪圖代碼應(yīng)放在OnDraw中。

OnPaint()是CWnd的類成員,負責(zé)響應(yīng)WM_PAINT消息。OnDraw()是CVIEW的成員函數(shù),沒有響應(yīng)消息的功能.當視圖變得無效時(包括大小的改變,移動,被遮蓋等等),Windows發(fā)送WM_PAINT消息。該視圖的OnPaint 處理函數(shù)通過創(chuàng)建CPaintDC類的DC對象來響應(yīng)該消息并調(diào)用視圖的OnDraw成員函數(shù).OnPaint最后也要調(diào)用OnDraw,因此一般在OnDraw函數(shù)中進行繪制。


The WM_PAINT message is sent when the UpdateWindow or RedrawWindow member function is called.

在OnPaint中,將調(diào)用BeginPaint,用來獲得客戶區(qū)的顯示設(shè)備環(huán)境,并以此調(diào)用GDI函數(shù)執(zhí)行繪圖操作。在繪圖操作完成后,將調(diào)用EndPaint以釋放顯示設(shè)備環(huán)境。而OnDraw在BeginPaint與EndPaint間被調(diào)用。(一個應(yīng)用程序除了響應(yīng)WM_PAINT消息外,不應(yīng)該調(diào)用BeginPaint。每次調(diào)用BeginPaint都應(yīng)該有相應(yīng)的EndPaint函數(shù)。

1) 在mfc結(jié)構(gòu)里OnPaint是CWnd的成員函數(shù). OnDraw是CView的成員函數(shù).
2) OnPaint()調(diào)用OnDraw(),OnPrint也會調(diào)用OnDraw(),所以O(shè)nDraw()是顯示和打印的共同操作。

OnPaint是WM_PAINT消息引發(fā)的重繪消息處理函數(shù),在OnPaint中會調(diào)用OnDraw來進行繪圖。OnPaint中首先構(gòu)造一個CPaintDC類得實例,然后一這個實例為參數(shù)來調(diào)用虛函數(shù)OnPrepareDC來進行一些繪制前的一些處理,比設(shè)置映射模式,最后調(diào)用OnDraw。而
OnDraw和OnPrepareDC不是消息處理函數(shù)。所以在不是因為重繪消息所引發(fā)的OnPaint導(dǎo)致OnDraw被調(diào)用時,比如在OnLButtonDown等消息處理函數(shù)中繪圖時,要先自己調(diào)用OnPrepareDC。
至于CPaintDC和CClientDC根本是兩回事情 CPaintDC是一個設(shè)備環(huán)境類,在OnPaint中作為參數(shù)傳遞給OnPrepareDC來作設(shè)備環(huán)境的設(shè)置。真正和CClientDC具有可比性的是CWindowDC,他們一個是描述客戶區(qū)域,一個是描述整個屏幕。
如果是對CVIEW或從CVIEW類派生的窗口繪圖時應(yīng)該用OnDraw。

OnDraw()和OnPaint()有什么區(qū)別呢?
首先:我們先要明確CView類派生自CWnd類。而OnPaint()是CWnd的類成員,同時負責(zé)響應(yīng)WM_PAINT消息。OnDraw()是CVIEW的成員函數(shù),并且沒有響應(yīng)消息的功能。這就是為什么你用VC成的程序代碼時,在視圖類只有OnDraw沒有
OnPaint的原因。而在基于對話框的程序中,只有OnPaint。
其次:我們在第《每天跟我學(xué)MFC》3的開始部分已經(jīng)說到了。要想在屏幕上繪圖或顯示圖形,首先需要建立設(shè)備環(huán)境DC。其實DC是一個數(shù)據(jù)結(jié)構(gòu),它包含輸出設(shè)備(不單指你17寸的純屏顯示器,還包括打印機之類的輸出設(shè)備)的繪圖屬性的描述。MFC提供了CPaintDC類和CWindwoDC類來實時的響應(yīng),而CPaintDC支持重畫。當視圖變得無效時(包括大小的改變,移動,被遮蓋等等),Windows 將 WM_PAINT 消息發(fā)送給它。該視圖的OnPaint 處理函數(shù)通過創(chuàng)建 CPaintDC 類的DC對象來響應(yīng)該消息并調(diào)用視圖的 OnDraw 成員函數(shù)。通常我們不必編寫重寫的 OnPaint 處理成員函數(shù)。


///CView默認的標準的重畫函數(shù)
void CView::OnPaint() //見VIEWCORE.CPP
{

CPaintDC dc(
this);
OnPrepareDC(
&dc);
OnDraw(
&dc); //調(diào)用了OnDraw
}

///CView默認的標準的OnPrint函數(shù)
void CView::OnPrint(CDC* pDC, CPrintInfo*)
{
ASSERT_VALID(pDC);
OnDraw(pDC); 
// Call Draw
}



既然OnPaint最后也要調(diào)用OnDraw,因此我們一般會在OnDraw函數(shù)中進行繪制。下面是一個典型的程序。

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

CMyDoc
* pDoc = GetDocument();
CString s 
= pDoc->GetData();
GetClientRect( 
&rect ); // Returns a CString CRect rect;
pDC->SetTextAlign( TA_BASELINE | TA_CENTER );
pDC
->TextOut( rect.right / 2, rect.bottom / 2, s, s.GetLength() );
}




最后:現(xiàn)在大家明白這哥倆之間的關(guān)系了吧。因此我們一般用OnPaint維護窗口的客戶區(qū)(例如我們的窗口客戶區(qū)加一個背景圖片),用OnDraw維護視圖的客戶區(qū)(例如我們通過鼠標在視圖中畫圖)。當然你也可以不按照上面規(guī)律來,只要達到目的并且沒有問題,怎么干都成。補充:我們還可以利用Invalidate(),ValidateRgn(),ValidateRect()函數(shù)強制的重畫窗口,具體的請參考MSDN吧。

OnDraw中可以繪制用戶區(qū)域。OnPaint中只是當窗口無效時重繪不會保留CClientDC繪制的內(nèi)容。

這兩個函數(shù)有區(qū)別也有聯(lián)系:

1、區(qū)別:OnDraw是一個純虛函數(shù),定義為virtual void OnDraw( CDC* pDC ) = 0; 而OnPaint是一個消息響應(yīng)函數(shù),它響應(yīng)了WM_PANIT消息,也是是窗口重繪消息。

2、聯(lián)系:我們一般在視類中作圖的時候,往往不直接響應(yīng)WM_PANIT消息,而是重載OnDraw純虛函數(shù),這是因為在CVIEW類中的WM_PANIT消息響應(yīng)函數(shù)中調(diào)用了OnDraw函數(shù),如果在CMYVIEW類中響應(yīng)了WM_PAINT消息,不顯式地調(diào)用OnDraw函數(shù)的話,是不會在窗口重繪的時候調(diào)用OnDraw函數(shù)的。

應(yīng)用程序中幾乎所有的繪圖都在視圖的 OnDraw 成員函數(shù)中發(fā)生,必須在視圖類中重寫該成員函數(shù)。(鼠標繪圖是個特例,這在通過視圖解釋用戶輸入中討論。)


OnDraw 重寫:
通過調(diào)用您提供的文檔成員函數(shù)獲取數(shù)據(jù)。
通過調(diào)用框架傳遞給 OnDraw 的設(shè)備上下文對象的成員函數(shù)來顯示數(shù)據(jù)。
當文檔的數(shù)據(jù)以某種方式更改后,必須重繪視圖以反映該更改。默認的 OnUpdate 實現(xiàn)使視圖的整個工作區(qū)無效。當視圖變得無效時,Windows 將 WM_PAINT 消息發(fā)送給它。該視圖的 OnPaint 處理函數(shù)通過創(chuàng)建 CPaintDC 類的設(shè)備上下文對象來響應(yīng)該消息并調(diào)用視圖的 OnDraw 成員函數(shù)。

當沒有添加WM_PAINT消息處理時,窗口重繪時,由OnDraw來進行消息響應(yīng)...當添加WM_PAINT消息處理時,窗口重繪時,WM_PAINT消息被投遞,由OnPaint來進行消息響應(yīng).這時就不能隱式調(diào)用OnDraw了.必須顯式調(diào)用(
CDC *pDC=GetDC(); OnDraw(pDC); )..
隱式調(diào)用:當由OnPaint來進行消息響應(yīng)時,系統(tǒng)自動調(diào)用CView::OnDraw(&pDC).


想象一下,窗口顯示的內(nèi)容和打印的內(nèi)容是差不多的,所以,一般情況下,統(tǒng)一由OnDraw來畫。窗口前景需要刷新時,系統(tǒng)會會調(diào)用到OnPaint,而OnPaint一般情況下是對DC作一些初始化操作后,調(diào)用OnDraw()。


OnEraseBkGnd(),是窗口背景需要刷新時由系統(tǒng)調(diào)用的。明顯的一個例子是設(shè)置窗口的背景顏色(你可以把這放在OnPaint中去做,但是會使產(chǎn)生閃爍的現(xiàn)象)。

至于怎么界定背景和前景,那要具體問題具體分析了,一般情況下,你還是很容易區(qū)別的吧。

的確,OnPaint()用來響應(yīng)WM_PAINT消息,視類的OnPaint()內(nèi)部根據(jù)是打印還是屏幕繪制分別以不同的參數(shù)調(diào)用OnDraw()虛函數(shù)。所以在OnDraw()里你可以區(qū)別對待打印和屏幕繪制。
其實,MFC在進行打印前后還做了很多工作,調(diào)用了很多虛函數(shù),比如OnPreparePrint()等。


另外OnInitialUpdate

視圖窗口完全建立后第一個被框架調(diào)用的函數(shù)。框架在第一次調(diào)用OnDraw前會調(diào)用OnInitialUpdate,因此OnInitialUpdate是設(shè)置滾動視圖的邏輯尺寸和映射模式的最合適的地方。

posted on 2009-07-30 12:40 楊粼波 閱讀(2058) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美一区二区高清| 亚洲一区二区精品视频| 亚洲国产日韩美| 精品福利电影| 麻豆精品网站| 亚洲伦理在线免费看| 黄色日韩网站| 美女爽到呻吟久久久久| 久久精品夜色噜噜亚洲aⅴ| 国产视频久久网| 在线亚洲+欧美+日本专区| 欧美一级专区| 亚洲电影av在线| 久久婷婷av| 日韩视频一区二区三区在线播放| 亚洲欧美激情在线视频| 欧美黑人国产人伦爽爽爽| 久久亚洲国产成人| …久久精品99久久香蕉国产| 欧美日韩国产在线播放网站| 亚洲欧美制服另类日韩| 欧美亚洲日本国产| 在线观看一区二区精品视频| 欧美日韩免费在线观看| 亚洲乱码日产精品bd| 香蕉视频成人在线观看| 国产精品扒开腿爽爽爽视频| 欧美在线观看一区| 91久久在线播放| 亚洲国内在线| 国产精品视频大全| 亚洲影视在线播放| 亚洲国产精品悠悠久久琪琪| 亚洲欧美成aⅴ人在线观看| 国产精品劲爆视频| 夜夜嗨av色一区二区不卡| 亚洲一区二区三区四区五区午夜| 韩国欧美一区| 欧美aⅴ99久久黑人专区| 欧美成人自拍| 亚洲欧洲在线一区| 国产麻豆精品theporn| 欧美高清视频一区二区| 欧美一区二区三区喷汁尤物| 亚洲精品国精品久久99热一| 麻豆免费精品视频| 最新日韩在线| 欧美日韩和欧美的一区二区| 另类尿喷潮videofree| 亚洲福利一区| 亚洲一区二区三区乱码aⅴ蜜桃女 亚洲一区二区三区乱码aⅴ | 欧美成人精品1314www| 亚洲国产精品久久久久婷婷884| 欧美成人一品| 久久久蜜臀国产一区二区| 欧美大胆成人| 一区二区国产在线观看| 国产精品久久久久久亚洲调教 | 国产精品一区在线观看| 欧美亚洲系列| 亚洲在线不卡| 亚洲色图自拍| 一区二区三区视频在线播放| 久久久999国产| 91久久久久久久久| 樱花yy私人影院亚洲| 国产日韩欧美一区二区三区四区| 美女主播精品视频一二三四| 一本一本久久a久久精品牛牛影视| 欧美激情精品久久久久久久变态| 你懂的亚洲视频| 美日韩在线观看| 美女视频黄 久久| 午夜亚洲福利| 亚洲激情影视| 亚洲人成欧美中文字幕| 国产精品永久免费| 国产欧美视频一区二区| 欧美激情网友自拍| 午夜老司机精品| 亚洲国产免费看| 久久精品亚洲热| av不卡免费看| 国产午夜精品一区二区三区欧美 | 国产精品国产三级国产普通话99| 欧美制服丝袜| 久久久精品一区二区三区| 99综合在线| 西西人体一区二区| 亚洲免费观看高清完整版在线观看| 亚洲人成久久| 欧美国产成人精品| 亚洲日产国产精品| 欧美a级在线| 亚洲美女黄色| 亚洲国产精品成人久久综合一区 | 99国产一区| 亚洲免费网址| 99re这里只有精品6| 欧美a级大片| 亚洲精品一区二区三区四区高清 | 激情欧美国产欧美| 国产精品一区二区在线观看| 欧美日韩另类在线| 国产精品亚洲综合| 欧美日韩一级黄| 国产一区二区| 亚洲精选中文字幕| 欧美亚洲综合在线| 欧美国产高潮xxxx1819| 亚洲视频在线看| 一本色道久久综合亚洲二区三区| 亚洲综合国产| 欧美成人福利视频| 国产欧美婷婷中文| 国产日韩欧美在线播放| 亚洲激情中文1区| 91久久线看在观草草青青| 亚洲特黄一级片| 欧美二区视频| 亚洲国产黄色| 亚洲高清视频一区| 性欧美超级视频| 欧美女激情福利| 精品动漫3d一区二区三区免费版| 国模私拍视频一区| 国产综合18久久久久久| 日韩视频精品在线观看| 一区二区三区**美女毛片| 久久久91精品国产一区二区三区| 久久久999成人| 久久永久免费| 亚洲在线视频| 欧美日韩成人在线| 1024亚洲| 久久精品一区二区三区不卡牛牛 | 欧美好吊妞视频| 樱花yy私人影院亚洲| 欧美亚洲三级| 米奇777超碰欧美日韩亚洲| 亚洲一区二区免费看| 欧美激情精品久久久久久| 黄色成人免费观看| 欧美一区2区视频在线观看| 久久久久久久999| 亚洲免费小视频| 欧美日韩一区在线观看| 日韩午夜黄色| 欧美激情第五页| 久久久久久香蕉网| 极品日韩久久| 亚洲少妇在线| 久久人91精品久久久久久不卡| 亚洲美女精品久久| 欧美一级视频免费在线观看| 国产精品国产三级国产专区53 | 免费欧美日韩国产三级电影| 欧美日韩国产成人高清视频| 91久久精品国产91久久| 免费国产自线拍一欧美视频| 亚洲美女黄网| 欧美日韩一区在线播放| 一区二区欧美激情| 久久综合伊人| 欧美在线首页| 欧美另类一区二区三区| 亚洲美女黄色片| 久久九九99视频| 久久精品国产视频| 激情综合色综合久久综合| 男女精品视频| 亚洲欧美久久久久一区二区三区| 麻豆乱码国产一区二区三区| 国产精品久久久久一区二区| 亚洲国产高清一区| 性做久久久久久久免费看| 欧美大成色www永久网站婷| 老巨人导航500精品| 亚洲精品麻豆| a4yy欧美一区二区三区| 国产精品日韩| 久久午夜视频| 亚洲中无吗在线| 激情综合色丁香一区二区| 欧美国产一区二区| 欧美日韩大片| 久久成人在线| 麻豆视频一区二区| 国内一区二区在线视频观看| 亚洲免费在线看| 日韩亚洲精品视频| 欧美高清视频一区二区| 精品动漫一区二区| 亚洲人www| 欧美激情精品久久久久久变态| 亚洲神马久久| 亚洲九九九在线观看| 欧美www视频| 亚洲国产清纯| 亚洲一级特黄|