MFC ListBox控件设置字体颜色
文章目录
- 描述
- 需要解决的问题
- 方案
- 设置 Item 颜色
- 鼠标双击事件
- 调用
- Static 控件的背景颜色设置
描述
最近的项目中需要用到 MFC 的列表控件,列表控件中需要动态插入产品不同的测试状态,产品的不同状态下的测试结果分为 PASS 和 FAIL 两种情况,这两种测试结果插入的状态字符串颜色分别呈现为绿色和红色。并且双击状态 Item,绘制出对应状态下的测试结果曲线。
需要解决的问题
- MFC 自带的 ListBox 控件无法设置 Item 中的颜色
- 捕获控件中的 Item 双击事件
方案
设置 Item 颜色
ListBox 无法直接设置字体颜色,因此需要自己实现对字体重绘功能。创建一个继承 ListBox 的类
CColorListBox,重写ListBox 中以下虚函数
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
以及重载函数
int AddString(LPCTSTR lpszItem, COLORREF itemColor);
实现如下:
void CColorListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{// Losing focus ?if (lpDrawItemStruct->itemID == -1){DrawFocusRect(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem);return;}CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);COLORREF clrOld;CString sText;// get color info from item dataCOLORREF clrNew = (COLORREF)(lpDrawItemStruct->itemData);// item selected ?if ((lpDrawItemStruct->itemState & ODS_SELECTED) &&(lpDrawItemStruct->itemAction & (ODA_SELECT | ODA_DRAWENTIRE))){CBrush brush(::GetSysColor(COLOR_HIGHLIGHT));pDC->FillRect(&lpDrawItemStruct->rcItem, &brush);}// item deselected ?if (!(lpDrawItemStruct->itemState & ODS_SELECTED) &&(lpDrawItemStruct->itemAction & ODA_SELECT)){CBrush brush(::GetSysColor(COLOR_WINDOW));pDC->FillRect(&lpDrawItemStruct->rcItem, &brush);}// item has focus ?if ((lpDrawItemStruct->itemAction & ODA_FOCUS) &&(lpDrawItemStruct->itemState & ODS_FOCUS)){pDC->DrawFocusRect(&lpDrawItemStruct->rcItem);}// lost focus ?if ((lpDrawItemStruct->itemAction & ODA_FOCUS) &&!(lpDrawItemStruct->itemState & ODS_FOCUS)){pDC->DrawFocusRect(&lpDrawItemStruct->rcItem);}// set the background mode to TRANSPARENTint nBkMode = pDC->SetBkMode(TRANSPARENT);if (lpDrawItemStruct->itemState & ODS_SELECTED)clrOld = pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));elseif (lpDrawItemStruct->itemState & ODS_DISABLED)clrOld = pDC->SetTextColor(::GetSysColor(COLOR_GRAYTEXT));elseclrOld = pDC->SetTextColor(clrNew);// get item textGetText(lpDrawItemStruct->itemID, sText);CRect rect = lpDrawItemStruct->rcItem;// text formatUINT nFormat = DT_LEFT | DT_SINGLELINE | DT_VCENTER;if (GetStyle() & LBS_USETABSTOPS)nFormat |= DT_EXPANDTABS;// draw the textpDC->DrawText(sText, -1, &rect, nFormat);// restore old valuespDC->SetTextColor(clrOld);pDC->SetBkMode(nBkMode);
}
void CColorListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{lpMeasureItemStruct->itemHeight = ::GetSystemMetrics(SM_CYMENUCHECK);
}
int CColorListBox::AddString(LPCTSTR lpszItem, COLORREF itemColor)
{// Add the string to the list boxint nIndex = CListBox::AddString(lpszItem);// save color dataif (nIndex >= 0)SetItemData(nIndex, itemColor);return nIndex;
}
鼠标双击事件
右击工程进入类向导,选择自定义的 CColorListBox 类,添加 WM_LBUTTONDBLCLK 消息响应函数。进入响应函数即可添加相应的响应代码。
void CColorListBox::OnLButtonDblClk(UINT nFlags, CPoint point)
{// TODO: 在此添加消息处理程序代码和/或调用默认值int nIndex = GetCurSel();//双击了哪个 Itemint nCount = GetCount();//得到总共的 Item 数if (nIndex >= 0 && nIndex < nCount){//回调函数,具体实现取决于给它注册的类m_dbClick(m_result[nIndex - 1]);}CListBox::OnLButtonDblClk(nFlags, point);
}
本项目采用回调的方式,即在创建列表时,给 CColorListBox 类注册一个双击事件的回调函数,如此可以在其他类中响应这一双击事件。当然,也可以在捕获到双击事件后,将消息post到指定窗口进行响应。
回调函数原型:
//回调函数:双击列表中的姿态,图表进行响应切换,参数为自定义的测试结果结构体
typedef void(CALLBACK DBCLICKBOXCALLBACK) (ANTRes res);
typedef DBCLICKBOXCALLBACK FAR *LPDBCLICKBOXCALLBACK;
回调函数注册
//m_dbClick为 LPDBCLICKBOXCALLBACK 类型的成员,参数为具体实现的函数指针,在创建列表时调用该函数进行回调注册
void CColorListBox::setDbClickFunc(LPDBCLICKBOXCALLBACK DbClick)
{m_dbClick = DbClick;
}
调用
- CColorListBox.h 头文件大致如下:
#include <vector>
using namespace std;//回调函数:双击列表中的姿态,图标进行响应切换,可以设置参数
typedef void(CALLBACK DBCLICKBOXCALLBACK) ();
typedef DBCLICKBOXCALLBACK FAR *LPDBCLICKBOXCALLBACK;class CColorListBox : public CListBox
{
public:CColorListBox();virtual ~CColorListBox();virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);//重载int AddString(LPCTSTR lpszItem, COLORREF itemColor);DECLARE_MESSAGE_MAP()afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
public:void setDbClickFunc(LPDBCLICKBOXCALLBACK DbClick);LPDBCLICKBOXCALLBACK m_dbClick;//双击回调函数
};
- CColorListBox.cpp 文件大致如下:
#include "CColorListBox.h"
CColorListBox::CColorListBox()
{
}
CColorListBox::~CColorListBox()
{
}
BEGIN_MESSAGE_MAP(CColorListBox, CListBox)ON_WM_LBUTTONDBLCLK()
END_MESSAGE_MAP()
void CColorListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{// Losing focus ?if (lpDrawItemStruct->itemID == -1){DrawFocusRect(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem);return;}CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);COLORREF clrOld;CString sText;// get color info from item dataCOLORREF clrNew = (COLORREF)(lpDrawItemStruct->itemData);// item selected ?if ((lpDrawItemStruct->itemState & ODS_SELECTED) &&(lpDrawItemStruct->itemAction & (ODA_SELECT | ODA_DRAWENTIRE))){CBrush brush(::GetSysColor(COLOR_HIGHLIGHT));pDC->FillRect(&lpDrawItemStruct->rcItem, &brush);}// item deselected ?if (!(lpDrawItemStruct->itemState & ODS_SELECTED) &&(lpDrawItemStruct->itemAction & ODA_SELECT)){CBrush brush(::GetSysColor(COLOR_WINDOW));pDC->FillRect(&lpDrawItemStruct->rcItem, &brush);}// item has focus ?if ((lpDrawItemStruct->itemAction & ODA_FOCUS) &&(lpDrawItemStruct->itemState & ODS_FOCUS)){pDC->DrawFocusRect(&lpDrawItemStruct->rcItem);}// lost focus ?if ((lpDrawItemStruct->itemAction & ODA_FOCUS) &&!(lpDrawItemStruct->itemState & ODS_FOCUS)){pDC->DrawFocusRect(&lpDrawItemStruct->rcItem);}// set the background mode to TRANSPARENTint nBkMode = pDC->SetBkMode(TRANSPARENT);if (lpDrawItemStruct->itemState & ODS_SELECTED)clrOld = pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));elseif (lpDrawItemStruct->itemState & ODS_DISABLED)clrOld = pDC->SetTextColor(::GetSysColor(COLOR_GRAYTEXT));elseclrOld = pDC->SetTextColor(clrNew);// get item textGetText(lpDrawItemStruct->itemID, sText);CRect rect = lpDrawItemStruct->rcItem;// text formatUINT nFormat = DT_LEFT | DT_SINGLELINE | DT_VCENTER;if (GetStyle() & LBS_USETABSTOPS)nFormat |= DT_EXPANDTABS;// draw the textpDC->DrawText(sText, -1, &rect, nFormat);// restore old valuespDC->SetTextColor(clrOld);pDC->SetBkMode(nBkMode);
}void CColorListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{lpMeasureItemStruct->itemHeight = ::GetSystemMetrics(SM_CYMENUCHECK);
}int CColorListBox::AddString(LPCTSTR lpszItem, COLORREF itemColor)
{// Add the string to the list boxint nIndex = CListBox::AddString(lpszItem);// save color dataif (nIndex >= 0)SetItemData(nIndex, itemColor);return nIndex;
}void CColorListBox::OnLButtonDblClk(UINT nFlags, CPoint point)
{// TODO: 在此添加消息处理程序代码和/或调用默认值int nIndex = GetCurSel();int nCount = GetCount();if (nIndex >= 0 && nIndex < nCount){m_dbClick();}CListBox::OnLButtonDblClk(nFlags, point);
}void CColorListBox::setDbClickFunc(LPDBCLICKBOXCALLBACK DbClick)
{m_dbClick = DbClick;
}
- 使用
//回调函数具体实现,必须和回调声明类型一致
static void WINAPI OnDbClickListItem()
{//此处实现双击事件具体需要做的事,如刷新图表
}//创建一个 CColorListBox 类指针,注意不用时释放
CColorListBox *listBox = new CColorListBox();
listBox->Create(LBS_HASSTRINGS | LBS_OWNERDRAWFIXED | WS_HSCROLL | LBS_NOTIFY | WS_CHILD | WS_VISIBLE | WS_TABSTOP, CRect(0, 0, 60, 60), this, IDC_LISTBOX + iAnt);
//为列表注册双击回调函数
listBox->setDbClickFunc(OnDbClickListItem);
//插入字符串,第二个参数为可选的颜色
listBox->AddString("全部姿态", RGB(255, 0, 0));//红色
- 效果
每种状态测试完将状态插入列表,并以颜色表示测试结果
双击右侧列表中的状态,刷新对应状态下的测试曲线
Static 控件的背景颜色设置
界面在显示测试结果时,经常采用 Static 控件,有时候需要让结果看起来很醒目,这时也需要设置控件的背景颜色以达到醒目效果。那么顺便简单说一下 Static 控件的背景颜色与字体的设置,效果如下:
- 实现
进入类向导,选择 Static 控件所在的类,添加 WM_CTLCOLOR 消息响应函数。在响应函数中根据控件 ID 设置控件背景颜色。
HBRUSH CDlgControl::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);// TODO: 在此更改 DC 的任何特性int n = pWnd->GetDlgCtrlID();if (n == IDC_STATIC_RESULT_TOTAL){pDC->SetBkColor(RGB(255, 0, 0));pDC->SetTextColor(RGB(0, 0, 0));hbr = CreateSolidBrush(RGB(255, 0, 0));}else if (n == IDC_STATIC_TIME){pDC->SetTextColor(RGB(0, 0, 0)); //设置字体颜色pDC->SetBkMode(TRANSPARENT); //设置字体背景为透明hbr = CreateSolidBrush(RGB(255, 255, 0));//控件背景色}// TODO: 如果默认的不是所需画笔,则返回另一个画笔return hbr;
}
设置 Static 控件字体与字号
CFont m_font;
m_font.CreatePointFont(580, _T("宋体"));
GetDlgItem(IDC_STATIC_RESULT_TOTAL)->SetFont(&m_font);
MFC ListBox控件设置字体颜色相关推荐
- Qml控件设置字体样式
Qml中的部分控件支持设置字体样式,如Control控件有font属性,可以用来设置字体样式(除了字体的颜色),按照正确的格式编写才可以运行正常. 正确编写格式如下: import QtQuick 2 ...
- 修改Static控件的字体颜色
首先在窗体上添加WM_CTLCOLOR消息,这时就会有一个OnCtlColor消息响应函数. 下面是我的OnCtlColor函数里的代码 HBRUSH CMyMailDlg::OnCtlColor(C ...
- WinForm下ListBox控件“设置DataSource属性后无法修改项集合”的问题解决方案
在做winform程序开发时,我用DataSource绑定了ListBox中的Item,但是当我进行一些添加.删除操作时就报了这个错"设置DataSource属性后无法修改项集合" ...
- PyQt5 技术篇-调用字体对话框(QFontDialog)获取字体,控件设置字体。
QFontDialog字体对话框 font, isok = QFontDialog.getFont() 返回值font是QFont字体对象,isok是True或False. 注:如果点了确定就是Tru ...
- windows edit控件设置背景颜色和文本颜色
在父窗口中响应:WM_CTLCOLOREDIT消息, { - HWND edit = GetDlgItem(ID_EDIT); //获取edit 的句柄 if(edit == (HWND)lParam ...
- MFC listbox 控件实时显示写入的内容
RedrawWindow函数.
- MFC 之 控件的颜色、字体、背景设置
实现WM_CTLCOLOR消息 HBRUSH CtestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) {HBRUSH hbr = CDia ...
- MFC中Listbox控件的简单使用
MFC中listbox控件是为了显示一系列的文本,每个文本占一行. Listbox控件可以设置属性为: LBS_CHILD :(默认)子窗口 LBS_Visible :(默认)可视 LBS_Mul ...
- VS2008 在IE8中 调试 ActiveX控件 无法进入断点的解决方法 设置VS2008和IE8 调试ATL MFC ActiveX控件
VS2008 在IE8中 调试 ActiveX控件 无法进入断点的解决方法 设置VS2008和IE8 调试ATL MFC ActiveX控件 参考文章: (1)VS2008 在IE8中 调试 Acti ...
最新文章
- SQLServer特殊字符/生僻字与varchar
- IOS开发 ARC forbids explicit message send of 'autorelease'错误解决办法
- java的classpath配置文件_Java Classpath及.properties配置文件
- mysql数据库驱动_JDBC 加载mysql数据库驱动
- iOS WebView的用法
- .net工程师至少要懂的东西
- (素材源代码) 猫猫学iOS 之UIDynamic重力、弹性碰撞吸附等现象牛逼Demo
- c/c++ 前置声明 -- typedef问题
- canvas 判断哪个元素被点击_监听 Canvas 内部元素点击事件的三种方法
- mysql清理死链接_对MySQL的死连接Sleep的进程的来源研究
- Extjs使用(最最基础)
- C++数据范围及字节对照表
- ai面试的优缺点_找工作时让AI给你面试,你愿意吗?
- matlab regstat函数,MATLAB如何使用binostat函数计算二项分布的期望和方差
- shiro 记住我 的实现
- 《自控力》第五章读书笔记
- 第五 python中格式化输入input()函数的使用
- git时光穿梭机总结
- OFDM峰均比抑制matlab,一种降低OFDM峰均比的解决方法
- mysql引擎与优化
热门文章
- ns-3网络仿真(简易脚本解析)
- 144显示器只有60_144Hz显示器为什么只跑60Hz?这几个原因很关键!
- 产品经理如何破壳成长?
- 分类Classification:决策树Decision Tree
- 计算机局域网组建课件,为什么《计算机局域网组建与维护案例教程沈大林课件》找不到?...
- CH340驱动(含各平台)
- 进销存管理怎么做?推荐一款免费进销存管理系统!
- Windows安装MySQL报错:由于找不到msvcr120.dll无法继续执行代码
- Acrel-2000电力监控系统在生物诊断试剂浙江迪安诊断的应用
- 数学笔记22——三角替换3(反向替换和配方)