在使用VC開發(fā)圖形相關(guān)的應(yīng)用程序時(shí),,常常需要使用MFC的CDC類直接把圖形畫在窗口上,。這通常是通過響應(yīng)Windows的WM_PAINT消息實(shí)現(xiàn)的。如果要畫的圖形比較復(fù)雜,,或者比較大,,那么畫圖過程可能會造成窗口的閃爍。當(dāng)窗口調(diào)整大小時(shí),,這種閃爍由為明顯,。 解決窗口閃爍問題的有效辦法就是使用內(nèi)存DC,也稱為緩沖DC,。在內(nèi)存中準(zhǔn)備一個(gè)和窗口DC相同屬性的DC,,在這個(gè)內(nèi)存DC上執(zhí)行畫圖操作。完成畫圖以后,,把畫圖輸出的內(nèi)容整體復(fù)制到目標(biāo)窗口DC上,。因?yàn)楫媹D操作不在窗口DC上進(jìn)行,所以在畫圖的過程中窗口可以保持原來的內(nèi)容,。當(dāng)畫好的內(nèi)容被復(fù)制到窗口DC時(shí),,因?yàn)閺?fù)制操作執(zhí)行的非常快,,所以用戶感覺窗口仿佛被立刻被畫好,,從而消除了從舊畫面到白板再到新畫面的閃爍現(xiàn)象。 生成內(nèi)存DC主要用到以下四個(gè)函數(shù): CreateCompatibleDC(CDC* pDC ),。CDC類的成員函數(shù),,用于創(chuàng)建一個(gè)和pDC指向的DC兼容的內(nèi)存DC。 CreateCompatibleBitmap( CDC* pDC, int nWidth, int nHeight),。CBitmap類的成員函數(shù),,用于按指定尺寸創(chuàng)建一個(gè)和pDC指向的DC兼容的位圖。 SelectObject(CBitmap * pBitmap),。CDC類的成員函數(shù),,執(zhí)行以后,所以在該DC上的圖像輸出都將被畫到pBitmap指向的位圖上,。 BOOL BitBlt(HDC hdcDest,int nXDest,int nYDest,int nWidth,int nHeight,HDC hdcSrc,int nXSrc,int nYSrc,DWORD dwRop),;CDC類的成員函數(shù),用于從源DC(pSrcDC)復(fù)制一個(gè)矩形的圖象到當(dāng)前DC中,。
hdcDest:指向目標(biāo)設(shè)備環(huán)境的句柄,。 nXDest:指定目標(biāo)矩形區(qū)域左上角的X軸邏輯坐標(biāo)。 nYDest:指定目標(biāo)矩形區(qū)域左上角的Y軸邏輯坐標(biāo),。 nWidth:指定源和目標(biāo)矩形區(qū)域的邏輯寬度,。 nHeight:指定源和目標(biāo)矩形區(qū)域的邏輯高度。 hdcSrc:指向源設(shè)備環(huán)境的句柄,。 nXSrc:指定源矩形區(qū)域左上角的X軸邏輯坐標(biāo)。 nYSrc:指定源矩形區(qū)域左上角的Y軸邏輯坐標(biāo)。 過程:
1.以屏幕DC建立內(nèi)存DC(CreateCompatibleDC)以屏幕DC建立位圖(CreateCompatibleBitmap) 大小使用GetClientRect取得客戶區(qū)大小 將上面創(chuàng)建的位圖選入內(nèi)存DC中(SelectObject)
2.所有的繪圖動(dòng)作都針對內(nèi)存DC進(jìn)行,。
3.完成繪圖動(dòng)作后,將內(nèi)存DC中內(nèi)容復(fù)制到屏幕DC中,。
4.釋放資源,。
注意點(diǎn):
建立位圖一定要使用屏幕DC 如果屏幕DC有使用調(diào)色板,則必須將此調(diào)色板選入內(nèi)存DC中,,否則將發(fā)生色彩不正確的情況,。 例子:
CDC memdc; CBitmap bitmap; CBitmap *pOldBitmap; CRect rect; GetClientRect(&rect); memdc.CreateCompatibleDC(pDC); //以屏幕DC 建立內(nèi)存DC bitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());//以屏幕DC建立位圖 pOldBitmap = memdc.SelectObject(&bitmap);//將上面創(chuàng)建的位圖選入內(nèi)存DC中,返回CBitmap的指針并賦給pOldBitmap //下面可以在memdc上進(jìn)行繪圖操作 memdc.FillSolidRect(rect,RGB(0,0,0)); CString str; str.Format("%d",212); memdc.SetBkColor(RGB(0,0,255)); memdc.SetTextColor(RGB(255,0,0)); memdc.TextOut(rect.left+rect.Width()/2,rect.top+10,str); //繪圖結(jié)束 pDC->BitBlt(0,0,rect.Width(),rect.Height(),&memdc,0,0,SRCCOPY); // 從內(nèi)存DC復(fù)制到屏幕DC memdc.SelectObject(pOldBitmap); |
|