Newsgroup: it.comp.lang.visual-basic
Titolo: help su listview e messaggio complicato

Ho un brutto problema con un messaggio per un ListView.
conoscendo il punto in cui faccio click col mouse dovrei risalire a quale
iteme subitem c'č "sotto".
so che c'č il messaggio LVM_SUBITEMHITTEST.
vi dico come ho proceduto, cosě se qualcuno conosce questo messaggio puň
correggermi (visto che tutti i risultati mi escono -1)...
all'evento mousemove del listview1 ho scritto
xx=x:yy=y
in modo tale da avere sempre le coordinate del punto in cui si trova il
mouse.
all'evento dblclick ho messo quanto segue:
pInfo.pt.x = xx
pInfo.pt.y = yy
' dpve pInfo č la struttura da passare a sendmessage, che contiene le
coordinate 8che gli do io) e i vari dati (che restituisce lui).
e quindi:
RetVal = SendMessage(ListView1.hwnd, LVM_SUBITEMHITTEST, 0&, pInfo)
quando vado a leggere RetVal, e i vari elementi di pInfo, perň, non mi esce
niente. a volte miesce -1, altre volte a pInfo.flag mi esce qualcosa  di
diverso, ma sempre senza che nessun altro elemento mi indichi su quale item
mi trovo.
secondo voi dove ho sbagliato?
la struttura l'ho dichiarata cosě
Public Type LVHITTESTINFO
    pt As POINTAPI
    flags As Long
    iItem As Long
    iSubItem As Long
End Type
le dichiarazioni delle costanti le ho prese da VB-Net e dovrebbero essere le
seguenti:
Public Const LVM_FIRST As Long = &H1000
Public Const LVM_HITTEST = (LVM_FIRST + 18)
Public Const LVM_SUBITEMHITTEST = (LVM_FIRST + 57)
un'ultima cosa.
su MSDN c'č scritto
LVM_SUBITEMHITTEST
    wParam = 0;
    lParam = (LPARAM)(LVHITTESTINFO FAR *)pInfo;
Parameters
pInfo
Address of an LVHITTESTINFO structure. The POINT structure within
LVHITTESTINFO should be set to the client coordinates to be hit-tested.
forse c'entra quel "FAR" o quell'asterisco...? boh...
aiutatemi, davvero, č molto importante e non so dove sbattere la capa...
grazie
mario

 ha scritto

probabilmente c'e' qc che non capisco. se ci puoi fare clic / doppio clic
vuol dire che l'elemento e' visibile. allora non basta qc come (il listview
ha fullrowselect=true, proprieta' di vb6):
Private Sub LV_BeforeLabelEdit(Cancel As Integer)
    Cancel = True
End Sub
Private Sub LV_Click()
    FileSelect
End Sub
Private Sub LV_DblClick()
    If chkExec.Value <> 1 Then Exit Sub
    Dim lRet As Long
    lRet = ShellExecute(Me.hwnd, vbNullString, _
    MyFile, vbNullString, "c:\", SW_SHOWNORMAL)
End Sub
Private Sub FileSelect()
    'On Error GoTo errman
    FName = LV.SelectedItem.Text
    MyFile = MyPath & FName
Exit Sub
errman: MsgBox Error
End Sub
?
ciao, a.

c'č un esempio su VBNet che sembra facilissimo e che ho riportato pari pari,
ma che neanche funziona.
su vbnet si parla della versione 4.7 di comctl32.dll e si dice che
"When using the VB5 control, enhanced Comctl32 functionality is only
available to users with comctl32.dll version 4.70 or greater installed. This
dll is typically installed with IE3.x or greater"
io sto usando VB6, quindi non dovrei avere problemi, č cosě?
grazie
mario

dietro front!!!!!!
sembra funzionare adesso... ::))))))
nonho manco capito che cosa avevo sbagliato, cmq un cavillino formale, tutto
qui... però avete notato quanto è bello quando alla fine riesci a venire a
capo di una cosa complicata... ihih mi sento proprio bene... ::))))) ehi
ma... sono quasi le 2 di notte... io vado a nanna...
bye
mario

 ha scritto

quando si parla delle versioni dei controlli comuni, il condizionale e'
obbligatorio. io ho vb6 ita sp3 su win2k ita sp1.
la possibilita' di selezionare la riga intera, a parte che non e' bruttina
come in gestione risorse, direi dia la possibilita' di beccare l'item anche
se clicchi su un subitem. almeno, l'ho fatto subito prima di postare ed e'
andata. francamente non so se la cosa funziona anche se viene evidenziato
solo l'item come in g.r., direi di no.
in vb5 la riga intera si seleziona con un qualche sendmessage che al limite
dovrei poterti trovare. ma con il 6 non dovrebbe servirti.
fa' sapere.
buona, a.

 mi trovo.
Se retval e' != 0 allora guarda dentro pInfo.
Fai la prova nell' evento MouseDown, poi ti sposterai quello che ti serve
nel DoubleClick:
Private Sub ListView1_MouseDown(Button As Integer, Shift As Integer, x As
Single, y As Single)
          Dim RetVal As Long
          Dim pInfo As LVHITTESTINFO
          pInfo.pt.x = ScaleX(x, vbTwips, vbPixels)
          pInfo.pt.y = ScaleX(y, vbTwips, vbPixels)
          RetVal = SendMessage(ListView1.hwnd, _
                                       LVM_SUBITEMHITTEST,  _
                                      0&, pInfo)
            // N.B.: la prima riga ha indice 0, il primo subitem anche
            Debug.Print pInfo.iItem, pInfo.iSubItem
