Catching when user selects an item from a CComboBox

好久不见. 提交于 2019-12-01 15:55:58

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!