zoukankan      html  css  js  c++  java
  • Duilib动画按钮实现(转载)

    转载:http://blog.csdn.net/cuiguanghui123/article/details/51674218 

    .h文件

     1 #ifndef __UIBUTTONEX_H__
     2 #define __UIBUTTONEX_H__
     3 
     4 #pragma once
     5 
     6 #define EVENT_ANIMA_ENTER_TIMERID    UIMSG_USER+100         //鼠标进入按钮TimerID
     7 #define EVENT_ANIMA_LEAVE_TIMERID    UIMSG_USER+101         //鼠标离开按钮TimerID
     8 class  CButtonUIEx : public CButtonUI
     9 {
    10     DECLARE_DUICONTROL(CButtonUIEx)
    11 public:
    12     enum ChannelARGB {
    13         Blue = 0, Green = 1, Red = 2, Alpha = 3
    14     };
    15 
    16     CButtonUIEx();
    17     virtual ~CButtonUIEx();
    18 
    19     virtual void SetMaskImage(LPCTSTR pStrImage);
    20     virtual LPCTSTR GetMaskImage();
    21 
    22     virtual LPCTSTR GetPushedForeImage();
    23     virtual void SetPushedForeImage(LPCTSTR pStrImage);
    24 
    25     virtual RECT GetPushedTextPadding();
    26     virtual void SetPushedTextPadding(RECT rc);
    27 
    28     void SetAnimationImages(vector<DuiLib::CDuiString>);
    29 
    30     virtual void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);
    31 
    32     virtual void DoPaint(HDC hDC, const RECT& rcPaint);
    33     virtual void PaintBkImage(HDC hDC);
    34     void PaintStatusImage(HDC hDC);
    35 
    36     virtual bool TransferOneARGBChannelFromOneBitmapToAnother(IN Gdiplus::Bitmap &src,
    37         OUT Gdiplus::Bitmap &dst,
    38         ChannelARGB srcChannel,
    39         ChannelARGB dstChannel);
    40 
    41     //-------------添加---------
    42     void    OnTimer(UINT_PTR idEvent);
    43     void    DoEvent(TEventUI& event) override;
    44     void    DrawFrame(HDC hDC);        // 绘制GIF每帧
    45     void    OnLeaveTimer(UINT_PTR idEvent);
    46     void    DrawLeaveFrame(HDC hDC);        // 绘制GIF每帧
    47 
    48     void PaintText(HDC hDC);
    49 
    50 private:
    51     bool _ResizeClone(Gdiplus::Image *&image, INT width, INT height);
    52 
    53 protected:
    54     DuiLib::CDuiString m_sBkImageEx;
    55     DuiLib::CDuiString m_sMaskImage;
    56 
    57     Gdiplus::Image *m_pMaskImage;
    58     Gdiplus::Bitmap *m_pBmpFluffy;
    59     Gdiplus::Bitmap *m_pBmpMask;
    60 
    61 
    62     CDuiString m_sPushedForeImage;
    63     vector<DuiLib::CDuiString> vecAnimation;
    64     UINT            m_nFrameCount;                // 图片总帧数
    65     UINT            m_nFramePosition;            // 当前放到第几帧
    66     UINT            m_nTimerSize;                // 帧与帧之间间隔时间
    67     BOOL            m_bLeaveFlag;
    68     BOOL            m_bNormalFlag;
    69     RECT            m_rcPushedTextPadding;
    70 };
    71 
    72 
    73 #endif //__UIBUTTONEX_H__

     .cpp文件

      1 #include "stdafx.h"
      2 #include "UIButtonEx.h"
      3 
      4 #ifndef SAFE_DELETE
      5 #define SAFE_DELETE(p) { if (p) { delete (p); (p) = 0; } }
      6 #endif // SAFE_DELETE
      7 
      8 IMPLEMENT_DUICONTROL(CButtonUIEx)
      9 /////////////////////////////////////////////////////////////////////////////////////
     10 //
     11 //
     12 
     13 CButtonUIEx::CButtonUIEx()
     14     : CButtonUI()
     15     , m_pMaskImage(NULL)
     16     , m_pBmpFluffy(NULL)
     17     , m_pBmpMask(NULL)
     18 {
     19     m_nFramePosition = 0;
     20     m_nFrameCount = 0;
     21     m_nTimerSize = 60;
     22     m_bLeaveFlag = false;
     23     m_bNormalFlag = true;
     24     ::ZeroMemory(&m_rcPushedTextPadding, sizeof(m_rcPushedTextPadding));
     25 }
     26 
     27 CButtonUIEx::~CButtonUIEx()
     28 {
     29     SAFE_DELETE(m_pMaskImage);
     30     SAFE_DELETE(m_pBmpFluffy);
     31     SAFE_DELETE(m_pBmpMask);
     32 }
     33 
     34 void CButtonUIEx::SetMaskImage(LPCTSTR pStrImage)
     35 {
     36     m_sMaskImage = pStrImage;
     37     Invalidate();
     38 }
     39     
     40 LPCTSTR CButtonUIEx::GetMaskImage()
     41 {
     42     return m_sMaskImage;
     43 }
     44 
     45 LPCTSTR CButtonUIEx::GetPushedForeImage()
     46 {
     47     return m_sPushedForeImage;
     48 }
     49 
     50 void CButtonUIEx::SetPushedForeImage(LPCTSTR pStrImage)
     51 {
     52     m_sPushedForeImage = pStrImage;
     53     Invalidate();
     54 }
     55 
     56 void CButtonUIEx::SetAnimationImages(vector<DuiLib::CDuiString> vecList)
     57 {
     58     vecAnimation = vecList;
     59     m_nFrameCount = vecList.size();
     60 }
     61 
     62 RECT CButtonUIEx::GetPushedTextPadding()
     63 {
     64     return m_rcPushedTextPadding;
     65 }
     66 
     67 void CButtonUIEx::SetPushedTextPadding(RECT rc)
     68 {
     69     m_rcPushedTextPadding = rc;
     70     Invalidate();
     71 }
     72 
     73 void CButtonUIEx::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
     74 {
     75     if (_tcscmp(pstrName, _T("maskimage")) == 0) SetMaskImage(pstrValue);
     76     else if (_tcsicmp(pstrName, _T("pushedforeimage")) == 0) SetPushedForeImage(pstrValue);
     77     else if (_tcsicmp(pstrName, _T("pushedtextpadding")) == 0) {
     78         RECT rcTextPadding = { 0 };
     79         LPTSTR pstr = NULL;
     80         rcTextPadding.left = _tcstol(pstrValue, &pstr, 10);  ASSERT(pstr);
     81         rcTextPadding.top = _tcstol(pstr + 1, &pstr, 10);    ASSERT(pstr);
     82         rcTextPadding.right = _tcstol(pstr + 1, &pstr, 10);  ASSERT(pstr);
     83         rcTextPadding.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
     84         SetPushedTextPadding(rcTextPadding);
     85     }
     86     else CButtonUI::SetAttribute(pstrName, pstrValue);
     87 }
     88 
     89 void CButtonUIEx::DoPaint(HDC hDC, const RECT& rcPaint)
     90 {
     91     if (!::IntersectRect(&m_rcPaint, &rcPaint, &m_rcItem)) return;
     92 
     93     // RESERVED: add your code here.
     94     if (m_bNormalFlag && vecAnimation.size() > 0)
     95         DrawImage(hDC, (LPCTSTR)vecAnimation[0]);
     96 
     97     if ((m_uButtonState & UISTATE_HOT) != 0)
     98     {
     99         DrawFrame(hDC);
    100         m_bNormalFlag = false;
    101     }
    102     if(m_bLeaveFlag)
    103         DrawLeaveFrame(hDC);
    104     __super::DoPaint(hDC, rcPaint);
    105 }
    106 
    107 void CButtonUIEx::PaintBkImage(HDC hDC)
    108 {
    109     if (m_sMaskImage && m_sBkImageEx != m_sBkImage) {
    110         do {
    111             m_sBkImageEx = m_sBkImage;
    112 
    113             SAFE_DELETE(m_pBmpFluffy);
    114             m_pBmpFluffy = new Gdiplus::Bitmap(m_pManager->GetResourcePath() + m_sBkImageEx);
    115             if (!m_pBmpFluffy || m_pBmpFluffy->GetLastStatus() != Gdiplus::Status::Ok) {
    116                 // TODO: check if m_sBkImageEx contains an absolute path.
    117                 m_pBmpFluffy = new Gdiplus::Bitmap(m_sBkImageEx);
    118                 if (!m_pBmpFluffy || m_pBmpFluffy->GetLastStatus() != Gdiplus::Status::Ok) {
    119                     break;
    120                 }
    121             }
    122 
    123             if (m_sMaskImage.IsEmpty()) {
    124                 break;
    125             }
    126 
    127             SAFE_DELETE(m_pMaskImage);
    128             m_pMaskImage = Gdiplus::Image::FromFile(m_pManager->GetResourcePath() + m_sMaskImage);
    129             if (!m_pMaskImage || m_pMaskImage->GetLastStatus() != Gdiplus::Status::Ok) {
    130                 break;
    131             }
    132 
    133             if (!_ResizeClone(m_pMaskImage, m_pBmpFluffy->GetWidth(), m_pBmpFluffy->GetHeight())) {
    134                 break;
    135             }
    136 
    137             Gdiplus::Rect rectFluffy(0, 0, m_pBmpFluffy->GetWidth(), m_pBmpFluffy->GetHeight());
    138 
    139             SAFE_DELETE(m_pBmpMask);
    140             m_pBmpMask = new Gdiplus::Bitmap(rectFluffy.Width, rectFluffy.Height);
    141             if (!m_pBmpMask) {
    142                 break;
    143             }
    144 
    145             Gdiplus::Graphics graphics(m_pBmpMask);
    146             graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
    147             graphics.SetInterpolationMode(Gdiplus::InterpolationModeBicubic);
    148             graphics.DrawImage(m_pMaskImage, rectFluffy);
    149 
    150             TransferOneARGBChannelFromOneBitmapToAnother(*m_pBmpMask, *m_pBmpFluffy, ChannelARGB::Blue, ChannelARGB::Alpha);
    151             SAFE_DELETE(m_pBmpMask);
    152         } while (0);
    153     }
    154 
    155     if (m_pBmpFluffy) {
    156         Gdiplus::Rect rectDst(m_rcPaint.left, m_rcPaint.top, m_rcPaint.right - m_rcPaint.left, m_rcPaint.bottom - m_rcPaint.top);
    157         Gdiplus::Rect rectSrc((m_rcPaint.left - m_rcItem.left) * m_pBmpFluffy->GetWidth() / (m_rcItem.right - m_rcItem.left),
    158                                 (m_rcPaint.top - m_rcItem.top) * m_pBmpFluffy->GetHeight() / (m_rcItem.bottom - m_rcItem.top),
    159                                 (m_rcPaint.right - m_rcPaint.left) * m_pBmpFluffy->GetWidth() / (m_rcItem.right - m_rcItem.left),
    160                                 (m_rcPaint.bottom - m_rcPaint.top) * m_pBmpFluffy->GetHeight() / (m_rcItem.bottom - m_rcItem.top));
    161 
    162         Gdiplus::Graphics g(hDC);
    163         g.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
    164         g.SetInterpolationMode(Gdiplus::InterpolationModeBicubic);
    165         g.DrawImage(m_pBmpFluffy, rectDst, rectSrc.X, rectSrc.Y, rectSrc.Width, rectSrc.Height, Gdiplus::Unit::UnitPixel);
    166     }
    167 }
    168 
    169 bool CButtonUIEx::TransferOneARGBChannelFromOneBitmapToAnother(IN Gdiplus::Bitmap &src,
    170                                                                         OUT Gdiplus::Bitmap &dst,
    171                                                                         ChannelARGB srcChannel,
    172                                                                         ChannelARGB dstChannel)
    173 {
    174     if (src.GetWidth() != dst.GetWidth() || src.GetHeight() != dst.GetHeight())
    175         return false;
    176 
    177     Gdiplus::Rect rectSrc(0, 0, src.GetWidth(), src.GetHeight());
    178     Gdiplus::BitmapData bdSrc, bdDst;
    179     src.LockBits(&rectSrc, Gdiplus::ImageLockMode::ImageLockModeRead, PixelFormat32bppPARGB, &bdSrc);
    180     dst.LockBits(&rectSrc, Gdiplus::ImageLockMode::ImageLockModeWrite, PixelFormat32bppPARGB, &bdDst);
    181 
    182     // unsafe codes that protected by LockBits
    183     byte *bpSrc = (byte *)bdSrc.Scan0;
    184     byte *bpDst = (byte *)bdDst.Scan0;
    185 
    186     bpSrc += (int)srcChannel;
    187     bpDst += (int)dstChannel;
    188     for (int i = rectSrc.Height * rectSrc.Width; i > 0; i--) {
    189         *bpDst = *bpSrc;
    190         bpSrc += 4;
    191         bpDst += 4;
    192     }
    193     // end (unsafe codes)
    194 
    195     src.UnlockBits(&bdSrc);
    196     dst.UnlockBits(&bdDst);
    197     return true;
    198 }
    199 
    200 bool CButtonUIEx::_ResizeClone(Gdiplus::Image *&image, INT width, INT height)
    201 {
    202     UINT image_width = image->GetWidth();
    203     UINT image_height = image->GetHeight();
    204     INT width_ = width;
    205     INT height_ = height;
    206         
    207     if (image_width == width_ && image_height == height_)
    208         return true;
    209 
    210     double ratio = ((double)image_width) / image_height;
    211     if (image_width > image_height) { // Resize down by width
    212         height_ = static_cast<UINT>(((double)width_) / ratio);
    213     }
    214     else {
    215         width_ = static_cast<UINT>(((double)height_) / ratio);
    216     }
    217 
    218     Gdiplus::Image *dst = new Gdiplus::Bitmap(width_, height_, image->GetPixelFormat());
    219     if (dst && dst->GetLastStatus() == Gdiplus::Status::Ok) {
    220         Gdiplus::Graphics graphics(dst);
    221         graphics.DrawImage(image, 0, 0, width_, height_);
    222 
    223         SAFE_DELETE(image);
    224         image = dst;
    225         return true;
    226     }
    227         
    228     SAFE_DELETE(dst);
    229     return false;
    230 }
    231 
    232 void CButtonUIEx::PaintStatusImage(HDC hDC)
    233 {
    234     if (IsFocused()) m_uButtonState |= UISTATE_FOCUSED;
    235     else m_uButtonState &= ~UISTATE_FOCUSED;
    236     if (!IsEnabled()) m_uButtonState |= UISTATE_DISABLED;
    237     else m_uButtonState &= ~UISTATE_DISABLED;
    238 
    239     if (!::IsWindowEnabled(m_pManager->GetPaintWindow())) {
    240         m_uButtonState &= UISTATE_DISABLED;
    241     }
    242     if ((m_uButtonState & UISTATE_DISABLED) != 0) {
    243         if (!m_sDisabledImage.IsEmpty())
    244         {
    245             if (!DrawImage(hDC, (LPCTSTR)m_sDisabledImage)) m_sDisabledImage.Empty();
    246             else goto Label_ForeImage;
    247         }
    248     }
    249     else if ((m_uButtonState & UISTATE_PUSHED) != 0) {
    250         if (!m_sPushedImage.IsEmpty()) {
    251             if (!DrawImage(hDC, (LPCTSTR)m_sPushedImage)){
    252                 m_sPushedImage.Empty();
    253             }
    254             if (!m_sPushedForeImage.IsEmpty())
    255             {
    256                 if (!DrawImage(hDC, (LPCTSTR)m_sPushedForeImage))
    257                     m_sPushedForeImage.Empty();
    258                 return;
    259             }
    260             else goto Label_ForeImage;
    261         }
    262         else if (m_dwPushedBkColor != 0) {
    263             CRenderEngine::DrawColor(hDC, m_rcPaint, GetAdjustColor(m_dwPushedBkColor));
    264             return;
    265         }
    266     }
    267     else if ((m_uButtonState & UISTATE_HOT) != 0) {
    268         if (!m_sHotImage.IsEmpty()) 
    269         {
    270             if (!DrawImage(hDC, (LPCTSTR)m_sHotImage))
    271             {
    272                 m_sHotImage.Empty();
    273             }
    274             if (!m_sHotForeImage.IsEmpty()) 
    275             {
    276                 if (!DrawImage(hDC, (LPCTSTR)m_sHotForeImage))
    277                     m_sHotForeImage.Empty();
    278                 return;
    279             }
    280             else goto Label_ForeImage;
    281         }
    282         else if (m_nFrameCount != 0)
    283         {
    284             m_pManager->SetTimer(this, EVENT_ANIMA_ENTER_TIMERID, m_nTimerSize);
    285         }
    286         else if (m_dwHotBkColor != 0) {
    287             CRenderEngine::DrawColor(hDC, m_rcPaint, GetAdjustColor(m_dwHotBkColor));
    288             return;
    289         }
    290     }
    291     else if ((m_uButtonState & UISTATE_FOCUSED) != 0) {
    292 if (!m_sFocusedImage.IsEmpty()) {
    293     if (!DrawImage(hDC, (LPCTSTR)m_sFocusedImage)) m_sFocusedImage.Empty();
    294     else goto Label_ForeImage;
    295 }
    296     }
    297 
    298     if (!m_sNormalImage.IsEmpty()) {
    299         if (!DrawImage(hDC, (LPCTSTR)m_sNormalImage)) m_sNormalImage.Empty();
    300         else goto Label_ForeImage;
    301     }
    302 
    303     if (!m_sForeImage.IsEmpty())
    304         goto Label_ForeImage;
    305 
    306     return;
    307 
    308 Label_ForeImage:
    309     if (!m_sForeImage.IsEmpty()) {
    310         if (!DrawImage(hDC, (LPCTSTR)m_sForeImage)) m_sForeImage.Empty();
    311     }
    312 }
    313 
    314 void CButtonUIEx::DoEvent(TEventUI& event)
    315 {
    316     CButtonUI::DoEvent(event);
    317     if (event.Type == UIEVENT_MOUSELEAVE)
    318     {
    319         if (IsEnabled()) {
    320             m_uButtonState &= ~UISTATE_HOT;
    321             Invalidate();
    322             if (m_pManager->KillTimer(this, EVENT_ANIMA_ENTER_TIMERID))
    323             {
    324                 m_bLeaveFlag = true;
    325                 m_pManager->SetTimer(this, EVENT_ANIMA_LEAVE_TIMERID, m_nTimerSize);
    326             }
    327         }
    328     }
    329     if (event.Type == UIEVENT_TIMER)
    330     {
    331         if ((UINT_PTR)event.wParam == EVENT_ANIMA_ENTER_TIMERID)
    332             OnTimer((UINT_PTR)event.wParam);
    333         else if ((UINT_PTR)event.wParam == EVENT_ANIMA_LEAVE_TIMERID)
    334             OnLeaveTimer((UINT_PTR)event.wParam);
    335     }
    336 }
    337 
    338 void CButtonUIEx::OnTimer(UINT_PTR idEvent)
    339 {
    340     if (idEvent != EVENT_ANIMA_ENTER_TIMERID)
    341         return;
    342     m_pManager->KillTimer(this, EVENT_ANIMA_ENTER_TIMERID);
    343     this->Invalidate();
    344 
    345     m_nFramePosition++;
    346 
    347     m_pManager->SetTimer(this, EVENT_ANIMA_ENTER_TIMERID, m_nTimerSize);
    348 }
    349 
    350 void CButtonUIEx::DrawFrame(HDC hDC)
    351 {
    352     if (NULL == hDC || vecAnimation.size() == 0 || m_nFramePosition >= m_nFrameCount)
    353         return;
    354     DrawImage(hDC, (LPCTSTR)vecAnimation[m_nFramePosition]);
    355     if (m_nFramePosition + 1 == m_nFrameCount)
    356     {
    357         m_pManager->KillTimer(this, EVENT_ANIMA_ENTER_TIMERID);
    358         DrawImage(hDC, (LPCTSTR)vecAnimation[m_nFramePosition]);
    359         this->Invalidate();
    360     }
    361 }
    362 
    363 void CButtonUIEx::OnLeaveTimer(UINT_PTR idEvent)
    364 {
    365     if (idEvent != EVENT_ANIMA_LEAVE_TIMERID)
    366         return;
    367     m_pManager->KillTimer(this, EVENT_ANIMA_LEAVE_TIMERID);
    368     m_pManager->KillTimer(this, EVENT_ANIMA_ENTER_TIMERID);
    369     this->Invalidate();
    370 
    371     m_nFramePosition--;
    372     m_pManager->SetTimer(this, EVENT_ANIMA_LEAVE_TIMERID, m_nTimerSize);
    373 }
    374 
    375 void CButtonUIEx::DrawLeaveFrame(HDC hDC)
    376 {
    377     if (NULL == hDC || vecAnimation.size() == 0)
    378         return;
    379     DrawImage(hDC, (LPCTSTR)vecAnimation[m_nFramePosition]);
    380     if (m_nFramePosition == 0)
    381     {
    382         m_pManager->KillTimer(this, EVENT_ANIMA_LEAVE_TIMERID);
    383         DrawImage(hDC, (LPCTSTR)vecAnimation[m_nFramePosition]);
    384         this->Invalidate();
    385         m_bLeaveFlag = false;
    386         m_bNormalFlag = true;
    387     }
    388 }
    389 
    390 void CButtonUIEx::PaintText(HDC hDC)
    391 {
    392     if ((m_uButtonState & UISTATE_PUSHED) != 0 && (m_rcPushedTextPadding.bottom != 0 || m_rcPushedTextPadding.left != 0 || m_rcPushedTextPadding.right != 0 || m_rcPushedTextPadding.top != 0))
    393     {
    394         CDuiString sText = GetText();
    395         if (sText.IsEmpty()) return;
    396         DWORD clrColor = IsEnabled() ? m_dwTextColor : m_dwDisabledTextColor;
    397 
    398         if (GetPushedTextColor() != 0)
    399             clrColor = GetPushedTextColor();
    400 
    401         RECT rc = m_rcItem;
    402         rc.left += m_rcPushedTextPadding.left;
    403         rc.right -= m_rcPushedTextPadding.right;
    404         rc.top += m_rcPushedTextPadding.top;
    405         rc.bottom -= m_rcPushedTextPadding.bottom;
    406 
    407         CRenderEngine::DrawText(hDC, m_pManager, rc, sText, clrColor, 
    408             m_iFont, m_uTextStyle);
    409     }
    410     else
    411         CButtonUI::PaintText(hDC);
    412 }

    效果图:

    demo下载地址:动画按钮

  • 相关阅读:
    第五周学习进度
    第四周学习进度
    四则运算三
    第三周学习进度
    软件工程个人作业—四则运算2
    软件工程个人作业01
    软件工程概论—用户登录界面
    构建之法读书笔记06
    构建之法读书笔记05
    构建之法读书笔记04
  • 原文地址:https://www.cnblogs.com/chechen/p/5984484.html
Copyright © 2011-2022 走看看