IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo

FAQ VC++ et MFCConsultez toutes les FAQ

Nombre d'auteurs : 20, nombre de questions : 545, dernière mise à jour : 5 avril 2013  Ajouter une question

 

Cette faq a été réalisée pour répondre aux questions les plus fréquement posées sur le forum Développement Visual C++

Je tiens à souligner que cette faq ne garantit en aucun cas que les informations qu'elle contient sont correctes ; Les auteurs font le maximum, mais l'erreur est humaine. Si vous trouvez une erreur, ou si vous souhaitez devenir redacteur, lisez ceci.

Sur ce, je vous souhaite une bonne lecture. Farscape

SommaireContrôlesCComboBox (12)
précédent sommaire suivant
 

L'insertion peut se faire simplement avec la fonction AddString .
Si la combobox n'a pas le style CBS_SORT la chaîne est insérée en fin de liste.
Cette fonction renvoie le numéro d'item dans la liste box la première démarrant à zéro.

Code c++ : Sélectionner tout
1
2
3
  
CComboBox::AddString 
int AddString( LPCTSTR lpszString );
Code c++ : Sélectionner tout
1
2
3
4
5
6
7
8
  
CString str; 
int nIndex; 
for (int i=0;i < 20;i++) 
{ 
   str.Format("Ma chaîne %d"), i); 
   nIndex=MyComboBox.AddString( str ); 
}
Autre fonction utilisable:

Code c++ : Sélectionner tout
1
2
3
  
CComboBox::InsertString 
int InsertString( int nIndex, LPCTSTR lpszString );
même chose que AddString mais ici on précise l'emplacement avec l'argument nIndex.
Si nIndex == -1 l'insertion se fait en bout de liste .

Mis à jour le 5 avril 2013 farscape

Code c++ : Sélectionner tout
1
2
3
  
CComboBox::SetCurSel 
int SetCurSel( int nSelect );
La valeur retournée est l'indice de l'élément sélectionné si la commande réussit,
Sinon elle renvoie CB_ERR pour indiquer une erreur,
Si nSelect est égal à -1 la sélection en cours est supprimée et le retour sera aussi CB_ERR.
Exemple sélection du dernier élément de la combobox.

Code c++ : Sélectionner tout
1
2
3
  
int nCount = MyComboBox.GetCount(); 
if (nCount > 0) MyComboBox.SetCurSel(nCount-1);
Pour la sélection en fonction d'une chaîne de caractère utiliser :SelectString qui est la combinaison de FindString et SetCurSel.

Mis à jour le 5 avril 2013 farscape

Pour changer la couleur dans une «Combobox» il faut reprendre la main sur la fonction « DrawItem »:
Il faudra générer une classe de type CComboBox avec l'aide de « classwizard » et générer la fonction DrawItem .

Exemple de traitement standard sur la gestion des couleurs à modifier selon vos besoins:

Code c++ : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
  
void CMyComboBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)  
{ 
    // TODO: Add your code to draw the specified item 
    ASSERT(lpDrawItemStruct->CtlType == ODT_COMBOBOX); 
    // permet dans le cas ou le contrôle est chargé dans l'éditeur de ressources  
    //d'initialisé itemdata correctement 
    // m_bInit:variable de type bool a mettre a true dans le constructeur. 
    if(m_bInit && (GetStyle() & CBS_HASSTRINGS))  
    { 
        for(int i=0;i<GetCount() ;i++) SetItemData(i,i); 
    } 
    m_bInit=false; 
    LPCTSTR lpszText=NULL ; 
    CString str; 
    // si le style est <> de CBS_HASSTRINGS on considère que la valeur à afficher  
    //est dans ItemData. 
    if(lpDrawItemStruct->itemID!=CB_ERR && !(GetStyle() & CBS_HASSTRINGS)) 
        lpszText=(LPCTSTR) lpDrawItemStruct->itemData; 
    else 
    { 
        // Récupération de la chaîne grâce à l'index stocké dans ItemData. 
        GetLBText(lpDrawItemStruct->itemData,str); 
        lpszText= str; 
    } 
    ASSERT(lpszText != NULL); 
    CDC dc; 
    dc.Attach(lpDrawItemStruct->hDC); 
    // Sauvegarde des anciennes valeurs 
    COLORREF crOldTextColor = dc.GetTextColor(); 
    COLORREF crOldBkColor = dc.GetBkColor(); 
    // Traitement couleurs quand l'item est sélectionné. 
    if ((lpDrawItemStruct->itemAction | ODA_SELECT) && 
      (lpDrawItemStruct->itemState  & ODS_SELECTED)) 
    { 
        // couleur d'ecriture 
        dc.SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT)); 
        // couleur de fond  
        dc.SetBkColor(::GetSysColor(COLOR_HIGHLIGHT)); 
        // pareil pour le fond. 
        dc.FillSolidRect(&lpDrawItemStruct->rcItem, 
            ::GetSysColor(COLOR_HIGHLIGHT)); 
    } 
    else 
    { 
        // couleur de fond de la zone hors sélection 
        dc.FillSolidRect(&lpDrawItemStruct->rcItem, crOldBkColor); 
    } 
    // ecriture du texte. 
    dc.DrawText( 
      lpszText, 
      strlen(lpszText), 
      &lpDrawItemStruct->rcItem,DT_SINGLELINE); 
  
    // Restitution des valeurs d'origines 
    dc.SetTextColor(crOldTextColor); 
    dc.SetBkColor(crOldBkColor); 
    dc.Detach(); 
}
Lorsque l'on prend le contrôle sur l'affichage d'une combobox ou Listbox par la fonction « DrawItem » la récupération de la chaîne de caractère se fait par un cast de la zone ItemData que l'utilisateur remplit avec la fonction SetItemData.
Lorsque que le type CBS_HASSTRINGS ou LBS_HASSTRINGS est présent dans une listbox, le traitement standard met dans itemdata le numéro de l'index.
Pour éviter une assertion quand les valeurs sont remplies directement dans l'éditeur de ressources j'ai placé une boucle de remplissage de itemdata la première fois .
Pour gérer les couleurs il suffira de modifier le traitement standard des couleurs selon que l'item est sélectionné ou pas .

Mis à jour le 5 avril 2013 farscape

Récupération de l'indice de l'item en sélection :

Code c++ : Sélectionner tout
1
2
3
  
CComboBox::GetCurSel 
int GetCurSel( ) const;
Récupération d'une chaîne pour un numéro d'indice :

Code c++ : Sélectionner tout
1
2
3
4
  
CComboBox::GetLBText 
int GetLBText( int nIndex, LPTSTR lpszText ) const; 
void GetLBText( int nIndex, CString& rString ) const;
Code c++ : Sélectionner tout
1
2
3
4
5
  
CString str ; 
int nIndex = MyComboBox.GetCurSel(); 
if(nIndex!=LB_ERR) MyComboBox.GetLBText(nIndex,str); 
AfxMessageBox(str);

Mis à jour le 5 avril 2013 farscape

Code c++ : Sélectionner tout
1
2
3
  
CComboBox::FindString 
int FindString( int nStartAfter, LPCTSTR lpszString ) const;
La valeur retournée sera supérieure ou égale à zéro en case de succès sinon le retour vaudra CB_ERR .

nStartAfter
Contient la valeur de l'index du premier élément où la recherche doit commencer
Quand la recherche atteint la fin de la combobox elle continue à partir du haut jusqu'à la valeur nStartAfter.
Si -1 la recherche démarrera à partir du début.

lpszString
Contient la chaîne terminée par un'\0' qui doit être recherchée.

Code c++ : Sélectionner tout
1
2
3
4
5
6
  
// selection de la chaîne ligne 1 
MyComboBox.SetCurSel(MyComboBox.FindString(0, “Ligne 1)); 
  
// que l'on peut aussi faire de la manière suivante: 
MyComboBox. SelectString(0,”Ligne 1);

Mis à jour le 5 avril 2013 farscape

Code c++ : Sélectionner tout
1
2
3
4
  
// prototype de la méthode: 
// CComboBox::DeleteString 
int DeleteString( UINT nIndex );
Code c++ : Sélectionner tout
1
2
3
4
5
6
7
  
