WTL 窗口自绘 (CQsSkinWindowUI)
概述:
该类为主要是实现窗口的背景绘制和各种子控件的管理已经,通用控件的资源的加载等一些基础的工作,为我们使用
控件的核心。
代码实现如下:
#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)相关推荐
- UCGUI编程三:背景窗口重绘
官方例程如下: #include "GUI.h" #include "WM.H" #include "FRAMEWIN.H"static v ...
- MFC-4简单的窗口重绘(非部分重绘)
#include <afxwin.h> #include "resource.h" #include <afxtempl.h> //定义模板类的头文件cla ...
- qt 窗口自绘、鼠标响应拖动窗口
2019独角兽企业重金招聘Python工程师标准>>> setWindowFlags(Qt::FramelessWindowHint|Qt::WindowSystemMenuHint ...
- 基础语法篇_4——插入符【文本插入符|图形插入符】、窗口重绘、路径、字符输入【设置字体|字幕变色】
- vc++图像保存,重绘
新建mfc应用程序,单文档 增加绘图 分别增加命令响应 添加成员变量UINIT 图形可以运行,如何保存呢?(一个集合类,CPtArt) 用一个类的对象来保存一个图形的三个要素 所以插入一个新的类(通常 ...
- mfc笔记--摘录关于裁剪窗口区域的设置,WS_CLIPCHILDREN和WS_CLIPSIBLINGS的理解
声明,原文来源:http://www.cnblogs.com/helloj2ee/archive/2009/05/29/1491822.html 1.求助MSDN 我的第一步当然是求助MSDN.在MS ...
- 双缓冲法解决重绘和闪屏问题
重绘导致原因:UpdateData.Invalidate.InvalidateRect和UpdateWindow函数. 1. UpdateData重绘控件函数 UpdateData(TRUE)--刷新 ...
- VC的MFC中重绘函数的使用总结(整理)
原文网址:http://www.cnblogs.com/x8023z/archive/2008/12/09/mfc33.html 在刷新窗口时经常要调用重绘函数 MFC提供了三个函数用于窗口重绘 In ...
- Windows窗口刷新机制详解
1.Windows的窗口刷新管理 窗口句柄(HWND)都是由操作系统内核管理的,系统内部有一个z-order序列,记录着当前窗口从屏幕底部(假象的从屏幕到眼睛的方向),到屏幕最高层的一个窗口句柄的排序 ...
- Linux OpenGL 实践篇-2 创建一个窗口
OpenGL 作为一个图形接口,并没有包含窗口的相关内容,但OpenGL使用必须依赖窗口,即必须在窗口中绘制.这就要求我们必须了解一种窗口系统,但不同的操作系统提供的创建窗口的API都不相同,如果我们 ...
最新文章
- 详解Paint的setPathEffect(PathEffect effect)
- Nature突破:首个比头发丝还细的机器人诞生了!可用针头注射入人体
- 光纤光缆市场需求高于预期 我国将迎来流量经济
- 201103阶段二linux gdb调试与ftp配置
- 在JSF 2中对定制验证器进行参数化
- linux内核epub,Android底层开发技术实战详解——内核、移植和驱动(第2版)[EPUB][MOBI][AZW3][42.33MB]...
- Flask笔记-使用flask-sqlacodegen自动生成model
- windows日志 重要事件 id_操作系统日志简述
- 别再瞎学 Python 了!
- 服务器4通道性能相当于多少人民币,有钱人的世界我们不懂,组装电脑花费百来万,跑分世界第四...
- linux文件描述符、软硬连接、输入输出重定向
- 深入理解javascript内部原理(2): 变量对象(Variable object)
- 炸了!!又一 VSCode 神器面世!
- apache日志文件 accesslog
- noip2019集训测试赛(二)
- java 中xsd文件在哪_在Java Eclipse项目中存储XSD文件的约定 - java
- 波特率和比特率的区分
- 数字图像处理技术的应用领域
- 如何用matlab对两个行向量作图_matlab 绘图与图形处理(二)
- Linux命令 - 覆盖 > 和 追加 >>
热门文章
- 独立站卖家如何借势营销
- 占领电商细分领域高地的湖南,在产业互联网时代该如何入海?
- mysql切片库_Database数据库切片模式
- gsoap linux中文乱码,gsoap中文乱码及内存清理等问题的解决方案
- 为什么《百家讲坛》上的中学教师收视率最高?
- 表扩展字段2种实施方案研究
- 兴趣专业测试软件,测试你的专业兴趣是什么
- Evolutionary algorithm (遗传算法)介绍
- wii模拟器linux版,Dolphin模拟器_Dolphin模拟器最新版下载[Wii模拟器]-下载之家
- 微信公众号接入自己的客服系统,自定义客服系统