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
- Comment remplir une CCombobox ?
- Comment sélectionner une ligne dans une CComboBox ?
- Comment changer la couleur d'un élément dans une CComboBox ?
- Comment récupérer la valeur de la sélection en cours dans une CComboBox ?
- Comment retrouver l'indice d'une ligne en fonction d'une chaîne de caractère dans une CCombobox ?
- Comment supprimer une ligne dans une CComboBox ?
- Comment empêcher la saisie dans un CComboBox ?
- Comment régler la liste déroulante d'une CComboBox ?
- Comment insérer une image dans une CComboBox ?
- Comment prendre le contrôle du CEdit d'une CComboBox ?
- Comment définir une CComboBox en lecture seule dynamiquement ?
- Comment changer le style et la hauteur de la liste d'une CComboBox
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 ); } |
Code c++ : | Sélectionner tout |
1 2 3 | CComboBox::InsertString int InsertString( int nIndex, LPCTSTR lpszString ); |
Si nIndex == -1 l'insertion se fait en bout de liste .
Code c++ : | Sélectionner tout |
1 2 3 | CComboBox::SetCurSel int SetCurSel( int nSelect ); |
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 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 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 .
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; |
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); |
Code c++ : | Sélectionner tout |
1 2 3 | CComboBox::FindString int FindString( int nStartAfter, LPCTSTR lpszString ) const; |
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”); |
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( ); |
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.
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.
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); |
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); |
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(); } |
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 |
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. ); } |
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 çaLes 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.