Bonsoir à toutes et à tous.

Dans mon D7 PE je trouve une démo fort sympathique permettant de recréer un Explorateur (non, je ne parle pas du couple ShellTreeview/ShellListview).
Au premier lancement il affiche la liste des disques, tout ce qu'il y a de joli,
Je vous mets ci-dessous le code du FormCreate, avec mes ajouts en commentaires, venant de mon SDK :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
procedure TForm1.FormCreate(Sender: TObject);
var
  FileInfo: TSHFileInfo;
  ImageListHandle: THandle;
  NewPIDL: PItemIDList;
begin
  OLECheck(SHGetDesktopFolder(FIDesktopFolder));
  FIShellFolder := FIDesktopFolder;
  FIDList := TList.Create;
 
  ImageListHandle := SHGetFileInfo('C:\',
                           0,
                           FileInfo,
                           SizeOf(FileInfo),
                           SHGFI_SYSICONINDEX or SHGFI_SMALLICON);
  SendMessage(ListView.Handle, LVM_SETIMAGELIST, LVSIL_SMALL, ImageListHandle);
 
  ImageListHandle := SHGetFileInfo('C:\',
                           0,
                           FileInfo,
                           SizeOf(FileInfo),
                           SHGFI_SYSICONINDEX or SHGFI_LARGEICON);
  SendMessage(ListView.Handle, LVM_SETIMAGELIST, LVSIL_NORMAL, ImageListHandle);
 
  OLECheck(
    SHGetSpecialFolderLocation(
      Application.Handle,
      CSIDL_DRIVES, // [in] A CSIDL value that identifies the folder of interest.
      NewPIDL)      // [out] A pointer to an item identifier list (PIDL)
  );                // specifying the folder's location relative to the root
                    // of the namespace (the desktop).
                    // The calling application is responsible for freeing this pointer
                    // with the Shell's IMalloc interface (see SHGetMalloc).
 
  SetPath(NewPIDL);
 
  CoTaskMemFree(NewPIDL); // Rajout suite lecture SDK (SHGetMalloc renvoie vers CoTask...)
 
  ActiveControl := cbPath;
  cbPath.SelStart := 0;
  cbPath.SelLength := Length(cbPath.Text);
end;
Et qu'est-ce que je gagne à l'exécution ? L'erreur
Violation d'accès à l'adresse 7CE4E3C5 dans le module 'shell32.dll'. Lecture de l'adresse 00155475.
et des icônes absentes, ou "la main" (qu'on retrouve sous les dossiers partagés), et certains textes bleus, d'autres noirs...

Si maintenant je remplace ImageListHandle := SHGetFileInfo('C:\', par ImageListHandle := SHGetFileInfo('', je n'ai plus cette violation d'accès mais toutes les icônes affichent "la main"...

J'aimerais bien comprendre, car cette variable NewPIDL est locale à la procédure...

Pour info, le code de OleCheck (d'un vieux [D7 PE oblige...] ComObj.pas) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
{ Raise EOleSysError exception if result code indicates an error }
 
procedure OleCheck(Result: HResult);
begin
  if Result < 0 then OleError(Result);
end;
Pas de mystère là-dedans ; mon SDK raconterait-il des blagues ? Un tour sur MSDN et je lis
[out] A pointer to an item identifier list (PIDL) specifying the folder's location relative to the root of the namespace (the desktop). It is the responsibility of the calling application to free the returned IDList by using CoTaskMemFree.
Bon.
Donc j'ai raison (d'essayer) de libérer la mémoire, mais mon prog part en vrille !

De plus je lis, toujours à propos de cette fonction, With Microsoft Windows 2000, this function is superseded by SHGetFolderLocation.
Ça tombe bien, je suis sous 2000, donc je teste avec SHGetFolderLocation mais je gagne les mêmes résultats foireux !

Et pourtant, Madshi, sur une page d'EE dit bien qu'il faut « freer » les Pidl's :
when you call SHGetSpecialFolderLocation, Windows allocates a new pidl for you (in win9x even in shared memory). So you DO need to free it again. What happens, if you don't? Well, memory leak.
Au fait, un test avec MemCheck ne montre pas de fuite mémoire si j'enlève mon ajout (code d'origine, donc).

Voilà, désolé d'avoir été un peu long, mais si quelqu'un pouvait m'expliquer ce mystère, j'en serais vraiment ravi !
Merci,