日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

VC的MFC中重绘函数的使用总结(整理)

發(fā)布時(shí)間:2023/12/18 c/c++ 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VC的MFC中重绘函数的使用总结(整理) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

原文網(wǎng)址:http://www.cnblogs.com/x8023z/archive/2008/12/09/mfc33.html

在刷新窗口時(shí)經(jīng)常要調(diào)用重繪函數(shù)
MFC提供了三個(gè)函數(shù)用于窗口重繪
InvalidateRect(&Rect)
Invalidate()
UpdateWindow()
當(dāng)需要更新或者重繪窗口時(shí),一般系統(tǒng)會(huì)發(fā)出兩個(gè)消息WM_PAINT(通知客戶區(qū)有變化)和WM_NCPAINT(通知非客戶區(qū)有變化)
--WM_NVPAINT系統(tǒng)會(huì)自己搞定
--WM_PAINT消息對(duì)應(yīng)的函數(shù)是OnPaint(),它是系統(tǒng)默認(rèn)的接受WM_PAINT消息的函數(shù),但我們一般在程序中做重繪時(shí)都在OnDraw函數(shù)中進(jìn)行的,因?yàn)樵贠NPAIN函數(shù)中調(diào)用了ONDRAW函數(shù)。
///CView默認(rèn)的標(biāo)準(zhǔn)的重畫函數(shù)
void CView::OnPaint()
{
?? CPaintDC dc(this);
??? OnPreparDC(&dc);
??? OnDraw(&dc); //調(diào)用了OnDraw
}

上面講到
InvalidateRect(&Rect)
Invalidate()兩個(gè)函數(shù)形式和功能差不多,但I(xiàn)nvalidate是使得整個(gè)窗口無效,形成無效矩形,而InvalidateRect(&Rect)是使得指定的區(qū)域無效。

Invalidate()申明無效,等待WM_PAINT消息以便重繪,隊(duì)列中無其他消息時(shí)系統(tǒng)會(huì)自動(dòng)發(fā)送
UpdateWindow()會(huì)立即發(fā)送WM_PAINT,不過在它發(fā)送前,先調(diào)用GetUpdateRect(hWnd,NULL,TRUE)看有無可繪制區(qū)域,如果沒有則不發(fā)送消息RedrawWindow()RedrawWindow()則是具有Invalidate()和UpdateWindow()的雙特性。聲明窗口的狀態(tài)為無效,并立即更新窗口,立即調(diào)用WM_PAINT消息處理。

?

????? 系統(tǒng)為什么不在調(diào)用Invalidate時(shí)發(fā)送WM_PAINT消息呢?又為什么非要等應(yīng)用消息隊(duì)列為空時(shí)才發(fā)送WM_PAINT消息呢?這是因?yàn)橄到y(tǒng)把在窗口中的繪制操作當(dāng)作一種低優(yōu)先級(jí)的操作,于是盡可能地推后做。不過這樣也有利于提高繪制的效率:兩個(gè)WM_PAINT消息之間通過InvalidateRect和InvaliateRgn使之失效的區(qū)域就會(huì)被累加起來,然后在一個(gè)WM_PAINT消息中一次得到 更新,不僅能避免多次重復(fù)地更新同一區(qū)域,也優(yōu)化了應(yīng)用的更新操作。像這種通過InvalidateRect和InvalidateRgn來使窗口區(qū)域無效,依賴于系統(tǒng)。在合適的時(shí)機(jī)發(fā)送WM_PAINT消息的機(jī) 制實(shí)際上是一種異步工作方式,也就是說,在無效化窗口區(qū)域和發(fā)送WM_PAINT消息之間是有延遲的;有時(shí)候這種延遲并不是我們希望的,這時(shí)我們當(dāng)然可以在無效化窗口區(qū)域后利用SendMessage 發(fā)送一條WM_PAINT消息來強(qiáng)制立即重畫,但不如使用Windows GDI為我們提供的更方便和強(qiáng)大的函數(shù):UpdateWindow和RedrawWindow。UpdateWindow會(huì)檢查窗口的Update Region,當(dāng)其不為空時(shí)才發(fā)送WM_PAINT消息;RedrawWindow則給我們更多的控制:是否重畫非客戶區(qū)和背景,是否總是發(fā)送WM_PAINT消息而不管Update Region是否為空等。
BeginPaint和WM_PAINT消息緊密相關(guān)。試一試在WM_PAINT處理函數(shù)中不寫B(tài)eginPaint會(huì)怎樣?程序會(huì)像進(jìn)入了一個(gè)死循環(huán)一樣達(dá)到驚人的CPU占用率,你會(huì)發(fā)現(xiàn)程序總在處理一個(gè)接 一個(gè)的WM_PAINT消息。這是因?yàn)樵谕ǔG闆r下,當(dāng)應(yīng)用收到WM_PAINT消息時(shí),窗口的Update Region都是非空的(如果為空就不需要發(fā)送WM_PAINT消息了),BeginPaint的一個(gè)作用就是把該Update Region置為空,這樣如果不調(diào)用BeginPaint,窗口的Update Region就一直不為空,如前所述,系統(tǒng)就會(huì)一直發(fā)送WM_PAINT消息。

