Нужно получить структуру дерева чужой программы.
Обсуждалось тут
https://www.sql.ru/forum/210543/izvlechenie-informacii-iz-chuzhogo-treeview
но так и не нашли решение
Обходим узлы первого уровня, но вот в текст TreeItem получить не выходит. Возвращается пустая строка.
Может кто сталкивался с подобным? В чём может быть проблема?
procedure GetItemsText(hTreeView:hwnd);
var hProcess:LongInt;
pMem1, pMem2:Pointer;
pID:Cardinal;
tWindow:LongInt;
w: QWord;
hItem:HTREEITEM;
tvi:TV_ITEM;
s:string;
begin
tWindow := GetParent(hTreeView);
while GetParent(tWindow) <> 0 do
tWindow := GetParent(tWindow);
// По этому дескриптору получаем ID процесса:
GetWindowThreadProcessId(tWindow, pID);
// Открываем процесс с правами записи и чтения:
hProcess := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, False, pID);
// Если не получилось - выходим:
if hProcess = 0 then Exit;
// Резервируем кусок памяти в контексте процесса:
pMem1 := nil;
pMem2 := nil;
pMem1 := VirtualAllocEx(hProcess, nil, SizeOf(tvi), MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);
pMem2 := VirtualAllocEx(hProcess, nil, 255, MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);
if (pMem1 <> nil) and (pMem2 <> nil) then
// если получилось, то начинаем работу:
// ==========================================================
begin
hItem := HTREEITEM(SendMessage(hTreeView, TVM_GETNEXTITEM, TVGN_ROOT, 0));
while LongInt(hItem) <> 0 do
begin
SetLength(s, 255);
FillChar(s[1], 255, #0);
WriteProcessMemory(hProcess, pMem2, @s[1], 255, w);
// заполняем поля структуры:
tvi.hItem := hItem;
tvi.mask := TVIF_TEXT + TVIF_HANDLE;
tvi.cchTextMax := 255;
tvi.pszText := @pMem2;
// копируем структуру в память процесса:
WriteProcessMemory(hProcess, pMem1, @tvi, SizeOf(tvi), w);
// посылаем сообщение дереву:
SendMessage(hTreeView, TVM_GETITEM, 0, Int64(pMem1));
// копируем строку-результат обратно в свою память:
ReadProcessMemory(hProcess, pMem2, @s[1], 255, w);
// выводим ее
Form1.Memo1.Lines.Append(inttostr(LongInt(hitem))+':'+s);
// переходим к следующему:
hItem :=HTREEITEM( SendMessage(hTreeView, TVM_GETNEXTITEM, TVGN_NEXT, LongInt(hItem)));
end;
// =========================================================
VirtualFreeEx(hProcess, pMem1, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, pMem2, 0, MEM_RELEASE);
// Закрываем процесс:
// CloseHandle(hProcess);
end;
end;