ChoiceListButton Control

Synopsis

I wanted to have a button that would display a selection of choices to the user.
I could of course use an ownerdraw dropdown box. The problem with that solution, is that, when the dropdown is collapsed it will display the last chosen item always insted of some descriptive text.
That was why i opted for a custom solution.

 

ITCLib

Optionally, the control can use the freeware library 'ITCLib' from Interface technologies, Inc. This is a great library and I will suggest that every MFC developer takes a look at it - it is a real time saver.

ITCLib has only been used for painting the small arrow on the button, and is as such not an integreated part of the control. That is why all references to ITCLib is initially disabled via preprocessor statements, so the sample should compile fine on installations without the library.

To enable ITCLib:

  • If you have ITCLib installed and you want to enable it, do the following:
  • In Project Settings - C/C++ - Preprocessor - Preprocessor definitions, add _ITCDLL
  • In Project Settings - C/C++ - Preprocessor - Additional include directories, add the folder with your ITCLib header files
  • In Project Settings - Link - Input - Additional Library Path, add the folder with your ITCLib lib-files

That's it!

If you want to use you own button class for painting the arrow or what ever it is you want to paint on the button surface, you could enherit CChoiceWindowBtn from your own class instead of CButton or ITCImageButton.

 

Using the control

To use the control, create a project and add these files:

ChoiceWindow.h
ChoiceWindow.cpp
ChoiceWindowBtn.h
ChoiceWindowBtn.cpp
drop_arrow.bmp (or another bitmap)

Assign the bitmap the resource name "DROP_ARROW" - notice as  a string - not as an integer ID.

Next add a button to a dialog and use the member functions from you WM_INITDIALOG handler.

Add an object of type CChoiceWindowBtn to the dialog class. Make sure to add the header include too.

Example - notice the use of preprocessor definitions.

// TODO: Add extra initialization here

#ifdef _ITCDLL	 	
	m_btnDropDown.SubclassControl(IDC_OPTIONS, this);
	m_btnDropDown.AddImage("DROP_ARROW", -1, RGB(255,0,255));
	m_btnDropDown.SetImageAlign(DT_RIGHT|DT_VCENTER);
#else
	m_btnDropDown.SubclassDlgItem(IDC_OPTIONS, this);
#endif

	m_btnDropDown.AddChoice("Name", TRUE);
	m_btnDropDown.AddChoice("Address", TRUE);
	m_btnDropDown.AddChoice("Notes", FALSE);
	m_btnDropDown.AddChoice("Telephone", TRUE);

 

Interface

The control is accessed through the class CChoiceWindowButton. It has a few simple member functions:

 

CChoiceWindowButton::AddChoice

void AddChoice(LPCTSTR szText, BOOL bChecked=FALSE)

Return value
None
Parameters
szText: The text to display as a choice.
bChecked: Should the choice be iniitally checked or not.
Remarks
Adds a new choice to the list.

 

CChoiceWindowButton::Reset

void Reset()

Return value
None
Parameters
None
Remarks
Deletes all the items from the choice list.

CChoiceWindowButton::GetCheck

BOOL GetCheck(int iItem)

Return value
Boolean - the state of the choice specified by iItem
Parameters
nItem: Zero based index of the item to query the state for.
Remarks
Returns TRUE if the choice had a check mark, and FALSE if the choice was not checked by the user.

 

CChoiceWindowButton::SetCheck

void SetCheck(int iItem, BOOL bCheck=TRUE)

Return value
void
Parameters
iItem: Zero based index of the item to query the state for.
bCheck: Boolean value. If true, the item is checked otherwise it is unchecked.

CChoiceWindowButton::GetItemCount

int  GetItemCount()

Return value
The number of items in the list.
Parameters
none

 

CChoiceWindowButton::GetListCtrl

CListCtrl&  GetListCtrl()

Return value
A reference to the underlying CListCtrl object 
Parameters
none
Remarks
You access the list control like this:
CListCtrl& list = btnChoiceList.GetListCtrl();

 

CChoiceWindowButton::RemoveAt

void  RemoveAt(int iIndex)

Return value
None
Parameters
The index of the item to remove from the list.

 

CChoiceWindowButton::m_bDisableIfEmpty

BOOL m_bDisableIfEmpty

Remarks
Boolean value, that specifies if the button is disbaled if the choice list does not contain any items. The default value is TRUE.

 

CChoiceWindowButton::Reset

vid Reset()

Return value
None
Parameters
None
Remarks
Removes all the items from the list.


Downloads

Download demo project - 25 KB


Comments

  • Corrections for Choice Button

    Posted by Legacy on 05/14/2000 12:00am

    Originally posted by: Don Schindler

    This is a really great button! However I noticed that you cannot get the first option state, as the code is written. Looking at the code for GetChecked, the first option will always be item number zero (this uses a zero-based list). The code shown here performs an ASSERT check to make sure the item being checked has an item number larger than zero.


    BOOL CChoiceWindowBtn::GetCheck(int iItem)
    {
    // Is the item with index iItem checked?
    ASSERT(iItem>0 && iItem<m_choiceArray.GetSize());

    CChoice* pChoice = m_choiceArray[iItem];

    return (pChoice->bChecked);
    }


    To fix this, change the ASSERT line to read:
    ASSERT(iItem>=0 && iItem<m_choiceArray.GetSize());

    The important part is "iItem >= 0"
    This allows checking of the first item.

    - Don Schindler
    IBM / CMT

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

Top White Papers and Webcasts

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • Hundreds of millions of users have adopted public cloud storage solutions to satisfy their Private Online File Sharing and Collaboration (OFS) needs. With new headlines on cloud privacy issues appearing almost daily, the need to explore private alternatives has never been stronger. Join ESG Senior Analyst Terri McClure and Connected Data in this on-demand webinar to take a look at the business drivers behind OFS adoption, how organizations can benefit from on-premise deployments, and emerging private OFS …

Most Popular Programming Stories

More for Developers

RSS Feeds