Read/Only CCombobox class

Have you ever wanted the CCombobox class to display "readable" text when it is disabled? No matter whether it is a drop-down or a drop-list type of combobox!

Here's a class that'll do that (and much more, although the rest is not visually related)!

For example, in the pictures below, you can see the "before" and "after" effects of disabling the comboboxes using the standard "EnableWindow()" function call to either enable/disable the combobox.

Before

After

The TComboBox class also provides mechanisms for quite a few time saving headaches when working with comboboxes, such as:

  1. Function calls to add entries into the combobox with "hidden" string information (i.e. in the screens above, the data "Item Data 1,2" is associated with the first combobox but is not visable). I know that Microsoft provides the "SetItemData()" member function for comboboxes, but it only allows for a DWORD, not a string. Therefore, there is no need to have global variables defined to contain the "hidden" information. Such an example is trying to use a CStringArray as data to be associated with the various entries in the combobox. As soon as the CStringArray goes out of scope, specifically if it is defined locally to a function, the data for the combobox will no longer be valid once the function exists.
  2. The ability to select an item based on the "hidden" code (i.e. in the above example, the statement to select the item in the third combobox was basically 'm_cbcDropDownNew.SelectCode(-1, "Item Data 1,2")'.
  3. The ability to "force fill" the combobox if the information isn't found. It is displayed differently (i.e. with special characters before/after the entry), to let you know that the entry was forced (the characters displayed are by default '+' and ';' - so a forced item would look like "+Drop List 3;").
  4. Let the combobox deal with duplicates (whether you want duplicates, or you don't).
  5. Function calls to switch the mode from drop-down to drop-list (so that you don't have to remember the style code necessary to switch to either).

Once you get the code, it is simple enough to add to whatever project you are working on, by opening up ClassWizard, and clicking on the "Add Class..." button in the upper right hand corner of ClassWizard. Click on "New..." from the drop down menu. The class name should be entered as CTComboBox, and the base class should be CCombobox. After clicking on OK, the files "TComboBox.h" and "TComboBox.cpp" will be generated. Once that is done, simply replace the files with the two that come with the demo project. I'd like to give you an easier way to do this, but I'm using VC 5.0, and haven't been able to find out any other way to add a class to a project (P.S. if anyone knows a better way, feel free to recommend one!).

Once you've added the class to the project, all you have to do to add member variables that are based on the "CTComboBox" class, is to "Add variable...", give the variable a name, set the "Category" to control, and a select "variable type" of "CTComboBox". ClassWizard will of course remind you that you need to include the "tcombobox.h" file in the header of the dialog itself.

Downloads

Download demo project - 27 Kb
Download source - 8 Kb


Comments

  • Does not work with drop list types

    Posted by Funkhouser on 10/20/2004 03:16pm

    First, be sure that the "Disabled" option is not checked from within "Properties" dialog.

    With Visual C++ v6:
    1. Add a ComboBox of type "Drop List" with values "Off" (default) and "On"
    2. Add a control variable of type TComboBox
    3. Run your GUI and enable the TComboBox.
    4. Change the selection in the combo box to On
    5. Change the combobox to read-only

    At this point, the box is set to read-only mode with the selection being displayed as "Of". Note the missing "f". So it appears that it uses the old value with the length of the new value.

    My solution is the following:
    91,96d90
    < {
    < pChildWnd->GetWindowText(csChildTxt);
    <
    < _tcsncpy((LPTSTR)lParam, (LPCTSTR)csChildTxt, wParam - 1);
    < } // End of pointer validation
    < else

    Reply
  • How we can add an string to list box item of combobox by code?

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

    Originally posted by: zeinalzadeh

    How we can add an string to list box item of combobox by code.While exit that program the date saved on that combobox.

    Reply
  • No .dsp or .dsw in your project ?

    Posted by Legacy on 02/28/2003 12:00am

    Originally posted by: Bruno Leclerc

    No .dsp or .dsw in your project ?

    Reply
  • Creating ComboBox could not be any easier...

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

    Originally posted by: Hassn Ikbal

    There is a new COM Control for VC++ and VB called SmartCombo Control. It allows you to create your very own custom DropDown ComboBox in no time. All you have to do is invoke its DropDown method and SmartCombo will take care of the rest. You can create Color Combo, TreeView Combo, MultiColumn, File Picker, Date Picker and any thing elese you can think of. It has AutoComplete feature among many other. DropPortion can be resized by the user (if you enable this feature). Every aspect of it controlled by you - behaviours and appearances. All properties are readabled and setable at both run and design time.

    visit http://www.visualdatasolution.com

    it will staisfy you - because you will create it in no time.

    Reply
  • FIX: string not terminated in WM_GETTEXT handling

    Posted by Legacy on 03/13/2002 12:00am

    Originally posted by: Aaron

    Handling of WM_GETTEXT message does not terminate the
    
    string retrieved with _tcsncpy. The last line in the
    following snippet is how I fixed this.

    // Check if pointer is valid
    if (pChildWnd)
    {
    pChildWnd->GetWindowText(csChildTxt);

    _tcsncpy((LPTSTR)lParam, (LPCTSTR)csChildTxt, wParam - 1);
    } // End of pointer validation
    else
    // Copy out the selected text, stripping of "forced" entry
    // pre/post string attachments
    _tcsncpy((LPTSTR)lParam, (LPCTSTR)GetCurrentText(), wParam - 1);

    *(LPTSTR)(lParam + wParam - 1) = 0; // terminate the string


    Reply
  • Need a 3 state combo box.

    Posted by Legacy on 11/01/2001 12:00am

    Originally posted by: Wes

    While working on a project @ home, I ran accross a need for a 3 state combobox. The 3 states are Disabled, Read Only, and Normal. Disable and Normal are the two states already supported by the MFC combobox. The third state (read only) I mostly derrived from the Read Only Combobox design. The problem is that while the combobox is "read only", I am unable to select text in the window nor tab into or out of the control. Does anyone have any ideas?

    Thanks
    Wes

    Reply
  • fix for WM_ENABLE crashing

    Posted by Legacy on 01/31/2001 12:00am

    Originally posted by: Alistair McLuckie

    Thanks for the class, its been very useful.
    
    But needed to add a m_hWnd test in the WM_ENABLE block if enabling a droplist rather than a dropdown as it was crashing when trying to enable the m_pReadOnlyEdit

    Change:
    // Check if enabling window, and edit control exists
    if ((wParam == 1) && m_pReadOnlyEdit)
    m_pReadOnlyEdit->ShowWindow(SW_HIDE);// Hide the edit control

    to:
    // Check if enabling window, and edit control exists
    if ((wParam == 1) && m_pReadOnlyEdit &&
    m_pReadOnlyEdit->m_hWnd != NULL)
    m_pReadOnlyEdit->ShowWindow(SW_HIDE);// Hide the edit control

    Reply
  • Adding CB_SETCURSEL message

    Posted by Legacy on 10/07/1999 12:00am

    Originally posted by: Xavier Lelievre

      case CB_SETCURSEL:
    
    {
    LRESULT
    lRtrn = CComboBox::DefWindowProc(message, wParam, lParam);

    DWORD dwStyle = GetStyle();
    // See if we're disabling the control
    if ((dwStyle & WS_DISABLED) == WS_DISABLED)
    {
    // Check if edit control has been created and has a valid windows handle
    if (m_pReadOnlyEdit &&
    (m_pReadOnlyEdit->m_hWnd != NULL))
    {
    // Try to show the edit control
    m_pReadOnlyEdit->ShowWindow(SW_SHOW);
    m_pReadOnlyEdit->SetReadOnly(TRUE);
    m_pReadOnlyEdit->ModifyStyle(WS_TABSTOP, 0);

    CString csComboText;
    GetWindowText(csComboText);
    m_pReadOnlyEdit->SetWindowText(csComboText);
    } // End of pointer validation
    } // Check if disabled flag is on
    return lRtrn;
    }

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

Top White Papers and Webcasts

  • Live Event Date: May 6, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT While you likely have very good reasons for remaining on WinXP after end of support -- an estimated 20-30% of worldwide devices still are -- the bottom line is your security risk is now significant. In the absence of security patches, attackers will certainly turn their attention to this new opportunity. Join Lumension Vice President Paul Zimski in this one-hour webcast to discuss risk and, more importantly, 5 pragmatic risk mitigation techniques …

  • With JRebel, developers get to see their code changes immediately, fine-tune their code with incremental changes, debug, explore and deploy their code with ease (both locally and remotely), and ultimately spend more time coding instead of waiting for the dreaded application redeploy to finish. Every time a developer tests a code change it takes minutes to build and deploy the application. JRebel keeps the app server running at all times, so testing is instantaneous and interactive.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds