Click here to Skip to main content
15,887,746 members
Articles / Desktop Programming / MFC

CRadioListBox: A ListBox with Radio Buttons (MFC version)

Rate me:
Please Sign up or sign in to vote.
4.79/5 (16 votes)
22 Dec 2007CPOL2 min read 132.9K   4.3K   54  
How to implement an owner-drawn ListBox with radio buttons instead of standard selection highlight
// RadioListBox.cpp : implementation file
//

#include "stdafx.h"
#include "RadioListBox.h"

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

/////////////////////////////////////////////////////////////////////////////
// CRadioListBox

CRadioListBox::CRadioListBox()
{
}

CRadioListBox::~CRadioListBox()
{
}

BEGIN_MESSAGE_MAP(CRadioListBox, CListBox)
	//{{AFX_MSG_MAP(CRadioListBox)
	ON_WM_CTLCOLOR_REFLECT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRadioListBox message handlers


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

     // just draws focus rectangle when listbox is empty
     if (lpDrawItemStruct->itemID == (UINT)-1)
     {
          if (lpDrawItemStruct->itemAction & ODA_FOCUS)
               pDC->DrawFocusRect(&lpDrawItemStruct->rcItem);
          return;
     }
     else
     {
          int selChange   = lpDrawItemStruct->itemAction & ODA_SELECT;
          int focusChange = lpDrawItemStruct->itemAction & ODA_FOCUS;
          int drawEntire  = lpDrawItemStruct->itemAction & ODA_DRAWENTIRE;

          if (selChange || drawEntire) {
               BOOL sel = lpDrawItemStruct->itemState & ODS_SELECTED;

               // Draws background rectangle
			   pDC->FillSolidRect(&lpDrawItemStruct->rcItem, 
				   ::GetSysColor((GetExStyle()&WS_EX_TRANSPARENT)?COLOR_BTNFACE:COLOR_WINDOW));

               // Draw radio button
			   int h = lpDrawItemStruct->rcItem.bottom - lpDrawItemStruct->rcItem.top;
               CRect rect(lpDrawItemStruct->rcItem.left+2, lpDrawItemStruct->rcItem.top+2, 
				   lpDrawItemStruct->rcItem.left+h-3, lpDrawItemStruct->rcItem.top+h-3);
			   pDC->DrawFrameControl(&rect, DFC_BUTTON, DFCS_BUTTONRADIO | (sel?DFCS_CHECKED:0));

               // Draws item text
               pDC->SetTextColor(COLOR_WINDOWTEXT);
               pDC->SetBkMode(TRANSPARENT);
               lpDrawItemStruct->rcItem.left += h;
               pDC->DrawText((LPCTSTR)lpDrawItemStruct->itemData, &lpDrawItemStruct->rcItem, DT_LEFT);
          }
		  // draws focus rectangle
          if (focusChange || (drawEntire && (lpDrawItemStruct->itemState & ODS_FOCUS)))
               pDC->DrawFocusRect(&lpDrawItemStruct->rcItem);
     }
}

HBRUSH CRadioListBox::CtlColor(CDC* pDC, UINT nCtlColor) 
{
    // If transparent style selected...
	if ( (GetExStyle()&WS_EX_TRANSPARENT) && nCtlColor==CTLCOLOR_LISTBOX)
		return (HBRUSH)::GetSysColorBrush(COLOR_BTNFACE);

	return NULL;
}

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
Architect
Peru Peru


Computer Electronics professional, Software Architect and senior Windows C++ and C# developer with experience in many other programming languages, platforms and application areas including communications, simulation systems, PACS/DICOM (radiology), GIS, 3D graphics and HTML5-based web applications.
Currently intensively working with Visual Studio and TFS.

Comments and Discussions