![]() |
Rechtsklick auf TreeView Item in einem Fenster
Hi,
ich möchte in einem fremden TreeView auf eine bestimmte Node rechtsklicken. Handle des Fensters bzw. des TreeViews hab ich schon. Nur hab ich das Problem, dass ich nicht weiß, wie ich auf ein bestimmtes Node (dessen Text mit meinem übereinstimmt) rechtsklicke. Beispiel: Ich schreib in meinem Programm, dass auf das Node mit dem Text "Test" ein Rechtsklick ausgeführt werden soll. Und genau auf diese Node soll dann im fremden Programm ein Rechtsklick ausgeführt werden. Wie stellt man sowas am geschicktesten an? |
Re: Rechtsklick auf TreeView Item in einem Fenster
*Schubkarre auspack*
*Thread in Schubkarre einlad* *Mit Schubkarre hochfahren* *Thread ausladen* |
Re: Rechtsklick auf TreeView Item in einem Fenster
*hatschi*
|
Re: Rechtsklick auf TreeView Item in einem Fenster
WIndowsmessages? WM_CLICK? WM_MOUSEDOWN?
|
Re: Rechtsklick auf TreeView Item in einem Fenster
Hi Lukas,
das ist soweit klar. Jedoch muss ich ein bestimmtes Item anklicken, dessen Name mit einem bestimmten Namen übereinstimmt. Das heißt, ich bräuchte erstmal die Koordinaten oder ein Handle zum Senden einer Nachricht. |
Re: Rechtsklick auf TreeView Item in einem Fenster
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:
Wie zu sehen ist funktioniert dieser Code nur auf Windows NT 32-Bit Systemen.
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; 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. |
Re: Rechtsklick auf TreeView Item in einem Fenster
Wow, das schau ich mir später mal an. Erstmal den Source verstehen :D
|
Re: Rechtsklick auf TreeView Item in einem Fenster
Hi bitsetter,
funktioniert an sich ganz gut. Jedoch, sobald viele Items da sind und gescrollt werden muss, funktioniert das ganze nicht mehr. Da werde ich wohl erst noch runterscrollen müssen. [edit] Nach dem Scrollen funktioniert es wieder 1a. Danke vielmals :)[/edit] |
Re: Rechtsklick auf TreeView Item in einem Fenster
Zitat:
du könntest auch das gesuchte Item als TopItem setzen, dann kurz warten und erst danach die Position des Items abfragen. Um das Item als TopItem zu setzen könntest du den Code so abändern:
Delphi-Quellcode:
Damit wird praktisch automatisch auf die richtige Position gescrollt. Getestet mit dem Windows Explorer unter Windows XP.
...
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 SendMessage(hTree, TVM_SELECTITEM, TVGN_FIRSTVISIBLE, Cardinal(hItem));//als TopItem setzen (*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; ... |
Re: Rechtsklick auf TreeView Item in einem Fenster
Hi,
danke, aber ich komme mit meinem Scrollen auch gut zurande :-) Was allerdings noch bleibt, ist dass z.B. bei zwei gleichnamigen SubItems das richtige aufgerufen wird. Aber da hab ich schon eine Idee, muss sie nur noch umsetzen :) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:26 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz