Icons auf dem Windows-Desktop

Position der Desktop-Icons sichern und wiederherstellen

Desk­top-Icons füh­ren bei Win­dows manch­mal ein Eigen­le­ben. Wenn sich die Auf­lö­sung ändert, etwa bei der Instal­la­ti­on eines neu­en Gra­fik­trei­bers oder nach dem Start älte­rer Spie­le, ist die Anord­nung der Icons auf dem Win­dows-Desk­top nicht mehr die­sel­be. Mit dem Tool pcwSIcons3 kön­nen Sie die Posi­tio­nen der Icons sichern und wie­der­her­stel­len.

 

Down­loads zu die­sem Arti­kel:

pcwSIcons3_setup.exe: Set­up-Pro­gramm für alle Pro­gram­me. Das Instal­la­ti­ons­pro­gramm instal­liert auto­ma­tisch die 32- oder 64-Bit-Ver­si­on (für Win­dows Vis­ta, Win­dows 7 oder Win­dows 8)

pcwSIcons3.zip: ZIP-Archiv mit allen Pro­gram­men. Ach­tung: Die Activ­eX-DLL müs­sen Sie selbst regis­trie­ren. Batch-Datei­en für die­sen Zweck lie­gen bei (als Admi­nis­tra­tor aus­füh­ren)

pcwSIcons_CLI.zip: Nur das Kom­man­do­zei­len­pro­gramm (32-Bit und 64-Bit), bei­spiels­wei­se für die Ver­wen­dung in einer Batch-Datei.

pcw­SI­con­s3-Source: Source-Code für alle Pro­gramm (Del­phi XE3).

Das Pro­blem beglei­tet Win­dows seit Jah­ren. Und jeder, der  häu­fig die Icons auf dem Desk­top nutzt und hier eine gewis­se Ord­nung bevor­zugt, kennt es wahr­schein­lich. Unter bestimm­ten Bedin­gun­gen wer­den die Icons neu ange­ord­net und die eige­ne Ord­nung ist dahin. Das pas­siert bevor­zugt bei Ände­run­gen der Bild­schirm­auf­lö­sung, etwa bei der Instal­la­ti­on einen neu­en Gra­fik­trei­bers oder bei bestimm­ten Spie­len. Ein wei­te­res Pro­blem sind PCs, an denen in der Regel meh­re­re Moni­to­re hän­gen, aber eben nicht immer. Icons die auf dem zwei­ten Bild­schirm lie­gen, lan­den dann irgend­wo auf dem ers­ten Bild­schirm, wenn nur ein Moni­tor ange­schlos­sen ist. Ähn­li­ches gilt für Note­books, wenn sie hin und wie­der mit höhe­rer Auf­lö­sung oder im Zwei-Bild­schirm-Betrieb lau­fen.

Es wäre daher wün­schens­wert, die Anord­nung der Icons zu spei­chern und bei Bedarf wie­der­her­zu­stel­len. Dafür gibt es bereits eini­ge Tools, die jedoch nicht so fle­xi­bel sind, wie ich mir das wün­sche. Da ich im Besitz eines Edi­tors und eines Com­pi­lers bin, habe ich mich also selbst an Werk gemacht. Der ver­wen­de­te Del­phi-Code ist schon ziem­lich alt. Er stammt ursprüng­lich aus den Zei­ten von Win­dows 95, funk­tio­niert mit eini­gen Anpas­sun­gen aber auch heu­te noch. Ich habe das Pro­gramm mit Embar­ca­de­ro Del­phi XE3 erstellt, es soll­te aber mit eini­gen klei­nen Ände­run­gen auch mit ande­ren Del­phi/F­ree­pas­cal-Umge­bun­gen zu erstel­len sein. Das Pro­gramm ist ursprüng­lich für eine PC-WELT-Arti­kel ent­stan­den und ich habe es jetzt etwas wei­ter­ent­wi­ckelt. Der Quell­code steht unter GPL.

Wie funktionieren die Programme?

Aber zuerst – für Nicht-Pro­gram­mie­rer – zu den Pro­gram­men selbst. Um alle Wün­sche abzu­de­cken, gibt es davon meh­re­re Vari­an­ten. Das ers­te Pro­grämm­chen ist eine Activ­eX-DLL. Die­se lässt sich per Script oder über ein maus­be­dien­ba­res Pro­gramm nut­zen. Das zwei­te Tool kann unab­hän­gig davon auf der Kom­man­do­zei­le oder in einer Batch-Datei ver­wen­det wer­den.

