文章目录

  • 描述
  • 需要解决的问题
  • 方案
    • 设置 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控件设置字体颜色相关推荐

  1. Qml控件设置字体样式

    Qml中的部分控件支持设置字体样式,如Control控件有font属性,可以用来设置字体样式(除了字体的颜色),按照正确的格式编写才可以运行正常. 正确编写格式如下: import QtQuick 2 ...

  2. 修改Static控件的字体颜色

    首先在窗体上添加WM_CTLCOLOR消息,这时就会有一个OnCtlColor消息响应函数. 下面是我的OnCtlColor函数里的代码 HBRUSH CMyMailDlg::OnCtlColor(C ...

  3. WinForm下ListBox控件“设置DataSource属性后无法修改项集合”的问题解决方案

    在做winform程序开发时,我用DataSource绑定了ListBox中的Item,但是当我进行一些添加.删除操作时就报了这个错"设置DataSource属性后无法修改项集合" ...

  4. PyQt5 技术篇-调用字体对话框(QFontDialog)获取字体,控件设置字体。

    QFontDialog字体对话框 font, isok = QFontDialog.getFont() 返回值font是QFont字体对象,isok是True或False. 注:如果点了确定就是Tru ...

  5. windows edit控件设置背景颜色和文本颜色

    在父窗口中响应:WM_CTLCOLOREDIT消息, { - HWND edit = GetDlgItem(ID_EDIT); //获取edit 的句柄 if(edit == (HWND)lParam ...

  6. MFC listbox 控件实时显示写入的内容

    RedrawWindow函数.

  7. MFC 之 控件的颜色、字体、背景设置

    实现WM_CTLCOLOR消息 HBRUSH CtestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) {HBRUSH hbr = CDia ...

  8. MFC中Listbox控件的简单使用

    MFC中listbox控件是为了显示一系列的文本,每个文本占一行. Listbox控件可以设置属性为: LBS_CHILD   :(默认)子窗口 LBS_Visible :(默认)可视 LBS_Mul ...

  9. VS2008 在IE8中 调试 ActiveX控件 无法进入断点的解决方法 设置VS2008和IE8 调试ATL MFC ActiveX控件

    VS2008 在IE8中 调试 ActiveX控件 无法进入断点的解决方法 设置VS2008和IE8 调试ATL MFC ActiveX控件 参考文章: (1)VS2008 在IE8中 调试 Acti ...

最新文章

  1. SQLServer特殊字符/生僻字与varchar
  2. IOS开发 ARC forbids explicit message send of 'autorelease'错误解决办法
  3. java的classpath配置文件_Java Classpath及.properties配置文件
  4. mysql数据库驱动_JDBC 加载mysql数据库驱动
  5. iOS WebView的用法
  6. .net工程师至少要懂的东西
  7. (素材源代码) 猫猫学iOS 之UIDynamic重力、弹性碰撞吸附等现象牛逼Demo
  8. c/c++ 前置声明 -- typedef问题
  9. canvas 判断哪个元素被点击_监听 Canvas 内部元素点击事件的三种方法
  10. mysql清理死链接_对MySQL的死连接Sleep的进程的来源研究
  11. Extjs使用(最最基础)
  12. C++数据范围及字节对照表
  13. ai面试的优缺点_找工作时让AI给你面试,你愿意吗?
  14. matlab regstat函数,MATLAB如何使用binostat函数计算二项分布的期望和方差
  15. shiro 记住我 的实现
  16. 《自控力》第五章读书笔记
  17. 第五 python中格式化输入input()函数的使用
  18. git时光穿梭机总结
  19. OFDM峰均比抑制matlab,一种降低OFDM峰均比的解决方法
  20. mysql引擎与优化

热门文章

  1. ns-3网络仿真(简易脚本解析)
  2. 144显示器只有60_144Hz显示器为什么只跑60Hz?这几个原因很关键!
  3. 产品经理如何破壳成长?
  4. 分类Classification:决策树Decision Tree
  5. 计算机局域网组建课件,为什么《计算机局域网组建与维护案例教程沈大林课件》找不到?...
  6. CH340驱动(含各平台)
  7. 进销存管理怎么做?推荐一款免费进销存管理系统!
  8. Windows安装MySQL报错:由于找不到msvcr120.dll无法继续执行代码
  9. Acrel-2000电力监控系统在生物诊断试剂浙江迪安诊断的应用
  10. 数学笔记22——三角替换3(反向替换和配方)