2009-09-22 8 views
27

Voglio eseguire del codice quando l'utente seleziona una riga in una CListCtrl (visualizzazione report, non mi interessa circa le altre modalità di visualizzazione).Come rilevare una modifica alla selezione di CListCtrl?

Come faccio a prendere questo evento? c'è qualche messaggio che posso mappare o un metodo come "OnSelectionChanged" o qualcosa del genere?

risposta

38

correlate:

BEGIN_MESSAGE_MAP(cDlgRun, CDialog) 
    ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST2, OnItemchangedList2) 
END_MESSAGE_MAP() 

/* ... */ 

void cDlgRun::OnItemchangedList2(NMHDR* pNMHDR, LRESULT* pResult) 
{ 
    NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; 

    if ((pNMListView->uChanged & LVIF_STATE) 
     && (pNMListView->uNewState & LVIS_SELECTED)) 
    { 
     // do stuff... 
    } 
} 
+1

Questo non prenderà un cambiamento quando selezioni tre elementi con shift, ma poi ne selezioni uno (che deseleziona gli altri due, ma mantiene selezionato quello). Qualche soluzione per questo tranne mantenere un elenco di elementi selezionati? –

+0

Al momento non riesco a testarlo, ma penso che dovrai prendere la deselezione e anche la selezione: per catturare la deselezione basta usare 'if ((pNMListView-> uChanged & LVIF_STATE) && (pNMListView-> uOldState & LVNI_SELECTED) &&! (PNMListView -> uNewState e LVNI_SELECTED)) ' – djeidot

+2

@djeidot: Grazie mille, mi ha aiutato. Se incorporato nella propria classe Control, questo potrebbe anche essere ridotto a ON_NOTIFY_REFLECT (LVN_ITEMCHANGED, & OnItemSelected) – mox

4

djeidot è proprio su.

Voglio solo aggiungere che non v'è alcuna OnSelectionChanged() perché il ListView supporta multi-selezione (anche se questo può essere disabilitata). Pertanto, un elenco a selezione singola ti invierà due eventi: Vecchio elemento non selezionato E Nuovo elemento selezionato.

9

ci sono un paio di notifiche basate su ciò che sta accadendo.

Se si seleziona un elemento e non è ancora selezionato, verrà inviata una notifica di modifica di LVIF_STATE: uNewState & LVIS_SELECTED. La voce appena selezionata sarà disponibile all'indirizzo:

pNMListView->iItem 

Se si seleziona una voce prima di selezionare un nuovo oggetto, si otterrà tre cambiamenti di stato:

Per prima cosa viene informato che la voce precedente messa a fuoco è perdere la concentrazione:

pNMListView->uOldState & LVIS_FOCUSED 

Poi vi verrà notificato che il vecchio articolo è stato selezionata:

pNMListView->uOldState & LVIS_SELECTED 

Infine, si otterrà il nuovo stato di selezione degli articoli:

pNMListView->uNewState & LVIS_SELECTED 

(di nuovo un'occhiata a iItem per la voce appena selezionata)

Così la trappola ci siamo imbattuti in è che, perché i risultati oggetto disattivazione nel due notifiche , stavamo facendo un sacco di elaborazione ripetitiva, a volte dannosa. Quello che abbiamo finito per fare solo in questo modo di elaborazione per il 2 ° messaggio (pNMListView->uOldState & LVIS_SELECTED), e saltando la stessa elaborazione dopo la perdita di notifiche di attivazione.

-1

Sul mio Visual Studio 2010, l'editor visuale dichiara una richiamata nel file di intestazione finestra come questa:

afx_msg void OnLbnSelchangeListOnvif(); 

e nel file di origine:

BEGIN_MESSAGE_MAP(CDialogOnvif, CDialog) 
    ON_LBN_SELCHANGE(IDC_LIST_ONVIF, &CDialogOnvif::OnLbnSelchangeListOnvif) 
END_MESSAGE_MAP() 

void CDialogOnvif::OnLbnSelchangeListOnvif() 
{ 
    // do stuff... 
} 
+2

Che funzionerà solo per le List Box (CListBox), non CListCtrl. –

Problemi correlati