End Sub
Non hai messo la dichiarazione che fai di SendMessage, ma immagino sia tipo
questa:
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
        ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam
As Any) As Long
Ciao
Aldo


allora, come vi avevo detto ci sono riuscito l'altro ieri notte.
praticamente l'erroe era proprio nella scala, twip, pixel, sta roba qua
insomma...
sull'esempio di vbnet c'era il passaggio in cui si convertiva da twip in
pixel, ma erano le 2 di notte e me l'ero perso... ::))))))
per il problema del fullrowselect, mi sembr adi capire che si tratti della
possibilita di selezionare una riga intera, ma non credo che si attinente al
mio caso, o non č cosě? nell'es. di vbnet ne parla, ma č un esempio
"duplice", e quindi le due parti (riga intera e selezione del subitem)
possono essere "separate".
in ogni caso funziona, č perfetto.
ah, č vero che nell'esempio vbnet usa mousedown, ma a me interessa sapere
quale subitem c'č sotto, solo quando si fa doppio click, e quindi mi č
sembrato inevitabile fare come ho fatto, e cioč tenere sempre "in caldo" i
valori di x e y usando mouse move, e poi recuperarli e convertirli quando
faccio dblclick. so che fa storcere il naso a chi dice che bisogna scrivere
meno codice possibile... ma č l'unico modo che ho trovato, tra parentesi č
veloce e non sbaglia mai.
un'ultima cosa. secondo voi č normale che un'operazione simile, che dovrebbe
essere "frequente" non avrebbe richiesto un'apposita funzione/comando del
VB, invece che tutta una complessa operazione via Api...??????? eh?????????
mario

 VB, invece che tutta una complessa operazione via Api...???????
eh?????????
sono contento che funzioni, ma non sono ancora sicuro di avere capito cosa
volevi ottenere con quel codice, e in che situazioni.

 veloce e non sbaglia mai.
Permettimi una considerazione, che non vuole vuole essere soltanto una
conversazione fra colleghi.
Non conosco l' esempio di vbnet pero' la scelta di tenere "in caldo", fa
fare del lavoro supplementare alla macchina. D' accordo che nello specifico
caso il lavoro extra e' poco, ma se lo stesso principio venisse applicato
sempre, sarebbe poco onesto poi dare la colpa a windows o a vb delle scarse
performances delle nostre applicazioni.
Termino con un' informazione di tipo tecnico.
Quando si fa un DblClick, questa e' la sequenza degli eventi:
MouseDown
MouseUp
Click
MouseMove
DblClick
MouseUp
Puo' essere utile tenerne conto.
Ciao
Aldo

 conversazione fra colleghi.
Oddio, adesso mi lincia !
Il "non" non c' entra!
Giuro che non e' un lapsus freudiano, ma sono stato imbrogliato da c+p e
backspace !
Ciao
Aldo

tanto non siamo colleghi... io questo lo faccio per hobby... io studio
legge... ::))))
eheh
mario

 volevi ottenere con quel codice, e in che situazioni.
in parole povere, ho un listview, con diverse colonne, nella prima ci sono
dei nomi di directory, nell'altra ci sono dei nomi di file zip, e nell'altra
ci sono dei nomi di file archiviati in questi file zip.
se faccio doppio click sulla prima, non mi succede niente;
sulla seconda, lui mi apre il file zip (con shellexecute - consiglio che
avevo chiesto in un post successivo);
sulla terza, lui mi estrae il file indicato.
bye
mario

0   = indice del subitem cliccato
Byee
Zeross

anche se devo dire la verità, mi piacerebbe essere chiamato "collega" da un
programmatore... ::)))))))
mario

è praticamente quella che ho fatto io... ::))))))
mario
grazie 1000 Zeross... in futuro approfitterò ancora della tua bravura...
::))))


So che hai gią risolto, ma ti propongo una mia soluzione che non fa uso di
API.
Supponiamo che la listview si chiami lvwMessaggi.
Innanzitutto dichiara due variabili.
Dim MainItem As ListItem
Dim SubItemIndex As Long
Quando fai doppio click vengono generati i seguenti eventi.
MouseDown
ItemClick
MouseUp
Click
DblClick
MouseUp
Con l'evento MouseDown catturi la colonna in cui hai cliccato.
Private Sub lvwMessaggi_MouseDown(Button As Integer, Shift As Integer, x As
Single, y As Single)
   Dim I As Long
   For I = 1 To lvwMessaggi.ColumnHeaders.Count
      With lvwMessaggi.ColumnHeaders(I)
         If y > .Position And y < .Position + .Width Then SubItemIndex = I
      End With
   Next I
End Sub
Con l'evento ItemClick catturi la riga in cui hai cliccato.
Private Sub lvwMessaggi_ItemClick(ByVal Item As MSComctlLib.ListItem)
   Set MainItem = Item
End Sub
Ora nell'evento DblClick puoi conosere il subitem.
Private Sub lvwMessaggi_DblClick()
    Item.SubItems(I) ' Qui ci fai quel che vuoi tu
End Sub

 So che hai già risolto, ma ti propongo una mia soluzione che non fa uso di

Complimenti. E' ingegnoso. L' unico difetto, se mi permetti, e' che il
codice rimane disperso in piu' eventi e nel codice di un form vero, con un
sacco di altra roba scritta, potrebbe risultare poco chiaro a distanza di
tempo.
Cmq, mi e' piaciuto. E' la dimostrazione che, se si vuole, quasi sempre si
puo' !
Ciao
Aldo

beh, certo è interessante... ne terrò conto.
grazie
mario