WTL 自绘控件库 (CQsRadioBox)
概述:
CQsRadioBox基础与 CButton,通过自绘来实现 实现Radion Box的效果,通过BST_CHECKED 属性来实现。
代码实现如下:
#pragma once
#include "QsInclude.h"#define MAXRADIOXTXT 512#define QS_RAD_SYSYSTEM 0x00000001 //RadioBox系统样式
#define QS_RAD_OWNERDRAW 0x00000002 //RadioBox自绘样式,默认为自绘样式。class CQsRadioBox :public CWindowImpl<CQsRadioBox, CButton>,public CImageMgrCtrlBase< CQsRadioBox>,public COwnerDraw< CQsRadioBox >
{typedef CWindowImpl< CQsRadioBox, CButton > theBaseClass;typedef CImageMgrCtrlBase< CQsRadioBox > theImageCtrlBaseClass;Image *m_pCurImage; //当前正在使用的图片Image *m_pLastImage; //发生状态改变前使用的图片volatile int m_nCheck; //是否被选中标志volatile bool m_bMouseDown; //鼠标左键按下Color m_enableColor; //可用状态时字体的颜色Color m_unenableColor; //不可用状态时字体的颜色
public:BEGIN_MSG_MAP( CQsRadioBox )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< CQsRadioBox >, 1 )CHAIN_MSG_MAP( theImageCtrlBaseClass )DEFAULT_REFLECTION_HANDLER()END_MSG_MAP()/***@method CQsRadioBox*@brief CQsRadioBox类构造函数* *@return */CQsRadioBox():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_RDB_FIRST;m_uLastPos = CONTROL_RDB_LAST;SetQsStyle(QS_RAD_OWNERDRAW);}/***@method ~CQsRadioBox*@brief CQsRadioBox析构造函数* *@return */virtual ~CQsRadioBox(){}/***@method DrawItem*@brief 按钮重画函数* *@param LPDRAWITEMSTRUCT lpdis 详见MSN*@return void*/void DrawItem( LPDRAWITEMSTRUCT lpdis ){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();}/***@method Create*@brief 通过Create来创建窗口。* *@param HWND hWndParent parent window*@param ATL::_U_RECT rect = NULL create window rect*@param LPCTSTR szWindowName = NULL the window name*@param DWORD dwStyle = 0 base window style*@param DWORD dwExStyle = 0 extended window style*@param ATL::_U_MENUorID MenuOrID = 0U menu or ID*@param LPVOID lpCreateParam = NULL create param*@return HWND 非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 SubclassWindow*@brief 类对象关联* *@param HWND hWnd 对象句柄*@return BOOL*/BOOL SubclassWindow( HWND hWnd ){//在此之前可能已经SetCheckm_nCheck = (int)::SendMessage( hWnd, BM_GETCHECK, 0, 0 );BOOL bRet = theBaseClass::SubclassWindow( hWnd );if(m_dwQsStyle&QS_RAD_OWNERDRAW){UINT nBS = GetButtonStyle();SetButtonStyle( nBS | BS_OWNERDRAW );}return bRet;}/***@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;}
protected:/***@method OnSetCheck*@brief 设置状态消息响应函数* *@param UINT uMsg 消息类型*@param WPARAM wParam 未被使用*@param LPARAM lParam 详见MSDN*@param BOOL& bHandled 未被使用*@return LRESULT*/LRESULT OnSetCheck( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/ ){if(m_dwQsStyle&QS_RAD_SYSYSTEM){return DefWindowProc(uMsg, wParam, lParam); }//首先获得check标志m_nCheck = ( wParam != 0 );if( m_nCheck ){CSimpleArray< HWND > lst;lst.Add( m_hWnd );//获得父窗口句柄HWND hWndParent = GetParent().m_hWnd;//获得控件窗口句柄HWND hWnd = m_hWnd;while( hWnd ){//获得同组内控件的窗口句柄hWnd = ::GetNextDlgGroupItem( hWndParent, hWnd, 0 );//在list中查找这个句柄是否被查询到过int nPos = lst.Find( hWnd );if( nPos != -1 ){//如果找到了这个句柄,那就代表搜索到头了hWnd = NULL;}if( NULL != hWnd ){//如果没有搜索完一组,则把当前搜索的句柄添加到list中去(目的是为了不让同一控件被发送两次消息)lst.Add( hWnd );//对这个控件发送unChecked消息::PostMessage( hWnd, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0 );}}}Invalidate();return 0;}/***@method OnGetCheck*@brief 读取状态消息响应函数* *@param UINT uMsg 消息类型*@param WPARAM wParam 未被使用*@param LPARAM lParam 详见MSDN*@param BOOL& bHandled 未被使用*@return LRESULT*/LRESULT OnGetCheck( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/ ){if(m_dwQsStyle&QS_RAD_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*/LRESULT OnLButtonDown( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled ){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_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*/LRESULT OnMouseLeave( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled ){Invalidate();bHandled = FALSE;return 0;}/***@method OnLButtonUp*@brief 鼠标左键被放开消息响应函数* *@param UINT uMsg 消息类型*@param WPARAM wParam 未被使用*@param LPARAM lParam 详见MSDN*@param BOOL& bHandled 未被使用*@return LRESULT*/LRESULT OnLButtonUp( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled ){m_bMouseDown = false;Invalidate();bHandled = FALSE;return 0;}/***@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 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*/){SetCheck( BST_CHECKED );Invalidate();return 0;}private:/***@method GetButtonTextFormat*@brief 得到Button文字的对齐方式(用DrawText()输出时的格式)* *@param const LONG lStyle 控件风格*@return UINT 输出时的格式* 说 明: 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 DrawButton*@brief 绘制按钮函数* *@param HDC hDC 作图设备句柄*@param RECT itemRect 按钮位置*@return void*/void DrawButton( HDC hDC, RECT /*itemRect*/ ){HDC hdc = hDC;WTL::CDCHandle dc( hDC );SetBkMode( hdc, TRANSPARENT );LONG lStyle = GetWindowLong( GWL_STYLE );BOOL bIsDisabled = ( ( lStyle & WS_DISABLED ) != 0 ); //是否被禁止BOOL bIsChecked = ( GetCheck() == BST_CHECKED );//判断鼠标是否在按钮上CRect rc;GetWindowRect( rc );POINT pt;GetCursorPos( &pt );Image *pImg = NULL;UINT uStateFont = CONTROL_BTN_NORMAL;//如果当前处于失效状态if( bIsDisabled ){if( bIsChecked )//如果当前被选择{pImg = ( GetImage( CONTROL_RDB_DISCHECKED ) != NULL ? GetImage( CONTROL_RDB_DISCHECKED ) : GetImage ( CONTROL_RDB_CHECKED ) );uStateFont = CONTROL_RDB_DISCHECKED; }else{pImg = ( GetImage( CONTROL_RDB_DISUNCHECK ) != NULL ? GetImage( CONTROL_RDB_DISUNCHECK ) : GetImage( CONTROL_RDB_DISCHECKED ) );uStateFont = CONTROL_RDB_DISUNCHECK; //CONTROL_RDB_DISUNCHECK}}else{if( bIsChecked )//如果当前被选择{pImg = GetImage( CONTROL_RDB_CHECKED );uStateFont = CONTROL_RDB_CHECKED;}else{pImg = GetImage( CONTROL_RDB_UNCHECK );uStateFont = CONTROL_RDB_UNCHECK;}}//如果没有对应状态的图片if( pImg == NULL ){if( m_pCurImage != NULL ){pImg = m_pCurImage;}else{pImg = GetImage( CONTROL_BTN_NORMAL );uStateFont = CONTROL_BTN_NORMAL;}}//如果当前图片相同if( m_pCurImage != pImg ){//保存上一个状态的图片if( NULL != m_pCurImage){m_pLastImage = m_pCurImage;}else{m_pLastImage = pImg;}m_pCurImage = pImg;}//绘制图片Graphics graph( hDC );int titleStart = 0;if( m_pCurImage != NULL ){graph.SetPageScale( 1.0 );graph.SetPageUnit( UnitPixel ); graph.SetSmoothingMode( SmoothingModeNone );titleStart = m_pCurImage->GetWidth( );graph.DrawImage( m_pCurImage, 0, 0, titleStart, m_pCurImage->GetHeight() );}// 显示标题TCHAR tstrTitle[MAXRADIOXTXT] = _T("");GetWindowText( tstrTitle, MAXRADIOXTXT);CRect rtWnd;GetWindowRect( &rtWnd );ScreenToClient( &rtWnd );HFONT hFont = GetStateFont(uStateFont); //得到的Font要求销毁!Gdiplus::Font fontTitle(hDC,hFont);StringFormat format;UINT uStyle = GetButtonStyle();if ( BS_PUSHLIKE & uStyle ){CRect rtfTitle( 0, 0, rtWnd.Width(), rtWnd.Height() );format.SetAlignment(StringAlignmentCenter);format.SetLineAlignment(StringAlignmentCenter);if(!bIsDisabled) //失效状态{HFONT hOldFont = dc.SelectFont( hFont );dc.SetTextColor(m_enableColor.ToCOLORREF());dc.DrawText( tstrTitle, -1, &rtfTitle, GetButtonTextFormat( lStyle ) );dc.SelectFont( hOldFont );//SolidBrush sbTitle(m_enableColor);//graph.DrawString( tstrTitle,(int) _tcslen(tstrTitle), &fontTitle, rtfTitle, &format, &sbTitle );}else{HFONT hOldFont = dc.SelectFont( hFont );dc.SetTextColor(m_unenableColor.ToCOLORREF());dc.DrawText( tstrTitle, -1, &rtfTitle, GetButtonTextFormat( lStyle ) );dc.SelectFont( hOldFont );//SolidBrush sbTitle(m_unenableColor);//graph.DrawString( tstrTitle,(int) _tcslen(tstrTitle), &fontTitle, rtfTitle, &format, &sbTitle );}}else{ CRect rtfTitle( titleStart, 0, rtWnd.Width() - titleStart, rtWnd.Height() );format.SetAlignment( StringAlignmentNear );format.SetLineAlignment( StringAlignmentCenter );if(!bIsDisabled) //失效状态{HFONT hOldFont = dc.SelectFont( hFont );dc.SetTextColor(m_enableColor.ToCOLORREF());dc.DrawText( tstrTitle, -1, &rtfTitle, GetButtonTextFormat( lStyle ) );dc.SelectFont( hOldFont );// SolidBrush sbTitle(m_enableColor);// graph.DrawString( tstrTitle, (int)_tcslen(tstrTitle), &fontTitle, rtfTitle, &format, &sbTitle );}else{HFONT hOldFont = dc.SelectFont( hFont );dc.SetTextColor(m_unenableColor.ToCOLORREF());dc.DrawText( tstrTitle, -1, &rtfTitle, GetButtonTextFormat( lStyle ) );dc.SelectFont( hOldFont );//SolidBrush sbTitle(m_unenableColor);//graph.DrawString( tstrTitle, (int)_tcslen(tstrTitle), &fontTitle, rtfTitle, &format, &sbTitle );}}graph.ReleaseHDC( hDC );DeleteObject( hFont );}
};
WTL 自绘控件库 (CQsRadioBox)相关推荐
- WTL 自绘控件库 (CQsTabCtrl)
概述: CQsTabCtrl 继承与 CTabCtrl,通过自绘来背景的绘制,以及各种选中状态的的绘制,以及选中和非选中字体的颜色等一些属性. 代码实现如下: #pragma once; #inclu ...
- WTL 自绘控件库 (CQSProgressBar)
概述: CQSProgressBar 进度条,是显示进度控制.但是需要添加自绘属性. 代码实现如下: #pragma once; #pragma warning(disable:4995 4819)# ...
- winform checkbox要点击两次_开源C# Winform控件库SunnyUI强力推荐
本站(https://dotnet9.com)曾介绍过一款Winform开源控件库<HZHControls>,文章发布后不少朋友热情的咨询相关控件库信息,由此看来Winform在大家心中的 ...
- 开源C# Winform控件库《SunnyUI》强力推荐
本站(https://dotnet9.com)曾介绍过一款Winform开源控件库<HZHControls>,文章发布后不少朋友热情的咨询相关控件库信息,由此看来Winform在大家心中的 ...
- Github 开源:升讯威 Winform 开源控件库( Sheng.Winform.Controls)
Github 地址:https://github.com/iccb1013/Sheng.Winform.Controls 本控件库中的代码大约写于10年前(2007年左右),难免有不成熟与欠考虑之处, ...
- 如何在WPF中调用C#控件库(HexEdit)
1 编写一个Hex Edit控件,使用VS2010建立一个类控件库,分别增加两个类文件,一个命名为HexEdit.cs, 一个命名为TextEditControl.cs,具体内容如下所示: 1)Hex ...
- MFC自绘控件系列-按钮PNG贴图(GDI+)
常规的GDI自绘控件仅支持BMP图片,不支持png图片.png图片体积小,支持透明色,可以做圆角界面.自绘控件想要支持PNG图片,需要在MFC工程引入GDI+.需要注意的是MFC工程默认是不支持GDI ...
- UI控件库分享:DWZ(j-UI)、LigerUI、Linb
DWZ(j-UI): 在线演示地址:http://demo.dwzjs.com 在线文档:http://demo.dwzjs.com/doc/dwz-user-guide.pdf DWZ框架Ajax开 ...
- 虚拟桌面模拟查找点击自绘控件
// VDesktopClick.cpp : 定义控制台应用程序的入口点. //#include "stdafx.h" #include <string> #inclu ...
- [原创]基于Extjs的开源控件库 - http://extaspnet.codeplex.com/
ExtAspNet ExtAspNet - ExtJS based ASP.NET Controls with Full AJAX Support ExtAspNet是一组专业的Asp.n ...
最新文章
- 周期方波的傅里叶级数系数
- 修改initrd做miniLinux
- [福大软工] W班 总成绩排行榜
- Mac查看本机ip地址
- 收藏 | 可能是最详尽的PyTorch动态图解析
- Android AES加密算法及事实上现
- java四种修饰符_java中的四种修饰符
- ueditor样式过滤问题
- Android 系统服务列表
- mysql 字符串搜_Mysql搜索字符串
- MATLAB绘制散点图
- VS2015如何添加头文件
- http的响应码200,404,302,500表示的含义分别是?
- 如何建立个人网站(免费创建个人网站制作流程步骤)
- 游戏建模中游戏人物设计要点是什么?
- 微信配置JS接口安全域名-Nginx配置 文件的配置
- 如何利用Excel批量下载网页图片?
- 华为手机下拉菜单变大_华为手机下拉菜单变少了 华为下拉通知栏变白色
- 火车头采集翻页内容_八爪鱼采集器 循环翻页只翻3、5页就提示采集结束
- 计算机静音图标无法更改怎么办,电脑桌面出现静音图标,是桌面上,不是右下角,怎么处理...
热门文章
- aws服务器如何修改远程密码,谷歌云、亚马逊 AWS 设置 root 密码并开启 SSH 登录...
- 猜拳php代码,微信猜拳游戏源码
- angular ng-show中表达式的写法
- openBSD安装桌面
- 计算机英语写作题范文,2018年6月英语四级考试写作范文:人与电脑
- 详解 物理学四大神兽————拉普拉斯兽
- conda install pytorch torchvision torchaudio cudatoolkit=11.6 -c pytorch -c conda-forge遇到的报错
- 【操作系统】第二章--进程的描述与控制--深入与解释(1)
- HTTP hijack
- 目前最新全国行政区域JSON数据截止2015年9月30日