Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to highlight 1st item on external listview?

Status
Not open for further replies.

Jason231

MIS
Apr 15, 2006
43
0
0
NL
Hi all could any one tell me how i can highligh the first item on the external listview . I did not many searches but could not find the solution!! So i hope some one help me.Thanks
 
montrealsoft thank u for u reply. but could u tell me what modules and what controle and refrences i need. Just pasting one line code will not allow me to select an item from external listview.Thanks
 
The items are located in external listview which i do not have its source code and i want highlt the first item of it . I know it can be done but i do not know how.
 
It is quite possible. However it isn't straightforward.

Step 1 is to figure out the hWnd of the ListView that you are interested in

Step 2 is to send the necessary messages to that window (that's the tricky bit that MontrealSoft is referring to, because the messages required pass a block of memory, but the memory belongs to your VB process and cannot be passed via SendMessage to a foreign process - but this can be fixed by allocating a block of memory in the foreign process and copying our block of memory over to it).

Now - do you really want to proceed?
 
thank u all for u reply. Well yes i do realy want proceed:)
 
Ok. For the demonstration you'll nedd a new project with a form (with a command button) and a module

The following code goes in the module:
Code:
[blue]Option Explicit

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
Private Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As Long, ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
Private Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

Private Type LV_ITEM
    mask As Long
    iItem As Long
    iSubitem As Long
    state As Long
    stateMask As Long
    pszText As String
    cchTextMax As Long
    iImage As Long
    lParam As Long
    iIndent As Long
End Type

Private Const LVM_FIRST = &H1000&
Private Const LVM_SETITEMSTATE = (LVM_FIRST + 43)
Private Const LVIF_STATE = &H8&
Private Const LVIS_SELECTED = &H2&
Private Const PROCESS_VM_OPERATION = &H8
Private Const PROCESS_VM_READ = &H10
Private Const PROCESS_VM_WRITE = &H20
Private Const PAGE_READWRITE = &H4&
Private Const MEM_RESERVE = &H2000
Private Const MEM_COMMIT = &H1000
Private Const MEM_RELEASE = &H8000

Private hWndlvw As Long

Private Function EnumWindowsProc(ByVal hWnd As Long, ByVal lParam As Long) As Long
    hWndlvw = FindWindowEx(hWnd, 0&, "ListView20WndClass", "")
    EnumWindowsProc = (hWndlvw = 0) 'Stop when we find first listview
End Function


' This demonstration example finds first child window with class "ListView20WndClass"
' which may not be what you want. Use your own method to find the real hWnd that you want
Public Function FindListView() As Long
    EnumWindows AddressOf EnumWindowsProc, 0&
    FindListView = hWndlvw
End Function


Public Function MessageCrossProcess(ByVal hWnd As Long)
    Dim lProcID As Long
    Dim hProc As Long
    Dim lxprocLVITEM As Long
    Dim LVITEM As LV_ITEM
    Dim lItemPos As Long
    
    GetWindowThreadProcessId hWnd, lProcID ' Get the process ID in which the ListView is running
    If lProcID <> 0 Then
        hProc = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, lProcID) ' makwe sure we have read write permissions in the process space
        If hProc <> 0 Then
            lxprocLVITEM = VirtualAllocEx(hProc, 0, LenB(LVITEM), MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE) ' Grab enough memory in the other procedure's space to hold our LV_ITEM
            
            ' Set up our local LV_ITEM to change the selected item
            LVITEM.mask = LVIF_STATE
            LVITEM.state = True
            LVITEM.stateMask = LVIS_SELECTED
            
            ' Copy the local LV_ITEM into the space we reserved in the foreign process
            WriteProcessMemory hProc, ByVal lxprocLVITEM, ByVal VarPtr(LVITEM), LenB(LVITEM), 0
            
            ' Now send the message, but pass the address of the copy of our LV_ITEM that now exists in the foreign process instead of our local versiony
            lItemPos = 0& ' first item
            SendMessage hWnd, LVM_SETITEMSTATE, lItemPos, ByVal lxprocLVITEM
            
            ' Clean up
            VirtualFreeEx hProc, ByVal lxprocLVITEM, LenB(LVITEM), MEM_RELEASE
            CloseHandle hProc
        End If
    End If
End Function[/blue]

And the following goes in the Form:
Code:
[blue]Private Sub Command1_Click()
    MessageCrossProcess FindListView
End Sub[/blue]
To properly demo it, you would also want another VB project with a form with a listview, and the following code:
Code:
[blue]Private Sub Form_Load()
    ListView1.View = lvwList
    ListView1.HideSelection = False
    ListView1.ListItems.Add , , "Hello"
    ListView1.ListItems.Add , , "there"
    ListView1.ListItems.Add , , "tek-tips"
End Sub[/blue]
and run it first
 
