Click here to Skip to main content
15,896,111 members
Articles / Programming Languages / C++

Color CButton, CEdit, and CDialog using CAdvancedComponent

Rate me:
Please Sign up or sign in to vote.
2.75/5 (8 votes)
3 Nov 2008CPOL1 min read 37K   2.2K   15  
Using CAdvancedComponent to change the background, foreground, and other colors on CButton, CEdit, and CDialog.
/////////////////////////////////////////////////////////////////////////////
// AdvancedButton.cpp : implementation file for the CAdvancedButton class
//
// Written by Loic Brayat (dev@pileouface.org)
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "AdvancedButton.h"
  
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// Classes used by the CAdvancedButton to draw itself
/////////////////////////////////////////////////////////////////////////////

class DrawnObject {

public:

    virtual void Draw(CDC *DC, CRect R, UINT state, COLORREF color) = 0;

    virtual void DrawText(CDC *DC, 
                          CRect R, 
                          const char *Buf, 
                          COLORREF TextColor);

protected:

    virtual void DrawFrame(CDC *DC, CRect R, int Inset) = 0;
    virtual void DrawFilled(CDC *DC, CRect EndPoints, COLORREF color) = 0;
    virtual void DrawFocus(CDC *DC, CRect EndPoints, COLORREF bkcolor) = 0;

};

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

class DrawnRect : public DrawnObject {

public:

    virtual void Draw(CDC *DC, CRect R, UINT state, COLORREF color);

protected:

    virtual void DrawFilled(CDC *DC, CRect EndPoints, COLORREF color);
    virtual void DrawFocus(CDC *DC, CRect EndPoints, COLORREF bkcolor);
    virtual void DrawFrame(CDC *DC, CRect R, int Inset);

};

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

class DrawnEllipse : public DrawnObject {

public:

    virtual void Draw(CDC *DC, CRect R, UINT state, COLORREF color);

protected:

    virtual void DrawFilled(CDC *DC, CRect EndPoints, COLORREF color);
    virtual void DrawFocus(CDC *DC, CRect EndPoints, COLORREF bkcolor);
    virtual void DrawFrame(CDC *DC, CRect R, int Inset);

};

/////////////////////////////////////////////////////////////////////////////
// CAdvancedButton's implementation
/////////////////////////////////////////////////////////////////////////////

IMPLEMENT_DYNAMIC(CAdvancedButton, CButton)

CAdvancedButton::CAdvancedButton() 
{  
// initialize hwndOwner for GetOwner() and SetOwner() support in MFC < 2.5
#if (_MFC_VER < 0x0250)
  hwndOwner = NULL;  
#endif 

    drawType = DRAW_RECT;
} 

CAdvancedButton::~CAdvancedButton()
{
} 

BEGIN_MESSAGE_MAP(CAdvancedButton, CButton)
    ON_WM_LBUTTONUP()
END_MESSAGE_MAP()

void CAdvancedButton::PreSubclassWindow()
{
    ModifyStyle(0,BS_OWNERDRAW);
}

bool CAdvancedButton::SubclassDlgItem(const UINT nID, 
                                      CWnd* pParent, 
                                      const COLORREF BGColor, 
                                      const COLORREF FGColor, 
                                      const COLORREF DisabledColor)
{
    if (!CButton::SubclassDlgItem(nID, pParent))
		return false;

	m_BGColor = BGColor; 
	m_FGColor = FGColor;
	m_disabled = DisabledColor;

    drawType = DRAW_RECT;

	return true;
} 

bool CAdvancedButton::SetColors(const COLORREF BGColor, 
                                const COLORREF FGColor, 
                                const COLORREF DisabledColor)
{
	m_BGColor = BGColor; 
    m_FGColor = FGColor;
	m_disabled = DisabledColor;

    this->RedrawWindow();

	return true;
} 

void CAdvancedButton::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
	CDC* pDC = CDC::FromHandle(lpDIS->hDC);

	UINT state = lpDIS->itemState; 
	CRect btnRect;
	btnRect.CopyRect(&lpDIS->rcItem); 

    DrawnObject * pDrawnObj;

    switch(drawType) {
        case DRAW_ELLIPSE : pDrawnObj = new DrawnEllipse();
                            break;
        default /* RECT */: pDrawnObj = new DrawnRect();
                            break;
    }

    const int bufSize = 512;
    TCHAR buffer[bufSize];
    GetWindowText(buffer, bufSize);
	
    pDrawnObj->Draw(pDC, btnRect, state, GetBackGroundColor());

    if (state & ODS_DISABLED)
    	pDrawnObj->DrawText(pDC, btnRect, buffer, GetDisabledColor());
    else
      	pDrawnObj->DrawText(pDC, btnRect, buffer, GetForeGroundColor());

    delete pDrawnObj;
} 

