Handling combo closing up in WindowProc!

Posted on 2009-02-19
Last Modified: 2013-11-20
Ah hello.

I have a custom combo box that, when dropped down, hides the default windows listbox part of the control, then displays my own custom one.  This all works, but I am having problems...

I have a class derived from CComboBox that handles the CBN_CLOSEUP and CBN_DROPDOWN via ON_CONTROL_REFLECT macros:  I can hide and show my custom list control respectively in these handler functions.  However, I am now instance subclassing an existing plain old CComboBox control: to do that I need to provide a special window procedure, which I do via SetWindowLong/GWL_WNDPROC.  This is the function I have so far:

      WNDPROC wndProcOld = NULL;
      VERIFY ( wndProcOld = ( WNDPROC ) GetProp ( hWnd, _T("OldWndProc") ) );
      if ( !wndProcOld ) return 0;

      LRESULT lRes = 0;

      if ( msg == CB_SHOWDROPDOWN )
            // Show custom list control: this works fine
            return 0;
      if ( msg == CBN_CLOSEUP )
            // Hide custom list control.  This does not work!
            return 0;
      lRes = ::CallWindowProc ( wndProcOld, hWnd, msg, wp, lp );

      return lRes;

Clearly, I get the old window procedure that I have set in the combo box's property table, using it if necessary.  I find that whereas I receive the CB_SHOWDROPDOWN every time the combo is dropped down, I don't receive the CBN_CLOSEUP message.  In fact, I only ever receieve this message once - strangely enough when the combo is first dropped down.  As a consequence, I am finding it hard to know when to close my custom list.

How can I handle the combo being closed?

Question by:mrwad99
    LVL 43

    Expert Comment

    Is the following correct?

    When your list is shown it has the focus - right?
    So when the custom list loses the focus then it should be hidden (eg. user clicks elsewhere on the dialog, user has selected an entry)

    (I suspect the CBN_CLOSEUP is not being generated as you aren't using the listbox part of the combo, or do I misunderstand what you are doing.  Why you get it the very first time I am not certain.)
    LVL 43

    Accepted Solution

    Something (possibly) interesting in the help files:

    An application sends a CB_SHOWDROPDOWN message to show or hide the list  box of a combo box that has the CBS_DROPDOWN or CBS_DROPDOWNLIST style.  
    To send this message, call the SendMessage  function as follows.        Copy Code lResult = SendMessage(     // returns BOOL in lResult    (HWND) hWndControl,     // handle to destination control    (UINT) CB_SHOWDROPDOWN,     // message ID    (WPARAM) wParam,     // = (WPARAM) (BOOL) wParam;   (LPARAM) lParam     // = 0; not used, must be zero);
    Parameters  wParam Specifies whether the drop-down list box is to be shown or hidden. A value  of TRUE shows the list box; a value of FALSE hides it.  lParam This parameter is not used.
    LVL 19

    Author Comment

    Hi Andy, I hope you are well.

    I am still having major problems with this.  To answer your question, yes, that is correct: when the combo is dropped down, I display my own special window, which is, in essence, the skinned list control.  (see the article on codeproject).  I have uploaded a simple project to demonstrate this (; you might even find it useful for your own code one day.  Click the skin windows button, then drop down the combo.  All of the code handling the combo is at the top of Skinner.cpp in the custom window procedure.  I am aware you might be busy, so provide the link for anyone else that may be interested.

    Let me know if you take a look and have any ideas please.

    LVL 43

    Expert Comment

    OK, I've downloaded and had a quick compile and run.

    Before skinning I can drop and close the combo without problems.  After skinning I can only drop it and close it once, the second attempt just results in only the frame being shown when dropped (no list contents), when closing the frame just shrinks a little.  That makes me think your cleanup from the first drop/close is buggy, which might result in the bad behaviour on later drops/closes.
    LVL 19

    Author Comment

    Thanks Andy.  After much playing, I needed to handle the CB_SHOWDROPDOWN as you suggested.  It turns out that the dialog was sending this message as you described, which was what was causing the standard list to be hidden.  When I started handling this, it all worked fine.

    A summary of how to deal with this, for future searches is:

    If receive CBN_DROPDOWN, WM_LBUTTONDOWN, then show the custom list.

    If receive CB_SHOWDROPDOWN with a WPARAM of TRUE, then show the custom list.

    If receive a WM_WINDOWPOSCHANGING, A CBN_CLOSEUP, or a CB_SHOWDROPDOWN with a WPARAM of FALSE, then hide the list.

    The caveat to the latter is that a CBN_CLOSEUP will be sent the very first time the list is dropped, so the best thing to do is ignore it just the first time.

    Thanks again :o)

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How your wiki can always stay up-to-date

    Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
    - Increase transparency
    - Onboard new hires faster
    - Access from mobile/offline

    Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
    Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
    This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
    This video is in connection to the article "The case of a missing mobile phone (". It will help one to understand clearly the steps to track a lost android phone.

    761 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    6 Experts available now in Live!

    Get 1:1 Help Now