2009-03-30 6 views
6

Ceci est aussi basique que possible.Attraper lorsque l'utilisateur sélectionne un élément d'un CComboBox

Je veux attraper quand l'utilisateur sélectionne un élément d'un CComboBox (en fait, une sous-classe de CComboBox).

Beaucoup de combinaisons de OnCblSelChange, OnCommand ont été essayées. Je suppose que je n'ai pas encore frappé le bon combo (sans jeu de mots).

OS est Vista mais je forcer un dialogue de style XP (Cela ne devrait pas d'importance, devrait-il?)

Je suis capable d'attraper des événements pour les classes dérivées de CEdit et CFileDialog.

Je suis à bout de nerfs ici. Toute aide serait toujours appréciée.

Tout code source serait, bien sûr, plus que jamais apprécié.

+0

Code ajouté à ma réponse ci-dessous. J'espère que cela aide! – mwigdahl

Répondre

1

CBN_SELENDOK devrait être le message que vous cherchez. Il est envoyé après que la sélection de l'utilisateur est finalisée mais avant la fermeture de la combo (si c'est le cas). CBN_SELCHANGE est envoyé avant la sélection est en fait enregistrée dans le contrôle zone de liste déroulante.

This MSDN link a plus d'informations (vous avez probablement vu déjà ...)

Voici le code que je vous avais promis. Une chose que j'ai remarquée lors de la collecte est qu'il est possible de supprimer ce message si vous utilisez un gestionnaire ON_CONTROL_REFLECT dans la classe dérivée de CComboBox. Cela entraînerait le contrôle lui-même pour gérer le message et ne pas le transmettre au parent. Vous pouvez contourner ce problème en utilisant avec le bon code retour, ce qui fera à la fois la boîte elle-même et le parent de recevoir le message.

Quoi qu'il en soit, voici l'extrait de code:

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 ... 
} 
+0

Merci. Essayé CBN_SELENDOK mais toujours pas de chance. Bien sûr, il me manque quelque chose de fondamental. Quelqu'un a-t-il un échantillon de code? –

+0

Je vais essayer de faire peur et de poster demain quand je serai au travail. – mwigdahl

+0

Merci pour votre échantillon. Je ne connaissais pas le truc DoDataExchange. Je l'ai essayé et je n'arrive toujours pas à attraper l'événement dropdown/selected (s?) Mais le DoDataExchange me donnera des pistes supplémentaires à explorer. Ça doit être quelque chose de stupide-simple que je néglige. –

6

, il semble malheureusement que tous les messages (même SELEND_OK) pour zone de liste déroulante à langer sont envoyés avant le texte a réellement changé, DoDataExchange vous donnera la texte précédent dans le CComboBox. Je l'ai utilisé la méthode suivante, 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(); 
} 

Il semble fonctionner assez bien.

Questions connexes