Internet Explorer-Style Options Panel

COptionsPanel

This class implements a control that is designed to have the look and feel of the Internet Explorer 'Advanced Options' property page, as shown by the picture below.

COptionsPanel sample

The control allows multiple sets of check boxes and radio buttons to be grouped together and indented in a similar style to a standard tree control. Keyboard navigation is supported using the Up and Down arrows, Page-Up, Page-Down, Home and End. Buttons can be selected using the mouse or the space bar. Expanding and collapsing the groups is not supported. The control sends notification messages to the parent dialog when the user selects or deselects a button.

How to use it

  1. I use the STL implementation of vector so you'll have to ensure that you add #include <vector> to your stdafx.h file.
  2. Copy OptionsPanel.h and OptionsPanel.cpp to your project directory and insert them into your project.
  3. Copy the bitmap IDB_OPTIONS_PANEL_IMAGES from the sample project to your project.
  4. Place an ordinary push-button on your dialog or property page where you want the options panel to appear, and make sure that you give it the 'owner draw' style.
  5. Use the class wizard to add a data member for the button, call it whatever you like.
  6. Open your dialog header file, add #include "OptionsPanel.h" at the top and change the CButton m_YourButton data member to read COptionsPanel m_YourButton instead.
  7. Populate the options panel in your dialog's DoDataExchange() member function.

Populating the Options Panel

The options panel should be populated in your dialog's DoDataExchange() member function using the following member functions:

void SetImageList(CImageList& list)

This member function sets the image list containing the images used for the groups in the options panel and you must call it exactly once. Every group must have an associated 16x16 image in this list. The options panel takes a copy of the image list that you pass to it so it's safe to let it go out of scope.

void AddGroup(const CString& strText,
              const int nLevel,
              const int nImage)

void AddGroup(const UINT resID,
              const int nLevel,
              const int nImage)

These two member functions add a new group to the options panel. The first function takes a text string and the second takes a resource identifier, apart from which they are the same. nLevel should be the indentation level of the group, starting at zero for the left edge of the control. nImage is the zero-based index of the image for the group. All groups must have images, you cannot have a group without an image.

void AddCheck(const CString& strText,
              const BOOL bChecked,
              const int nLevel,
              const int nID)

void AddCheck(const UINT resID,
              const BOOL bChecked,
              const int nLevel)

These two member functions add check boxes to the options panel. The first function takes a text string and requires you to supply a unique integer identifier for the button and the second takes a resource identifier and will also use that identifier to identify the button. Set bChecked to TRUE if you would like the check box to be checked, or FALSE to leave it clear. nLevel should be the indentation level of the group, starting at zero for the left edge of the control.

void AddRadio(const CString& strText,
              const BOOL bChecked,
              const int nLevel,
              const int nID)
void AddRadio(const UINT resID, const BOOL bChecked, const int nLevel)

These two member functions add radio buttons to the options panel. The first function takes a text string and requires you to supply a unique integer identifier for the button and the second takes a resource identifier and will also use that identifier to identify the button. Set bChecked to TRUE if you would like the radio button to be checked, or FALSE to leave it clear. nLevel should be the indentation level of the group, starting at zero for the left edge of the control.

	
BOOL SetCheckState(const int nID, const BOOL bChecked)

This member function can be used at any time to check or uncheck one of the check boxes or radio buttons. nID should be set to the identifier of the check box or radio button and bChecked set to TRUE or FALSE to check or uncheck it. Notification messages are not sent when you call this member function.

Retrieving data from the Options Panel

You can get the state of any of the check boxes or radio buttons in the options panel at any time by calling this member functions

BOOL GetCheckState(const int nID) const

nID should be set to the identifier of the check box or radio button and TRUE or FALSE will be returned to indicate the current state.

Notification Messages

When the user checks or unchecks one of the buttons in the options panel a notification message is sent to the parent dialog using the WM_NOTIFY message. To handle this notification you should add the following line to your dialog's message map:

ON_NOTIFY(OPN_SELCHANGE,IDC_OPTIONS,OnSelChangeOptions)

Your dialog's header file will also required the following prototype:

afx_msg void OnSelChangeOptions(NMHDR *pNMHDR,LRESULT *pResult);

As with all the recent Microsoft common controls, pNMHDR actually points to a larger structure who's first data member is an NMHDR structure. In this case the structure is called NMOPTIONSPANEL and looks like this:

typedef struct
{
  NMHDR hdr;
  int idButton;
  BOOL bChecked;
} NMOPTIONSPANEL;

idButton is the identifier of the button that has changed state and bChecked is set to TRUE or FALSE to indicate the new state.

Downloads

Download demo project (normal dialog) - 15 Kb
Download demo project (resizing dialog) - 15 Kb
Download source - 4 Kb