strong thank u for u code . But the issue is that i want to deal with external listview which i do not have access to its source code. :-(
 
but it did not work for external listview . could u tell me why ?Thanks
 
This comment

[green]' This demonstration example finds first child window with class "ListView20WndClass"
' which may not be what you want. Use your own method to find the real hWnd that you want[/green]

that I carefully put in the code for exactly this reason may help explain
 
Strong i have the following ineformation about my external listview :hWnd=527632, class =sysListView32

How i can use it in your code. Or do i need further information.Thanks

 
hWnd=527632

This will change every time the appication containing the listview is run. You will need to search for the correct window. In my example I just search for the very first VB Listview (which is a subclassed SysListView32) that I can find. Your search will need to be more explicit. Best thing would be to see if you can find the caption/title of the window that contains the listview, so the code for the would look something (but not exactly, since I feel that you should do some work yourself) like this (note that there are once or two advanced tricks being used here):
Code:
[blue]Option Explicit

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
Private Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As Long, ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
Private Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

Private Type LV_ITEM
    mask As Long
    iItem As Long
    iSubitem As Long
    state As Long
    stateMask As Long
    pszText As String
    cchTextMax As Long
    iImage As Long
    lParam As Long
    iIndent As Long
End Type

Private Const LVM_FIRST = &H1000&
Private Const LVM_SETITEMSTATE = (LVM_FIRST + 43)
Private Const LVIF_STATE = &H8&
[b][navy]Private Const LVIS_FOCUSED = &H1[/navy][/b]
Private Const LVIS_SELECTED = &H2&
Private Const PROCESS_VM_OPERATION = &H8
Private Const PROCESS_VM_READ = &H10
Private Const PROCESS_VM_WRITE = &H20
Private Const PAGE_READWRITE = &H4&
Private Const MEM_RESERVE = &H2000
Private Const MEM_COMMIT = &H1000
Private Const MEM_RELEASE = &H8000

Private hWndlvw As Long

[b][navy]Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hWnd As Long) As Long[/navy][/b]


Private Function EnumWindowsProc(ByVal hWnd As Long, ByVal lParam As [b][navy]String[/navy][/b]) As Long
    Dim strCaption As String
    Dim lLen As Long
    
    hWndlvw = FindWindowEx(hWnd, 0&, [b][navy]"SysListView32"[/navy][/b], "")
    [b][navy][green]' If we've found a window with the SysListView32 class
    ' check to see if parent window caption is the one we are looking for[/green]
    If hWndlvw <> 0 Then
        lLen = GetWindowTextLength(hWnd)
        If lLen > 0 Then
            strCaption = Space(lLen)
            GetWindowText hWnd, strCaption, lLen + 1
        End If
    End If[/navy][/b]
    EnumWindowsProc = (hWndlvw = 0 [b][navy]And strCaption <> lParam[/navy][/b])
End Function

[b][navy][green]' New example looks for a window with class SysListView32 that is hosted
' by a window whose caption matches the contents of strInWindowWithCaption[/green][/navy][/b]
Public Function FindListView([b][navy]strInWindowWithCaption As String[/navy][/b]) As Long
    EnumWindows AddressOf EnumWindowsProc, [b][navy]StrPtr(strInWindowWithCaption)[/navy][/b]
    FindListView = hWndlvw
End Function


Public Function MessageCrossProcess(ByVal hWnd As Long)
    Dim lProcID As Long
    Dim hProc As Long
    Dim lxprocLVITEM As Long
    Dim LVITEM As LV_ITEM
    Dim lItemPos As Long
    
    GetWindowThreadProcessId hWnd, lProcID [green]' Get the process ID in which the ListView is running[/green]
    If lProcID <> 0 Then
        hProc = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, lProcID) ' make sure we have read write permissions in the process space
        If hProc <> 0 Then
            lxprocLVITEM = VirtualAllocEx(hProc, 0, LenB(LVITEM), MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE) [green]' Grab enough memory in the other procedure's space to hold our LV_ITEM
            
            ' Set up our local LV_ITEM to change the selected item[/green]
            LVITEM.mask = LVIF_STATE
            LVITEM.state = True
            LVITEM.stateMask = LVIS_SELECTED [b][navy]Or LVIS_FOCUSED [green]' Just enforcing the selection better than in original version by moving the focus as well[/green][/navy][/b][green]           
            ' Copy the local LV_ITEM into the space we reserved in the foreign process[/green]
            WriteProcessMemory hProc, ByVal lxprocLVITEM, ByVal VarPtr(LVITEM), LenB(LVITEM), 0
            
            [green]' Now send the message, but pass the address of the copy of our LV_ITEM that now exists in the foreign process instead of our local version[/green]
            lItemPos = 0& ' first item
            SendMessage hWnd, LVM_SETITEMSTATE, lItemPos, ByVal lxprocLVITEM
            
            [green]' Clean up[/green]
            VirtualFreeEx hProc, ByVal lxprocLVITEM, LenB(LVITEM), MEM_RELEASE
            CloseHandle hProc
        End If
    End If
End Function[/blue]

Now on my PC - but not necessarily on yours - I am running Checkpoint's SecuRemote client software, which has a SySListView. The title of the Checkpoin program's window is "VPN-1 SecuRemote". So to enforce selection of the first item in that listview I'd modify the code in the form from my example to:
Code:
[blue]Private Sub Command1_Click()
    MessageCrossProcess FindListView[b][navy]("VPN-1 SecuRemote")[/navy][/b]
End Sub[/blue]
 
strong thank u for u code. Well actually i could not make it work for my external listniew !!:-(. I used the window grabber program to get the class and some info about my externial window but no luck!
 
>I used the window grabber program

1. Did you use it to get the caption of the listview's parent?
2. Can you confirm that the parent is a top level window (I ask because the example code only looks listview's in top level windows; I assumed you would do some work yourself if your situation was different as)
 
Strongm yes i used to get the caption too. The caption is readable and it it in the top of the list view but when i run it nothing happens .i replaced caption with the form's cpation that contains the listview but did not work!!
 
I repeat: can you confirm that the parent is a top level window?
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top