[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Handling combo closing up in WindowProc!

Posted on 2009-02-19
5
Medium Priority
?
1,038 Views
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:

LRESULT CALLBACK CustomWndProc ( HWND hWnd, UINT msg, WPARAM wp, LPARAM lp )
{
      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?

TIA
0
Comment
Question by:mrwad99
  • 3
  • 2
5 Comments
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 23689593
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.)
0
 
LVL 45

Accepted Solution

by:
AndyAinscow earned 1000 total points
ID: 23690097
Something (possibly) interesting in the help files:

CB_SHOWDROPDOWN Message  
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.  
Syntax
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.
0
 
LVL 19

Author Comment

by:mrwad99
ID: 23692212
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 http://tinyurl.com/c4ug77 on codeproject).  I have uploaded a simple project to demonstrate this (http://www.yousendit.com/download/U0d5Wmdpd0lHa09Ga1E9PQ); 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.

Thanks.
0
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 23693240
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.
0
 
LVL 19

Author Comment

by:mrwad99
ID: 23700149
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)
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
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.
As many of you are aware about Scanpst.exe utility which is owned by Microsoft itself to repair inaccessible or damaged PST files, but the question is do you really think Scanpst.exe is capable to repair all sorts of PST related corruption issues?
Suggested Courses
Course of the Month18 days, 6 hours left to enroll

830 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