问题
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:
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.
回答2:
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 ...
}
来源:https://stackoverflow.com/questions/698910/catching-when-user-selects-an-item-from-a-ccombobox