views:

700

answers:

4

Hi, first apologies for my english, I hope it make sense what I`ve wrote here. Now to my problem.

How can I get the string representation of the content type of a Variant using TypInfo.GetEnumName(). I have tried the following, without luck, i get a numeric representation.

myString := GetEnumName( TypeInfo(TVarType), TVarData(myVar).VType );

thank you

+3  A: 

Quoting from the Delphi 2007 help:

Use GetEnumName to convert a Delphi enumerated value into the symbolic name that represents it in code.

That means that you can't use it for that purpose, as TVarData.VType is not an enumerated value, but an integer which is set to one of the constants in System.pas that are taken from the Windows SDK wtypes.h file. Look at the source of GetEnumName(), it does immediately return a string containing the value of the integer.

Edit:

is there any other way to get the string representation of TVarData.VType

You can determine the string representation manually. First you need to be aware of that there are several bits of information encoded in that integer, so a simple case statement or array lookup will not work. The lower 12 bits are the type mask, and the upper bits encode information about whether it is a vector or array type and whether it is given by reference or not. The important parts are:

const
  varTypeMask = $0FFF;
  varArray    = $2000;
  varByRef    = $4000;

So you could do something like:

function VariantTypeName(const AValue: TVarData): string;
begin
  case AValue.VType and varTypeMask of
    vtInteger: Result := 'integer';
    // ...
  end;

  if AValue.VType and varArray <> 0 then
    Result := 'array of ' + Result;
  if AValue.VType and varByRef <> 0 then
    Result := Result + ' by ref';
end;
mghie
thank you for the answer ... is there any other way to get the string representation of TVarData.VType ?
Alin Sfetcu
+1  A: 

Since it's not an enum, you'll have to do it manually. Write something like this:

function VariantTypeName(const value: TVarData): string;
begin
  case value.VType of
    vtInteger: result := 'integer';
    //and so on
end;

Or, since the values in System.pas are listed in order, you could try declaring a const array of strings and have your VariantTypeName function return the appropriate member of the array.

Mason Wheeler
+7  A: 

Just use the build-in Delphi function for getting the string representation of a Variant type.

var
  MyVariantType: string;
  MyVariant: Variant;
begin
  MyVariant := 'Hello World';
  MyVariantType := VarTypeAsText(VarType(MyVariant));
  ShowMessage(MyVariantType); //displays: String

  MyVariant := 2;
  MyVariantType := VarTypeAsText(VarType(MyVariant));
  ShowMessage(MyVariantType); //displays: Byte
end;
The_Fox
+1, didn't know about this function.
mghie
Ah, it's in Delphi 2007, but not in Delphi 5. Do you know by chance with what version this became available?
mghie
Using Delphi 7 here, the function probably came with the Variants unit.
The_Fox
A: 

Here's a thought for Delphi versions that don't support VarTypeAsText: You could define a enumerate type yourself that follows the VType values:

type
  {$TYPEINFO ON}
  TMyVarType = (
    varEmpty = System.varEmpty, 
    varNull = System.varNull,
    // etc...
    );

(Fill the unused enum slots too - see http://stackoverflow.com/questions/1420562/why-do-i-get-type-has-no-typeinfo-error-with-an-enum-type for the reasoning behind this).

Next, use these functions to read the Variants' type as your own enumerate type :

function MyVarType(VType: TVarType): TMyVarType; overload;
begin
  Result := TMyVarType(VType);
end;

function MyVarType(V: Variant): TMyVarType; overload;
begin
  Result := TMyVarType(TVarData(V).VType);
end;

And then you can convert it to a string like this :

function VarTypeToString(aValue: TMyVarType): string;
begin
  Result := GetEnumName(TypeInfo(TMyVarType), Ord(aValue));
end;
PatrickvL