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();	
}



Comments

  • Help - Crashing when I run "SubclassDlgItem" function.

    Posted by InternationScape on 01/12/2006 10:40pm

    How to use it ???

    Reply
  • Where is code

    Posted by Legacy on 09/16/2003 12:00am

    Originally posted by: Arbind Yadav

    hi

    Can you provide its code also.

    Arbind Yadav

    Reply
  • use TRANSPARENT attributes but...

    Posted by Legacy on 08/06/2002 12:00am

    Originally posted by: use_id

    i use the TRANSPARENT attribute for the CStatic,
    there is a error when i change the static window text for twice or more.

    why?

    Reply
  • How can I make Static text has the same bkcolor of dlg's ?

    Posted by Legacy on 07/01/2001 12:00am

    Originally posted by: vikey

    I change the dlg's to green,but the static text's bk color doesn't change,it's bkcolor is system color gray.And I check the style of static text for transparent,it has no affect!How can i do?
    thx very much!

    Reply
  • opsss

    Posted by Legacy on 05/16/2000 12:00am

    Originally posted by: sid

    Never mind... it does work... 
    
    i was doing something wrong.
    Sorry..

    Helpfull code by the way..

    thanks...

    SiD

    • carsh~~~~

      Posted by InternationScape on 01/12/2006 10:33pm

      How to use it, could you give me a sample?

      Reply
    Reply
  • Crashes

    Posted by Legacy on 05/16/2000 12:00am

    Originally posted by: sid

    Crashes !!
    

    Reply
  • Help - Crashing when I run "SubclassDlgItem" function.

    Posted by Legacy on 07/22/1999 12:00am

    Originally posted by: Joe Ersinghaus

    Hello,

    I crash when I run the "SubclassDlgItem" function.

    Wanted to clarify if what I'm doing is correct.

    My code from OnInitDialog:
    m_Static.SubclassDlgItem(IDC_STATIC_ESB,this);
    m_Static.ReloadBitmap(IDB_BITMAP6);


    IDC_STATIC_ESB is the static control which contains the bitmap.

    IDB_BITMAP6 is the bitmap that needs to conform to system color and is loaded into IDC_STATIC_ESB static control.

    Are these the right controls in these functions?

    Thanks,
    Joe

    Reply
  • source update

    Posted by Legacy on 11/25/1998 12:00am

    Originally posted by: Michel Wasink

    In the constructor it says"
    m_nImageID == -1;
    Of course this should be:
    m_nImageID = -1;

    When using default operators the definition of:
    void ReloadBitmap(int nImageID = -1);
    in class CSysColStatic
    must be:
    void CSysColStatic::ReloadBitmap(int nImageID /* = -1 */)
    {
    ...
    }
    instead of
    void CSysColStatic::ReloadBitmap(int nImageID)
    {
    ...
    }

    ,,,^..^,,,
    Michel

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Today's agile organizations pose operations teams with a tremendous challenge: to deploy new releases to production immediately after development and testing is completed. To ensure that applications are deployed successfully, an automatic and transparent process is required. We refer to this process as Zero Touch Deployment™. This white paper reviews two approaches to Zero Touch Deployment--a script-based solution and a release automation platform. The article discusses how each can solve the key …

  • Learn How A Global Entertainment Company Saw a 448% ROI Every business today uses software to manage systems, deliver products, and empower employees to do their jobs. But software inevitably breaks, and when it does, businesses lose money -- in the form of dissatisfied customers, missed SLAs or lost productivity. PagerDuty, an operations performance platform, solves this problem by helping operations engineers and developers more effectively manage and resolve incidents across a company's global operations. …

Most Popular Programming Stories

More for Developers

RSS Feeds