Reputation: 4173
How do you change the text color of a CStatic
text control? Is there a simple way other that using the CDC::SetTextColor
?
Upvotes: 20
Views: 73336
Reputation: 1
I believe you can't return nullptr
for a HBRUSH
rather (HBRUSH)GetStockObject(NULL_BRUSH);
Upvotes: -2
Reputation: 31
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;
Upvotes: 3
Reputation: 556
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
}
Upvotes: 5
Reputation: 381
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.
Upvotes: 8
Reputation: 4642
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.
Upvotes: 37
Reputation: 2239
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.
Upvotes: 8