[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Listview control & LVM_GETNEXTITEM

Posted on 2002-07-29
5
Medium Priority
?
1,569 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 54

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 28

Accepted Solution

by:
Ark earned 800 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 28

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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: Martin
Here are a few simple, working, games that you can use as-is or as the basis for your own games. Tic-Tac-Toe This is one of the simplest of all games.   The game allows for a choice of who goes first and keeps track of the number of wins for…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Suggested Courses
Course of the Month19 days, 5 hours left to enroll

834 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