Para esa tarea, Windows tiene previsto el acceso a través de mensajes encapsulados en macros estilo C: List View, la pega es que no funcionan si se trata de acceder desde un proceso distinto, se debe a la compartimentación de la memoria aislada entre procesos. Pudiera parecer que es un escollo insalvable, pero no lo es si "invadimos" el proceso a espiar, para eso están las APIs VirtualAllocEx, WriteProcessMemory y ReadProcessMemory.
Armados con estas APIs y obteniendo el Handle del proceso anfitrión podemos invadir su memoria y extraer los datos que buscamos.
Lo que sigue es un ejemplo que fisgonea en un ListView de un proceso ajeno coniciendo previamente el Handle de ventana de dicho control y las coordenadas del "mouse" donde se encuentra el Item a asaltar, obtenemos los subitems. El sumitem[0] representa el texto principal del Item mientras que números superiores representan los siguientes subitems en orden.
El código está diseñado para encajarlo en WinInfo, que ya se encarga de obtener el Handle y las coordenadas necesarias pero se puede adaptar para uso en otros entronos.
delphi
function GetLVText(hListView: HWND; X, Y: integer; iSubItem: Cardinal): String; var pid: DWORD; hProcess: THANDLE; IInfo: TLVHITTESTINFO; _IInfo: PLVHITTESTINFO; Index: integer; Buffer: array [0..511] of CHAR; _Buffer: PCHAR; Item: TLVITEM; _Item: PLVITEM; begin Result:= ''; GetWindowThreadProcessId(hListView, pid); hProcess:= OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE or PROCESS_QUERY_INFORMATION, FALSE, pid); if hProcess <> THANDLE(0) then begin // Encontramos el índice del LVItem en X, Y Index:= -1; IInfo.pt:= Point(10, Y); _IInfo:= VirtualAllocEx(hProcess, nil, sizeof(TLVHITTESTINFO), MEM_COMMIT, PAGE_READWRITE); WriteProcessMemory(hProcess, _IInfo, @IInfo, sizeof(TLVHITTESTINFO), PDWORD(0)^); Index:= ListView_HitTest(hListView, _IInfo^); if Index >= 0 then begin // Encontramos el Texto del Item _Buffer:= VirtualAllocEx(hProcess, nil, sizeof(Buffer), MEM_COMMIT, PAGE_READWRITE); _Item:= VirtualAllocEx(hProcess, nil, sizeof(TLVITEM), MEM_COMMIT, PAGE_READWRITE); Item.iSubItem:= iSubItem; Item.pszText:= _Buffer; Item.cchTextMax:= sizeof(Buffer); WriteProcessMemory(hProcess, _Item, @Item, sizeof(TLVITEM), PDWORD(0)^); SendMessage(hListView, LVM_GETITEMTEXT, Index, Cardinal(_Item)); ReadProcessMemory(hProcess, _Buffer, @Buffer[0], sizeof(Buffer), PDWORD(0)^); Result:= String(Buffer); // Liberamos memoria del proceso VirtualFreeEx(hProcess, _Item, 0, MEM_RELEASE); VirtualFreeEx(hProcess, _Buffer, 0, MEM_RELEASE); end; // Liberamos memoria del proceso VirtualFreeEx(hProcess, _IInfo, 0, MEM_RELEASE); end; end;
Saludos.