Skip to main content
Email Password   helpLost your password?

Sample Image - CAdvComboBox

AdvComboBox Article Index

   Introduction
   Installation
   Functions
   Notifications
   Styles
   Future upgrades
   Hints & Tips
   Improvements and Bug Fixes

What's new in Version 2.1

I got really tired of having to add all items in the InitDialog function, which can be really annoying in the case where you have several CAdvComboBox in one page. This class will now look for an entry in the stringtable with the same ID as the CAdvComboBox control has in the resource editor. The demo project has been upgraded to display this feature. More information about this has been added under Installation. If you want to add another stringtable entry, just call the new function LoadString(UINT nID) where nID refers to the stringtable entry.

In this version, I have added the code so the CAdvComboBox can be used with the macro RUNTIME_CLASS. Requested by Krishna.

I've also added the missing functionality that opens the dropdown window by pressing Alt-Down or Alt-Up. This was requested by Thomas Freudenberg.

Introduction

I started to work on a control that I was going to use in another program that had combo boxes within a CListBox. The first criteria that I wanted was that the combobox should be flat (no shadows). I looked around for a while and could not find any suitable so I had to create my own somehow. When I had started to work on the flat combobox, I come to think of another cool feature that would be nice to have. How many times have you wanted the same functionality as the address bar in IE. When you type an address and the IAutoComplete COM-object goes to work. Wonderful!...or not. I wanted the same functionality in a my combobox, and especially the resizeable dropdown window. And so, back to the drawing board. After many long nights and several different approaches, I got it to work.

This ComboBox is not subclassing the MFC's CComboBox mostly because I wanted to be able to resize the drop-down window. Instead, I created a CWnd object that looks almost the same as MFC's CComboBox. The tricky part was to get the dropdown window to react the same way as CComboBox. First of all, the dropdown window has to be a child to the desktop, and then there is the nasty problem with the mouse and keyboard capture. The solution to that problem was to have one window that has a listbox and a scrollbar within itself. The scrollbar that the CListBox class uses could not be used due to the capture problem.

During the development more features were added; checked items and disabled items in the dropdown window.

Below is a picture over the class structure.

Class overview
Picture 1

The dropdown window of the AdvComboBox is of an autosize style, that is, it calculates the size it needs to show all items in the list.
So the result is a combobox that acts almost the same as the MFC's CComboBox. You should not have to change any code that are already in use, besides that you have to change the resource from the standard combobox to a custom control. I have tested on W2K and XP. Now I turn to CodeProject's members and other to help me test and find bugs, and maybe some new features to add.

Installation

Installation Index
   Create a new project
   Upgrade your current project
   Use CAdvComboBox in a MFC DLL

This article contains of three different ways of implementing the CAdvComboBox class into your project. One describes the workorder for a new project, and the second how to upgrade your current projects, and the last how to implement the CAdvComboBox in a MFC DLL.

