MFC - change text color of a cstatic text control

2019-03-15 05:01发布

How do you change the text color of a CStatic text control? Is there a simple way other that using the CDC::SetTextColor?

thanks...

5条回答
孤傲高冷的网名
2楼-- · 2019-03-15 05:05

unfortunately you won't find a SetTextColor method in the CStatic class. If you want to change the text color of a CStatic you will have to code a bit more.

In my opinion the best way is creating your own CStatic-derived class (CMyStatic) and there cacth the ON_WM_CTLCOLOR_REFLECT notification message.

BEGIN_MESSAGE_MAP(CMyStatic, CStatic)
    //{{AFX_MSG_MAP(CMyStatic)
    ON_WM_CTLCOLOR_REFLECT()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

HBRUSH CColorStatic::CtlColor(CDC* pDC, UINT nCtlColor) 
{
    pDC->SetTextColor(RGB(255,0,0)); 

    return (HBRUSH)GetStockObject(NULL_BRUSH);  
}

Obviously you can use a member variable and a setter method to replace the red color (RGB(255,0,0)).

Regards.

查看更多
Explosion°爆炸
3楼-- · 2019-03-15 05:15

You can implement ON_WM_CTLCOLOR in your dialog class, without having to create a new CStatic-derived class:

BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
    //{{AFX_MSG_MAP(CMyDialog)
    ON_WM_CTLCOLOR()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

HBRUSH CMyDialog::OnCtlColor(CDC* pDC, CWnd *pWnd, UINT nCtlColor)
{
    switch (nCtlColor)
    {
    case CTLCOLOR_STATIC:
        pDC->SetTextColor(RGB(255, 0, 0));
        return (HBRUSH)GetStockObject(NULL_BRUSH);
    default:
        return CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
    }
}

Notice that the code above sets the text of all static controls in the dialog. But you can use the pWnd variable to filter the controls you want.

查看更多
混吃等死
4楼-- · 2019-03-15 05:21

From the Answers given here and other places, it was not obvious how to create a derived class to be used instead of CStatic that handles coloring itself.

So following is what works for me, using MSVS 2013 Version 12.0.40629.00 Update 5. I can place a "Static Text"-control in the resource editor, then replace the type of the member variable with TColorText.

In the .h-file:

class TColorText : public CStatic
{
protected:
  DECLARE_MESSAGE_MAP( )

public:
  // make the background transparent (or if ATransparent == true, restore the previous background color)
  void setTransparent( bool ATransparent = true );
  // set background color and make the background opaque
  void SetBackgroundColor( COLORREF );
  void SetTextColor( COLORREF );

protected:
  HBRUSH CtlColor( CDC* pDC, UINT nCtlColor );

private:
  bool MTransparent = true;
  COLORREF MBackgroundColor = RGB( 255, 255, 255 );  // default is white (in case someone sets opaque without setting a color)
  COLORREF MTextColor = RGB( 0, 0, 0 );  // default is black. it would be more clean 
                                         // to not use the color before set with SetTextColor(..), but whatever...
};

in the .cpp-file:

void TColorText::setTransparent( bool ATransparent )
{
  MTransparent = ATransparent;
  Invalidate( );
}

void TColorText::SetBackgroundColor( COLORREF AColor )
{
  MBackgroundColor = AColor;
  MTransparent = false;
  Invalidate( );
}

void TColorText::SetTextColor( COLORREF AColor )
{
  MTextColor = AColor;
  Invalidate( );
}

BEGIN_MESSAGE_MAP( TColorText, CStatic )
  ON_WM_CTLCOLOR_REFLECT( )
END_MESSAGE_MAP( )

HBRUSH TColorText::CtlColor( CDC* pDC, UINT nCtlColor )
{
  pDC->SetTextColor( MTextColor );
  pDC->SetBkMode( TRANSPARENT );  // we do not want to draw background when drawing text. 
                                  // background color comes from drawing the control background.
  if( MTransparent )
    return nullptr;  // return nullptr to indicate that the parent object 
                     // should supply the brush. it has the appropriate background color.
  else
    return (HBRUSH) CreateSolidBrush( MBackgroundColor );  // color for the empty area of the control
}
查看更多
爷的心禁止访问
5楼-- · 2019-03-15 05:21

Very helpful.

https://msdn.microsoft.com/de-de/library/0wwk06hc.aspx

Alike to

HBRUSH hBrush = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if (nCtlColor == CTLCOLOR_STATIC &&
    pWnd->GetSafeHwnd() == GetDlgItem(XXX)->GetSafeHwnd()
) pDC->SetTextColor(RGB(255, 0, 0));    
return hBrush;
查看更多
Root(大扎)
6楼-- · 2019-03-15 05:28

Just a follow up to the painting issue (a transparent background), which caused by *return (HBRUSH)GetStockObject(NULL_BRUSH);*

Easy change as below:

HBRUSH hBrush = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

if (nCtlColor == CTLCOLOR_STATIC &&
    pWnd->GetSafeHwnd() == GetDlgItem(XXX)->GetSafeHwnd()
) pDC->SetTextColor(RGB(255, 0, 0));    

return hBrush;

Hope this helps.

查看更多
登录 后发表回答