CStatic with bitmap sensitive to change in system colours

If an icon is used in a static control, it is sensitive to changes
in the system colours. This means that areas of the icon that have
background colour, is updated with the new background colour etc.

As far as I can see, there is not the same if instead a bitmap is used
in the static control. Here is a small class that adds this
functionality for bitmaps. This is useful if for instance you add your
non-square logo in the About dialog box.

The example figures are from the Database Sample
(Repeater Frequency Index) by Eric Hoagland.

Without the CSysColStatic

With the CSysColStatic

To use the class you add a member variable to you dialog header:

protected:
CSysColStatic m_Static;

Then you add the following to OnInitDialog:

BOOL CMyApp::OnInitDialog()
{
	CDialog::OnInitDialog();

	m_Static.SubclassDlgItem(IDC_ARROW_STATIC,this);
	m_Static.ReloadBitmap(IDB_BITMAP1);

The last statement makes the static control reload the bitmap given by
IDB_BITMAP1
with correct system colours.

The implementation of the static subclass is very simple:

#if !defined(AFX_SYSCOLSTATIC_H__664DE301_4F7B_11D1_9E3D_00A0245800CF__INCLUDED_)
#define AFX_SYSCOLSTATIC_H__664DE301_4F7B_11D1_9E3D_00A0245800CF__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// SysColStatic.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CSysColStatic window

class CSysColStatic : public CStatic
{
// Construction
public:
	CSysColStatic();
	void ReloadBitmap(int nImageID = -1);
// Attributes
public:

// Operations
public:

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

// Implementation
public:
	virtual ~CSysColStatic();

	// Generated message map functions
protected:
	int m_nImageID;
	//{{AFX_MSG(CSysColStatic)
	afx_msg void OnSysColorChange();
	//}}AFX_MSG

	DECLARE_MESSAGE_MAP()
};

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

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

#endif // !defined(AFX_SYSCOLSTATIC_H__664DE301_4F7B_11D1_9E3D_00A0245800CF__INCLUDED_)

ReloadBitmap reloads the bitmap identified by m_nImageID. ReloadBitmap is
also used to
set m_nImageID because I have not found a way to automatically extract the
bitmap ID
from the control. By loading the bitmap with LoadImage using the
LR_LOADMAP3DCOLORS style,
the colour changes are done automatically.

A handler is added to respond to WM_SYSCOLORCHANGE messages. It simply
calls ReloadBitmap
without any arguments.

// SysColStatic.cpp : implementation file
//

#include "stdafx.h"
#include "myapp.h"
#include "SysColStatic.h"

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

/////////////////////////////////////////////////////////////////////////////
// CSysColStatic

CSysColStatic::CSysColStatic()
{
	m_nImageID == -1;
}

CSysColStatic::~CSysColStatic()
{
}

void CSysColStatic::ReloadBitmap(int nImageID)
{
	if(nImageID != -1)
		m_nImageID = nImageID;

	if(m_nImageID == -1)
		return;

	HBITMAP hBmp = (HBITMAP)::LoadImage( AfxGetInstanceHandle(),
            MAKEINTRESOURCE(m_nImageID), IMAGE_BITMAP, 0,0, LR_LOADMAP3DCOLORS );

	if( hBmp == NULL )
		return;

	hBmp = SetBitmap(hBmp);
	if(hBmp != NULL)
		::DeleteObject(hBmp);
}

BEGIN_MESSAGE_MAP(CSysColStatic, CStatic)
	//{{AFX_MSG_MAP(CSysColStatic)
	ON_WM_SYSCOLORCHANGE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSysColStatic message handlers

void CSysColStatic::OnSysColorChange()
{
	CStatic::OnSysColorChange();

	ReloadBitmap();
}

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read