views:

293

answers:

1

I have a CListCtrl class and at the moment when a user selects one of the sub items I am displaying a CComboBox over the subitem which the user can then make a selection from.

However I have a problem. When the user has made a selection i need the combo box to disappear (ie intercept CBN_SELCHANGE). The problem is that I need to make the CComboBox a child of the CListCtrl (Otherwise I get weird problems with the list drawing over the combo box even if i set the combo box to be topmost). So the CBN_SELCHANGE message gets sent to the list view which, understandably, ignores it. How can I get the list view to pass that message up to the parent window.

Do I really need to derive my own CListCtrl class that simply intercepts the CBN_SELCHANGE message and passes it up to the parent window? Is there a better way to do this than creating an OnWndMsg handler?

Thanks for any help!

Edit: This code works

class CPassThroughListCtrl : public CListCtrl
{
protected:
    virtual BOOL OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
    {
     if ( message == WM_COMMAND )
     {
      GetParent()->SendMessage( message, wParam, lParam );
     }
     return CListCtrl::OnWndMsg( message, wParam, lParam, pResult );
    }
public:
    CPassThroughListCtrl()
    {
    };
};

But i'd really like to know if there is a nicer way to do this.

+1  A: 

You can subclass CComboBox such that it will handle CBN_CLOSEUP message. Your custom Combo will know about the manager i.e. the object that created it in the first place and will have to destroy it upon close up (top level window or whatever, should be provided as an argument to your custom combobox constructor)... So when you create combobox on a top of the list item you will create instance of this customized combobox instead of the MFC default one. Combobox event handler could look like that:

BEGIN_MESSAGE_MAP(CNotifyingComboBox, CComboBox)
 ON_CONTROL_REFLECT(CBN_CLOSEUP, OnCloseUp)
END_MESSAGE_MAP()

void CNotifyingComboBox::OnCloseUp()
{
    // _manager is pointer to the object that created this combobox, 
    // and is responsible for its destruction, 
    // should be passed into CNotifyingComboBox cosntructor
    if( NULL != _manager )
    {
        _manager->OnCloseUpComboBox(this);
    }
}
BostonLogan
While its not a bad suggestion I still end up creating a custom class that has little use outside of the specific situation. Furthermore when you say Subclass the window I take it you don't mean using the SubclassWindow function? I am left wondering if using a genuine subclasing of the window if i could intercept the message. Shame I've neer got window subclassing to work (
Goz
No by subclassing I mean no more than this :-) :class CNotifyingComboBox : public CComboBox
BostonLogan
So alas I'm still back to square one, ie creating a class that is only used in these specific circumstances. That said your combo box has the advantage that I can override the drawing and fit it into a list view sub item :)
Goz
TBH I'm using the scheme i put in my OP, but i'm gonna accept this post anyway :)
Goz