Solved

Listview control & LVM_GETNEXTITEM

Posted on 2002-07-29
5
1,481 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
5 Comments
 
LVL 52

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 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 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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

When trying to find the cause of a problem in VBA or VB6 it's often valuable to know what procedures were executed prior to the error. You can use the Call Stack for that but it is often inadequate because it may show procedures you aren't intereste…
This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
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…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

691 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