zoukankan      html  css  js  c++  java
  • WTL-双缓冲(double buffer)绘图

    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);
    
    }
  • 相关阅读:
    经典面试题sql基础篇-50常用的sql语句(有部分错误)
    Java中类方法与实例方法的区别
    认识区块链,认知区块链— —数据上链
    Excel中RATE函数的Java实现
    Excel中PMT函数的Java实现
    xtrabackup 全量备份、恢复数据
    程序员成长过程中不可忽略的几本书
    基于SpringBoot的WEB API项目的安全设计
    基于SpringCloud的Microservices架构实战案例-在线API管理
    他山之石,可以攻玉:从别人的项目中汲取经验
  • 原文地址:https://www.cnblogs.com/ihaoqi/p/4941811.html
Copyright © 2011-2022 走看看