问个问题,看看还有没有大神能解决。
delphi吧
全部回复
仅看楼主
level 3
梁红玉 楼主
我想获取其他程序的systreeview32的内容(如注册表左边栏),也参考了很多网上的资料,在CSDN上有一篇文章,我复制了代码过来,但是无法获取到treeview中的内容,具体代码如下:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
Winapi.CommCtrl, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
{$R *.dfm}
implementation
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);
if vParentID <> nil then
Result := TreeView_GetNextSibling(mHandle, vParentID);
end;
end;
end;
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;
function GetTreeViewText(mHandle: THandle; mStrings: TStrings): Boolean;
var
vItemCount: Integer;
vBuffer: array[0..255] of Char;
vProcessId: DWORD;
vProcess: THandle;
vPointer: Pointer;
vNumberOfBytesRead: SIZE_T;
I: Integer;
vItem: TTVItemex;
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, SizeOf(TTVItem), MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);
mStrings.BeginUpdate;
try
mStrings.Clear;
vItemCount := TreeView_GetCount(mHandle);
vTreeItem := TreeView_GetRoot(mHandle);
if vTreeItem = nil then
ShowMessage('getroot error');
for I := 0 to vItemCount - 1 do
begin
with vItem do
begin
mask := TVIF_TEXT;
cchTextMax := SizeOf(vBuffer);
pszText := vBuffer;
hItem := vTreeItem;
end;
WriteProcessMemory(vProcess, vPointer, @vItem, SizeOf(vItem), vNumberOfBytesRead);
if SendMessage(mHandle, TVM_GETITEM, 0, LPARAM(vPointer)) = 0 then
begin
ShowMessage('SendMessage failed. Error code: ' + IntToStr(GetLastError) +
#13#
10 + SysErrorMessage(GetLastError));
Exit;
end
else
begin
ReadProcessMemory(vProcess, @vBuffer[0], vPointer, SizeOf(vBuffer), vNumberOfBytesRead);
mStrings.Add(StringOfChar(#9, TreeNodeGetLevel(mHandle, vTreeItem)) + vBuffer);
mStrings.Add(string(vBuffer));
vTreeItem := TreeNodeGetNext(mHandle, vTreeItem);
end;
end;
finally
VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE);
CloseHandle(vProcess);
mStrings.EndUpdate;
end;
Result := True;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
GetTreeViewText(StrToInt(Edit1.Text), Memo1.Lines);//edit1.text是注册表systreeview32的句柄
end;
end.
困扰很久了。一直解决不了.
编程环境是win1022h2+delphi 10 seattle.
2023年12月12日 10点12分 1
level 14
拿到句柄然后一层层往下找,找到对应控件就取text
2023年12月13日 03点12分 2
我只能拿到SysTreeView32的句柄,里面每个小节点的句柄拿不到,要怎么拿?如跟帖的图片,这里发不了,只能跟帖了。
2023年12月13日 11点12分
level 13
你确认了那个是systreeview32
2023年12月13日 06点12分 3
是SysTreeView32,如跟帖所示。
2023年12月13日 11点12分
level 3
梁红玉 楼主
注册表句柄如图:
2023年12月13日 11点12分 4
level 3
梁红玉 楼主
顶一个吧,希望有人能解答。
2023年12月22日 01点12分 5
level 1
把代码打包发我,我调试看下。
2023年12月23日 05点12分 6
不用打包,直接新建一个form,放一个edit,memo,button,然后直接复制以上代码就好了(procedure Button2Click(Sender: TObject);这句删掉)。
2023年12月23日 12点12分
level 12
32位和64位结构体是不一样的,如果是编译的32位程序要操作64位进程控件,要改结构体的吧。把程序编译成64位应该问题不大
2024年01月26日 14点01分 7
1