IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Delphi .NET Discussion :

Imperfection de Delphi : Interop et IPropertyStorage ? [Bug report]


Sujet :

Delphi .NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Enseignant
    Inscrit en
    Juillet 2004
    Messages
    128
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juillet 2004
    Messages : 128
    Par défaut Imperfection de Delphi : Interop et IPropertyStorage ?
    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.

  2. #2
    Membre confirmé
    Profil pro
    Enseignant
    Inscrit en
    Juillet 2004
    Messages
    128
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juillet 2004
    Messages : 128
    Par défaut
    Bon je reviens avec mon problème, j'ai trouvé un bout de code en C que voici :

    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
     
    CLIPDATA*
     pClip = propVar.pclipdata;
     PACKEDMETA*	pPackedMeta;
     if (pClip->ulClipFmt == -1) {
       BYTE* pb = pClip->pClipData;
       if (*reinterpret_cast(pb) == CF_METAFILEPICT) {
          pb += sizeof(DWORD);		// Skip the clip type
          pPackedMeta = (PACKEDMETA*)pb;
          pb += sizeof(PACKEDMETA);	// Skip packed meta struct
          int	nMetaFileSize = pClip->cbSize - 
              sizeof(pClip->ulClipFmt) -
              sizeof(DWORD) -
              sizeof(PACKEDMETA);
                                
           HMETAFILE	hMetaFile;
           hMetaFile = SetMetaFileBitsEx(nMetaFileSize, pb);
           if (hMetaFile) {...}
    Voila ce que j'en ai fait :
    ou value est de type TPropVariant.
    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
     
    clpData:=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)));
     
             size:=clpData.cbSize-16;
             Data:=IntPtr(clpData.pClipData.ToInt32+12);
             setlength(Datas,size);
             marshal.Copy(Data,Datas,0,size);
              tpHandle:=SetEnhMetaFileBits(size,Datas);
              if tpHandle<>0 then
              begin
     
                FValue:=TMetafile.create;
                TMetaFile(FValue).Handle:=tpHandle;
              end
              else
                RaiseLastOSError;
    Mais j'ai un message avec setEnhMetaFileBits comme quoi les données ne sont pas valides alors que je teste sur un fichier word contenant mon image.
    Ce que je trouve bizarre, c'est que mon packedMeta définie par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    [structlayout(LayoutKind.Sequential)]
      TPackedMeta = packed record
        mm: word;
        xExt: word;
        yExt: word;
        reserved: word;
      end;
    à une valeur reserved différente de 0.

    Donc ma question, ai-je bien traduit mes conversion avec les pointeurs ?

Discussions similaires

  1. Interop Delphi 7 // C# .NET // Application portable
    Par babidyxp dans le forum Général Dotnet
    Réponses: 0
    Dernier message: 29/09/2009, 08h01
  2. Différences entre Delphi et Visual Basic ?
    Par Anonymous dans le forum Débats sur le développement - Le Best Of
    Réponses: 75
    Dernier message: 30/03/2009, 20h09
  3. [Kylix] Migration delphi -> kylix
    Par Christian dans le forum EDI
    Réponses: 1
    Dernier message: 03/04/2002, 22h50
  4. Réponses: 4
    Dernier message: 27/03/2002, 11h03
  5. Réponses: 2
    Dernier message: 20/03/2002, 23h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo