WM_CTLCOLOR消息重载
转载自: wangyao1052 的WM_CTLCOLOR消息
参考文章:白乔原创:VC之美化界面篇
在每个控件开始绘制之前,都会向其父窗口发送WM_CTLCOLOR
通告消息,在该消息的处理函数中,可以设置控件显示文本的前景色、背景色以及字体。该消息处理函数还要求返回一个画刷的句柄,用于在控件具体的绘制之前擦除其客户区。
WM_CTLCOLOR
映射消息处理函数为afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)。
常用代码:
pDC->SetTextColor(RGB(255, 0, 0)); //设置文本前景色
pDC->SetBkColor(RGB(255, 255, 255)); //设置文本背景色
pDC->SetBkMode(TRANSPARENT); //TRANSPARENT或OPAQUE
pDC->SelectObject(...)
简单示例如下:
//
//m_font1与m_font2为CTestDlg的成员,类型为CFont
//
BOOL CTestDlg::OnInitDialog()
{ ...... // TODO: Add extra initialization here m_font1.CreatePointFont(120, TEXT("Impact")); m_font2.CreatePointFont(120, TEXT("Arial")); ......
} HBRUSH CTestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{ HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); // TODO: Change any attributes of the DC here if (nCtlColor == CTLCOLOR_STATIC) { switch (pWnd->GetDlgCtrlID()) { case IDC_STATIC_1: pDC->SetTextColor(RGB(255, 0, 0)); pDC->SetBkColor(RGB(255, 255, 255)); pDC->SetBkMode(TRANSPARENT); pDC->SelectObject(&m_font1); return (HBRUSH)::GetStockObject(BLACK_BRUSH); break; case IDC_STATIC_2: pDC->SetTextColor(RGB(255, 255, 0)); pDC->SetBkColor(RGB(255, 255, 255)); pDC->SelectObject(&m_font2); return (HBRUSH)::GetStockObject(BLACK_BRUSH); break; default: break; } } // TODO: Return a different brush if the default is not desired return hbr;
}
说明一
OnCtlColor
中的nCtlColor
可为:
CTLCOLOR_BTN //Button controlCTLCOLOR_DLG //Dialog boxCTLCOLOR_EDIT //Edit controlCTLCOLOR_LISTBOX //List-box controlCTLCOLOR_MSGBOX //Message boxCTLCOLOR_SCROLLBAR //Scroll-bar controlCTLCOLOR_STATIC //Static control
可见,WM_CTLCOLOR
可作用于按钮控件CButton
、编辑框控件CEdit
、ListBox
控件、Static
控件、滚动条控件,也可作用于对话框本身。
注意:前面讲WM_CTLCOLOR
为通告消息,也即是子控件发送给父窗口的,但对于对话框本身,它能收到nCtlColor
为CTLCOLOR_DLG
的WM_CTLCOLOR
消息,这是自身发给自身的,显然,这时不是通告消息。
示例:
HBRUSH CTestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{ HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); // TODO: Change any attributes of the DC here if (nCtlColor == CTLCOLOR_DLG) return (HBRUSH)::GetStockObject(BLACK_BRUSH); else pDC->SetTextColor(RGB(255, 0, 0)); // TODO: Return a different brush if the default is not desired return hbr;
}
说明2
OnCtlColor
消息里面的处理对PushButton
是不起作用的,由说明一中的示例效果也可以看出,而对CheckBox
和RadioButton
是OK的。附上CSDN给出的解释:
Buttons with the BS_PUSHBUTTON
, BS_DEFPUSHBUTTON
,or BS_PUSHLIKE
styles do not use the returned brush. Buttons with these styles are always drawn with the default system colors. Drawing push buttons requires several different brushes-face, highlight, and shadow-but the WM_CTLCOLORBTN
message allows only one brush to be returned. To provide a custom appearance for push buttons, use an owner-drawn button.
所以,对PushButton
只能将其设置为owner-drawn button
,然后响应控件通告消息WM_DRAWITEM
来处理,该消息的响应函数原型为afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
。
说明三:对ComboBox控件的应用
ComboBox
控件包含一个EditBox
,当单击展开的时候,会出现一个ListBox
列出所有的项目,注意,这时ListBox
控件的父窗口不是这个ComboBox
,而是ComboBox
的父窗口。
所以,如果要在代码中设置某个ComboBox
所显示文字的字体颜色为红色(EditBox
以及下拉ListBox
中的文字),假设该ComboBox
的ID为IDC_COMBO
,则使用如下代码将无任何作用。
if (pWnd->GetDlgCtrlID() == IDC_COMBO)
{ pDC->SetTextColor(RGB(255, 0, 0));
}
EditBox以及下拉ListBox中的文字颜色均没有改变。
以下对话框中有两个ComboBox控件m_combo1,m_combo2。现要使m_combo1中显示的文字颜色为红色,而m_combo2为默认。代码如下
HBRUSH CTestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{ HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); // TODO: Change any attributes of the DC here //对m_combo1的EditBox(该EditBox的父窗口为m_combo1) if (nCtlColor == CTLCOLOR_EDIT && pWnd->GetParent()->GetDlgCtrlID() == m_combo1.GetDlgCtrlID()) { pDC->SetTextColor(RGB(255, 0, 0)); } //对m_combo1下拉的ListBox if (nCtlColor == CTLCOLOR_LISTBOX && m_combo1.GetParent()->GetDlgCtrlID() == pWnd->GetParent()->GetDlgCtrlID()) { //获取ListBox和m_combo1的屏幕坐标范围 RECT rectListBox; RECT rectComboBox; pWnd->GetWindowRect(&rectListBox); m_combo1.GetWindowRect(&rectComboBox); //如果该ListBox刚好在m_combo1的下面,则是单击m_combo1产生的下拉ListBox if (rectListBox.left == rectComboBox.left && rectListBox.top == rectComboBox.bottom) { pDC->SetTextColor(RGB(255, 0, 0)); } } // TODO: Return a different brush if the default is not desired return hbr;
}
更简单的办法是:利用向导新增MFC类CMyComboBox : CComboBox
,再增加WM_CTLCOLOR
消息的响应函数。(注意:ComboBox
下的EditBox
和ListBox
均会向ComboBox
窗口发送WM_CTLCOLOR
消息,如果在ComboBox
对应的消息映射表没有找到对应的处理函数,再向CComboBox
的父窗口发送WM_CTLCOLOR
消息,具体可参考文章WM_NOTIFY
消息流程实例分析)
BEGIN_MESSAGE_MAP(CMyComboBox, CComboBox) ON_WM_CTLCOLOR()
END_MESSAGE_MAP() HBRUSH CMyComboBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{ HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor); // TODO: Change any attributes of the DC here pDC->SetTextColor(RGB(255, 255, 0)); // TODO: Return a different brush if the default is not desired return hbr;
}
pDC->SetTextColor(RGB(255, 255, 0));
一句代码就可以实现上面的功能。
说明四
WM_CTLCOLOR
为通告消息,所以也可以在反射消息中处理。
ON_WM_CTLCOLOR_REFLECT()
WM_CTLCOLOR消息重载相关推荐
- WM_CTLCOLOR消息
文章参考地址:http://blog.csdn.net/hisinwang/article/details/8070393 在每个控件开始绘制之前,都会向其父窗口发送WM_CTLCOLOR通告消息,在 ...
- vc picture控件载入背景图,随控件大小改变
在mfc里,想要在Picture控件中载入一张图片有两种方法:静态的和动态的.静态的方法就是图片先载入资源(.rc)文件中,拥有一个唯一的ID:动态的方法就是制定图片的路径名即可. 当然这样的方法网上 ...
- vc picture控件的分类总结(转载)
VC PICTURE控件的使用,如何加载背景图片 vc picture控件的分类总结: (一) 非动态显示图片(即图片先通过资源管理器载入,有一个固定ID) (二) 动态载入图片(即只需要在程序中指定 ...
- Android多点触控详解
本文转载自GcsSloop的 安卓自定义View进阶-多点触控详解 的文章 Android 多点触控详解,在前面的几篇文章中我们大致了解了 Android 中的事件处理流程和一些简单的处理方案,本次带 ...
- 基于对话框的MFC程序加载位图为背景图案
from: http://rwsk.snnu.edu.cn/?uid-156-action-viewspace-itemid-240 先载入一张图片 ,ID 为 IDB_BITMAP2 TestDlg ...
- MFC中显示图片(静态、动态)(转)
(一) 非动态显示图片(即图片先通过资源管理器载入,有一个固定ID) (二) 动态载入图片(即只需要在程序中指定图片的路径即可载入) 为方便说明,我们已经建好一个基于对话框的工程,名为Ttest. 对 ...
- MFC对话框中显示图片的四种方法
先分类如下: (一) 非动态显示图片(即图片先通过资源管理器载入,有一个固定ID) (二) 动态载入图片(即只需要在程序中指定图片的路径即可载入) 为方便说明,我们已经建好一个基于对话框的工程,名为T ...
- 在对话框显示图片的多种方法(上)
我们先从简单的开始吧.先分一个类: (一) 非动态显示图片(即图片先通过资源管理器载入,有一个固定ID) (二) 动态载入图片(即只需要在程序中指定图片的路径即可载入) 为方便说明,我们已经建好一个基 ...
- 在对话框显示图片的多种方法
我们先从简单的开始吧.先分一个类: (一) 非动态显示图片(即图片先通过资源管理器载入,有一个固定ID) (二) 动态载入图片(即只需要在程序中指定图片的路径即可载入) 为方便说明,我们已经建好一个基 ...
最新文章
- 第二话 最最最简单的计算机
- tensorflow包_在Keras和Tensorflow中使用深度卷积网络生成Meme(表情包)文本
- Vijos p1097 合并果子
- Mvp快速搭建商城购物车模块
- Spring Data JPA 从入门到精通~@Procedure 储存过程的查询方法
- 全新的 Fragment 通信方式
- 文石服务器维护,文石BOOX OS 2.0新系统即将上线,联合京东读书推出BOOX书城
- bash: 未预期的符号 `( 附近有语法错误_安规群中关于泄漏电流测试、接地符号等相关的6个问题,快来围观大神的回答吧!...
- [转载] scala
- 在网站中使用Cookie的简单例子
- 不能因技术后天的死 而迷茫了今天的“学” 生
- Objective-c编程语言(一):The Objective-C Programming Language:Introduction
- java持久层用文件_JAVA中用三种方法将字符串持久化到文件中
- 配置 Hadoop 时遇到的一些问题
- L1-032 Left-pad (20 分)—团体程序设计天梯赛
- ubuntu之路——day7.1 衡量模型好坏的因素偏差和方差biasvariance 以及在深度学习中的模型优化思路...
- Android Java开发实例项目+游戏视频教程免费下载咯。。
- 烘焙软件Knald介绍
- Js 中null 和underfined的区别
- Pdf 插入图片 | 指定位置插入图片 不改变原格式 直接操作
热门文章
- Win10 安装 UG10.0 UG8.5教程 --(及安装错误问题解决)--NX 8.5 NX 10.0 安装教程
- 2022-2027年中国国际货物运输行业市场深度分析及投资战略规划报告
- Can't locate Time/HiRes.pm in @INC错误的处理方法 perl安装不全
- 微信开放平台开发(一)
- 第三章 C语言运算符,表达式,序列点,类型转换
- 电脑桌面的文件突然不见了怎么办
- 教育培训机构怎么做推广?有什么好建议?
- matlab 双馈,基于Matlab的双馈调速系统研究
- 浏览器垃圾与回收机制
- 生成xslx文件,写入并读取