Desktop-Icons mit pcwSIcon3 sichern und wiederherstellen

Das ers­te Pro­gramm heißt pcwSIcon3 und lässt sich am ein­fachs­ten per Set­up-Pro­gramm instal­lie­ren. Die­ses sorgt auch für die Regis­trie­rung der Activ­eX-DLL. Das Set­up-Pro­gramm instal­liert – je nach Sys­tem-Archi­tek­tur – die 32- oder die 64-Bit-Ver­si­on der Datei­en. Im Start­me­nü fin­det sich danach das Pro­gramm PC-WELT-pcw­SI­con­s3. Es bie­tet eine ein­fa­che Ober­flä­che. Über die Schalt­flä­che „Posi­tio­nen spei­chern“ las­sen sich die Icon-Posi­tio­nen in einer INI-Datei sichern. Die­se liegt unter %APPDATA%\pcwSIcons3\pcwSIcon3.ini. Das Tool ermit­telt die aktu­el­le Bild­schirm­auf­lö­sung und spei­chert die­se als Lay­out-Namen. Auf die­se Wei­se las­sen sich die Icon-Posi­tio­nen für unter­schied­li­che Auf­lö­sun­gen getrennt spei­chern. In das Ein­ga­be­feld hin­ter „Lay­out-Name“ kann man auch selbst einen Namen ein­tip­pen, bei­spiels­wei­se Mein­De­sk­top. Per Klick auf „Wie­der­her­stel­len“ setzt das Tool die Icons wie­der an die zuvor gespei­cher­te Stel­le.

Für die Auto­ma­ti­sie­rung die­ses Vor­gangs die­nen die bei­den Scrip­te SaveIcons.vbs und RestoreIcons.vbs. Die­se errei­chen Sie über das Win­dows-Start­me­nü oder direkt über den Instal­la­ti­ons­ord­ner, etwa „C:\Program Files\PC-WELT\pcwSIcons3“. Sie kön­nen die VBS-Scrip­te bei Bedarf anpas­sen. Dazu öff­nen Sie die VBS-Datei­en in einem Edi­tor. Sie kön­nen hin­ter „.Ini­Fi­le­Na­me“ den Pfad anpas­sen, in dem die INI-Datei gespei­chert wird und hin­ter „ ‚.Reso­lu­ti­on“ einen eige­nen Namen für das Bild­schirm-Lay­out fest­le­gen. Stan­dard­mä­ßig wird die Bild­schirm­auf­lö­sung als Name ver­wen­det. Für den täg­li­chen Gebrauch soll­ten Sie noch die „MsgBox“-Zeile aus­kom­men­tie­ren, damit kei­ne Mel­dung auf dem Bild­schirm erscheint.

Pro­gramm für die Kom­man­do­zei­le: Wer statt VB-Script lie­ber eine Batch-Datei ver­wen­den möch­te nimmt das Pro­gramm pcwSIcons3_CLI_X64.exe bezie­hungs­wei­se pcwSIcons3_CLI_x86.exe. Es arbei­tet unab­hän­gig von der Activ­eX-DLL, bie­tet aber die glei­chen Funk­tio­nen. Mit der Zei­le

   pcwSIcons3_CLI.exe /i:c:\MyIniFile.ini /s

las­sen sich die Icon-Posi­tio­nen in der Datei „MyIniFile.ini“ spei­chern und mit

   pcwSIcons3_CLI.exe /i:c:\MyIniFile.ini /r

wie­der zurück­si­chern. Über den Para­me­ter „/l“ kön­nen Sie einen benut­zer­de­fi­nier­ten Namen für das Bild­schirm­lay­out ange­ben:

   pcwSIcons3_CLI.exe /i:c:\MyIniFile.ini /s /l:"MyDesktopLyaout"

Der Quellcode

