Option Explicit
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) 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 dwProcId 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, ByVal lpAddress As Long, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Long, ByRef lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Long, ByRef lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function ReadProcessMemoryStr Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As Long, ByVal lpBaseAddress As Long, ByVal lpBuffer As String, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
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 Const PROCESS_VM_OPERATION = &H8
Private Const PROCESS_VM_READ = &H10
Private Const PROCESS_VM_WRITE = &H20
Private Const MAX_LVMSTRING As Long = 255
Private Const MEM_COMMIT = &H1000
Private Const MEM_DECOMMIT = &H4000
Private Const MEM_RELEASE = &H8000
Private Const PAGE_READWRITE = &H4
Private Const LVIF_TEXT As Long = &H1
Private Const LVM_FIRST = &H1000
Private Const LVM_GETITEMTEXT = LVM_FIRST + 45
Private Const LVM_GETITEMCOUNT = LVM_FIRST + 4
Private Type LV_ITEM
mask As Long
iItem As Long
iSubItem As Long
state As Long
stateMask As Long
pszText As Long
cchTextMax As Long
iImage As Long
lParam As Long
iIndent As Long
End Type
Private Function GetListviewItem(ByVal hWindow As Long, ByVal iItem As Long, ByVal subItem As Long) As String
Dim Result As Long, pHandle As Long, ProcessID As Long, Index As Long
Dim pStrBufferMemory As Long, pMyItemMemory As Long, strLength As Long
Dim strBuffer As String, tmpString As String, LVItem As LV_ITEM
GetWindowThreadProcessId hWindow, ProcessID
pHandle = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, ProcessID)
pStrBufferMemory = VirtualAllocEx(pHandle, 0, MAX_LVMSTRING, MEM_COMMIT, PAGE_READWRITE)
LVItem.mask = LVIF_TEXT
LVItem.iSubItem = subItem
LVItem.pszText = pStrBufferMemory
LVItem.cchTextMax = MAX_LVMSTRING
pMyItemMemory = VirtualAllocEx(pHandle, 0, LenB(LVItem), MEM_COMMIT, PAGE_READWRITE)
Result = WriteProcessMemory(pHandle, pMyItemMemory, LVItem, Len(LVItem), 0)
strLength = SendMessage(hWindow, LVM_GETITEMTEXT, iItem, ByVal pMyItemMemory)
strBuffer = Space(strLength)
Result = ReadProcessMemoryStr(pHandle, pStrBufferMemory, strBuffer, strLength, 0)
Result = VirtualFreeEx(pHandle, pStrBufferMemory, 0&, MEM_RELEASE)
Result = VirtualFreeEx(pHandle, pMyItemMemory, 0&, MEM_RELEASE)
Result = CloseHandle(pHandle)
GetListviewItem = strBuffer
End Function
Private Function GetHandle(ParentTitle As String, ParentWindow As String, ChildWindow As String) As Long
Dim hWnd1 As Long, hWndEx As Long
hWnd1 = FindWindow(vbNullString, ParentTitle)
If hWnd1 <> 0 Then
hWndEx = FindWindowEx(hWnd1, 0&, ParentWindow, vbNullString)
hWndEx = FindWindowEx(hWndEx, 0&, ChildWindow, vbNullString)
GetHandle = hWndEx
Else
Debug.Print "Could not get handle"
End If
End Function
Private Sub Form_Load()
Dim hWnd1 As Long, Count As Integer, i As Integer
hWnd1 = GetHandle("External App Title", "Parent of LV", "SysListView32")
If hWnd1 <> 0 Then
Count = SendMessage(hWnd1, LVM_GETITEMCOUNT, 0&, 0&)
For i = 0 To Count - 1
Debug.Print GetListviewItem(hWnd1, i, 0)
Next i
End If
End Sub