Results 1 to 10 of 10

Thread: [RESOLVED] get Tlistview object

  1. #1

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    6,606

    Resolved [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
    ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
    πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·

  2. #2
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,444

    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

  3. #3

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    6,606

    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.
    ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
    πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·

  4. #4
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,444

    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

  5. #5

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    6,606

    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.
    ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
    πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·

  6. #6

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    6,606

    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.
    ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
    πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·

  7. #7

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    6,606

    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
    ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
    πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·

  8. #8

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    6,606

    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!
    ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
    πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·

  9. #9
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,444

    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

  10. #10

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    6,606

    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
  •  



Click Here to Expand Forum to Full Width