for (int i=MyComboBox.GetCount()-1; i>=0 ;i--) 
{ 
   MyComboBox.DeleteString( i ); 
} 
// Ce même code peut être écrit de la manière suivante : 
MyComboBox.ResetContent() ;
Code c++ : Sélectionner tout
1
2
3
  
//CComboBox::ResetContent 
void ResetContent( );
Supprime tous les éléments de la combobox

Mis à jour le 7 juillet 2008 farscape

Dans l'éditeur de ressources sur les propriétés du combo box :
Sélectionner l'onglet général et mettre l'option drop list dans le champ type.
c'est tout.

Mis à jour le 5 avril 2013 farscape

La taille par défaut de la liste déroulante correspond à celle d'un élément, donnant ainsi l'impression qu'elle ne s'ouvre pas.
Son réglage se fait dans l'éditeur de ressources :
Sélectionner le contrôle ComboBox et cliquer sur la flèche de la liste, un rectangle montrant la hauteur de la liste apparaît, il suffit alors de lui régler sa taille avec la souris.

Mis à jour le 5 avril 2013 farscape

Il faut utiliser la classe CComboBoxEx :
D'abord déclarer un objet CImageList comme donnée membre de la classe parent.
Remplir la liste d'image avec des bitmaps ou des icônes.

Code c++ : Sélectionner tout
1
2
3
4
5
  
/*CImageList*/ m_ImageList.Create(16, 16, ILC_COLOR, 2, 2); 
m_ImageList.Add(&Bitmap1); 
m_ImageList.Add(&Bitmap2); 
m_ImageList.Add(&Bitmap3);
Après associer l'image à une item de la combobox:

Code c++ : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  
COMBOBOXEXITEM     cbi; 
CString            str; 
int                   i=0; 
  
cbi.mask = CBEIF_IMAGE | CBEIF_INDENT | CBEIF_OVERLAY | 
     CBEIF_SELECTEDIMAGE | CBEIF_TEXT; 
  
cbi.iItem = i; 
str.Format(_T("Item %02d"), i); 
cbi.pszText = (LPTSTR)(LPCTSTR)str; 
cbi.cchTextMax = str.GetLength(); 
cbi.iImage = 0; 
cbi.iSelectedImage = 1; 
cbi.iOverlay = 2; 
cbi.iIndent = 0;  
  
m_ComboEx.InsertItem(&cbi);
voir doc MSDN pour la description de la structure COMBOBOXEXITEM.

Mis à jour le 5 avril 2013 farscape

La création d'un objet CCombobox avec l'option dropdown ou simple initialise automatiquement un objet CEdit associé à la CComboBox.
Pour changer le comportement de cet Edit ( sous entendu fournir sa propre classe ) il faut subclasser l'édit de la combobox.

Pour cela il faudra créer une classe dérivée de la classe CComboBox et surcharger
la fonction PreSubclassWindow() .
Cette classe devra avoir comme donnée membre la classe CEdit personnalisée.
Enfin, l'identifiant de l'édit dans une CComboBox est 1001 ,il ne reste plus qu'à écrire le code suivant :

Code c++ : Sélectionner tout
1
2
3
4
5
6
  
void CMyCombo::PreSubclassWindow()  
{  
   m_MyEdit.SubclassDlgItem(1001, this);  
   CComboBox::PreSubclassWindow();  
}

Mis à jour le 20 mai 2006 farscape

Dans le cas d'une combobox de type Dropdown (et uniquement dans ce cas), le plus simple est de créer une variable de contrôle associée à la combobox puis de procéder ainsi :

Code C++ : Sélectionner tout
1
2
3
4
5
// Mettre la combobox en lecture seule : 
CEdit *pEdit = static_cast<CEdit*> (m_maCombo.GetWindow (GW_CHILD)); 
  
if (pEdit) 
    pEdit->SetReadOnly(TRUE);

Pour retirer le mode de lecture seule à la combobox, il suffit de faire pareil en passant FALSE à la méthode SetReadOnly.

Dans le cas d'une combobox de type Droplist ou Simple, ou si l'on préfère ne pas se préoccuper du type de la combobox (la méthode décrite ci-après fonctionne dans tous les cas), il faudra créer une nouvelle classe, dérivée de CComboBox.
Dans cette nouvelle classe, on redéfinira la méthode PreSubclassWindow de façon à pouvoir prendre le contrôle du CEdit de la combobox comme décrit dans la FAQ Comment prendre le contrôle du CEdit d'une CComboBox ?.
À noter qu'un CEdit n'est associé à la combobox que dans le cas des types Dropdown et Simple.
On définira aussi une méthode SetReadOnly qui fera le nécessaire pour mettre la combobox en lecture seule. Il faudra également intercepter les messages de changement de sélection dans la liste, dans la méthode OnCmdMsg, de façon à annuler ces changements lorsque la combobox est en lecture seule.
La classe CComboBoxLS (LS pour Lecture Seule) proposée ci-dessous fait tout cela, avec en plus la perte de la propriété TabStop lorsque la combobox est en lecture seule (on ne peut plus accéder au contrôle avec la touche de tabulation).

Dans le .h :

Code C++ : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
class CComboBoxLS : public CComboBox 
{ 
#pragma region Attributs 
protected : 
    /// <summary>Index de la sélection dans la liste.</summary> 
    int m_posSel; 
  
    /// <summary>Indique si la combobox est en lecture seule ou non.</summary> 
    bool m_lectureSeule; 
  
    /// <summary>Indique si la combobox a l'aspect grisé de la lecture seule ou non.</summary> 
    bool m_grise; 
  
    /// <summary>Sauvegarde éventuelle du paramétrage Tabstop du contrôle.</summary> 
    bool m_tabStop; 
  
    /// <summary>Champ de saisie associé à la combobox.</summary> 
    CEdit m_edit; 
#pragma endregion 
  
#pragma region Constructeurs & destructeur 
public : 
    /// <summary>Construit une instance de combobox.</summary> 
    CComboBoxLS(); 
  
    /// <summary>Libère la mémoire occupée par l'objet.</summary> 
    virtual ~CComboBoxLS() {}; 
#pragma endregion 
  
#pragma region Accesseurs 
public : 
    /// <summary>Indique si la combobox est en lecture seule ou non.</summary> 
    /// <returns><c>TRUE</c> si la combobox est en lecture seule, <c>FALSE</c> sinon.</returns> 
    BOOL GetReadOnly() { return m_lectureSeule; }; 
  
    /// <summary>Change le mode d'accès à la combobox : lecture seule ou mode normal.</summary> 
    /// <param name='valeur'><c>TRUE</c> pour passer en lecture seule, <c>FALSE</c> pour passer en mode normal.</param> 
    /// <returns><c>TRUE</c> si la modification s'est correctement effectuée, <c>FALSE</c> si une erreur 
    /// est intervenue.</returns> 
    BOOL SetReadOnly(BOOL valeur = TRUE); 
#pragma endregion 
  
#pragma region Méthodes 
public : 
    /// <summary>Ajoute un élément à la fin de la liste déroulable.</summary> 
    /// <param name='texte'>Libellé de l'élément à ajouter.</param> 
    /// <returns>Position dans la liste de l'élément ajouté, ou <c>CB_ERR</c> en cas d'échec de l'ajout, 
    /// ou <c>CB_ERRSPACE</c> si l'espace est insuffisant dans la liste pour ajouter l'élément.</returns> 
    int AddString(LPCTSTR texte); 
  
    /// <summary>Ajoute un élément à la liste déroulable à une position donnée.</summary> 
    /// <param name='index'>Index (en base 0) de l'élément à insérer, ou <c>-1</c> pour l'ajouter en fin de liste.</param> 
    /// <param name='texte'>Libellé de l'élément à ajouter.</param> 
    /// <returns>Position dans la liste de l'élément inséré, ou <c>CB_ERR</c> en cas d'échec de l'insertion, 
    /// ou <c>CB_ERRSPACE</c> si l'espace est insuffisant dans la liste pour ajouter l'élément.</returns> 
    int InsertString(int index, LPCTSTR texte); 
  
    /// <summary>Change la sélection de la combobox en fonction de l'index passé en paramètre.</summary> 
    /// <param name='index'>Index (en base 0) de l'élément à sélectionner, ou <c>-1</c> pour ne rien 
    /// sélectionner.</param> 
    /// <returns>Index (en base 0) de la nouvelle sélection, ou <c>CB_ERR</c> si la sélection a échoué 
    /// ou si aucun élément n'a été sélectionné.</returns> 
    int SetCurSel(int index) 
    { 
        m_posSel = CComboBox::SetCurSel(index); 
        return m_posSel; 
    }; 
  
    /// <summary>Recherche dans la liste un libellé commençant par la chaîne de caractères passée en paramètre. 
    /// Si un libellé est ainsi trouvé, l'élément correspondant dans la liste est sélectionné.</summary> 
    /// <param name='posDepart'>Index de départ de la recherche (en base 0). <c>-1</c> pour une recherche 
    /// dans toute la liste.</param> 
    /// <param name='texte'>Chaîne de caractères devant correspondre au moins au début du libellé recherché.</param> 
    /// <returns>Index de l'élément sélectionné si le libellé a été trouvé, ou <c>CB_ERR</c> en cas d'échec 
    /// de la recherche.</returns> 
    int SelectString(int posDepart, LPCTSTR texte); 
  
    /// <summary>Supprime un élément de la liste en fonction de sa position.</summary> 
    /// <param name='index'>Index (en base 0) de l'élément à supprimer.</param> 
    /// <returns>Nombre d'éléments restant dans la liste (si <c>>= 0</c>), ou <c>CB_ERR</c> si l'élément 
    /// recherché n'a pas été trouvé.</returns> 
    int DeleteString(UINT index); 
  
    /// <summary>Vide la liste déroulable de tous ses éléments.</summary> 
    void ResetContent() 
    { 
        CComboBox::ResetContent(); 
        SetLectureSeule(); 
    }; 
  
protected : 
    DECLARE_MESSAGE_MAP() 
  
    /// <summary>Change le mode d'accès à la combobox : lecture seule ou mode normal.</summary> 
    /// <param name='valeur'><c>true</c> pour passer en lecture seule, <c>false</c> pour passer en mode normal.</param> 
    /// <returns><c>true</c> si la modification s'est correctement effectuée, <c>false</c> si une erreur 
    /// est intervenue.</returns> 
    /// <remarks>Cette méthode est utilisée entre autres par <c>SetReadOnly</c>, qui, en plus, garde en mémoire 
    /// l'état de la combobox, ce qui n'est pas le cas de cette méthode.</remarks> 
    bool SetLectureSeule(bool valeur = true); 
  
    virtual void PreSubclassWindow() 
    { 
        m_edit.SubclassDlgItem(1001, this); 
        CComboBox::PreSubclassWindow(); 
    }; 
  
    afx_msg HBRUSH CtlColor(CDC *pDC, UINT /*nCtlColor*/); 
    virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo); 
#pragma endregion 
};

Dans le .cpp :

Code C++ : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include "ComboBoxLS.h" 
#pragma region Constructeurs & destructeur 
  
CComboBoxLS::CComboBoxLS() 
{ 
    m_posSel = -1; 
    m_lectureSeule    = m_grise = false; 
    m_tabStop        = true; 
} 
  
#pragma endregion 
  
#pragma region Accesseurs 
  
BOOL CComboBoxLS::SetReadOnly(BOOL valeur /*= TRUE*/) 
{ 
    bool val = (valeur == TRUE); 
  
    if (val == m_lectureSeule) 
        return TRUE; 
  
    BOOL resu = SetLectureSeule(val); 
  
    if (resu) 
        m_lectureSeule = val; 
  
    return resu; 
} 
  
#pragma endregion 
  
#pragma region Méthodes 
  
BEGIN_MESSAGE_MAP(CComboBoxLS, CComboBox) 
    ON_WM_CTLCOLOR_REFLECT() 
END_MESSAGE_MAP() 
  
int CComboBoxLS::AddString(LPCTSTR texte) 
{ 
    int resu = CComboBox::AddString(texte); 
  
    if ((resu != CB_ERR) && (resu != CB_ERRSPACE) && !m_lectureSeule && GetCount()) 
        SetLectureSeule(false); 
  
    return resu; 
} 
  
int CComboBoxLS::InsertString(int index, LPCTSTR texte) 
{ 
    int resu = CComboBox::InsertString(index, texte); 
  
    if ((resu != CB_ERR) && (resu != CB_ERRSPACE) && !m_lectureSeule && GetCount()) 
        SetLectureSeule(false); 
  
    return resu; 
} 
  
int CComboBoxLS::SelectString(int posDepart, LPCTSTR texte) 
{ 
    int resu = CComboBox::SelectString(posDepart, texte); 
  
    if (resu != CB_ERR) 
        m_posSel = resu; 
  
    return resu; 
} 
  
int CComboBoxLS::DeleteString(UINT index) 
{ 
    int resu = CComboBox::DeleteString(index); 
  
    if ((resu != CB_ERR) && !GetCount()) 
        SetLectureSeule(); 
  
    return resu; 
} 
  
bool CComboBoxLS::SetLectureSeule(bool valeur /*= true*/) 
{ 
    if (m_grise == valeur) 
        return true; 
  
    if (IsWindow(m_edit.m_hWnd) && !m_edit.SetReadOnly(valeur)) 
        return false; 
  
    if (IsWindow(m_hWnd)) 
        if (valeur) 
        { 
            m_tabStop = (GetStyle() & WS_TABSTOP)? true : false; 
            ModifyStyle(WS_TABSTOP, 0); 
        } 
        else if (m_tabStop) 
            ModifyStyle(0, WS_TABSTOP); 
  
    m_grise = valeur; 
    Invalidate();    // Déclenche la méthode CtlColor. 
    return true; 
} 
  
HBRUSH CComboBoxLS::CtlColor(CDC *pDC, UINT /*nCtlColor*/) 
{ 
    // Réglage de la couleur de fond en fonction du mode d'accès. 
    if (IsWindowEnabled() && !m_grise) 
    { 
        pDC->SetBkColor(GetSysColor(COLOR_WINDOW)); 
        return GetSysColorBrush(COLOR_WINDOW); 
    } 
    else 
    { 
        pDC->SetBkColor(GetSysColor(COLOR_BTNFACE)); 
        return GetSysColorBrush(COLOR_BTNFACE); 
    } 
} 
  
BOOL CComboBoxLS::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) 
{ 
    if (nCode == CBN_SELCHANGE) 
    { 
        // La notification CBN_SELCHANGE (changement de sélection dans la liste de la combobox) 
        // ne doit être envoyée à la fenêtre parent que dans le cas où la sélection a changé et où 
        // la combobox n'est pas en lecture seule. 
        int pos = GetCurSel(); 
  
        if (pos == m_posSel) 
        { 
            // La sélection n'a pas changé ; on n'envoie pas la notification. 
            ShowDropDown(FALSE); 
            return TRUE; 
        } 
  
        if (m_lectureSeule) 
        { 
            // La combobox est en lecture seule ; 
            // on annule la modification et on n'envoie pas la notification. 
            ShowDropDown(FALSE); 
            CComboBox::SetCurSel(m_posSel); 
            return TRUE; 
        } 
        else 
            // La combobox n'est pas en lecture seule ; 
            // on enregistre la nouvelle sélection, puis on envoie la notification. 
            m_posSel = pos; 
    } 
  
    // Transmission de la notification. 
    return CComboBox::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); 
} 
  
#pragma endregion
Utilisation : il suffit de créer une variable de contrôle de type CComboBoxLS associée à la combobox et d'utiliser la méthode SetReadOnly...

Mis à jour le 7 juillet 2008 farscape lucky PetitPapaNoël

D'origine, on ne peut définir le style d'une CComboBox que pendant la phase de développement, ainsi que la taille maximum de la liste.
Deux fonctions permettent de résoudre ce problème, sans avoir à créer une classe fille.
Le principe est de recréer une CComboBox avec les nouvelles propriétés qui remplacera la combo actuelle.

