首页  编辑  

排列桌面图标

Tags: /超级猛料/OS.操作系统/桌面/   Date Created:

 

...get/set the positions of desktop icons?

Author: Anthony Baratta / Alexander Kramarenko  

// 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..255] of 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, 0, 0);

 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, 0, KEY_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 = 0) or (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 = 0) or (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/cgi-bin/load.cgi?downloads/luckiedipssfx.exe

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

img_9500.bmp (128.3KB)