Newsgroup: it.comp.programmare.win32
Titolo: Doc/View in VC++ con vista derivata dalla classe CListView

Ho creato un nuovo progetto con Visual C++ del tipo Document/View a singolo
documento. La classe vista che ho creato per la mia applicazione, l'ho
derivata dalla classe CListView.
In tal modo ho una vista con il controllo di tipo CListCtrl a cui quindi
posso aggiungere, modificare, eliminare elementi alla lista. Le operazioni
su tale controllo le so gestire, infatti basta utilizzare la funzione
GetListCtrl che mi restituisce il controllo di tipo lista e quindi si
possono effettuare tutte le operazioni su tale controllo utilizzando le
funzioni membro che consentono di aggiungere, eliminare elementi dalla
lista, ecc.
Il mio problema è come gestire gli eventi di tale controllo, cioè ad esempio
come intercettare l'evento selezione di un elemento del controllo lista,
ecc.
Grazie.

 come intercettare l'evento selezione di un elemento del controllo lista,
Il CListCtrl spedisce messaggi alla finestra che lo contiene (nel
tuo caso, quella della classe derivata da CListView) a fronte dei
vari eventi in questione; gestisci quei messaggi, e sei a posto.
(Il messaggio usato e` WM_NOTIFY, quindi userai il wizard per
aggiungere un OnChildNotify).
Ad esempio, la notifica di codice LVN_ITEMACTIVATE e` quella
che viene spedita quando un elemento e` attivato dall'utente, che
penso sia quello cui tu qui ti riferisci.
Alex

 penso sia quello cui tu qui ti riferisci.
Per attivazione di un elemento però si intende il click di un elemento e non
la selezione di un elemento. Cioè quando con il mouse ci si sposta sopra un
elemento, esso viene evidenziato cioè selezionato e non attivato (cioè
cliccato).
Qual è quindi il messaggio che consente di intercettare la selezione singola
(e NON l'attivazione) di un elemento?
Ho impostato anche l'attibuto LVS_EX_ONECLICKACTIVATE perchè di default
l'attivazione si ha con 2 click e non con 1.
Inoltre ho abilitato l'hot tracking cioè la selezione automatica al
passaggio del mouse mediante l'attributo  LVS_EX_TRACKSELECT:
l'hot tracking è abilitato, però l'elemento non viene attivato in modo
automatico, ma è sempre necessario effettuare un singolo click. Allora come
si fa?
(In Visual Basic era sufficiente attivare l'hottracking e con la selezione
automatica veniva generato automaticamente l'evento click).
Grazie.

 elemento, esso viene evidenziato cioè selezionato e non attivato (cioè
Allora penso che quel che tu desideri sia settare la
"callback mask" del tuo listview-control (inviando
il messaggio LVM_SETCALLBACKMASK al controllo, ad
esempio, ma anche chiamando la funzione membro
SetCallbackMask del tuo CListCtrl, se preferisci
lavorare a questo livello) in modo tale che comprenda
il bit LVIS_SELECTED; otterrai allora la notifica
LVN_GETDISPINFO per ciascun item posto in stato
"selected" (dovrai rispondere appropriatamente al
messaggio di notifica, naturalmente, ma mi sembra
sia la soluzione piu` vicina a quanto tu abbia in mente).
Alex

Non funziona! Nel senso che ottengo più messaggi di notifica nonostante sia
stato selezionato 1 solo elemento (ho potuto constatare che vengono inviati
più messaggi perchè quando faccio il test dell'arrivo del messaggio
LVN_GETDISPINFO ho inserito una istruzione di prova che mi mostra un
messaggio di testo).
Possibile che sia disponibile soltanto l'evento fornito dal messaggio
ITEMACTIVATE cioè attivazione di un elemento (che purtroppo non equivale
alla semplice selezione, ma invece al click di un elemento) e non esista un
messaggio del tipo "ITEMSELECTED" che sia in grado di fornire l'evento "è
stato selezionato un elemento".


 stato selezionato un elemento".
Non conosco un messaggio di notifica esattamente congruente con
quello che desideri, ma sarei stupito se non potessi ottenere lo
stesso effetto con l'opportuna callback mask e l'opportuno esame
della struttura LVITEM contenuta nell'NMLVDISPINFO che ti viene
spedito ad accompagnamento degli LVN_GETDISPINFO risultanti.
Alex





Alex, non riesco a "saltarci fuori", ti dico allora quello che 
ho scritto:


 


Ho inanzitutto settato la CallBackMask con:


 


CListCtrl& 
lstctrl=GetListCtrl();


lstctrl.SetCallbackMask(LVIS_SELECTED);


 


Poi ho aggiunto la seguente funzione:


 


BOOL CMyView::OnChildNotify(UINT message, WPARAM 
wParam, LPARAM lParam, LRESULT* pLResult){
 if 
(message==WM_NOTIFY){
  


       // 
puntatore alla struttura di tipo NMHDR che contiene informazioni di 
notifica 
       // riguardante la 
selezione di un elemento della lista
     
 
NMHDR* phdr = 
(NMHDR*)lParam; 
      if 
((phdr->code)==LVN_GETDISPINFO){  
         
   MessageBox("Selezionato!"); 
// messaggio di 
prova
  
    

}


 }


 
 return 
CListView::OnChildNotify(message, wParam, lParam, 
pLResult);
}


 


Come risultato però ottengo che vengono visualizzati più di 1 
messaggio, quando seleziono un elemento nella lista.


Dove ho sbagliato?



 wrote in message 8551jr$sl5$1...@nslave1.tin.it...
Per favore, NON postare in HTML, e` una scocciatura.
L'esempio HTML che posti non fa assolutamente nulla di quello che
ti ho consigliato l'ultima volta, cioe` di esaminare, ricevuta una
LVN_GETDISPINFO, da quale item ti giunga, quale sia lo stato di
quell'item, eccetera.  Al contrario, si limita a ribadire quello che
gia` dicevi al tuo messaggio precedente, cioe` che ti arrivano
molte notifiche (che non stai neppure cercando di discriminare)
per quella che per te e` una operazione di "selezione item".
Ripeto dunque lo stesso consiglio che ti ho dato la volta precedente.
E ti prego di non ribadire ulteriormente con lo stesso identico
codice senza neppure aver provato il mio consiglio, grazie:-).
Alex

Puoi scrivermi un esempio di codice?
Grazie.


 Puoi scrivermi un esempio di codice?
Avevo in mente qualcosa del tipo:
BOOL CLionView::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam,
LRESULT* pLResult)
{
    NMLVDISPINFO* pnmv = (NMLVDISPINFO*) lParam;
    if(message==WM_NOTIFY && pnmv->hdr.code==LVN_GETDISPINFO) {
        LV_ITEM& it = pnmv->item;
        if((it.mask&LVIF_STATE) && (it.stateMask&LVIS_SELECTED)) {
            it.state = it.stateMask = LVIS_SELECTED;
            char buf[80];
            wsprintf(buf,"Selected item %d\n", it.iItem);
            OutputDebugString(buf);
            return TRUE;
        }
    }
 return CListView::OnChildNotify(message, wParam, lParam, pLResult);
}
Neppure questo funziona molto bene, per quel poco che ho provato,
ma penso che la soluzione si possa probabilmente trovare lungo
queste linee.
Alex