您的位置:首页 > Web前端

WTL-双缓冲(double buffer)绘图

2015-11-06 10:14 363 查看
WTL中有两个Mix-in类: CDoubleBufferImpl和CDoubleBufferWindowImpl,用于创建双缓冲绘图窗口,用法非常简单。下面创建了一个普通的WTL窗口类,在窗口的客户区中有大量的绘图工作,使用CDoubleBufferImpl类来消除绘图时的闪烁现象:
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操作系统增加了对Double buffered paint的内建支持,这里有一篇文章介绍如何在Win32程序中使用这些API:Using Windows Vista Built-In Double Buffering在WTL中使用Vista提供的这一功能非常容易,最新的WTL库中提供了CBufferedPaintImpl和CBufferedPaintWindowImpl两个类,这两个类的用法和前面提到的两个WTL自带的双缓冲类几乎一样。区别仅仅是所重载的DoPaint()函数的参数稍有不同。对于CBufferedPaintImpl类,所需重载的DoPaint()函数的样子如下所示:
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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: