Read the text from another programs listview control?
Read the text from another programs listview control?
Read the text from another programs listview control?
Read the text from another programs listview control?
Read the text from another programs listview control?
Read the text from another programs listview control? Read the text from another programs listview control? Read the text from another programs listview control? Read the text from another programs listview control? Read the text from another programs listview control? Read the text from another programs listview control? Read the text from another programs listview control? Read the text from another programs listview control?
Read the text from another programs listview control? Read the text from another programs listview control?
Read the text from another programs listview control?
Go Back  Xtreme Visual Basic Talk > > > Read the text from another programs listview control?


Reply
 
Thread Tools Display Modes
  #1  
Old 06-18-2008, 04:43 AM
appolospb appolospb is offline
Freshman
 
Join Date: Feb 2008
Posts: 39
Unhappy Read the text from another programs listview control?


I would like to read text from another programs listview control. I have searched over 3x forums for this and cant find any working examples and especially no working VB.NET examples.

I know that i have to use the command 'LVM_GETITEMTEXT' with the API Sendmessage but i have no idea how to issue the command and need a working example to go from. From what i have seen it seems more complicated then a normal sendmessage command as you have to allocate memory buffers etc which reallly confuses me .

I would be grateful if anyone could provide me with a working code example in VB.NET although i wont hold my breath as no one seems to know how to do this.
Reply With Quote
  #2  
Old 06-18-2008, 05:03 AM
Cas's Avatar
CasRead the text from another programs listview control? Cas is offline
Senior Contributor

* Expert *
 
Join Date: May 2008
Posts: 1,012
Default

I daresay this should help you out - it's in our code library and very easy to find if you search the forum for "LVM_GETITEMTEXT", not sure why that didn't work for you.

Anyway, good luck!

Edit: It's Legacy VB, I should mention. But I don't think the differences are significant as far as API usage is concerned, are they?
__________________

"Lying in bed would be an altogether perfect and supreme experience if only one had a colored pencil long enough to draw on the ceiling."

Chesterton, "Tremendous Trifles"
Reply With Quote
  #3  
Old 06-18-2008, 08:05 AM
appolospb appolospb is offline
Freshman
 
Join Date: Feb 2008
Posts: 39
Default

I have done a search on all of the forums for 'LVM_GETITEMTEXT' and sendmessage. I have found examples but the code samples usually dont work when i try and run them or are poorly explained / bits missing. I am also not very experienced in converting VB6 code to .NET 2005 , the VS converter usually fails to convert them correctly.

I have taken a look at the code you referr to and it experienced many failures (20+) when it was converted to .NET 2005 format using the VS converter :-( . As my knowledge of this code is weak at best and i dont know VB6 syntax i am unable to resolve the issues. Perhaps someone could convert it to .NET 2005 for me or has a .NET 2005 version somewhere?.

Last edited by appolospb; 06-18-2008 at 08:22 AM.
Reply With Quote
  #4  
Old 06-18-2008, 10:11 AM
appolospb appolospb is offline
Freshman
 
Join Date: Feb 2008
Posts: 39
Default

Ok here is the code im working on i have based it on the code found on the following forum topic:

http://www.vbforums.com/showthread.php?t=184384

I have tried to convert the code to VB.NET with little success as the program throws a Pininvoke error on the following line of code:

Code:
pHandle = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, ProcessID)
Perhaps someone can explain what im doing wrong. I just want to read the names of items contained in another programs listview control.

