国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開(kāi)通VIP
WM_PAINT詳解
WM_PAINT發(fā)送條件是"The WM_PAINT message is sent when the system or another application makes a request to paint a portion of an application's window."那什么時(shí)候系統(tǒng)或其他應(yīng)用程序會(huì)發(fā)送重畫請(qǐng)求呢?需要重畫的"portion"又有多大呢?再往下看,"The message is sent when the UpdateWindow or RedrawWindow function is called, or by the DispatchMessage function when the application obtains a WM_PAINT message by using the GetMessage or PeekMessage function. "這就說(shuō)明這個(gè)WM_PAINT消息既可能由系統(tǒng)發(fā)送,也可能由應(yīng)用程序人工發(fā)送。這個(gè)很好理解。當(dāng)窗口的一部分被其它窗口遮蓋而復(fù)原,或者從最小化狀態(tài)恢復(fù)到正常狀態(tài)時(shí),系統(tǒng)自然會(huì)要求窗口重畫。系統(tǒng)重畫窗口的條件可以參見(jiàn)MSDN\Platform SDK\Windows GDI\Painting and Drawing\When to Draw in a window. 而有時(shí)候我們需要窗口的某些部分作出改變,就得人工要求窗口重畫(通過(guò)調(diào)用UpdateWindow和RedrawWindow)。比如我的基礎(chǔ)類庫(kù)里窗口上沒(méi)有任何Windows意義上的控件(有hWnd),只是人為定義某一個(gè)區(qū)域是一個(gè)“按鈕”,當(dāng)鼠標(biāo)指向這個(gè)區(qū)域時(shí)加載hover圖像以獲得hottrack效果。這時(shí)操作系統(tǒng)自然不會(huì)認(rèn)為有重畫的必要,但程序卻必須重畫,這時(shí)就得人工發(fā)送WM_PAINT消息了。注意不要傻乎乎地直接用SendMessage或PostMessage發(fā)送WM_PAINT,后面會(huì)解釋原因。
由于重畫很費(fèi)時(shí)間和資源,并且也不是應(yīng)用程序的“主業(yè)”,因此系統(tǒng)也知道要盡量減少重畫的次數(shù)。系統(tǒng)只在應(yīng)用程序的消息隊(duì)列為空的時(shí)候才發(fā)送WM_PAINT,這就是為什么當(dāng)程序死鎖時(shí)窗口圖像不會(huì)更新。同樣為了減少重畫的工作量,Windows提出了update region的概念,"The update region identifies the portion of a window that is out-of-date or invalid and in need of redrawing. The system uses the update region to generate WM_PAINT messages for applications and to minimize the time applications spend bringing the contents of their windows up to date. "也就是說(shuō),Windows會(huì)判斷窗口的哪些區(qū)域需要重畫,這個(gè)區(qū)域就是update region. 比如原來(lái)在窗口上面的一個(gè)窗口現(xiàn)在挪走了,系統(tǒng)就把新露出來(lái)的區(qū)域定義為update region(這個(gè)過(guò)程稱為invalidate)。系統(tǒng)不斷檢測(cè)一個(gè)窗口的update region是否為空,當(dāng)update region不為空并且應(yīng)用程序沒(méi)有消息要處理(消息隊(duì)列為空)的時(shí)候,系統(tǒng)就通過(guò)WM_PAINT告訴應(yīng)用程序“現(xiàn)在沒(méi)事干了?窗口的一部分需要重畫,你把這一部分重畫一下”。應(yīng)用程序重畫了窗口之后,把update region重新設(shè)置為空(這個(gè)過(guò)程稱為validate),如此不斷循環(huán)。如果消息隊(duì)列不為空,系統(tǒng)就把update region不斷更新(采用取并集的方法),等消息隊(duì)列為空的時(shí)候一起處理。這就大大減少了重畫的次數(shù)。
這樣你或許就明白了為什么不能直接用SendMessage和PostMessage發(fā)送WM_PAINT的原因:由于沒(méi)有invalidate,系統(tǒng)認(rèn)為窗口沒(méi)有更新的必要,于是就對(duì)發(fā)來(lái)的WM_PAINT消息不理不睬。解決方案就是——我們自己invalidate!相關(guān)的API就是InvalidateRect()和InvalidateRgn(). 畫完了之后用ValidateRect()和ValidateRgn()告訴系統(tǒng)“我畫完了”就行了??梢园裪nvalidate過(guò)程看成類似CombineRgn()取并集,把validate過(guò)程看成取差集即可。還有一些相關(guān)的API: GetUpdateRect(), GetUpdateRgn(), ExcludeUpdateRgn(), 從名字就能猜出個(gè)大概,各位可以自行去查MSDN.
在WM_PAINT消息處理過(guò)程中有兩個(gè)不得不提到的函數(shù):BeginPaint()和EndPaint(). 只有WM_PAINT消息處理能使用這兩個(gè)函數(shù)。實(shí)際上默認(rèn)消息處理函數(shù)DefWindowProc()對(duì)WM_PAINT的處理方式就是:
case WM_PAINT:
    PAINTSTRUCT ps;
    BeginPaint (hWnd, &ps);
    EndPaint (hWnd, &ps);
    return 0;
BeginPaint()和EndPaint()之所以不可或缺,就是因?yàn)樗鼈儗?shí)現(xiàn)了validate過(guò)程。BeginPaint()的主要任務(wù)之一就是validate. 如果在WM_PAINT的消息處理中直接return 0,update region就始終不為空,系統(tǒng)就會(huì)不停地發(fā)送WM_PAINT消息。EndPaint()負(fù)責(zé)釋放BeginPaint()返回的DC,做好善后工作(比如重新顯示BeginPaint()隱藏起來(lái)的光標(biāo))。
最后還有一點(diǎn)需要額外說(shuō)明:用WM_PAINT處理重畫是異步(asynchronous)的。也就是說(shuō),在invalidate之后窗口并不會(huì)立即重畫而是等到消息隊(duì)列為空時(shí)再重畫,這樣就有一個(gè)時(shí)間差。這個(gè)事件差有時(shí)短到不被注意,但有時(shí)就是個(gè)大問(wèn)題(尤其是當(dāng)程序需要執(zhí)行耗費(fèi)時(shí)間的任務(wù),如串口I/O)。這時(shí)可以采用同步重畫法,直接用GetDC()獲得hDC執(zhí)行重畫操作。如果非要使用WM_PAINT來(lái)同步重畫(個(gè)人比較喜歡這種方法,和重畫有關(guān)的代碼就應(yīng)該在WM_PAINT的處理程序里嘛),可以使用UpdateWindow()和RedrawWindow(). 這兩個(gè)API函數(shù)會(huì)直接把WM_PAINT送進(jìn)窗口的消息隊(duì)列而不是應(yīng)用程序的消息隊(duì)列,這樣就不用等到最后了。注意前者當(dāng)update region不為空時(shí)才會(huì)發(fā)送WM_PAINT,后者的控制選項(xiàng)更為豐富。
 
本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/ljfxmf/archive/2008/06/05/2513221.aspx
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
轉(zhuǎn):關(guān)于WM
VC窗口刷新InvalidateRect和UpdateWindow
Windows窗口刷新機(jī)制詳解
Invalidate和UpdateWindow的區(qū)別
SDK編程講座之第四講:Windows基礎(chǔ)結(jié)構(gòu)(1)(轉(zhuǎn)載)
設(shè)置雙緩沖減少窗體閃爍
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服