Здравствуйте!
Прошу помощи, так как нигде не могу найти подсказки на вопрос о получении содержимого дерева SysTreeView32.
Встретил лишь следующее про ListView:
SendMessage(Wnd, LVM_GETITEMTEXT, Номер строки по списку, Указатель на структуру LVITEM);
А как найти (пройтись по структуре) текст из TVITEM? Мне надо получить текст ключей из списка дерева SysTreeView32. Чувствую здесь нужно выгружать TVM_GETITEM в буфер-указатель и... вот здесь загвоздка.
Должно быть как-то так:
TreeView_GetItem(hWin, TVITEM) или
SendMessage(Wnd, LVM_GETITEM, ?, Указатель на структуру TVITEM)
Если не сложно - про указатель поподробнее.
Буду всем очень благодарен кто откликнется! Всё. Спасибо.
Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице. Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.
28-03-2018 19:10
Тоже искал ответ на этот вопрос, нашёл вот это, и нашёл ошибку. Вместо:
УРА!!! Решение найдено!!! Передайте Handle окна-дерева, а результат пишется в MemoText (посредством mStrings)
function TreeNodeGetNext(mHandle: THandle; mTreeItem: HTreeItem): HTreeItem;
var
vParentID: HTreeItem;
begin
Result := nil;
if (mHandle <> 0) and (mTreeItem <> nil) then begin
Result := TreeView_GetChild(mHandle, mTreeItem);
if Result = nil then
Result := TreeView_GetNextSibling(mHandle, mTreeItem);
vParentID := mTreeItem;
while (Result = nil) and (vParentID <> nil) do begin
vParentID := TreeView_GetParent(mHandle, vParentID);
Result := TreeView_GetNextSibling(mHandle, vParentID);
end;
end;
end; { TreeNodeGetNext }
function TreeNodeGetLevel(mHandle: THandle; mTreeItem: HTreeItem): Integer;
var
vParentID: HTreeItem;
begin
Result := -1;
if (mHandle <> 0) and (mTreeItem <> nil) then begin
vParentID := mTreeItem;
repeat
Inc(Result);
vParentID := TreeView_GetParent(mHandle, vParentID);
until vParentID = nil;
end;
end; { TreeNodeGetLevel }
function GetTreeViewText(mHandle: THandle; mStrings: TStrings): Boolean;
var
vItemCount: Integer;
vBuffer: array[0..255] of Char;
vProcessId: DWORD;
vProcess: THandle;
vPointer: Pointer;
vNumberOfBytesRead: Cardinal;
I: Integer;
vItem: TTVItem;
vTreeItem: HTreeItem;
begin
Result := False;
if not Assigned(mStrings) then Exit;
GetWindowThreadProcessId(mHandle, @vProcessId);
vProcess := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or
PROCESS_VM_WRITE, False, vProcessId);
vPointer := VirtualAllocEx(vProcess, nil, 4096, MEM_RESERVE or MEM_COMMIT,
PAGE_READWRITE);
mStrings.BeginUpdate;
try
mStrings.Clear;
vItemCount := TreeView_GetCount(mHandle);
vTreeItem := TreeView_GetRoot(mHandle);
for I := 0 to vItemCount - 1 do begin
with vItem do begin
mask := TVIF_TEXT;
cchTextMax := SizeOf(vBuffer);
pszText := Pointer(Cardinal(vPointer) + SizeOf(vItem));
hItem := vTreeItem;
end;
WriteProcessMemory(vProcess, vPointer, @vItem,
SizeOf(vItem), vNumberOfBytesRead);
SendMessage(mHandle, TVM_GETITEM, 0, lparam(vPointer));
ReadProcessMemory(vProcess, Pointer(Cardinal(vPointer) + SizeOf(TLVItem)),
@vBuffer[0], SizeOf(vBuffer), vNumberOfBytesRead);
mStrings.Add(StringOfChar(#9, TreeNodeGetLevel(mHandle, vTreeItem)) + vBuffer);
vTreeItem := TreeNodeGetNext(mHandle, vTreeItem);
end;
finally
VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE);
CloseHandle(vProcess);
mStrings.EndUpdate;
end;
Result := True;
end; { GetTreeViewText }
Да, SysTreeView32 это аналог ShellTreeView в Windows. Мне уже удалось разобраться с тем, как получить Handle данного объекта-дерева (это - окно) в требуемом приложении. Чтобы получить элементы дерева (ветви и текст в них)надо получить доступ к объекту через буфер-указатель, так как иначе попадаем в собственное приложение. Некоторые варианты я уже нашёл (часто встречается пример перехода на на нужный ключ в Regedit). Осталось разобраться с резервированием памяти и чтения из неё структуры HTREEITEM. С теорией на msdn2.microsoft.com уже ознакомился. Неплохой пример нашёл здесь http://bugtraq.ru/cgi-bin/forum.mcgi?type=sb&b=2&m=139991 и очень близко вот это http://64.233.183.104/search?q=cache:-mGhfL63J1EJ:aspjspphp.net/html/Delphi_Perl/20070428_2128.html+GetTreeViewText&hl=en&ct=clnk&cd=1 (извините если нельзя, так как не знаю можно ли так публиковать ссылки...)
Для дерева события начинаются на TVM_*** - ищите среди них то, что вам нужно. Только с Вашим компонентом не знаком - стандартный компонент в Delphi имеет имя ShellTreeView, а ваш наверное либо наследник, либо аналог.
Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Функция может не работать в некоторых версиях броузеров.