Capture when user selects item from CComboBox

It is as simple as he is.

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

I tried many combinations of OnCblSelChange, OnCommand. I think I haven’t hit the right combo yet (no pun intended).

The OS is Vista, but I force the XP-style dialog (it doesn't matter, does it?)

I can track events for classes derived from CEdit and CFileDialog.

I am here on my way. Any help would always be appreciated.

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

+6
mfc ccombobox
source share
2 answers

Unfortunately, it seems that all messages (even SELEND_OK ) to change the combo box are sent before the text really changes, so DoDataExchange will provide you with the previous text in CComboBox. I used the following method as suggested on 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 very well.

+6
source share

CBN_SELENDOK should be the message you are looking for. It is sent after the user selection is completed, but before the combo box is closed (if it is). CBN_SELCHANGE dispatched before the selection is actually stored in the list control.

This MSDN link contains more information (you probably already saw it ...)

Here is the code I promised you. One thing that I noticed when compiling is that this message can be suppressed if you use the ON_CONTROL_REFLECT handler in a class derived from CComboBox . This will cause the control to process the message and not pass it to the parent. You can work around this problem by using ON_CONTROL_REFLECT_EX with the correct return code, which will make the message both the window itself and the parent message.

In any case, here is 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 ... } 
+1
source share

All Articles