WTL学习笔记(5)双缓冲技术和动画(BufferedPaint)
2011-08-10 20:37 Clingingboy 阅读(1745) 评论(0) 编辑 收藏 举报
Vista+添加了相关函数对GDI双缓冲进行了支持,下面是wtl进行的封装
1.CBufferedPaint
对相关的BufferedPaint函数进行封装
class CBufferedPaint
{
public:
HPAINTBUFFER m_hPaintBuffer;
CBufferedPaint() : m_hPaintBuffer(NULL)
{ }
~CBufferedPaint()
{
ATLVERIFY(SUCCEEDED(End()));
}
bool IsNull() const
{
return (m_hPaintBuffer == NULL);
}
HPAINTBUFFER Begin(HDC hdcTarget, const RECT* prcTarget, BP_BUFFERFORMAT dwFormat, BP_PAINTPARAMS* pPaintParams, HDC* phdcPaint)
{
ATLASSERT(m_hPaintBuffer == NULL);
m_hPaintBuffer = ::BeginBufferedPaint(hdcTarget, prcTarget, dwFormat, pPaintParams, phdcPaint);
return m_hPaintBuffer;
}
HRESULT End(BOOL bUpdate = TRUE)
{
HRESULT hRet = S_FALSE;
if(m_hPaintBuffer != NULL)
{
hRet = ::EndBufferedPaint(m_hPaintBuffer, bUpdate);
m_hPaintBuffer = NULL;
}
return hRet;
}
…
};
好像构造函数和析构函数中没有添加BufferedPaintInit和BufferedPaintUnInit函数,使用相关函数必须先调用BufferedPaintInit,结束时调用BufferedPaintUnInit
2.CBufferedPaintBase
CBufferedPaintBase封装了BufferedPaintInit和BufferedPaintUnInit函数,IsBufferedPaintSupported判断必须是vista+
class CBufferedPaintBase
{
public:
static int m_nIsBufferedPaintSupported;
CBufferedPaintBase()
{
if(IsBufferedPaintSupported())
ATLVERIFY(SUCCEEDED(::BufferedPaintInit()));
}
~CBufferedPaintBase()
{
if(IsBufferedPaintSupported())
ATLVERIFY(SUCCEEDED(::BufferedPaintUnInit()));
}
static bool IsBufferedPaintSupported()
{
if(m_nIsBufferedPaintSupported == -1)
{
CStaticDataInitCriticalSectionLock lock;
if(FAILED(lock.Lock()))
{
ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CBufferedPaintBase::IsBufferedPaintSupported.\n"));
ATLASSERT(FALSE);
return false;
}
if(m_nIsBufferedPaintSupported == -1)
m_nIsBufferedPaintSupported = RunTimeHelper::IsVista() ? 1 : 0;
lock.Unlock();
}
ATLASSERT(m_nIsBufferedPaintSupported != -1);
return (m_nIsBufferedPaintSupported == 1);
}
};
3.CBufferedPaintImpl
CBufferedPaintImpl继承了CBufferedPaintBase,并在内部调用了CBufferedPaint的相关方法
4.CBufferedPaintWindowImpl
继承自CBufferedPaintImpl,默认实现BufferedPaint功能
参考:
http://www.cnblogs.com/dflying/archive/2007/03/21/681921.html
http://www.codeguru.com/cpp/w-p/vista/print.php/c15709/(源码示例参考)
动画支持
5.CBufferedAnimation
BeginBufferedAnimation,EndBufferedAnimation,BufferedPaintRenderAnimation是新增了三个函数,可以在画图时提供动画支持.
CBufferedAnimation封装了这3个函数
6.CBufferedAnimationImpl
除了了解上面三个函数之外,动画肯定需要提供默认的动画效果,BP_ANIMATIONPARAMS用来设置动画效果和动画间隔时间
// BP_ANIMATIONSTYLE
typedef enum _BP_ANIMATIONSTYLE
{
BPAS_NONE, // No animation
BPAS_LINEAR, // Linear fade animation
BPAS_CUBIC, // Cubic fade animation
BPAS_SINE // Sinusoid fade animation
} BP_ANIMATIONSTYLE;
// BP_ANIMATIONPARAMS
typedef struct _BP_ANIMATIONPARAMS
{
DWORD cbSize;
DWORD dwFlags; // BPAF_ flags
BP_ANIMATIONSTYLE style;
DWORD dwDuration;
} BP_ANIMATIONPARAMS, *PBP_ANIMATIONPARAMS;
CBufferedAnimationImpl继承自CBufferedPaintBase,并在内部设置了默认的动画效果,同时添加了DoPaint方法,供子类重写
7.CBufferedAnimationWindowImpl
继承自CBufferedAnimationImpl,重写DoPaint方法,默认支持GDI动画程序效果
参考:http://www.codeguru.com/cpp/w-p/vista/print.php/c15841/
感谢这位作者提供的2个通俗易懂的例子