MFC的控件常常需要动态的改变文字颜色和背景底色,最好的做法是修改控件本身,增加设置颜色的接口函数直接调用,进行控件颜色的修改。CtlColor是反射式消息的响应函数,在控件内部自己实现重绘,这种方式是最好的。与反射式消息修改控件本身不同,还有另一种方式使用OnCtlColor在控件父窗口类中增加代码修改颜色,这两种方式都可以实现颜色的修改。这篇博客主要介绍反射式消息的方式。
0.给对话框添加一个Edit Control控件,并添加空间变量
1.从CEdit继承一个类CColorEdit
2.在CColorEdit类中添加反射消息
这里注意添加的消息是 ”’=WM_CTLCOLOR”’ 而不是 ”’WM_CTLCOLOR”’ (少了等于号),前者”’=WM_CTLCOLOR”’ 是反射式,响应函数是CtlColor,控件自己发送自己接受,后者是接收子控件发给自己的消息,响应函数是OnCtlColor,由于我们使用CColorEdit类自行绘制,所以我们选取反射式消息。
添加完毕,我们会发现代码中多了如下消息,接下来,我们就要修改代码了
3.添加修改颜色和字体的代码
3.1 添加头文件
#pragma once #include "afxwin.h" class CColorEdit : public CEdit { public: CColorEdit(); ~CColorEdit(); void SetForeColor(COLORREF color); void SetBkColor(COLORREF color); void SetTextFont(int FontHight, LPCTSTR FontName); private: COLORREF m_ForeColor; // text color COLORREF m_BackColor; // background color CBrush m_BkBrush; // background brush CFont* p_Font; public: DECLARE_MESSAGE_MAP() afx_msg HBRUSH CtlColor(CDC* /*pDC*/, UINT /*nCtlColor*/); };
3.2 添加函数
构造函数中添加初始化背景色和文字颜色,创建画刷。
在消息函数CtlColor中添加改变颜色的代码,注意返回值为背景色的画刷。
#include "stdafx.h" #include "CoEdit.h" CColorEdit::CColorEdit() { m_ForeColor = RGB(0, 0, 0); m_BackColor = RGB(240, 240, 240); m_BkBrush.CreateSolidBrush(m_BackColor); p_Font = NULL; } CColorEdit::~CColorEdit() { if (p_Font){ delete p_Font; } } BEGIN_MESSAGE_MAP(CColorEdit, CEdit) ON_WM_CTLCOLOR_REFLECT() END_MESSAGE_MAP() HBRUSH CColorEdit::CtlColor(CDC* pDC, UINT nCtlColor) { // TODO: Change any attributes of the DC here pDC->SetTextColor(m_ForeColor); pDC->SetBkColor(m_BackColor); m_BkBrush.DeleteObject(); m_BkBrush.CreateSolidBrush(m_BackColor); // TODO: Return a non-NULL brush if the parent's handler should not be called return (HBRUSH)m_BkBrush.GetSafeHandle(); } void CColorEdit::SetForeColor(COLORREF color){ m_ForeColor = color; } void CColorEdit::SetBkColor(COLORREF color){ m_BackColor = color; } void CColorEdit::SetTextFont(int FontHight, LPCTSTR FontName){ if (p_Font){ delete p_Font; } p_Font = new CFont; p_Font->CreatePointFont(FontHight, FontName); SetFont(p_Font); }
4.使用与测试
将原先添加的控件变量类型修改成我们刚刚创建的类型
class CColorEditerDlg : public CDialogEx { ... DECLARE_MESSAGE_MAP() public: //CEdit m_edit; CColorEdit m_edit; };
在使用时调用函数进行颜色设置,例如设置背景色,下面三行代码是重绘和刷新,可以将这三行代码集成到SetColor中,实现立即刷新显示
m_edit.SetBkColor(RGB(255, 96, 96)); m_edit.SetRedraw(TRUE); m_edit.Invalidate(); m_edit.UpdateWindow();
修改控件中的字体和颜色也是同理。
博主可不可以讲解一下使用OnCtlColor在控件父窗口类中增加代码修改颜色,我在MFC基于对话框的程序中使用了此函数,但是并没有实现
需要自己在类向导里添加,博客里已经写了