Windows - salvar e obter a posicao do icones no desktop

Top  Previous  Next

Other Source for NT, Win2k, XP only

http://www.luckie-online.de/programme/luckiedipssfx.exe 

 

 

// For Win9x: 

//------------------------------------------- 

 

uses 

  CommCtrl, 

  IPCThrd; (from your Delphi\Demos\Ipcdemos directory) 

 

function GetDesktopListViewHandle: THandle; 

var 

  S: String; 

begin 

  Result := FindWindow('ProgMan', nil); 

  Result := GetWindow(Result, GW_CHILD); 

  Result := GetWindow(Result, GW_CHILD); 

  SetLength(S, 40); 

  GetClassName(Result, PChar(S), 39); 

  if PChar(S) <> 'SysListView32' then Result := 0

end

 

procedure TForm1.Button1Click(Sender: TObject); 

 type 

   PInfo = ^TInfo; 

   TInfo = packed record 

     infoPoint: TPoint; 

     infoText: array[0..255of Char; 

     infoItem: TLVItem; 

     infoFindInfo: TLVFindInfo; 

   end

var 

   r : TRect; 

   hWnd : THandle; 

   i, iCount : Integer; 

 

   Info: PInfo; 

   SharedMem: TSharedMem; 

begin 

  hWnd := GetDesktopWindow(); 

  GetWindowRect(hWnd,r); 

  Memo.Lines.Add('Bottom: ' +  IntToStr(r.Bottom)); 

  Memo.Lines.Add('Right: ' + IntToStr(r.Right)); 

 

  hWnd := GetDesktopListViewHandle; 

  iCount := ListView_GetItemCount(hWnd); 

  Memo.Lines.Add('# Icons: ' + IntToStr(iCount)); 

 

  SharedMem := TSharedMem.Create('', SizeOf(TInfo)); 

  Info := SharedMem.Buffer; 

 

   with Info^ do 

   try 

     infoItem.pszText := infoText; 

     infoItem.cchTextMax := 255

     infoItem.mask := LVIF_TEXT; 

     try 

       begin 

         for i := 0 to iCount - 1 do 

         begin 

           infoItem.iItem := i; 

           try 

             ListView_GetItem(hWnd, infoItem); 

             ListView_GetItemPosition(hWnd, I, infoPoint); 

             Memo.Lines.Add('Icon: ' + infoText); 

             Memo.Lines.Add('   X: ' + IntToStr(infoPoint.X)); 

             Memo.Lines.Add('   Y: ' + IntToStr(infoPoint.Y)); 

           except 

           end

         end

       end

     finally 

     end

   finally 

     SharedMem.Free; 

   end

end

 

// For NT, Win2k, XP: 

//------------------------------------------- 

// Unit to save/restore the positions of desktop icons to/from the registry) 

 

unit dipsdef; 

 

interface 

 

uses 

  Windows, CommCtrl; 

 

const 

  RegSubKeyName = 'Software\LVT\Desktop Item Position Saver'

 

procedure RestoreDesktopItemPositions; 

procedure SaveDesktopItemPositions; 

 

implementation 

 

uses 

  uvirtalloc, registry; 

 

procedure SaveListItemPosition(LVH : THandle; RemoteAddr : Pointer); 

var 

  lvi : TLVITEM; 

  lenlvi : integer; 

  nb : integer; 

  buffer : array [0..MAX_PATH] of char; 

  Base : Pointer; 

  Base2 : PByte; 

  i, ItemsCount : integer; 

  Apoint : TPoint; 

  key : HKEY; 

  Dummy : integer; 

begin 

  ItemsCount := SendMessage(LVH, LVM_GETITEMCOUNT, 00); 

  Base := RemoteAddr; 

  lenlvi := SizeOf(lvi); 

  FillChar(lvi, lenlvi, 0); 

  lvi.cchTextMax := 255

  lvi.pszText := Base; 

  inc(lvi.pszText, lenlvi); 

 

  WriteToRemoteBuffer(@lvi, Base, 255); 

 

  Base2 := Base; 

  inc(Base2, Lenlvi); 

 

  RegDeleteKey(HKEY_CURRENT_USER, RegSubKeyName); 

 

  RegCreateKeyEx(HKEY_CURRENT_USER

    PChar(RegSUbKeyName), 

    0

    nil, 

    REG_OPTION_NON_VOLATILE, 

    KEY_SET_VALUE, 

    nil, 

    key

    nil); 

 

  for i := 0 to ItemsCount - 1 do 

  begin 

    nb := SendMessage(LVH, LVM_GETITEMTEXT, i, LParam(Base)); 

 

    ReadRemoteBuffer(Base2, @buffer, nb + 1); 

    FillChar(Apoint, SizeOf(Apoint), 0); 

 

    WriteToRemoteBuffer(@APoint, Base2, SizeOf(Apoint)); 

    SendMessage(LVH, LVM_GETITEMPOSITION, i, LParam(Base) + lenlvi); 

 

    ReadRemoteBuffer(Base2, @Apoint, SizeOf(Apoint)); 

    RegSetValueEx(key, @buffer, 0, REG_BINARY, @Apoint, SizeOf(APoint)); 

  end

  RegCloseKey(key); 

end

 

 

procedure RestoreListItemPosition(LVH : THandle; RemoteAddr : Pointer); 

type 

  TInfo = packed record 

    lvfi : TLVFindInfo; 

    Name : array [0..MAX_PATH] of char; 

  end

var 

  SaveStyle : Dword; 

  Base : Pointer; 

  Apoint : TPoint; 

  key : HKey; 

  idx : DWord; 

  info : TInfo; 

  atype : Dword; 

  cbname, cbData : Dword; 

  itemidx : DWord; 

begin 

  SaveStyle := GetWindowLong(LVH, GWL_STYLE); 

  if (SaveStyle and LVS_AUTOARRANGE) = LVS_AUTOARRANGE then 

    SetWindowLong(LVH, GWL_STYLE, SaveStyle xor LVS_AUTOARRANGE); 

 

  RegOpenKeyEx(HKEY_CURRENT_USER, RegSubKeyName, 0KEY_QUERY_VALUE, key); 

 

  FillChar(info, SizeOf(info), 0); 

  Base := RemoteAddr; 

 

  idx := 0

  cbname := MAX_PATH; 

  cbdata := SizeOf(APoint); 

 

  while (RegEnumValue(key, idx, info.Name, cbname, nil, @atype, @Apoint, @cbData) <> 

    ERROR_NO_MORE_ITEMS) do 

  begin 

    if (atype = REG_BINARY) and (cbData = SizeOf(Apoint)) then 

    begin 

      info.lvfi.flags := LVFI_STRING; 

      info.lvfi.psz := Base; 

      inc(info.lvfi.psz, SizeOf(info.lvfi)); 

      WriteToRemoteBuffer(@info, Base, SizeOf(info.lvfi) + cbname + 1); 

      itemidx := SendMessage(LVH, LVM_FINDITEM, - 1, LParam(Base)); 

      if itemidx > -1 then 

        SendMessage(LVH, LVM_SETITEMPOSITION, itemidx, MakeLong(Apoint.x, Apoint.y)); 

    end

    inc(idx); 

    cbname := MAX_PATH; 

    cbdata := SizeOf(APoint); 

  end

  RegCloseKey(key); 

 

  SetWindowLong(LVH, GWL_STYLE, SaveStyle); 

end

 

function GetSysListView32: THandle; 

begin 

  Result := FindWindow('Progman', nil); 

  Result := FindWindowEx(Result, 0, nil, nil); 

  Result := FindWindowEx(Result, 0, nil, nil); 

end

 

procedure SaveDesktopItemPositions; 

var 

  pid : integer; 

  rembuffer : PByte; 

  hTarget : THandle; 

begin 

  hTarget := GetSysListView32; 

  GetWindowThreadProcessId(hTarget, @pid); 

  if (hTarget = 0or (pid = 0) then 

    Exit

  rembuffer := CreateRemoteBuffer(pid, $FFF); 

  if Assigned(rembuffer) then 

  begin 

    SaveListItemPosition(hTarget, rembuffer); 

    DestroyRemoteBuffer; 

  end

end

 

procedure RestoreDesktopItemPositions; 

var 

  hTarget : THandle; 

  pid : DWord; 

  rembuffer : PByte; 

begin 

  hTarget := GetSysListView32; 

  GetWindowThreadProcessId(hTarget, @pid); 

  if (hTarget = 0or (pid = 0) then 

    Exit

  rembuffer := CreateRemoteBuffer(pid, $FFF); 

  if Assigned(rembuffer) then 

  begin 

    RestoreListItemPosition(hTarget, rembuffer); 

    DestroyRemoteBuffer; 

  end

end

 

end

 

{----------------------------------------------------------} 

 

unit uvirtalloc; 

 

interface 

 

uses 

  Windows, SysUtils; 

 

function CreateRemoteBuffer(Pid : DWord; Size: Dword): PByte; 

procedure WriteToRemoteBuffer(Source : PByte; 

                               Dest : PByte; 

                               Count : Dword); 

 

function ReadRemoteBuffer (Source : PByte; 

                            Dest : PByte; 

                            Count : Dword): Dword; 

 

procedure DestroyRemoteBuffer; 

 

implementation 

 

var 

  hProcess : THandle; 

  RemoteBufferAddr: PByte; 

  BuffSize : DWord; 

 

function CreateRemoteBuffer; 

begin 

  RemoteBufferAddr := nil; 

  hProcess := OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid); 

  if (hProcess = 0) then 

    RaiseLastWin32Error; 

 

  Result := VirtualAllocEx(hProcess, 

                            nil, 

                            Size, 

                            MEM_COMMIT

                            PAGE_EXECUTE_READWRITE); 

 

  Win32Check(Result <> nil); 

  RemoteBufferAddr := Result; 

  BuffSize := Size; 

end

 

procedure WriteToRemoteBuffer; 

var 

  BytesWritten: Dword; 

begin 

 if hProcess = 0 then 

   Exit

 Win32Check(WriteProcessMemory(hProcess, 

                                Dest, 

                                Source, 

                                Count

                                BytesWritten)); 

end

 

function ReadRemoteBuffer; 

begin 

  Result := 0

  if hProcess = 0 then 

     Exit

 

  Win32Check(ReadProcessMemory(hProcess, 

                                Source, 

                                Dest , 

                                Count

                                Result)); 

end

 

procedure DestroyRemoteBuffer; 

begin 

   if (hProcess > 0)  then 

     begin 

       if Assigned(RemoteBufferAddr) then 

         Win32Check(Boolean(VirtualFreeEx(hProcess, 

                                          RemoteBufferAddr, 

                                          0

                                          MEM_RELEASE))); 

       CloseHandle(hProcess); 

     end

end

 

end

 

{----------------------------------------------------------} 

 

Other Source for NT, Win2k, XP only

http://www.luckie-online.de/programme/luckiedipssfx.exe 

(Complete demo to save/restore the positions of desktop icons, nonVCL)