читаю вот таким кодом, но чужой SysListView содержит 4 поля под каждый итем, этот код читает только первое поля, как корректно прочесть все поля? Код (Text): hwndRemoteSysListView := $0001023C; if hwndRemoteSysListView = 0 then ExitProcess(GetLastError); nItemCount := ListView_GetItemCount(hwndRemoteSysListView); // Получаем ID процесса, которому принадлежит найденное окно GetWindowThreadProcessId(hwndRemoteSysListView, @dwProcessID); if dwProcessID = 0 then ExitProcess(GetLastError); // Открываем процесс hProcess := OpenProcess(PROCESS_ALL_ACCESS, TRUE, dwProcessID); if hProcess = 0 then ExitProcess(GetLastError); // Выделяем в нем память под текстовый буффер pszText := VirtualAllocEx(hProcess, nil, cchTextMax, MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE); // Выделяем в нем память под структуру LVITEM plviRemoteLVItem := VirtualAllocEx(hProcess, nil, SizeOf(LV_ITEM), MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE); // Заполняем структуру ZeroMemory(@lviRemoteLVItem, SizeOf(LV_ITEM)); lviRemoteLVItem.mask := LVIF_TEXT; lviRemoteLVItem.pszText := pszText; lviRemoteLVItem.cchTextMax := cchTextMax; // Пишем ее в память удаленного процесса if not WriteProcessMemory(hProcess, plviRemoteLVItem, @lviRemoteLVItem, SizeOf(LV_ITEM), dwBytesWriten) then ExitProcess(GetLastError); // Выделяем в нем память под структуру TRect pRemoteRect := VirtualAllocEx(hProcess, nil, SizeOf(TRect), MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE); // Получаем текст со всех элементов for I := 0 to nItemCount - 1 do begin // Отправляем сообщение с указателем на выделенный буффер под LVITEM nTextLength := SendMessage(hwndRemoteSysListView, LVM_GETITEMTEXT, I, Integer(plviRemoteLVItem)); // Читаем результат ZeroMemory(@svText, cchTextMax); ReadProcessMemory(hProcess, lviRemoteLVItem.pszText, @svText[1], nTextLength, dwBytesWriten); // Чтобы получить координаты каждого элемента нужно подготовить структуру ZeroMemory(@ARect, SizeOf(TRect)); ARect.Left := LVIR_ICON; if not WriteProcessMemory(hProcess, pRemoteRect, @ARect, SizeOf(TRect), dwBytesWriten) then ExitProcess(GetLastError); // Посылаем сообщение для получения координат каждого элемента SendMessage(hwndRemoteSysListView, LVM_GETITEMRECT, I, Integer(pRemoteRect)); // Читаем результат ReadProcessMemory(hProcess, pRemoteRect, @ARect, SizeOf(TRect), dwBytesWriten); Writeln(Translate(PChar(@svText[1]))); Writeln(Translate( Format('- координаты: Left = %d, Top = %d, Right = %d, Bottom = %d', [ARect.Left, ARect.Top, ARect.Right, ARect.Bottom]))); end; // Освобождаем ранее выделенную память VirtualFreeEx(hProcess, pszText, 0, MEM_RELEASE); VirtualFreeEx(hProcess, plviRemoteLVItem, 0, MEM_RELEASE); // Закрываем описатель процесса CloseHandle(hProcess); end.
noname правду говорит, у ListView, как ни странно, вторая и последующие колонки тоже являются subitem'ами первой. Нормального ...Grid без выгибонов Микрософт не родила.
так и есть, всем спасибо, при чтении нужно было всеголишь установить LVItem.iSubItem := X, где X - номер колонки в записи
как программно нажать Enter в ListBox'е? не работают ни PostMessage WM_CHAR 13, ни WM_KEYDOWN VK_RETURN и даже keybd_event