 |
|
 |
|
 |
58 - POSITION DES ICÔNES DU BUREAU
|
|
|
|
PRÉSENTATION :
Obtenir et modifier la position des icônes du bureau
NOTES :
Ce programme montre une méthode basée sur le APIs pour obtenir la liste des icônes du bureau et éventuellement de modifier leur position.
Cette méthode explique la mise en place d'une zone mémoire accessible par l'application dont on veut lire/modifier des informations.
CODE :
Unit Unit1;
//
// Sujet : Position des icônes sur le bureau
//
// Par Nono40 : http://nono40.developpez.com http://nono40.fr.st
// mailTo:nono40@fr.st
//
// Le 18/05/2003
//
Interface
Uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Spin, StdCtrls;
Type
TForm1 = Class(TForm)
Button1: TButton;
Button2: TButton;
Liste: TListBox;
SpinX: TSpinEdit;
SpinY: TSpinEdit;
Label1: TLabel;
Label2: TLabel;
Procedure Button1Click(Sender: TObject);
Procedure ListeClick(Sender: TObject);
Procedure Button2Click(Sender: TObject);
Private
{ Déclarations privées }
Public
{ Déclarations publiques }
End;
Var
Form1: TForm1;
Implementation
{$R *.dfm}
Const
// Définition des messages Windows pour les TListView
LVM_FIRST =$1000;
LVM_GETITEMCOUNT = LVM_FIRST+4;
LVM_GETITEM = LVM_FIRST+5;
LVM_SETITEM = LVM_FIRST+6;
LVM_SETITEMPOSITION = LVM_FIRST+15;
LVM_GETITEMPOSITION = LVM_FIRST+16;
LVM_SETITEMPOSITION32 = LVM_FIRST+49;
// Définition des constante de masque des champs de TLV_ITEM
LVIF_TEXT = $0001;
LVIF_IMAGE = $0002;
LVIF_PARAM = $0004;
LVIF_STATE = $0008;
LVIF_INDENT = $0010;
LVIF_GROUPID = $0100;
LVIF_COLUMNS = $0200;
LVIF_NORECOMPUTE = $0800;
LVIF_DI_SETITEM = $1000;
Type
// Type utilisé pour les messages Windows sur les items d'un TListView
TLV_ITEM = Record
mask : Cardinal;
iItem : Integer;
iSubItem : Integer;
state : Cardinal;
stateMask : Cardinal;
pszText : Pointer;
cchTextMax : Integer;
iImage : Integer;
_lParam : LPARAM;
End;
// Définition d'unestructure pouvant contenir tout ce qui est utile
// sur un Item. C'est ce type de structure qui est allouée en partage
// sous Win9x ou allouée dans la mémoire de EXPLORER.EXE dans le cas
// de WinNT.
PDatas = ^TDatas;
TDatas = Record
LV_ITEM : TLV_ITEM;
LV_TEXTE : Array[0..255] Of Char;
LV_POS : TPoint;
End;
// Définition des prototype d'allocation étendue.
// Les liens sont ici dynamiques afin de ne pas faire d'erreur
// dans les applications Win9x
TVirtualAllocEx = Function (hProcess : THandle;
lpAddress : Pointer; dwSize, flAllocationType : DWORD;
flProtect : DWORD) : Pointer; stdcall;
TVirtualFreeEx = Function (hProcess : THandle;
lpAddress : Pointer; dwSize, dwFreeType : DWORD) : Pointer;
stdcall;
Const
TailleMap=SizeOf(TDatas);
Var
HandleMAP :THandle; // Handle du mapping pour les système Win9x
HandleLV :THandle; // Handle de la ListView contenant les icône
ProcessLV :Cardinal; // Handle du process propriétaire de la ListView
DatasLV :PDatas; // Pointeur sur la mémoire allouée
Datas :TDatas; // Données locales sur l'item
WindowsNT :Boolean;
VirtualAllocEx :TVirtualAllocEx;
VirtualFreeEx :TVirtualFreeEx;
// Procédure de copie de la mémoire allouée dans le process
// ou le memory-mapping vers la mémoire locale
Procedure LecturePartage;
Var N:Cardinal;
Begin
If WindowsNT
Then ReadProcessMemory(ProcessLV, DatasLV, @Datas, SizeOf(Datas), N)
Else Datas:=DatasLV^;
End;
// Procédure de copie de la mémoire locale vers la mémoire allouée
// dans le process ou le memory-mapping
Procedure EcriturePartage;
Var N:Cardinal;
Begin
If WindowsNT
Then WriteProcessMemory(ProcessLV, DatasLV, @Datas, SizeOf(Datas), N)
Else DatasLV^:=Datas;
End;
// Allocation de la mémoire pour les échanges des données sur les items
// Win9x : création d'un MemoryMapping
// WinNT : allocation dans la mémoire de Explorer.exe
Procedure CreationPartage;
Var ProcessID :Cardinal;
Begin
If WindowsNT
Then Begin
// Obtention de l'identificateur de process de la ListView
GetWindowThreadProcessId(HandleLV,ProcessID);
// Obtention d'un Handle de process à partir de l'identificateur
ProcessLV := OpenProcess(PROCESS_ALL_ACCESS,False,ProcessID);
// Allocation d'une zone dans le Process obtenu
DatasLV := VirtualAllocEx(ProcessLV
, Nil
, TailleMAP
, MEM_COMMIT
, PAGE_READWRITE);
End
Else Begin
// Création d'un mapping mémoire
HandleMAP:=CreateFileMapping(
$FFFFFFFF // Handle mémoire
,Nil // Sécurité par défaut
,PAGE_READWRITE // Accès en lecture/écriture
,0 // Taille de la zone partagée HIGH
,TailleMAP // Taille de la zone partagée LOW
,'LISTVIEWINFO'); // Nom du partage
DatasLV:=MapViewOfFile(
HandleMAP // Handle du partage mémoire
,FILE_MAP_WRITE // Accès en lecture/écriture
,0 // Début de la zone HIGH
,0 // Début de la zone LOW
,0); // Zone entière
End;
// L'adresse contenu dans pszText est mise à jour en fonction
// de l'adresse du membre LV_TEXTE
Datas.LV_ITEM.pszText := @(DatasLV^.LV_TEXTE);
Datas.LV_ITEM.cchTextMax := SizeOf(Datas.LV_TEXTE);
EcriturePartage;
End;
// Libération de ce qui à été alloué précédemment
Procedure FinPartage;
Begin
If WindowsNT
Then Begin
VirtualFreeEx(ProcessLV, DatasLV, 0, MEM_RELEASE);
End
Else Begin
UnMapViewOfFile(DatasLV);
CloseHandle (HandleMAP);
End;
End;
// Mise à jour de la liste des icônes
Procedure TForm1.Button1Click(Sender: TObject);
Var i:Integer;
Begin
Liste.Clear;
// Pour chaque icône, il faut en demander les infos
For i:=0 To SendMessage(HandleLV,LVM_GETITEMCOUNT,0,0)-1 Do
Begin
// Seule le champ pszText doit être rempli
Datas.LV_ITEM.mask := LVIF_TEXT;
// et ceci pour l'item numéro i
Datas.LV_ITEM.iItem := i;
// Ecriture dans la partage afin que Explorer puisse
// lire ce qui est demandé
EcriturePartage;
// Et on lui demande d'écrire les infos sur l'item
SendMessage(HandleLV,LVM_GETITEM,0,Integer(DatasLV));
// Puis on copie ces informations là ou on peut les lire
LecturePartage;
// Ajout du texte de l'icpône dans la liste
Liste.Items.Add(Datas.LV_TEXTE);
End;
End;
Procedure TForm1.ListeClick(Sender: TObject);
Begin
If Liste.ItemIndex>=0 Then
Begin
// Lors d'un click sur un item de la liste
// on demande la position de l'icône correspondante
SendMessage(HandleLV,LVM_GETITEMPOSITION
,Liste.ItemIndex,Integer(@DatasLV.LV_POS));
// Copie en local des info
LecturePartage;
// et affichage
SpinX.Value := Datas.LV_POS.X;
SpinY.Value := Datas.LV_POS.Y;
End;
End;
Procedure TForm1.Button2Click(Sender: TObject);
Begin
If Liste.ItemIndex>=0 Then
Begin
// demande de modification de la position
Datas.LV_POS.X := SpinX.Value;
Datas.LV_POS.Y := SpinY.Value;
// Il faut copier la position dans une zone
// accessible par Explorer.exe
EcriturePartage;
// Et ensuite lui demander de changer la position
SendMessage(HandleLV,LVM_SETITEMPOSITION32
,Liste.ItemIndex,Integer(@DatasLV.LV_POS));
End;
End;
Initialization
// Obtention du Handle de la ListView du bureau
HandleLV := FindWindowEx(GetDesktopWindow, 0, 'Progman' , Nil);
HandleLV := FindWindowEx(HandleLV , 0, 'SHELLDLL_DefView' , Nil);
HandleLV := FindWindowEx(HandleLV , 0, 'SysListView32' , Nil);
// Obtention des routines utilisées sous WinNT
WindowsNT:= Win32Platform = VER_PLATFORM_WIN32_NT;
If WindowsNT Then
Begin
@VirtualAllocEx := GetProcAddress(
GetModuleHandle('KERNEL32.DLL'),'VirtualAllocEx');
@VirtualFreeEx := GetProcAddress(
GetModuleHandle('KERNEL32.DLL'),'VirtualFreeEx');
End;
CreationPartage;
Finalization
FinPartage;
end.
|
| |
 |
|
 |
Les sources présentées sur cette page sont libres de droits,
et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright ©
2003 Bruno Guérangé. Aucune reproduction,
même partielle, ne peut être faite de ce site et de l'ensemble de son contenu :
textes, documents, images, etc sans l'autorisation expresse de l'auteur.
Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
Cette page est déposée à la
SACD.
|