Click to See Complete Forum and Search --> : Changing the color of a CStatic control


Troy T
May 13th, 1999, 02:05 PM
Hello-

I have a CStatic control that I need to change the color on. I can change the font easily, but there isn't a SetTextColor() function in CWnd. Can someone give me some tips to changing the text color of a CStatic member? Thanks!

- Troy

May 13th, 1999, 02:57 PM
hi

U can use SetTextColor() to achieve the above. Remember that SetTextColor() is a member function of CDC. Now coming to your question, say u have a dialog box with a static control with id IDC_STATIC. To change its text color , do the following in any of your CDialog derived class's member functions:

CStatic * pStatic = (CStatic*)GetDlgItem(IDC_STATIC);
if(pStatic != NULL)
{
CDC * pDC = pStatic->GetDC();
pDC->SetTextColor(RGB(255,0,0)); // set the text color
pDC->SetBkColor(RGB(166,166,166)); // set the bk color
pDC->TextOut(2,2, "New");
pStatic->ReleaseDC(pDC);
pStatic->UpdateWindow();
}


This will take care of changing the text color. U can put in this piece of code whenever u want the color to change.

HTH

Mark Messer
May 13th, 1999, 03:02 PM
I was just looking at that problem too. In a CFormView or CDialog, you would use the class wizard to add a handler for WM_CTLCOLOR.

HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

if (pWnd->GetDlgCtrlID() == ID_MY_CTRL)
{
pDC->SetTextColor(RGB(0,0,255)); //Blue
}

return hbr;
}



But I don't see that message in the class wizard for other classes.

Troy T
May 13th, 1999, 03:38 PM
I like this solution, but it isn't working for me. Also, I already have text in a CStatic control, instead of using pDC->TextOut( 2, 2, _T("Hello") ); is there a better way to just attach to the existing text already in my static control, and to use it's already predefined position on the dialog?

Thanks for your help..

- Troy

Troy T
May 13th, 1999, 03:42 PM
This could be an acceptable solution, but let's say I have some CComboBoxEx controls with colors in them. When the user changes the selection in the combo, I need to updated the color of the static text on the fly. How would you suggest doing this with this code in mind? Would I have to just post a WM_CTLCOLOR message to the current window so that it updates, or??

Thanks for the help!

- Troy

May 13th, 1999, 03:54 PM
Here is a class that does just that:

The header file StaticField.h

#if !defined(AFX_STATICFIELD_H__E288D123_4260_11D2_A046_00600831FDB2__INCLUDED_)
#define AFX_STATICFIELD_H__E288D123_4260_11D2_A046_00600831FDB2__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

/**
* This class makes it easy to change colors of a static box.
* @author Wayne Fuller
* @see CStatic
*/
class CStaticField : public CStatic
{
/// Variable that holds the background color.
COLORREF m_bgColor;
/// Variable that holds the foreground color.
COLORREF m_fgColor;
/// Variable that holds the background brush.
CBrush m_bgBrush;

// Construction
public:
CStaticField();

// Operations
public:
COLORREF GetFgColor() { return m_fgColor; }
COLORREF GetBgColor() { return m_bgColor; }
void SetColors(COLORREF fgColor, COLORREF bgColor);

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CStaticField)
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~CStaticField();

// Generated message map functions
protected:
//{{AFX_MSG(CStaticField)
afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
DECLARE_DYNCREATE(CStaticField)
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STATICFIELD_H__E288D123_4260_11D2_A046_00600831FDB2__INCLUDED_)




StaticField.cpp


#include "stdafx.h"
#include "StaticField.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

IMPLEMENT_DYNCREATE(CStaticField, CStatic)

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CStaticField
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*************************************************************************************************************************
* NAME : CStaticField
* NOTES : Constructor...
* HISTORY: 2 Sep 1998 - RWF Created
*************************************************************************************************************************/
CStaticField::CStaticField()
{
// Default colors - FG : Black, BG - Gray
m_fgColor = RGB(0,0,0);
m_bgColor = RGB(192,192,192);
m_bgBrush.CreateSolidBrush(m_bgColor);
}
/*************************************************************************************************************************
* NAME : CStaticField
* NOTES : Constructor...
* HISTORY: 2 Sep 1998 - RWF Created
*************************************************************************************************************************/
CStaticField::CStaticField(COLORREF fgColor, COLORREF bgColor)
{
m_fgColor = fgColor;
m_bgColor = bgColor;
m_bgBrush.CreateSolidBrush(bgColor);
}
/*************************************************************************************************************************
* NAME : ~CStaticField
* NOTES : Destructor...
* HISTORY: 2 Sep 1998 - RWF Created
*************************************************************************************************************************/
CStaticField::~CStaticField()
{
}

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

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CStaticField message handlers
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*************************************************************************************************************************
* NAME : CtlColor
* NOTES : Window message - WM_CTLCOLORSTATIC
* HISTORY: 2 Sep 1998 - RWF Created
*************************************************************************************************************************/
HBRUSH CStaticField::CtlColor(CDC* pDC, UINT /*nCtlColor*/)
{
pDC->SetTextColor(m_fgColor);
pDC->SetBkColor(m_bgColor);
// Return the brush handle
return m_bgBrush;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CStaticField function calls
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*************************************************************************************************************************
* NAME : SetColors
* NOTES : Sets the member variable colors and then Invalidates the control.
* HISTORY: 2 Sep 1998 - RWF Created
*************************************************************************************************************************/
void CStaticField::SetColors(COLORREF fgColor, COLORREF bgColor)
{
// Check to see if the background has been changed
// No sense to create the brush everytime
if ( m_bgColor != bgColor ) {
m_bgColor = bgColor;
m_bgBrush.DeleteObject();
m_bgBrush.CreateSolidBrush(m_bgColor);
}

m_fgColor = fgColor;
// Redraw the control
Invalidate();
}




Excuse the formatting since I just cut and pasted this code.
Now all you do is map a ctrl from the dialog and pick control. Then go into the header file and change the class from CStatic to CStaticField. Of course include the proper headers. Let me know if this works. The problem I have found doing it any other way is you have to make sure you do the same thing in OnPaint, this way the messages route directly to this class. This can also be used for CEdit, just change the base class.

Hope this helps,

Wayne

Mark Messer
May 13th, 1999, 04:38 PM
When the framework posts a WM_CTLCOLOR message, it does some work you don't see. E.g. It creates a CDC an includes a pointer to it in the message. In that case you can use a simple handler.

If you are just using a CWnd instead of a class that does the message for you, you will have to create the CDC yourself. I would just use Anonomous' solution (12:57).