Developpez.com - Delphi
X

Choisissez d'abord la catégorieensuite la rubrique :

Nono40.developpez.com
Le petit coin du web de Nono40
SOURCES TESTS DELPHI WIN32 AUTOMATISMES DELPHI .NET QUICK-REPORT
Retour à l'accueil
58 - POSITION DES ICÔNES DU BUREAU

PRÉSENTATION : Obtenir et modifier la position des icônes du bureau
ZIP : Téléchargez le zip APERÇUS :

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..255Of 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 œuvre intellectuelle protégée par les droits d'auteur. 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'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Responsables bénévoles de la rubrique Delphi : Gilles Vasseur - Alcatîz -