contents   index   previous   next



VariantCreate

 

f90VB Modules

 

f90VBDefs, f90VBVariants

Summary

 

Creates, initializes and returns a Variant of the requested type.

Syntax

 

Syntax Variation 1:

 

type(VARIANT) function VariantCreate (iRet)

Syntax Variation 2:

integer(HRESULT_KIND),intent(out),optional:: iRet

 

type(VARIANT) function VariantCreate (vtType, InitValue, iRet, InitValueType, lcid, flags)

integer(VARTYPE_KIND),intent(in)::  vtType
{
logical,intent(in):: InitValue |
integer(BYTE_KIND),intent(in):: InitValue |
integer(SHORT_KIND),intent(in):: InitValue |
integer(LONG_KIND),intent(in):: InitValue |
real(FLOAT_KIND),intent(in):: InitValue |
real(DOUBLE_KIND),intent(in):: InitValue |
type(CURRENCY),intent(in):: InitValue |
type(DECIMAL),intent(in):: InitValue |
character(len=*),intent(in):: InitValue |
type(FSafeArray),intent(in):: InitValue |
integer(SAFEARRAY_KIND),intent(in):: InitValue |
integer(BSTRHNDL_KIND),intent(in):: InitValue |
integer(OLECHAR_KIND),dimension(:),intent(in):: InitValue |
type(OLESTRING),intent(in):: InitValue |
}
integer(HRESULT_KIND),intent(out),optional:: iRet
integer(VARTYPE_KIND),intent(in),optional:: InitValueType
integer(LCID_KIND),intent(in),optional:: lcid
integer(WORD_KIND),intent(in),optional:: flags

Arguments

 

vtType [Input]

The VT-Type of the Variant to create. See comments for more information.

InitValue [Input]

A value to initialize the variant. If the type of InitValue is different to the type of the new variant, VariantCreate will perform the necessary type conversion.

 

InitValueType [Input/Optional]

The VT-Type of InitValue. See comments for more information.

 

lcid [Input/Optional]

A locale identifier.

 

flags [Input/Optional]

Flags that control the coercion of InitValue. The only defined flag is VARIANT_NOVALUEPROP, which prevents the function from attempting to coerce an object to a fundamental type by getting the object’s Value property. Applications should set this flag only if necessary, because it makes their behavior inconsistent with other applications

iRet [Output/Optional]

Upon return, iRet contains S_OK or an error code. See comments for more information.

Comments

 

Syntax Variation 1 creates an empty variant (i.e. a variant which vt field is VT_EMPTY). Syntax Variation 2 creates and initializes the variant with the contents of InitValue in a single step. If an error occurs during the creation process, function VariantCreate returns an empty variant and an error code in argument iRet.

 

You cannot create variants that contain the VT_BYREF flag using VariantCreate. To do this you can first create an empty variant (possibly using VariantCreate), and then set the variant fields manually.

Argument vtType

 

Table 3.1 (User Manual - Chapter 3) contains a list of allowed values for vtType as well as the f90VB constants that represent them. However, not all possible combinations of vtType, InitValue and InitValueType are allowed. In particular:

 

If vtType contains the mask VT_ARRAY (to create a Variant containing a Safe Array), the passed InitValue must be a handle to a Safe Array and InitValueType must also have the mask VT_ARRAY.

 

vtType cannot have the VT_BYREF flag when creating variants with VariantCreate.

 

Attempting to use an invalid combination of vtType, InitValue and InitValueType will result in an error condition that can be detected by testing the value returned in argument iRet.

Argument InitValue

 

InitValue can be any valid Fortran or OLE/COM type. If the type of InitValue is not the same as the type of the variant, VariantCreate attempts to coerce the content of InitValue into the appropriate variant type. Coercion is performed using the OLE/COM conversion rules. During the coercion process, VariantCreate de-references InitValue. So if InitValue is a pointer (indicated with a InitValueType that contains the VT_BYREF mask), or if InitValue is a variant containing the VT_BYREF flag, the new variant created by VariantCreate will be initialized to the value pointed to by InitValue, but it will not have the VT_BYREF flag.

 

Note that f90VB represents some OLE/COM types as handles rather than an intrinsic type. For example BStrings and Safe Arrays are represented as a long integer that contains a handle (pointer) to the BString or Safe Array. In these cases, you must use optional argument InitValueType to clarify the content of InitValue.

Argument InitValueType

 

This is an optional argument that can be used to further identify the contents of InitValue. If you don’t provide this argument, InitValue is assumed to be the VT-Type equivalent of its Fortran type (see table below).

 

