WTL学习笔记(5)双缓冲技术和动画(BufferedPaint)
2011-08-10 20:37 Clingingboy 阅读(1750) 评论(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个通俗易懂的例子
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现