none
他アプリのリストビューに表示されているデータの取得 RRS feed

  • 質問

  • VB2005初心者です。

    VB2005+Vista環境で他アプリのリストビューに表示されているデータの取得するするには、どのようにすればよいでしょうか。

    ここ<http://www.vbforums.com/showthread.php?t=217372>を参考にしてコードを書いてみましたがうまく動作しません。

    大変恐れ入りますが、より良い実装方法をご教示いただきたく存じます。

     

    [Code]

     

       Private Const LVM_FIRST = &H1000
        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 Integer = 255
        Public Const MEM_COMMIT = &H1000
        Private Const MEM_RELEASE = &H8000
        Public Const PAGE_READWRITE = &H4
        Public Const LVIF_TEXT As Integer = &H1
        Private Const LVM_GETITEMTEXT = LVM_FIRST + 45
        Private Const LVM_GETITEMCOUNT = LVM_FIRST + 4

        Public Structure LV_ITEM
            Dim mask As Integer
            Dim iItem As Integer
            Dim iSubItem As Integer
            Dim state As Integer
            Dim stateMask As Integer
            Dim pszText As IntPtr
            Dim cchTextMax As Integer
            Dim iImage As Integer
            Dim lParam As Integer
            Dim iIndent As Integer
        End Structure

        Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Integer, ByVal bInheritHandle As IntPtr, ByVal dwProcId As Integer) As Integer
        Public Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As IntPtr, ByVal lpAddress As Integer, ByVal dwSize As Integer, ByVal flAllocationType As Integer, ByVal flProtect As Integer) As Integer
        Public Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As IntPtr, ByVal lpAddress As Integer, ByVal dwSize As Integer, ByVal dwFreeType As Integer) As Integer
        Public Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As IntPtr, ByVal lpBaseAddress As Integer, ByVal lpBuffer As Integer, ByVal nSize As Integer, ByVal lpNumberOfBytesWritten As Integer) As Integer
        Public Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As IntPtr, ByVal lpBaseAddress As Integer, ByVal lpBuffer As LV_ITEM, ByVal nSize As Integer, ByVal lpNumberOfBytesWritten As Integer) As Integer
        Public Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As IntPtr, ByVal lpBaseAddress As Integer, ByVal lpBuffer As Integer, ByVal nSize As Integer, ByVal lpNumberOfBytesWritten As Integer) As Integer
        Public Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As IntPtr, ByVal lpBaseAddress As Integer, ByVal lpBuffer As LV_ITEM, ByVal nSize As Integer, ByVal lpNumberOfBytesWritten As Integer) As Integer
        Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As IntPtr, ByVal lpdwProcessId As Integer) As Integer
        Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
        Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As IntPtr) As Integer

        Public Function GetListviewItem(ByVal hWindow As IntPtr, ByVal ProcessID As Integer, ByVal pColumn As Integer, ByVal pRow As Integer) As String
            Dim result As Integer
            Dim myItem As LV_ITEM
            Dim pHandle As IntPtr
            Dim pStrBufferMemory As Integer
            Dim pMyItemMemory As Integer
            Dim strBuffer() As Byte
            Dim index As Integer
            Dim tmpString As String = ""

            GetListviewItem = ""

            '**********************
            '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 = New LV_ITEM

            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, 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, 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


     

    2007年5月20日 15:24

すべての返信

  • 巧く動作しない、とだけ言われても困ります。

    まず、ステップ実行するなりしてどこで意図しない結果(返値が期待していない値になっているとか)になっているのかを切り分けてください。

    2007年5月21日 0:54
  • > Vista環境で他アプリ

     

    Windows Vista からは、 どうやっても手を出せない Window が出来ました。
    それに引っ掛かってるとか?

     

    参考 → .NET Framework 全般 >> C++:OpenProcesssが失敗する。

    2007年5月21日 8:13
  • ご指摘ありがとうございます。

    まずはXP環境にて再確認をいたしましたところ、

     pMyItemMemory = VirtualAllocEx(pHandle, 0, Len(myItem), MEM_COMMIT, PAGE_READWRITE)

    の第3引数の指定方法が正しくないと判明しましたが、正しい記述方法がよくわかりません。

    どういった記述にすればよいでしょうか?

    ご教示の程、よろしくお願いいたします。

     

    2007年5月23日 9:56