Code:
Public Class Form1

    Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As Boolean, ByVal lParam As IntPtr) As IntPtr
    Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
    Public 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
    Public Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As Long, ByVal lpAddress As Long, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
    Public Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByRef lpBuffer As Integer, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer
    Public Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As IntPtr, ByVal lpBaseAddress As Integer, ByRef lpBuffer As Byte, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer
    Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

    Private Structure LVITEM
        Dim mask As Integer
        Dim iItem As Integer
        Dim iSubItem As Integer
        Dim state As Integer
        Dim stateMask As Integer
        Dim pszText As Integer
        Dim cchTextMax As Integer
        Dim iImage As Integer
        Dim lParam As Integer
        Dim iIndent As Integer
    End Structure

    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 Long = 255
    Public Const MEM_COMMIT = &H1000
    Public Const PAGE_READWRITE = &H4
    Public Const LVIF_TEXT As Long = &H1

    Public Const MEM_RELEASE = &H8000&

    Const LVM_FIRST = &H1000
    Const LVM_GETITEMTEXT = (LVM_FIRST + 45)
    Const LVM_GETITEMCOUNT = (LVM_FIRST + 4)

    Dim handle As IntPtr

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        handle = TextBox1.Text
        ' Aquire listview handle from the textbox

        GetListviewItem(handle, 3794, 0, 0)

    End Sub

    Public Function GetListviewItem(ByVal hWindow As Long, ByVal ProcessID As Long, ByVal pColumn As Long, ByVal pRow As Long) As String

        Dim result As Long
        Dim myItem As LVITEM
        Dim pHandle As Long
        Dim pStrBufferMemory As Long
        Dim pMyItemMemory As Long
        Dim strBuffer() As Byte
        Dim index As Long
        Dim tmpString As String
        Dim strLength As Long

        '**********************
        'init the string buffer
        '**********************
        ReDim strBuffer(MAX_LVMSTRING)

        '***********************************************************
        'open a handle to the process and allocate the string buffer
        '***********************************************************
        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)

        '************************************************************************************
        'initialize the local LV_ITEM structure
        'The myItem.iSubItem member is set to the index of the column that is being retrieved
        '************************************************************************************
        myItem.mask = LVIF_TEXT
        myItem.iSubItem = pColumn
        myItem.pszText = pStrBufferMemory
        myItem.cchTextMax = MAX_LVMSTRING

        '**********************************************************
        'write the structure into the remote process's memory space
        '**********************************************************
        pMyItemMemory = VirtualAllocEx(pHandle, 0, Len(myItem), MEM_COMMIT, PAGE_READWRITE)
        result = WriteProcessMemory(pHandle, pMyItemMemory, Val(myItem), Len(myItem), 0)

        '*************************************************************
        'send the get the item message and write back the memory space
        '*************************************************************
        result = SendMessage(hWindow, LVM_GETITEMTEXT, pRow, pMyItemMemory)
        result = ReadProcessMemory(pHandle, pStrBufferMemory, strBuffer(0), MAX_LVMSTRING, 0)
        result = ReadProcessMemory(pHandle, pMyItemMemory, Val(myItem), Len(myItem), 0)

        '**************************************************
        'turn the byte array into a string and send it back
        '**************************************************
        For index = LBound(strBuffer) To UBound(strBuffer)
            If Chr(strBuffer(index)) = vbNullChar Then Exit For
            tmpString = tmpString & Chr(strBuffer(index))
        Next index

        tmpString = Trim(tmpString)

        '**************************************************
        'deallocate the memory and close the process handle
        '**************************************************
        result = VirtualFreeEx(pHandle, pStrBufferMemory, 0, MEM_RELEASE)
        result = VirtualFreeEx(pHandle, pMyItemMemory, 0, MEM_RELEASE)

        result = CloseHandle(pHandle)

        If Len(tmpString) > 0 Then GetListviewItem = tmpString

    End Function

End Class
Reply With Quote
  #5  
Old 06-18-2008, 11:01 AM
darkforcesjedi's Avatar
darkforcesjediRead the text from another programs listview control? darkforcesjedi is offline
Trust me, I'm an

* Expert *
 
Join Date: Apr 2001
Location: In ur base, pwnin d00dz
Posts: 1,964
Default

How do you know you have the correct process ID and handle? How did you obtain them?
__________________
To err is human; to debug, divine.
Reply With Quote
  #6  
Old 06-18-2008, 11:09 AM
Roger_Wgnr's Avatar
Roger_Wgnr Roger_Wgnr is offline
CodeASaurus Hex

Forum Leader
* Expert *
 
Join Date: Jul 2006
Location: San Antonio TX
Posts: 2,427
Default

The prolem is in your declarations.
The immediate problem is that the long should be an integer declaration. In VB6 Long were 32 bit entity and in .Net they are 64.

You may find this link of help also it provides information on replacing VB6 API calls for .NET

Replacing API Calls with .NET Framework Classes
__________________
Code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. ~Martin Golding
The user is a peripheral that types when you issue a read request. ~Peter Williams
MSDN Visual Basic .NET General FAQ
Reply With Quote
  #7  
Old 06-19-2008, 04:41 AM
appolospb appolospb is offline
Freshman
 
Join Date: Feb 2008
Posts: 39
Default

Thanks for the help

darkforcesjedi :

I am aquiring the PROCESS ID of the listview control by using Winspector or by enumerating through the running windows and then grabbing the ID of the current handle that matches the listview control. I am using the same method to aquire the handle of the listview control also. I am fairly confident i am supplying the program with the correct data.

Roger_Wgnr:

I have converted every 'As Long' entry to 'As Integer' and it did improve things as it moved onto a further stage in the code before it crashed. However i am still completely clueless as to whats causing the fault. As i have re-worked someone elses code i dont really know what a lot of the statements do so cant fix them.

Looked at the supplied link but didnt really find anything relevant to the problems im having upgrading the code from VB6 to .NET 2005
Reply With Quote
  #8  
Old 06-23-2008, 11:01 PM
jo0lsRead the text from another programs listview control? jo0ls is offline
Senior Contributor

Forum Leader
* Expert *
 
Join Date: Feb 2005
Location: London
Posts: 1,050
Default

Translating from vb6 isn't that helpful usually. There are too many differences. If I can't find C# or VB.Net code, then I do them from scratch using the msdn library definitions and maybe the header files. There is a tonne of information on "Platform Invoke" in the msdn library. You just have to practice.

Here's a rough version, a cut down version (no comments, no exceptions, or error checking, or try..catch blocks). I'll post the other version when I'm done. It needs some classes derived from SafeHandle to wrap the HWNDS. And it should use SendMessageTimeout when reading captions, as otherwise if the external process is hung, so will SendMessage.

Code:
Option Strict On
Option Explicit On

Imports System.Runtime.InteropServices
Imports System.Text

Public Class Form1

    Private appCaption As String = "Explorer"
    Private WithEvents go As New Button
    Private info As New TextBox    
    Private listviewCaption As String = "FolderView"
    Private listviewClass As String = "SysListView32"
    Private listviewHandle As IntPtr
    Private nl As String = Environment.NewLine
    Private windowCaption As String = "C:\"
    Private windowClass As String = "CabinetWClass" ' Sometimes: "ExploreWClass"
    Private Const kernel32 As String = "kernel32"
    Private Const user32 As String = "user32"
    Private Const LVM_GETITEMCOUNT As UInteger = &H1004
    Private Const LVM_GETITEMTEXT As UInteger = &H102D
    Private Const MEM_COMMIT As UInteger = &H1000
    Private Const MEM_RELEASE As UInteger = &H8000
    Private Const PAGE_READWRITE As UInteger = 4
    Private Const PROCESS_VM_READ As UInteger = &H10
    Private Const PROCESS_VM_WRITE As UInteger = &H20
    Private Const PROCESS_VM_OPERATION As UInteger = &H8
    Private Const WM_GETTEXT As UInteger = &HD
    Private Const WM_GETTEXTLENGTH As UInteger = &HE
    
    Private Delegate Function EnumChildProcDelegate(ByVal hWnd As IntPtr, ByVal lParam As IntPtr) As Boolean

    <DllImport(kernel32, SetLastError:=True)> Private Shared Function CloseHandle(ByVal handle As IntPtr) As Boolean
    End Function
    <DllImport(user32, SetLastError:=True)> Private Shared Function EnumChildWindows(ByVal hWndParent As IntPtr, ByVal enumProcDelegate As EnumChildProcDelegate, ByVal lParam As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
    <DllImport(user32, CharSet:=CharSet.Unicode, SetLastError:=True)> Private Shared Function FindWindow(ByVal className As String, ByVal windowName As String) As IntPtr
    End Function
    <DllImport(user32, CharSet:=CharSet.Unicode, SetLastError:=True)> Private Shared Function GetClassName(ByVal hWnd As IntPtr, ByVal className As StringBuilder, ByVal bufferSize As Integer) As Integer
    End Function
    <DllImport(kernel32, SetLastError:=True)> Private Shared Function OpenProcess(ByVal dwDesiredAccess As UInteger, ByVal bInheritHandle As Boolean, ByVal dwProcessId As Integer) As IntPtr
    End Function
    <DllImport(kernel32, SetLastError:=True)> Private Shared Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As StringBuilder, ByVal nSize As Integer, ByRef bytesRead As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
    <DllImport(kernel32, SetLastError:=True)> Private Shared Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByRef lpBuffer As LV_ITEM, ByVal nSize As Integer, ByRef bytesRead As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
    <DllImport(user32, SetLastError:=True)> Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal message As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
    End Function
    <DllImport(user32, SetLastError:=True)> Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal message As UInteger, ByVal wParam As Integer, ByVal lParam As StringBuilder) As Integer
    End Function
    <DllImport(user32, SetLastError:=True)> Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal message As UInteger, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer
    End Function
    <DllImport(kernel32, SetLastError:=True)> Private Shared Function VirtualAllocEx(ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, ByVal dwSize As Integer, ByVal flAllocationType As UInteger, ByVal flProtect As UInteger) As IntPtr
    End Function
    <DllImport(kernel32, SetLastError:=True)> Private Shared Function VirtualFreeEx(ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, ByVal dwSize As Integer, ByVal dwFreeType As UInteger) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
    <DllImport(kernel32, SetLastError:=True)> Private Shared Function WriteProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByRef lpBuffer As LV_ITEM, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
    Public Structure LV_ITEM
        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
        Public iIndent As Integer
        Public iGroupId As Integer
        Public cColumns As Integer
        Public puColumns As IntPtr
        Public piColFmt As IntPtr
        Public iGroup As Integer
    End Structure

    Sub New()
        InitializeComponent()
        Me.Controls.Add(info)
        Me.Controls.Add(go)
        go.Text = "go"
        go.Location = New Point(Me.ClientSize.Width - go.Width - 5, Me.ClientSize.Height - go.Height - 5)
        go.Anchor = AnchorStyles.Right Or AnchorStyles.Bottom
        info.Width = Me.Width
        info.Multiline = True
        info.ScrollBars = ScrollBars.Vertical
        info.Height = go.Top - 5
        info.Anchor = AnchorStyles.Bottom Or AnchorStyles.Left Or AnchorStyles.Right Or AnchorStyles.Top
        Dim psi As New ProcessStartInfo("Explorer", "C:\")
        Process.Start(psi)
    End Sub

    Private Sub go_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles go.Click
        Dim hParent As IntPtr = FindWindow(windowClass, windowCaption)
        Dim del As New EnumChildProcDelegate(AddressOf EnumChildProc)
        EnumChildWindows(hParent, del, IntPtr.Zero)
        Dim itemCount As Integer = SendMessage(listviewHandle, LVM_GETITEMCOUNT, IntPtr.Zero, IntPtr.Zero)
        Dim id As Integer = -1
        For Each p In Process.GetProcessesByName(appCaption)
            If p.MainWindowTitle = windowCaption Then
                id = p.Id
            End If
        Next
        Dim hProcess As IntPtr = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE Or &H8, False, id)
        For index As Integer = 0 To itemCount - 1
            Dim lvi As New LV_ITEM
            lvi.cchTextMax = 260
            lvi.mask = 1
            lvi.iItem = index
            Dim pString As IntPtr = VirtualAllocEx(hProcess, IntPtr.Zero, 260, MEM_COMMIT, PAGE_READWRITE)
            lvi.pszText = pString
            Dim pLvItem As IntPtr = VirtualAllocEx(hProcess, IntPtr.Zero, Marshal.SizeOf(lvi), MEM_COMMIT, PAGE_READWRITE)            
            Dim success As Boolean = WriteProcessMemory(hProcess, pLvItem, lvi, Marshal.SizeOf(lvi), 0)
            Dim result As Integer = SendMessage(listviewHandle, LVM_GETITEMTEXT, index, pLvItem)
            Dim s As New StringBuilder(260)
            success = ReadProcessMemory(hProcess, pString, s, 260, 0)
            success = ReadProcessMemory(hProcess, pLvItem, lvi, Marshal.SizeOf(lvi), 0)
            success = VirtualFreeEx(hProcess, pString, 0, MEM_RELEASE)
            success = VirtualFreeEx(hProcess, pLvItem, 0, MEM_RELEASE)
            s.AppendLine()
            info.AppendText(s.ToString)
        Next
        CloseHandle(hProcess)        
    End Sub

    Private Function EnumChildProc(ByVal hWndChild As IntPtr, ByVal lParam As IntPtr) As Boolean
        Dim length As Integer = SendMessage(hWndChild, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero)        
        Dim captionBuilder As New StringBuilder(length + 1)
        If length > 0 Then
            Dim result As Integer = SendMessage(hWndChild, WM_GETTEXT, captionBuilder.Capacity, captionBuilder)
        End If
        If captionBuilder.ToString.Equals(listviewCaption) Then            
            Dim classBuilder As New StringBuilder(256)
            Dim result As Integer = GetClassName(hWndChild, classBuilder, classBuilder.Capacity - 1)
            If classBuilder.ToString.Equals(listviewClass) Then                
                listviewHandle = hWndChild
                Return False
            End If
        End If
        Return True
    End Function

End Class

Last edited by jo0ls; 06-24-2008 at 06:58 PM.
Reply With Quote
  #9  
Old 06-24-2008, 11:27 PM
jo0lsRead the text from another programs listview control? jo0ls is offline
Senior Contributor

Forum Leader
* Expert *
 
Join Date: Feb 2005
Location: London
Posts: 1,050
Default

Here's a commented example, with error checking and a SafeHandle for the process handle. It also grabs the header if it exists.

It's worth noting why this is not easy.

To get the text from the listview, you have to send an LV_ITEM strucutre:

SendMessage(hListView, LVM_GETITEMTEXT, itemIndex, item)


Where item is an instance of the LV_ITEM structure. With P/Invoke this is quite easy to do. We want to get the LV_ITEM back from the call,
and as it is a structure it is a value type, so we just pass it by ref. The marshaller will convert this to a pointer to the structure (if we pass
it by value, then it just sends the bytes of the structure itself, and we wouldn't see any changes on return.)

BUT: the Listview is in another process. And that process has its own virtual memory space. Therefore our pointer to a structure has no
meaning over there, it is pointing to memory in our process' virtual memory space which maps to different real memory to the virtual memory
in the other process. So, the other process doesn't have an LV_ITEM at the address we specified.

The solution is to allocate memory in the other process' memory space. You then write the LV_ITEM into that memory. You SendMessage with
the address of that memory, and this time it will work as the memory pointer is valid for the external process. Finally you read the memory back
from the remote process and clean up.
Attached Files
File Type: zip ReadExternalListView.zip (59.8 KB, 489 views)

Last edited by jo0ls; 06-25-2008 at 11:29 AM. Reason: Updated attachment
Reply With Quote
  #10  
Old 06-25-2008, 09:31 AM
appolospb appolospb is offline
Freshman
 
Join Date: Feb 2008
Posts: 39
Default

JOOLS:

Thank you very much for your help and contribution . You managed to give me a answer to a question that no one else could answer and even provided a .NET Sample lol. Without your code i wouldnt have been able to do the below:

I tried to use your sample program but couldnt run it due to it being VB 2008 and im running VB 2005. However all was not lost as i played around with the code you posted on this page instead .

Your orginal 'Explorer' code wouldnt work on my machine as window titles etc were different. However with a little playing around i managed to get that code working and then started on making a Nero Burning Rom listviewer (Supplied) thats .NET 2005 compatable .

I added some extra functionality. Your example only read 'ROW' data so if the listview had multiple columns you didnt get the text from the other coloum results. There was also a few other very minor bugs.

I will supply my code in the next post due to the 1000 character post limit
Reply With Quote
  #11  
Old 06-25-2008, 09:32 AM
appolospb appolospb is offline
Freshman
 
Join Date: Feb 2008
Posts: 39
Default

Code:
Imports System.Runtime.InteropServices
Imports System.Text

Public Class Form1

    Private WithEvents go As New Button
    Private info As New TextBox
    Private listviewHandle As IntPtr
    Private nl As String = Environment.NewLine
    Private Const kernel32 As String = "kernel32"
    Private Const user32 As String = "user32"
    Private Const LVM_GETITEMCOUNT As UInteger = &H1004
    Private Const LVM_GETITEMTEXT As UInteger = &H102D
    Private Const LVM_GETHEADER As UInteger = 4127
    Private Const HDM_GETITEMCOUNT As UInteger = 4608
    Private Const MEM_COMMIT As UInteger = &H1000
    Private Const MEM_RELEASE As UInteger = &H8000
    Private Const PAGE_READWRITE As UInteger = 4
    Private Const PROCESS_VM_READ As UInteger = &H10
    Private Const PROCESS_VM_WRITE As UInteger = &H20
    Private Const PROCESS_VM_OPERATION As UInteger = &H8
    Private Const WM_GETTEXT As UInteger = &HD
    Private Const WM_GETTEXTLENGTH As UInteger = &HE

    Private Delegate Function EnumChildProcDelegate(ByVal hWnd As IntPtr, ByVal lParam As IntPtr) As Boolean

    <DllImport(kernel32, SetLastError:=True)> Private Shared Function CloseHandle(ByVal handle As IntPtr) As Boolean
    End Function
    <DllImport(user32, SetLastError:=True)> Private Shared Function EnumChildWindows(ByVal hWndParent As IntPtr, ByVal enumProcDelegate As EnumChildProcDelegate, ByVal lParam As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
    <DllImport(user32, CharSet:=CharSet.Unicode, SetLastError:=True)> Private Shared Function FindWindow(ByVal className As String, ByVal windowName As String) As IntPtr
    End Function
    <DllImport(user32, CharSet:=CharSet.Unicode, SetLastError:=True)> Private Shared Function GetClassName(ByVal hWnd As IntPtr, ByVal className As StringBuilder, ByVal bufferSize As Integer) As Integer
    End Function
    <DllImport(kernel32, SetLastError:=True)> Private Shared Function OpenProcess(ByVal dwDesiredAccess As UInteger, ByVal bInheritHandle As Boolean, ByVal dwProcessId As Integer) As IntPtr
    End Function
    <DllImport(kernel32, SetLastError:=True)> Private Shared Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As StringBuilder, ByVal nSize As Integer, ByRef bytesRead As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
    <DllImport(kernel32, SetLastError:=True)> Private Shared Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByRef lpBuffer As LV_ITEM, ByVal nSize As Integer, ByRef bytesRead As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
    <DllImport(user32, SetLastError:=True)> Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal message As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
    End Function
    <DllImport(user32, SetLastError:=True)> Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal message As UInteger, ByVal wParam As Integer, ByVal lParam As StringBuilder) As Integer
    End Function
    <DllImport(user32, SetLastError:=True)> Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal message As UInteger, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer
    End Function
    <DllImport(kernel32, SetLastError:=True)> Private Shared Function VirtualAllocEx(ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, ByVal dwSize As Integer, ByVal flAllocationType As UInteger, ByVal flProtect As UInteger) As IntPtr
    End Function
    <DllImport(kernel32, SetLastError:=True)> Private Shared Function VirtualFreeEx(ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, ByVal dwSize As Integer, ByVal dwFreeType As UInteger) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
    <DllImport(kernel32, SetLastError:=True)> Private Shared Function WriteProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByRef lpBuffer As LV_ITEM, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
    Public Structure LV_ITEM
        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
        Public iIndent As Integer
        Public iGroupId As Integer
        Public cColumns As Integer
        Public puColumns As IntPtr
        Public piColFmt As IntPtr
        Public iGroup As Integer
    End Structure

    Sub New()
        InitializeComponent()
        Me.Controls.Add(info)
        Me.Controls.Add(go)
        go.Text = "go"
        go.Location = New Point(Me.ClientSize.Width - go.Width - 5, Me.ClientSize.Height - go.Height - 5)
        go.Anchor = AnchorStyles.Right Or AnchorStyles.Bottom
        info.Width = Me.Width
        info.Multiline = True
        info.ScrollBars = ScrollBars.Vertical
        info.Height = go.Top - 5
        info.Anchor = AnchorStyles.Bottom Or AnchorStyles.Left Or AnchorStyles.Right Or AnchorStyles.Top
    End Sub

    Private Sub go_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles go.Click

        Dim subitem As Integer
        ' This stores the column number currently being queried
        Dim hParent As IntPtr = FindWindow("#32770", "Choose Recorder(s)")
        ' Aquire the handle of the parent window containing the listview control

        Dim del As New EnumChildProcDelegate(AddressOf EnumChildProc)
        EnumChildWindows(hParent, del, IntPtr.Zero)

        Dim itemCount As Integer = SendMessage(listviewHandle, LVM_GETITEMCOUNT, IntPtr.Zero, IntPtr.Zero)
        ' Aquire the amount of rows in the listview
        Dim headerhandle As IntPtr = SendMessage(listviewHandle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero)
        ' Aquire the handle of the listviews header
        Dim coloumcount As Integer = SendMessage(headerhandle, HDM_GETITEMCOUNT, IntPtr.Zero, IntPtr.Zero)
        ' Aquire the amount of coloumns in the listview header

        Dim id As Integer = -1
        Dim p As Process

        For Each p In Process.GetProcessesByName("nero")
            ' See if 'Nero.exe' is running
            id = p.Id
            ' Grab the process ID of Nero
        Next

        Dim hProcess As IntPtr = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE Or &H8, False, id)
        For index As Integer = 0 To itemCount - 1
            ' For each of the rows do the following :
            For subitem = 0 To coloumcount
                ' For each of the columns do the following :

                Dim lvi As New LV_ITEM
                lvi.cchTextMax = 260
                lvi.iSubItem = subitem
                lvi.mask = 1
                lvi.iItem = index
                Dim pString As IntPtr = VirtualAllocEx(hProcess, IntPtr.Zero, 260, MEM_COMMIT, PAGE_READWRITE)
                lvi.pszText = pString
                Dim pLvItem As IntPtr = VirtualAllocEx(hProcess, IntPtr.Zero, Marshal.SizeOf(lvi), MEM_COMMIT, PAGE_READWRITE)
                Dim success As Boolean = WriteProcessMemory(hProcess, pLvItem, lvi, Marshal.SizeOf(lvi), 0)
                Dim result As Integer = SendMessage(listviewHandle, LVM_GETITEMTEXT, index, pLvItem)
                Dim s As New StringBuilder(260)
                success = ReadProcessMemory(hProcess, pString, s, 260, 0)
                success = ReadProcessMemory(hProcess, pLvItem, lvi, Marshal.SizeOf(lvi), 0)
                success = VirtualFreeEx(hProcess, pString, 0, MEM_RELEASE)
                success = VirtualFreeEx(hProcess, pLvItem, 0, MEM_RELEASE)
                s.AppendLine()
                info.AppendText(s.ToString)

            Next

        Next

        CloseHandle(hProcess)

    End Sub

    Private Function EnumChildProc(ByVal hWndChild As IntPtr, ByVal lParam As IntPtr) As Boolean

        Dim length As Integer = SendMessage(hWndChild, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero)
        Dim captionBuilder As New StringBuilder(length + 1)

        If length > 0 Then

            Dim result As Integer = SendMessage(hWndChild, WM_GETTEXT, captionBuilder.Capacity, captionBuilder)

        End If

        If captionBuilder.ToString.ToLower = "list1" Then
            ' If the captionbuilder string matches the 'title' of the listview control then :

            Dim classBuilder As New StringBuilder(256)
            Dim result As Integer = GetClassName(hWndChild, classBuilder, classBuilder.Capacity - 1)

            If classBuilder.ToString.ToLower = "syslistview32" Then
                ' If the captionbuilder string matches the 'classname' of the listview control then :

                listviewHandle = hWndChild
                ' Aquire the handle of the listview control

                Return False

            End If

        End If

        Return True

    End Function