Many OLE/COM standard types do not have intrinsic representations in Fortran. For example, Fortran does not provide a representation for long unsigned integers (VT_UI4). However, there is no reason why you cannot store a long unsigned value into a normal Fortran signed integer; both types use the same amount of bytes (four in this case). f90VB uses this fact to store pointers (handles) to BStrings and Safe Arrays in long integer variables. The only difference between an unsigned and a signed integer is the way applications interpret the four bytes used by both quantities. In the case of applications written in Fortran, the most significant bit is taken to represent the sign of the quantity. If you want your variant to see the passed quantity as a long unsigned integer, you can indicate so by passing VT_UI4 in argument InitValueType.

 

Note that allowed InitValueType values depend of the Fortran type of argument InitValue. For example, if you pass an integer(2) variable in argument InitValue, you can only specify two possible types in InitValueType; VT_UI2 (unsigned two-byte integer) or VT_I2 (signed two-byte integer). In this case passing any other VT-Type constant in InitValueType will result in an error condition, and function VariantCreate will return an empty variant. The table below shows allowed InitValueType for the different Fortran types passed in as InitValue arguments.

 

 

Type of the Fortran variable passed as argument InitValue Assumed type of InitValue if InitValueType is not indicated Allowed InitValueType values that can be used to further classify the Fortran variable passed in InitValue
Logical VT_BOOL VT_BOOL
integer(BYTE_KIND) VT_I1 VT_I1, VT_UI1
integer(SHORT_KIND) VT_I2 VT_I2, VT_UI2, VT_BOOL
integer(LONG_KIND)

integer(BSTRHNDL_KIND)

integer(SAFEARRAY_KIND) VT_I4 VT_I4, VT_UI4, VT_BSTR, VT_DISPATCH, VT_ERROR, VT_UNKNOWN, VT_INT, VT_UINT, VT_VOID, VT_HRESULT, VT_PTR, VT_LPSTR, VT_LPWSTR, VT_RECORD, VT_CLSID, and the following masks: VT_BYREF, VT_ARRAY

real(FLOAT_KIND) VT_R4 VT_R4

real(DOUBLE_KIND) VT_R8 VT_R8, VT_DATE

type(CURRENCY) VT_CY VT_CY

type(DECIMAL) VT_DECIMAL VT_DECIMAL

character(len=*) VT_LPSTR VT_LPSTR

integer(OLECHAR_KIND),dimension(:) VT_LPWSTR VT_LPWSTR

type(OLESTRING) VT_LPWSTR VT_LPWSTR

type(FSafeArray) VT_ARRAY Any valid VT-Type masked with VT_ARRAY

type(VARIANT) VT_VARIANT Ignored. Information taken directly from the InitValue.

Argument lcid

 

Optional Argument lcid can be used to indicate the Locale Id (LCID) of InitValue. This value is useful when either InitValue or the variant to create are of type VT_BSTR, VT_DATE or VT_DISPATCH. If argument lcid is not passed, the default user Locale (LOCALE_USER_DEFAULT) is used. The Locale controls things like the format in which dates are converted to strings, the symbol used as the decimal separator, currency symbols, etc.

Argument iRet

 

Indicates success or failure of the subroutine. The following codes can be returned in this argument:

 

 

Value returned in argument iRet Description
S_OK Success.
DISP_E_BADVARTYPE The value of vtType is not a valid type of variant.
DISP_E_OVERFLOW The data pointed to by InitValue does not fit in the destination type.
DISP_E_TYPEMISMATCH InitValue could not be coerced to the specified type.
E_INVALIDARG One of the arguments is invalid.
E_OUTOFMEMORY Memory could not be allocated for the conversion.

Examples

 

The following examples show how to create some common variants. In addition, see the examples in Chapter 3 (User Manual).

 

program VariantCreateExample

 

!Demonstrates the use of VariantCreate

!Copyright 1999-2000, Canaima Software

!All rights reserved

 

use f90VBDefs

use f90VBSafeArrays

use f90VBBStrings

use f90VBVariants

implicit none

 

type(VARIANT)::VarVect(20)

integer(BSTRHNDL_KIND)::BStrSrc, BStrDest

integer(SAFEARRAY_KIND)::SAHndlSrc

integer(OLECHAR_KIND),dimension(50)::FxOLEStrSrc

type(OLEString)::OLEStrSrc

character(len=50)::FStrSrc, FStrDest

logical::LogicSrc

integer(SHORT_KIND)::ShortSrc

integer(LONG_KIND)::LongSrc, Ptr

real(FLOAT_KIND)::RealSrc, RealDest

real(DATE_KIND)::DateSrc

 

integer(HRESULT_KIND)::iRet,i

 

!Initialize some of the source values

BStrSrc = BStrAlloc('Example BString')

call StrCopy('Example Fixed OLE string', FxOLEStrSrc)

call StrCopy('Example Fortran OLE string', OLEStrSrc)

FStrSrc= 'Example Fortran string'

LogicSrc = .true.

ShortSrc = -10

LongSrc = -20

RealSrc = 20.5

 

!Create some variants containing BStrings

 

!from a f90VB Fixed Ole string

VarVect(1)=VariantCreate(VT_BSTR, FxOLEStrSrc,iRet)

!from a f90VB OLE string

VarVect(2)=VariantCreate(VT_BSTR, OLEStrSrc, iRet)

!from a Fortran string

VarVect(3)=VariantCreate(VT_BSTR, FStrSrc, iRet)

!from a Fortran Logical

VarVect(4)=VariantCreate(VT_BSTR, LogicSrc, iRet)

!from a short integer interpreted as unsigned value

VarVect(5)=VariantCreate(VT_BSTR, ShortSrc, iRet, VT_UI2)

!from a signed short integer

VarVect(6)=VariantCreate(VT_BSTR, ShortSrc, iRet, VT_I2)

!from a long integer

VarVect(7)=VariantCreate(VT_BSTR, LongSrc, iRet)

!for a long integer interpreted as unsigned value

VarVect(8)=VariantCreate(VT_BSTR, LongSrc, iRet, VT_UI4)

!from a BString

VarVect(9)=VariantCreate(VT_BSTR, BStrSrc, iRet, VT_BSTR)

!from a real passed as a pointer

VarVect(10)=VariantCreate(VT_BSTR, loc(LongSrc), iRet, &

                          VT_I4+VT_BYREF)

!from a real

VarVect(11)=VariantCreate(VT_BSTR, RealSrc, iRet)

 

!Print the content of these variants

do i=1,11

    call StrCopy(VarVect(i)%varVal%bstrVal,FStrDest)

    write(*,'(a9,i2.2,a2,a50)') 'VarVect(',i,'):', &

                                trim(FStrDest)

    !clear the variant for later use

    call VariantClear(VarVect(i))

enddo

 

!Clear dynamic strings used as source values

call StrFree(BStrSrc)

call StrFree(OLEStrSrc)

 

!Create variants containing real values

 

!from a fortran logical

VarVect(1)=VariantCreate(VT_R4, .false., iRet)

!from a short integer interpreted as unsigned value

VarVect(2)=VariantCreate(VT_R4, ShortSrc, iRet, VT_UI2)

!from a signed short integer

VarVect(3)=VariantCreate(VT_R4, ShortSrc, iRet, VT_I2)

!from a long integer

VarVect(4)=VariantCreate(VT_R4, LongSrc, iRet)

!for a long integer interpreted as unsigned value

VarVect(5)=VariantCreate(VT_R4, LongSrc, iRet, VT_UI4)

!from a real passed as a pointer

VarVect(6)=VariantCreate(VT_R4, loc(RealSrc), iRet, &

                         VT_R4+VT_BYREF)

!from a fortran string

VarVect(7)=VariantCreate(VT_R4, '101.05', iRet)

 

!Print the content of these variants

print *,''

do i=1,7

    write(*,'(a9,i2.2,a2,f15.2)') 'VarVect(',i,'):', &

                                  VarVect(i)%VarVal%fltVal

    !clear the variant for later use

    call VariantClear(VarVect(i))

enddo

 

!Create a date value from a fortran string

VarVect(1) = VariantCreate(VT_DATE,'01/01/1999 10:00 AM',iRet)

 

!Retrieve the date as a BString for printing

BStrDest = VariantToBString(VarVect(1),iRet)

call StrCopy(BStrDest,FStrDest,iRet)

print *,''

print *,'Date: ', FStrDest

print *,'Numeric representation of date above:', &

         VarVect(1)%VarVal%dateVal

!Free the temporal BString

call StrFree(BStrDest)

 

!Create a temporal safe array

call SafeArrayCreate(SAHndlSrc, VT_R4, 1,5)

!Add some data to the safe array

do i=SafeArrayLowerBound(SAHndlSrc,1), &

     SafeArrayUpperBound(SAHndlSrc,1)

    call SafeArrayPutElement(SAHndlSrc,real(i,4),i,iRet)

enddo

 

!Create a variant containing a copy of the safe array

VarVect(2) = VariantCreate(VT_ARRAY,SAHndlSrc,iRet,VT_ARRAY,iRet)

 

!print the elements of the safe array

print *,''

print *,'Elements of a variant with a Safe Array:'

do i=SafeArrayLowerBound(VarVect(2)%varVal%parray,1), &

     SafeArrayUpperBound(VarVect(2)%varVal%parray,1)

    call SafeArrayGetElement(SAHndlSrc,RealDest,i,iRet)

    print *,RealDest

enddo

!Destroy the temporal safe array

call SafeArrayDestroy(SAHndlSrc,iRet)

 

!Clear variants

do i=1,2

    call VariantClear(VarVect(i))

enddo

 

stop

end

Related Topics

 

For information about: See:
Changing the type of a variant VariantChangeType
Initializing a variant VariantInit
Copying a Variant VariantCopy, VariantCopyInd

 

 


VariantCyFrom