скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

Получить или установить позицию пиктограмм рабочего стола



Оформил: DeeCo

// 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/programme/luckiedipssfx.exe 
(Complete demo to save/restore the positions of desktop icons, nonVCL)





Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook