-
Feb 19th, 2019, 11:21 AM
#1
[RESOLVED] get Tlistview object
Hi.
I was cut and sawing so I can create an app the will read the first line of an external app Tlistview.
Whatever I am trying I cannot get the WinAPI.ReadProcessMemory(processHandle, textBufferPtr, strBuffer, lvItemLocalPtr, nbr)
strBuffer to fill.
I can't seem to find any working vb.net example anywhere.
So any thoughts? I am getting every number on all the variables but the strBuffer won't fill ( note that initially the ReadProcessMemory was ((processHandle, textBufferPtr, strBuffer, 255, 0) but it doesn't seem right by some declarations I have found.
I know this is a long shot but for future reference for anyone it will get him/her until the ReadProcessMemory line with filled intprts and integers.
Code:
Imports System.Runtime.InteropServices
Imports System.Text
Imports EpsonHandler.WinAPI
Public Class Form2
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function FindWindow(lpClassName As String, lpWindowName As String) As IntPtr
End Function
<DllImport("user32.dll")> _
Private Shared Function GetWindowText(hWnd As Integer, text As StringBuilder, count As Integer) As Integer
End Function
Public Const PROCESS_QUERY_INFORMATION = 1024
Public Const PROCESS_VM_OPERATION = &H8
Public Const PROCESS_VM_READ = &H10
Public Const PROCESS_VM_WRITE = &H20
Public Const STANDARD_RIGHTS_REQUIRED = &HF0000
Public Const MAX_LVMSTRING As Int32 = 255
Public Const MEM_COMMIT = &H1000
Public Const PAGE_READWRITE = &H4
Public Const LVIF_TEXT As Int32 = &H1
Private Const LVIF_IMAGE = &H2
Private Const LVM_FIRST = &H1000
Private Const LVM_GETITEM = (LVM_FIRST + 5)
Private Const LVM_GETITEMCOUNT = (LVM_FIRST + 4)
Private Const LVM_GETITEMSTATE = (LVM_FIRST + 44)
Private Const LVIS_SELECTED = &H2
Private Const LVM_SETITEMSTATE = (LVM_FIRST + 43)
Private Const LVIF_STATE = &H8&
Private Const MEM_RESERVE = &H2000
Private Const MEM_RELEASE = &H8000
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim hWnd As IntPtr = FindWindow(Nothing, "Monitoring Tool")
Dim lngProcID As Integer, lngProcHandle As Integer
Dim lngVarPtr1 As IntPtr, lngVarPtr2 As IntPtr
Const intCharCount As Integer = 256 'Number Of Characters For String Buffer
Dim intWindowHandle As Integer = 0 'Window Handle
Dim strWindowText As New StringBuilder(intCharCount) 'Set Up String Builder To Hold Text From GWT API
Dim strBuffer() As Byte
' intWindowHandle = GetForegroundWindow() 'get Current Active Window
Dim processId As Integer
Dim s As String = strWindowText.ToString() 'Retrieve Window Caption
'Retrieve Window Handle
Dim x As String = hWnd.ToString()
Dim typLvItem As String = ""
lngProcHandle = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, lngProcID)
typLvItem = typLvItem.PadRight(255, vbNullChar)
lngVarPtr1 = GCHandle.Alloc(typLvItem, GCHandleType.Pinned).AddrOfPinnedObject
ReDim strBuffer(MAX_LVMSTRING)
Dim listViewPtr As IntPtr = hWnd
' get the ID of the process who owns the list view
WinAPI.GetWindowThreadProcessId(listViewPtr, processId)
Dim processHandle As IntPtr = WinAPI.OpenProcess((WinAPI.ProcessAccessFlags.VirtualMemoryOperation _
Or (WinAPI.ProcessAccessFlags.VirtualMemoryRead Or WinAPI.ProcessAccessFlags.VirtualMemoryWrite)), False, processId)
Dim textBufferPtr As IntPtr = WinAPI.VirtualAllocEx(processHandle, IntPtr.Zero, WinAPI.MAX_LVMSTRING, WinAPI.AllocationType.Commit, WinAPI.MemoryProtection.ReadWrite)
Dim itemId As Integer = 1
Dim subItemId As Integer = 0
Dim lvItem As WinAPI.LVITEM = New WinAPI.LVITEM() With {.mask = WinAPI.ListViewItemFilters.LVIF_TEXT, .cchTextMax = WinAPI.MAX_LVMSTRING, .pszText = textBufferPtr, .iItem = itemId, .iSubItem = subItemId}
Dim lvItemSize As Integer = Marshal.SizeOf(LVITEM)
Dim lvItemBufferPtr As IntPtr = WinAPI.VirtualAllocEx(processHandle, IntPtr.Zero, CType(lvItemSize, UInteger), WinAPI.AllocationType.Commit, WinAPI.MemoryProtection.ReadWrite)
Dim lvItemLocalPtr As IntPtr = Marshal.AllocHGlobal(lvItemSize)
' ... then copy the managed object into the unmanaged memory
Marshal.StructureToPtr(LVITEM, lvItemLocalPtr, False)
' and write into remote process's memory
Dim nbr As Integer = 0
WinAPI.WriteProcessMemory(processHandle, lvItemBufferPtr, lvItemLocalPtr, CType(lvItemSize, UInteger), nbr)
' tell the list view to fill in the text we desired
WinAPI.SendMessage(listViewPtr, CType(WinAPI.ListViewMessages.LVM_GETITEMTEXT, UInteger), itemId, lvItemBufferPtr)
Dim localTextBuffer As Byte() = New Byte((WinAPI.MAX_LVMSTRING) - 1) {}
WinAPI.ReadProcessMemory(processHandle, textBufferPtr, strBuffer, lvItemLocalPtr, nbr)
Dim text As String = Encoding.Unicode.GetString(localTextBuffer)
' the trailing zeros are not cleared automatically
text = text.Substring(0, text.IndexOf("0"))
' finally free all the memory we allocated, and close the process handle we opened
WinAPI.VirtualFreeEx(processHandle, textBufferPtr, 0, WinAPI.AllocationType.Release)
WinAPI.VirtualFreeEx(processHandle, lvItemBufferPtr, 0, WinAPI.AllocationType.Release)
Marshal.FreeHGlobal(lvItemLocalPtr)
WinAPI.CloseHandle(processHandle)
End Sub
End Class
Public Class WinAPI
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function FindWindow(lpClassName As String, lpWindowName As String) As IntPtr
End Function
<DllImport("user32.dll")> _
Private Shared Function GetWindowText(hWnd As Integer, text As StringBuilder, count As Integer) As Integer
End Function
<DllImport("kernel32.dll", SetLastError:=True)> _
Public Shared Function OpenProcess( _
ByVal dwDesiredAccess As UInt32, _
ByVal bInheritHandle As Int32, _
ByVal dwProcessId As UInt32) As IntPtr
End Function
<DllImport("kernel32.dll", SetLastError:=True, ExactSpelling:=True)> _
Public Shared Function VirtualAllocEx(ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, _
ByVal dwSize As UInteger, ByVal flAllocationType As UInteger, _
ByVal flProtect As UInteger) As IntPtr
End Function
<DllImport("kernel32.dll", SetLastError:=True, ExactSpelling:=True)> _
Public Shared Function VirtualFreeEx( _
ByVal hProcess As IntPtr, _
ByVal pAddress As IntPtr, _
ByVal size As UIntPtr, _
ByVal freeType As IntPtr) As Boolean
End Function
<DllImport("kernel32.dll", SetLastError:=True)> _
Public Shared Function ReadProcessMemory( _
ByVal hProcess As IntPtr, _
ByVal lpBaseAddress As IntPtr, _
<Out()> ByVal lpBuffer As Byte(), _
ByVal dwSize As Integer, _
ByRef lpNumberOfBytesRead As Integer) As Boolean
End Function
<DllImport("kernel32.dll")> _
Public Shared Function WriteProcessMemory( _
ByVal hProcess As IntPtr, _
ByVal lpBaseAddress As IntPtr, _
ByVal lpBuffer As Integer, _
ByVal nSize As System.UInt32, _
<Out()> ByRef lpNumberOfBytesWritten As Int32) As Boolean
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Public Shared Function SendMessage( _
ByVal hWnd As IntPtr, _
ByVal Msg As UInteger, _
ByVal wParam As Integer, _
ByVal lParam As IntPtr) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Public Shared Function GetWindowThreadProcessId(ByVal hwnd As IntPtr, _
ByRef lpdwProcessId As Integer) As Integer
End Function
<DllImport("kernel32.dll", SetLastError:=True)> _
Public Shared Function CloseHandle(ByVal hObject As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Public Enum ListViewMessages
LVM_GETITEMTEXT = 260
B
End Enum
Public Enum ListViewItemFilters As UInteger
LVIF_TEXT = 1
End Enum
Public Const MAX_LVMSTRING As UInteger = 255
<StructLayoutAttribute(LayoutKind.Sequential)> _
Public Structure LVITEM
Public mask As UInteger
Public iItem As Integer
Public iSubItem As Integer
Public state As UInteger
Public stateMask As UInteger
Public pszText As IntPtr
Public cchTextMax As Integer
Public iImage As Integer
Public lParam As IntPtr
End Structure
Public Enum ProcessAccessFlags As UInteger
VirtualMemoryOperation = 8
VirtualMemoryRead = 16
VirtualMemoryWrite = 32
End Enum
<Flags()> _
Public Enum AllocationType
Commit = 4096
Release = 32768
End Enum
<Flags()> _
Public Enum MemoryProtection
ReadWrite = 4
End Enum
End Class
ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·
-
Feb 20th, 2019, 02:02 AM
#2
Re: get Tlistview object
If i'm reading this right, you're allocating textBufferPtr with VirtualAllocEx (https://docs.microsoft.com/en-us/win...virtualallocex).
So you're getting a reserved Memory-Space inside that Process you've opened.
https://docs.microsoft.com/de-de/win...dprocessmemory
In ReadProcessMemory you're using this value as the BaseAddress.
I would have expected the Address of the ListView-Item you're trying to read.
strBuffer fails to fill up probably because there is nothing to fill it from, since VirtualAllocEx fills up the reserved Memory with Zeros.
Next: You're using lvItemLocalPtr as the Parameter for Size (in Bytes)????
Is it possible that you've confused your parameters?
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
-
Feb 20th, 2019, 06:56 AM
#3
Re: get Tlistview object
Hi and thanks for the reply.
I was actually testing the values so lets start from this:
I created a windows form named form3 and inserted a listview with one row.
I cannot get the row text.
Here is the code on by one with explanation:
Code:
Dim hWnd As IntPtr = FindWindow(Nothing, "form3")
Dim processId As Integer
Dim listViewPtr As IntPtr = hWnd
Dim lngVarPtr1 As IntPtr
Dim strBuffer() As Byte
Dim lngProcHandle As Integer
Dim pStrBufferMemory As IntPtr
Dim pMyItemMemory As IntPtr
ReDim strBuffer(MAX_LVMSTRING)
' get the ID of the process who owns the list view
WinAPI.GetWindowThreadProcessId(listViewPtr, processId)
lngProcHandle = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, processId)
pStrBufferMemory = VirtualAllocEx(lngProcHandle, 0, MAX_LVMSTRING, MEM_COMMIT, PAGE_READWRITE)
'The myItem.iSubItem member is set to the index of the column that is being retrieved
Dim myItem As LV_ITEMA
myItem.mask = LVIF_TEXT
myItem.iSubItem = 0
myItem.pszText = pStrBufferMemory
myItem.cchTextMax = MAX_LVMSTRING
'write the structure into the remote process's memory space
'**********************************************************
pMyItemMemory = VirtualAllocEx(lngProcHandle, 0, Len(myItem), MEM_COMMIT, PAGE_READWRITE)
Dim lvItemSizeX As Integer = Marshal.SizeOf(myItem)
Dim lvItemLocalPtrX As IntPtr = Marshal.AllocHGlobal(lvItemSizeX)
' ... then copy the managed object into the unmanaged memory
Marshal.StructureToPtr(myItem, lvItemLocalPtrX, False)
Dim result As Boolean = WriteProcessMemory(lngProcHandle, pMyItemMemory, lvItemLocalPtrX, Len(myItem), 0)
'''''''''''''''''' RESULT = TRUE HERE . I am not sure about the WriteProcessMemory as there are variations. So I used the Microsoft one.
' 1 = supposed to be the listview row?
' gives false
result = SendMessage(hWnd, CType(WinAPI.ListViewMessages.LVM_GETITEMTEXT, UInteger), 1, pMyItemMemory)
' If i use lngProcHandle insted of Hwnd ( that is supposed to be wrong), i get some data into the buffer on the next line that is just garbage.
result = ReadProcessMemory(lngProcHandle, pStrBufferMemory, strBuffer, MAX_LVMSTRING, 0)
'' Gives false
'' below all True
result = VirtualFreeEx(lngProcHandle, pStrBufferMemory, 0, MEM_RELEASE)
result = VirtualFreeEx(lngProcHandle, pMyItemMemory, 0, MEM_RELEASE)
result = CloseHandle(lngProcHandle)
So it seems that SendMessage is not working? Am i selecting something else for the listview? I am using 1 as the Listview and 0 as the subitem.
Thanks.
Edit . If I use a Private Const LB_GETTEXT = &H189
and pass it as SendMessage(hWnd, LB_GETTEXT, 1, pMyItemMemory)
I get TRUE but the ReadProcessMemory will still give out gibberish buffer
Last edited by sapator; Feb 20th, 2019 at 08:53 AM.
ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·
-
Feb 20th, 2019, 10:21 AM
#4
Re: get Tlistview object
Just saw something:
You're using FindWindow on Form3. The Handle you get back is to the Form, not the ListView
Have you tried FindWindowEx and looking for your listview?
After looking some more at your code i'd bet you don't have a valid handle to your ListView, but instead you have a handle to your Form, and all subsequent procedure-calls use that Form-Handle
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
-
Feb 20th, 2019, 10:52 AM
#5
Re: get Tlistview object
Hi.
Doing this:
Code:
Dim hWnd As IntPtr = FindWindow(Nothing, "Form3")
Dim HWNDL As IntPtr = FindWindowEx(hWnd, IntPtr.Zero, "SysListView32", Nothing)
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Public Shared Function FindWindowEx(ByVal parentHandle As IntPtr, _
ByVal childAfter As IntPtr, _
ByVal lclassName As String, _
ByVal windowTitle As String) As IntPtr
End Function
Will return Zero for HWNDL
So does this return something if you try a form with a listview in your app?
Thanks.
ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·
-
Feb 20th, 2019, 10:57 AM
#6
Re: get Tlistview object
Right.
This Dim HWNDL As IntPtr = FindWindowEx(hWnd, IntPtr.Zero, Nothing, Nothing)
will return a value but how can we be sure what window did it get?
could be the whole form.
ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·
-
Feb 21st, 2019, 06:14 AM
#7
Re: get Tlistview object
Hi.
OK so after search after search I found out that FindWindowEx is truly problematic with W7 and above.
What seems to must be done is use the EnumChildWindows . Now I have another issue. I am able to get the handle of the listview on a windows form, however I am NOT able to get the handle on the external APP with the Tlistview. I somehow must be done as the spy++ show the handle.
Any thoughts?
Code:
Imports System.Runtime.InteropServices
Public Class Form5
<DllImport("User32.dll")> _
Private Shared Function EnumChildWindows _
(ByVal WindowHandle As IntPtr, ByVal Callback As EnumWindowProcess, _
ByVal lParam As IntPtr) As Boolean
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function FindWindow(lpClassName As String, lpWindowName As String) As IntPtr
End Function
Public Delegate Function EnumWindowProcess(ByVal Handle As IntPtr, ByVal Parameter As IntPtr) As Boolean
Public Shared Function GetChildWindows(ByVal ParentHandle As IntPtr) As IntPtr()
Dim ChildrenList As New List(Of IntPtr)
Dim ListHandle As GCHandle = GCHandle.Alloc(ChildrenList)
Try
EnumChildWindows(ParentHandle, AddressOf EnumWindow, GCHandle.ToIntPtr(ListHandle))
Finally
If ListHandle.IsAllocated Then ListHandle.Free()
End Try
Return ChildrenList.ToArray
End Function
Private Shared Function EnumWindow(ByVal Handle As IntPtr, ByVal Parameter As IntPtr) As Boolean
Dim ChildrenList As List(Of IntPtr) = GCHandle.FromIntPtr(Parameter).Target
If ChildrenList Is Nothing Then Throw New Exception("GCHandle Target could not be cast as List(Of IntPtr)")
ChildrenList.Add(Handle)
Return True
End Function
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
'Dim hWnd As IntPtr = FindWindow(Nothing, "Monitoring Tool") ' not getting child windows
Dim hWnd As IntPtr = FindWindow(Nothing, "Form5") ' Works
Dim intpWindows As IntPtr()
intpWindows = GetChildWindows(hWnd)
End Sub
End Class
ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·
-
Feb 21st, 2019, 06:40 AM
#8
Re: get Tlistview object
I'm so close I can taste it!
If I use the spy++ handler I'm able to get the listview. I just need to change the LVM_GETITEMTEXT = 4141 . That is the correct number.
The only problem is that I cannot get the handler to the Tlistview but spy++ does it!
Any help? I just need to get the handler and I'm through!
ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·
-
Feb 21st, 2019, 09:08 AM
#9
Re: get Tlistview object
In your Callback-Function "EnumWindow" use the Handle that you get for each ChildWindow and pass it to the GetClassName-API
https://docs.microsoft.com/en-us/win...r-getclassname
Make sure that you allocate enough space in the String-Buffer.
There you can check if you'll find your "SysListView32"
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
-
Feb 21st, 2019, 09:41 AM
#10
Re: get Tlistview object
As I've said I can't get any external APP Listivew handle.
I don't want to start looking at GetClassName as I have finally fixed this.
I was able to get the whole thing working with a couple of thousand of lines of code.... Just to get one handler!
Code:
Imports System.Runtime.InteropServices
Imports System.Text
Imports System.Security
Public Class Form5
<DllImport("user32.dll", SetLastError:=True)> _
Public Shared Function GetWindowThreadProcessId(ByVal hwnd As IntPtr, _
ByRef lpdwProcessId As Integer) As Integer
End Function
<DllImport("User32.dll")> _
Private Shared Function EnumChildWindows _
(ByVal WindowHandle As IntPtr, ByVal Callback As EnumWindowProcess, _
ByVal lParam As IntPtr) As Boolean
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function FindWindow(lpClassName As String, lpWindowName As String) As IntPtr
End Function
<DllImport("USER32.DLL")> _
Private Shared Function GetShellWindow() As IntPtr
End Function
<DllImport("USER32.DLL")> _
Private Shared Function GetWindowText(ByVal hWnd As IntPtr, ByVal lpString As StringBuilder, ByVal nMaxCount As Integer) As Integer
End Function
<DllImport("USER32.DLL")> _
Private Shared Function GetWindowTextLength(ByVal hWnd As IntPtr) As Integer
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, <Out()> ByRef lpdwProcessId As UInt32) As UInt32
End Function
<DllImport("USER32.DLL")> _
Private Shared Function IsWindowVisible(ByVal hWnd As IntPtr) As Boolean
End Function
Private Delegate Function EnumWindowsProc(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Boolean
<DllImport("USER32.DLL")> _
Private Shared Function EnumWindows(ByVal enumFunc As EnumWindowsProc, ByVal lParam As Integer) As Boolean
End Function
Private hShellWindow As IntPtr = GetShellWindow()
Private dictWindows As New Dictionary(Of IntPtr, String)
Private currentProcessID As Integer
Public Function GetOpenWindowsFromPID(ByVal processID As Integer) As IDictionary(Of IntPtr, String)
dictWindows.Clear()
currentProcessID = processID
EnumWindows(AddressOf enumWindowsInternal, 0)
Return dictWindows
End Function
Private Function enumWindowsInternal(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Boolean
If (hWnd <> hShellWindow) Then
Dim windowPid As UInt32
If Not IsWindowVisible(hWnd) Then
Return True
End If
Dim length As Integer = GetWindowTextLength(hWnd)
If (length = 0) Then
Return True
End If
GetWindowThreadProcessId(hWnd, windowPid)
If (windowPid <> currentProcessID) Then
Return True
End If
Dim stringBuilder As New StringBuilder(length)
GetWindowText(hWnd, stringBuilder, (length + 1))
dictWindows.Add(hWnd, stringBuilder.ToString)
End If
Return True
End Function
Public Delegate Function EnumWindowProcess(ByVal Handle As IntPtr, ByVal Parameter As IntPtr) As Boolean
Public Shared Function GetChildWindows(ByVal ParentHandle As IntPtr) As IntPtr()
Dim ChildrenList As New List(Of IntPtr)
Dim ListHandle As GCHandle = GCHandle.Alloc(ChildrenList)
Try
EnumChildWindows(ParentHandle, AddressOf EnumWindow, GCHandle.ToIntPtr(ListHandle))
Finally
If ListHandle.IsAllocated Then ListHandle.Free()
End Try
Return ChildrenList.ToArray
End Function
Private Shared Function EnumWindow(ByVal Handle As IntPtr, ByVal Parameter As IntPtr) As Boolean
Dim ChildrenList As List(Of IntPtr) = GCHandle.FromIntPtr(Parameter).Target
If ChildrenList Is Nothing Then Throw New Exception("GCHandle Target could not be cast as List(Of IntPtr)")
ChildrenList.Add(Handle)
Return True
End Function
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim hWnd As IntPtr = FindWindow(Nothing, "Monitoring Tool")
If hWnd = IntPtr.Zero Then
Exit Sub
End If
Dim processId As Integer
GetWindowThreadProcessId(hWnd, processId)
If processId <= 0 Then Exit Sub
Dim HListView As IntPtr = 0
Dim windows As IDictionary(Of IntPtr, String) = GetOpenWindowsFromPID(processId)
For Each kvp As KeyValuePair(Of IntPtr, String) In windows
HListView = kvp.Key
Exit For
Next
Dim hWnd1 As IntPtr = HListView
Dim intpWindows As IntPtr()
' Tlistview
intpWindows = GetChildWindows(hWnd1)
If intpWindows.Count <= 0 Then
Exit Sub
End If
'You need this
Dim intprListviwe As IntPtr = intpWindows(2)
End Sub
Now I need to glue this to the working get listview value code and I'm off!
I had to go and find 100 pages with scattered info to do this but it's done.
Thanks again!
ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|