⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pbvariantutils.pas

📁 Delphi snippet to convert variants values to xml
💻 PAS
📖 第 1 页 / 共 3 页
字号:
{== PBVariantUtils ====================================================}
{: This unit provides a number of helper routines to analyze variants.
@author Dr. Peter Below
@desc   Version 1.0 created 2003-06-07<BR>
        Last modified       2003-06-09<P>
The unit uses Berend de Boers xml_generator unit to generate XML, you
can download this unit from http://www.thedelphimagazine.com/disks.php
(code for issue 77 (2002) or contact the author via his web site at
http://www.pobox.com/~berend/delphi .   }
{======================================================================}
{$BOOLEVAL OFF}{Unit depends on shortcut boolean evaluation}
Unit PBVariantUtils;
{$I JEDI.INC} {version symbols from Jedi code library jcl.sourceforge.net }
Interface

Uses Windows, activex,
     {$IFDEF DELPHI6_UP} variants, {$ENDIF}
     sysutils, xml_generator;

{-- VariantToXML ------------------------------------------------------}
{: Convert a variant to an XML representation
@Param V is the variant to convert
@Returns a String containing a complete XML file, ISO 8859.1-encoded
@Desc The XML representation uses four level of tags: "variant",
  "array", "element", and "binary". The root is a "variant" node. The
  "variant" node has an attribute "type", which identifies the variants
  data type. The "array" node has an attribute "bounds", which gives the
  arrays low and high bounds for each dimension, using Delphi syntax.
  "element" has an attribute "type", which has the same meaning as for
  the "variant" node type, and an element "indices", which contains the
  array index for the element. "binary" has an attribute "size", holding
  the number of bytes, and an attribute "encoding", which can be either
  "hex" or "base64" to describe the way the binary data in the node is
  represented as text. We only use hex encoding here, however. <br/>
  A "variant" can contain literal values or an "array" or "binary" child
  node, or can be empty (in case of null and unassigned nodes, for
  instance). "array" contains "element" child nodes, "element" can
  contain literal data, "binary" or "variant" nodes, which makes the
  whole structure recursive.
}{ Created 2003-06-07 by P. Below
-----------------------------------------------------------------------}
Function VariantToXML( const V: Variant ): String;

{: Convert a variant type to a string representation }
Function VarTypeToString( vt: TVarType ): String;

{: Debug helper, will convert the passed variant to XML, save it to
 a file in the temp folder, then display that via ShellExecute. It
 will usually be shown in Internet Explorer if no other program is
 registered as server for XML.
 @returns "OK" in case of succes and an exception message in case of
   failure. }
Function DebugDisplayVariant( const V: Variant ): String;

Type
  IVariantToXML = Interface
  ['{98B9AA6C-AD47-4371-99B3-91F49EAF4554}']
    Procedure Convert( const V: Variant );
    Function AsAnsiString: String;
    Function AsUTF8: String;
    Function AsUTF16: WideString;
  End;

  TPBVariantToXMLConverter = class( TInterfacedObject, IVariantToXML )
  private
    FGenerator: TXMLGenerator;
    FOwnsGenerator: Boolean;
    {$IFDEF DELPHI7_UP}
    FFmt: TFormatSettings;
    {$ENDIF}

  protected
    Procedure ConvertArrayVariantData(const V: Variant; vt: TVarType);
    Procedure ConvertByRefVariantData(const V: Variant; vt: TVarType);
    Procedure ConvertSimpleVariantData(const V: Variant);
    Procedure ConvertVariantData(const V: Variant);
    Procedure ConvertVectorVariantData(const V: Variant; vt: TVarType);

    Function  GetBoundsString( value: PVarArray ): String;
    Function  GetElementSize( vt: TVarType ): Integer;
    Function  GetSafearrayDataPointer( value: PVarArray; const indices: Array of integer ): Pointer;
    Function  GetSafeArrayLBound( value: PVarArray; dim: Integer ): Integer;
    Function  GetSafeArrayUBound( value: PVarArray; dim: Integer ): Integer;
    Procedure GetSafearrayVType( value: PVarArray; Var vt: TVarType );
    Function  IsSupportedElementType( vt: TVarType ): Boolean;

    Procedure WriteAddress( value: Pointer );
    procedure WriteBinary(size: Cardinal; pvalue: Pointer);
    Procedure WriteBoolean(value: Boolean);
    Procedure WriteBStr( value: PWidechar );
    Procedure WriteCurrency(const value: Currency);
    Procedure WriteDate(const value: TDatetime);
    Procedure WriteDecimal(const value: TDecimal);
    Procedure WriteElementData( pData: Pointer; vt: TVarType );
    procedure WriteFiletime(const value: int64);
    Procedure WriteFloat(const value: Double);
    Procedure WriteHex( value: Cardinal; width: integer );
    Procedure WriteHex64( value: int64 );
    Procedure WriteHexData(size: Cardinal; pData: PByte);
    Procedure WriteInteger( value: Integer );
    Procedure WriteInt64( value: int64 );
    Procedure WriteSafeArray(value: PVarArray; vt: TVarType);
    Procedure WriteString( value: String );
    Procedure WriteVariant(const value: Variant);
    procedure WriteVectorData(numElements: Cardinal; pData: Pointer;
      vt: TVarType);

    { Methods of the IVariantToXML interface }
    Function AsAnsiString: String;
    Function AsUTF16: WideString;
    Function AsUTF8: String;
    Procedure Convert(const V: Variant);

  public
    Constructor Create( generator: TXMLGenerator );
    Destructor Destroy; override;
  End;

Implementation

Uses classes,
     {$IFDEF DELPHI6_UP}
     VarUtils,
     {$ENDIF}
     ComObj, ShellAPI;

Const
  cVariant = 'variant';
  cArray   = 'array';
  cElement = 'element';
  cType    = 'type';
  cBounds  = 'bounds';
  cIndices = 'indices';
  cBinary  = 'binary';
  cSize    = 'size';
  cEncoding= 'encoding';
  cEncodingHex = 'hex';
  cEncodingBase64 = 'base64';

  // some new VT types not declared in D7 ActiveX unit
  VT_RECORD   = 36;
  VT_INT_PTR  = 37;
  VT_UINT_PTR = 38;
  VT_VERSIONED_STREAM = 73;
  VT_BSTR_BLOB = $fff;
  VT_VECTOR    = $1000;

  // Other things not declared in D7s units
  FADF_HAVEVARTYPE = $80;

  {$IFNDEF DELPHI6_UP}
  varShortInt = $0010; { vt_i1          16 }
  varWord     = $0012; { vt_ui2         18 }
  varLongWord = $0013; { vt_ui4         19 }
  varInt64    = $0014; { vt_i8          20 }
  {$ENDIF}

Type
  TVector = packed record
    numElements: Cardinal;
    pData: Pointer;
  end;
  PVector = ^TVector;
  {$IFNDEF DELPHI6_UP}
  PPointer = ^Pointer;
  PCardinal= ^Cardinal;
  PVarData = ^TVarData;
  PWordBool= ^WordBool;
  TVarData = packed record  // this is the D7 declaration
    case Integer of
      0: (VType: TVarType;
          case Integer of
            0: (Reserved1: Word;
                case Integer of
                  0: (Reserved2, Reserved3: Word;
                      case Integer of
                        varSmallInt: (VSmallInt: SmallInt);
                        varInteger:  (VInteger: Integer);
                        varSingle:   (VSingle: Single);
                        varDouble:   (VDouble: Double);
                        varCurrency: (VCurrency: Currency);
                        varDate:     (VDate: TDateTime);
                        varOleStr:   (VOleStr: PWideChar);
                        varDispatch: (VDispatch: Pointer);
                        varError:    (VError: HRESULT);
                        varBoolean:  (VBoolean: WordBool);
                        varUnknown:  (VUnknown: Pointer);
                        varShortInt: (VShortInt: ShortInt);
                        varByte:     (VByte: Byte);
                        varWord:     (VWord: Word);
                        varLongWord: (VLongWord: LongWord);
                        varInt64:    (VInt64: Int64);
                        varString:   (VString: Pointer);
                        varAny:      (VAny: Pointer);
                        varArray:    (VArray: PVarArray);
                        varByRef:    (VPointer: Pointer);
                     );
                  1: (VLongs: array[0..2] of LongInt);
               );
            2: (VWords: array [0..6] of Word);
            3: (VBytes: array [0..13] of Byte);
          );
      1: (RawData: array [0..3] of LongInt);
  end;

  {$ENDIF}

Function VarTypeToString( vt: TVarType ): String;
  Var
    S: String;
  Begin
    Result := '';
    If (varByRef and vt) <> 0 then
      Result := 'Byref ';
    If (varArray and vt) <> 0 then
      Result := Result + 'array of ';
    If (VT_VECTOR and vt) <> 0 then
      Result := Result + 'vector of ';

    Case vt AND varTypemask Of
      varEmpty    : S:= 'varEmpty (VT_EMPTY)';
      varNull     : S:= 'varNull (VT_NULL)';
      varSmallint : S:= 'varSmallint (VT_I2)';
      varInteger  : S:= 'varInteger (VT_I4)';
      varSingle   : S:= 'varSingle (VT_R4)';
      varDouble   : S:= 'varDouble (VT_R8)';
      varCurrency : S:= 'varCurrency (VT_CY)';
      varDate     : S:= 'varDate (VT_DATE)';
      varOleStr   : S:= 'varOleStr (VT_BSTR)';
      varDispatch : S:= 'varDispatch (VT_DISPATCH)';
      varError    : S:= 'varError (VT_ERROR)';
      varBoolean  : S:= 'varBoolean (VT_BOOL)';
      varVariant  : S:= 'varVariant (VT_VARIANT)';
      varUnknown  : S:= 'varUnknown (VT_UNKNOWN)';
      VT_DECIMAL  : S:= 'VT_DECIMAL';
      varShortInt : S:= 'varShortInt (VT_I1)';
      varByte     : S:= 'varByte (VT_UI1)';
      varWord     : S:= 'varWord (VT_UI2)';
      varLongWord : S:= 'varLongWord (VT_UI4)';
      varInt64    : S:= 'varInt64 (VT_I8)';
      VT_UI8      : S:= 'VT_UI8';
      VT_INT      : S:= 'VT_INT';
      VT_UINT     : S:= 'VT_UINT';
      VT_VOID     : S:= 'VT_VOID';
      VT_HRESULT  : S:= 'VT_HRESULT';
      VT_PTR      : S:= 'VT_PTR';
      VT_SAFEARRAY: S:= 'VT_SAFEARRAY';
      VT_CARRAY   : S:= 'VT_CARRAY';
      VT_USERDEFINED: S:= 'VT_USERDEFINED';
      VT_LPSTR    : S:= 'VT_LPSTR';
      VT_LPWSTR   : S:= 'VT_LPWSTR';
      VT_RECORD   : S:= 'VT_RECORD';
      VT_INT_PTR  : S:= 'VT_INT_PTR';
      VT_UINT_PTR : S:= 'VT_UINT_PTR';
      VT_FILETIME : S:= 'VT_FILETIME';
      VT_BLOB     : S:= 'VT_BLOB';
      VT_STREAM   : S:= 'VT_STREAM';
      VT_STORAGE  : S:= 'VT_STORAGE';
      VT_STREAMED_OBJECT: S:= 'VT_STREAMED_OBJECT';
      VT_STORED_OBJECT: S:= 'VT_STORED_OBJECT';
      VT_BLOB_OBJECT: S:= 'VT_BLOB_OBJECT';
      VT_CF       : S:= 'VT_CF';
      varStrArg   : S:= 'varStrArg (VT_CLSID)';
      VT_VERSIONED_STREAM: S:= 'VT_VERSIONED_STREAM';
      VT_BSTR_BLOB: S:= 'VT_BSTR_BLOB';
      varString   : S:= 'varString';
      varAny      : S:= 'varAny';
      VT_ILLEGAL  : S:= 'unknown';
    else
      S:= Format('unknown typecode $%x', [vt and varTypemask]);
    End; { Case }
    Result := Result + S;
  End;

Function VariantToXML( const V: Variant ): String;
  Var
    generator: TXMLGenerator;
    converter: IVariantToXML;
  Begin { VariantToXML }
    generator := TXMLGenerator.CreateWithEncoding( $10000, encISO_8859_1 );
    Try
      converter:=  TPBVariantToXMLConverter.Create( generator );
      converter.Convert( V );
      Result := converter.AsAnsiString;
    Finally
      generator.Free;
    End; { Finally }
  End; { VariantToXML }

Procedure SaveStringToFile( const S, filename: String );
  Var
    fs: TFilestream;
  Begin
    fs:= TFileStream.Create( filename, fmCreate );
    try
      If Length( S ) > 0 Then 
        fs.WriteBuffer( S[ 1 ], Length( S ));
    finally
      fs.free
    end;
  End; { SaveStringToFile }

{$IFNDEF DELPHI6_UP}
Function IncludeTrailingPathDelimiter( const path: String ): String;
  Begin
    Result := IncludeTrailingBackslash( path );
  End;

const
  oleaut32 = 'oleaut32.dll';

function SafeArrayGetDim( pdata: PVarArray ): Integer; stdcall;
  external oleaut32 name 'SafeArrayGetDim';

function SafeArrayPtrOfIndex(psa: PVarArray; rgIndices: Pointer; out pvData: Pointer): HResult; stdcall;
  external oleaut32 name 'SafeArrayPtrOfIndex';

function SafeArrayGetLBound(psa: PVarArray; nDim: Integer; out lLbound: Longint): HResult; stdcall;
  external oleaut32 name 'SafeArrayGetLBound';

function SafeArrayGetUBound(psa: PVarArray; nDim: Integer; out lUbound: Longint): HResult; stdcall;
  external oleaut32 name 'SafeArrayGetUBound';

function SafeArrayLock(psa: PVarArray): HResult; stdcall;
  external oleaut32 name 'SafeArrayLock';
function SafeArrayUnlock(psa: PVarArray): HResult; stdcall;
  external oleaut32 name 'SafeArrayUnlock';
function SafeArrayGetElemsize(psa: PVarArray): Integer; stdcall;
  external oleaut32 name 'SafeArrayGetElemsize';
{$ENDIF}


Function DebugDisplayVariant( const V: Variant ): String;
  Var
    S: String;
    filename: String;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -