概述:

该类为主要是实现窗口的背景绘制和各种子控件的管理已经,通用控件的资源的加载等一些基础的工作,为我们使用
控件的核心。

代码实现如下:

#pragma once
#include "UserMessage.h"
#include "QsCtrls.h"
#include <vector>
#include "ResourceManager.h"#pragma comment(lib, "ResourceManager.lib")template< class T, bool _bIsChildWnd = false >
class CQsSkinWindowUI//: public CQsMaxMinBase<T>
{public:typedef enum{WINUI_FIRST = 0,WINUI_TOPLEFT,     //窗口左上角WINUI_TOP,         //窗口顶部WINUI_TOPRIGHT,    //窗口右上角WINUI_CENTERLEFT,  //窗口中部左边WINUI_CENTER,      //窗口中部WINUI_CENTERRIGHT, //窗口中部右边WINUI_BOTTOMLEFT,  //窗口底部左边WINUI_BOTTOM,      //窗口底部WINUI_BOTTOMRIGHT, //窗口底部右边WINUI_LAST};
//typedef CQsMaxMinBase<T> theMaxMinClass;
private:CRect  m_rcWnd;                             //当前画刷图像尺寸Image  *m_pImage[WINUI_LAST];    //窗口背景分解图
protected:Bitmap *m_pBKImage;                      //当前窗口背景图片bool m_bIsTransparent;                  //  窗口是否透明public:BEGIN_MSG_MAP(CQsSkinWindowUI)MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)MESSAGE_HANDLER(WM_PAINT, OnPaint)MESSAGE_HANDLER( WM_DRAWBKGNDUI, OnDrawBKGndUI )MESSAGE_HANDLER( WM_DRAWBKGNDUIEX, OnDrawBKGndUIEx )MESSAGE_HANDLER( WM_SIZE, OnSize )MESSAGE_HANDLER( WM_ERASEBKGND, OnEraseBkgnd )MESSAGE_HANDLER(WM_REDRAWBKGND, OnRedrawBkgnd )//CHAIN_MSG_MAP(theMaxMinClass)END_MSG_MAP()DECLARE_WND_CLASS( _T("QsSkinWindow") )/***@method   CQsSkinWindowUI*@brief    CQsSkinWindowUI类构造函数*    *@return   */CQsSkinWindowUI():m_pBKImage( NULL ){for( int i = WINUI_FIRST; i < WINUI_LAST; i++ ){m_pImage[i] = NULL;}m_bIsTransparent = false;}/***@method   ~CQsSkinWindowUI*@brief    CQsSkinWindowUI析构造函数*    *@return   */virtual ~CQsSkinWindowUI(){//释放图片资源for( int i = WINUI_FIRST; i < WINUI_LAST; i++ ){delete m_pImage[i];}//释放当前窗口背景图片if( m_pBKImage ){delete m_pBKImage;m_pBKImage = NULL;}//释放按钮控件int nSize = m_ctlButtons.GetSize();for( int i = 0; i < nSize; i++ ){CQsButton *p = m_ctlButtons[i];ATLASSERT( p );delete p;}m_ctlButtons.RemoveAll();//释放CheckBoxnSize = m_ctlCheckBoxs.GetSize();for( int i = 0; i < nSize; i++ ){CQsCheckBox *p = m_ctlCheckBoxs[i];ATLASSERT( p );delete p;}m_ctlCheckBoxs.RemoveAll();//释放RadioBoxsnSize = m_ctlRadioBoxs.GetSize();for( int i = 0; i < nSize; i++ ){CQsRadioBox *p = m_ctlRadioBoxs[i];ATLASSERT( p );delete p;}m_ctlRadioBoxs.RemoveAll();//释放ComboBoxnSize = m_ctlComboBoxs.GetSize();for( int i = 0; i < nSize; i++ ){CQsComboBox *p = m_ctlComboBoxs[i];ATLASSERT( p );delete p;}m_ctlComboBoxs.RemoveAll();//释放EditnSize = m_ctlEdits.GetSize();for( int i = 0; i < nSize; i++ ){CQsEdit *p = m_ctlEdits[i];ATLASSERT( p );delete p;}m_ctlEdits.RemoveAll();//释放EditnSize = m_ctlProgs.GetSize();for( int i = 0; i < nSize; i++ ){CQSProgressBar *p = m_ctlProgs[i];ATLASSERT( p );delete p;}m_ctlProgs.RemoveAll();//释放CCustomStatic2nSize = m_ctlStaCtrls.GetSize();for( int i = 0; i < nSize; i++ ){CQsStatic *p = m_ctlStaCtrls[i];ATLASSERT( p );delete p;}m_ctlStaCtrls.RemoveAll();//释放控件状态图片对象nSize = m_stImages.GetSize();for( int i = 0; i < nSize; i++ ){STATEIMAGE *p = m_stImages[i];delete p;}m_stImages.RemoveAll();}/***@method   SetExSkin*@brief    换肤时消息背景图片删除和公共控件图片的加载*    *@return   void*/void SetExSkin(){for( int i = WINUI_FIRST; i < WINUI_LAST; i++ ) //bei背景先清除掉{delete m_pImage[i];}//释放当前窗口背景图片if( m_pBKImage ){delete m_pBKImage;m_pBKImage = NULL;}SubClassImagePublic();}/***@method     SetTransparent*@brief      设置窗口是否透明*    *@param       bool bTrans*@return    void*/void SetTransparent( bool bTrans = true ){m_bIsTransparent = bTrans;}/***@method   OnInitDialog*@brief    对话框窗口初始化消息响应函数*    *@param    UINT uMsg        消息类型*@param    WPARAM wParam    未被使用*@param    LPARAM lParam    详见MSDN*@param    BOOL& bHandled   未被使用*@return   LRESULT*/LRESULT OnInitDialog( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/ ){T *pT = static_cast< T* >( this );HMENU  hSystemMenu = ::GetSystemMenu( pT->m_hWnd, FALSE );if ( NULL != hSystemMenu ){::RemoveMenu( hSystemMenu, SC_MOVE, MF_BYCOMMAND );}//ShowMenuButton();return 0;}protected:/***@method   OnSysCommand*@brief    对话框窗口尺寸发生变化消息响应函数*    *@param    UINT uMsg     消息类型*@param    WPARAM wParam   未被使用*@param    LPARAM lParam   详见MSDN*@param    BOOL& bHandled  未被使用*@return   LRESULT*/LRESULT OnSysCommand( UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled ){bHandled = FALSE;return TRUE;}/***@method   OnSize*@brief    对话框窗口尺寸发生变化消息响应函数*    *@param    UINT  uMsg    消息类型*@param    WPARAM wParam  未被使用*@param    LPARAM lParam  详见MSDN*@param    BOOL& bHandled 未被使用*@return   LRESULT*/LRESULT OnSize( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled ){T *pT = static_cast< T* >( this );int cx = LOWORD( lParam );int cy = HIWORD( lParam );//重新生成背景图片if( !CreateBKImageEx( cx, cy ) ){return 0;}CRect rect;pT->GetClientRect(&rect);pT->InvalidateRect( rect );bHandled = false;return 0;}/***@method   SubQSclassAllControls*@brief       将窗口上的所有控件进行关联*    *@param    void*@return   BOOL*/virtual BOOL SubQSclassAllControls( void ){SubClassImagePublic();SetPublicDefaultFont();SetPublicDefaultColor();return SubclassAllControls();}/***@method   SetPublicDefaultColor*@brief    设置默认字体的颜色*    *@return   void*/void SetPublicDefaultColor(){DWORD dword =0;std::wstring sss = _T("default_color");GetColor(sss,dword);CCtrlImageMgr::SetDefaultFontColor(dword);}/***@method   SetPublicDefaultFont*@brief    设置窗口默认的字体*    *@return   void*/void SetPublicDefaultFont(){std::wstring strfontName;double nfontsize=0;int nfontstyle =0;int fnWeight = FW_NORMAL; BYTE bItalic = FALSE;BYTE bUnderline = FALSE; BYTE bStrikeOut = FALSE;GetFontEx(_T("default_font"),strfontName,nfontsize,nfontstyle);if(FontStyleRegular == nfontstyle){fnWeight = FW_NORMAL;}else if(FontStyleBold == nfontstyle){fnWeight = FW_BOLD;}else if(FontStyleItalic == nfontstyle){bItalic = TRUE;}else if(FontStyleBoldItalic == nfontstyle){bItalic = TRUE;fnWeight = FW_BOLD;}else if(FontStyleUnderline == nfontstyle){bUnderline = TRUE;}else if(FontStyleStrikeout == nfontstyle){bStrikeOut = TRUE;}CCtrlImageMgr::SetDefaultFont(strfontName.c_str(),(int)nfontsize,fnWeight,bItalic,bUnderline,bStrikeOut);}/***@method   SubClassImagePublic*@brief    设置公共控件的Image*    *@return   void*/void SubClassImagePublic(){CCtrlImageMgr::ClearStateImage();按钮Image *pImg = NULL;GetImage( _T("comm_button.png"), pImg);if(NULL != pImg){CCtrlImageMgr::SetStateImage( CONTROL_BTN_NORMAL, pImg, 0, 0, 84, 37 );CCtrlImageMgr::SetStateImage( CONTROL_BTN_FOCUS, pImg, 84, 0, 84, 37 );CCtrlImageMgr::SetStateImage( CONTROL_BTN_MOUSEIN, pImg, 84, 0, 84, 37 );CCtrlImageMgr::SetStateImage( CONTROL_BTN_MOUSEDOWN, pImg, 168, 0, 84, 37 );CCtrlImageMgr::SetStateImage( CONTROL_BTN_DISABLED, pImg, 252, 0, 84, 37 );}//复选框GetImage( _T("comm_checkbox.png"), pImg);if(NULL != pImg){   CCtrlImageMgr::SetStateImage( CONTROL_CHK_DISCHECKED, pImg,0,0,18,18 );CCtrlImageMgr::SetStateImage( CONTROL_CHK_CHECKED, pImg,18,0,18,18);CCtrlImageMgr::SetStateImage( CONTROL_CHK_DISUNCHECK, pImg,36,0,18,18 );CCtrlImageMgr::SetStateImage( CONTROL_CHK_UNCHECK, pImg,54,0,18,18);GetImage( _T("comm_checkbox_select_focus.png"), pImg);if(NULL!= pImg){CCtrlImageMgr::SetStateImage( CONTROL_CHK_FOUCS_CHECKED, pImg,0,0,18,18);}GetImage( _T("comm_checkbox_unselect_focus.png"), pImg);if(NULL!= pImg){CCtrlImageMgr::SetStateImage( CONTROL_CHK_FOUCS_UNCHECK, pImg,0,0,18,18);}}//单选框GetImage( _T("comm_radiobox.png"), pImg);if(NULL != pImg){CCtrlImageMgr::SetStateImage( CONTROL_RDB_UNCHECK, pImg, 0, 0, 20, 20 );CCtrlImageMgr::SetStateImage( CONTROL_RDB_CHECKED, pImg, 20, 0, 20, 20 );CCtrlImageMgr::SetStateImage( CONTROL_RDB_DISUNCHECK, pImg, 40, 0, 20, 20 );CCtrlImageMgr::SetStateImage( CONTROL_RDB_DISCHECKED, pImg, 60, 0, 20, 20 );}GetImage( _T("comm_combox.png"), pImg);if(NULL != pImg){CCtrlImageMgr::SetStateImage( CONTROL_CBS_NORMAL, pImg, 0, 0, 24, 24 );CCtrlImageMgr::SetStateImage( CONTROL_CBS_FOCUS, pImg, 0, 0, 24, 24 );CCtrlImageMgr::SetStateImage( CONTROL_CBS_MOUSEIN, pImg, 24, 0, 24, 24 );CCtrlImageMgr::SetStateImage( CONTROL_CBS_MOUSEDOWN, pImg, 48, 0, 24, 24 );CCtrlImageMgr::SetStateImage( CONTROL_CBS_DISABLED, pImg, 72, 0, 24, 24 );}}/***@method   OnEraseBkgnd*@brief    窗口背景绘制消息*    *@param    UINT uMsg        消息类型*@param    WPARAM wParam    未被使用*@param    LPARAM lParam    详见MSDN*@param    BOOL&  bHandled  未被使用*@return   LRESULT*/LRESULT OnEraseBkgnd( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/ ){return FALSE;}LRESULT OnRedrawBkgnd( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/ ){ReDraw();return TRUE;}/***@method   OnCtlColorStatic*@brief    窗口绘制消息响应函数*    *@param    UINT uMsg    消息类型*@param    WPARAM wParam   未被使用*@param    LPARAM lParam   详见MSDN*@param    BOOL& bHandled  未被使用*@return   LRESULT*/LRESULT OnCtlColorStatic( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ){T *pT = static_cast< T* >( this );HWND hwnd = ( HWND )lParam;for( int i = 0; i < m_ctlStaCtrls.GetSize(); i++ ){if( m_ctlStaCtrls[i]->m_hWnd == hwnd ){HDC hdc = ( HDC )wParam;//用控件背景做一个画刷WTL::CDC memDC;memDC.CreateCompatibleDC( hdc );WTL::CBitmap memBitmap;CRect rc;::GetWindowRect( hwnd, rc );memBitmap.CreateCompatibleBitmap( hdc, rc.Width(), rc.Height() );HBITMAP hOldBmp = memDC.SelectBitmap( memBitmap.m_hBitmap );//获得控件背景pT->SendMessage( WM_DRAWBKGNDUI, ( WPARAM )memDC.m_hDC, ( LPARAM )hwnd );//创建画刷HBRUSH hBrush = ::CreatePatternBrush( memBitmap.m_hBitmap );memDC.SelectBitmap( hOldBmp );return ( LRESULT )hBrush;//( LRESULT )::GetStockObject( NULL_BRUSH );}}return DefWindowProc( pT->m_hWnd, uMsg, wParam, lParam );}/***@method   OnDrawBKGndUI*@brief    绘制子控件背景*    *@param    UINT uMsg        消息类型*@param    WPARAM wParam    未被使用*@param    LPARAM lParam    详见MSDN*@param    BOOL& bHandled   未被使用*@return   LRESULT*/LRESULT OnDrawBKGndUI( UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/ ){HDC hdc = ( HDC )wParam;HWND hwnd = ( HWND )lParam;//获得当前控件在窗口上的位置T *pT = static_cast< T* >( this );if( !m_pBKImage ){CRect rc;pT->GetWindowRect( rc );if( !CreateBKImageEx( rc.Width(), rc.Height() ) )return FALSE;}//获得控件在当前窗口上的位置CRect rc;::GetWindowRect( hwnd, rc );pT->ScreenToClient( rc );//将图像复制给控件Graphics graph( hdc );graph.DrawImage( m_pBKImage, Rect( 0, 0, rc.Width(), rc.Height() ),rc.left, rc.top, rc.Width(), rc.Height(), UnitPixel );graph.ReleaseHDC( hdc );return 0;}LRESULT OnDrawBKGndUIEx( UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/ ){Graphics* pGraph = (Graphics*)wParam;HWND hwnd = ( HWND )lParam;//获得当前控件在窗口上的位置T *pT = static_cast< T* >( this );if( !m_pBKImage ){CRect rc;pT->GetWindowRect( rc );if( !CreateBKImageEx( rc.Width(), rc.Height() ) )return FALSE;}//获得控件在当前窗口上的位置CRect rc;::GetWindowRect( hwnd, rc );pT->ScreenToClient( rc );pGraph->DrawImage( m_pBKImage, Rect( 0, 0, rc.Width(), rc.Height() ),rc.left, rc.top, rc.Width(), rc.Height(), UnitPixel );return TRUE;}/***@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*/ ){T *pT = static_cast< T* >( this );CRect rc;pT->GetWindowRect( rc );WTL::CPaintDC paintDC( pT->m_hWnd );//创建窗口图片对象WTL::CDC memDC;memDC.CreateCompatibleDC( paintDC.m_hDC );WTL::CBitmap memBitmap;memBitmap.CreateCompatibleBitmap( paintDC.m_hDC, rc.Width(), rc.Height() );HBITMAP hOldBmp = memDC.SelectBitmap( memBitmap.m_hBitmap );BOOL bRet = CreateBkImage( memDC.m_hDC, rc.Width(), rc.Height() );if( bRet ){paintDC.StretchBlt( 0, 0, rc.Width(), rc.Height(), memDC.m_hDC, 0, 0, rc.Width(), rc.Height(), SRCCOPY );}memDC.SelectBitmap( hOldBmp );if( !bRet ){#ifdef _USERLOGFILE_DEBUG_MSG( _LOGSTR( "创建窗口背景图片失败! cx=%d cy=%d" ), rc.Width(), rc.Height() );
#endifreturn ::DefWindowProc( pT->m_hWnd, uMsg, wParam, lParam );}return 0;}/***@method   OnCtlColorDlg*@brief    获得对话框窗口背景*    *@param    UINT uMsg     消息类型*@param    WPARAM wParam   未被使用*@param    LPARAM lParam   详见MSDN*@param    BOOL& bHandled  未被使用*@return   LRESULT*/LRESULT OnCtlColorDlg( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/ ){T *pT = static_cast< T* >( this );CRect rc;pT->GetWindowRect( rc );HBRUSH hBrush = CreateBkBrush( rc.Width(), rc.Height() );if( !hBrush ){return ::DefWindowProc( pT->m_hWnd, uMsg, wParam, lParam );}return ( LRESULT ) hBrush;}/***@method   CreateBkImage*@brief    创建背景图像*    *@param    HDC hDC*@param    int width  宽度*@param    int height 高度*@return   BOOL*/BOOL CreateBkImage( HDC hDC, int width, int height ){CSize szBmp( 0, 0 ), szWnd( width, height );if( m_pBKImage ){szBmp = CSize( m_pBKImage->GetWidth(), m_pBKImage->GetHeight() );}if( szBmp != szWnd ){if( !CreateBKImageEx( width, height ) ){#ifdef _USERLOGFILE_DEBUG_MSG( _LOGSTR( "创建窗口背景图片失败! cx=%d cy=%d" ), width, height );
#endifreturn FALSE;}}//将图像送给指定设备Graphics graph( hDC );graph.DrawImage( m_pBKImage, Rect( 0, 0, width, height ), 0, 0, width, height, UnitPixel );graph.ReleaseHDC( hDC );return TRUE;}/***@method   CreateBkBrush*@brief    创建背景画刷*    *@param    int width  窗口宽度*@param    int height 窗口高度*@return   HBRUSH   成功返回创建的画刷句柄,否则返回NULL*/HBRUSH CreateBkBrush( int width, int height ){WTL::CDC memDC;T *pT = static_cast< T* >( this );HDC hdc = pT->GetDC();//创建内存作图句柄memDC.CreateCompatibleDC( hdc );WTL::CBitmap memBitmap;memBitmap.CreateCompatibleBitmap( hdc, width, height );HBITMAP hOldBmp = memDC.SelectBitmap( memBitmap.m_hBitmap );//创建背景BOOL bRet = CreateBkImage( memDC.m_hDC, width, height );memDC.SelectBitmap( hOldBmp );if( !bRet )return NULL;return CreatePatternBrush( memBitmap.m_hBitmap );}private:/***@method   CreateBKImageEx*@brief    创建当前背景图片*    *@param    int width  窗口宽度*@param    int height 窗口高度*@return   BOOL*/BOOL CreateBKImageEx( int width, int height ){T *pT = static_cast< T* >( this );delete m_pBKImage;m_pBKImage = new Bitmap( width, height );if( NULL == m_pBKImage ){#ifdef _USERLOGFILE_DEBUG_MSG( _LOGSTR( "创建窗口背景图片失败! cx=%d cy=%d" ), width, height );
#endifreturn FALSE;}Graphics gh( m_pBKImage );gh.SetPageScale( 1.0 );gh.SetPageUnit( UnitPixel ); gh.SetSmoothingMode( SmoothingModeNone );//  如果是透明窗口,需要向父窗口发送请求,绘制父窗口在该位置的别经if ( m_bIsTransparent ) {HWND hParent = pT->GetParent( );if ( NULL != hParent ){::SendMessage( hParent, WM_DRAWBKGNDUIEX, (WPARAM)(&gh), ( LPARAM )pT->m_hWnd );}}else{//填充白色背景SolidBrush sb( Color( 255, 255, 255, 255 ) );gh.FillRectangle( &sb, 0, 0, width, height );}//调用背景绘制函数BOOL bRet =  OnDrawBKGnd( gh );if( !bRet ){#ifdef _USERLOGFILE_DEBUG_MSG( _LOGSTR( "调用OnDrawBKGnd函数返回错误!" ) );
#endifdelete m_pBKImage;m_pBKImage = NULL;}//      if( !_bIsChildWnd )
//      {//          //创建异形窗口
//          HRGN rgn = ::CreateRoundRectRgn( 3, 0, width-3, height-3, 10, 10 );
//          T *pT = static_cast< T* >( this );
//          ::SetWindowRgn( pT->m_hWnd, rgn, TRUE );
//          DeleteObject( rgn );
//      }return bRet;}/***@method   CheckBKImage*@brief    检查窗口背景分解图的完整性*    *@param    void*@return   BOOL*/BOOL CheckBKImage( void ){for( int i = 1; i < 10; i++ ){if( m_pImage[i] == NULL )return FALSE;}return TRUE;}public:/***@method   ResizeWindow*@brief    重新绘制窗口背景*    *@param    void*@return   BOOL*/BOOL ResizeWindow( void ){T* pT = static_cast< T* >( this );CRect rc;pT->GetWindowRect( rc );if( !CreateBKImageEx( rc.Width(), rc.Height() ) )return FALSE;pT->InvalidateRect(rc);return TRUE;}/***@method   SetImage*@brief    设置窗口背景图像*    *@param    UINT nState  详见CONTROL_STATE_IMG定义*@param    Image *pImg  指向图像的指针*@param    int nx = 0   图像范围--左上点的X坐标,默认为0*@param    int ny = 0   图像范围--左上点的Y坐标,默认为0*@param    int nWidth = 0   图像范围--宽度,默认为0,此时为图像的宽度*@param    int nHeight = 0  图像范围--高度,默认为0,此时为图像的高度*@return   BOOL*/BOOL SetImage( UINT nState, Image *pImg, int nx = 0, int ny = 0, int nWidth = 0, int nHeight = 0 ){if( (nState >= WINUI_LAST ) || (nState <= WINUI_FIRST ) || ( NULL == pImg ) ){return FALSE;}int width = nWidth==0?pImg->GetWidth():nWidth;int height = nHeight==0?pImg->GetHeight():nHeight;Bitmap bmp( width, height );Graphics graph( &bmp );graph.DrawImage( pImg, Rect( 0, 0, width, height ), nx, ny, width, height, UnitPixel );m_pImage[ nState ] = bmp.Clone( 0, 0, width, height, bmp.GetPixelFormat() );return TRUE;}/***@method   SetImage*@brief    设置窗口背景图像*    *@param    UINT nState   详见CONTROL_STATE_IMG定义*@param    UINT uID      图片在资源中存放的ID*@param    LPCTSTR sTR   图片在资源中存放的资源标签*@param    int nx = 0    图像范围--左上点的X坐标,默认为0*@param    int ny = 0    图像范围--左上点的Y坐标,默认为0*@param    int nWidth = 0  图像范围--宽度,默认为0,此时为图像的宽度*@param    int nHeight = 0 图像范围--高度,默认为0,此时为图像的高度*@return   BOOL*/BOOL SetImage( UINT nState, UINT uID, LPCTSTR sTR, int nx = 0, int ny = 0, int nWidth = 0, int nHeight = 0 ){Image *pImage = ImageFromIDResourceEx( uID, sTR );if( NULL == pImage )return FALSE;BOOL bRet = SetImage( nState, pImage, nx, ny, nWidth, nHeight );delete pImage;return bRet;}/***@method   SetImage*@brief    设置窗口背景图像*    *@param    Image *pImg     窗口图像对象*@param    int width = 50  截取宽度*@param    int height = 50 截取高度*@return   BOOL*/BOOL SetImage( Image *pImg, int width = 50, int height = 50 ){int left = 0;int top = 0;int halfx = pImg->GetWidth() / 2;int halfy = pImg->GetHeight() / 2;int right = pImg->GetWidth() - width;int bottom = pImg->GetHeight() - height;SetImage( WINUI_TOPLEFT, pImg, left, top, width, height );SetImage( WINUI_TOP, pImg, halfx, top, width, height );SetImage( WINUI_TOPRIGHT, pImg, right, top, width, height );SetImage( WINUI_CENTERLEFT, pImg, left, halfy, width, height );SetImage( WINUI_CENTER, pImg, halfx, halfy, width, height );SetImage( WINUI_CENTERRIGHT, pImg, right, halfy, width, height );SetImage( WINUI_BOTTOMLEFT, pImg, left, bottom, width, height );SetImage( WINUI_BOTTOM, pImg, halfx, bottom, width, height );SetImage( WINUI_BOTTOMRIGHT, pImg, right, bottom, width, height );return CheckBKImage();}/***@method   SetImage*@brief    设置窗口背景图像*    *@param    UINT uID         图片在资源中存放的ID*@param    LPCTSTR sTR      图片在资源中存放的资源标签*@param    int width = 50   截取宽度*@param    int height = 50  截取高度*@return   BOOL*/BOOL SetImage( UINT uID, LPCTSTR sTR, int width = 50, int height = 50 ){Image *pImage = ImageFromIDResourceEx( uID, sTR );if( NULL == pImage )return FALSE;BOOL bRet = SetImage( pImage, width, height );delete pImage;return bRet;}/***@method   OnDrawBKGnd*@brief    绘制窗口背景*    *@param    Graphics &graph  用于作图的画布对象*@return   BOOL*/virtual BOOL OnDrawBKGnd(Graphics &graph){if( !CheckBKImage() ){return FALSE;}T *pT = static_cast< T* >( this );//获得当前窗口尺寸CRect rc;pT->GetWindowRect( rc );//使用5填充整个区域int nStart = m_pImage[WINUI_CENTERLEFT]->GetWidth();int nEnd = rc.Width() - m_pImage[WINUI_CENTERRIGHT]->GetWidth();int width = m_pImage[WINUI_CENTER]->GetWidth();for( int x = nStart; x < nEnd; x += width ){if( ( nEnd - x ) < width )width = nEnd - x;int nTopStart = m_pImage[WINUI_TOP]->GetHeight();int nTopEnd = rc.Height() - m_pImage[WINUI_BOTTOM]->GetHeight();int height = m_pImage[WINUI_CENTER]->GetHeight();for( int y = nTopStart; y < nTopEnd; y += height ){if( ( nTopEnd - y ) < height )height = nTopEnd - y;graph.DrawImage( m_pImage[WINUI_CENTER], Rect( x, y, width, height ), 0, 0, width, height, UnitPixel );}}//画顶端横条nStart = m_pImage[WINUI_TOPLEFT]->GetWidth();nEnd = rc.Width() - m_pImage[WINUI_TOPRIGHT]->GetWidth();width = m_pImage[WINUI_TOP]->GetWidth();for( int x = nStart; x < nEnd ; x += width ){if( ( nEnd - x ) < width )width = nEnd - x;graph.DrawImage( m_pImage[WINUI_TOP], Rect( x, 0, width, m_pImage[WINUI_TOP]->GetHeight() ),0, 0, width, m_pImage[WINUI_TOP]->GetHeight(), UnitPixel );}//画底部横条nStart = m_pImage[WINUI_BOTTOMLEFT]->GetWidth();nEnd = rc.Width() - m_pImage[WINUI_BOTTOMRIGHT]->GetWidth();width = m_pImage[WINUI_BOTTOM]->GetWidth();int top = rc.Height() - m_pImage[WINUI_BOTTOM]->GetHeight();for( int x = nStart; x < nEnd ; x += width ){if( ( nEnd - x ) < width )width = nEnd - x;graph.DrawImage( m_pImage[WINUI_BOTTOM], Rect( x, top, width, m_pImage[WINUI_BOTTOM]->GetHeight() ),0, 0, m_pImage[WINUI_BOTTOM]->GetWidth(), m_pImage[WINUI_BOTTOM]->GetHeight(), UnitPixel );}//画左部竖条nStart = m_pImage[WINUI_TOPLEFT]->GetHeight();nEnd = rc.Height() - m_pImage[WINUI_BOTTOMLEFT]->GetHeight();int height = m_pImage[WINUI_CENTERLEFT]->GetHeight();for( int y = nStart; y < nEnd ; y += height ){if( ( nEnd - y ) < height )height = nEnd - y;graph.DrawImage( m_pImage[WINUI_CENTERLEFT], Rect( 0, y, m_pImage[WINUI_CENTERLEFT]->GetWidth(), height ),0, 0, m_pImage[WINUI_CENTERLEFT]->GetWidth(), m_pImage[WINUI_CENTERLEFT]->GetHeight(), UnitPixel );}//画右部竖条nStart = m_pImage[WINUI_TOPRIGHT]->GetHeight();nEnd = rc.Height() - m_pImage[WINUI_BOTTOMRIGHT]->GetHeight();height = m_pImage[WINUI_CENTERRIGHT]->GetHeight();int left = rc.Width() - m_pImage[WINUI_CENTERRIGHT]->GetWidth();for( int y = nStart; y < nEnd ; y += height ){if( ( nEnd - y ) < height )height = nEnd - y;graph.DrawImage( m_pImage[WINUI_CENTERRIGHT], Rect( left, y, m_pImage[WINUI_CENTERRIGHT]->GetWidth(), height ),0, 0, m_pImage[WINUI_CENTERRIGHT]->GetWidth(), m_pImage[WINUI_CENTERRIGHT]->GetHeight(), UnitPixel );}//画4个角graph.DrawImage( m_pImage[WINUI_TOPLEFT], Rect( 0, 0, m_pImage[WINUI_TOPLEFT]->GetWidth(), m_pImage[WINUI_TOPLEFT]->GetHeight() ), 0, 0, m_pImage[WINUI_TOPLEFT]->GetWidth(), m_pImage[WINUI_TOPLEFT]->GetHeight(), UnitPixel );graph.DrawImage( m_pImage[WINUI_TOPRIGHT], Rect( rc.Width() - m_pImage[WINUI_TOPRIGHT]->GetWidth(), 0, m_pImage[WINUI_TOPRIGHT]->GetWidth(), m_pImage[WINUI_TOPRIGHT]->GetHeight() ), 0, 0, m_pImage[WINUI_TOPRIGHT]->GetWidth(), m_pImage[WINUI_TOPRIGHT]->GetHeight(), UnitPixel );graph.DrawImage( m_pImage[WINUI_BOTTOMLEFT], Rect( 0, rc.Height()-m_pImage[WINUI_BOTTOMLEFT]->GetHeight(),m_pImage[WINUI_BOTTOMLEFT]->GetWidth(), m_pImage[WINUI_BOTTOMLEFT]->GetHeight() ), 0, 0, m_pImage[WINUI_BOTTOMLEFT]->GetWidth(), m_pImage[WINUI_BOTTOMLEFT]->GetHeight(), UnitPixel );graph.DrawImage( m_pImage[WINUI_BOTTOMRIGHT], Rect( rc.Width() - m_pImage[WINUI_BOTTOMRIGHT]->GetWidth(), rc.Height()-m_pImage[WINUI_BOTTOMRIGHT]->GetHeight(), m_pImage[WINUI_BOTTOMRIGHT]->GetWidth(), m_pImage[WINUI_BOTTOMRIGHT]->GetHeight() ), 0, 0, m_pImage[WINUI_BOTTOMRIGHT]->GetWidth(), m_pImage[WINUI_BOTTOMRIGHT]->GetHeight(), UnitPixel );return TRUE;}public:typedef enum{CTRL_BUTTON = 0,    //按钮控件CTRL_CHECKBOX,      //CHECKBOXCTRL_COMBOBOX,      //COMBOBOXCTRL_EDIT,          //EDITCTRL_PROGRESS,      //进度条CTRL_RADIOBOX,      //单选按钮CTRL_STATIC,        //静态标签CTRL_SCROLLBAR,     //滚动条CTRL_TABCTRL,       //属性页}CTRLTYPE;protected:CSimpleArray< CQsButton * > m_ctlButtons;        //界面上的所有按钮控件列表CSimpleArray< CQsCheckBox * > m_ctlCheckBoxs;    //界面上的所有按钮控件列表CSimpleArray< CQsRadioBox * > m_ctlRadioBoxs;    //界面上的所有按钮控件列表CSimpleArray< CQsComboBox * > m_ctlComboBoxs;    //界面上的所有下列选择控件列表CSimpleArray< CQsEdit * > m_ctlEdits;            //界面上的所有下列选择控件列表CSimpleArray< CQSProgressBar * > m_ctlProgs; //界面上的所有进度条控件列表CSimpleArray< CQsStatic * > m_ctlStaCtrls;   //界面上的所有Static控件列表std::vector< HWND > m_vtUnSubclass;         //不需要自动绑定的控件句柄
private:/***@method   GetCustomObjectEx*@brief    获得对象实例*    *@param    HWND hwnd  根据窗口句柄获得自定义控件对象*@return   CCtrlImageMgr *  如果存在,返回对象地址否则返回NULL*/CCtrlImageMgr *GetCustomObjectEx( HWND hwnd ){CCtrlImageMgr *pcim = NULL;for( int i = 0; ( i < m_ctlButtons.GetSize() ) && ( NULL == pcim ); i++ ){CQsButton *p = m_ctlButtons[i];if( p->m_hWnd == hwnd ){pcim = (CCtrlImageMgr*)p;break;}}for( int i = 0; ( i < m_ctlCheckBoxs.GetSize() ) && ( NULL == pcim ); i++ ){CQsCheckBox *p = m_ctlCheckBoxs[i];if( p->m_hWnd == hwnd ){pcim = (CCtrlImageMgr*)p;break;}}for( int i = 0; ( i < m_ctlRadioBoxs.GetSize() ) && ( NULL == pcim ); i++ ){CQsRadioBox *p = m_ctlRadioBoxs[i];if( p->m_hWnd == hwnd ){pcim = (CCtrlImageMgr*)p;break;}}for( int i = 0; ( i < m_ctlComboBoxs.GetSize() ) && ( NULL == pcim ); i++ ){CQsComboBox *p = m_ctlComboBoxs[i];if( p->m_hWnd == hwnd ){pcim = (CCtrlImageMgr*)p;break;}}for( int i = 0; ( i < m_ctlEdits.GetSize() ) && ( NULL == pcim ); i++ ){CQsEdit *p = m_ctlEdits[i];if( p->m_hWnd == hwnd ){pcim = (CCtrlImageMgr*)p;break;}}for( int i = 0; ( i < m_ctlProgs.GetSize() ) && ( NULL == pcim ); i++ ){CQSProgressBar *p = m_ctlProgs[i];if( p->m_hWnd == hwnd ){pcim = (CCtrlImageMgr*)p;break;}}for( int i = 0; ( i < m_ctlStaCtrls.GetSize() ) && ( NULL == pcim ); i++ ){CQsStatic *p = m_ctlStaCtrls[i];if( p->m_hWnd == hwnd ){pcim = (CCtrlImageMgr*)p;break;}}return pcim;}protected:/***@method   GetCustomObject*@brief    获得对象实例*    *@param    HWND hwnd   根据窗口句柄获得自定义控件对象*@return   void *      如果存则,返回对象地址否则返回NULL*/void *GetCustomObject( HWND hwnd ){void *pcim = NULL;for( int i = 0; ( i < m_ctlButtons.GetSize() ) && ( NULL == pcim ); i++ ){CQsButton *p = m_ctlButtons[i];if( p->m_hWnd == hwnd ){pcim = (CQsButton*)p;break;}}for( int i = 0; ( i < m_ctlCheckBoxs.GetSize() ) && ( NULL == pcim ); i++ ){CQsCheckBox *p = m_ctlCheckBoxs[i];if( p->m_hWnd == hwnd ){pcim = (CQsCheckBox*)p;break;}}for( int i = 0; ( i < m_ctlRadioBoxs.GetSize() ) && ( NULL == pcim ); i++ ){CQsRadioBox *p = m_ctlRadioBoxs[i];if( p->m_hWnd == hwnd ){pcim = (CQsRadioBox*)p;break;}}for( int i = 0; ( i < m_ctlComboBoxs.GetSize() ) && ( NULL == pcim ); i++ ){CQsComboBox *p = m_ctlComboBoxs[i];if( p->m_hWnd == hwnd ){pcim = (CQsComboBox*)p;break;}}for( int i = 0; ( i < m_ctlEdits.GetSize() ) && ( NULL == pcim ); i++ ){CQsEdit *p = m_ctlEdits[i];if( p->m_hWnd == hwnd ){pcim = (CQsEdit*)p;break;}}for( int i = 0; ( i < m_ctlProgs.GetSize() ) && ( NULL == pcim ); i++ ){CQSProgressBar *p = m_ctlProgs[i];if( p->m_hWnd == hwnd ){pcim = (CQSProgressBar*)p;break;}}for( int i = 0; ( i < m_ctlStaCtrls.GetSize() ) && ( NULL == pcim ); i++ ){CQsStatic *p = m_ctlStaCtrls[i];if( p->m_hWnd == hwnd ){pcim = (CQsStatic*)p;break;}}return pcim;}/***@method   GetCustomObject*@brief    获得对象实例*    *@param    UINT uID*@return   void *  如果存则,返回对象地址否则返回NULL*/void *GetCustomObject( UINT uID ){T *pT = static_cast< T* >( this );return GetCustomObject( pT->GetDlgItem( uID ) );}/***@method   SetImage*@brief    设置控件图像*    *@param    HWND hwnd*@param    UINT nState      详见CTRL_STATE_IMG定义*@param    Image *pImage    图片对象*@param    int nx = 0       图像范围--左上点的X坐标,默认为0*@param    int ny = 0       图像范围--左上点的Y坐标,默认为0*@param    int nWidth = 0   图像范围--宽度,默认为0,此时为图像的宽度*@param    int nHeight = 0  图像范围--高度,默认为0,此时为图像的高度*@return   BOOL*/BOOL SetImage( HWND hwnd, UINT nState, Image *pImage, int nx = 0, int ny = 0, int nWidth = 0, int nHeight = 0 ){CCtrlImageMgr *pcim = GetCustomObjectEx( hwnd );if( NULL != pcim ){return pcim->SetImage( nState, pImage, nx, ny, nWidth, nHeight );}return FALSE;}/***@method   SetImage*@brief    设置控件图像*    *@param    HWND hwnd*@param    UINT nState  详见CTRL_STATE_IMG定义*@param    UINT uID     图片在资源中存放的ID*@param    LPCTSTR sTR  图片在资源中存放的资源标签*@param    int nx = 0   图像范围--左上点的X坐标,默认为0*@param    int ny = 0   图像范围--左上点的Y坐标,默认为0*@param    int nWidth = 0   图像范围--宽度,默认为0,此时为图像的宽度*@param    int nHeight = 0  图像范围--高度,默认为0,此时为图像的高度*@return   BOOL*/BOOL SetImage( HWND hwnd, UINT nState, UINT uID, LPCTSTR sTR, int nx = 0, int ny = 0, int nWidth = 0, int nHeight = 0 ){Image *pImage = ImageFromIDResourceEx( uID, sTR );if( pImage ){SetImage( hwnd, nState, pImage, nx, ny, nWidth, nHeight );delete pImage;}return TRUE;}/***@method   SetCtrlIcon*@brief    设置控件图标*    *@param    HWND hwnd*@param    UINT nState      详见CTRL_STATE_IMG定义*@param    Image *pImage    图片对象*@param    int nx = 0       图像范围--左上点的X坐标,默认为0*@param    int ny = 0       图像范围--左上点的Y坐标,默认为0*@param    int nWidth = 0   图像范围--宽度,默认为0,此时为图像的宽度*@param    int nHeight = 0  图像范围--高度,默认为0,此时为图像的高度*@return   BOOL*/BOOL SetCtrlIcon( HWND hwnd, UINT nState, Image *pImage, int nx = 0, int ny = 0, int nWidth = 0, int nHeight = 0 ){CCtrlImageMgr *pcim = GetCustomObjectEx( hwnd );if( NULL != pcim ){return pcim->SetCtrlIcon( nState, pImage, nx, ny, nWidth, nHeight );}return FALSE;}/***@method   SetCtrlIcon*@brief    设置控件图标*    *@param    HWND hwnd*@param    UINT nState   详见CTRL_STATE_IMG定义*@param    UINT uID      图片在资源中存放的ID*@param    LPCTSTR sTR   图片在资源中存放的资源标签*@param    int nx = 0    图像范围--左上点的X坐标,默认为0*@param    int ny = 0    图像范围--左上点的Y坐标,默认为0*@param    int nWidth = 0   图像范围--宽度,默认为0,此时为图像的宽度*@param    int nHeight = 0  图像范围--高度,默认为0,此时为图像的高度*@return   BOOL*/BOOL SetCtrlIcon( HWND hwnd, UINT nState, UINT uID, LPCTSTR sTR, int nx = 0, int ny = 0, int nWidth = 0, int nHeight = 0 ){Image *pImage = ImageFromIDResourceEx( uID, sTR );if( pImage ){SetCtrlIcon( hwnd, nState, pImage, nx, ny, nWidth, nHeight );delete pImage;}return TRUE;}private:typedef struct _STATEIMAGE{HWND          hWnd;   //控件句柄CTRLTYPE      ct;     //控件类型UINT          uState; //状态Image         *pImage;//显示图片_STATEIMAGE():pImage( NULL ){}~_STATEIMAGE(){delete pImage;}}STATEIMAGE;CSimpleArray< STATEIMAGE * > m_stImages;  //控件状态图片列表private:/***@method   GetControlImage*@brief    获得控件在指定状态下的图片*    *@param    CTRLTYPE ct  控件类型*@param    UINT uState  控件状态*@param    HWND hwnd    控件句柄,如果该值为NULL,则返回该控件类型对应状态下的图片*@return   Image *      成功返回对应的图片对象,否则返回NULL*/Image *GetControlImage( CTRLTYPE ct, UINT uState, HWND hwnd ){Image *pImage = NULL;int nSize = m_stImages.GetSize();for( int i = 0; i < nSize; i++ ){STATEIMAGE *p = m_stImages[i];//如果获得控件类型对应状态下的图片if( ( ct == p->ct ) && ( uState == p->uState ) ){pImage = p->pImage;}if( ( ct == p->ct ) && ( uState == p->uState ) && ( hwnd == p->hWnd ) ){return p->pImage;}}return pImage;}public:/***@method   SetControlImage*@brief    设置控件在指定状态下的图片*    *@param    CTRLTYPE ct   控件类型*@param    UINT uState   控件状态*@param    Image *pImage 图片对象*@param    HWND hwnd = NULL   *@param    int nx = 0         图像范围--左上点的X坐标,默认为0*@param    int ny = 0         图像范围--左上点的Y坐标,默认为0*@param    int nWidth = 0     图像范围--宽度,默认为0,此时为图像的宽度*@param    int nHeight = 0    图像范围--高度,默认为0,此时为图像的高度*@return   BOOL*/BOOL SetControlImage( CTRLTYPE ct, UINT uState, Image *pImage, HWND hwnd = NULL, int nx = 0, int ny = 0, int nWidth = 0, int nHeight = 0 ){int nSize = m_stImages.GetSize();for( int i = 0; i < nSize; i++ ){STATEIMAGE *p = m_stImages[i];if( ( ct == p->ct ) && ( uState == p->uState ) && ( hwnd == p->hWnd ) ){delete p;m_stImages.RemoveAt( i );break;}}STATEIMAGE *p = new STATEIMAGE;p->hWnd = hwnd;p->ct = ct;p->uState = uState;//复制图片int width = nWidth==0?pImage->GetWidth():nWidth;int height = nHeight==0?pImage->GetHeight():nHeight;Bitmap bmp( width, height );Graphics graph( &bmp );graph.DrawImage( pImage, Rect( 0, 0, width, height ), nx, ny, width, height, UnitPixel );bmp.Clone(0, 0, width, height, bmp.GetPixelFormat() );p->pImage = bmp.Clone( 0, 0, width, height, bmp.GetPixelFormat() );m_stImages.Add( p );return TRUE;}/***@method   SetControlImage*@brief    设置控件在指定状态下的图片*    *@param    CTRLTYPE ct   控件类型*@param    UINT uState   控件状态*@param    UINT uID      图片在资源中存放的ID*@param    LPCTSTR sTR   图片在资源中存放的资源标签*@param    HWND hwnd = NULL*@param    int nx = 0    图像范围--左上点的X坐标,默认为0*@param    int ny = 0    图像范围--左上点的Y坐标,默认为0*@param    int nWidth = 0    图像范围--宽度,默认为0,此时为图像的宽度*@param    int nHeight = 0   图像范围--高度,默认为0,此时为图像的高度*@return   BOOL*/BOOL SetControlImage( CTRLTYPE ct, UINT uState, UINT uID, LPCTSTR sTR, HWND hwnd = NULL, int nx = 0, int ny = 0, int nWidth = 0, int nHeight = 0 ){Image *pImage = ImageFromIDResourceEx( uID, sTR );if( NULL == pImage )return FALSE;return SetControlImage( ct, uState, pImage, hwnd, nx, ny, nWidth, nHeight );}/***@method   SubclassAllControls*@brief    将窗口上的所有控件进行关联*    *@param    void*@return   BOOL*/BOOL SubclassAllControls( void ){T* pT = static_cast< T* > ( this );return ::EnumChildWindows( pT->m_hWnd, EnumChildProc, ( LPARAM ) this );}/***@method   UnSubclassControl*@brief    根据控件类型对控件进行关联*    *@param    HWND hwnd  hwnd 控件句柄*@return   void*/void UnSubclassControl( HWND hwnd ){m_vtUnSubclass.push_back( hwnd );}/***@method   SubclassWindow*@brief    根据控件类型对控件进行关联*    *@param    HWND hwnd    控件句柄*@param    CTRLTYPE ct  控件类型*@return   BOOL*/virtual BOOL SubclassWindow( HWND hwnd, CTRLTYPE ct ){//判断该句柄是否在不邦定列表中for( size_t i = 0; i < m_vtUnSubclass.size(); i++ ){if( m_vtUnSubclass[i] == hwnd ){return TRUE;}}T *pT = static_cast< T * > ( this );ATL::CWindow cw( hwnd );if( cw.GetParent().m_hWnd != pT->m_hWnd )return TRUE;Image* pImg = NULL;switch( ct ){case CTRL_BUTTON:{CQsButton *pCtrl = new CQsButton;pCtrl->SubclassWindow( hwnd );m_ctlButtons.Add( pCtrl );break;}case CTRL_CHECKBOX:{CQsCheckBox *pCtrl = new CQsCheckBox;pCtrl->SubclassWindow( hwnd );m_ctlCheckBoxs.Add( pCtrl );break;}case CTRL_RADIOBOX:{CQsRadioBox *pCtrl = new CQsRadioBox;pCtrl->SubclassWindow( hwnd );m_ctlRadioBoxs.Add( pCtrl );break;}case CTRL_COMBOBOX:{CQsComboBox *pCtrl = new CQsComboBox;pCtrl->SubclassWindow( hwnd );m_ctlComboBoxs.Add( pCtrl );break;}case CTRL_EDIT:{CQsEdit *pCtrl = new CQsEdit;pCtrl->SubclassWindow( hwnd );m_ctlEdits.Add( pCtrl );break;}case CTRL_PROGRESS:{CQSProgressBar *pCtrl = new CQSProgressBar;pCtrl->SubclassWindow( hwnd );m_ctlProgs.Add( pCtrl );break;}case CTRL_STATIC:{CQsStatic *pCtrl = new CQsStatic;pCtrl->SubclassWindow( hwnd );m_ctlStaCtrls.Add( pCtrl );                break;}}return TRUE;}/***@method   EnumChildProc*@brief    控件遍历回调函数*    *@param    HWND hwnd*@param    LPARAM lParam*@return   BOOL CALLBACK*/static BOOL CALLBACK EnumChildProc( HWND hwnd, LPARAM lParam ){CQsSkinWindowUI< T, _bIsChildWnd > *pThis = ( CQsSkinWindowUI< T, _bIsChildWnd > * )lParam;CString strClass;GetClassName( hwnd, strClass.GetBuffer( 64 ), 64 );strClass.MakeUpper();if( strClass == _T("BUTTON") ){LONG lStyle = GetWindowLong( hwnd, GWL_STYLE );if( ( lStyle & BS_CHECKBOX ) == BS_CHECKBOX ){return pThis->SubclassWindow( hwnd, CTRL_CHECKBOX );}else if( ( lStyle & BS_AUTOCHECKBOX ) == BS_AUTOCHECKBOX ){return pThis->SubclassWindow( hwnd, CTRL_CHECKBOX );}else if( ( lStyle & BS_AUTORADIOBUTTON ) == BS_AUTORADIOBUTTON ){return pThis->SubclassWindow( hwnd, CTRL_RADIOBOX );}else if( ( lStyle & BS_GROUPBOX ) == BS_GROUPBOX ){}else if( ( lStyle & BS_RADIOBUTTON ) == BS_RADIOBUTTON ){return pThis->SubclassWindow( hwnd, CTRL_RADIOBOX );}else{return pThis->SubclassWindow( hwnd, CTRL_BUTTON );}}else if( strClass == _T( "COMBOBOX" ) ){return pThis->SubclassWindow( hwnd, CTRL_COMBOBOX );}else if( strClass == _T( "EDIT" ) ){return pThis->SubclassWindow( hwnd, CTRL_EDIT );}else if( strClass == _T( "MSCTLS_PROGRESS32" ) ){return pThis->SubclassWindow( hwnd, CTRL_PROGRESS );}else if( strClass == _T( "SCROLLBAR" ) ){return pThis->SubclassWindow( hwnd, CTRL_SCROLLBAR );}else if( strClass == _T( "SYSTABCONTROL32" ) ){return pThis->SubclassWindow( hwnd, CTRL_TABCTRL );}else if( strClass == _T( "STATIC" ) ){return pThis->SubclassWindow( hwnd, CTRL_STATIC );}return TRUE;}/***@method   ImageFromIDResourceEx*@brief    从资源中读取图像*    *@param    UINT nID      资源ID*@param    LPCTSTR sTR   资源标签名*@return   Image *   成功返回读取到的图片对象,否则返回NULL*/Image *ImageFromIDResourceEx(UINT nID, LPCTSTR sTR){Image *pImage;HINSTANCE hIns = _AtlBaseModule.GetResourceInstance();HRSRC hRsrc = ::FindResource (hIns,MAKEINTRESOURCE(nID),sTR); // typeif (!hRsrc)return NULL;// load resource into memoryDWORD len = SizeofResource(hIns, hRsrc);BYTE* lpRsrc = (BYTE*)LoadResource(hIns, hRsrc);if (!lpRsrc)return NULL;// Allocate global memory on which to create streamHGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len);BYTE* pmem = (BYTE*)GlobalLock(m_hMem);IStream* pstm;memcpy(pmem,lpRsrc,len);if(CreateStreamOnHGlobal(m_hMem,FALSE,&pstm) != S_OK)return NULL;// load from streampImage=Gdiplus::Image::FromStream(pstm);GlobalUnlock(m_hMem);pstm->Release();FreeResource(lpRsrc);GlobalFree(m_hMem);return pImage;}/***@method   SetCtrlText*@brief    设置控件显示文字*    *@param    int nCtrlID   控件ID*@param    LPCTSTR strText  要设置的文字*@return   BOOL*/BOOL SetCtrlText( int nCtrlID, LPCTSTR strText ){T *pT = static_cast< T* >( this );ATL::CWindow cw = pT->GetDlgItem( nCtrlID );if( !cw.IsWindow() )return FALSE;WTL::CString strClass;GetClassName( cw.m_hWnd, strClass.GetBuffer( 64 ), 64 );strClass.MakeUpper();if( strClass == _T( "COMBOBOX" ) ){DWORD dwStyle = cw.GetWindowLong( GWL_STYLE );if( ( dwStyle & CBS_DROPDOWNLIST ) ){WTL::CComboBox cb = cw.m_hWnd;for( int i = 0; i < cb.GetCount(); i++ ){WTL::CString strTemp;cb.GetLBText( i, strTemp );if( strTemp == strText ){cb.SetCurSel( i );break;}}}else{cw.SetWindowText( strText );CRect rc;cw.GetWindowRect( rc );pT->ScreenToClient( rc );pT->InvalidateRect( rc, TRUE );}}else{cw.SetWindowText( strText );CRect rc;cw.GetWindowRect( rc );pT->ScreenToClient( rc );pT->InvalidateRect( rc, TRUE );}return TRUE;}/***@method   SetCtrlText*@brief    设置控件显示文字*    *@param    int nCtrlID  控件ID*@param    int nTextID  要设置的文字在资源中的ID*@return   BOOL*/BOOL SetCtrlText( int nCtrlID, int nTextID ){CString strText;strText.LoadString( nTextID );return SetCtrlText( nCtrlID, strText );}/***@method   GetCtrlText*@brief    获得控件文字*    *@param    int nCtrlID   控件ID*@return   WTL::CString  控件文字*/CString GetCtrlText( int nCtrlID ){CString strText;T* pT = static_cast< T* >( this );ATL::CWindow cw = pT->GetDlgItem( nCtrlID );if( !cw.IsWindow() )return strText;int len = cw.GetWindowTextLength() + 1;cw.GetWindowText( strText.GetBuffer( len ), len );strText.ReleaseBuffer();return strText;}/***@method   SetCtrlFont*@brief    设置控件制定状态下文字字体*    *@param    int nCtrlID        控件ID*@param    UINT uState = 0    状态ID*@param    LPCTSTR lpszFaceName = _T("宋体")   字体*@param    int nHeight = 12               字体高度*@param    int fnWeight = FW_NORMAL     *@param    BYTE bItalic = FALSE           斜体字*@param    BYTE bUnderline = FALSE        下划线*@param    BYTE bStrikeOut = FALSE        删除线*@return   BOOL*/BOOL SetCtrlFont( int nCtrlID, UINT uState = 0, LPCTSTR lpszFaceName = _T( "宋体" ), int nHeight = 12, int fnWeight = FW_NORMAL, BYTE bItalic = FALSE, BYTE bUnderline = FALSE, BYTE bStrikeOut = FALSE ){T *pT = static_cast< T* >( this );HWND hwnd = pT->GetDlgItem( nCtrlID );CCtrlImageMgr *pcim = ( CCtrlImageMgr* )GetCustomObjectEx( hwnd );if( pcim ){pcim->SetStateFont( uState, lpszFaceName, nHeight, fnWeight, bItalic, bUnderline, bStrikeOut );return TRUE;}else{return FALSE;}}/***@method   SetFontColor*@brief    设置指定状态下字体的颜色*    *@param    HWND hwnd     控件句柄*@param    UINT uState   状态值*@param    COLORREF rgb  字体颜色*@return   BOOL*/BOOL SetFontColor( HWND hwnd, UINT uState, COLORREF rgb ){CCtrlImageMgr *pcim = ( CCtrlImageMgr* )GetCustomObjectEx( hwnd );if( pcim ){pcim->SetFontColor( uState, rgb );return TRUE;}else{return FALSE;}}/***@method   SetFontColor*@brief    设置指定状态下字体的颜色*    *@param    int nCtrlID     控件ID*@param    UINT uState     状态值*@param    COLORREF rgb    字体颜色*@return   BOOL*/BOOL SetFontColor( int nCtrlID, UINT uState, COLORREF rgb ){T *pT = static_cast< T* >( this );HWND hwnd = pT->GetDlgItem( nCtrlID );return SetFontColor( hwnd, uState, rgb );}void ReDraw( ){delete m_pBKImage;m_pBKImage = NULL;T *pT = static_cast< T* >( this );if ( pT->IsWindow()){pT->Invalidate( );HWND hChild = FindWindowEx( pT->m_hWnd, NULL, NULL, NULL );while ( NULL != hChild ){::SendMessage( hChild, WM_REDRAWBKGND, 0, 0 );hChild = FindWindowEx( pT->m_hWnd, hChild, NULL, NULL  );}}}
};

WTL 窗口自绘 (CQsSkinWindowUI)相关推荐

  1. UCGUI编程三:背景窗口重绘

    官方例程如下: #include "GUI.h" #include "WM.H" #include "FRAMEWIN.H"static v ...

  2. MFC-4简单的窗口重绘(非部分重绘)

    #include <afxwin.h> #include "resource.h" #include <afxtempl.h> //定义模板类的头文件cla ...

  3. qt 窗口自绘、鼠标响应拖动窗口

    2019独角兽企业重金招聘Python工程师标准>>> setWindowFlags(Qt::FramelessWindowHint|Qt::WindowSystemMenuHint ...

  4. 基础语法篇_4——插入符【文本插入符|图形插入符】、窗口重绘、路径、字符输入【设置字体|字幕变色】

  5. vc++图像保存,重绘

    新建mfc应用程序,单文档 增加绘图 分别增加命令响应 添加成员变量UINIT 图形可以运行,如何保存呢?(一个集合类,CPtArt) 用一个类的对象来保存一个图形的三个要素 所以插入一个新的类(通常 ...

  6. mfc笔记--摘录关于裁剪窗口区域的设置,WS_CLIPCHILDREN和WS_CLIPSIBLINGS的理解

    声明,原文来源:http://www.cnblogs.com/helloj2ee/archive/2009/05/29/1491822.html 1.求助MSDN 我的第一步当然是求助MSDN.在MS ...

  7. 双缓冲法解决重绘和闪屏问题

    重绘导致原因:UpdateData.Invalidate.InvalidateRect和UpdateWindow函数. 1. UpdateData重绘控件函数 UpdateData(TRUE)--刷新 ...

  8. VC的MFC中重绘函数的使用总结(整理)

    原文网址:http://www.cnblogs.com/x8023z/archive/2008/12/09/mfc33.html 在刷新窗口时经常要调用重绘函数 MFC提供了三个函数用于窗口重绘 In ...

  9. Windows窗口刷新机制详解

    1.Windows的窗口刷新管理 窗口句柄(HWND)都是由操作系统内核管理的,系统内部有一个z-order序列,记录着当前窗口从屏幕底部(假象的从屏幕到眼睛的方向),到屏幕最高层的一个窗口句柄的排序 ...

  10. Linux OpenGL 实践篇-2 创建一个窗口

    OpenGL 作为一个图形接口,并没有包含窗口的相关内容,但OpenGL使用必须依赖窗口,即必须在窗口中绘制.这就要求我们必须了解一种窗口系统,但不同的操作系统提供的创建窗口的API都不相同,如果我们 ...

最新文章

  1. 详解Paint的setPathEffect(PathEffect effect)
  2. Nature突破:首个比头发丝还细的机器人诞生了!可用针头注射入人体
  3. 光纤光缆市场需求高于预期 我国将迎来流量经济
  4. 201103阶段二linux gdb调试与ftp配置
  5. 在JSF 2中对定制验证器进行参数化
  6. linux内核epub,Android底层开发技术实战详解——内核、移植和驱动(第2版)[EPUB][MOBI][AZW3][42.33MB]...
  7. Flask笔记-使用flask-sqlacodegen自动生成model
  8. windows日志 重要事件 id_操作系统日志简述
  9. 别再瞎学 Python 了!
  10. 服务器4通道性能相当于多少人民币,有钱人的世界我们不懂,组装电脑花费百来万,跑分世界第四...
  11. linux文件描述符、软硬连接、输入输出重定向
  12. 深入理解javascript内部原理(2): 变量对象(Variable object)
  13. 炸了!!又一 VSCode 神器面世!
  14. apache日志文件 accesslog
  15. noip2019集训测试赛(二)
  16. java 中xsd文件在哪_在Java Eclipse项目中存储XSD文件的约定 - java
  17. 波特率和比特率的区分
  18. 数字图像处理技术的应用领域
  19. 如何用matlab对两个行向量作图_matlab 绘图与图形处理(二)
  20. Linux命令 - 覆盖 > 和 追加 >>

热门文章

  1. 独立站卖家如何借势营销
  2. 占领电商细分领域高地的湖南,在产业互联网时代该如何入海?
  3. mysql切片库_Database数据库切片模式
  4. gsoap linux中文乱码,gsoap中文乱码及内存清理等问题的解决方案
  5. 为什么《百家讲坛》上的中学教师收视率最高?
  6. 表扩展字段2种实施方案研究
  7. 兴趣专业测试软件,测试你的专业兴趣是什么
  8. Evolutionary algorithm (遗传算法)介绍
  9. wii模拟器linux版,Dolphin模拟器_Dolphin模拟器最新版下载[Wii模拟器]-下载之家
  10. 微信公众号接入自己的客服系统,自定义客服系统