Beim Win­dows-Desk­top han­delt es sich um ein Fens­ter ohne Rah­men, das seit den ers­ten Win­dows „Prog­man“ heißt und den Titel „Pro­gram Mana­ger“ trägt. Die­ses Fens­ter wird kom­plett von einem SysListView32 aus­ge­füllt, das die Desk­top-Icons anzeigt. In einem ers­ten Schritt muss man mit der API-Funk­ti­on Find­Win­dow den Hand­le  die­ses Fens­ters ermit­teln. Danach fin­det man mit Enum­child­Win­dows her­aus, wie die Unter­fens­ter hei­ßen. Eins davon trägt (hof­fent­lich) die Bezeich­nung „Fol­der­View“.  Mit ListView_GetItemCount erhält man dann die Anzahl der Icons auf dem Desk­top. Mit Get­Win­dow­Th­readPro­ces­sId und Open­Pro­cess kann man sich dann Zugang zum­List­View ver­schaf­fen und die ein­zel­nen Ele­men­te mit ListView_GetItemPosition aus­le­sen. Hier der ent­schei­den­de Aus­schnitt aus dem Quell­code:

Procedure IterateIcons(const S:string; TheAction: TIconAction);
  TYPE
  PSharedStuff = ^TSharedStuff;
  TSharedStuff = record
    Buffer : ARRAY[0..MAX_PATH] OF Char;
    LV     : TLVItem;
    Pt     : TPoint;
  end;
  var
  TI: TIniFile;
  hWnd1: HWND;
  dwProcessId: DWORD;
  hProcess: THandle;
  Pointer1: Pointer;
  PLVItem1: PLVITEM;
  PChar1: PChar;
  I: Integer;
  NumberOfBytesRead: SIZE_T;
  NumberOfItems: Integer;
  N: Integer;
  myIconPoint: TPoint;
  PSS:PSharedStuff;

Procedure OneIconNT(N:Integer);
begin
//*************** ein Icon lesen **************
with PLVItem1^ do
        begin
          cchTextMax := 256;
          pszText := Pointer(Cardinal(Pointer1) + SizeOf(TLVItem));
          mask := LVIF_TEXT;
          iItem := N;
          iSubItem := 0;
        end;
        WriteProcessMemory(hProcess, Pointer1, PLVItem1,SizeOf(TLVItem) ,NumberOfBytesRead);
        SendMessage(hWnd1, LVM_GETITEM, N, lparam(Pointer1));
        ReadProcessMemory( hProcess, Pointer(Cardinal(Pointer1) +
           SizeOf(TLVItem)), PChar1,DWORD(256),
           NumberOfBytesRead);

    ListView_GetItemPosition(hWnd1, N, PPoint(Pointer1)^);
               ReadProcessMemory( hProcess, Pointer1, @myIconPoint,
               DWORD(sizeof(TPoint)), NumberOfBytesRead);

Case TheAction Of
  SaveToIni: TI.WriteInteger (S, PChar1, Integer(PointToSmallPoint(myIconPoint)));
  RestFromIni: begin
  I:=TI.ReadInteger(S, PChar1, -1);
If I <>-1 Then
   begin
     myIconPoint:=SmallPointToPoint(TSmallPoint(I));
   end;
   ListView_SetItemPosition(hWnd1,N, myIconPoint.x, myIconPoint.y);
 end;
end;
end;
//************** W95/98  ****************
Procedure OneIcon95(N:Integer);
Begin
WITH PSS^.LV DO
      begin
        mask       := LVIF_TEXT;
        iItem      := N;
        iSubItem   := 0;
        state      := 0;
        statemask  := 0;
        pszText    := @PSS^.Buffer;
        cchTextMax := MAX_PATH;
        iImage     := 0;
      end;
  SendMessage(hWnd1, LVM_GETITEM, 0, Integer(@PSS^.LV));
  SendMessage(hWnd1, LVM_GETITEMPOSITION, N, Integer(@PSS^.pt));
  Case TheAction Of
    SaveToIni: TI.WriteInteger(S, StrPas(Pss^.Buffer),
                  Integer(PointToSmallPoint(PSS^.Pt)));
    RestFromIni: begin
      I:=TI.ReadInteger(S, StrPas(PSS^.Buffer), -1);
      If I <>-1 Then
     begin
     PSS^.Pt:=SmallPointToPoint(TSmallPoint(I));
     end;
     ListView_SetItemPosition(hWnd1,N, PSS.Pt.x, PSS.Pt.y);
   end;
end;

end;

//************* main *******************
Begin
 TI:=TIniFile.Create(sIniFileName);
 hWnd1 := DesktopListViewHandle;
 if hWnd1 = 0 then exit;

 //************** 95/98/ME ***************

 if TOSVersion.ToString='' then begin
//
end;

If CheckForWin95= VER_PLATFORM_WIN32_WINDOWS Then
begin
  NumberOfItems := ListView_GetItemCount(hWnd1);
  hProcess:=CreateFileMapping( $FFFFFFFF, NIL, PAGE_READWRITE,
  0, SizeOf(TSharedStuff), LVMapName);
  PSS:=MapViewOfFile(hProcess, FILE_MAP_ALL_Access,0,0,0);
   IF TheAction=SaveToIni Then TI.EraseSection(S);
  try
    For N:=0 To NumberOfItems-1 Do OneIcon95(N);
  finally
   TI.Free;
  end;
   CloseHandle(hProcess);
end
//************** NT/2K/Vista/7/8***************
Else If CheckForWin95= VER_PLATFORM_WIN32_NT Then
begin
 GetWindowThreadProcessId(hWnd1, @dwProcessId);
  hProcess := OpenProcess(
    PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE,
    false, dwProcessId);
  if hProcess = 0 then exit;
  Pointer1 := VirtualAllocEx(hProcess, nil, 4096,
                      MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);
  PLVItem1 := AllocMem(SizeOf(TLVItem));
  PChar1 := StrAlloc(256);

 NumberOfItems := ListView_GetItemCount(hWnd1);

 IF TheAction=SaveToIni Then TI.EraseSection(S);
  try
  For N:=0 To NumberOfItems-1 Do OneIconNT(N);

  finally
  TI.Free;
  end;
  VirtualFreeEx(hProcess, PLVItem1, 0, MEM_RELEASE);
  CloseHandle(hProcess);
 end
 else
 WriteLn('Diese Plattform wird nicht unterstützt.');

end;

Schlagwörter:


Kommentare

2 Antworten zu „Position der Desktop-Icons sichern und wiederherstellen“

  1. Gibt es auf dem Note­book evtl. eine Sicher­heits­soft­ware, die die Arbeit des Tools behin­dert? Ich kann mir gera­de kei­nen Feh­ler vor­stel­len, der sonst dazu führt.

    Sie kön­nen ver­su­chen, die Activ­eX-DLL neu zu regis­trie­ren. Dazu öff­nen Sie als Admi­nis­tra­tor eine Kom­man­do­zei­le und set­zen den Befehl

    regsvr32.exe „C:\Program Files\PC-WELT\pcwSIcons3\pcwSIcon3.dll“

    ab. Pas­sen Sie den Pfad zur Datei pcwSIcon3.dll ggf. an.
    Es soll­te die Mel­dung erschei­nen

    „Dll­Re­gis­ter­Ser­ver in C:\Program Files\PC-WELT\pcwSIcons3\pcwSIcon3.dll erfolg­reich durch­ge­führt.“

    Pro­bie­ren Sie bit­te auch aus, ob pcwSIcons3_CLI.exe funk­tio­niert. Das Kom­man­do­zei­len­pro­gramm kommt ohne die Activ­eX-DLL aus. Soll­te auch die­ses nicht funk­tio­nie­ren, muss das Pro­blem woan­ders lie­gen.

  2. Avatar von Matthias
    Matthias

    Guten Abend Herr Egge­ling!

    Ich nut­ze Ihr pcwSIcons3 Soft­ware sehr ger­ne auf mei­nem Desk­top Rech­ner und pro­bie­re gera­de – ver­zwei­felnd – die Soft­ware auch auf mei­nem Note­book zum Lau­fen zu brin­gen.

    Wenn ich mit den vbs Scripts (SaveI­cons und Res­to­r­eI­cons) arbei­te, dann erschei­nen zwar die Mel­dun­gen wie „Lay­out spei­chern.“, aber die pcwSIcon3.ini bleibt leer.

    Wenn ich die exe star­te, einen Lay­out-Name ein­ge­be und auf „Posi­tio­nen spei­chern“ kli­cke, dann wird weder der Lay­out-Name ein­ge­tra­gen noch die ini bear­bei­tet.

    Haben Sie mir einen Tipp, wie ich die Soft­ware zum Funk­tio­nie­ren über­re­den kann?

    Vie­len Dank!
    Mat­thi­as

    Sys­tem: Win­dows 7, 64-bit, aktu­el­le Auf­lö­sung lt. SIcons3 3840x1080 (Note­book + exter­ner Moni­tor).

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.

Neueste Kommentare


Die Website durchsuchen