Link to home
Start Free TrialLog in
Avatar of SiWix
SiWix

asked on

Listview control & LVM_GETNEXTITEM

'LVM_FIRST = &H1000
'LVM_GETNEXTITEM = (LVM_FIRST + 12)
'LVM_GETSELECTEDCOUNT = (LVM_FIRST + 50)
'LVNI_SELECTED = &H2
'listhwnd = handle to the listview control

sub test()

nTotal = sendmessage(listhwnd, LVM_GETSELECTEDCOUNT, 0, 0) - this returns the correct number of selected items.

for n=0 to nTotal -1
i=-1

i=sendmessage(listhwnd, LVM_GETNEXTITEM, i, LVNI_SELECTED)

'i always return -1, why?

next n

end sub

I'm trying to find all the selected items in a listview control. The listview control is in a different process.

I do not understand why i is always -1, LVM_GETNEXTITEM should return the next selected item in the list.
Avatar of Ryan Chong
Ryan Chong
Flag of Singapore image

What don't use ListView built-in methods to check whether an item is selected or not?

Anyway, try find some codes useful at:
http://www.mvps.org/vbnet/code/toc/tocbytopic_l.htm#ListView

regards
Avatar of SiWix
SiWix

ASKER

ryancys:  The listview control reside in a different process (application). I do not have a "listview1".

I refer to the listview through it's window handle (HWND), by using windows api - Sendmessage.

regards,
Stian
ASKER CERTIFIED SOLUTION
Avatar of Ark
Ark
Flag of Russian Federation image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of SiWix

ASKER

That's it!!!!

It works, just as you said.

The i=-1 was misplaced in the question.

I couldn't understand why the hell it worked using C, but not VB.

I definitely need a good Win32api book. I'll have a look at your recommendation.

What problems are you referring to, with regards to LV_ITEM. I can easily get the text from the listview, but yes I do have a problem. I have to make sure that the list is scrolled to the end, otherwise the LV_ITEM returns empty for non visible items. (ie only list items that have been visible is returned)


Thanks!
Thanks for points. Glad I could help you.
About difference in C and VB - C works with pointers easy, while VB doesn't. Take a look on SendMessage declaration:
'Normal' declaration,like in Api Viewer.

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Look, last parameter (lParam) is passing ByRef and without Type checking (as Any). Actually, in C it'd DWORD (long) - pointer to additional message info. When you use structure as lParam, everything is OK - you pass pointer to this structure ByRef. But when you pass long variable (LVNI_SELECTED in your case), SendMessage thing that this is a pointer (memory address = 2) and try to get anything there. So, you need force passing this value ByVal (like in my sample) or use 'TypeSafe" VB declaration:


Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Now about possible problems with passing structures to another processes. Each process have its own memory map. It means that memory used by process is "Virtual" memory, ie. memory address in one process may be same as in another process, but these processes store different variables at these addresses. Now look at SendMessage declaration again. When you send message to another process with structure pointer:
Dim li As LV_ITEM
SendMessage hLV, LVM_GETITEM, nItem, li
actually, you send to another process a pointer to LV_ITEM structure which another process should fill with data. But this pointer belong to your process and another process know nothing about it!. Same address in another process may be already in use and you'll get GPF. So, you need smth like "Interprocess memory communication". Under w9x/Me you can use upper memory (above 2GB limit). This virtual memory area is shareable for all application. You can allocate memory in this area via FileMapping API and pass to another process this memory address. Another process have access to this area, so it can fill it with data. Then you process can copy this memory to structure via rtlMoveMemory API. As for NT/2000/XP - there isn't shareable memory. But these OS have VirtualAllocateEx API which allow your process to allocate memory in different process. So, you allocate memory in different process, that process fill this memory with data and you can read this data from your process with ReadProcessMemory API.

Regards
Ark