Registriert seit: 17. Jan 2007
1.169 Beiträge
Turbo Delphi für Win32
|
Re: Rechtsklick auf TreeView Item in einem Fenster
26. Aug 2007, 13:51
Hi,
mit einer Rekursion könnte man von allen Items den Text und dann die Position auslesen. Mein Lösungsansatz sieht so aus:
Delphi-Quellcode:
procedure TreeItemRect(hTree: THandle);
const
BufferSize= 1024;
var
MemL, MemR : Pointer;
hProc : THandle;
procedure NextItem(hItem: HTREEITEM; Code: Integer);
var
BytesR, BytesW: Cardinal;
ItemRect, TreeRect: TRect;
begin
while Assigned(hItem) do
begin
ZeroMemory(MemL, BufferSize);
PTVItem(MemL)^.hItem:= hItem;
PTVItem(MemL)^.mask:= TVIF_TEXT or TVIF_CHILDREN;
PTVItem(MemL)^.pszText:= Pointer(Cardinal(MemR)+ SizeOf(TTvItem)+ SizeOf(TRect));
PTVItem(MemL)^.cchTextMax:= BufferSize- SizeOf(TTVItem)- SizeOf(TRect);
HTreeItem(Pointer(Cardinal(MemL)+ SizeOf(TTvItem))^):= hItem;//GETITEMRECT
if WriteProcessMemory(hProc, MemR, MemL, BufferSize, BytesW)
and (SendMessage(hTree, TVM_GETITEM, 0, LPARAM(MemR))> 0)
and ReadProcessMemory(hProc, MemR, MemL, BufferSize, BytesR)
and (SendMessage(hTree, TVM_GETITEMRECT, Integer(true), Cardinal(MemR)+ SizeOf(TTvItem))> 0)//GETITEMRECT
and ReadProcessMemory(hProc, Pointer(Cardinal(MemR)+ SizeOf(TTvItem)), Pointer(Cardinal(MemL)+ SizeOf(TTvItem)), SizeOf(TRect), BytesR) then
begin
ItemRect:= PRect(Cardinal(MemL)+ SizeOf(TTvItem))^;
if PChar(Cardinal(MemL) + SizeOf(TTVItem)+ SizeOf(TRect))= 'Arbeitsplatz' then
begin
windows.GetWindowRect(hTree, TreeRect);
SetCursorPos(TreeRect.Left+ (ItemRect.Right+ ItemRect.Left) div 2, TreeRect.Top+ (ItemRect.Bottom+ ItemRect.Top) div 2);
mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
end;
//Form1.ListBox1.Items.Add(format('Text= %s Left= %d Top= %d', [PChar(Cardinal(MemL) + SizeOf(TTVItem)+ SizeOf(TRect)), ItemRect.Left, ItemRect.Top]) );
end;
NextItem(Treeview_GetNextItem(hTree, hItem, TVGN_CHILD), 0);
hItem := TreeView_GetNextItem(hTree, hItem, TVGN_NEXT);
end;
end;
var
ProcessId: DWORD;
hTVItem: HTREEITEM;
begin
GetWindowThreadProcessId(hTree, @ProcessId);
hProc := OpenProcess(PROCESS_ALL_ACCESS, False, ProcessId);
if hProc > 0 then
try
MemL:= VirtualAlloc(nil, BufferSize, MEM_COMMIT, PAGE_READWRITE);
MemR:= VirtualAllocEx(hProc, nil, BufferSize, MEM_COMMIT, PAGE_READWRITE);
try
if Assigned(MemL) and Assigned(MemR) then
begin
hTVItem:= TreeView_GetRoot(hTree);
NextItem(hTVItem, 0);
end;
finally
if Assigned(MemR) then
VirtualFreeEx(hProc, MemR, 0, MEM_RELEASE);
if Assigned(MemL) then
VirtualFree(MemL, 0, MEM_RELEASE);
end;
finally
CloseHandle(hProc);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
sleep(2000);
TreeItemRect(...);
end;
Wie zu sehen ist funktioniert dieser Code nur auf Windows NT 32-Bit Systemen.
Getestet habe ich das Ganze mit dem Windows Explorer unter Windows XP. Es wird dort ein Rechtsklick auf das Item Arbeitsplatz durchgeführt.
EDIT: Der Code wurde noch etwas überarbeitet.
Gruß bitsetter
"Viele Wege führen nach Rom" Wolfgang Mocker (geb. 1954), dt. Satiriker und Aphoristiker
|