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) |
| 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)
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 | |