Je conseille de définir les propriétés suivantes de la CComboBox dans les ressources : DROPDOWN, VERTICALSCROLL

Code c++ : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
  
// From Paul S. Vickery 
BOOL MyClass::RecreateComboBox(CComboBox* pCombo, LPVOID lpParam/*=0*/) 
{ 
    if (pCombo == NULL) 
        return FALSE; 
    if (pCombo->GetSafeHwnd() == NULL) 
        return FALSE; 
  
    CWnd* pParent = pCombo->GetParent(); 
    if (pParent == NULL) 
        return FALSE; 
  
    // get current attributes 
    DWORD dwStyle = pCombo->GetStyle(); 
    DWORD dwStyleEx = pCombo->GetExStyle(); 
    CRect rc; 
    pCombo->GetDroppedControlRect(&rc); 
    pParent->ScreenToClient(&rc);// map to client co-ords 
    UINT nID = pCombo->GetDlgCtrlID(); 
    CFont* pFont = pCombo->GetFont(); 
    CWnd* pWndAfter = pCombo->GetNextWindow(GW_HWNDPREV); 
  
    // get the currently selected text (and whether it is a valid list selection) 
    CString sCurText; 
    int nCurSel = pCombo->GetCurSel(); 
    BOOL bItemSelValid = nCurSel != -1; 
    if (bItemSelValid) 
        pCombo->GetLBText(nCurSel, sCurText); 
    else 
        pCombo->GetWindowText(sCurText); 
  
    // copy the combo box items into a temp combobox (not sorted) 
    // along with each item's data 
    CComboBox comboNew; 
    if (! comboNew.CreateEx(dwStyleEx, _T("COMBOBOX"), _T(""),  
        dwStyle, rc, pParent, nID, lpParam)) 
        return FALSE; 
    comboNew.SetFont(pFont); 
    int nNumItems = pCombo->GetCount(); 
    for (int n = 0; n < nNumItems; n++) 
    { 
        CString sText; 
        pCombo->GetLBText(n, sText); 
        int nNewIndex = comboNew.AddString(sText); 
        comboNew.SetItemData(nNewIndex, pCombo->GetItemData(n)); 
    } 
    // re-set selected text 
    if (bItemSelValid) 
        comboNew.SetCurSel(comboNew.FindStringExact(-1, sCurText)); 
    else 
        comboNew.SetWindowText(sCurText); 
  
    // destroy the existing window, then attach the new one 
    pCombo->DestroyWindow(); 
    HWND hwnd = comboNew.Detach(); 
    pCombo->Attach(hwnd); 
  
    // position correctly in z-order 
    pCombo->SetWindowPos(pWndAfter == NULL ?  
        &CWnd::wndBottom :  
    pWndAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 
    return TRUE; 
}
Code c++ : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  
// From Unknown :? 
void MyClass::set_DropDownSize(CComboBoxExt& box, UINT LinesToDisplay) 
{ 
    ASSERT(IsWindow(box));// Window must exist or SetWindowPos won't work 
  
    CRect cbSize;// current size of combo box 
    int Height;            // new height for drop-down portion of combo box 
  
    box.GetClientRect(cbSize); 
    Height = box.GetItemHeight(-1);      // start with size of the edit-box portion 
    Height += box.GetItemHeight(0) * LinesToDisplay;// add height of lines of text 
  
    // Note: The use of SM_CYEDGE assumes that we're using Windows '95 
    // Now add on the height of the border of the edit box 
    Height += GetSystemMetrics(SM_CYEDGE) * 2; // top & bottom edges 
  
    // The height of the border of the drop-down box 
    Height += GetSystemMetrics(SM_CYEDGE) * 2; // top & bottom edges 
  
    // now set the size of the window 
    box.SetWindowPos(NULL,            // not relative to any other windows 
        0, 0,                         // TopLeft corner doesn't change 
        cbSize.right, Height,         // existing width, new height 
        SWP_NOMOVE | SWP_NOZORDER     // don't move box or change z-ordering. 
        ); 
}

Mis à jour le 20 mai 2006 bizulk

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.