【问题标题】:Change text and background color from a CEdit derived class从 CEdit 派生类更改文本和背景颜色
【发布时间】:2019-06-13 18:09:38
【问题描述】:

我有一个来自CEdit 的派生类,我想更改文本和背景颜色。我已尝试使用消息ON_WM_CTLCOLOR_REFLECTON_WM_CTLCOLOR,但我从未收到这些消息。除了ON_PAINT,还有其他选择吗?

这是我初始化CColorEdit 控件的方法:

//in my dialog.h
CColorEdit m_test;
//in .cpp
DDX_Control(pDX, IDC_TEST, m_test);

我不能像这样手动设置颜色:

m_test.SetTextColor(...);

这是我尝试处理ON_WM_CTLCOLOR 的方式:

BEGIN_MESSAGE_MAP(CColorEdit, CEdit)
    ON_WM_CTLCOLOR()
END_MESSAGE_MAP()

HBRUSH CColorEdit::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CEdit::OnCtlColor(pDC, pWnd, nCtlColor);
    if (m_theme != 0)
    {
        pDC->SetTextColor(RGB(0, 255, 0));
    }
    return hbr;
}

这是我对WM_CTLCOLOR_REFLECT 的尝试:

BEGIN_MESSAGE_MAP(CColorEdit, CEdit)
    //{{AFX_MSG_MAP(CColorEdit)
    ON_WM_CTLCOLOR_REFLECT()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CColorEdit::SetTextColor(COLORREF textColor)
{
    m_textColor = textColor;
    Invalidate();
}
void CColorEdit::SetBkColor(COLORREF backgroundColor)
{
    m_backgroundColor = backgroundColor;
    m_brBkgnd.DeleteObject();
    m_brBkgnd.CreateSolidBrush(backgroundColor);
    Invalidate();
}

HBRUSH CColorEdit::CtlColor(CDC* pDC, UINT nCtlColor)
{
    pDC->SetBkColor(m_backgroundColor);
    pDC->SetTextColor(m_textColor);

    if (nCtlColor)       // To get rid of compiler warning
        nCtlColor += 0;

    return hbr;
}

谢谢。

【问题讨论】:

  • 展示一下你到目前为止所做的处理程序怎么样?你能确定他们没有被叫到吗?
  • @AndrewTruckle 我已经在 OnCtlColor 中放置了一个断点,但我永远不会进入该函数。我已经编辑了我的问题。我已经尝试了您链接中的示例,但仍然没有收到消息。
  • 您是否在调试模式下运行?发布模式并不总是在断点处停止。
  • ON_WM_CTLCOLOR 是这里的错误用法。显示您对ON_WM_CTLCOLOR_REFLECT的尝试

标签: c++ mfc


【解决方案1】:

here。引用:

CEdit 进行简单的背景颜色更改对我来说是一个真正的挑战。我惊讶地发现没有标准函数,比如CEdit::SetBkColor,可以做到这一点。

第一步是创建从CEdit派生的类并声明函数CtlColor

// CustomEdit.h
class CCustomEdit : public CEdit
{
protected:
  HBRUSH CtlColor(CDC *pDC, UINT);
  DECLARE_MESSAGE_MAP()
};

二、处理WM_CTLCOLOR_REFLECT事件:

// CustomEdit.cpp
BEGIN_MESSAGE_MAP(CCustomEdit, CEdit)
  ON_WM_CTLCOLOR_REFLECT()
END_MESSAGE_MAP()

HBRUSH CCustomEdit::CtlColor(CDC *pDC, UINT)
{
  COLORREF bkColor = RGB(255, 255, 255);
  pDC->SetBkColor(bkColor);
  return CreateSolidBrush(bkColor);
}

所以你需要同时使用它们

【讨论】:

  • 我已经尝试了这两个示例,但似乎没有任何效果......也许我的顶级课程之一处理 OnCltColor 消息? ://
  • @Emile 尝试做一个新的测试对话项目。尝试重现您的错误。
  • ::CreateSolidBrush(bkColor) 每次都会创建一个画笔句柄。这个句柄没有被释放然后丢失,导致资源泄漏。你应该创建一个类成员数据CBrush m_brush; 并返回那个画笔。
  • @AndrewTruckle 我有一个没有返回 CtlColor 消息的基类!现在我改变了它,它完美地工作!谢谢你:)
【解决方案2】:

如果您创建CColorEdit 类仅用于执行这种自定义颜色绘制,则不需要,因为您可以简单地在父窗口中处理WM_CTLCOLOR 消息。该消息实际上是 WM_CTLCOLOREDITWM_CTLCOLOR 用于旧 Windows 版本),但是 MFC 将所有 WM_CTLCOLORxxxx 消息映射到 ON_WM_CTLCOLOR 处理程序并将控件类型作为参数传递。

这里有一些代码:

#define COLOR_YELLOW RGB(255,255,0)
HBRUSH hBrYellow = []() { return CreateSolidBrush(COLOR_YELLOW); }();

HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    // Our custom edit-control
    if (nCtlColor == CTLCOLOR_EDIT && pWnd->GetDlgCtrlID() == IDC_MYCUSTOMEDIT)
    {
        pDC->SetBkColor(COLOR_YELLOW);
        return hBrYellow;
    }

    // All the rest
    return CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
}

此代码示例将编辑控件的背景颜色设置为黄色。编辑控件是一个简单标准的windows编辑框,不需要子类化。

【讨论】:

  • 我有很多其他类使用 CEdit,所以我不想在每个类中都更改它。这就是为什么我需要在我的 CColorEdit 类中执行消息处理程序:/跨度>
猜你喜欢
  • 2018-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-15
  • 2019-02-06
  • 1970-01-01
相关资源
最近更新 更多