| auteur : Farscape | Sur les propriétés de la CListBox, il suffit de mettre le type de sélection à :extended et les combinaisons de touches ctrl ou maj seront opérationnelles.
|
| auteur : Farscape | En utilisant la fonction GetCurSel qui renvoie l'indice courant sélectionné.
int nIndex = myListBox.GetCurSel ();
if ((nIndex ! = LB_ERR)) myListBox.DeleteString ( nindex );
|
|
| auteur : Farscape | Si on ne dispose pas du numéro index de la ligne il faudra la rechercher en utilisant la fonction FindString :
CListBox:: FindString
int FindString ( int nStartAfter, LPCTSTR lpszItem ) const ;
|
Exemple:
nIndex = myListBox.FindString (0 ," coucou " );
if ((nIndex ! = LB_ERR)) myListBox.DeleteString ( nindex );
|
|
| auteur : Farscape | Il suffit d'enlever la coche ?Sort ? sur les propriétés de la listbox dans l'éditeur de ressources.
|
| auteur : Farscape |
int nCount = MyListBox.GetCount ();
if (nCount > 0 ) MyListBox.SetCurSel (nCount- 1 );
|
|
| auteur : Farscape |
CListBox:: AddString
int AddString ( LPCTSTR lpszItem );
|
CString str;
for (int i= 0 ;i < 10 ;i+ + )
{
str.Format (_T (" item string %d " ), i);
MyListBox.AddString ( str );
}
|
|
| auteur : Farscape | Avec la fonction ResetContent( )
CListBox:: ResetContent
void ResetContent ( );
|
MyListBox.ResetContent ();
ASSERT (MyListBox.GetCount () = = 0 );
|
|
| auteur : Farscape | Avec la fonction GetText :
CListBox:: GetText
int GetText ( int nIndex, LPTSTR lpszBuffer ) const ;
void GetText ( int nIndex, CString& rString ) const ;
|
Exemple : récupérer le texte de la ligne sélectionnée:
CStrng str;
int nIndex = myListBox.GetCurSel ();
if ((nIndex ! = LB_ERR)) myListBox.GetText ( nindex,str );
AfxMessageBox (str);
|
|
| auteur : Farscape | En utilisant la fonction virtuelle DrawItem
CListBox:: DrawItem
virtual void DrawItem ( LPDRAWITEMSTRUCT lpDrawItemStruct );
|
Le style Owner Draw devra être sélectionné dans les propriétés de la ListBox et l'option HasString devra être cochée.
Il faudra bien sûr créer une classe dérivée de CListBox avec l'aide de ClassWizard et surcharger la fonction DrawItem toujours avec ClassWizard.
Exemple d'implémentation issue de la documentation MSDN :
Affichage du texte centré horizontalement.
void CMyListBox:: DrawItem (LPDRAWITEMSTRUCT lpDrawItemStruct)
{
ASSERT (lpDrawItemStruct- > CtlType = = ODT_LISTBOX);
LPCTSTR lpszText= NULL ;
CString str;
if (lpDrawItemStruct- > itemID! = CB_ERR & & ! (GetStyle () & LBS_HASSTRINGS))
lpszText= (LPCTSTR) lpDrawItemStruct- > itemData;
else
{
GetText (lpDrawItemStruct- > itemID,str);
lpszText= str;
}
ASSERT (lpszText ! = NULL );
CDC dc;
dc.Attach (lpDrawItemStruct- > hDC);
COLORREF crOldTextColor = dc.GetTextColor ();
COLORREF crOldBkColor = dc.GetBkColor ();
if ((lpDrawItemStruct- > itemAction | ODA_SELECT) & &
(lpDrawItemStruct- > itemState & ODS_SELECTED))
{
dc.SetTextColor (:: GetSysColor (COLOR_HIGHLIGHTTEXT));
dc.SetBkColor (:: GetSysColor (COLOR_HIGHLIGHT));
dc.FillSolidRect (& lpDrawItemStruct- > rcItem,
:: GetSysColor (COLOR_HIGHLIGHT));
}
else
dc.FillSolidRect (& lpDrawItemStruct- > rcItem, crOldBkColor);
if ((lpDrawItemStruct- > itemAction | ODA_FOCUS) & &
(lpDrawItemStruct- > itemState & ODS_FOCUS))
{
CBrush br (RGB (255 , 0 , 0 ));
dc.FrameRect (& lpDrawItemStruct- > rcItem, & br);
}
dc.DrawText (
lpszText,
strlen (lpszText),
& lpDrawItemStruct- > rcItem,
DT_CENTER| DT_SINGLELINE| DT_VCENTER);
dc.SetTextColor (crOldTextColor);
dc.SetBkColor (crOldBkColor);
dc.Detach ();
}
|
L'exemple ci-dessus montre entre autres qu'il sera très facile d'intervenir sur la couleur d'écriture de fond sur une ligne en sélection ou non.
|
| auteur : Farscape | En insérant dans la chaîne le caractère tabulation entre chaque portion et en appelant la fonction SetTabStop pour fixer les intervalles.
Il faut aussi coché l'option use tab stop sur le contrôle dans l'éditeur de ressources .
int tab_stop[2 ] = { 100 , 200 } ;
VERIFY (m_listbox.SetTabStops (2 , tab_stop));
m_listbox.AddString (" String1\tString2\tString3 " );
|
|
| auteur : Farscape | Le réglage de la hauteur pourra s'effectuer avec la fonction :
CListBox:: SetItemHeight
int SetItemHeight ( int nIndex, UINT cyItemHeight );
|
Dans le cas d'une Listbox classique l'argument nIndex n'est pas pris en compte et doit rester à zéro, l'ensemble des lignes de la Listbox aura la même hauteur.
Exemple :
CSize sz;
CDC* pDC = m_ListboxNormal.GetDC ();
m_ListboxNormal.GetText ( 0 , str );
CFont* pOldFont = pDC- > SelectObject (& m_Font);
sz = pDC- > GetTextExtent (str);
m_ListboxNormal.SetItemHeight (0 ,sz.cy* 2 );
pDC- > SelectObject (pOldFont);
m_ListboxNormal.ReleaseDC (pDC);
|
L'argument nIndex sera pris en compte avec une Listbox possédant le style LBS_OWNERDRAWVARIABLE, permettant ainsi de spécifier la hauteur de chaque ligne de la ListBox.
CString str;
CSize sz;
int dx= 0 ;
CDC* pDC = pmyListBox- > GetDC ();
for (int i= 0 ;i < pmyListBox- > GetCount ();i+ + )
{
pmyListBox- > GetText ( i, str );
sz = pDC- > GetTextExtent (str);
pmyListBox- > SetItemHeight ( i, sz.cy );
}
pmyListBox- > ReleaseDC (pDC);
|
Si la Listbox est LBS_OWNERDRAWFIXED SetItemHeight permettra de spécifier la hauteur pour l'ensemble des lignes de la Listbox .
Dans le cas où la listbox est LBS_OWNERDRAWVARIABLE nous disposons d'une autre possibilité pour spécifier la hauteur d'une ligne :
Redéfinir la fonction virtuelle MeasureItem avec l'aide de classwizard.
virtual void MeasureItem (LPMEASUREITEMSTRUCT lpMeasureItemStruct);
|
Exemple:
void CMyListBox:: MeasureItem (LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
CDC * pDC = GetDC ();
if (m_pFont)
{
CFont* pOldFont = pDC- > SelectObject (m_pFont);
TEXTMETRIC tm;
pDC- > GetTextMetrics (& tm);
lpMeasureItemStruct- > itemHeight = tm.tmHeight + tm.tmExternalLeading;
lpMeasureItemStruct- > itemHeight + = lpMeasureItemStruct- > itemHeight / 2 ;
pDC- > SelectObject (pOldFont);
}
ReleaseDC (pDC);
}
|
|
| auteur : Farscape |
La première réponse serait de faire :
MyListBox.ModifyStyle (WS_VSCROLL,0 );
MyListBox.ModifyStyle (0 ,WS_VSCROLL);
|
Malheureusement ça ne fonctionne pas,
la Listbox n'accepte pas les changements de style après sa création ,
Il faut donc la recréer pour que le style soit pris en compte.
On procédera par recopie des infos de l'objet à l'identique :
BOOL CMyListBox:: Recreate (LPVOID lpParam)
{
if (GetSafeHwnd () = = NULL )return FALSE;
CWnd* pParent = GetParent ();
if (pParent = = NULL ) return FALSE;
DWORD dwStyle = GetStyle ();
DWORD dwStyleEx = GetExStyle ();
CRect rc;
GetWindowRect (& rc);
pParent- > ScreenToClient (& rc);
UINT nID = GetDlgCtrlID ();
CFont* pFont = GetFont ();
CWnd* pWndAfter = GetNextWindow (GW_HWNDPREV);
CString sCurText;
int nCurSel = GetCurSel ();
BOOL bItemSelValid = nCurSel ! = - 1 ;
if (bItemSelValid)GetText (nCurSel, sCurText);
CMyListBox listboxNew;
if (! listboxNew.CreateEx (dwStyleEx, _T (" ListBox " ), _T (" " ),
dwStyle, rc, pParent, nID, lpParam))
return FALSE;
listboxNew.SetFont (pFont);
int nNumItems = GetCount ();
for (int n = 0 ; n < nNumItems; n+ + )
{
CString sText;
GetText (n, sText);
int nNewIndex = listboxNew.AddString (sText);
listboxNew.SetItemData (nNewIndex,GetItemData (n));
}
if (bItemSelValid)
listboxNew.SetCurSel (listboxNew.FindStringExact (- 1 , sCurText));
DestroyWindow ();
HWND hwnd = listboxNew.Detach ();
Attach (hwnd);
SetWindowPos (pWndAfter = = NULL ?
& CWnd:: wndBottom :
pWndAfter, 0 , 0 , 0 , 0 , SWP_NOMOVE | SWP_NOSIZE);
return TRUE;
}
|
|
| auteur : Farscape | Les propriétés sont modifiables en utilisant la fonction de la classe CWnd :ModifyStyle
qui permet de supprimer /d'ajouter en un seul appel des styles au contrôle.
MyListBox.ModifyStyle (LBS_SORT ,0 );
|
Les styles sont visibles dans l'aide MSDN sur la fonction create, on trouve un lien List-Box Styles.
|
Consultez les autres F.A.Q.
|
|