如何设置CMFCToolBarComboBoxButton中编辑框的字体?
问题原因
CMFCToolBarComboBoxButton 的编辑控件并非始终存在——默认状态下,组合框折叠且未获得焦点时,工具栏会直接绘制选中项的文本,而非通过真正的 CEdit 控件显示。这时候调用 GetEditCtrl() 自然会返回 nullptr,因为编辑控件还没被创建出来。只有当组合框展开、或者获得焦点进入编辑状态时,CEdit 控件才会被实例化。
正确设置字体的方法
方法一:重载按钮类自定义绘制折叠状态文本
既然折叠状态的文本是工具栏直接绘制的,我们可以接管绘制逻辑,用指定字体渲染内容:
- 自定义继承自
CMFCToolBarComboBoxButton的类,比如CMyComboToolbarBtn - 重载
DrawItem方法,手动处理折叠状态的文本绘制:
void CMyComboToolbarBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { // 先让基类处理下拉列表部分的绘制 CMFCToolBarComboBoxButton::DrawItem(lpDrawItemStruct); // 判断当前是折叠状态且存在选中文本 if (!IsDropDownOpen()) { CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); CRect textRect = lpDrawItemStruct->rcItem; textRect.DeflateRect(3, 3); // 调整内边距避免贴边 // 切换到自定义字体并绘制文本 CFont* pOldFont = pDC->SelectObject(&m_customFont); CString selText; GetWindowText(selText); pDC->DrawText(selText, textRect, DT_LEFT | DT_VCENTER | DT_SINGLELINE); pDC->SelectObject(pOldFont); } }
- 在工具栏初始化时,替换原有的
CMFCToolBarComboBoxButton为自定义类实例。
方法二:在编辑控件创建后动态设置字体
编辑控件会在组合框获得焦点或展开时创建,我们可以捕获这个时机设置字体:
- 自定义按钮类,添加消息映射处理焦点事件:
BEGIN_MESSAGE_MAP(CMyComboToolbarBtn, CMFCToolBarComboBoxButton) ON_WM_SETFOCUS() END_MESSAGE_MAP() void CMyComboToolbarBtn::OnSetFocus(CWnd* pOldWnd) { CMFCToolBarComboBoxButton::OnSetFocus(pOldWnd); // 此时编辑控件已创建,获取指针并设置字体 CEdit* pEdit = GetEditCtrl(); if (pEdit) { pEdit->SetFont(&m_customFont); } }
- 也可以在按钮创建完成后尝试设置,重载
OnCreate:
int CMyComboToolbarBtn::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CMFCToolBarComboBoxButton::OnCreate(lpCreateStruct) == -1) return -1; CEdit* pEdit = GetEditCtrl(); if (pEdit) { pEdit->SetFont(&m_customFont); } return 0; }
注意事项
- 自定义字体对象
m_customFont需作为按钮类的成员变量,确保在按钮生命周期内有效,避免局部变量销毁导致绘制异常。 - 运行时动态修改字体时,更新
m_customFont后调用Invalidate()触发按钮重绘即可。
内容的提问来源于stack exchange,提问作者Friggle
相关产品推荐
相关产品推荐