Create a new project

  1. Create a dialog application using the App Wizard.

  2. The explanation below are built upon that you call your application AdvCBDemo

  3. Insert the following files to your workspace
  4. AdvComboBox.h
    AdvComboBox.cpp
    DropWnd.h
    DropWnd.cpp
    DropListBox.h
    DropListBox.cpp
    DropScrollBar.h
    DropScrollBar.cpp
    VisualStylesXP.h
    VisualStylesXP.h

  5. Include the file AdvComboBox.h in your AdvCBDemoDlg.h file

  6. Add a custom control to your dialog

  7. In resource editor, place a new custom control in the dialog by using the Custom Control tool in the toolbar. Enter the properties for the control as shown in the picture below.

    The CAdvComboBox custom control class name is AdvComboBoxCtrl which is defined in AdvComboBox.h.

    Custom control properties
    Picture 2

    Descriptions of the different styles to set:
     Combo style  Value in property window
     CBS_DROPDOWN  0x_____002
     CBS_DROPDOWNLIST  0x_____103
     CBS_AUTOHSCROLL  0x_____043
     CBS_SORT  0x_____103

    So this means that if you want your combobox to have the styles CBS_DROPDOWN, CBS_AUTOHSCROLL, and CBS_SORT the style value should end with 142(as seen in picture 2). You can also edit the resource file in text mode and add the styles there. The resouce editor then translate the style you have choosen into this value.

    The following styles has not been implemented yet:

       CBS_DISABLENOSCROLL
       CBS_HASSTRINGS
       CBS_LOWERCASE
       CBS_NOINTEGRALHEIGHT
       CBS_OEMCONVERT
       CBS_OWNERDRAWFIXED
       CBS_OWNERDRAWVARIABLE
       CBS_SIMPLE
       CBS_UPPERCASE

  8. Add the following public member variable to your CAdvCBDemoDlg class in the AdvCBDemoDlg.h header file:
  9. CAdvComboBox	m_ctlAdvCombo;
  10. Add the following DXX_ call in your AdvCBDemoDlg.cpp file
    DDX_Control(pDX, IDC_ADV_COMBO, m_ctlAdvCombo);
    Add it outside of AFX_DATA_MAP to avoid any mishaps in the future.
    Now, the function DoDataExchange(...) should look like this:
    void CAdvCBDemoDlg::DoDataExchange(CDataExchange* pDX)
    {
    	CDialog::DoDataExchange(pDX);
    	//{{AFX_DATA_MAP(CAdvCBDemoDlg)
    
    		// NOTE: the ClassWizard will add DDX and DDV calls here
    
    	//}}AFX_DATA_MAP
    
    	DDX_Control(pDX, IDC_ADV_COMBO, m_ctlAdvCombo);
    }
    
  11. Compile and run

  12. You should now be able to test your dialog with the AdvComboBox within it.

    Another feature that still has to be implemented is how to get and set data from the control. This is described below.

  13. Set and get data from AdvComboBox

  14. You can use the same way to get and set data as you would with a normal CComboBox, except one small difference.
    The DDX_CBIndex and DDX_CBString should be changed to DDX_ACBIndex and DDX_ACBString for it to work. These functions can be found in the AdvComboBox.cpp file.

    To add functionality to get and set data add one of, or both, the following variables in your AdvCBDemoDlg.h file

    int	m_nAdvCombo;
    CString	m_strAdvCombo;
    You also have to initialize the value to these variables in the constructor of CAdvCBDemoDlg. Add the following code outside AFX_DATA_INIT.
    m_nAdvCombo = -1;
    m_strAdvCombo = "";
    Add also the DDX_ calls in the function DoDataExchange(...) in AdvCBDemoDlg.cpp file below the DDX_Control that you added in step 6.
    DDX_ACBIndex( pDX, IDC_ADV_COMBO, m_nAdvCombo );
    DDX_ACBString( pDX, IDC_ADV_COMBO, m_strAdvCombo );

    You should now be able to use the AdvComboBox control in the same way as the MFC's CComboBox.

    The following was added in version 2.1

  15. Use a stringtable entry to populate the CAdvComboBox list.

  16. To be able to use the stringtable with this combobox, a stringtable entry has to be created with the same identifier as the control was created with in the resource editor. In this case, the stringtable entry ID should be IDC_ADV_COMBO. Below is a picture (picture 3) of this example that you can add to your project.

    In the stringtable entry, a newline ('\n') represents the ending of one item in the combobox list. Please look into the demo project for further information on how to implement this.

    Stringtable entry
    Picture 3

Upgrade your current project

This description is not so detailed as the one above. Hopefully you have enough knowledge to manage the following.
  1. Insert the following files to your workspace
  2. AdvComboBox.h
    AdvComboBox.cpp
    DropWnd.h
    DropWnd.cpp
    DropListBox.h
    DropListBox.cpp
    DropScrollBar.h
    DropScrollBar.cpp
    VisualStylesXP.h
    VisualStylesXP.h

  3. Include the file AdvComboBox.h in your header file

  4. Change classnames

  5. Rename all of your CComboBox variable definitions to CAdvComboBox in your header file.

  6. Replace resource comboboxes

  7. Replace your current comboboxes in the resource editor to custom controls and set the properties as shown in picture 2. You can of course change the style of the custom control.

    Tip! Use the same ID for your custom controls as you had for the comboboxes. This makes it a lot easier further on so that you won't have to change ID's for all your events(ON_CBN_SELCHANGE, etc.) currectly assigned to the standard comboboxes.

  8. Change DDX_ calls

  9. Change all DDX_CBIndex and DDX_CBString to DDX_ACBIndex and DDX_ACBString in your .cpp file. Change the ID's in these calls if you didn't set the same ID's on your new custom controls as you had on the old comboboxes.
  10. Compile and test

  11. Your project should now work except the limitations of the CAdvComboBox.

Use CAdvComboBox in a MFC DLL

