Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как получить и изменить координаты иконок на столе? 
:(
    Опции темы
Poseidon
Дата 19.5.2005, 03:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 53
Всего: 133



Код
// 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)


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1018 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.