Einzelnen Beitrag anzeigen

Benutzerbild von bitsetter
bitsetter

Registriert seit: 17. Jan 2007
1.169 Beiträge
 
Turbo Delphi für Win32
 
#6

Re: Rechtsklick auf TreeView Item in einem Fenster

  Alt 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))= 'Arbeitsplatzthen
          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
  Mit Zitat antworten Zitat