This is just a small description of how to use this class in a DLL that has windows(dialogs) in the DLL, and those windows uses CAdvComboBox. To be able to register the class, you have to change the code somewhat. The HINSTANCE in the structure WNDCLASS must have the DLL's HINSTANCE, and not the calling applications HINSTANCE.
  1. Declare a CAdvComboBox variable

  2. Create the class like this:
    CAdvComboBox m_ctlAdvCombo( TRUE )
  3. Global HINSTANCE variable

  4. You also have to add a global HINSTANCE variable the the DLL project.
    Add the following to, for example, StdAfx.cpp in your DLL project:
    HINSTANCE g_hDLLInstance = NULL;
    Then, add the extern definition in the StdAfx.h file like this:
    extern HINSTANCE g_hDLLInstance;
  5. Initialize the global HINSTANCE

  6. Set the hDllInstance in the DllMain function.
    g_hDLLInstance = hInstance;
  7. Change code in CAdvComboBox

  8. Next thing is to find the function RegisterWindowClass() in the AdvComboBox.cpp file. Change the function so it looks like this:
    BOOL CAdvComboBox::RegisterWindowClass()
    {
        WNDCLASS wndcls;
        HINSTANCE hInst;
        if( m_bInst )
        {
            hInst = g_hDLLInstance;
        }
        else
        {
            hInst = AfxGetInstanceHandle();
        }
    
        ASSERT( hInst != 0 );
    
        ...
    	
        return TRUE;
    }
    

  9. Export the CAdvComboBox class

  10. Last, but not least, you have to make the class exported if you want to be able to use it outside the DLL. Remember to make the two DDX_ functions exported too. Class definition:
    class __declspec(dllexport) CAdvComboBox : public CWnd
    DDX_ Definitions:
    _declspec(dllexport) void AFXAPI DDX_ACBIndex( CDataExchange* pDX, 
                                                   int nIDC, int& index );
    _declspec(dllexport) void AFXAPI DDX_ACBString( CDataExchange* pDX, 
                                                    int nIDC, CString& value );

AdvComboBox Functions

The functions in CAdvComboBox class are the same as in MFC's CComboBox. For mor help on those, look in MSDN.
There are also some extra functions that can be used. These are described below

Below is a list of CComboBox functions implemented in CAdvComboBox.

The following CComboBox functions are not implemented in CAdvComboBox

AdvComboBox Notifications

The CAdvComboBox sends the following notifications to the parent, as MFC's CComboBox does.

The following notifications are not sent.

AdvComboBox Styles

The CAdvComboBox has its own styles. They are described here.

The CAdvComboBox supports the following CComboBox styles

The following CComboBox styles are not supported

Future Upgrades

Hints & Tips

Improvements and Bug Fixes

Version 2.1

Version 2.0

Version 1.21

Version 1.2

Version 1.1

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralHow to make the width of the scrollbar bigger? Pin
dragomir
6:34 1 Jun '09  
GeneralMy vote of 2 Pin
joerg-schumann
4:10 22 Jan '09  
GeneralRe: Multiple Monitors Pin
pietje_01
3:30 30 Jan '09  
GeneralCDropWnd crash Pin
simon heffer
6:58 7 Feb '07  
GeneralCListCtrl instead of CListBox will help... Pin
anandarv
17:58 4 Dec '06  
QuestionUse in commercial application? Pin
Carl Fredrik Abelson
2:12 27 Nov '06  
GeneralQuestion (Virtual List for more than 32736 items) ? Pin
ana_v123
10:23 25 Nov '06  
QuestionNo XP Users Pin
AngelPortal
3:08 14 Nov '06  
GeneralWhy not emplemented clear method? Pin
fst-fst
22:59 20 Sep '06  
GeneralI had to make the following mods to make it work as I wanted Pin
cokes
3:14 21 Jul '06  
GeneralFeature Request to Mathias Tunared..! Pin
ana_v123
8:05 10 Jul '06  
Generalno case censetive Pin
dmit_klg
21:54 5 Jun '06  
GeneralAutocompletion scrolling problem Pin
Thomas Blenkers
10:21 17 May '06  
GeneralHow to set the height ? Pin
ouquoi
4:20 17 Feb '06  
GeneralProblem with combo in Windows 98 Pin
Manuel Bautista
5:52 21 Dec '05  
GeneralWinXP and Classic Theme selection Pin
Manfred Kubica
20:29 14 Jul '05  
Generala big bug Pin
dirkiller
16:47 22 May '05  
GeneralRe: a big bug Pin
Anonymous
15:19 24 May '05  
GeneralActive X Control Pin
rk824
2:44 11 May '05  
GeneralA flat scrollbar will be good Pin
z16166
15:18 10 Mar '05  
Generala small memory leak bug Pin
z16166
15:13 10 Mar '05  
GeneralGreat Control and Example! Pin
Galileomak
4:53 28 Nov '04  
GeneralBug with ESC- key Pin
Stefan Pfitzner
0:42 12 Jul '04  
GeneralI've created this control dynamically, but where EditBox? Pin
Gonsaless
7:49 30 May '04  
GeneralA few small changes Pin
Guy Clinger
11:21 7 May '04  


Last Updated 5 Sep 2002 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2009