Solved

Listview control & LVM_GETNEXTITEM

Posted on 2002-07-29
5
1,392 Views
Last Modified: 2012-05-04
'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.
0
Comment
Question by:SiWix
  • 2
  • 2
5 Comments
 
LVL 49

Expert Comment

by:Ryan Chong
ID: 7184741
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
0
 

Author Comment

by:SiWix
ID: 7184771
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
0
 
LVL 27

Accepted Solution

by:
Ark earned 200 total points
ID: 7192491
Hi
First of all, you have to pass lParam ByVal:

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

Second, why do you reset i to -1 every loop? Correct code

sub test()

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

i=-1

for n=0 to nTotal -1

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

'Works OK
next n

end sub


And last, if your listview is in a different process, you'll have a problemm when try to pass structures (LV_ITEM, for examle, to retrive selected item text) via sendmessage. See my sample at http://www.freevbcode.com/ShowCode.Asp?ID=3290 how to pass structures via SendMessage to another processes.

Cheers
0
 

Author Comment

by:SiWix
ID: 7192763
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!
0
 
LVL 27

Expert Comment

by:Ark
ID: 7192832
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
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now