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 16×16 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

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read