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

  • On-demand Event Event Date: September 10, 2014 Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild." This loop of continuous delivery and continuous feedback is how the best mobile …

  • As mobile devices have pushed their way into the enterprise, they have brought cloud apps along with them. This app explosion means account passwords are multiplying, which exposes corporate data and leads to help desk calls from frustrated users. This paper will discover how IT can improve user productivity, gain visibility and control over SaaS and mobile apps, and stop password sprawl. Download this white paper to learn: How you can leverage your existing AD to manage app access. Key capabilities to …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds