先看一段移動圖片的程序:
??
?? 繪圖工作都在ReDraw()中
? 響應(yīng)MouseMove? 改變圖片的位置,鼠標(biāo)移動后需要重繪窗口
?
實驗一: ReDraw()在MouseMove函數(shù)中調(diào)用
[html] view plaincopy print?
OnMouseMove(UINT?nFlags,?CPoint?point)??{??????。。。????????????????ReDraw();??????????????InvalidateRect(m_ClientRect);??????。。。??}??
OnMouseMove(UINT nFlags, CPoint point)
{。。。ReDraw();InvalidateRect(m_ClientRect); 。。。
}
[html] view plaincopy print?
試驗發(fā)現(xiàn):?鼠標(biāo)移動時,圖片移動不連貫,也就是說窗口沒有實時重繪,而是每隔不定的時間重繪一次,這樣圖片移動時給人磕磕絆絆、很不順暢的感覺。??
試驗發(fā)現(xiàn): 鼠標(biāo)移動時,圖片移動不連貫,也就是說窗口沒有實時重繪,而是每隔不定的時間重繪一次,這樣圖片移動時給人磕磕絆絆、很不順暢的感覺。
?
試驗二: ReDraw()在OnDraw函數(shù)中調(diào)用
?
[html] view plaincopy print?
OnDraw(CDC*?pDC)??{????...??????ReDraw();????...??}??
OnDraw(CDC* pDC)
{...ReDraw();...
}
?
[html] view plaincopy print?
OnMouseMove(UINT?nFlags,?CPoint?point)??{??????。。。????????????????//ReDraw();??注釋掉ReDraw(),僅使用InvalidateRect()??????????????InvalidateRect(m_ClientRect);?????????。。。??}??
OnMouseMove(UINT nFlags, CPoint point)
{。。。//ReDraw(); 注釋掉ReDraw(),僅使用InvalidateRect()InvalidateRect(m_ClientRect); 。。。
}
試驗發(fā)現(xiàn):圖片能夠隨鼠標(biāo)實時移動,也就是說窗口得到了實時更新
?
那問題自然就來了:為什么兩個試驗,結(jié)果迥然?
要說InvalidateRect()不能馬上更新窗口,那為什么試驗二的效果看起來如立即更新一樣?
據(jù)我分析,可能的原因是這樣的:
????????首先,InvalidateRect()不能馬上更新窗口,而是將更新消息WM_PAINT放在消息隊列中,在實驗二中,消息隊列中的消息很少,所以很快便執(zhí)行到了WM_PAINT,而實驗一中,在InvalidateRect()之前還要執(zhí)行ReDraw(),執(zhí)行ReDraw()需要一段時間,這段時間,因為鼠標(biāo)一直移動,所以一直將鼠標(biāo)移動消息放入消息隊列中,因此,WM_PAINT前的消息多,所以便出現(xiàn)了圖片移動不連貫的現(xiàn)象。
?
試驗三 :ReDraw()放入MouseMOVE函數(shù)中 使用UpDateWindow()
?
[cpp] view plaincopy print?
OnMouseMove(UINT?nFlags,?CPoint?point)??{??????。。。??????????????ReDraw();??????????????UpdateWindow();?????????。。。??}??
OnMouseMove(UINT nFlags, CPoint point)
{。。。ReDraw();UpdateWindow();。。。
}
按相關(guān)資料說:UpdateWindow()可以立即更新窗口,那么這下應(yīng)該沒有問題了吧!
可是,試驗顯示,鼠標(biāo)移動時,圖片穩(wěn)如磐石,絲毫不動。而只有窗口最小化然后最大化需要重繪時,圖片才顯示到鼠標(biāo)所在的位置
怎么回事?怎么回事呀,資料上不是說UpdateWindow()立即更新窗口嗎?怎么試驗結(jié)果好像差之千里。。。
?
別急: 先找找原因。
誠然,UpdateWindow() 可以實現(xiàn)立即更新,但是它是有前提的。
什么?沒找到前提條件?只看到資料說立即更新?---------這就是不完善的資料造成的后果
額。。。-----還有一種就是明明資料上有介紹,是自己忽視了
?
UpdateWindow() 可以實現(xiàn)立即更新,但是它的前提是:先讓需要更新的區(qū)域失效。
?
試驗四: 使用UpdateWindow()更新窗口
[cpp] view plaincopy print?
OnMouseMove(UINT?nFlags,?CPoint?point)??{??????。。。?????????????????????ReDraw();?????????????????????????????InvalidateRect(m_ClientRect);?????????????????UpdateWindow();?????????。。。??}??
OnMouseMove(UINT nFlags, CPoint point)
{。。。ReDraw();InvalidateRect(m_ClientRect); //先將需要更新的區(qū)域 用InvalidateRect失效掉,然后再UpdateWindow() UpdateWindow();。。。
}
結(jié)果顯示: 圖片移動連貫,可以實現(xiàn)立即更新
?
試驗五: 使用RedrawWindow()
?
?
[cpp] view plaincopy print?
OnMouseMove(UINT?nFlags,?CPoint?point)??{??????。。。?????????????????????ReDraw();??????????????????????????????RedrawWindow(m_ClientRect);???????。。。??}??
OnMouseMove(UINT nFlags, CPoint point)
{。。。ReDraw();RedrawWindow(m_ClientRect);。。。
}
結(jié)果顯示:圖片移動連貫,可以立即更新窗口
RedrawWindow(m_ClientRect); 效果相當(dāng)于InvalidateRect(m_ClientRect); UpdateWindow();
[cpp] view plaincopy print?
BOOL?RedrawWindow(LPCRECT?lpRectUpdate?=?NULL,??????CRgn*?prgnUpdate?=?NULL,??????UINT?flags?=?RDW_INVALIDATE?|?RDW_UPDATENOW?|?RDW_ERASE);??
BOOL RedrawWindow(LPCRECT lpRectUpdate = NULL,CRgn* prgnUpdate = NULL,UINT flags = RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
這是 RedrawWindow()的定義,由此得知:默認參數(shù)情況下是立即更新窗口
RedrawWindow(rect) 相當(dāng)于:
[cpp] view plaincopy print?
RedrawWindow(m_ClientRect,NULL,?RDW_INVALIDATE?|?RDW_UPDATENOW?|?RDW_ERASE);??
RedrawWindow(m_ClientRect,NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
總結(jié):?
???? ? 由以上五個例子分析了三者之區(qū)別,簡言之,InvalidateRect()不能實現(xiàn)立即更新?,
???????但是InvalidateRect()與?UpdateWindow()結(jié)合后可以實現(xiàn)立即更新,
?????? 兩者結(jié)合的效果相當(dāng)于RedrawWindow(rect)
總結(jié)
以上是生活随笔為你收集整理的InvalidateRect()、UpdateWindow()、RedrawWindow()区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。