End Class
The next thing i would love to be able to do is the following:

Select one of the rows in the listview control that contains text that meets my criteria. What i mean by 'Select' is simulate a one click mouse event so that row becomes highlighted and selected.

For eg if the row contains the word "DVD-RW" then select the drive, if it contains 'DVD Image Recorder' then dont select it

Last edited by appolospb; 06-25-2008 at 09:43 AM.
Reply With Quote
  #12  
Old 06-25-2008, 11:35 AM
jo0lsRead the text from another programs listview control? jo0ls is offline
Senior Contributor

Forum Leader
* Expert *
 
Join Date: Feb 2005
Location: London
Posts: 1,050
Default

Quote:
Originally Posted by appolospb View Post
I tried to use your sample program but couldnt run it due to it being VB 2008 and im running VB 2005.
Ah, its not using any 2008 specific stuff, so you could've started a new project and added the files manually. (not quite true, I accidentally used type inference)

I've altered the original, it includes a 2005 project in the zip now.

It doesn't seem to quite work on vista 64. It has ? chars in the date column.
Reply With Quote
  #13  
Old 06-27-2008, 09:04 AM
appolospb appolospb is offline
Freshman
 
Join Date: Feb 2008
Posts: 39
Default

Sorry to repeat but i think this got missed lol due to being posted under excessive lines of code:

The next thing i would love to be able to do is the following:

Select one of the rows in the listview control that contains text that meets my criteria. What i mean by 'Select' is simulate a one click mouse event so that row becomes highlighted and selected in the same way that you could select a row in excel or access for eg.
For eg if the row contains the word "DVD-RW" then select the drive, if it contains 'DVD Image Recorder' then dont select it
Reply With Quote
  #14  
Old 09-28-2008, 08:28 PM
appasri appasri is offline
Newcomer
 
Join Date: Aug 2008
Posts: 1
Default

JOOLS;
Why should we declare lvitem structure.Can't we use Listview or Lvitem class instead
appasri
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Read the text from another programs listview control?
Read the text from another programs listview control?
Read the text from another programs listview control? Read the text from another programs listview control?
Read the text from another programs listview control?
Read the text from another programs listview control?
Read the text from another programs listview control? Read the text from another programs listview control? Read the text from another programs listview control? Read the text from another programs listview control? Read the text from another programs listview control? Read the text from another programs listview control? Read the text from another programs listview control?
Read the text from another programs listview control?
Read the text from another programs listview control?
 
Read the text from another programs listview control?
Read the text from another programs listview control?
 
-->