Click here to Skip to main content
16,016,746 members
Articles / Desktop Programming / MFC
Article

XColorStatic - a colorizing static control

Rate me:
Please Sign up or sign in to vote.
4.75/5 (34 votes)
16 Oct 2003CPOL1 min read 157.6K   4.6K   76   26
XColorStatic is a simple CStatic-based control that provides font changes, text and background colors, and icon display.

Introduction

XColorStatic is a general-purpose control to allow nice text display on a dialog. The demo shows you the kinds of text and icon display that are possible:

screenshot

XColorStatic API

Here is the complete list of CXColorStatic methods:

void SetBackgroundColor(COLORREF rgb, BOOL bRedraw = TRUE);
void SetTextColor(COLORREF rgb, BOOL bRedraw = TRUE);
void SetBold(BOOL bFlag, BOOL bRedraw = TRUE);
void SetFont(LPCTSTR lpszFaceName, int nPointSize, BOOL bRedraw = TRUE);
void SetFont(LOGFONT *pLogFont, BOOL bRedraw = TRUE);
void SetFont(CFont *pFont, BOOL bRedraw = TRUE);
void SetIcon(HICON hIcon, BOOL bRedraw = TRUE);
void SetMargins(int x, int y) { m_nXMargin = x; m_nYMargin = y; }

How To Use

To integrate XColorStatic into your app, you first need to add the following files to your project:

  • XColorStatic.cpp
  • XColorStatic.h
  • FontSize.cpp
  • FontSize.h

Then use the resource editor to add a static control to your dialog, and use Class Wizard to attach a member variable to that control. Note that when adding the static control, you must name it something other than IDC_STATIC.

Next, include the header file XColorStatic.h in the dialog's header file. Then replace the CStatic definition with CXColorStatic. Now you are ready to start using XColorStatic.

Usage

This software is released into the public domain. You are free to use it in any way you like. If you modify it or extend it, please to consider posting new code here for everyone to share. This software is provided "as is" with no expressed or implied warranty. I accept no liability for any damage or loss of business that this software may cause.

Revision History

Version 1.0 - 2003 October 17

  • Initial public release.

License

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


Written By
Software Developer (Senior) Hans Dietrich Software
United States United States
I attended St. Michael's College of the University of Toronto, with the intention of becoming a priest. A friend in the University's Computer Science Department got me interested in programming, and I have been hooked ever since.

Recently, I have moved to Los Angeles where I am doing consulting and development work.

For consulting and custom software development, please see www.hdsoft.org.






Comments and Discussions

 
GeneralScrollbar Improvement Pin
only4lee7-Jun-06 5:41
only4lee7-Jun-06 5:41 
GeneralFull Transparent Background Pin
wlburgess19-Oct-05 11:54
wlburgess19-Oct-05 11:54 
GeneralRe: Full Transparent Background Pin
LeeJ.C.23-Oct-05 21:36
LeeJ.C.23-Oct-05 21:36 
GeneralRe: Full Transparent Background Pin
CALIFF218-Jan-07 4:53
CALIFF218-Jan-07 4:53 
GeneralNot displaying tabs correctly. Pin
David Fleming1-Sep-05 23:50
David Fleming1-Sep-05 23:50 
JokeRe: Not displaying tabs correctly. Pin
David Fleming2-Sep-05 12:19
David Fleming2-Sep-05 12:19 
GeneralCode to add Vertical Scroll Bars to this Control Pin
kbomb98728-May-05 8:01
kbomb98728-May-05 8:01 
Here is how to add vertical scroll bars to the static control.
Replace your XColorStatic.h and XColorStatic.cpp with the following code below. Note the new functions added ResetScrollBars(), WindowProc(), OnVScroll() to handle the scroll bar. The actual drawing of the scrolled text occurs within OnPaint() and is commented by // BEGIN SCROLL CODE and // END SCROLL CODE. You can tweak the hardcoded values for amount of scrolling and size of clipping region inside OnPaint(). Have fun!


// XColorStatic.h Version 1.0
//
// Author: Hans Dietrich
// hdietrich2@hotmail.com
//
// This software is released into the public domain.
// You are free to use it in any way you like.
//
// This software is provided "as is" with no expressed
// or implied warranty. I accept no liability for any
// damage or loss of business that this software may cause.
//
///////////////////////////////////////////////////////////////////////////////

#ifndef XCOLORSTATIC_H
#define XCOLORSTATIC_H

/////////////////////////////////////////////////////////////////////////////
// CXColorStatic window

class CXColorStatic : public CStatic
{
private:
int m_iLineHeight;

// Construction
public:
CXColorStatic();
virtual ~CXColorStatic();

// Attributes
public:
void SetBackgroundColor(COLORREF rgb, BOOL bRedraw = TRUE);
void SetTextColor(COLORREF rgb, BOOL bRedraw = TRUE);
void SetBold(BOOL bFlag, BOOL bRedraw = TRUE);
void SetFont(LPCTSTR lpszFaceName, int nPointSize, BOOL bRedraw = TRUE);
void SetFont(LOGFONT * pLogFont, BOOL bRedraw = TRUE);
void SetFont(CFont *pFont, BOOL bRedraw = TRUE);
void SetIcon(HICON hIcon, BOOL bRedraw = TRUE);
void SetMargins(int x, int y) { m_nXMargin = x; m_nYMargin = y; }
void ShowText(CString strText);

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CXColorStatic)
protected:
virtual void PreSubclassWindow();
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL

// Implementation
protected:
CFont m_font;
COLORREF m_rgbText;
COLORREF m_rgbBackground;
CBrush * m_pBrush;
BOOL m_bBold;
int m_nXMargin, m_nYMargin;
HICON m_hIcon;

// Generated message map functions
void ResetScrollBar();

protected:
//{{AFX_MSG(CXColorStatic)
afx_msg void OnPaint();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
};

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

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif //XCOLORSTATIC_H









//////////////////////////////////////////////////////////////
// XColorStatic.cpp
//////////////////////////////////////////////////////////////

// XColorStatic.cpp Version 1.0
//
// Author: Hans Dietrich
// hdietrich2@hotmail.com
//
// This software is released into the public domain.
// You are free to use it in any way you like.
//
// This software is provided "as is" with no expressed
// or implied warranty. I accept no liability for any
// damage or loss of business that this software may cause.
//
///////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "XColorStatic.h"
#include "FontSize.h"

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

///////////////////////////////////////////////////////////////////////////////
// CXColorStatic

BEGIN_MESSAGE_MAP(CXColorStatic, CStatic)
//{{AFX_MSG_MAP(CXColorStatic)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_VSCROLL()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

///////////////////////////////////////////////////////////////////////////////
// ctor
CXColorStatic::CXColorStatic()
{
m_rgbText = GetSysColor(COLOR_BTNTEXT);
m_rgbBackground = GetSysColor(COLOR_BTNFACE);
m_pBrush = new CBrush(m_rgbBackground);
m_bBold = FALSE;
m_hIcon = NULL;
m_nXMargin = m_nYMargin = 0;

// The amount of scroll to make when clicking the UP or DOWN arrows on the scroll bar.
m_iLineHeight = 8;
}

///////////////////////////////////////////////////////////////////////////////
// dtor
CXColorStatic::~CXColorStatic()
{
TRACE(_T("in CXColorStatic::~CXColorStatic\n"));

if (m_font.GetSafeHandle())
m_font.DeleteObject();

if (m_pBrush)
{
m_pBrush->DeleteObject();
delete m_pBrush;
}
m_pBrush = NULL;
}

///////////////////////////////////////////////////////////////////////////////
// PreSubclassWindow
void CXColorStatic::PreSubclassWindow()
{
TRACE(_T("in CXColorStatic::PreSubclassWindow\n"));

// get current font
CFont* pFont = GetFont();
if (!pFont)
{
HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
if (hFont == NULL)
hFont = (HFONT) GetStockObject(ANSI_VAR_FONT);
if (hFont)
pFont = CFont::FromHandle(hFont);
}
ASSERT(pFont);
ASSERT(pFont->GetSafeHandle());

// create the font for this control
LOGFONT lf;
pFont->GetLogFont(&lf);
m_font.CreateFontIndirect(&lf);
}

///////////////////////////////////////////////////////////////////////////////
// OnPaint
void CXColorStatic::OnPaint()
{
CPaintDC dc(this); // device context for painting

dc.SaveDC();

dc.SetTextColor(m_rgbText);
dc.SetBkColor(m_rgbBackground);
dc.SetBkMode(OPAQUE);
dc.SelectObject(m_pBrush);

CRect rect;
GetClientRect(rect);

// cannot have both an icon and text

if (m_hIcon)
{
int nIconX = ::GetSystemMetrics(SM_CXICON);
int nIconY = ::GetSystemMetrics(SM_CYICON);

rect.left = rect.left + (rect.Width() - nIconX) / 2;
rect.top = rect.top + (rect.Height() - nIconY) / 2;

dc.DrawIcon(rect.left, rect.top, m_hIcon);
}
else
{
dc.SelectObject(&m_font);

// get static's text
CString strText = _T("");
GetWindowText(strText);

UINT nFormat = 0;
DWORD dwStyle = GetStyle();

// set DrawText format from static style settings
if (dwStyle & SS_CENTER)
nFormat |= DT_CENTER;
else if (dwStyle & SS_LEFT)
nFormat |= DT_LEFT;
else if (dwStyle & SS_RIGHT)
nFormat |= DT_RIGHT;

if (dwStyle & SS_CENTERIMAGE) // vertical centering ==> single line only
nFormat |= DT_VCENTER | DT_SINGLELINE;
else
nFormat |= DT_WORDBREAK;

//
// BEGIN SCROLL CODE
//
// Create a rect above our target rect that will not allow drawing to.
// We will make 200 pixels above our target non-drawing. That should give us enough
// room to scroll text upwards.
RECT excluderect;
excluderect.top = rect.top - 200;
excluderect.bottom = rect.top;
excluderect.left = rect.left;
excluderect.right = rect.right;
dc.ExcludeClipRect(&excluderect);

// Draw the text accounting for any scrolling of the scroll bar.
rect.top -= GetScrollPos( SB_VERT );
//
// END SCROLL CODE
//

rect.left += m_nXMargin;
rect.top += m_nYMargin;
dc.DrawText(strText, rect, nFormat);
}

dc.RestoreDC(-1);

ResetScrollBar();
}

///////////////////////////////////////////////////////////////////////////////
// OnEraseBkgnd
BOOL CXColorStatic::OnEraseBkgnd(CDC* pDC)
{
CRect cr;
GetClientRect(cr);
pDC->FillRect(&cr, m_pBrush);

return TRUE; //CStatic::OnEraseBkgnd(pDC);
}

///////////////////////////////////////////////////////////////////////////////
// SetFont
void CXColorStatic::SetFont(LOGFONT *pLogFont, BOOL bRedraw /*= TRUE*/)
{
ASSERT(pLogFont);
if (!pLogFont)
return;

if (m_font.GetSafeHandle())
m_font.DeleteObject();

LOGFONT lf = *pLogFont;

lf.lfWeight = m_bBold ? FW_BOLD : FW_NORMAL;

m_font.CreateFontIndirect(&lf);

if (bRedraw)
RedrawWindow();
}

///////////////////////////////////////////////////////////////////////////////
// SetFont
void CXColorStatic::SetFont(LPCTSTR lpszFaceName,
int nPointSize,
BOOL bRedraw /*= TRUE*/)
{
// null face name is ok - we will use current font

LOGFONT lf;
memset(&lf, 0, sizeof(lf));

if (lpszFaceName == NULL)
{
CFont *pFont = GetFont();
ASSERT(pFont);
pFont->GetLogFont(&lf);
}
else
{
_tcsncpy(lf.lfFaceName, lpszFaceName, sizeof(lf.lfFaceName)/sizeof(TCHAR)-1);
}

lf.lfHeight = GetFontHeight(nPointSize);

SetFont(&lf, bRedraw);
}

///////////////////////////////////////////////////////////////////////////////
// SetFont
void CXColorStatic::SetFont(CFont *pFont, BOOL bRedraw /*= TRUE*/)
{
ASSERT(pFont);
if (!pFont)
return;

LOGFONT lf;
memset(&lf, 0, sizeof(lf));

pFont->GetLogFont(&lf);

SetFont(&lf, bRedraw);
}

///////////////////////////////////////////////////////////////////////////////
// SetTextColor
void CXColorStatic::SetTextColor(COLORREF rgb, BOOL bRedraw /*= TRUE*/)
{
m_rgbText = rgb;
if (bRedraw)
RedrawWindow();
}

///////////////////////////////////////////////////////////////////////////////
// SetBold
void CXColorStatic::SetBold(BOOL bFlag, BOOL bRedraw /*= TRUE*/)
{
m_bBold = bFlag;

LOGFONT lf;
memset(&lf, 0, sizeof(lf));

CFont *pFont = GetFont();
ASSERT(pFont);
pFont->GetLogFont(&lf);

lf.lfWeight = m_bBold ? FW_BOLD : FW_NORMAL;

SetFont(&lf, bRedraw);
}

///////////////////////////////////////////////////////////////////////////////
// SetBackgroundColor
void CXColorStatic::SetBackgroundColor(COLORREF rgb, BOOL bRedraw /*= TRUE*/)
{
m_rgbBackground = rgb;
if (m_pBrush)
{
m_pBrush->DeleteObject();
delete m_pBrush;
}
m_pBrush = new CBrush(m_rgbBackground);
if (bRedraw)
RedrawWindow();
}

///////////////////////////////////////////////////////////////////////////////
// SetIcon
void CXColorStatic::SetIcon(HICON hIcon, BOOL bRedraw /*= TRUE*/)
{
ASSERT(hIcon);

m_hIcon = hIcon;
if (bRedraw)
RedrawWindow();
}

void CXColorStatic::ShowText(CString strText)
{
SetWindowText(strText);
RedrawWindow();

// Reset the scroll bar position back to 0.
SetScrollPos(SB_VERT, 0);
}

void CXColorStatic::ResetScrollBar()
{
CRect rFrame;

GetClientRect( rFrame );

// Need for scrollbars?
if( 0 )//rFrame.Height() > m_iDocHeight + 8 )
{
ShowScrollBar( SB_VERT, FALSE ); // Hide it
SetScrollPos( SB_VERT, 0 );
}
else
{
SCROLLINFO si;
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_PAGE | SIF_RANGE;
si.nPage = rFrame.Height();
si.nMax = 500;//m_iDocHeight + 8;
si.nMin = 0 ;

SetScrollInfo(SB_VERT, &si);

EnableScrollBarCtrl( SB_VERT, TRUE );
}
}

void CXColorStatic::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
int iScrollBarPos = GetScrollPos( SB_VERT );

CRect rFrame;

GetClientRect( rFrame );

switch( nSBCode )
{
case SB_LINEUP:
iScrollBarPos = max( iScrollBarPos - m_iLineHeight, 0 );
break;

case SB_LINEDOWN:
iScrollBarPos = min( iScrollBarPos + m_iLineHeight,
GetScrollLimit( SB_VERT ) );
break;

case SB_PAGEUP:
iScrollBarPos = max( iScrollBarPos - rFrame.Height(), 0 );
break;

case SB_PAGEDOWN:
iScrollBarPos = min( iScrollBarPos + rFrame.Height(),
GetScrollLimit( SB_VERT ) );
break;

case SB_THUMBTRACK:
case SB_THUMBPOSITION:
iScrollBarPos = nPos;
break;
}

SetScrollPos( SB_VERT, iScrollBarPos );

Invalidate();
}

LRESULT CXColorStatic::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if( message == WM_NCHITTEST || message == WM_NCLBUTTONDOWN ||
message == WM_NCLBUTTONDBLCLK )
return ::DefWindowProc( m_hWnd, message, wParam, lParam );

return CStatic::WindowProc(message, wParam, lParam);
}

QuestionIs It A BUG ?? Pin
Renjith Ramachandran1-Jul-04 19:31
Renjith Ramachandran1-Jul-04 19:31 
AnswerRe: Is It A BUG ?? Pin
Sean Moss-Pultz16-Jul-04 1:03
Sean Moss-Pultz16-Jul-04 1:03 
GeneralRe: Is It A BUG ?? Pin
Renjith Ramachandran16-Jul-04 1:29
Renjith Ramachandran16-Jul-04 1:29 
GeneralThat's wrong! Pin
SB200313-Nov-10 9:42
SB200313-Nov-10 9:42 
GeneralDebug assertion at non-modal dialogs Pin
Frank Isensee6-Apr-04 21:59
Frank Isensee6-Apr-04 21:59 
GeneralRe: Debug assertion at non-modal dialogs Pin
Hans Dietrich7-Apr-04 0:29
mentorHans Dietrich7-Apr-04 0:29 
GeneralRe: Debug assertion at non-modal dialogs Pin
Hans Dietrich7-Apr-04 17:16
mentorHans Dietrich7-Apr-04 17:16 
GeneralRe: Debug assertion at non-modal dialogs Pin
Gray Dragon6-May-04 11:01
Gray Dragon6-May-04 11:01 
GeneralRe: Debug assertion at non-modal dialogs Pin
Hans Dietrich6-May-04 11:38
mentorHans Dietrich6-May-04 11:38 
GeneralRe: Debug assertion at non-modal dialogs Pin
Gray Dragon6-May-04 18:35
Gray Dragon6-May-04 18:35 
GeneralRe: Debug assertion at non-modal dialogs Pin
Gray Dragon6-May-04 18:58
Gray Dragon6-May-04 18:58 
GeneralRe: Debug assertion at non-modal dialogs Pin
wikiguyjd26-Jan-07 10:32
wikiguyjd26-Jan-07 10:32 
QuestionBug? Pin
alex.barylski27-Nov-03 12:38
alex.barylski27-Nov-03 12:38 
AnswerRe: Bug? Pin
Hans Dietrich28-Nov-03 0:37
mentorHans Dietrich28-Nov-03 0:37 
GeneralDebug Assertion Failed Pin
andrewgs7327-Nov-03 4:12
andrewgs7327-Nov-03 4:12 
GeneralRe: Debug Assertion Failed Pin
Hans Dietrich27-Nov-03 9:53
mentorHans Dietrich27-Nov-03 9:53 
GeneralRe: Debug Assertion Failed Pin
andrewgs7328-Nov-03 14:09
andrewgs7328-Nov-03 14:09 
GeneralNice But........ Pin
Atif Mushtaq17-Oct-03 20:41
Atif Mushtaq17-Oct-03 20:41 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.