天天看點

WTL自繪界面庫(CQsStatic)

概述:

CQsStatic 實作如下:

#pragma once;
#include "QsInclude.h"
#include "UserMessage.h"
#include "UiPublicDefine.h"

//  大小調整方式
typedef enum
{
    E_SizeAdjustStyl_No = 0,
    E_SizeAdjustStyl_Left,
    E_SizeAdjustStyl_Center,
    E_SizeAdjustStyl_Right
} enSizeAdjustStyle;

class CQsStatic : 
    public CWindowImpl<CQsStatic, CStatic>,
    public CImageMgrCtrlBase< CQsStatic>
{
    std::vector< Image* > m_vtImage;  //圖檔對象
    volatile bool   m_bMouseTrack;   //滑鼠是否進入
    Image*  m_pImageMoseIn;

    UINT m_nActiveFrameNo;  //目前祯号
    UINT m_nTotalFrames;    //總祯數
    UINT m_nInterval;       //頁面翻轉時間
    UINT m_nDisTimer;
    UINT m_uFormat;
    BOOL m_isDrawEdge;      //是否繪制邊框
    Color m_EdgeClr;        //邊框顔色
    Color m_LineClr;        //陰影線顔色
    int   m_leftspace;      //距左邊的距離
    int   m_rightspace;     //距右邊的距離
    int   m_topspace;     //距上邊的距離
    int   m_bottomspace;    //距底邊的距離
    BOOL   m_bReturn;

    enSizeAdjustStyle   m_eSizeAdjustStyle;

    typedef CWindowImpl< CQsStatic, CStatic > theBaseClass;
    typedef CImageMgrCtrlBase< CQsStatic> theImageCtrlBaseClass;
public:

    BEGIN_MSG_MAP( CQsStatic )
        MESSAGE_HANDLER( WM_PAINT, OnPaint )
        MESSAGE_HANDLER( WM_TIMER, OnTimer )
        MESSAGE_HANDLER( WM_TIMER, OnDestroy )
        //MESSAGE_HANDLER( WM_SETWINDOWTEXT )
        MESSAGE_HANDLER( WM_MOUSELEAVE, OnMouseLeave )
        MESSAGE_HANDLER( WM_MOUSEMOVE, OnMouseMove )
        CHAIN_MSG_MAP( theImageCtrlBaseClass )
        DEFAULT_REFLECTION_HANDLER()

    END_MSG_MAP()

    /**
    *@method   CQsStatic
    *@brief    CQsStatic類構造函數
    *    
    *@return   
    */
    CQsStatic() :
        m_nActiveFrameNo( 0 ),
        m_nTotalFrames( 0 ),
        m_nInterval( 5000 ),
        m_nDisTimer( 0 )
    {
        m_bMouseTrack = TRUE; 
        m_uFirstPos = CONTROL_STA_FIRST;
        m_uLastPos = CONTROL_STA_LAST;
        m_uFormat = DT_SINGLELINE|DT_LEFT;
        m_isDrawEdge = FALSE;                   //預設為沒有邊框
        m_EdgeClr = Color(128, 255, 255, 255);  //預設邊框顔色
        m_LineClr = Color(200, 182, 164, 183);   //預設陰影線顔色
        m_pImageMoseIn = NULL;
        m_leftspace = 0;      //距左邊的距離
        m_rightspace = 0;     //距右邊的距離
        m_topspace = 0;     //距上邊的距離
        m_bottomspace = 0;    //距底邊的距離
        m_eSizeAdjustStyle = E_SizeAdjustStyl_No;
        m_bReturn = FALSE;
    }

    /**
    *@method   ~CQsStatic
    *@brief    CQsStatic析構造函數
    *    
    *@return   
    */
    virtual ~CQsStatic()
    {
        if(m_pImageMoseIn != NULL)
        {
            delete m_pImageMoseIn;
        }
        
    }

    /**
    *@method   SubclassWindow
    *@brief    類對象關聯
    *    
    *@param    HWND hWnd   對象句柄
    *@return   BOOL
    */
    BOOL SubclassWindow( HWND hWnd )
    {
        if( m_nDisTimer > 0 )
        {
            KillTimer( m_nDisTimer );
            m_nDisTimer = 0;
        }

        BOOL bRet = theBaseClass::SubclassWindow( hWnd );
        if( m_nTotalFrames > 1 )
        {
            m_nDisTimer = (UINT)SetTimer( 1001, m_nInterval );
        }

        //WS_EX_TRANSPARENT
        ModifyStyleEx( 0, WS_EX_TRANSPARENT );

        return bRet;
    }

    /**
    *@method   SetWindowTextEx
    *@brief    設定文字顯示,重寫防止重新整理閃爍。
    *    
    *@param    LPCTSTR lpszString
    *@return   void
    */
    void SetWindowTextEx(LPCTSTR lpszString)
    {
        SetRedraw(FALSE);
        SetWindowText(lpszString);
        SetRedraw(TRUE);
        Invalidate(FALSE);
    }
    /**
    *@method   SetbReturn
    *@brief    設定是否支援換車換行符
    *    
    *@return   void
    */
    void SetbReturn(BOOL bRetrun)
    {
       m_bReturn = bRetrun;
    }

    BOOL SetWindowText(LPCTSTR lpszString) throw()
    {
        ATLASSERT(::IsWindow(m_hWnd));

        BOOL bRet = ::SetWindowText(m_hWnd, lpszString);

        AdjustSize();

        return bRet;
    }

    void SetSizeAdjustStyle( enSizeAdjustStyle eStyle ) 
    {
        m_eSizeAdjustStyle = eStyle;
    }

    void AdjustSize( void )
    {
        if ( E_SizeAdjustStyl_No == m_eSizeAdjustStyle )
        {
            return;
        }

        WTL::CDC paintDC( ::GetDC(m_hWnd) );
        Graphics graph( paintDC.m_hDC);

        CRect rtStatic;
        GetWindowRect(&rtStatic);
        GetParent().ScreenToClient( &rtStatic );

        // 計算繪制文字所需的區域
        RectF rtfTitle( 0, 0, 10000, 10 );

        //HFONT hFont = GetFont( );
        HFONT hFont = GetStateFont( CONTROL_STA_NORMAL );
        Font font( paintDC.m_hDC, hFont );
        StringFormat strfmtTitle;
        strfmtTitle.SetAlignment( StringAlignmentNear );
        strfmtTitle.SetLineAlignment( StringAlignmentNear );
        RectF boundTitle;
        //WTL::CString strText;
        //GetWindowText( strText );
        int nLength = GetWindowTextLength();
        TCHAR* szText = new TCHAR[nLength+1];
        memset( szText, 0, sizeof(TCHAR)*(nLength+1));
        GetWindowText( szText, nLength+1 );
        std::wstring strText = szText;
        graph.MeasureString( strText.c_str(), 
            (INT)strText.length(), 
            &font, 
            rtfTitle, 
            &strfmtTitle, 
            &boundTitle );

        int nNewWidth = (int)(boundTitle.Width) + m_leftspace + m_rightspace;
        int nOldWidth = rtStatic.Width();
        if ( E_SizeAdjustStyl_Left == m_eSizeAdjustStyle )
        {
            SetWindowPos( NULL, 0, 0, boundTitle.Width, rtStatic.Height(), SWP_NOMOVE|SWP_NOZORDER );
        }
        else if ( E_SizeAdjustStyl_Center == m_eSizeAdjustStyle )
        {
            SetWindowPos( NULL, rtStatic.left - (nNewWidth-nOldWidth)/2, rtStatic.top, nNewWidth, rtStatic.Height(), SWP_NOZORDER );
        }
        else if ( E_SizeAdjustStyl_Right == m_eSizeAdjustStyle )
        {
            SetWindowPos( NULL, rtStatic.left - (nNewWidth-nOldWidth), rtStatic.top, nNewWidth, rtStatic.Height(), SWP_NOZORDER );
        }
        else
        {

        }

    }

    /**
    *@method   SetTextFormat
    *@brief    設定字型顯示格式
    *    
    *@param    UINT uFormat
    *@return   void
    */
    void SetTextFormat(UINT uFormat)
    {
        m_uFormat = uFormat;
    }

    /**
    *@method   SetTextSpace
    *@brief    設定繪制文字的空間
    *    
    *@param    int leftspace
    *@param    int rightspace
    *@param    int widthspace
    *@param    int heightspace
    *@return   void
    */
    void SetTextSpace(int leftspace,int rightspace,int topspace,int bottomspace)     
    {
       m_leftspace = leftspace;      //距左邊的距離
       m_rightspace = rightspace;     //距右邊的距離
       m_topspace = topspace;           //距上邊的距離
       m_bottomspace = bottomspace;    //距底邊的距離
    }
    /**
    *@method   SetStyle
    *@brief    設定static的圖檔是否繪制邊框,及其邊框顔色
    *    
    *@param    BOOL bDrawEdge = FALSE  用于控制是否繪制邊框,預設值為FALSE
    *@param    Color edgeClr = Color(128,255,255,255)邊框顔色,預設值為白色
    *@param    Color lineClr= Color(200,182,164,183)陰影線,預設值為灰色
    *@return   void
    */
    void SetEdgeStyle(BOOL bDrawEdge = FALSE,Color edgeClr = Color(128, 255, 255, 255), Color lineClr = Color(255, 128, 128, 128))
    {
        m_isDrawEdge = bDrawEdge;
        m_EdgeClr = edgeClr;
        m_LineClr = lineClr;
    }
protected:

    /**
    *@method   OnTimer
    *@brief    頁面翻轉時間
    *    
    *@param    UINT uMsg         消息類型
    *@param    WPARAM wParam     未被使用
    *@param    LPARAM lParam     詳見MSDN
    *@param    BOOL& bHandled    未被使用
    *@return   LRESULT
    */
    LRESULT OnTimer( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/ )
    {
        if( m_nTotalFrames <= 1 )
        {
            return 0;
        }

        m_nActiveFrameNo++;
        if( m_nActiveFrameNo >= m_nTotalFrames )
        {
            m_nActiveFrameNo = 0;
        }

        Invalidate();
        return 0;
    }

    /**
    *@method   OnDestroy
    *@brief    清除資源
    *    
    *@param    UINT uMsg        消息類型
    *@param    WPARAM wParam    未被使用
    *@param    LPARAM lParam    詳見MSDN
    *@param    BOOL&  bHandled  未被使用
    *@return   LRESULT
    */
    LRESULT OnDestroy( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/ )
    {
        //清除圖檔,釋放記憶體
        for( size_t i = 0; i < m_vtImage.size(); i++ )
        {
            delete m_vtImage[i];
        }
        m_vtImage.clear();

        if( m_nDisTimer > 0 )
        {
            KillTimer( m_nDisTimer );
            m_nDisTimer = 0;
        }
        return 0;
    }
    /**
    *@method   DrawEdgeEx
    *@brief    繪制圖檔的邊框
    *    
    *@param    HDC &hDC  裝置内容具備
    *@param    CRect & rc 繪圖區域
    *@param    Color &edgeClr 邊框顔色
    *@param    Color &lineClr 陰影線顔色
    *@return   void
    */
    void DrawEdgeEx(HDC &hDC, CRect & rc, Color &edgeClr, Color &lineClr)
    {
        //Pen  mypen(Color(128, 255,255, 255),14);
        Pen  mypen(edgeClr,10);
        Pen  mypen1(Color(64, 65,65, 65),1);
        //Pen  mypen2(Color(200,182,164,183),3);
        Pen  mypen2(lineClr,3);

        Graphics mygraph(hDC);
        mygraph.DrawRectangle(&mypen,1,1,rc.Width()-2,rc.Height()-2);
        mygraph.DrawRectangle(&mypen1,0,0,rc.Width()-1,rc.Height()-1);

        //畫線
        Point  startpoint(rc.right,0);
        Point  endpoint(rc.right,rc.bottom);
        mygraph.DrawLine(&mypen2,startpoint,endpoint);
        startpoint.X = 0;
        startpoint.Y = rc.bottom;
        endpoint.X = rc.right;
        endpoint.Y = rc.bottom;
        mygraph.DrawLine(&mypen2,startpoint,endpoint);
        mygraph.ReleaseHDC(hDC);
    }

public:
    /**
    *@method   OnMouseMove
    *@brief    滑鼠進入消息響應函數
    *    
    *@param    UINT uMsg 消息類型
    *@param    WPARAM wParam
    *@param    LPARAM lParam
    *@param    BOOL& bHandled
    *@return   LRESULT
    */
    LRESULT OnMouseMove( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled )
    {
        if ( m_bMouseTrack )
        {
            // 向父視窗發送BN_MOUSEIN擴充通知消息
            HWND hParent = GetParent();
            if ( NULL != hParent )
            {
                WPARAM wParam = MAKELONG( ::GetWindowLong(m_hWnd, GWL_ID), STAT_MOUSEIN );
                ::PostMessage( hParent, WM_COMMANDEX, wParam, (LPARAM)m_hWnd );
            }
        }

        if(m_bMouseTrack)
        {
            Invalidate();


            // 啟動滑鼠離開時間
            TRACKMOUSEEVENT tme;
            tme.cbSize  = sizeof(tme);
            tme.hwndTrack = m_hWnd;
            tme.dwFlags = TME_LEAVE|TME_HOVER;
            TrackMouseEvent(&tme);
            m_bMouseTrack = FALSE;
        }

        bHandled = FALSE;
        return 0;
    }

    /**
    *@method   OnMouseLeave
    *@brief    滑鼠離開消息響應函數
    *    
    *@param    UINT uMsg 消息類型
    *@param    WPARAM wParam
    *@param    LPARAM lParam
    *@param    BOOL& bHandled
    *@return   LRESULT
    */
    LRESULT OnMouseLeave( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled )
    {
        if(!m_bMouseTrack)
        {
            Invalidate();
            bHandled = FALSE;
            m_bMouseTrack = TRUE;
            // 向父視窗發送BN_MOUSEOUT擴充通知消息
            HWND hParent = GetParent();
            if ( NULL != hParent )
            {
                WPARAM wParam = MAKELONG( ::GetWindowLong(m_hWnd, GWL_ID), STAT_MOUSEOUT );
                ::PostMessage( hParent, WM_COMMANDEX, wParam, (LPARAM)m_hWnd );
            }

        }
        return 0;
    }
    /**
    *@method   SetImageMoseIn
    *@brief    
    *    
    *@param    Image * pImage
    *@return   void
    */
    void SetImageMoseIn(Image* pImage)
    {
         m_pImageMoseIn = pImage->Clone();
    }
    /**
    *@method   GetStrRow
    *@brief    得到字元串的行數
    *    
    *@param    CString & str
    *@return   int
    */
    int GetStrRow(CString& str)
    {
        int i=0;
        int c=0;
        do
        {
            i = str.Find(_T('\n'),i+1);
            ++c;

        }while ((i != -1)&&i!= str.GetLength()-1);
        return c;

    }
    /**
    *@method   GetRowString
    *@brief    得到
    *    
    *@param    CString & str
    *@return   void
    */
    void GetRowString(int nCount,CString str,vector<CString>& strVector)
    {
        for(int i =0;i<nCount;i++)
        {
            int nLeght = str.Find(_T('\n'));
            CString strTemp;
            if (nLeght > 0)
            {
                strTemp = str.Left(nLeght+1);
                str.Delete(0,nLeght+1);
            }
            else
            {
                strTemp = str;
            }
            strVector.push_back(strTemp);
        }
    }
    /**
    *@method   OnPaint
    *@brief    繪制消息函數
    *    
    *@param    UINT uMsg            消息類型
    *@param    WPARAM wParam        未被使用
    *@param    LPARAM lParam        詳見MSDN
    *@param    BOOL&  bHandled      未被使用
    *@return   LRESULT
    */
    LRESULT OnPaint( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/ )
    {
        WTL::CPaintDC paintDC( m_hWnd );
        paintDC.SetBkMode( TRANSPARENT );
        
        CRect rc;
        GetClientRect( rc );

        //建立記憶體作圖對象
        WTL::CDC dc;
        dc.CreateCompatibleDC( paintDC.m_hDC );
        WTL::CBitmap memBitmap;
        memBitmap.CreateCompatibleBitmap( paintDC.m_hDC, rc.Width(), rc.Height() );
        HBITMAP hOldBmp = dc.SelectBitmap( memBitmap );
        dc.SetBkMode( TRANSPARENT );

        //獲得控件背景
        ::SendMessage( GetParent(), WM_DRAWBKGNDUI, ( WPARAM )dc.m_hDC, ( LPARAM )m_hWnd );

        int nLeft = 0;
        int ntop = 0;
        
        if (m_isDrawEdge)
        {
            //繪制邊框
            DrawEdgeEx(dc.m_hDC,rc,m_EdgeClr,m_LineClr);
            
            nLeft = ntop = 6;
        }

        POINT pt;
        GetCursorPos( &pt );
        BOOL bMouseIn =FALSE;
        HWND hwnd = WindowFromPoint(pt);
        if(hwnd==m_hWnd)
        {
            bMouseIn = TRUE;
        }
        if(bMouseIn == TRUE) //滑鼠在static内
        {
            if(m_pImageMoseIn != NULL)
            {
                Image *pImage = m_pImageMoseIn;
                Graphics graph( dc.m_hDC );
                //graph.DrawImage( pImage, Rect( nLeft, ntop, rc.Width()-2*nLeft, rc.Height()-2*ntop), 
                //  0, 0, pImage->GetWidth(), pImage->GetHeight(), UnitPixel );
                RectF rtfDest( (REAL)nLeft, (REAL)ntop, REAL(rc.Width()-2*nLeft), REAL(rc.Height()-2*ntop) );
                StretchImageExceptCorner( graph, pImage, rtfDest, 5, 5, 5, 5 );

                graph.ReleaseHDC( dc.m_hDC );

            }
            else
            {
                if( m_vtImage.size() > m_nActiveFrameNo )
                {
                    Image *pImage = m_vtImage[m_nActiveFrameNo];
                    Graphics graph( dc.m_hDC );
//                  graph.DrawImage( pImage, Rect( nLeft, ntop, rc.Width()-2*nLeft, rc.Height()-2*ntop), 
//                      0, 0, pImage->GetWidth(), pImage->GetHeight(), UnitPixel );
                    RectF rtfDest( (REAL)nLeft, (REAL)ntop, REAL(rc.Width()-2*nLeft), REAL(rc.Height()-2*ntop) );
                    StretchImageExceptCorner( graph, pImage, rtfDest, 5, 5, 5, 5 );

                    graph.ReleaseHDC( dc.m_hDC );
                }
            }
        }
        else
        {
            if( m_vtImage.size() > m_nActiveFrameNo )
            {
                Image *pImage = m_vtImage[m_nActiveFrameNo];
                Graphics graph( dc.m_hDC );
//              graph.DrawImage( pImage, Rect( nLeft, ntop, rc.Width()-2*nLeft, rc.Height()-2*ntop), 
//                  0, 0, pImage->GetWidth(), pImage->GetHeight(), UnitPixel );
                RectF rtfDest( (REAL)nLeft, (REAL)ntop, REAL(rc.Width()-2*nLeft), REAL(rc.Height()-2*ntop) );
                StretchImageExceptCorner( graph, pImage, rtfDest, 5, 5, 5, 5 );

                graph.ReleaseHDC( dc.m_hDC );
            }
        }
     


        //繪制文字
        int len = GetWindowTextLength();
        if( len > 0 )
        {
            len += 1;
            CString strText;
            GetWindowText( strText.GetBuffer( len ), len );
            strText.ReleaseBuffer();

            HFONT hFont = GetStateFont( CONTROL_STA_NORMAL );
            HFONT hOldFont = dc.SelectFont( hFont );
            dc.SetTextColor( GetFontColor( CONTROL_STA_NORMAL ) );

            CRect rect(rc);
            rect.left = rect.left+ m_leftspace;
            rect.right = rect.right+ m_rightspace;
            rect.top = rect.top+ m_topspace;
            rect.bottom = rect.bottom+ m_bottomspace;
            if(m_bReturn == TRUE)
            {
                int nCount = GetStrRow(strText);
                int nLenght = rect.Height()/nCount;
                vector<CString> verstring;
                GetRowString(nCount,strText,verstring);
                for (int i =0;i<nCount;i++)
                {
                    rect.top = i*nLenght;
                    rect.bottom = (i+1)*nLenght;
    
                    dc.DrawText(verstring[i], -1, &rect, GetTextFormat( ) | DT_NOPREFIX);
                }
            }
            else
            {
                dc.DrawText( strText, -1, &rect, GetTextFormat( ) | DT_NOPREFIX);
            }

            //LONG lStyle = GetWindowLong( GWL_STYLE );
            
            dc.SelectFont( hOldFont );
            ::DeleteObject( hFont );
        }

        paintDC.BitBlt( 0, 0, rc.Width(), rc.Height(), dc.m_hDC, 0, 0, SRCCOPY );

        dc.SelectBitmap( hOldBmp );
        memBitmap.DeleteObject();
        dc.DeleteDC();

        return 0;
    }

private:

    /**
    *@method   GetTextFormat
    *@brief    得到文字的對齊方式(用DrawText()輸出時的格式)
    *    
    *@return   UINT
    */
    UINT GetTextFormat()
    {
        return m_uFormat;
        //UINT uFormat = 0;//DT_WORDBREAK;//button上的字必須是一行

        //if ((lStyle&SS_SIMPLE)==SS_SIMPLE)
        //{
        //  uFormat = DT_SINGLELINE;
        //}

        //if ((lStyle&SS_LEFTNOWORDWRAP)==SS_LEFTNOWORDWRAP)
        //{
        //  uFormat = DT_WORDBREAK | DT_EDITCONTROL ;
        //}
        //else if ((lStyle&SS_ENDELLIPSIS)==SS_ENDELLIPSIS)
        //{
        //  uFormat = DT_END_ELLIPSIS;
        //}
        //
        x方向
        //if ( (lStyle & SS_CENTER)==SS_CENTER )//x方向,中
        //{
        //  uFormat |= DT_CENTER;
        //}
        //else if ( (lStyle & SS_RIGHT)==SS_RIGHT )//x方向,右
        //{
        //  uFormat |= DT_RIGHT;
        //}
        //else if ( (lStyle & SS_LEFT) == SS_LEFT )//x方向,左
        //{
        //  uFormat |= DT_LEFT;
        //}
        //else//預設,左對齊
        //{
        //  uFormat |= DT_LEFT;
        //}

        y方向
        //if( ( lStyle & SS_CENTER ) == SS_CENTER ) //y方向,中
        //{
        //  uFormat |= DT_VCENTER;
        //}
        //
        //return uFormat;
    }
public:

    /**
    *@method   DeleteImage
    *@brief     删除static設定的圖檔
    *    
    *@return   void
    */
    void DeleteImage()
    {
        for( size_t i = 0; i < m_vtImage.size(); i++ )
        {
            delete m_vtImage[i];
        }
        m_vtImage.clear();
    }

    
    /**
    *@method   SetImage
    *@brief    設定圖像
    *    
    *@param    Image *pImg       指向圖像的指針
    *@param    UINT uInterval = 5000   圖檔換祯時間
    *@return   BOOL
    */
    BOOL SetImage( Image *pImg, UINT uInterval = 5000 )
    {
        m_nInterval = uInterval;
        if( m_nDisTimer != 0 )
        {
            KillTimer( m_nDisTimer );
            m_nDisTimer = 0;
        }

        if( m_vtImage.size() > 0 )
        {
            //清除圖檔,釋放記憶體
            for( size_t i = 0; i < m_vtImage.size(); i++ )
            {
                delete m_vtImage[i];
            }
            m_vtImage.clear();

        }

        if( NULL == pImg )
        {
            return FALSE;
        }

        //獲得圖檔祯數
        m_nActiveFrameNo = 0;
        m_nTotalFrames = 0;    //總祯數

        UINT count = pImg->GetFrameDimensionsCount();
        GUID* pDimensionIDs = new GUID[count];
        pImg->GetFrameDimensionsList( pDimensionIDs, count );
        m_nTotalFrames = pImg->GetFrameCount( &pDimensionIDs[0] );

        //複制每一幀的圖檔,并将圖檔加入到清單中
        UINT i = 0;
        int width = pImg->GetWidth();
        int height = pImg->GetHeight();
        while( true )
        {
            //如果該幀不存在,則退出,否則,加入圖檔清單
            if( Ok == pImg->SelectActiveFrame( pDimensionIDs, i++ ) )
            {
                Bitmap bmp( width, height );
                Graphics graph( &bmp );

                graph.DrawImage( pImg, Rect( 0, 0, width, height ), 0, 0, width, height, UnitPixel );

                m_vtImage.push_back( bmp.Clone( 0, 0, width, height, bmp.GetPixelFormat() ) );
            }
            else
            {
                break;
            }
        }
        delete []pDimensionIDs;

        if(m_vtImage.size()==0) //當圖檔解析錯誤的時,添加一張圖檔!
        {
            m_vtImage.push_back(pImg->Clone());
        }

        if( ( m_nTotalFrames > 1 ) && IsWindow() )
        {
            m_nDisTimer = (UINT)SetTimer( 1001, m_nInterval );
        }

        CRect rc;
        GetWindowRect( rc );
        ScreenToClient( rc );
        InvalidateRect( rc, TRUE );
        return TRUE;
    }
    
    /**
    *@method   SetImage
    *@brief    設定按鈕圖像
    *    
    *@param    UINT uID      圖檔在資源中存放的ID
    *@param    LPCTSTR sTR   圖檔在資源中存放的資源标簽
    *@param    UINT uInterval = 5000  圖檔換祯時間
    *@return   BOOL
    */
    BOOL SetImage( UINT uID, LPCTSTR sTR, UINT uInterval = 5000 )
    {
        Image *pImage = ImageFromIDResourceEx( uID, sTR );
        if( NULL == pImage )
        {
            return FALSE;
        }

        BOOL bRet = SetImage( pImage, uInterval );

        delete pImage;
        return bRet;
    }
    
    /**
    *@method   SetImageEx
    *@brief    截取圖檔的一部分設定到控件中
    *    
    *@param    Image *pImg   指向圖像的指針
    *@param    int nX        指定截取圖檔的起始點,x坐标
    *@param    int nY        指定截取圖檔的起始點,y坐标
    *@param    int nWidth    指定截取圖檔的寬度
    *@param    int nHeigth   指定截取圖檔的寬度
    *@param    UINT uInterval = 5000  圖檔換祯時間
    *@return   BOOL
    */
    BOOL SetImageEx( Image *pImg, int nX, int nY, int nWidth, int nHeigth, UINT uInterval = 5000 )
    {
        m_nInterval = uInterval;
        if( m_nDisTimer != 0 )
        {
            KillTimer( m_nDisTimer );
            m_nDisTimer = 0;
        }

        if( m_vtImage.size() > 0 )
        {
            //清除圖檔,釋放記憶體
            for( size_t i = 0; i < m_vtImage.size(); i++ )
            {
                delete m_vtImage[i];
            }
            m_vtImage.clear();

        }

        if( NULL == pImg )
        {
            return FALSE;
        }

        //獲得圖檔祯數
        m_nActiveFrameNo = 0;
        m_nTotalFrames = 0;    //總祯數

        UINT count = pImg->GetFrameDimensionsCount();
        GUID* pDimensionIDs = new GUID[count];
        pImg->GetFrameDimensionsList( pDimensionIDs, count );
        m_nTotalFrames = pImg->GetFrameCount( &pDimensionIDs[0] );

        //複制每一幀的圖檔,并将圖檔加入到清單中
        UINT i = 0;
        int width = pImg->GetWidth();
        int height = pImg->GetHeight();

        while( Ok == pImg->SelectActiveFrame( pDimensionIDs, i++ ) )
        {
            //如果該幀不存在,則退出,否則,加入圖檔清單
            Bitmap bmp( width, height );
            Graphics graph( &bmp );

            graph.DrawImage( pImg, Rect( 0, 0, width, height ), nX, nY, nWidth, nHeigth, UnitPixel );
            m_vtImage.push_back( bmp.Clone( 0, 0, width, height, bmp.GetPixelFormat() ) );
        }

        delete []pDimensionIDs;

        if( ( m_nTotalFrames > 1 ) && IsWindow() )
        {
            m_nDisTimer = (UINT)SetTimer( 1001, m_nInterval );
        }

        CRect rc;
        GetWindowRect( rc );
        ScreenToClient( rc );
        InvalidateRect( rc, TRUE );
        return TRUE;
    }
    
    /**
    *@method   SetImageEx
    *@brief    截取圖檔的一部分設定到控件中
    *    
    *@param    UINT uID     指向圖像的指針
    *@param    LPCTSTR sTR
    *@param    int nX       指定截取圖檔的起始點,x坐标
    *@param    int nY       指定截取圖檔的起始點,y坐标
    *@param    int nWidth   指定截取圖檔的寬度
    *@param    int nHeigth  指定截取圖檔的寬度
    *@param    UINT uInterval = 5000  圖檔換祯時間
    *@return   BOOL
    */
    BOOL SetImageEx( UINT uID, LPCTSTR sTR, int nX, int nY, int nWidth, int nHeigth, UINT uInterval = 5000 )
    {
        Image *pImage = ImageFromIDResourceEx( uID, sTR );
        if( NULL == pImage )
            return FALSE;

        BOOL bRet = SetImageEx( pImage, nX, nY, nWidth, nHeigth, uInterval );

        delete pImage;
        return bRet;
    }

};