MFC - change text color of a cstatic text control

后端 未结 5 1094
野的像风
野的像风 2020-12-29 07:09

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条回答
  • 2020-12-29 07:53

    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.

    0 讨论(0)
  • 2020-12-29 07:54

    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;
    
    0 讨论(0)
  • 2020-12-29 07:55

    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.

    0 讨论(0)
  • 2020-12-29 07:55

    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.

    0 讨论(0)
  • 2020-12-29 08:02

    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
    }
    
    0 讨论(0)
提交回复
热议问题