2009-11-10 5 views
1

J'ai une classe CListCtrl et au moment où un utilisateur sélectionne l'un des sous-éléments, j'affiche un CComboBox sur le sous-élément dont l'utilisateur peut ensuite faire une sélection.Intercepter des messages provenant d'un enfant d'un enfant avec MFC

Cependant, j'ai un problème. Lorsque l'utilisateur a fait une sélection j'ai besoin de la zone de liste déroulante pour disparaître (c'est-à-dire intercepter CBN_SELCHANGE). Le problème est que j'ai besoin de faire du CComboBox un enfant de CListCtrl (Sinon, j'ai des problèmes bizarres avec le dessin de la liste sur la liste déroulante même si je mets la combo box au sommet). Ainsi, le message CBN_SELCHANGE est envoyé à la vue liste qui, naturellement, l'ignore. Comment puis-je obtenir l'affichage de la liste pour transmettre ce message à la fenêtre parente.

Ai-je vraiment besoin de dériver ma propre classe CListCtrl qui intercepte simplement le message CBN_SELCHANGE et le transmet à la fenêtre parente? Y at-il une meilleure façon de faire cela que de créer un gestionnaire OnWndMsg?

Merci pour toute aide!

Edit: Ce code fonctionne

class CPassThroughListCtrl : public CListCtrl 
{ 
protected: 
    virtual BOOL OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult) 
    { 
     if (message == WM_COMMAND) 
     { 
      GetParent()->SendMessage(message, wParam, lParam); 
     } 
     return CListCtrl::OnWndMsg(message, wParam, lParam, pResult); 
    } 
public: 
    CPassThroughListCtrl() 
    { 
    }; 
}; 

Mais je voudrais vraiment savoir s'il y a une plus belle façon de le faire.

Répondre

1

Vous pouvez sous-classer CComboBox de manière à traiter le message CBN_CLOSEUP. Votre Combo personnalisé connaîtra le gestionnaire, c'est-à-dire l'objet qui l'a créé en premier lieu et devra le détruire lors de la fermeture (fenêtre de haut niveau ou autre, doit être fourni comme argument à votre constructeur combobox personnalisé) ... Ainsi, lorsque vous créez une zone de liste déroulante en haut de l'élément de liste, vous créez une instance de cette zone de liste déroulante personnalisée au lieu de la zone par défaut MFC. gestionnaire d'événements COMBOBOX pourrait ressembler à ça:

BEGIN_MESSAGE_MAP(CNotifyingComboBox, CComboBox) 
ON_CONTROL_REFLECT(CBN_CLOSEUP, OnCloseUp) 
END_MESSAGE_MAP() 

void CNotifyingComboBox::OnCloseUp() 
{ 
    // _manager is pointer to the object that created this combobox, 
    // and is responsible for its destruction, 
    // should be passed into CNotifyingComboBox cosntructor 
    if(NULL != _manager) 
    { 
     _manager->OnCloseUpComboBox(this); 
    } 
} 
+0

Bien que ce ne est pas une mauvaise suggestion je finis toujours par créer une classe personnalisée qui a peu en dehors de l'utilisation de la situation spécifique. En outre, quand vous dites Subclass la fenêtre que je prends, vous ne voulez pas dire utiliser la fonction SubclassWindow? Je me suis demandé si utiliser un sous-clasement de la fenêtre si je pouvais intercepter le message. Dommage que je n'ai jamais eu de sous-classes de fenêtres pour travailler ( – Goz

+0

Non par sous-classe je ne veux pas dire plus que :-): class CNotifyingComboBox: public CComboBox – BostonLogan

+0

Donc, hélas, je suis encore de retour à la case départ, c'est à dire créer une classe qui est seulement utilisé dans ces circonstances spécifiques. Cela dit, votre boîte combo a l'avantage que je peux remplacer le dessin et l'insérer dans un sous-élément de vue liste :) – Goz

Questions connexes