![]() |
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 |
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 ![]() 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. |
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:
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...
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; |
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. |
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:
In dem ersten label steht \Software\Microsoft\Windows\Shell\Bags\1\Desktop drin und im Zweiten einfach ein Speicherpfad.
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; |
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:
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);
|
AW: Position der Icons auf dem Desktop ermitteln
Ok habs in das hier geändert:
Delphi-Quellcode:
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?
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; 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. |
AW: Position der Icons auf dem Desktop ermitteln
Hast du mein Edit oben bzgl "KEY_ALL_ACCESS" gelesen?
|
AW: Position der Icons auf dem Desktop ermitteln
Delphi-Quellcode:
ja hab ich. Siehe oben
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; |
AW: Position der Icons auf dem Desktop ermitteln
Was gibt denn das OpenKey zurück?
|
AW: Position der Icons auf dem Desktop ermitteln
Openkey geht.
Delphi-Quellcode:
zeigt die Nachricht.
if regist.OpenKey(lbledtpath.Text, False) then ShowMessage('Öffnen geht');
|
AW: Position der Icons auf dem Desktop ermitteln
Komisch. Ich habe SaveKey auch noch nie benutzt, aber wenn ich die Hilfe richtig deute, lass doch das OpenKey und CloseKey einmal weg. Außerdem darf die Zieldatei noch nicht existieren (wieso auch immer).
|
AW: Position der Icons auf dem Desktop ermitteln
Dann machen wir es doch mal richtig, dann bekommt man auch einigermaßen gescheite Fehlermeldungen:
Delphi-Quellcode:
Fehlermeldung lautet: "Ein Aufruf einer Betriebssystemfunktion ist fehlgeschlagen."
uses
Registry; const REGPATH = '\Software\Microsoft\Windows\Shell\Bags\1\Desktop'; FILENAME = 'd:\test.txt'; procedure SaveDesktopIconsFromRegistry(const FileName: string); var Reg: TRegistry; begin Reg := TRegistry.Create; try if Reg.KeyExists(REGPATH) then begin if not Reg.SaveKey(REGPATH, FileName) then RaiseLastOSError; end else RaiseLastOSError; finally Reg.Free; end; end; procedure TForm13.Button1Click(Sender: TObject); begin if FileExists(FILENAME) then begin if not DeleteFile(FILENAME) then ShowMessage(SysErrorMessage(GetLastError)); end; try SaveDesktopIconsFromRegistry(FILENAME); except on E: Exception do ShowMessage(E.Message); end; end; Laut Hilfe öffnet und schließt SaveKey den Schlüssel. Ein OpenKey und CloseKey ist also überflüssig. |
AW: Position der Icons auf dem Desktop ermitteln
Naja danke... aber das hilft uns auch nicht weiter oder? Die Frage ist ja eigentlich, wie ich die Datei jetzt speichern kann ;).
|
AW: Position der Icons auf dem Desktop ermitteln
Doch es hilft uns weiter, weil wir jetzt mal eine gescheite Fehlermeldung haben.
|
AW: Position der Icons auf dem Desktop ermitteln
Bei mir steht mit gleichem Code was anderes: Das System kann die angegebene Datei nicht finden. Keine Wunder... laut Beschreibung soll sie ja auch nicht existieren...was sie bei mir auch nicht tut.
|
AW: Position der Icons auf dem Desktop ermitteln
Deswegen lösche ich ja auch die Datei vorher, falls sie existiert.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:10 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-2025 by Thomas Breitkreuz