Мое почтение, джентльмены. Довелось мне писать программу для взаимодействия с чужим софтом. В этом софте есть контрол TVirtualStringTree, из которого необходимо получать текст. И вот, как говорится, «И что я только уже не пробовала.». С этим контролом невозможно вообще ничего сделать. Гугл не помогает, аналогичные проблемы не нашли решения.
Что я пробовал:
— Получить root этого дерева
RootTree := SendMessage(HandleTree, TVM_GETNEXTITEM, TVGN_ROOT, 0);
Тут проблем не возникает. Дерево с радостью отдает свой рут.
— Открыть процесс который содержит дерево
GetWindowThreadProcessID(HandleTree, @ProcessID);
ProcessHanlde := OpenProcess(PROCESS_ALL_ACCESS, False, ProcessID);
Опять же, проблем не возникло.
— Выделить память под TV_ITEM в открытом процессе
PItem := VirtualAllocEx(ProcessHanlde, nil, SizeOf(TV_ITEM), MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);
И снова все гладко.
— Заполнить структуру TV_ITEM
with LItem do
begin
hItem := HTreeItem(RootTree);
mask := TVIF_HANDLE;
end;
Надеюсь правильно.
— Записать эту структуру в выделеную память открытого процесса
WriteProcessMemory(ProcessHanlde, PItem, @LItem, SizeOf(LItem), Dummy);
Все нормально записывается, в Dummy возвращается 40.
— Получить структуру описывающую Root
if TreeView_GetItem(HandleTree, PItem^) then
begin
ReadProcessMemory(ProcessHanlde, PItem, @LItem, SizeOf(LItem), Dummy);
end;
А вот тут сплошное разочарование, макрос всегда возвращает False. Что я сделал не так? Где ошибся?
Я так же пробовал получить другие Item'ы, кроме рута:
SomeItem := SendMessage(HandleTree, TVM_GETNEXTITEM, TVGN_CHILD, RootTree);
но их нет. Или дерево их тщательно скрывает.
Даже просто удалить рут не выходит. Что же делать?
Дерево на котором я все это тестирую выглядит вот так:
Очень большие подозрения, что все эти проблемы связаны с устройством дерева.