VC圖形繪制雙緩存的代碼復用性討論
在前文中已經討論了如何實現界面繪制雙緩存的問題,前文網址如下:
http://www.2cto.com/kf/201111/112429.html
雙緩存的主要思路是:先把圖形繪制到內存DC中,然后再把內存DC中的所有圖形一次性的復制到屏幕DC中。在前文的實現示例中,我們把直接往DC中繪制圖形的函數封裝為DrawDirect,把通過雙緩存來實現圖形繪制的函數封裝為DrawWithBufferEfficient,其中DrawWithBufferEfficient調用了DrawDirect函數。這種實現方式,保證了視圖類可實現雙緩存繪制。
如果在這工程中,還存在其他需要進行雙緩存的彈出窗口,根據前文的實現方式,也許只能在彈出窗口類中,把DrawWithBufferEfficient重復實現一次,可能只需要簡單的復制和拷貝,然后更改相應的類名。但是,這種重復性的工作,不是一件很愉快的事,尤其是當DrawWithBufferEfficient函數需要變更的時候。如果能對繪制雙緩存的函數進行獨立封裝,其他類只要通過同一的接口調用或實現方法就可以完成雙緩存的實現,將會有效的提高代碼的復用性。
沒有使用雙緩存時,各類窗口是直接把圖形數據寫入到屏幕DC中,根據窗口圖形的不同,寫入的方式方法也不一樣,也就是DrawDirect函數的內容不一樣。使用雙緩存后,從內存DC復制到屏幕DC的動作是一樣的,即DrawWithBufferEfficient函數可以完全相同。考慮到需要調用不同的DrawDirect,可以把DrawDirect的指針作為DrawWithBufferEfficent的一個輸入參數,從而實現對DrawWithBufferEfficent函數的封裝。
下面來討論一下實現的方式:
1、函數指針
首先我們需要了解函數指針的基本概念及是用方法,而由于DrawDirect是類的成員函數,還應該了解類成員函數指針的使用。
函數指針的討論可參考之前的討論文章,鏈接如下:
http://www.2cto.com/kf/201111/112430.html
2、函數指針模板
由于DrawDirect可能是不同類的成員函數,因此,只能通過函數模板來實現調用不同類的DrawDirect。
函數指針模板可參考之前的討論文章,鏈接如下:
http://www.2cto.com/kf/201111/112431.html
3、可復用的雙緩存的實現
在工程添加一個類,用于實現雙緩存的接口函數模板,該函數的輸入包括,要繪制的窗口類的指針,窗口類的繪制函數的指針,窗口類的屏幕DC的指針。
為了調用方便,可把函數模塊設定為靜態函數,調用時就可不用對該類進行實例化。
該類的源代碼如下所示:
template <typename T>
class CDoubleBufferTemplate
{
public:
typedef void (T::*DrawFun)(CDC*);
static void DrawWithBuffer(T* pT, DrawFun fun, CDC* pDC)
{
ASSERT_VALID(pT);
ASSERT_VALID(pDC);
/*創建內存DC*/
CDC dcMemory;
dcMemory.CreateCompatibleDC(pDC);
dcMemory.SetBkColor(pDC->GetBkColor());
/*設置內存DC的畫板,大小與輸入DC的裁剪區域一樣*/
/*只對裁剪區域進行重新繪制*/
CRect rectClip(0,0,0,0);
pDC->GetClipBox(&rectClip);
CBitmap bmpMemory;
bmpMemory.CreateCompatibleBitmap(pDC,
rectClip.Width(), rectClip.Height());
dcMemory.SelectObject(&bmpMemory);
/*設置內存DC的起始點*/
dcMemory.SetViewportOrg(-1*rectClip.left, -1*rectClip.top);
/*粉刷背景*/
dcMemory.FillSolidRect(&rectClip, pDC->GetBkColor());
(pT->*fun)(&dcMemory);
/*把內存DC復制到輸入DC中*/
pDC->BitBlt(rectClip.left, rectClip.top, rectClip.Width(), rectClip.Height(),
&dcMemory, rectClip.left, rectClip.top, SRCCOPY);
/*釋放資源*/
bmpMemory.DeleteObject();
dcMemory.DeleteDC();
}
};
視圖類可在OnDraw或OnPaint中對雙緩存模板函數的調用,調用示例如下:
DoubleBufferTemplate<CDoubleBufferView>::DrawWithBuffer(
this, DrawDirect, pDC);
其中,this是視圖類的指針,DrawDirect是直接在DC中繪制圖形的函數,pDC是屏幕DC的指針。
4、工程源代碼下載:http://up.2cto.com/2011/1128/20111128044129235.rar
5、參考文章
http://www.2cto.com/kf/201111/112429.html
http://www.2cto.com/kf/201111/112430.html
http://www.2cto.com/kf/201111/112431.html
摘自 www.cnblogs.com/xianyunhe/archive/2011/11/27/2265165.html
RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成