当其他程序syslistview32中lvs_ownerdrawfixed设置为true时产生的数据如何读取。
下面的方法读取不出来,请高手帮忙Option ExplicitPrivate Const MEM_RELEASE = &H8000Private Const LVM_FIRST = &H1000
Private Const LVM_GETHEADER = LVM_FIRST + 31
Private Const LVM_GETITEMCOUNT = (LVM_FIRST + 4)Private Const LVM_GETITEM = (LVM_FIRST + 5)
Private Const LVM_GETSTRINGWIDTH = (LVM_FIRST + 17)
Private Const LVM_GETCOLUMN = (LVM_FIRST + 25)
Private Const LVM_GETITEMTEXT = (LVM_FIRST + 45)
Private Const HDM_FIRST = &H1200
Private Const HDM_GETITEMCOUNT = (HDM_FIRST + 0)
Private Const HDM_ORDERTOINDEX = (HDM_FIRST + 15)Private Const PROCESS_QUERY_INFORMATION = 1024
Private Const PROCESS_VM_OPERATION = &H8
Private Const PROCESS_VM_READ = &H10
Private Const PROCESS_VM_WRITE = &H20
Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
Private Const MAX_LVMSTRING As Long = 255
Private Const MEM_COMMIT = &H1000
Private Const PAGE_READWRITE = &H4
Private Const LVIF_TEXT As Long = &H1Private Const LVM_GETCOLUMNCOUNT = &HF11BPrivate Type LV_ITEMA
   mask         As Long
   iItem        As Long
   iSubItem     As Long
   state        As Long
   stateMask    As Long
   pszText      As Long
   cchTextMax   As Long
   iImage       As Long
   lParam       As Long
   iIndent      As Long
End TypePrivate Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
Private Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As Long, ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
Private Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As Long, ByVal lpAddress As Long, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByRef lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByRef lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As LongPrivate Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As LongPrivate Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function GetCurrentProcessId Lib "kernel32" () As LongPrivate Function GetListViewTextArray(ByVal hWindow As Long, ByVal ProcessID As Long) As String()
    Dim result              As Long
    Dim myItem()              As LV_ITEMA
    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
    Dim i As Integer, sum As Integer, j As Integer, hCount As Long
    Dim strArr() As String, itemString As String
    hCount = SendMessage(hWindow, LVM_GETHEADER, 0, 0)
    If hCount > 0 Then
        hCount = SendMessage(hCount, HDM_GETITEMCOUNT, 0, 0)
    Else
        hCount = 0
    End If
    ReDim strBuffer(MAX_LVMSTRING)
    pHandle = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, ProcessID)
    ReDim myItem(hCount)
    For j = 0 To SendMessage(hWindow, LVM_GETITEMCOUNT, 0, 0) - 1
        For i = 0 To hCount
            pStrBufferMemory = VirtualAllocEx(pHandle, 0, MAX_LVMSTRING, MEM_COMMIT, PAGE_READWRITE)
            myItem(i).mask = LVIF_TEXT
            myItem(i).iSubItem = i
            myItem(i).pszText = pStrBufferMemory
            myItem(i).cchTextMax = MAX_LVMSTRING
            
            pMyItemMemory = VirtualAllocEx(pHandle, 0, Len(myItem(i)), MEM_COMMIT, PAGE_READWRITE)
            result = WriteProcessMemory(pHandle, pMyItemMemory, myItem(i), Len(myItem(i)), 0)
            result = SendMessage(hWindow, LVM_GETITEMTEXT, j, ByVal pMyItemMemory)
            If result = 0 Then
                result = VirtualFreeEx(pHandle, pStrBufferMemory, 0, MEM_RELEASE)
                result = VirtualFreeEx(pHandle, pMyItemMemory, 0, MEM_RELEASE)
                Exit For
            End If
            result = ReadProcessMemory(pHandle, pStrBufferMemory, strBuffer(0), MAX_LVMSTRING, 0)
            result = ReadProcessMemory(pHandle, pMyItemMemory, myItem(i), Len(myItem(i)), 0)
            tmpString = StrConv(strBuffer, vbUnicode)
            tmpString = Left(tmpString, InStr(tmpString, vbNullChar) - 1)
            itemString = itemString & tmpString & ","
            result = VirtualFreeEx(pHandle, pStrBufferMemory, 0, MEM_RELEASE)
            result = VirtualFreeEx(pHandle, pMyItemMemory, 0, MEM_RELEASE)
        Next
        ReDim Preserve strArr(0 To sum)
        strArr(j) = Left(itemString, Len(itemString) - 1)
        sum = sum + 1
        itemString = ""
    Next
    result = CloseHandle(pHandle)
    GetListViewTextArray = strArr
End Function
Private Sub Command1_Click()
    Dim itemStr() As String, i As Integer
    
    itemStr = GetListViewTextArray(&H2A038E, 4964)    For i = 0 To UBound(itemStr)
        MsgBox itemStr(i)
    Next
End Sub

解决方案 »

  1.   

    远程子类化,然后捕获并处理LVN_GETDISPINFO消息
      

  2.   

    来源MiniSpy源代码,仅供参考
    void MyGetListViewItem(HWND hWindow,TStrings *strlist)
    {
        const nMaxLen=1023;
        char szBuf[nMaxLen+1];
        char buf[nMaxLen+1];    int          nLVItemCount;
        int          nColumns;
        DWORD        dwProcessID;
        HANDLE       hProcess;
        HANDLE       hHeaderCtrl;
        LVITEM       lvItemLocal;
        HDITEM       hdItemLocal;
        DWORD        dwBytesRead, dwBytesWrite;
        bool         bSuccess,bWriteOK;    //注意:本文来自www.ccrun.com,by ccrun(老妖),转载请注明出处。
        //本文转自 C++Builder研究 - http://www.ccrun.com/article.asp?i=583&d=eahk4z
        //为防止某些不负责任的转载者,故出此下策,在代码中加入声明,请大家原谅。    GetWindowThreadProcessId(hWindow,&dwProcessID);
        hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessID);
        if(!hProcess)  //得不到指定进程的句柄
            return;
        //在指定进程内分配存储空间
        LPVOID lpTextRemote=VirtualAllocEx(hProcess,NULL,nMaxLen+1,MEM_COMMIT,PAGE_READWRITE);
        LPVOID lpListItemRemote=VirtualAllocEx(hProcess,NULL,sizeof(LVITEM),MEM_COMMIT,PAGE_READWRITE);
        LPVOID lpHeadItemRemote=VirtualAllocEx(hProcess,NULL,sizeof(HDITEM),MEM_COMMIT,PAGE_READWRITE);
        if((!lpTextRemote) || (!lpListItemRemote) || (!lpHeadItemRemote)) //不能在指定进程内分配存储空间
            return;    nLVItemCount=ListView_GetItemCount(hWindow);
        hHeaderCtrl=ListView_GetHeader(hWindow);
        nColumns=Header_GetItemCount(hHeaderCtrl);
        if (nColumns<=0) {
            nColumns=1;
        } else {
            buf[0]=0;
            for (int j=0;j<nColumns;j++) {
                ZeroMemory(szBuf,nMaxLen+1);
                bWriteOK= WriteProcessMemory(hProcess,lpTextRemote,(LPVOID)szBuf,nMaxLen+1,(LPDWORD)&dwBytesWrite);
                if(!bWriteOK) //写内存错误
                    return;
                hdItemLocal.mask=HDI_TEXT;
                hdItemLocal.cchTextMax=nMaxLen;
                hdItemLocal.pszText=(LPTSTR)lpTextRemote;
                dwBytesWrite=0;
                bWriteOK=WriteProcessMemory(hProcess,lpHeadItemRemote,(LPVOID)&hdItemLocal,sizeof(HDITEM),(LPDWORD)&dwBytesWrite);
                if(!bWriteOK) //写内存错误
                    return;            SendMessage(hHeaderCtrl,HDM_GETITEM,(WPARAM)j,(LPARAM)lpHeadItemRemote);
                bSuccess=ReadProcessMemory(hProcess,lpTextRemote,szBuf,nMaxLen+1,&dwBytesRead);
                //从指定进程存储空间读取文本
                if(!bSuccess) //不能在指定进程内读取文本
                    return;
                if (j>0) strcat(buf,"|");
                strcat(buf,AnsiString(szBuf).c_str());
            }
            strlist->Add(buf);
        }
    //  strlist->Add("ListView的Columns数: " + String(nColumns));
    //  strlist->Add("---------------------------");    for (int i=0;i<nLVItemCount;i++) {
            buf[0]=0;
            for (int j=0;j<nColumns;j++) {
                ZeroMemory(szBuf,nMaxLen+1);
                bWriteOK= WriteProcessMemory(hProcess,lpTextRemote,(LPVOID)szBuf,nMaxLen+1,(LPDWORD)&dwBytesWrite);
                if(!bWriteOK) //写内存错误
                    return;
                lvItemLocal.iItem=i;
                lvItemLocal.iSubItem=j;
                lvItemLocal.mask=LVIF_TEXT;
                lvItemLocal.cchTextMax=nMaxLen;
                lvItemLocal.pszText=(LPTSTR)lpTextRemote;
                dwBytesWrite=0;
                bWriteOK=WriteProcessMemory(hProcess,lpListItemRemote,(LPVOID)&lvItemLocal,sizeof(LVITEM),(LPDWORD)&dwBytesWrite);
                if(!bWriteOK) //写内存错误
                    return;
                SendMessage(hWindow,LVM_GETITEMTEXT,(WPARAM)i,(LPARAM)lpListItemRemote);
                bSuccess=ReadProcessMemory(hProcess,lpTextRemote,szBuf,nMaxLen+1,&dwBytesRead);
                //从指定进程存储空间读取文本
                if(!bSuccess) //不能在指定进程内读取文本
                    return;
                if (j>0) strcat(buf,"|");
                strcat(buf,AnsiString(szBuf).c_str());
            }
            strlist->Add(buf);
        }//end of for(i)
        //在指定进程内释放存储空间
        VirtualFreeEx(hProcess,lpListItemRemote,0,MEM_RELEASE);
        VirtualFreeEx(hProcess,lpTextRemote,0,MEM_RELEASE);
        //关闭指定进程句柄
        CloseHandle(hProcess);
    }
      

  3.   

    用Spy4Win软件,里面有产生抓取对象内容VB源代码片断功能
      

  4.   

    Spy4Win抓不到里面的内容,因为里面的内容是在listview的ownerdraw中添加的