BeginPaint和WM_ERASEBKGND消息也有關(guān)系。當(dāng)窗口的Update Region被標(biāo)志為需要擦除背景時(shí),BeginPaint會(huì)發(fā)送WM_ERASEBKGND消息來重畫背景,同時(shí)在其返回信息里有一個(gè)標(biāo)志表明窗口背景是否被重畫過。當(dāng)我們用InvalidateRect和InvalidateRgn來把指定區(qū)域加到Update Region中時(shí),可以設(shè)置該區(qū)域是否需要被擦除背景,這樣下一個(gè)BeginPaint就知道是否需要發(fā)送WM_ERASEBKGND消息了。

?

另外要注意的一點(diǎn)是,BeginPaint只能在WM_PAINT處理函數(shù)中使用。

?

以下是Invalidate函數(shù)的作用::

void Invalidate( BOOL bErase = TRUE );?
該函數(shù)的作用是使整個(gè)窗口客戶區(qū)無效。窗口的客戶區(qū)無效意味著需要重繪,例如,如果一個(gè)被其它窗口遮住的窗口變成了前臺(tái)窗口,那么原來被遮住的部分就是無效的,需要重繪。這時(shí)Windows會(huì)在應(yīng)用程序的消息隊(duì)列中放置WM_PAINT消息。MFC為窗口類提供了WM_PAINT的消息處理函數(shù)OnPaint,OnPaint負(fù)責(zé)重繪窗口。視圖類有一些例外,在視圖類的OnPaint函數(shù)中調(diào)用了OnDraw函數(shù),實(shí)際的重繪工作由OnDraw來完成。參數(shù)bErase為TRUE時(shí),重繪區(qū)域內(nèi)的背景將被擦除,否則,背景將保持不變。

?

和 UpdateWindow( )區(qū)別在于:UpdateWindow( )的作用是使窗口立即重繪。調(diào)用Invalidate等函數(shù)后窗口不會(huì)立即重繪,這是由于WM_PAINT消息的優(yōu)先級(jí)很低,它需要等消息隊(duì)列中的其它消息發(fā)送完后才能被處理。調(diào)用UpdateWindow函數(shù)可使WM_PAINT被直接發(fā)送到目標(biāo)窗口,從而導(dǎo)致窗口立即重繪.

希望對(duì)有需要的人有用。。。。僅供參考!!有不對(duì)之處,請(qǐng)給位在評(píng)論中指出!謝謝。。。。

總結(jié)

以上是生活随笔為你收集整理的VC的MFC中重绘函数的使用总结(整理)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。