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


Comments

  • Thanks for all the comments!

    Posted by Legacy on 01/15/2003 12:00am

    Originally posted by: Andy Brown

    Note my email address has changed.

    Reply
  • Problem when used in resizable dialog (+solved)

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

    Originally posted by: Sander Verhagen

    Hello,
    
    


    When I tried to use this (great) control in one of the cdxCDynamicWnd resizable dialog thingies (elsewhere on CodeGuru), I ran into assertion failures because of the scroll bar not yet being created at a time that the resizing stuff already is moving all kinds of controls to the correct places.
    Therefore I've slightly modified the OnSize function of COptionsPanel.

    void COptionsPanel::OnSize( UINT nType, int cx, int cy )
    {
    CRect rcClient;

    // ensure we are created
    if(!IsWindow(GetSafeHwnd()))
    return;

    // ###added!!!###
    if(!IsWindow(m_wndVertScroll.GetSafeHwnd()))
    return;

    ... (etc.)


    Yours,


    Sander

    Reply
  • Look great! Gonna try it right away!

    Posted by Legacy on 07/05/2002 12:00am

    Originally posted by: Sander Verhagen

    Nothing more to say about it... as said... looks great...

    Reply
  • Little problem, when first group has radio buttons

    Posted by Legacy on 12/13/2001 12:00am

    Originally posted by: Sto�fan

    Hi,
    great job, to do this, and gnu shared it !

    However, I find a little problem. When the first group of the control has radio buttons, the radio button toggle mode doesn't work !
    If the first group has check buttons, no problem.

    Thanks for sharing your class and so on

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

Top White Papers and Webcasts

  • The latest release of SugarCRM's flagship product gives users new tools to build extraordinary customer relationships. Read an in-depth analysis of SugarCRM's enhanced ability to help companies execute their customer-facing initiatives from Ovum, a leading technology research firm.

  • You probably have several goals for your patient portal of choice. Is "community" one of them? With a bevy of vendors offering portal solutions, it can be challenging for a hospital to know where to start. Fortunately, YourCareCommunity helps ease the decision-making process. Read this white paper to learn more. "3 Ways Clinicians can Leverage a Patient Portal to Craft a Healthcare Community" is a published document owned by www.medhost.com

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds