[WTL/ATL]_[初级]_[如何设置CEdit的文本框背景色和文字颜色]
Posted infoworld
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[WTL/ATL]_[初级]_[如何设置CEdit的文本框背景色和文字颜色]相关的知识,希望对你有一定的参考价值。
场景
- 在开发
WTL
或MFC
界面程序时,经常会使用CEdit
文本框,但是有时候为了和父窗口的颜色对应上,文本框里的背景色也需要和父窗口一样。CEdit
或者说Edit
的Win32
控件[4]并没有相应的方法或者消息WM_XX
来设置背景色的值,怎么办?
说明
- 看
Edit
控件的官方说明, 当不是禁用或者只读时使用WM_CTLCOLOREDIT
消息来改变控件的文本和背景色(当禁用和只读时使用WM_CTLCOLORSTATIC
消息来处理)。父窗口通过指定设备的上下文句柄HDC
来改变颜色。
An edit control that is not read-only or disabled sends the WM_CTLCOLOREDIT message to its parent window when the control is about to be drawn. By responding to this message, the parent window can use the specified device context handle to set the text and background colors of the edit control.
-
相关改变颜色的函数就是以下两个函数,当然还需要返回一个
HBRUSH
作为窗口背景色.SetBkColor
只是文字的背景色,它的区域是比CEdit
的窗口区域小的。LRESULT CView::OnCtlColor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) HWND hWnd = (HWND)lParam; HDC hdc = (HDC)wParam; //1. 只改变多行`Edit`的文本框窗口颜色和文本背景底色. if(hWnd == *editMultiLine_) CDCHandle dc(hdc); dc.SetBkColor(RGB(255,0,0)); dc.SetTextColor(RGB(0,0,255)); return (LRESULT)AtlGetStockBrush(WHITE_BRUSH); //2. 其他`Edit`的消息不处理 bHandled = FALSE; return 0;
-
在消息映射宏里添加对
WM_CTLCOLOREDIT
和WM_CTLCOLORSTATIC
消息的捕抓.BEGIN_MSG_MAP_EX(CView) MSG_WM_CREATE(onCreate) MESSAGE_HANDLER(WM_PAINT, onPaint) MESSAGE_HANDLER(WM_CTLCOLOREDIT, OnCtlColor) MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnCtlColor) REFLECT_NOTIFICATIONS() END_MSG_MAP()
-
如果是自定义的
CEdit
子控件,可以通过转发的WM_CTLCOLOREDIT
消息来处理这个背景色,并提供setBkgColor()
方法即可.
class BASEdit : public CWindowImpl<BASEdit, CEdit>
public:
BASEdit();
~BASEdit();
BEGIN_MSG_MAP_EX(BASEdit)
MSG_OCM_CTLCOLOREDIT(OnReflectedCtlColorEdit)
MSG_WM_KEYDOWN(OnKeyDown)
DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
void setBkgColor(COLORREF color);
void setTextColor(COLORREF color);
...
;
#define OCM_CTLCOLOREDIT (OCM__BASE + WM_CTLCOLOREDIT)
例子
- 一下例子使用和原
CEdit
和子类的BASEdit
达到修改文本框背景色和文字颜色的效果。
View.h
// View.h : interface of the CView class
//
/
#ifndef VIEW_H
#define VIEW_H
class BASEdit;
typedef enum ViewWindowId1
kViewWindowEditId = WM_USER + 1000,
kViewWindowEditMultiLineId
ViewWindowId;
class CView : public CWindowImpl<CView>
public:
DECLARE_WND_CLASS(NULL)
BOOL PreTranslateMessage(MSG* pMsg);
BEGIN_MSG_MAP_EX(CView)
MSG_WM_CREATE(onCreate)
MESSAGE_HANDLER(WM_PAINT, onPaint)
MESSAGE_HANDLER(WM_CTLCOLOREDIT, OnCtlColor)
MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnCtlColor)
REFLECT_NOTIFICATIONS()
END_MSG_MAP()
// Handler prototypes (uncomment arguments if needed):
// LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
// LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
// LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
protected:
LRESULT OnCtlColor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT onPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
int onCreate(LPCREATESTRUCT lpCreateStruct);
void onEnter();
private:
BASEdit* edit_;
CEdit* editMultiLine_;
;
#endif
View.cpp
// View.cpp : implementation of the CView class
//
/
#include "stdafx.h"
#include "resource.h"
#include "View.h"
#include "base/bas_edit.h"
#include <functional>
static LRESULT CALLBACK Edit_Prc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
if (msg == WM_CHAR && wParam == 1)
SendMessage(hwnd, EM_SETSEL, 0, -1);
return 1;
auto oldProc = (WNDPROC)GetWindowLong(hwnd, GWL_USERDATA);
return CallWindowProc(oldProc, hwnd, msg, wParam, lParam);
BOOL CView::PreTranslateMessage(MSG* pMsg)
pMsg;
return FALSE;
void CView::onEnter()
auto length = edit_->GetWindowTextLength()+1;
auto buf = new wchar_t[length]();
edit_->GetWindowText(buf,length);
MessageBox(buf);
LRESULT CView::OnCtlColor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
HWND hWnd = (HWND)lParam;
HDC hdc = (HDC)wParam;
//1. 只改变多行`Edit`的文本框窗口颜色和文本背景底色.
if(hWnd == *editMultiLine_)
CDCHandle dc(hdc);
dc.SetBkColor(RGB(255,0,0));
dc.SetTextColor(RGB(0,0,255));
return (LRESULT)AtlGetStockBrush(WHITE_BRUSH);
//2. 其他`Edit`的消息不处理
bHandled = FALSE;
return 0;
int CView::onCreate(LPCREATESTRUCT lpCreateStruct)
edit_ = new BASEdit();
edit_->Create(m_hWnd, CRect(CPoint(100,100),CSize(200,30)), 0,
WS_CHILD|WS_VISIBLE|WS_BORDER, 0,kViewWindowEditId);
function<void()> funcEnter = bind(&CView::onEnter, this);
edit_->setFuncEnterCallback(funcEnter);
edit_->SetCueBannerText(L"Date: 2021-04-28",true);
edit_->setBkgColor(RGB(0,0,255));
edit_->setTextColor(RGB(255,255,255));
editMultiLine_ = new CEdit();
editMultiLine_->Create(m_hWnd, CRect(CPoint(100, 200), CSize(200, 30)), 0, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | ES_AUTOVSCROLL, 0,
kViewWindowEditMultiLineId);
auto oldProc = editMultiLine_->SetWindowLong(GWL_WNDPROC, (LONG)Edit_Prc);
editMultiLine_->SetWindowLong(GWL_USERDATA, (LONG)oldProc);
return 0;
LRESULT CView::onPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
CPaintDC dc(m_hWnd);
//TODO: Add your drawing code here
return 0;
BASEdit.h
#ifndef __BAS_EDIT
#define __BAS_EDIT
#include <Windows.h>
#include <GdiPlus.h>
#include <string>
#include <memory>
#include <functional>
#include "atlcrack.h"
using namespace std;
class BASEdit : public CWindowImpl<BASEdit, CEdit>
public:
BASEdit();
~BASEdit();
BEGIN_MSG_MAP_EX(BASEdit)
MSG_OCM_CTLCOLOREDIT(OnReflectedCtlColorEdit)
MSG_WM_KEYDOWN(OnKeyDown)
DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
void setFuncEnterCallback(function<void()>& func);
void setBkgColor(COLORREF color);
void setTextColor(COLORREF color);
protected:
HBRUSH OnReflectedCtlColorEdit(CDCHandle dc, HWND edit);
void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
private:
function<void()> funcEnterCallback_;
HBRUSH brushBkg_;
COLORREF colorBkg_;
COLORREF colorFont_;
;
#endif
BASEdit.cpp
#include "stdafx.h"
#include "bas_edit.h"
#include <iostream>
using namespace std;
BASEdit::BASEdit()
colorBkg_ = GetSysColor(COLOR_WINDOW);
colorFont_ = GetSysColor(COLOR_WINDOWTEXT);;
brushBkg_ = ::CreateSolidBrush(colorBkg_);
BASEdit::~BASEdit()
::DeleteObject(brushBkg_);
void BASEdit::setBkgColor(COLORREF color)
colorBkg_ = color;
::DeleteObject(brushBkg_);
brushBkg_ = ::CreateSolidBrush(colorBkg_);
void BASEdit::setTextColor(COLORREF color)
colorFont_ = color;
void BASEdit::setFuncEnterCallback(function<void()>& func)
funcEnterCallback_ = func;
void BASEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
if (nChar == VK_RETURN)
if (funcEnterCallback_)
funcEnterCallback_();
else
SetMsgHandled(FALSE);
HBRUSH BASEdit::OnReflectedCtlColorEdit(CDCHandle dc, HWND edit)
::SetBkColor(dc,colorBkg_);
::SetTextColor(dc,colorFont_);
return brushBkg_;
运行
图1
下载
https://download.csdn.net/download/infoworld/85143035
参考
以上是关于[WTL/ATL]_[初级]_[如何设置CEdit的文本框背景色和文字颜色]的主要内容,如果未能解决你的问题,请参考以下文章
[WTL/ATL]_[初级]_[如何设置CEdit的文本框背景色和文字颜色]
[WTL/ATL]_[初级]_[TreeView控件如何显示ToolTip]
[WTL/ATL]_[初级]_[微调控件CUpDownCtrl的使用]
[WTL/ATL]_[初级]_[关于窗口子类析构时崩溃的原因]