IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> WTL 自绘控件库 (CQsCheckBox) -> 正文阅读

[游戏开发]WTL 自绘控件库 (CQsCheckBox)

概述:

CQsCheckBox基础与 CButton,通过自绘来实现 实现check Box的效果,通过BST_CHECKED 属性来实现。

代码实现如下:

#pragma once;
#include "QsInclude.h"

#define     TXTMAX									512    //支持最大字体长度 
#define		QS_CHK_SYSYSTEM				0x00000001			//CheckBox系统样式
#define	    QS_CHK_OWNERDRAW        0x00000002          //CheckBox自绘样式,默认为自绘样式。

class CQsCheckBox:
	public CWindowImpl<CQsCheckBox, CButton>,
	public CImageMgrCtrlBase< CQsCheckBox>,
	public COwnerDraw< CQsCheckBox >
{
	typedef CWindowImpl< CQsCheckBox, CButton > theBaseClass;
	typedef CImageMgrCtrlBase< CQsCheckBox> theImageCtrlBaseClass;

	Image *m_pCurImage;                     //当前正在使用的图片
	Image *m_pLastImage;                    //发生状态改变前使用的图片
	volatile int m_nCheck;					   //是否被选中标志
	volatile bool m_bMouseDown;         //鼠标左键按下
	StringAlignment	m_eAlignment;		// CheckBox的方向
	Color m_enableColor;                       //可用状态时字体的颜色
	Color m_unenableColor;                  //不可用状态时字体的颜色。
	DWORD m_dwStyle;
	BOOL    m_bunifyfont;
public:
	BEGIN_MSG_MAP( CQsCheckBox )
		MESSAGE_HANDLER( WM_ERASEBKGND, OnEraseBKGnd )
		//MESSAGE_HANDLER( WM_LBUTTONDOWN, OnLButtonDown )
	   MESSAGE_HANDLER( WM_LBUTTONUP, OnLButtonUp )
		MESSAGE_HANDLER( WM_MOUSELEAVE, OnMouseLeave )
		MESSAGE_HANDLER( WM_MOUSEMOVE, OnMouseMove )
		MESSAGE_HANDLER( BM_SETCHECK, OnSetCheck )
		MESSAGE_HANDLER( BM_GETCHECK, OnGetCheck )
		//REFLECTED_COMMAND_CODE_HANDLER( BN_CLICKED, OnClicked )
		CHAIN_MSG_MAP_ALT( COwnerDraw< CQsCheckBox >, 1 )
		CHAIN_MSG_MAP( theImageCtrlBaseClass )
		DEFAULT_REFLECTION_HANDLER()
	END_MSG_MAP()

	/**
	*@method   CQsCheckBox
	*@brief     CQsCheckBox类构造函数
	*    
	*@return   
	*/
	CQsCheckBox():
		m_bMouseDown( false ),
		m_pCurImage( NULL ),
		m_pLastImage( NULL ),
		m_enableColor(255, 0, 0, 0),
		m_unenableColor(255, 128, 128, 128),
		m_nCheck( 0 )
	{
		m_uFirstPos = CONTROL_CHK_FIRST;
		m_uLastPos = CONTROL_CHK_LAST;
		SetAlignment( StringAlignmentNear );
		m_dwStyle = QS_CHK_OWNERDRAW;
		m_bunifyfont = FALSE;
	}

	/**
	*@method   ~CQsCheckBox
	*@brief       CQsCheckBox析构造函数
	*    
	*@return   
	*/virtual ~CQsCheckBox()
	{

	}

	/**
	*@method   Create
	*@brief    通过Create来创建窗口
	*    
	*@param    HWND hWndParent  parent window
	*@param    ATL::_U_RECT rect    window rect
	*@param    LPCTSTR szWindowName  the window name
	*@param    DWORD dwStyle   base window style
	*@param    DWORD dwExStyle
	*@param    ATL::_U_MENUorID MenuOrID
	*@param    LPVOID lpCreateParam
	*@return   非NULL success return TRUE, failed return NULL
	*/
	HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
		DWORD dwStyle = 0, DWORD dwExStyle = 0,
		ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
	{
		return theBaseClass::Create( hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
	}
	/**
	*@method   SetBtnUnifFont
	*@brief    设置CONTROL_CHK_CHECKED状态下统一使用一种字体
	*    
	*@return   void
	*/
	void SetBtnUnifFont(BOOL bunifyfont)
	{
		m_bunifyfont = bunifyfont;
	}
	/**
	*@method   SetAlignment
	*@brief    指定文本字符串相对于其布局矩形的对齐方式
	*    
	*@param    StringAlignment align  枚举
						Center 指定文本在布局矩形中居中对齐。  
						Far 指定文本远离布局矩形的原点位置对齐。在左到右布局中,远端位置是右。在右到左布局中,远端位置是左。  
						Near 指定文本靠近布局对齐。在左到右布局中,近端位置是左。在右到左布局中,近端位置是右 
	*@return   void
	*/void SetAlignment( StringAlignment align )
	{
		m_eAlignment = align;
	}

	/**
	*@method   GetAlignment
	*@brief        得到定文本字符串相对于其布局矩形的对齐方式
	*    
	*@param    void
	*@return   StringAlignment 枚举
						Center 指定文本在布局矩形中居中对齐。  
						Far 指定文本远离布局矩形的原点位置对齐。在左到右布局中,远端位置是右。在右到左布局中,远端位置是左。  
						Near 指定文本靠近布局对齐。在左到右布局中,近端位置是左。在右到左布局中,近端位置是右 
	*/
	StringAlignment GetAlignment( void )
	{
		return m_eAlignment;
	}
	 /**
	 *@method   SetQSWindowsStyle
	 *@brief        设置窗口的样式
	 *    
	 *@param    DWORD dwstyle dwstyle 窗口的样式
	 *@return   void
	 */void SetQSWindowsStyle(DWORD dwstyle)
	 {
			m_dwStyle = dwstyle;
	 }
	/**
	*@method   SubclassWindow
	*@brief        类对象关联
	*    
	*@param    HWND hWnd  对象句柄
	*@return   BOOL  成功返回TRUE,失败返回FALSE
	*/BOOL SubclassWindow( HWND hWnd )
	{
		//在此之前可能已经SetCheck
		m_nCheck = (int)::SendMessage( hWnd, BM_GETCHECK, 0, 0 );

		BOOL bRet = theBaseClass::SubclassWindow( hWnd );
		if(m_dwStyle&QS_CHK_OWNERDRAW)
		{
			UINT nBS = GetButtonStyle();
			SetButtonStyle( nBS | BS_OWNERDRAW );
		}
		return bRet;
	}
	/**
	*@method   GetState
	*@brief        得到CheckBox的现在的状态
	*    
	*@param    void
	*@return   UINT  现在CheckBox的状态
	*/UINT GetState( void )
	{
		LONG lStyle = GetWindowLong( GWL_STYLE );
		BOOL bIsDisabled = ( ( lStyle & WS_DISABLED ) != 0 ); //是否被禁止
		BOOL bIsChecked = ( GetCheck() == BST_CHECKED );
		UINT uStateFont = CONTROL_BTN_NORMAL;
		BOOL bIsFocused = ( ::GetFocus() == m_hWnd );

		//如果当前处于失效状态
		if( bIsDisabled )
		{
			if( bIsChecked)//如果当前被钩选
			{
				
				uStateFont = CONTROL_CHK_DISCHECKED;
			}
			else
			{
				uStateFont = CONTROL_CHK_DISUNCHECK;
			}
		}
		else
		{
			if( bIsChecked )//如果当前被钩选
			{
				if(bIsFocused)
				{
					uStateFont = CONTROL_CHK_FOUCS_CHECKED;
				}
				else
				{
					uStateFont = CONTROL_CHK_CHECKED;
				}
				
			}
			else
			{
				if(bIsFocused)
				{
					uStateFont = CONTROL_CHK_FOUCS_UNCHECK;
				}
				else
				{
					uStateFont = CONTROL_CHK_UNCHECK;
				}
			}
		}
		return uStateFont;
	}
	/**
	*@method   GetCheckStateFont
	*@brief        得到CheckBox的现在的状态
	*    
	*@param    void
	*@return   UINT  现在CheckBox的状态
	*/UINT GetCheckStateFont( void )
	{
		LONG lStyle = GetWindowLong( GWL_STYLE );
		BOOL bIsDisabled = ( ( lStyle & WS_DISABLED ) != 0 ); //是否被禁止
		BOOL bIsChecked = ( GetCheck() == BST_CHECKED );
		UINT uStateFont = CONTROL_CHK_CHECKED;
		BOOL bIsFocused = ( ::GetFocus() == m_hWnd );

		if(m_bunifyfont == TRUE)
		{
			return  uStateFont;
		}
		//如果当前处于失效状态
		if( bIsDisabled )
		{
			if( bIsChecked)//如果当前被钩选
			{
				
				uStateFont = CONTROL_CHK_DISCHECKED;
			}
			else
			{
				uStateFont = CONTROL_CHK_DISUNCHECK;
			}
		}
		else
		{
			if( bIsChecked )//如果当前被钩选
			{
				if(bIsFocused)
				{
					uStateFont = CONTROL_CHK_CHECKED;
				}
				else
				{
					uStateFont = CONTROL_CHK_CHECKED;
				}
				
			}
			else
			{
				if(bIsFocused)
				{
					uStateFont = CONTROL_CHK_UNCHECK;
				}
				else
				{
					uStateFont = CONTROL_CHK_UNCHECK;
				}
			}
		}
		return uStateFont;
	}
	/**
	*@method   GetTextFont
	*@brief        根据控件的状态获得控件当前使用的字体
	*    
	*@param    void
	*@return   HFONT  现在CheckBox的状态字体对象
	*/
	HFONT GetTextFont( void )
	{
		return GetStateFont( GetCheckStateFont() );
	}

	/**
	*@method   SetEnableColor
	*@brief        设置可用时字体的颜色
	*    
	*@param    Color enableColor  可用时字体的颜色
	*@return   void
	*/
	void SetEnableColor(Color enableColor)
	{
		m_enableColor =  enableColor;
	}

	/**
	*@method   SetUnEnableColor
	*@brief        设置不可用时字体的颜色
	*    
	*@param    Color unenableColor 不可用时字体的颜色
	*@return   void
	*/
	void SetUnEnableColor(Color unenableColor)
	{
		m_unenableColor = unenableColor;
	}
public:

	/**
	*@method   GetTextImageRect
	*@brief        得到字体和图片的显示区域
	*    
	*@param    RECT * lpTextRect  字体所在的区域
	*@param    RECT * lpImageRect  图片所在的区域
	*@return   void
	*/void GetTextImageRect( RECT* lpTextRect, RECT* lpImageRect )
	{
		CRect rtCtrl;
		GetClientRect( &rtCtrl );

		Image *pImg = GetCurrentImage(  );
		HFONT hFont = GetTextFont( );

		HDC hDC = ::GetDC( m_hWnd );
		Graphics graph( hDC );
		Gdiplus::Font fnt( hDC, hFont );
		
        RectF rtfText( 0, 0,(REAL)rtCtrl.Width(), (REAL)rtCtrl.Height() );

		RectF boundText( 0.0, 0.0, 0.0, 0.0 );
		TCHAR szTxt[TXTMAX] = {'0'};
		GetWindowText( szTxt, TXTMAX );
		StringFormat strfmtText;
		StringAlignment align = GetAlignment();
		strfmtText.SetAlignment( align );
	    strfmtText.SetLineAlignment( StringAlignmentNear );
		if( szTxt[0] != 0 )
		{
			graph.MeasureString( szTxt, (int)_tcslen(szTxt),&fnt, rtfText, &strfmtText,&boundText );
		}

		int nImgWidth = 0;
		int nImgHeight = 0;
		if ( pImg != NULL )
		{
			nImgWidth = pImg->GetWidth();
			nImgHeight = pImg->GetHeight();
		}
		if( StringAlignmentFar == GetAlignment() )
		{
			lpTextRect->left = (LONG)(rtCtrl.Width() - boundText.Width);
			lpTextRect->top = 0;
			lpTextRect->right = rtCtrl.Width();
			lpTextRect->bottom = rtCtrl.Height();
			int ytmp = rtCtrl.Height() - nImgHeight;
			lpImageRect->left = lpTextRect->left - nImgWidth - 5 ;
			lpImageRect->top = ( ytmp < 0 ? 0 : ytmp ) / 2;
			lpImageRect->right = lpImageRect->left + nImgWidth;
			lpImageRect->bottom = lpImageRect->top + nImgHeight;
		}
		else if( StringAlignmentCenter == GetAlignment() )
		{
			int nTotalWidth = (int)(nImgWidth + 10 + boundText.Width);
			int nLeft = ( rtCtrl.Width() - nTotalWidth ) / 2;
			nLeft = nLeft < 0 ? 0: nLeft;
			
			int ytmp = rtCtrl.Height() - nImgHeight;
			lpImageRect->left = nLeft;
			lpImageRect->top = ( ytmp < 0 ? 0 : ytmp ) / 2;
			lpImageRect->right = lpImageRect->left + nImgWidth;
			lpImageRect->bottom = lpImageRect->top + nImgHeight;
			lpTextRect->left = lpImageRect->right + 5;
			lpTextRect->top = 0;
			lpTextRect->right = (LONG)(lpTextRect->left + boundText.Width + 2);
			lpTextRect->bottom = rtCtrl.Height();
		}
		else
		{
			int ytmp = (int)(rtCtrl.Height() - nImgHeight);
			lpImageRect->left = 0;
			lpImageRect->top = ( ytmp < 0 ? 0 : ytmp ) / 2;
			lpImageRect->right = lpImageRect->left + nImgWidth;
			lpImageRect->bottom = lpImageRect->top + nImgHeight;
			lpTextRect->left = lpImageRect->right + 5;
			lpTextRect->top = 0;
			lpTextRect->right = (LONG)rtCtrl.right;//(LONG)(lpTextRect->left + boundText.Width+2);
			lpTextRect->bottom = rtCtrl.Height();
		}
		graph.ReleaseHDC( hDC );
		ReleaseDC( hDC );
		DeleteObject( hFont );
	}

	/**
	*@method   DrawItem
	*@brief       按钮重画函数
	*    
	*@param    LPDRAWITEMSTRUCT lpdis
	*@return   void
	*/void DrawItem( LPDRAWITEMSTRUCT lpdis )
	{
		if(m_dwStyle&QS_CHK_SYSYSTEM)
		{
			return ;
		}
		int width = lpdis->rcItem.right - lpdis->rcItem.left;
		int height = lpdis->rcItem.bottom - lpdis->rcItem.top;

		//创建内存作图对象
		WTL::CDC memDC;
		memDC.CreateCompatibleDC( lpdis->hDC );
		WTL::CBitmap memBitmap;
		memBitmap.CreateCompatibleBitmap( lpdis->hDC, width, height );
		HBITMAP hOldBmp = memDC.SelectBitmap( memBitmap );

		//获得控件背景
		memDC.SetBkMode( TRANSPARENT );
		::SendMessage( GetParent(), WM_DRAWBKGNDUI, ( WPARAM )memDC.m_hDC, ( LPARAM )lpdis->hwndItem );

		//绘制按钮
		DrawButton( memDC.m_hDC, lpdis->rcItem );

		//提交图像
		::BitBlt( lpdis->hDC, 0, 0, width, height, memDC.m_hDC, 0, 0, SRCCOPY );

		memDC.SelectBitmap( hOldBmp );
		memBitmap.DeleteObject();
		memDC.DeleteDC();
	}
protected:

	/**
	*@method   OnSetCheck
	*@brief    设置状态消息响应函数
	*    
	*@param    UINT uMsg   消息类型
	*@param    WPARAM wParam   详见MSDN
	*@param    LPARAM lParam   详见MSDN
	*@param    BOOL &
	*@return   LRESULT
	*/LRESULT OnSetCheck( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/ )
	{
		if(m_dwStyle&QS_CHK_SYSYSTEM)
		{
			return DefWindowProc(uMsg, wParam, lParam);
		}
		switch( wParam )
		{
		case BST_CHECKED:
		case BST_INDETERMINATE:
			m_nCheck = BST_CHECKED;
			break;
		default:
			m_nCheck = BST_UNCHECKED;
			break;
		}
		Invalidate();
		//OutputDebugStr( _T("OnSetCheck\r\n") );
		return 0;
	}

	/**
	*@method   OnGetCheck
	*@brief    读取状态消息响应函数
	*    
	*@param    UINT uMsg   消息类型
	*@param    WPARAM wParam  详见MSDN
	*@param    LPARAM lParam  详见MSDN
	*@param    BOOL &
	*@return   LRESULT   详见MSDN
	*/LRESULT OnGetCheck( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/ )
	{
		if(m_dwStyle&QS_CHK_SYSYSTEM)
		{
			return DefWindowProc(uMsg, wParam, lParam);
		}
		return m_nCheck;
	}

	/**
	*@method   OnLButtonDown
	*@brief    鼠标左键被按下消息响应函数
	*    
	*@param    UINT uMsg 消息类型
	*@param    WPARAM wParam 未被使用
	*@param    LPARAM lParam 详见MSDN
	*@param    BOOL& bHandled 未被使用
	*@return   LRESULT 详见MSDN
	*/
	LRESULT OnLButtonDown( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled )
	{
		//OutputDebugStr( _T("OnLButtonDown\r\n") );
		m_bMouseDown = true;
		//Invalidate();
		bHandled = FALSE;
		return 0;
	}

	/**
	*@method   OnMouseMove
	*@brief    鼠标进入消息响应函数
	*    
	*@param    UINT uMsg    消息类型
	*@param    WPARAM wParam    未被使用
	*@param    LPARAM lParam    详见MSDN
	*@param    BOOL& bHandled   未被使用
	*@return   LRESULT
	*/
	LRESULT OnMouseMove( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled )
	{
		if(m_dwStyle&QS_CHK_SYSYSTEM)
		{
			return TRUE;
		}
		if( m_pCurImage != GetImage( CONTROL_BTN_MOUSEIN ) )
		{
			//Invalidate();

			// 启动鼠标离开时间
			TRACKMOUSEEVENT tme;
			tme.cbSize  = sizeof(tme);
			tme.hwndTrack = m_hWnd;
			tme.dwFlags = TME_LEAVE;
			TrackMouseEvent(&tme);
		}

		bHandled = FALSE;
		return 0;
	}

	/**
	*@method   OnMouseLeave
	*@brief    鼠标离开消息响应函数
	*    
	*@param    UINT uMsg    消息类型
	*@param    WPARAM wParam    未被使用
	*@param    LPARAM lParam    详见MSDN
	*@param    BOOL& bHandled   未被使用
	*@return   LRESULT  详见MSDN
	*/
	LRESULT OnMouseLeave( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled )
	{
		if(m_dwStyle&QS_CHK_SYSYSTEM)
		{
			return TRUE;
		}
		//Invalidate();
		bHandled = FALSE;
		return 0;
	}

	/**
	*@method   OnLButtonUp
	*@brief    鼠标左键被放开消息响应函数
	*    
	*@param    UINT uMsg    消息类型
	*@param    WPARAM wParam    未被使用
	*@param    LPARAM lParam    详见MSDN
	*@param    BOOL& bHandled   未被使用
	*@return   LRESULT  详见MSDN
	*/
	LRESULT OnLButtonUp( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL/*& bHandled*/ )
	{
		//OutputDebugStr( _T("OnLButtonUp\r\n") );
		m_bMouseDown = false;
		SendMessage(WM_KILLFOCUS,0,0);
		 int nCtrlID = GetDlgCtrlID( );
		 SetCheck( !GetCheck() );
		 Invalidate();
		::SendMessage( GetParent(), WM_COMMAND, (WPARAM)nCtrlID,LPARAM(m_hWnd));
		
		//bHandled = FALSE;
		return 0;
	}

	/**
	*@method   OnEraseBKGnd
	*@brief    背景绘制消息函数
	*    
	*@param    UINT uMsg    消息类型
	*@param    WPARAM wParam    未被使用
	*@param    LPARAM lParam    详见MSDN
	*@param    BOOL& bHandled   未被使用
	*@return   LRESULT  详见MSDN
	*/
	LRESULT OnEraseBKGnd( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/ )
	{
		if(m_dwStyle&QS_CHK_SYSYSTEM)
		{
			return DefWindowProc(uMsg, wParam, lParam);
		}
		return 0;
	}

	/**
	*@method   OnClicked
	*@brief    按钮被按下消息响应函数
	*    
	*@param    WORD wNotifyCode 通知消息代码
	*@param    WORD wID 发送该消息的控件ID
	*@param    HWND hWndCtl 发送该消息的控件的句柄
	*@param    BOOL& bHandled   消息是否继续处理标志
	*@return   LRESULT
	*/
	LRESULT OnClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		if(m_dwStyle&QS_CHK_SYSYSTEM)
		{
			return 0;
		}
		//OutputDebugStr( _T("OnClicked\r\n") );
		SetCheck( !GetCheck() );

		Invalidate();
		return 0;
	}

private:
	/**
	*@method   GetButtonTextFormat
	*@brief    得到Button文字的对齐方式(用DrawText()输出时的格式)
	*    
	*@param    const LONG lStyle    控件风格	
	*@return   UINT 用DrawText()输出时的格式    button上的字必须是一行		
	*/
	UINT GetButtonTextFormat(const LONG lStyle)
	{
		UINT uFormat = DT_SINGLELINE;			//button上的字必须是一行
		
		//x方向
		if ( (lStyle & BS_CENTER)==BS_CENTER )//x方向,中
			uFormat |= DT_CENTER;
		else if ( (lStyle & BS_RIGHT)==BS_RIGHT )//x方向,右
			uFormat |= DT_RIGHT;
		else if ( (lStyle & BS_LEFT) == BS_LEFT )//x方向,左
			uFormat |= DT_LEFT;
		else//缺省,x中
			uFormat |= DT_LEFT;
		
		//y方向
		if ( (lStyle & BS_VCENTER ) == BS_VCENTER )//y,中
			uFormat |= DT_VCENTER;
		else if ( (lStyle & BS_TOP)==BS_TOP )//y方向,上
			uFormat |= DT_TOP;
		else if ( (lStyle & BS_BOTTOM)==BS_BOTTOM )//y方向,下
			uFormat |= DT_BOTTOM;
		else//缺省,y中
			uFormat |= DT_VCENTER;
		
		return uFormat;
	}

	/**
	*@method   GetCurrentImage
	*@brief    得到当前CheckBox使用的图片
	*    
	*@param    void
	*@return   Image*  当前图片的的对象指针
	*/Image* GetCurrentImage( void )
	{
		Image *pImg = NULL;
		UINT uStateFont = GetState();

		pImg = GetImage( uStateFont );

		//如果没有对应状态的图片
		if( pImg == NULL )
		{
			if( m_pCurImage != NULL )
			{
				pImg = m_pCurImage;
			}
			else
			{
				pImg = GetImage( CONTROL_BTN_NORMAL );
			}
		}
		return pImg;
	}

	/**
	*@method   DrawButton
	*@brief    绘制按钮函数
	*    
	*@param    HDC hDC   DC句柄
	*@param    RECT  itemRect 按钮位置
	*@return   void
	*/void DrawButton( HDC hDC, RECT /*itemRect*/ )
	{
		HDC hdc = hDC;

		SetBkMode( hdc, TRANSPARENT );
		
		LONG lStyle = GetWindowLong( GWL_STYLE );
		BOOL bIsDisabled = ( ( lStyle & WS_DISABLED ) != 0 ); //是否被禁止

		//判断鼠标是否在按钮上
		CRect rc;
		GetWindowRect( rc );
		
		POINT pt;
		GetCursorPos( &pt );

		Image *pImg = GetCurrentImage( );

		//如果当前图片相同
		if( m_pCurImage != pImg )
		{
			//保存上一个状态的图片
			if( m_pCurImage != NULL)
			{
				m_pLastImage = m_pCurImage;
			}
			else
			{
				m_pLastImage = pImg;
			}
			m_pCurImage = pImg;
		}

		CRect rtImage, rtText;
		GetTextImageRect( rtText, rtImage );

		if( m_pCurImage != NULL )
		{
			//绘制图片
			Graphics graph( hDC );
			graph.SetPageScale( 1.0 );
			graph.SetPageUnit( UnitPixel ); 
			graph.SetSmoothingMode( SmoothingModeNone );
			graph.DrawImage( m_pCurImage, rtImage.left, rtImage.top, rtImage.Width(), rtImage.Height() );
			graph.ReleaseHDC( hDC );
		}

		//绘制文字
		TCHAR szTxt[TXTMAX] = {0};
		GetWindowText( szTxt, TXTMAX );

		//获得控件当前使用的字体
		HFONT hFont = GetTextFont(  );

		WTL::CDCHandle dc( hDC );

		Graphics graph(dc.m_hDC);
		Gdiplus::Font fnt( dc.m_hDC, hFont );

		StringFormat strfmt;
		strfmt.SetAlignment(StringAlignmentCenter);
		strfmt.SetLineAlignment(StringAlignmentCenter);
		CRect rtf( rtText.left,rtText.top,rtText.right,rtText.Height()); 
		if( bIsDisabled )
		{
			//SolidBrush sdb(m_unenableColor);
			//graph.DrawString( szTxt,(int)_tcslen(szTxt), &fnt, rtf,&strfmt,  &sdb );	
			HFONT hOldFont = dc.SelectFont( hFont );
			dc.SetTextColor(m_unenableColor.ToCOLORREF());
			dc.DrawText( szTxt, -1, &rtf, GetButtonTextFormat( lStyle ) );
			dc.SelectFont( hOldFont );
			//SolidBrush sdb(m_unenableColor);
			//graph.DrawString( szTxt,(int)_tcslen(szTxt), &fnt, rtf,&strfmt,  &sdb );
		}
		else
		{
			HFONT hOldFont = dc.SelectFont( hFont );
			dc.SetTextColor(m_enableColor.ToCOLORREF());
			dc.DrawText( szTxt, -1, &rtf, GetButtonTextFormat( lStyle ) );
			dc.SelectFont( hOldFont );

			//SolidBrush sdb(m_enableColor); //可用状态时字体的颜色
			//graph.DrawString( szTxt,(int)_tcslen(szTxt),&fnt, rtf,&strfmt,&sdb );
		}
		graph.ReleaseHDC(dc.m_hDC);
		DeleteObject( hFont );
	}
};

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 18:15:32  更:2022-04-18 18:17:55 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 15:05:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码