tags:

views:

300

answers:

2

This is as basic as it gets.

I want to catch when the user selects an item from a CComboBox (actually, a subclass of CComboBox).

Tried lots of combinations of OnCblSelChange, OnCommand. Guess I haven't hit the right combo yet (no pun intended).

OS is Vista but I'm forcing an XP-style dialog (That shouldn't matter, should it?)

I'm able to catch events for classes derived from CEdit and CFileDialog.

I am at my wits end here. Any assistance would be ever-so appreciated.

Any source code would, of course, be more than ever-so appreciated.

+1  A: 

CBN_SELENDOK should be the message that you're looking for. It's sent after the user selection is finalized but before the combo box closes up (if it does). CBN_SELCHANGE is sent before the selection is actually saved to the combo box control.

This MSDN link has more information (you've likely seen it already...)

Here is the code I promised you. One thing I noticed when gathering this up is that it is possible to have this message suppressed if you are using an ON_CONTROL_REFLECT handler within the class derived from CComboBox. This would cause the control itself to handle the message and not pass it on to the parent. You can get around that problem by using ON_CONTROL_REFLECT_EX with the proper return code, which will make both the box itself and the parent receive the message.

Anyway, here's the code snippet:

class SPC_DOCK_CLASS ProcessingExceptionDockDlg : public CSPCDockDialog
{
    SPC_DOCK_DECLARE_SERIAL(ProcessingExceptionDockDlg);

public:
    // ... redacted ...

    //{{AFX_DATA(ProcessingExceptionDockDlg)
    CComboBox     m_comboFilter;
    //}}AFX_DATA

    //{{AFX_VIRTUAL(ProcessingExceptionDockDlg)
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);
    //}}AFX_VIRTUAL

protected:

    //{{AFX_MSG(ProcessingExceptionDockDlg)
    afx_msg void OnSelendokComboTreeFilter();
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

/****************/

// ProcessingExceptionDockDlg.cpp : implementation file
//

#include "stdafx.h"
#include "resource.h"
#include "ProcessingExceptionDockDlg.h"

// ... much code redacted ...

void ProcessingExceptionDockDlg::DoDataExchange(CDataExchange* pDX)
{
    CSPCDockDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(ProcessingExceptionDockDlg)
    DDX_Control(pDX, IDC_COMBO_TREE_FILTER, m_comboFilter);
    //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(ProcessingExceptionDockDlg, CSPCDockDialog)
    //{{AFX_MSG_MAP(ProcessingExceptionDockDlg)
    ON_CBN_SELENDOK(IDC_COMBO_TREE_FILTER, OnSelendokComboTreeFilter)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

void ProcessingExceptionDockDlg::OnSelendokComboTreeFilter() 
{
    // ... code redacted ...
}
mwigdahl
Thanks. Tried CBN_SELENDOK but still no luck. Sure I'm missing something fundamental. Anyone out there have a code sample?
I'll try to scare one up and post it tomorrow when I get into work.
mwigdahl
Thanx for your sample. I did not know about the DoDataExchange stuff. I tried it and still can't catch the dropdown changed/selected event(s?) but the DoDataExchange will give me additional avenues to explore. It's gotta be something dumbbutt-simple I'm overlooking.
A: 

Unfortunately, it seems that all messages (even SELEND_OK) for combo box changing are sent before the text has actually changed, so DoDataExchange will give you the previous text in the CComboBox. I have used the following method, as suggested by MSDN:

void MyDialog::DoDataExchange(CDataExchange* pDX)
{
    DDX_Text(pDX, IDC_COMBO_LOCATION, m_sLocation);
    CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(MyDialog, CDialog)
    ON_CBN_SELENDOK(IDC_COMBO1, &MyDialog::OnComboChanged)
    ON_CBN_EDITUPDATE(IDC_COMBO1, &MyDialog::OnComboEdited) // This one updates immediately
END_MESSAGE_MAP()

...

void MyDialog::OnComboChanged()
{
    m_myCombo.GetLBText(m_myCombo.GetCurSel(), m_sSomeString);
}

void MyDialog::OnComboEdited()
{
    UpdateData();
}

It seems to work quite nicely.

Smashery