/////////////////////////////////////////////////////////////////////////////
// DrawnObjects's implementation
/////////////////////////////////////////////////////////////////////////////

void DrawnObject::DrawText(CDC *DC, 
                           CRect R, 
                           const char *Buf, 
                           COLORREF TextColor)
{
    COLORREF prevColor = DC->SetTextColor(TextColor);
    DC->SetBkMode(TRANSPARENT);
	DC->DrawText(Buf, strlen(Buf), R, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
	DC->SetTextColor(prevColor);
}

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

void DrawnRect::DrawFrame(CDC *DC, CRect R, int Inset)
{ 
	COLORREF dark, light, tlColor, brColor;
	int i, m, width;
	width = (Inset < 0)? -Inset : Inset;
	
	for (i = 0; i < width; i += 1) {
		  
	  	if ( width == 1 ) {
			light = WHITE;
			dark = DKGRAY;
		}
        else {
		    m = 255 / (i + 2);
		    dark = PALETTERGB(m, m, m);
		    m = 192 + (63 / (i + 1));
		    light = PALETTERGB(m, m, m);
        }
		
		if ( Inset < 0 ) {
			tlColor = dark;
			brColor = light;
		}
		else {
			tlColor = light;
			brColor = dark;
		}
		
        DC->Draw3dRect(R, tlColor, brColor);
  	
        R.DeflateRect(1, 1);
	}
}

void DrawnRect::DrawFilled(CDC *DC, CRect R, COLORREF color)
{ 
	CBrush B;
	B.CreateSolidBrush(color);
	DC->FillRect(R, &B);
    B.DeleteObject();
}

void DrawnRect::DrawFocus(CDC *DC, CRect EndPoints, COLORREF bkcolor)
{    
    DrawFocusRect(DC->GetSafeHdc(), EndPoints);
}

void DrawnRect::Draw(CDC *DC, CRect R, UINT state, COLORREF color)
{
    DrawFilled(DC, R, color); 
    DrawFrame(DC, R, 2);    
    
    if (state & ODS_FOCUS) {
		if (state & ODS_SELECTED)
    		DrawFrame(DC, R, -1);
        R.DeflateRect(2, 2);
        DrawFocus(DC, (LPRECT)&R, color);
	}
}

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

void DrawnEllipse::DrawFilled(CDC *DC, CRect EndPoints, COLORREF color)
{
    CPen newPen;
    newPen.CreatePen(PS_SOLID, 3, color);
    CPen *oldPen = DC->SelectObject(&newPen);

    CRect aera = EndPoints;

    while (!aera.IsRectEmpty()) {
        aera.DeflateRect(1, 1);
        DC->Ellipse(aera);
    }

    DC->SelectObject(oldPen);
    newPen.DeleteObject();
}

void DrawnEllipse::DrawFrame(CDC *DC, CRect EndPoints, int Inset)
{
    COLORREF color = (Inset<0)?BLACK:DKGRAY;
		
    CPen newPen;
    newPen.CreatePen(PS_SOLID, 2, color);
    CPen *oldPen = DC->SelectObject(&newPen);
    DC->Ellipse(EndPoints);
    DC->SelectObject(oldPen); 
    newPen.DeleteObject();
}

void DrawnEllipse::DrawFocus(CDC *DC, CRect EndPoints, COLORREF bkcolor)
{
    CPen newPen;
    newPen.CreatePen(PS_DOT, 1, BLACK);
    CPen *oldPen = DC->SelectObject(&newPen);
    DC->SetBkMode(OPAQUE);
    DC->SetBkColor(bkcolor);
    DC->Ellipse(EndPoints);
    DC->SelectObject(oldPen);
    newPen.DeleteObject();
}

void DrawnEllipse::Draw(CDC *DC, CRect R, UINT state, COLORREF color)
{
    CRect rect;
    rect.CopyRect(R);

    rect.DeflateRect(1, 1);
    DrawFrame(DC, rect, 2);

    rect.DeflateRect(1, 1);
    DrawFilled(DC, rect, color);

    if (state & ODS_FOCUS) {
        if (state & ODS_SELECTED) {
            rect.InflateRect(1, 1);
            DrawFrame(DC, rect, -1);
            rect.DeflateRect(1, 1);
            DrawFrame(DC, rect, -1);
        }

        DrawFilled(DC, rect, color);
        rect.DeflateRect(2, 2);
        DrawFocus(DC, rect, color);
        rect.DeflateRect(1, 1);
        DrawFilled(DC, rect, color);
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
France (Metropolitan) France (Metropolitan)
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions