This article describes a set of control derived classes for colorful presentation. XP-styled hot-tracked controls with easy font customization and themed gradient buttons. Gives your edit boxes and buttons a nice look and feel both in XP and 2K.
This work is partly based on the articles "XP Style CBitmapButton (CHoverBitmapButton)" by Rail Jon Rogut and "Color Controls" by Paul J. Weiss. Credits to you both.
Note that the original versions of the control derived classes were written by Paul J. Weiss. Since the application I wrote this for is intended to run on touch screen systems, I focused mainly on the base class
CColorStatic, and most of all on the
CColorButton. These classes have been completely rewritten while the
CColorComboBox class consists of the original work by Paul. I kept it here in case anyone wants to make an effort. Don't expect it to work as it is (no offence Paul =).
Using the code
- Runs on Windows 2000 (classic style only, ses sample screen dump) and Windows XP.
CColorButton uses Uxtheme.h and tmschema.h (and corresponding libraries) for visual styling. Have your project include the path to these files (found in the SDK).
CColorButton uses GDI+ for drawing. gdiplus.dll must be present on targeted systems. Refer to SDK.
- Add theme.cpp and ColorControl.cpp to your project.
- Include ColorControl.h where you need it.
CEdit controls to your dialog template with desired style (disabled, readonly etc.).
- Create control variables for each control of type
- Compile and run.
Note that visual styling only works for Windows XP with XP-style enabled. In Windows 2000, the
CTheme class will fail to load the required DLL, and classic style will be forced.
void CColorControl::SetControlFont (int pointSize, CString fontName, bool bold = false, bool italic = false );
void CColorControl::SetColors (const COLORREF FGColor, const COLORREF BGColor, const COLORREF HotFGColor, const COLORREF HotBGColor);
void CColorControl::SetDisabledColors (const COLORREF DisabledFGColor = RGB_GRAYTEXT, const COLORREF DisabledBGColor = RGB_BTNFACE);
void CColorControl::SetColorBg (COLORREF clr);
void CColorControl::SetColorFg (COLORREF clr);
void CColorControl::SetColorBgHot (COLORREF clr);
void CColorControl::SetColorFgHot (COLORREF clr);
void CColorControl::SetColorBgDisabled(COLORREF clr);
void CColorControl::SetColorFgDisabled(COLORREF clr);
void CColorControl::SetRolloverDelay (UINT mSeconds);
void CColorControl::EnableHot (bool bEnable}; // turns hottracking on/of
void CColorButton::EnableXP (bool bEnable); // turns xp-style (if present on system) on/off
void CColorButton::SetGradientAngle (float nAngle);
void CColorButton::SetGradientColors (BYTE alphaUpper, COLORREF rgbUpper, BYTE alphaLower, COLORREF rgbLower, BYTE alphaLowerHot, COLORREF rgbLowerHot);
Tip: If you still need to handle
WM_CTLCOLOR for controls not derived from
CColorControl, you might wind up with a lot of
if statements to determine whether to let the message slip (for the
CColorControl derives) or to do something. To reduce the workload for this case, I added the
IMPLEMENT_DYNAMIC macros to the classes. This lets you use
RUNTIME_CLASS so you can do something like this:
HBRUSH CViewOperator::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
HBRUSH hbr = CFormView::OnCtlColor(pDC, pWnd, nCtlColor);
if(nCtlColor == CTLCOLOR_DLG || nCtlColor == CTLCOLOR_STATIC)
if( pWnd->IsKindOf(RUNTIME_CLASS(CColorEdit)) ||
static CBrush staticBrush(m_bgColor);
- Added font support
Don't hesitate to improve or change whatever you feel like and post it back. I'm all for perfection!
Good luck /Anders