Duilib动画按钮实现(转载)
转载:http://blog.csdn.net/cuiguanghui123/article/details/51674218
.h文件
#ifndef __UIBUTTONEX_H__
#define __UIBUTTONEX_H__ #pragma once #define EVENT_ANIMA_ENTER_TIMERID UIMSG_USER+100 //鼠标进入按钮TimerID
#define EVENT_ANIMA_LEAVE_TIMERID UIMSG_USER+101 //鼠标离开按钮TimerID
class CButtonUIEx : public CButtonUI
{
DECLARE_DUICONTROL(CButtonUIEx)
public:
enum ChannelARGB {
Blue = , Green = , Red = , Alpha =
}; CButtonUIEx();
virtual ~CButtonUIEx(); virtual void SetMaskImage(LPCTSTR pStrImage);
virtual LPCTSTR GetMaskImage(); virtual LPCTSTR GetPushedForeImage();
virtual void SetPushedForeImage(LPCTSTR pStrImage); virtual RECT GetPushedTextPadding();
virtual void SetPushedTextPadding(RECT rc); void SetAnimationImages(vector<DuiLib::CDuiString>); virtual void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue); virtual void DoPaint(HDC hDC, const RECT& rcPaint);
virtual void PaintBkImage(HDC hDC);
void PaintStatusImage(HDC hDC); virtual bool TransferOneARGBChannelFromOneBitmapToAnother(IN Gdiplus::Bitmap &src,
OUT Gdiplus::Bitmap &dst,
ChannelARGB srcChannel,
ChannelARGB dstChannel); //-------------添加---------
void OnTimer(UINT_PTR idEvent);
void DoEvent(TEventUI& event) override;
void DrawFrame(HDC hDC); // 绘制GIF每帧
void OnLeaveTimer(UINT_PTR idEvent);
void DrawLeaveFrame(HDC hDC); // 绘制GIF每帧 void PaintText(HDC hDC); private:
bool _ResizeClone(Gdiplus::Image *&image, INT width, INT height); protected:
DuiLib::CDuiString m_sBkImageEx;
DuiLib::CDuiString m_sMaskImage; Gdiplus::Image *m_pMaskImage;
Gdiplus::Bitmap *m_pBmpFluffy;
Gdiplus::Bitmap *m_pBmpMask; CDuiString m_sPushedForeImage;
vector<DuiLib::CDuiString> vecAnimation;
UINT m_nFrameCount; // 图片总帧数
UINT m_nFramePosition; // 当前放到第几帧
UINT m_nTimerSize; // 帧与帧之间间隔时间
BOOL m_bLeaveFlag;
BOOL m_bNormalFlag;
RECT m_rcPushedTextPadding;
}; #endif //__UIBUTTONEX_H__
.cpp文件
#include "stdafx.h"
#include "UIButtonEx.h" #ifndef SAFE_DELETE
#define SAFE_DELETE(p) { if (p) { delete (p); (p) = 0; } }
#endif // SAFE_DELETE IMPLEMENT_DUICONTROL(CButtonUIEx)
/////////////////////////////////////////////////////////////////////////////////////
//
// CButtonUIEx::CButtonUIEx()
: CButtonUI()
, m_pMaskImage(NULL)
, m_pBmpFluffy(NULL)
, m_pBmpMask(NULL)
{
m_nFramePosition = ;
m_nFrameCount = ;
m_nTimerSize = ;
m_bLeaveFlag = false;
m_bNormalFlag = true;
::ZeroMemory(&m_rcPushedTextPadding, sizeof(m_rcPushedTextPadding));
} CButtonUIEx::~CButtonUIEx()
{
SAFE_DELETE(m_pMaskImage);
SAFE_DELETE(m_pBmpFluffy);
SAFE_DELETE(m_pBmpMask);
} void CButtonUIEx::SetMaskImage(LPCTSTR pStrImage)
{
m_sMaskImage = pStrImage;
Invalidate();
} LPCTSTR CButtonUIEx::GetMaskImage()
{
return m_sMaskImage;
} LPCTSTR CButtonUIEx::GetPushedForeImage()
{
return m_sPushedForeImage;
} void CButtonUIEx::SetPushedForeImage(LPCTSTR pStrImage)
{
m_sPushedForeImage = pStrImage;
Invalidate();
} void CButtonUIEx::SetAnimationImages(vector<DuiLib::CDuiString> vecList)
{
vecAnimation = vecList;
m_nFrameCount = vecList.size();
} RECT CButtonUIEx::GetPushedTextPadding()
{
return m_rcPushedTextPadding;
} void CButtonUIEx::SetPushedTextPadding(RECT rc)
{
m_rcPushedTextPadding = rc;
Invalidate();
} void CButtonUIEx::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
{
if (_tcscmp(pstrName, _T("maskimage")) == ) SetMaskImage(pstrValue);
else if (_tcsicmp(pstrName, _T("pushedforeimage")) == ) SetPushedForeImage(pstrValue);
else if (_tcsicmp(pstrName, _T("pushedtextpadding")) == ) {
RECT rcTextPadding = { };
LPTSTR pstr = NULL;
rcTextPadding.left = _tcstol(pstrValue, &pstr, ); ASSERT(pstr);
rcTextPadding.top = _tcstol(pstr + , &pstr, ); ASSERT(pstr);
rcTextPadding.right = _tcstol(pstr + , &pstr, ); ASSERT(pstr);
rcTextPadding.bottom = _tcstol(pstr + , &pstr, ); ASSERT(pstr);
SetPushedTextPadding(rcTextPadding);
}
else CButtonUI::SetAttribute(pstrName, pstrValue);
} void CButtonUIEx::DoPaint(HDC hDC, const RECT& rcPaint)
{
if (!::IntersectRect(&m_rcPaint, &rcPaint, &m_rcItem)) return; // RESERVED: add your code here.
if (m_bNormalFlag && vecAnimation.size() > )
DrawImage(hDC, (LPCTSTR)vecAnimation[]); if ((m_uButtonState & UISTATE_HOT) != )
{
DrawFrame(hDC);
m_bNormalFlag = false;
}
if(m_bLeaveFlag)
DrawLeaveFrame(hDC);
__super::DoPaint(hDC, rcPaint);
} void CButtonUIEx::PaintBkImage(HDC hDC)
{
if (m_sMaskImage && m_sBkImageEx != m_sBkImage) {
do {
m_sBkImageEx = m_sBkImage; SAFE_DELETE(m_pBmpFluffy);
m_pBmpFluffy = new Gdiplus::Bitmap(m_pManager->GetResourcePath() + m_sBkImageEx);
if (!m_pBmpFluffy || m_pBmpFluffy->GetLastStatus() != Gdiplus::Status::Ok) {
// TODO: check if m_sBkImageEx contains an absolute path.
m_pBmpFluffy = new Gdiplus::Bitmap(m_sBkImageEx);
if (!m_pBmpFluffy || m_pBmpFluffy->GetLastStatus() != Gdiplus::Status::Ok) {
break;
}
} if (m_sMaskImage.IsEmpty()) {
break;
} SAFE_DELETE(m_pMaskImage);
m_pMaskImage = Gdiplus::Image::FromFile(m_pManager->GetResourcePath() + m_sMaskImage);
if (!m_pMaskImage || m_pMaskImage->GetLastStatus() != Gdiplus::Status::Ok) {
break;
} if (!_ResizeClone(m_pMaskImage, m_pBmpFluffy->GetWidth(), m_pBmpFluffy->GetHeight())) {
break;
} Gdiplus::Rect rectFluffy(, , m_pBmpFluffy->GetWidth(), m_pBmpFluffy->GetHeight()); SAFE_DELETE(m_pBmpMask);
m_pBmpMask = new Gdiplus::Bitmap(rectFluffy.Width, rectFluffy.Height);
if (!m_pBmpMask) {
break;
} Gdiplus::Graphics graphics(m_pBmpMask);
graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
graphics.SetInterpolationMode(Gdiplus::InterpolationModeBicubic);
graphics.DrawImage(m_pMaskImage, rectFluffy); TransferOneARGBChannelFromOneBitmapToAnother(*m_pBmpMask, *m_pBmpFluffy, ChannelARGB::Blue, ChannelARGB::Alpha);
SAFE_DELETE(m_pBmpMask);
} while ();
} if (m_pBmpFluffy) {
Gdiplus::Rect rectDst(m_rcPaint.left, m_rcPaint.top, m_rcPaint.right - m_rcPaint.left, m_rcPaint.bottom - m_rcPaint.top);
Gdiplus::Rect rectSrc((m_rcPaint.left - m_rcItem.left) * m_pBmpFluffy->GetWidth() / (m_rcItem.right - m_rcItem.left),
(m_rcPaint.top - m_rcItem.top) * m_pBmpFluffy->GetHeight() / (m_rcItem.bottom - m_rcItem.top),
(m_rcPaint.right - m_rcPaint.left) * m_pBmpFluffy->GetWidth() / (m_rcItem.right - m_rcItem.left),
(m_rcPaint.bottom - m_rcPaint.top) * m_pBmpFluffy->GetHeight() / (m_rcItem.bottom - m_rcItem.top)); Gdiplus::Graphics g(hDC);
g.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
g.SetInterpolationMode(Gdiplus::InterpolationModeBicubic);
g.DrawImage(m_pBmpFluffy, rectDst, rectSrc.X, rectSrc.Y, rectSrc.Width, rectSrc.Height, Gdiplus::Unit::UnitPixel);
}
} bool CButtonUIEx::TransferOneARGBChannelFromOneBitmapToAnother(IN Gdiplus::Bitmap &src,
OUT Gdiplus::Bitmap &dst,
ChannelARGB srcChannel,
ChannelARGB dstChannel)
{
if (src.GetWidth() != dst.GetWidth() || src.GetHeight() != dst.GetHeight())
return false; Gdiplus::Rect rectSrc(, , src.GetWidth(), src.GetHeight());
Gdiplus::BitmapData bdSrc, bdDst;
src.LockBits(&rectSrc, Gdiplus::ImageLockMode::ImageLockModeRead, PixelFormat32bppPARGB, &bdSrc);
dst.LockBits(&rectSrc, Gdiplus::ImageLockMode::ImageLockModeWrite, PixelFormat32bppPARGB, &bdDst); // unsafe codes that protected by LockBits
byte *bpSrc = (byte *)bdSrc.Scan0;
byte *bpDst = (byte *)bdDst.Scan0; bpSrc += (int)srcChannel;
bpDst += (int)dstChannel;
for (int i = rectSrc.Height * rectSrc.Width; i > ; i--) {
*bpDst = *bpSrc;
bpSrc += ;
bpDst += ;
}
// end (unsafe codes) src.UnlockBits(&bdSrc);
dst.UnlockBits(&bdDst);
return true;
} bool CButtonUIEx::_ResizeClone(Gdiplus::Image *&image, INT width, INT height)
{
UINT image_width = image->GetWidth();
UINT image_height = image->GetHeight();
INT width_ = width;
INT height_ = height; if (image_width == width_ && image_height == height_)
return true; double ratio = ((double)image_width) / image_height;
if (image_width > image_height) { // Resize down by width
height_ = static_cast<UINT>(((double)width_) / ratio);
}
else {
width_ = static_cast<UINT>(((double)height_) / ratio);
} Gdiplus::Image *dst = new Gdiplus::Bitmap(width_, height_, image->GetPixelFormat());
if (dst && dst->GetLastStatus() == Gdiplus::Status::Ok) {
Gdiplus::Graphics graphics(dst);
graphics.DrawImage(image, , , width_, height_); SAFE_DELETE(image);
image = dst;
return true;
} SAFE_DELETE(dst);
return false;
} void CButtonUIEx::PaintStatusImage(HDC hDC)
{
if (IsFocused()) m_uButtonState |= UISTATE_FOCUSED;
else m_uButtonState &= ~UISTATE_FOCUSED;
if (!IsEnabled()) m_uButtonState |= UISTATE_DISABLED;
else m_uButtonState &= ~UISTATE_DISABLED; if (!::IsWindowEnabled(m_pManager->GetPaintWindow())) {
m_uButtonState &= UISTATE_DISABLED;
}
if ((m_uButtonState & UISTATE_DISABLED) != ) {
if (!m_sDisabledImage.IsEmpty())
{
if (!DrawImage(hDC, (LPCTSTR)m_sDisabledImage)) m_sDisabledImage.Empty();
else goto Label_ForeImage;
}
}
else if ((m_uButtonState & UISTATE_PUSHED) != ) {
if (!m_sPushedImage.IsEmpty()) {
if (!DrawImage(hDC, (LPCTSTR)m_sPushedImage)){
m_sPushedImage.Empty();
}
if (!m_sPushedForeImage.IsEmpty())
{
if (!DrawImage(hDC, (LPCTSTR)m_sPushedForeImage))
m_sPushedForeImage.Empty();
return;
}
else goto Label_ForeImage;
}
else if (m_dwPushedBkColor != ) {
CRenderEngine::DrawColor(hDC, m_rcPaint, GetAdjustColor(m_dwPushedBkColor));
return;
}
}
else if ((m_uButtonState & UISTATE_HOT) != ) {
if (!m_sHotImage.IsEmpty())
{
if (!DrawImage(hDC, (LPCTSTR)m_sHotImage))
{
m_sHotImage.Empty();
}
if (!m_sHotForeImage.IsEmpty())
{
if (!DrawImage(hDC, (LPCTSTR)m_sHotForeImage))
m_sHotForeImage.Empty();
return;
}
else goto Label_ForeImage;
}
else if (m_nFrameCount != )
{
m_pManager->SetTimer(this, EVENT_ANIMA_ENTER_TIMERID, m_nTimerSize);
}
else if (m_dwHotBkColor != ) {
CRenderEngine::DrawColor(hDC, m_rcPaint, GetAdjustColor(m_dwHotBkColor));
return;
}
}
else if ((m_uButtonState & UISTATE_FOCUSED) != ) {
if (!m_sFocusedImage.IsEmpty()) {
if (!DrawImage(hDC, (LPCTSTR)m_sFocusedImage)) m_sFocusedImage.Empty();
else goto Label_ForeImage;
}
} if (!m_sNormalImage.IsEmpty()) {
if (!DrawImage(hDC, (LPCTSTR)m_sNormalImage)) m_sNormalImage.Empty();
else goto Label_ForeImage;
} if (!m_sForeImage.IsEmpty())
goto Label_ForeImage; return; Label_ForeImage:
if (!m_sForeImage.IsEmpty()) {
if (!DrawImage(hDC, (LPCTSTR)m_sForeImage)) m_sForeImage.Empty();
}
} void CButtonUIEx::DoEvent(TEventUI& event)
{
CButtonUI::DoEvent(event);
if (event.Type == UIEVENT_MOUSELEAVE)
{
if (IsEnabled()) {
m_uButtonState &= ~UISTATE_HOT;
Invalidate();
if (m_pManager->KillTimer(this, EVENT_ANIMA_ENTER_TIMERID))
{
m_bLeaveFlag = true;
m_pManager->SetTimer(this, EVENT_ANIMA_LEAVE_TIMERID, m_nTimerSize);
}
}
}
if (event.Type == UIEVENT_TIMER)
{
if ((UINT_PTR)event.wParam == EVENT_ANIMA_ENTER_TIMERID)
OnTimer((UINT_PTR)event.wParam);
else if ((UINT_PTR)event.wParam == EVENT_ANIMA_LEAVE_TIMERID)
OnLeaveTimer((UINT_PTR)event.wParam);
}
} void CButtonUIEx::OnTimer(UINT_PTR idEvent)
{
if (idEvent != EVENT_ANIMA_ENTER_TIMERID)
return;
m_pManager->KillTimer(this, EVENT_ANIMA_ENTER_TIMERID);
this->Invalidate(); m_nFramePosition++; m_pManager->SetTimer(this, EVENT_ANIMA_ENTER_TIMERID, m_nTimerSize);
} void CButtonUIEx::DrawFrame(HDC hDC)
{
if (NULL == hDC || vecAnimation.size() == || m_nFramePosition >= m_nFrameCount)
return;
DrawImage(hDC, (LPCTSTR)vecAnimation[m_nFramePosition]);
if (m_nFramePosition + == m_nFrameCount)
{
m_pManager->KillTimer(this, EVENT_ANIMA_ENTER_TIMERID);
DrawImage(hDC, (LPCTSTR)vecAnimation[m_nFramePosition]);
this->Invalidate();
}
} void CButtonUIEx::OnLeaveTimer(UINT_PTR idEvent)
{
if (idEvent != EVENT_ANIMA_LEAVE_TIMERID)
return;
m_pManager->KillTimer(this, EVENT_ANIMA_LEAVE_TIMERID);
m_pManager->KillTimer(this, EVENT_ANIMA_ENTER_TIMERID);
this->Invalidate(); m_nFramePosition--;
m_pManager->SetTimer(this, EVENT_ANIMA_LEAVE_TIMERID, m_nTimerSize);
} void CButtonUIEx::DrawLeaveFrame(HDC hDC)
{
if (NULL == hDC || vecAnimation.size() == )
return;
DrawImage(hDC, (LPCTSTR)vecAnimation[m_nFramePosition]);
if (m_nFramePosition == )
{
m_pManager->KillTimer(this, EVENT_ANIMA_LEAVE_TIMERID);
DrawImage(hDC, (LPCTSTR)vecAnimation[m_nFramePosition]);
this->Invalidate();
m_bLeaveFlag = false;
m_bNormalFlag = true;
}
} void CButtonUIEx::PaintText(HDC hDC)
{
if ((m_uButtonState & UISTATE_PUSHED) != && (m_rcPushedTextPadding.bottom != || m_rcPushedTextPadding.left != || m_rcPushedTextPadding.right != || m_rcPushedTextPadding.top != ))
{
CDuiString sText = GetText();
if (sText.IsEmpty()) return;
DWORD clrColor = IsEnabled() ? m_dwTextColor : m_dwDisabledTextColor; if (GetPushedTextColor() != )
clrColor = GetPushedTextColor(); RECT rc = m_rcItem;
rc.left += m_rcPushedTextPadding.left;
rc.right -= m_rcPushedTextPadding.right;
rc.top += m_rcPushedTextPadding.top;
rc.bottom -= m_rcPushedTextPadding.bottom; CRenderEngine::DrawText(hDC, m_pManager, rc, sText, clrColor, \
m_iFont, m_uTextStyle);
}
else
CButtonUI::PaintText(hDC);
}
效果图:
demo下载地址:动画按钮
Duilib动画按钮实现(转载)的更多相关文章
- 冒泡动画按钮的简单实现(使用CSS3)
冒泡动画按钮的简单实现(使用CSS3) 原始的参考文章是 http://tutorialzine.com/2010/10/css3-animated-bubble-buttons/ ,基本原理是利用了 ...
- 一款基于css3的动画按钮
之前为大家分享了 推荐10款纯css3实现的实用按钮.今天给大家带来一款基于css3的动画按钮.实现的效果图如下: 在线预览 源码下载 实现的代码. html代码: <div class=& ...
- 一款纯css3实现的动画按钮
今天给大家分享一款纯css3实现的动画按钮.第一排的按钮当鼠标经过的背景色动画切换,图标从右侧飞入,第二排的按钮当鼠标经过的时候边框动画切换,图标右侧飞入,效果非常好,一起看下效果图: 在线预览 ...
- 分享一款基于jquery的圆形动画按钮
之前为大家介绍过一款纯css3实现的圆形旋转分享按钮.今天要给大家带来一款基于jquery的圆形动画按钮.这款按钮鼠标经过的时候以边框转圈,然后逐渐消息,在实例中给出了四种颜色的demo.效果图如下: ...
- 使用 CSS3 制作一组超时尚的动画按钮效果
通过 CSS3 的新特性,我们创作出好的交互和效果的可能性大大增加.这篇文章中,我想与大家分享一些 CSS3 动画按钮效果.我们的想法是创建一个具有不同风格的一些动画链接元素,鼠标悬停时有动画效果和活 ...
- 基于jQuery点击加载动画按钮特效
分享一款基于jQuery点击加载动画按钮特效.这是一款基于jQuery+CSS3实现的鼠标点击按钮加载动画特效代码.效果图如下: 在线预览 源码下载 实现的代码. html代码: <div ...
- WPF界面设计技巧(3)—实现不规则动画按钮
原文:WPF界面设计技巧(3)-实现不规则动画按钮 发布了定义WPF按钮的教程后,有朋友问能否实现不规则形状的按钮,今天我们就来讲一下不规则按钮的制作. 不规则按钮的做法实际上和先前我们做不规则窗体的 ...
- 纯CSS3冒泡动画按钮实现教程
这款CSS3动画按钮非常的有创意,鼠标在滑过按钮时并不像其他按钮那样仅仅改变按钮的背景颜色,而是出现很酷的冒泡动画.这么惊艳的CSS3动画按钮,这篇文章主要将按钮实现的过程和代码分享给大家,希望能给在 ...
- 5种漂亮的纯CSS3动画按钮特效
这次我们要来分享一款很不错的CSS3按钮动画,这款CSS3按钮一共有5种动画方式,每一种都是鼠标滑过动画形式,虽然这些动画按钮不是十分华丽,但是小编觉得不像其他按钮那样很难扩展,我们可以修改CSS代码 ...
随机推荐
- hdu4609 3-idiots
FFT 代码 #include<iostream> #include<cstring> #include<cstdio> #include<cmath> ...
- bzoj1758 [Wc2010]重建计划 & bzoj2599 [IOI2011]Race
两题都是树分治. 1758这题可以二分答案avgvalue,因为avgvalue=Σv(e)/s,因此二分后只需要判断Σv(e)-s*avgvalue是否大于等于0,若大于等于0则调整二分下界,否则调 ...
- Demo12SimpleAdapter
/Users/alamps/AndroidStudioProjects/Demo12SimpleAdapter/Demo12SimpleAdapter/src/main/res/layout/data ...
- mysql explain
我们使用EXPLAIN解析SQL执行计划时,如果有下面几种情况,就需要特别关注下了: 首先看下 type 这列的结果,如果有类型是 ALL 时,表示预计会进行全表扫描(full table scan) ...
- 夺命雷公狗—angularjs—12—get参数的接收
我们在实际的开发中get和post的交互都是离不开的,我们先来研究下get参数是如何接收到的.. 而且在实际开发中利用json来进行传递参数也是比较多的,这里我们就以get来接收参数为列.. 先创建一 ...
- 夺命雷公狗---node.js---10之POST的接收
首先我们在项目下创建一个表单,代码如下所示: <!DOCTYPE html> <html lang="en"> <head> <meta ...
- 常用的网络配置命令 ifconfig 所在的包
通过rpm的数据库反查 ifconfig这个可执行文件的提供者,得出这个文件属于一个叫 net-tools 的包
- .NET 通过SmtpClient发送邮件 提示 4.7.1 service unavailable try again later 解决办法
最近用C#的SmtpClient发送电子邮件碰到这个错误: 正在处理错误. 服务器响应为:4.7.1 Service unavailable - try again later 换了其他的SMTP服务 ...
- struts2 笔记04 杂记
流程: 1. StrutsPrepareAndExcuteFilter:StrutsPrepareAndExcuteFilter作为前端控制器,是整个Struts2的调度中心. 2. ActionMa ...
- 160909、Filter多方式拦截、禁用IE图片缓存、Filter设置字符编码
dispatcher多方式拦截 我们来看一个例子 我们定义一个index.jsp,里面有一个链接跳转到dispatcher.jsp页面 <body> <a href="di ...