Einzelnen Beitrag anzeigen

Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Symbole des Desktops auslesen (Auflisten der DesktopSymb

  Alt 29. Jan 2005, 16:02
Das get auch einfacher:
Delphi-Quellcode:
type
  TDesktopIconInfo = packed record
    Caption: string;
    Position: TPoint;
  end;

  TDesktopIconInfoArray = array of TDesktopIconInfo;
  TIniSections = array of string;
Delphi-Quellcode:
////////////////////////////////////////////////////////////////////////////////
// Diese Funktion ist zwar einfach, aber nicht sicher genug (WinXP)

{-----------------------------------------------------------------------------
  Procedure : GetDesktopListView - Author : -
  Purpose  : Desktop Listview Handle ermitteln
  Result    : HWND
-----------------------------------------------------------------------------}


function GetDesktopListView(): HWND;
var
  ClassName : string;
begin
  Result := FindWindow('ProgMan', nil);
  Result := GetWindow(Result, GW_CHILD);
  Result := GetWindow(Result, GW_CHILD);
  SetLength(ClassName, 40);
  SetLength(ClassName, GetClassName(Result, PChar(ClassName), 39));
  if (ClassName <> 'SysListView32') then
  begin
    MessageBox(0, PChar(ERROR_GETDESKTOPHANDLE), APPNAME, MB_ICONERROR or MB_OK);
    Result := 0;
  end;
end;

////////////////////////////////////////////////////////////////////////////////
// Durch die Verwendung von VirtualAllocEx() funktioniert dieser Code nur auf NT

{-----------------------------------------------------------------------------
  Procedure : GetDesktopIconInfo - Author : Nico Bendlin
  Purpose  : Gets the caption and the position of the desktopicons
  Result    : TDesktopIconInfoArray
-----------------------------------------------------------------------------}


function GetDesktopIconInfo(): TDesktopIconInfoArray;
var
  ListView : HWND;
  ProcessId : DWORD;
  Process : THandle;
  Size : Cardinal; // SIZE_T
  MemLocal : Pointer;
  MemRemote : Pointer;
  NumBytes : Cardinal; // SIZE_T
  IconCount : DWORD;
  IconIndex : Integer;
  IconLabel : string;
  IconPos : TPoint;
  DesktopIconInfoArray: TDesktopIconInfoArray;
begin
  // Fensterhandle des Desktop-ListView ermitteln und Prozess oeffnen
  ProcessId := 0;
  ListView := GetDesktopListView();
  GetWindowThreadProcessId(ListView, @ProcessId);
  Process := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or
    PROCESS_VM_WRITE, False, ProcessId);
  if (Process <> 0) then
  try
    // Lokalen und entfernten (im Zielprozess) Puffer anlegen
    Size := SizeOf(TLVItem) + SizeOf(Char) * MAX_PATH + 1;
    MemLocal := VirtualAlloc(nil, Size, MEM_RESERVE or MEM_COMMIT,
      PAGE_READWRITE);
    MemRemote := VirtualAllocEx(Process, nil, Size, MEM_RESERVE or MEM_COMMIT,
      PAGE_READWRITE);
    if Assigned(MemLocal) and Assigned(MemRemote) then
    try
      // Anzahl der Symbole ermitteln und in einer Schleife durchlaufen
      IconCount := SendMessage(ListView, LVM_GETITEMCOUNT, 0, 0);
      Setlength(DesktopIconInfoArray, IconCount);
      for IconIndex := 0 to IconCount - 1 do
      begin
        // Symboltext auslesen
        // (es gibt zwei identische Strukturen, jeweils eine in diesem und eine
        // im Zielprozess. Wobei die Daten zwischen den Puffern hin und her
        // kopiert werden muessen. Dieser Aufwand ist noetig, da LVM_GETITEM
        // eine Struktur liest und schreibt, die sich im Adressraum des
        // Prozesses befindet, dem das entsprechende Fenster gehoert...)
        ZeroMemory(MemLocal, SizeOf(TLVItem));
        with PLVItem(MemLocal)^ do
        begin
          mask := LVIF_TEXT;
          iItem := IconIndex;
          // Der Puffer fuer den Text liegt direkt hinter der TLVItem-Struktur
          pszText := LPTSTR(Cardinal(MemRemote) + Cardinal(SizeOf(TLVItem)));
          cchTextMax := MAX_PATH;
        end;
        NumBytes := 0;
        if WriteProcessMemory(Process, MemRemote, MemLocal, Size, NumBytes) and
          Boolean(SendMessage(ListView, LVM_GETITEM, 0, LPARAM(MemRemote))) and
          ReadProcessMemory(Process, MemRemote, MemLocal, Size, NumBytes) then
        begin
          IconLabel := string(
            PChar(Cardinal(MemLocal) + Cardinal(SizeOf(TLVItem))));
          // Position auslesen
          // (-1, -1 ist nur ein Indiz fuer einen Fehlschlag, da diese Position
          // natuerlich moeglich ist...)
          IconPos.X := -1;
          IconPos.Y := -1;
          if Boolean(SendMessage(ListView, LVM_GETITEMPOSITION, IconIndex,
            LPARAM(MemRemote))) and ReadProcessMemory(Process, MemRemote,
            MemLocal, Size, NumBytes) then
          begin
            IconPos := PPoint(MemLocal)^;
          end;
          // Speichern ;)
          DesktopIconInfoArray[IconIndex].Caption := IconLabel;
          DesktopIconInfoArray[IconIndex].Position.X := IconPos.X;
          DesktopIconInfoArray[IconIndex].Position.Y := IconPos.Y;
        end;
        result := DesktopIconInfoArray;
      end;
    except
      // Exceptions ignorieren
    end;
    // Aufraeumen
    if Assigned(MemRemote) then
      VirtualFreeEx(Process, MemRemote, 0, MEM_RELEASE);
    if Assigned(MemLocal) then
      VirtualFree(MemLocal, 0, MEM_RELEASE);
  finally
    CloseHandle(Process);
  end;
end;
Frisch aus meinen LuckieDips.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat