Je travailles depuis une semaine sur IPropertyStorage et après quelques recherches je suis tomber sur quelques bugs.

Déjà le type TStatPropSTG n'est pas défini correctement dans Borland.VCL.activeX. voici la bonne déclaration :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
 
tagSTATPROPSTG = packed record
    lpwstrName: IntPtr; { POleStr }
    propid: TPropID;
    vt: TVarType;
  end;
  STATPROPSTG = tagSTATPROPSTG;
  TStatPropStg = tagSTATPROPSTG;
Bon ensuite je me balade avec plein d'interrogations.

Lorsque j'utilise IPropertyStorage.ReadMultiple j'ai un problème avec mon element de type TPropVariant. S'il s'agit d'un élément VT_VECTOR je me retrouve avec un tableau.
Si je prends la propriété capropvar.pelems elle est défini comme un IntPtr, mais en fait in s'agit d'un pointeur sur un tableau de TPropVariant. Comment je fais pour récupérer mon tableau ?
pour l'instant je fais :
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
 
  nb:=value.ulVal;
  if value.vt<>VT_EMPTY then
    subType:=value.vt - VT_VECTOR
  else
    subType:=VT_EMPTY;
  offs:=0;
  case subType of
    VT_LPSTR,VT_LPWSTR : len:=sizeof(IntPtr);
    VT_VARIANT : len:=SizeOf(TypeOf(TPropVariant));
  end;
  for I := 0 to nb - 1 do
  begin
    if subType<>VT_VARIANT then
      Data:=IntPtr(integer(value.caub.pElems.ToInt32)+i*sizeof(IntPtr))
    else
      Data:=IntPtr(value.caub.pElems.ToInt32+i*sizeof(TPropVariant));
    if subType<>VT_VARIANT then
    begin
      newProp.vt:=subType;
      newProp.puuid:=marshal.ReadIntPtr(Data);
      FValues.AddGood(subType).LoadValue(newProp);
    end
    else
    begin
      newProp:=TPropVariant(marshal.PtrToStructure(Data,typeOf(TPropVariant)));
      FValues.AddGood(newProp.vt).LoadValue(newprop);
    end;
  end;
Et donc je suis obligé de faire des conversions du type IntPtr(....ToInt32+...);

Enfin passons au cas où j'ai un TPropVariant de type VT_CF. Je n'arrive pas à récupérer l'image.
Voilà ce que je fais
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
 
lpData:=TClipData(marshal.PtrToStructure(value.pclipdata,typeof(TclipData)));
  size:=clpData.cbSize;
  format:=clpData.ulClipFmt;
  Data:=clpData.pClipData;
  if format=-1 then
  begin
    fileFormat:=marshal.ReadInt32(Data);
    case fileFormat of
      CF_METAFILEPICT :
        begin
          Data:=IntPtr(Data.ToInt32+sizeof(Int32));
          packedMeta:=TPackedMeta(marshal.PtrToStructure(Data,typeOf(TPackedMeta)));
          Data:=IntPtr(Integer(Data.ToInt32)+marshal.SizeOf(typeof(TPackedMeta)));
          size:=clpData.cbSize-sizeof(clpData.ulClipFmt)-sizeof(DWord)-sizeof(TPackedMeta);
          nSizeImage:=4*packedMeta.xExt*packedMeta.yExt;
          tpHandle:=SetEnhMetaFileBits(size,Data);
          if tpHandle<>0 then
          begin
 
            FValue:=TMetafile.create;
            TMetaFile(FValue).Handle:=tpHandle;
          end
          else
            RaiseLastOSError;
        end;
      CF_BITMAP :
        begin
          FValue:=TBitmap.Create;
        end;
    end;
  end;
Le problème c'est que j'ai une erreur. raiseLastOsError me retroune que les données ne sont pas valides. Pourtant j'ai suivi les instructions d'un site. Si quelqu'un a un autre exemple pour obtenir l'image associé à un fichier je suis preneur.