【问题标题】:Drawing text in a custom ComboBox在自定义 ComboBox 中绘制文本
【发布时间】:2020-02-06 22:44:16
【问题描述】:

我正在创建一个新的CComboBox 派生类,以便绘制它的所有区域并使其更加可定制。我能够绘制它的所有区域,并可以绘制其下拉列表的文本。但是,我不知道如何在控件内绘制文本。不知道为什么,控件的文本没有出现。有谁能够帮我?

头文件

class CEasyComboBox : public CComboBox
{
private:
    bool m_IsMouseOver; // Defines if the mouse is over the control.
    bool m_bDropDownListStyle;  // Type of the drop down list.
    bool m_bIsButtonClick;  // Defines if the button of the object has been clicked or not.
    COLORREF m_clrBack; // Color of the background of the color.
    COLORREF m_clrText; // Color of the text of the control.
    COLORREF m_clrBorder;   // Color of the border of the control.
    COLORREF m_clrArrow;    // Color of the arrow of the control.

public:
    CEasyComboBox();    // Constructor
    virtual ~CEasyComboBox();   // Destructor
    afx_msg void OnMouseLeave();    // Called when the mouse leaves the control.
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);    // Called everytime the mouse changes its location on the control.

protected:
    afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);    // Defines the colors of all existing elements of the control.
    afx_msg void OnPaint(); // Paints the control.
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);  // Called when user clicks on left button of the mouse.
    DECLARE_MESSAGE_MAP()

private:
    void SetColors();   // Sets all colors of the control.
};

Cpp 文件

CEasyComboBox::CEasyComboBox()
{
    // I set all colros:
    SetColors();
}

CEasyComboBox::~CEasyComboBox()
{
}

BEGIN_MESSAGE_MAP(CEasyComboBox, CComboBox)
    ON_WM_CTLCOLOR()
    ON_WM_PAINT()
    ON_WM_LBUTTONDOWN()
    ON_WM_MOUSELEAVE()
    ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()

void CEasyComboBox::SetColors()
{
    // I define all colors of the object.
    m_clrText = GENERIC_TEXT_COLOR;
    m_clrBack = GENERIC_BACKGROUND_COLOR;
    m_clrBorder = GENERIC_BORDER_COLOR;

    // Depending on the mouse, I define the colrs.
    if (m_IsMouseOver == true)
    {
        // I define all new colors.
        m_clrBack = RGB(86, 81, 78);
    }

    // I define the color of the arrow equal as the borders.
    m_clrArrow = m_clrText;
}

// CEasyComboBox message handlers

HBRUSH CEasyComboBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    // I check which control is going to be painted.
    pDC->SetBkColor(m_clrBack);
    pDC->SetTextColor(m_clrText);
    HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);
    return hbr;
}

void CEasyComboBox::OnPaint()
{
    // I generate all requiered objects.
    CPaintDC dc(this);
    CRect ClientRect;
    GetClientRect(&ClientRect);

    // I paint the background of the combobox and its borders.
    CBrush brush(m_clrBack);
    CBrush* pOldBrush = dc.SelectObject(&brush);
    dc.FillSolidRect(ClientRect, m_clrBorder);
    ClientRect.DeflateRect(1, 1);
    dc.FillRect(ClientRect, &brush);

    // Depending on the stype of the element, I finish the painting.
    DWORD dwComboStyle = GetStyle();
    BYTE byteComboStyle = (BYTE)dwComboStyle;
    if (byteComboStyle == CBS_SIMPLE)
    {
        dc.SelectObject(pOldBrush);
        return;
    }

    // I resize the client rect.
    int nButtonWidth = ::GetSystemMetrics(SM_CYSIZE);
    DWORD dwExStyles = GetExStyle();
    if (dwExStyles & WS_EX_RIGHT) ClientRect.right = ClientRect.left + nButtonWidth;
    else ClientRect.left = ClientRect.right - nButtonWidth + 4;

    // I draw the button if the mouse is over.
    if (m_IsMouseOver == true) dc.FillSolidRect(&ClientRect, m_clrBorder);
    else dc.FillSolidRect(ClientRect, m_clrBack);

    // I draw the arrow.
    CPoint CenterPoint(ClientRect.CenterPoint());
    ++CenterPoint.y;
    CPoint UpperPoint(CenterPoint.x, CenterPoint.y - 4);
    CPen Pen(PS_SOLID, 1, m_clrArrow);
    CPen* pOldPen = dc.SelectObject(&Pen);
    for (int i = 0; i < 4; ++i)
    {
        dc.MoveTo(CenterPoint);
        VERIFY(dc.LineTo(UpperPoint));

        --CenterPoint.x;
        --CenterPoint.y;
        --UpperPoint.x;
    }

    CenterPoint = ClientRect.CenterPoint();
    ++CenterPoint.y;
    UpperPoint = CenterPoint;
    UpperPoint.y -= 4;
    for (int i = 0; i < 4; ++i)
    {
        dc.MoveTo(CenterPoint);
        VERIFY(dc.LineTo(UpperPoint));

        ++CenterPoint.x;
        --CenterPoint.y;
        ++UpperPoint.x;
    }

    dc.SelectObject(pOldBrush);
    dc.SelectObject(pOldPen);
}

void CEasyComboBox::OnLButtonDown(UINT nFlags, CPoint point)
{
    //the combo gets this message when its Button is pressed
    m_bIsButtonClick = !m_bIsButtonClick;
    CComboBox::OnLButtonDown(nFlags, point);
}

void CEasyComboBox::OnMouseLeave()
{
    // I define the state of the variable.
    m_IsMouseOver = false;
    SetColors();
    CComboBox::OnMouseLeave();
}

void CEasyComboBox::OnMouseMove(UINT nFlags, CPoint point)
{
    // I define the state of the variable.
    if(m_IsMouseOver == false)
    {
        m_IsMouseOver = true;
        SetColors();
    }
    CComboBox::OnMouseMove(nFlags, point);
}

【问题讨论】:

  • 为什么要有文字?您没有呈现任何文本。
  • 我必须做什么来呈现控件的文本?
  • 致电CDC::DrawText(或任何您希望呈现文本的方式)。

标签: c++ mfc


【解决方案1】:

我为你改编了一些我在旧项目中已经做过的事情:

HBRUSH CHSpellComboBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hBGBrush = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor); 
    switch (nCtlColor)
    {
    case CTLCOLOR_LISTBOX :
        pDC->SetBkColor(RGB(200,0,0));
        break;
    }

    pDC->SetTextColor(RGB(255,255,255));
    hBGBrush = CreateSolidBrush(RGB (0,200,0));

    return hBGBrush;
}

结果:

  • 文字颜色:灰色 (255,255,255)
  • 文字背景:红色 (255,0,0)
  • 组合框区域:绿色 (0,255,0)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 1970-01-01
    • 2017-11-28
    • 2012-04-03
    • 2014-05-17
    • 1970-01-01
    相关资源
    最近更新 更多