基于WTL 雙緩沖(double buffer)繪圖的分析詳解
更新時(shí)間:2013年05月17日 16:16:56 作者:
本篇文章是對(duì)WTL下使用雙緩沖(double buffer)繪圖進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
WTL中有兩個(gè)Mix-in類(lèi): CDoubleBufferImpl和CDoubleBufferWindowImpl,用于創(chuàng)建雙緩沖繪圖窗口,用法非常簡(jiǎn)單。
下面創(chuàng)建了一個(gè)普通的WTL窗口類(lèi),在窗口的客戶(hù)區(qū)中有大量的繪圖工作,使用CDoubleBufferImpl類(lèi)來(lái)消除繪圖時(shí)的閃爍現(xiàn)象:
const COLORREF WHITE_COLOR = RGB(255,255,255);
const COLORREF BLUE_COLOR = RGB(0,0,255);
class CMainWindow :
public CWindowImpl<CMainWindow,CWindow,CSimpleWinTraits>,
public CDoubleBufferImpl<CMainWindow>
{
public:
typedef CMainWindow _thisClass;
typedef CDoubleBufferImpl<_thisClass> _baseDblBufImpl;
BEGIN_MSG_MAP(CMainWindow)
MSG_WM_CREATE(OnCreate)
MSG_WM_DESTROY(OnDestroy)
CHAIN_MSG_MAP(_baseDblBufImpl)
END_MSG_MAP()
int OnCreate(LPCREATESTRUCT lpCreateStruct)
{
m_RectPen.CreatePen(PS_SOLID,1,BLUE_COLOR);
return 0;
}
void OnDestroy()
{
PostQuitMessage(0);
}
void OnPaint(CDCHandle)
{
CPaintDC dc(m_hWnd);
DoPaint(dc.m_hDC);
}
void DoPaint(CDCHandle dc)
{
CRect rc;
GetClientRect(&rc);
dc.FillRect(&rc,WHITE_COLOR);
HPEN hOldPen = dc.SelectPen(m_RectPen);
const int width = 5;
int x = 0;
int count = rc.Width()/width;
int height = 0;
for (int i=0; i<count; i++)
{
height = (int)((double)rand()*rc.Height())/RAND_MAX;
dc.Rectangle(x,rc.Height(),x+width,rc.Height()-height);
x += width;
}
dc.SelectPen(hOldPen);
}
/*
void DoPaint(CDCHandle dc)
{
CRect rc;
GetClientRect(&rc);
int width = rc.Width(), height = rc.Height();
//use GDI+ to draw in the client area
Graphics g(dc.m_hDC);
SolidBrush whiteBrush(Color(255,255,255));
g.FillRectangle(&whiteBrush,0,0,width,height);
Pen bluePen(Color(0,0,255));
const int dx = 5;
int count = width/dx;
int x = 0, y = 0, h = 0;
for (int i=0;i<count;i++)
{
h = ((double)rand()*height)/RAND_MAX;
g.DrawRectangle(&bluePen,x,y,dx,h);
x += dx;
}
}
*/
private:
CPen m_RectPen;
};
值得一提的是,Windows Vista操作系統(tǒng)增加了對(duì)Double buffered paint的內(nèi)建支持,這里有一篇文章介紹如何在Win32程序中使用這些API:
Using Windows Vista Built-In Double Buffering
在WTL中使用Vista提供的這一功能非常容易,最新的WTL庫(kù)中提供了CBufferedPaintImpl和CBufferedPaintWindowImpl兩個(gè)類(lèi),這兩個(gè)類(lèi)的用法和前面提到的兩個(gè)WTL自帶的雙緩沖類(lèi)幾乎一樣。區(qū)別僅僅是所重載的DoPaint()函數(shù)的參數(shù)稍有不同。
對(duì)于CBufferedPaintImpl類(lèi),所需重載的DoPaint()函數(shù)的樣子如下所示:
void DoPaint(CDCHandle dc, RECT& rect)
{
CRect rc(rect);
dc.FillSolidRect(&rc,WHITE_COLOR);
HPEN hOldPen = dc.SelectPen(m_RectPen);
const int width = 5;
int x = 0;
int count = rc.Width()/width;
int height = 0;
for (int i=0; i<count; i++)
{
height = (int)((double)rand()*rc.Height())/RAND_MAX;
dc.Rectangle(x,rc.Height(),x+width,rc.Height()-height);
x += width;
}
dc.SelectPen(hOldPen);
}
下面創(chuàng)建了一個(gè)普通的WTL窗口類(lèi),在窗口的客戶(hù)區(qū)中有大量的繪圖工作,使用CDoubleBufferImpl類(lèi)來(lái)消除繪圖時(shí)的閃爍現(xiàn)象:
復(fù)制代碼 代碼如下:
const COLORREF WHITE_COLOR = RGB(255,255,255);
const COLORREF BLUE_COLOR = RGB(0,0,255);
class CMainWindow :
public CWindowImpl<CMainWindow,CWindow,CSimpleWinTraits>,
public CDoubleBufferImpl<CMainWindow>
{
public:
typedef CMainWindow _thisClass;
typedef CDoubleBufferImpl<_thisClass> _baseDblBufImpl;
BEGIN_MSG_MAP(CMainWindow)
MSG_WM_CREATE(OnCreate)
MSG_WM_DESTROY(OnDestroy)
CHAIN_MSG_MAP(_baseDblBufImpl)
END_MSG_MAP()
int OnCreate(LPCREATESTRUCT lpCreateStruct)
{
m_RectPen.CreatePen(PS_SOLID,1,BLUE_COLOR);
return 0;
}
void OnDestroy()
{
PostQuitMessage(0);
}
void OnPaint(CDCHandle)
{
CPaintDC dc(m_hWnd);
DoPaint(dc.m_hDC);
}
void DoPaint(CDCHandle dc)
{
CRect rc;
GetClientRect(&rc);
dc.FillRect(&rc,WHITE_COLOR);
HPEN hOldPen = dc.SelectPen(m_RectPen);
const int width = 5;
int x = 0;
int count = rc.Width()/width;
int height = 0;
for (int i=0; i<count; i++)
{
height = (int)((double)rand()*rc.Height())/RAND_MAX;
dc.Rectangle(x,rc.Height(),x+width,rc.Height()-height);
x += width;
}
dc.SelectPen(hOldPen);
}
/*
void DoPaint(CDCHandle dc)
{
CRect rc;
GetClientRect(&rc);
int width = rc.Width(), height = rc.Height();
//use GDI+ to draw in the client area
Graphics g(dc.m_hDC);
SolidBrush whiteBrush(Color(255,255,255));
g.FillRectangle(&whiteBrush,0,0,width,height);
Pen bluePen(Color(0,0,255));
const int dx = 5;
int count = width/dx;
int x = 0, y = 0, h = 0;
for (int i=0;i<count;i++)
{
h = ((double)rand()*height)/RAND_MAX;
g.DrawRectangle(&bluePen,x,y,dx,h);
x += dx;
}
}
*/
private:
CPen m_RectPen;
};
值得一提的是,Windows Vista操作系統(tǒng)增加了對(duì)Double buffered paint的內(nèi)建支持,這里有一篇文章介紹如何在Win32程序中使用這些API:
Using Windows Vista Built-In Double Buffering
在WTL中使用Vista提供的這一功能非常容易,最新的WTL庫(kù)中提供了CBufferedPaintImpl和CBufferedPaintWindowImpl兩個(gè)類(lèi),這兩個(gè)類(lèi)的用法和前面提到的兩個(gè)WTL自帶的雙緩沖類(lèi)幾乎一樣。區(qū)別僅僅是所重載的DoPaint()函數(shù)的參數(shù)稍有不同。
對(duì)于CBufferedPaintImpl類(lèi),所需重載的DoPaint()函數(shù)的樣子如下所示:
復(fù)制代碼 代碼如下:
void DoPaint(CDCHandle dc, RECT& rect)
{
CRect rc(rect);
dc.FillSolidRect(&rc,WHITE_COLOR);
HPEN hOldPen = dc.SelectPen(m_RectPen);
const int width = 5;
int x = 0;
int count = rc.Width()/width;
int height = 0;
for (int i=0; i<count; i++)
{
height = (int)((double)rand()*rc.Height())/RAND_MAX;
dc.Rectangle(x,rc.Height(),x+width,rc.Height()-height);
x += width;
}
dc.SelectPen(hOldPen);
}
相關(guān)文章
解析linux 文件和目錄操作的相關(guān)函數(shù)
以下是對(duì)linux中文件和目錄操作的相關(guān)函數(shù)進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下2013-08-08C語(yǔ)言實(shí)現(xiàn)靜態(tài)存儲(chǔ)通訊錄的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用C語(yǔ)言實(shí)現(xiàn)一個(gè)靜態(tài)存儲(chǔ)的通訊錄,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C語(yǔ)言有一定幫助,需要的可以參考一下2022-09-09C++實(shí)現(xiàn)二叉樹(shù)非遞歸遍歷方法實(shí)例總結(jié)
這篇文章主要介紹了C++實(shí)現(xiàn)二叉樹(shù)非遞歸遍歷方法實(shí)例總結(jié),是算法設(shè)計(jì)中比較經(jīng)典的一個(gè)遍歷算法,需要的朋友可以參考下2014-08-08C++中String增刪查改模擬實(shí)現(xiàn)方法舉例
這篇文章主要給大家介紹了關(guān)于C++中String增刪查改模擬實(shí)現(xiàn)方法的相關(guān)資料,String是C++中的重要類(lèi)型,程序員在C++面試中經(jīng)常會(huì)遇到關(guān)于String的細(xì)節(jié)問(wèn)題,甚至要求當(dāng)場(chǎng)實(shí)現(xiàn)這個(gè)類(lèi),需要的朋友可以參考下2023-11-11C語(yǔ)言函數(shù)棧幀的創(chuàng)建與銷(xiāo)毀詳解
函數(shù)棧幀(stack frame)就是函數(shù)調(diào)用過(guò)程中在程序的調(diào)用棧(call stack)所開(kāi)辟的空間,下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言函數(shù)棧幀的創(chuàng)建與銷(xiāo)毀的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09