Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Position der Icons auf dem Desktop ermitteln (https://www.delphipraxis.net/156950-position-der-icons-auf-dem-desktop-ermitteln.html)

eragon123 21. Dez 2010 15:43

Position der Icons auf dem Desktop ermitteln
 
Mein Problem ist das Windows immer mal wieder gerne Icons auf meinem Desktop nach einem Neustart verschiebt. Das nervt! (um es mal kurz und knackig auszudrücken ;) ).
Daher wollte ich mir ein Programm schreiben, welches sich die Positionen merkt und dann wiederherstellt. Dabei sollte er sich Icons und die Windows 7 "Apps" aus der Seitenleiste merken können.
Was natürlich auch ganz cool wäre wär die Möglich verschiedene Konfigurationen mit verschiedenen Icons usw. speichern zu können, und die per Knopfdruck zu wechseln.
Gibts da entsprechende Kommandos in der Win API?
PS Ich sprechen über Win 7 und ich würde das Programm in Delphi 7 schreiben, wenn möglich aber lieber in Java

Matze 21. Dez 2010 16:04

AW: Position der Icons auf dem Desktop ermitteln
 
Hallo,

fast das Gleiche hat Luckie glaub hier auch mal gefragt. Aus der genannten Lösung ist dann LuckieDIPS (bissl Runterscrollen) entstanden.
Da kannst du abgucken, wie's geht und deine Zusatzfunktionen selbst implementieren.

Das ist aber Delphi-Code und nach Java übersetze ich das nicht, wo ich Java persönlich, nunja, supoptimal finde. ;)
Ich weiß auch gar nicht, in wie weit Java API-Befehle unterstützt (falls Luckie welche nutzt), da es doch eher eine plattformunabhängige Sprache ist. Da müsstest du mal selbst recherchieren.

eragon123 21. Dez 2010 16:19

AW: Position der Icons auf dem Desktop ermitteln
 
Muss ja auch nicht umbedingt in Java sein. Delphi ist ja auch nicht schlecht. Wie heißt denn das Programm? Finde da in der List auf den ersten Blick nichts passendes. PS Habs gefunden ;)
Das hier scheint ja das zu sein, was die Icons findet:
Code:
function GetDesktopIconInfo: TDesktopIconInfoArray;
var
  ListView         : HWND;
  ProcessId        : DWORD;
  Process          : THandle;
  Size             : Cardinal; // SIZE_T
  MemLocal         : PLvItemBuffer;
  MemRemote        : PLvItemBuffer;
  NumBytes         : Cardinal; // SIZE_T
  IconCount        : DWORD;
  IconIndex        : Integer;
  IconLabel        : string;
  IconPos          : TPoint;
  DesktopIconInfoArray: TDesktopIconInfoArray;
begin
  // Fensterhandle des Desktop-ListView ermitteln und Prozess oeffnen
  ListView := GetDesktopListView;
  ProcessId := 0;
  GetWindowThreadProcessId(ListView, @ProcessId);
  Process := OpenProcess(PROCESS_QUERY_INFORMATION or 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(TLvItemBuffer);
    MemLocal := VirtualAlloc(nil, Size, MEM_COMMIT, PAGE_READWRITE);
    MemRemote := VirtualAllocEx(Process, nil, Size, 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(TLvItemBuffer));
        with MemLocal^ do
          if IsWow64Process(GetCurrentProcess) and
            not IsWow64Process(Process) then
          begin
            LvItem64.mask := LVIF_TEXT;
            LvItem64.iItem := IconIndex;
            LvItem64.pszText := Cardinal(MemRemote) + ItemBufferBlockSize;
            LvItem64.cchTextMax := High(MemLocal.ItemText) + 1;
          end
          else
          begin
            LvItem32.mask := LVIF_TEXT;
            LvItem32.iItem := IconIndex;
            LvItem32.pszText := Cardinal(MemRemote) + ItemBufferBlockSize;
            LvItem32.cchTextMax := High(MemLocal.ItemText) + 1;
          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(MemLocal.ItemText);
          // 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;
Leider verstehe ich das kaum^^ Also anscheinend gibt es einen Prozess der das bei Windows verwaltet? Richtig? Und den kopiert er aus irgendeinem Grund in einen neuen und ließt dabei noch die Daten aus...

himitsu 21. Dez 2010 16:56

AW: Position der Icons auf dem Desktop ermitteln
 
Der Desktop ist quasi ein großes Fenster, in welchem sich "alle" anderen Fenster befinden (quasi wie MDI-Childs).
In diesem Fenster befindet sich auch noch sowas wie eine ListView, im vsIcon-ViewStyle, welche die Icons des Desktops darstellt.
Und diese ListView liest Luckie dort aus.

Diese Daten stehen zwar (vermutlich) auch irgendwo in der Registry, aber Windows speichert dieses nur beim Runterfachen/Abmelden, so daß dort nicht unbedingt die aktuellen Werte drinstehn würden.

eragon123 21. Dez 2010 17:29

AW: Position der Icons auf dem Desktop ermitteln
 
Achso, naja ich habs gerade noch in der Registry gefunden unter: \Software\Microsoft\Windows\Shell\Bags\1\Desktop. Da gibts einen Schlüssel, der das binär speichert. Ich wollte jetzt eigentlich nur kurz ein Programm schreiben, welches den Schlüssel sichert, und später wiederherstellt. Das läuft auch, erstellt ein Datei... aber die ist leer. Kann mir jemand sagen warum?

Code:
procedure TForm1.saveRegistryKey();
  var regist: TRegistry;
begin
  regist := TRegistry.Create;
  try
    regist.RootKey:=HKEY_CURRENT_USER;
    if regist.KeyExists(lbledtpath.Text) then ShowMessage('Schlüssel existiert');
    regist.OpenKey(lbledtpath.Text, False);
    regist.SaveKey(lbledtpath.Text,lbledtsavepath.Text+'\reg');
    ShowMessage('Key "' + lbledtpath.Text + '" wurde erfolgreich in "'+lbledtsavepath.Text+'" gespeichert!');
  finally
    regist.free;
  end;
end;
In dem ersten label steht \Software\Microsoft\Windows\Shell\Bags\1\Desktop drin und im Zweiten einfach ein Speicherpfad.

Matze 21. Dez 2010 17:59

AW: Position der Icons auf dem Desktop ermitteln
 
Hallo,

gleich vorweg: Verwende zukünftig bitte die [delphi]-Tags und nicht die [code]-Tags. Dann greift das entsprechende Syntax-Highlighting.

Zu einem "OpenKey" gehört immer auch ein "CloseKey". Füge das noch mit ein.
Das hat mit deinem Problem jedoch nichts zu tun.

Ich habe deinen Code nicht getestet und "SaveKey" selbst nie verwendet. "SaveKey" hat einen boolschen Rückgabewert. Was liefert der denn zurück? False bzw. etwas anderes als "true"?
Zitat:

If SaveKey is successful it returns true and closes the key.
Liefert "KeyExists" den Wert "true" bzw. siehst du deine MessageBox?

Edit: Aber "OpenKey" ist meiner Meinung nach überflüssig. Vielleicht liegt's daran, vielleicht aber auch nicht. ;)
Edit 2: Du kannst auch mal versuchen, folgendes zu schreiben. So interpretiere ich die Delphi-Hilfe:


Delphi-Quellcode:
regist := Tregistry.Create(KEY_ALL_ACCESS);

eragon123 21. Dez 2010 18:05

AW: Position der Icons auf dem Desktop ermitteln
 
Ok habs in das hier geändert:
Delphi-Quellcode:
procedure TForm1.saveRegistryKey();
  var regist: TRegistry;
begin
  regist := TRegistry.Create;
  try
    regist.RootKey:=HKEY_CURRENT_USER;
    if regist.KeyExists(lbledtpath.Text) then ShowMessage('Schlüssel existiert');
    regist.OpenKey(lbledtpath.Text, False);
    if regist.SaveKey(lbledtpath.Text,lbledtsavepath.Text+'\reg') then
      ShowMessage('Key "' + lbledtpath.Text + '" wurde erfolgreich in "'+lbledtsavepath.Text+'" gespeichert!');
    regist.CloseKey;
  finally
    regist.free;
  end;
end;
Und es kommt zwar die Meldung das der Key existiert aber nicht die zweite Nachricht. Also save scheint irgendwie nicht zu gehen...kanns das irgendwelche Rechteprobleme geben?
Hab gerade mal noch das(KEY_ALL_ACCESS) angefügt... hilft nichts. Hab auch mal das openkey weg gelassen. Wird immer nur eine leere Datei erstellt.

Matze 21. Dez 2010 18:08

AW: Position der Icons auf dem Desktop ermitteln
 
Hast du mein Edit oben bzgl "KEY_ALL_ACCESS" gelesen?

eragon123 21. Dez 2010 18:09

AW: Position der Icons auf dem Desktop ermitteln
 
Delphi-Quellcode:
procedure TForm1.saveRegistryKey();
  var regist: TRegistry;
begin
  regist := TRegistry.Create(KEY_ALL_ACCESS);
  try
    regist.RootKey:=HKEY_CURRENT_USER;
    if regist.KeyExists(lbledtpath.Text) then ShowMessage('Schlüssel existiert');
    regist.OpenKey(lbledtpath.Text, False);
    if regist.SaveKey(lbledtpath.Text,lbledtsavepath.Text+'\reg') then
      ShowMessage('Key "' + lbledtpath.Text + '" wurde erfolgreich in "'+lbledtsavepath.Text+'" gespeichert!');
    regist.CloseKey;
  finally
    regist.free;
  end;
end;
ja hab ich. Siehe oben

DeddyH 21. Dez 2010 18:20

AW: Position der Icons auf dem Desktop ermitteln
 
Was gibt denn das OpenKey zurück?


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:53 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz