home *** CD-ROM | disk | FTP | other *** search
-
- <HTML>
- <HEAD>
- <TITLE>Win32::OLE::Variant - Create and modify OLE VARIANT variables</TITLE>
- <LINK REL="stylesheet" HREF="../../../../Active.css" TYPE="text/css">
- <LINK REV="made" HREF="mailto:">
- </HEAD>
-
- <BODY>
- <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
- <TR><TD CLASS=block VALIGN=MIDDLE WIDTH=100% BGCOLOR="#cccccc">
- <STRONG><P CLASS=block> Win32::OLE::Variant - Create and modify OLE VARIANT variables</P></STRONG>
- </TD></TR>
- </TABLE>
-
- <A NAME="__index__"></A>
- <!-- INDEX BEGIN -->
-
- <UL>
-
- <LI><A HREF="#name">NAME</A></LI><LI><A HREF="#supportedplatforms">SUPPORTED PLATFORMS</A></LI>
-
- <LI><A HREF="#synopsis">SYNOPSIS</A></LI>
- <LI><A HREF="#description">DESCRIPTION</A></LI>
- <UL>
-
- <LI><A HREF="#functions">Functions</A></LI>
- <LI><A HREF="#methods">Methods</A></LI>
- <LI><A HREF="#overloading">Overloading</A></LI>
- <LI><A HREF="#class variables">Class Variables</A></LI>
- <LI><A HREF="#constants">Constants</A></LI>
- <LI><A HREF="#variants">Variants</A></LI>
- <LI><A HREF="#variant arrays">Variant arrays</A></LI>
- <LI><A HREF="#variants by reference">Variants by reference</A></LI>
- </UL>
-
- <LI><A HREF="#authors/copyright">AUTHORS/COPYRIGHT</A></LI>
- </UL>
- <!-- INDEX END -->
-
- <HR>
- <P>
- <H1><A NAME="name">NAME</A></H1>
- <P>Win32::OLE::Variant - Create and modify OLE VARIANT variables</P>
- <P>
- <HR>
- <H1><A NAME="supportedplatforms">SUPPORTED PLATFORMS</A></H1>
- <UL>
- <LI>Windows</LI>
- </UL>
- <HR>
- <H1><A NAME="synopsis">SYNOPSIS</A></H1>
- <PRE>
- use Win32::OLE::Variant;
- my $var = Variant(VT_DATE, 'Jan 1,1970');
- $OleObject->{value} = $var;
- $OleObject->Method($var);</PRE>
- <P>
- <HR>
- <H1><A NAME="description">DESCRIPTION</A></H1>
- <P>The IDispatch interface used by the Perl OLE module uses a universal
- argument type called VARIANT. This is basically an object containing
- a data type and the actual data value. The data type is specified by
- the VT_xxx constants.</P>
- <P>
- <H2><A NAME="functions">Functions</A></H2>
- <DL>
- <DT><STRONG><A NAME="item_Variant">Variant(TYPE, DATA)</A></STRONG><BR>
- <DD>
- This is just a function alias of the <CODE>Win32::OLE::Variant-</CODE>new()>
- method (see below). This function is exported by default.
- <P></P></DL>
- <P>
- <H2><A NAME="methods">Methods</A></H2>
- <DL>
- <DT><STRONG><A NAME="item_new">new(TYPE, DATA)</A></STRONG><BR>
- <DD>
- This method returns a Win32::OLE::Variant object of the specified
- TYPE that contains the given DATA. The Win32::OLE::Variant object
- can be used to specify data types other than IV, NV or PV (which are
- supported transparently). See <EM>Variants</EM> below for details.
- <P>For VT_EMPTY and VT_NULL variants, the DATA argument may be omitted.
- For all non-VT_ARRAY variants DATA specifies the initial value.</P>
- <P>To create a SAFEARRAY variant, you have to specify the VT_ARRAY flag in
- addition to the variant base type of the array elemnts. In this cases
- DATA must be a list specifying the dimensions of the array. Each element
- can be either an element count (indices 0 to count-1) or an array
- reference pointing to the lower and upper array bounds of this dimension:</P>
- <PRE>
- my $Array = Win32::OLE::Variant->new(VT_ARRAY|VT_R8, [1,2], 2);</PRE>
- <P>This creates a 2-dimensional SAFEARRAY of doubles with 4 elements:
- (1,0), (1,1), (2,0) and (2,1).</P>
- <P>A special case is the the creation of one-dimensional VT_UI1 arrays with
- a string DATA argument:</P>
- <PRE>
- my $String = Variant(VT_ARRAY|VT_UI1, "String");</PRE>
- <P>This creates a 6 element character array initialized to ``String''. For
- backward compatibility VT_UI1 with a string initializer automatically
- implies VT_ARRAY. The next line is equivalent to the previous example:</P>
- <PRE>
- my $String = Variant(VT_UI1, "String");</PRE>
- <P>If you really need a single character VT_UI1 variant, you have to create
- it using a numeric intializer:</P>
- <PRE>
- my $Char = Variant(VT_UI1, ord('A'));</PRE>
- <P></P>
- <DT><STRONG><A NAME="item_As"><CODE>As(TYPE)</CODE></A></STRONG><BR>
- <DD>
- <A HREF="#item_As"><CODE>As</CODE></A> converts the VARIANT to the new type before converting to a
- Perl value. This take the current LCID setting into account. For
- example a string might contain a ',' as the decimal point character.
- Using <CODE>$variant-</CODE>As(VT_R8)> will correctly return the floating
- point value.
- <P>The underlying variant object is NOT changed by this method.</P>
- <P></P>
- <DT><STRONG><A NAME="item_ChangeType"><CODE>ChangeType(TYPE)</CODE></A></STRONG><BR>
- <DD>
- This method changes the type of the contained VARIANT in place. It
- returns the object itself, not the converted value.
- <P></P>
- <DT><STRONG><A NAME="item_Copy"><CODE>Copy([DIM])</CODE></A></STRONG><BR>
- <DD>
- This method creates a copy of the object. If the original variant had
- the VT_BYREF bit set then the new object will contain a copy of the
- referenced data and not a reference to the same old data. The new
- object will not have the VT_BYREF bit set.
- <PRE>
- my $Var = Variant(VT_I4|VT_ARRAY|VT_BYREF, [1,5], 3);
- my $Copy = $Var->Copy;</PRE>
- <P>The type of <CODE>$Copy</CODE> is now VT_I4|VT_ARRAY and the value is a copy of
- the other SAFEARRAY. Changes to elements of <CODE>$Var</CODE> will not be reflected
- in <CODE>$Copy</CODE> and vice versa.</P>
- <P>The <A HREF="#item_Copy"><CODE>Copy</CODE></A> method can also be used to extract a single element of a
- VT_ARRAY | VT_VARIANT object. In this case the array indices must be
- specified as a list DIM:</P>
- <PRE>
- my $Int = $Var->Copy(1, 2);</PRE>
- <P><CODE>$Int</CODE> is now a VT_I4 Variant object containing the value of element (1,2).</P>
- <P></P>
- <DT><STRONG><A NAME="item_Currency">Currency([FORMAT[, LCID]])</A></STRONG><BR>
- <DD>
- This method converts the VARIANT value into a formatted curency string. The
- FORMAT can be either an integer constant or a hash reference. Valid constants
- are 0 and LOCALE_NOUSEROVERRIDE. You get the value of LOCALE_NOUSEROVERRIDE
- from the Win32::OLE::NLS module:
- <PRE>
- use Win32::OLE::NLS qw(:LOCALE);</PRE>
- <P>LOCALE_NOUSEROVERRIDE tells the method to use the system default currency
- format for the specified locale, disregarding any changes that might have
- been made through the control panel application.</P>
- <P>The hash reference could contain the following keys:</P>
- <PRE>
- NumDigits number of fractional digits
- LeadingZero whether to use leading zeroes in decimal fields
- Grouping size of each group of digits to the left of the decimal
- DecimalSep decimal separator string
- ThousandSep thousand separator string
- NegativeOrder see L<Win32::OLE::NLS/LOCALE_ICURRENCY>
- PositiveOrder see L<Win32::OLE::NLS/LOCALE_INEGCURR>
- CurrencySymbol currency symbol string</PRE>
- <P>For example:</P>
- <PRE>
- use Win32::OLE::Variant;
- use Win32::OLE::NLS qw(:DEFAULT :LANG :SUBLANG :DATE :TIME);
- my $lcidGerman = MAKELCID(MAKELANGID(LANG_GERMAN, SUBLANG_NEUTRAL));
- my $v = Variant(VT_CY, "-922337203685477.5808");
- print $v->Currency({CurrencySymbol => "Tuits"}, $lcidGerman), "\n";</PRE>
- <P>will print:</P>
- <PRE>
- -922.337.203.685.477,58 Tuits</PRE>
- <P></P>
- <DT><STRONG><A NAME="item_Date">Date([FORMAT[, LCID]])</A></STRONG><BR>
- <DD>
- Converts the VARIANT into a formatted date string. FORMAT can be either
- one of the following integer constants or a format string:
- <PRE>
- LOCALE_NOUSEROVERRIDE system default date format for this locale
- DATE_SHORTDATE use the short date format (default)
- DATE_LONGDATE use the long date format
- DATE_YEARMONTH use the year/month format
- DATE_USE_ALT_CALENDAR use the alternate calendar, if one exists
- DATE_LTRREADING left-to-right reading order layout
- DATE_RTLREADING right-to left reading order layout</PRE>
- <P>The constants are available from the Win32::OLE::NLS module:</P>
- <PRE>
- use Win32::OLE::NLS qw(:LOCALE :DATE);</PRE>
- <P>The following elements can be used to construct a date format string.
- Characters must be specified exactly as given below (e.g. ``dd'' <STRONG>not</STRONG> ``DD'').
- Spaces can be inserted anywhere between formating codes, other verbatim
- text should be included in single quotes.</P>
- <PRE>
- d day of month
- dd day of month with leading zero for single-digit days
- ddd day of week: three-letter abbreviation (LOCALE_SABBREVDAYNAME)
- dddd day of week: full name (LOCALE_SDAYNAME)
- M month
- MM month with leading zero for single-digit months
- MMM month: three-letter abbreviation (LOCALE_SABBREVMONTHNAME)
- MMMM month: full name (LOCALE_SMONTHNAME)
- y year as last two digits
- yy year as last two digits with leading zero for years less than 10
- yyyy year represented by full four digits
- gg period/era string</PRE>
- <P>For example:</P>
- <PRE>
- my $v = Variant(VT_DATE, "April 1 99");
- print $v->Date(DATE_LONGDATE), "\n";
- print $v->Date("ddd',' MMM dd yy"), "\n";</PRE>
- <P>will print:</P>
- <PRE>
- Thursday, April 01, 1999
- Thu, Apr 01 99</PRE>
- <P></P>
- <DT><STRONG><A NAME="item_Dim"><CODE>Dim()</CODE></A></STRONG><BR>
- <DD>
- Returns a list of array bounds for a VT_ARRAY variant. The list contains
- an array reference for each dimension of the variant's SAFEARRAY. This
- reference points to an array containing the lower and upper bounds for
- this dimension. For example:
- <PRE>
- my @Dim = $Var->Dim;</PRE>
- <P>Now <CODE>@Dim</CODE> contains the following list: <CODE>([1,5], [0,2])</CODE>.</P>
- <P></P>
- <DT><STRONG><A NAME="item_Get"><CODE>Get(DIM)</CODE></A></STRONG><BR>
- <DD>
- For normal variants <A HREF="#item_Get"><CODE>Get</CODE></A> returns the value of the variant, just like the
- <A HREF="#item_Value"><CODE>Value</CODE></A> method. For VT_ARRAY variants <A HREF="#item_Get"><CODE>Get</CODE></A> retrieves the value of a single
- array element. In this case <CODE>DIM</CODE> must be a list of array indices. E.g.
- <PRE>
- my $Val = $Var->Get(2,0);</PRE>
- <P>As a special case for one dimensional VT_UI1|VT_ARRAY variants the <A HREF="#item_Get"><CODE>Get</CODE></A>
- method without arguments returns the character array as a Perl string.</P>
- <PRE>
- print $String->Get, "\n";</PRE>
- <P></P>
- <DT><STRONG><A NAME="item_LastError"><CODE>LastError()</CODE></A></STRONG><BR>
- <DD>
- The use of the <CODE>Win32::OLE::Variant-</CODE>LastError()> method is deprecated.
- Please use the <CODE>Win32::OLE-</CODE>LastError()> class method instead.
- <P></P>
- <DT><STRONG><A NAME="item_Number">Number([FORMAT[, LCID]])</A></STRONG><BR>
- <DD>
- This method converts the VARIANT value into a formatted number string. The
- FORMAT can be either an integer constant or a hash reference. Valid constants
- are 0 and LOCALE_NOUSEROVERRIDE. You get the value of LOCALE_NOUSEROVERRIDE
- from the Win32::OLE::NLS module:
- <PRE>
- use Win32::OLE::NLS qw(:LOCALE);</PRE>
- <P>LOCALE_NOUSEROVERRIDE tells the method to use the system default number
- format for the specified locale, disregarding any changes that might have
- been made through the control panel application.</P>
- <P>The hash reference could contain the following keys:</P>
- <PRE>
- NumDigits number of fractional digits
- LeadingZero whether to use leading zeroes in decimal fields
- Grouping size of each group of digits to the left of the decimal
- DecimalSep decimal separator string
- ThousandSep thousand separator string
- NegativeOrder see L<Win32::OLE::NLS/LOCALE_INEGNUMBER></PRE>
- <P></P>
- <DT><STRONG><A NAME="item_Put">Put(DIM, VALUE)</A></STRONG><BR>
- <DD>
- The <A HREF="#item_Put"><CODE>Put</CODE></A> method is used to assign a new value to a variant. The value will
- be coerced into the current type of the variant. E.g.:
- <PRE>
- my $Var = Variant(VT_I4, 42);
- $Var->Put(3.1415);</PRE>
- <P>This changes the value of the variant to <CODE>3</CODE> because the type is VT_I4.</P>
- <P>For VT_ARRAY type variants the indices for each dimension of the contained
- SAFEARRAY must be specified in front of the new value:</P>
- <PRE>
- $Array->Put(1, 1, 2.7);</PRE>
- <P>It is also possible to assign values to *every* element of the SAFEARRAY at
- once using a single <A HREF="#item_Put"><CODE>Put()</CODE></A> method call:</P>
- <PRE>
- $Array->Put([[1,2], [3,4]]);</PRE>
- <P>In this case the argument to <A HREF="#item_Put"><CODE>Put()</CODE></A> must be an array reference and the
- dimensions of the Perl list-of-lists must match the dimensions of the
- SAFEARRAY exactly.</P>
- <P>The are a few special cases for one-dimensional VT_UI1 arrays: The VALUE
- can be specified as a string instead of a number. This will set the selected
- character to the first character of the string or to '\0' if the string was
- empty:</P>
- <PRE>
- my $String = Variant(VT_UI1|VT_ARRAY, "ABCDE");
- $String->Put(1, "123");
- $String->Put(3, ord('Z'));
- $String->Put(4, '');</PRE>
- <P>This will set the value of <CODE>$String</CODE> to <CODE>"A1CZ\0"</CODE>. If the index is omitted
- then the string is copied to the value completely. The string is truncated
- if it is longer than the size of the VT_UI1 array. The result will be padded
- with '\0's if the string is shorter:</P>
- <PRE>
- $String->Put("String");</PRE>
- <P>Now <CODE>$String</CODE> contains the value ``Strin''.</P>
- <P><A HREF="#item_Put"><CODE>Put</CODE></A> returns the Variant object itself so that multiple <A HREF="#item_Put"><CODE>Put</CODE></A> calls can be
- chained together:</P>
- <PRE>
- $Array->Put(0,0,$First_value)->Put(0,1,$Another_value);</PRE>
- <P></P>
- <DT><STRONG><A NAME="item_Time">Time([FORMAT[, LCID]])</A></STRONG><BR>
- <DD>
- Converts the VARIANT into a formatted time string. FORMAT can be either
- one of the following integer constants or a format string:
- <PRE>
- LOCALE_NOUSEROVERRIDE system default time format for this locale
- TIME_NOMINUTESORSECONDS don't use minutes or seconds
- TIME_NOSECONDS don't use seconds
- TIME_NOTIMEMARKER don't use a time marker
- TIME_FORCE24HOURFORMAT always use a 24-hour time format</PRE>
- <P>The constants are available from the Win32::OLE::NLS module:</P>
- <PRE>
- use Win32::OLE::NLS qw(:LOCALE :TIME);</PRE>
- <P>The following elements can be used to construct a time format string.
- Characters must be specified exactly as given below (e.g. ``dd'' <STRONG>not</STRONG> ``DD'').
- Spaces can be inserted anywhere between formating codes, other verbatim
- text should be included in single quotes.</P>
- <PRE>
- h hours; 12-hour clock
- hh hours with leading zero for single-digit hours; 12-hour clock
- H hours; 24-hour clock
- HH hours with leading zero for single-digit hours; 24-hour clock
- m minutes
- mm minutes with leading zero for single-digit minutes
- s seconds
- ss seconds with leading zero for single-digit seconds
- t one character time marker string, such as A or P
- tt multicharacter time marker string, such as AM or PM</PRE>
- <P>For example:</P>
- <PRE>
- my $v = Variant(VT_DATE, "April 1 99 2:23 pm");
- print $v->Time, "\n";
- print $v->Time(TIME_FORCE24HOURFORMAT|TIME_NOTIMEMARKER), "\n";
- print $v->Time("hh.mm.ss tt"), "\n";</PRE>
- <P>will print:</P>
- <PRE>
- 2:23:00 PM
- 14:23:00
- 02.23.00 PM</PRE>
- <P></P>
- <DT><STRONG><A NAME="item_Type"><CODE>Type()</CODE></A></STRONG><BR>
- <DD>
- The <A HREF="#item_Type"><CODE>Type</CODE></A> method returns the variant type of the contained VARIANT.
- <P></P>
- <DT><STRONG><A NAME="item_Unicode"><CODE>Unicode()</CODE></A></STRONG><BR>
- <DD>
- The <A HREF="#item_Unicode"><CODE>Unicode</CODE></A> method returns a <CODE>Unicode::String</CODE> object. This contains
- the BSTR value of the variant in network byte order. If the variant is
- not currently in VT_BSTR format then a VT_BSTR copy will be produced first.
- <P></P>
- <DT><STRONG><A NAME="item_Value"><CODE>Value()</CODE></A></STRONG><BR>
- <DD>
- The <A HREF="#item_Value"><CODE>Value</CODE></A> method returns the value of the VARIANT as a Perl value. The
- conversion is performed in the same manner as all return values of
- Win32::OLE method calls are converted.
- <P></P></DL>
- <P>
- <H2><A NAME="overloading">Overloading</A></H2>
- <P>The Win32::OLE::Variant package has overloaded the conversion to
- string and number formats. Therefore variant objects can be used in
- arithmetic and string operations without applying the <A HREF="#item_Value"><CODE>Value</CODE></A>
- method first.</P>
- <P>
- <H2><A NAME="class variables">Class Variables</A></H2>
- <P>The Win32::OLE::Variant class used to have its own set of class variables
- like <CODE>$CP</CODE>, <CODE>$LCID</CODE> and <CODE>$Warn</CODE>. In version 0.1003 and later of the
- Win32::OLE module these variables have been eleminated. Now the settings
- of Win32::OLE are used by the Win32::OLE::Variant module too. Please read
- the documentation of the <CODE>Win32::OLE->Option</CODE> class method.</P>
- <P>
- <H2><A NAME="constants">Constants</A></H2>
- <P>These constants are exported by default:</P>
- <PRE>
- VT_EMPTY
- VT_NULL
- VT_I2
- VT_I4
- VT_R4
- VT_R8
- VT_CY
- VT_DATE
- VT_BSTR
- VT_DISPATCH
- VT_ERROR
- VT_BOOL
- VT_VARIANT
- VT_UNKNOWN
- VT_DECIMAL
- VT_UI1</PRE>
- <PRE>
- VT_ARRAY
- VT_BYREF</PRE>
- <P>VT_DECIMAL is not on the official list of allowable OLE Automation
- datatypes. But even Microsoft ADO seems to sometimes return values
- of Recordset fields in VT_DECIMAL format.</P>
- <P>
- <H2><A NAME="variants">Variants</A></H2>
- <P>A Variant is a data type that is used to pass data between OLE
- connections.</P>
- <P>The default behavior is to convert each perl scalar variable into
- an OLE Variant according to the internal perl representation.
- The following type correspondence holds:</P>
- <PRE>
- C type Perl type OLE type
- ------ --------- --------
- int IV VT_I4
- double NV VT_R8
- char * PV VT_BSTR
- void * ref to AV VT_ARRAY
- ? undef VT_ERROR
- ? Win32::OLE object VT_DISPATCH</PRE>
- <P>Note that VT_BSTR is a wide character or Unicode string. This presents a
- problem if you want to pass in binary data as a parameter as 0x00 is
- inserted between all the bytes in your data. The <A HREF="#item_Variant"><CODE>Variant()</CODE></A> method
- provides a solution to this. With Variants the script writer can specify
- the OLE variant type that the parameter should be converted to. Currently
- supported types are:</P>
- <PRE>
- VT_UI1 unsigned char
- VT_I2 signed int (2 bytes)
- VT_I4 signed int (4 bytes)
- VT_R4 float (4 bytes)
- VT_R8 float (8 bytes)
- VT_DATE OLE Date
- VT_BSTR OLE String
- VT_CY OLE Currency
- VT_BOOL OLE Boolean</PRE>
- <P>When VT_DATE and VT_CY objects are created, the input parameter is treated
- as a Perl string type, which is then converted to VT_BSTR, and finally to
- VT_DATE of VT_CY using the <CODE>VariantChangeType()</CODE> OLE API function.
- See <A HREF="../../../../site/lib/Win32/OLE.html#examples">EXAMPLES in the Win32::OLE manpage</A> for how these types can be used.</P>
- <P>
- <H2><A NAME="variant arrays">Variant arrays</A></H2>
- <P>A variant can not only contain a single value but also a multi-dimensional
- array of values (called a SAFEARRAY). In this case the VT_ARRAY flag must
- be added to the base variant type, e.g. <CODE>VT_I4 | VT_ARRAY</CODE> for an array of
- integers. The VT_EMPTY and VT_NULL types are invalid for SAFEARRAYs. It
- is possible to create an array of variants: <CODE>VT_VARIANT | VT_ARRAY</CODE>. In this
- case each element of the array can have a different type (including VT_EMPTY
- and VT_NULL). The elements of a VT_VARIANT SAFEARRAY cannot have either of the
- VT_ARRAY or VT_BYREF flags set.</P>
- <P>The lower and upper bounds for each dimension can be specified separately.
- They do not have to have all the same lower bound (unlike Perl's arrays).</P>
- <P>
- <H2><A NAME="variants by reference">Variants by reference</A></H2>
- <P>Some OLE servers expect parameters passed by reference so that they
- can be changed in the method call. This allows methods to easily
- return multiple values. There is preliminary support for this in
- the Win32::OLE::Variant module:</P>
- <PRE>
- my $x = Variant(VT_I4|VT_BYREF, 0);
- my $y = Variant(VT_I4|VT_BYREF, 0);
- $Corel->GetSize($x, $y);
- print "Size is $x by $y\n";</PRE>
- <P>After the <CODE>GetSize</CODE> method call <CODE>$x</CODE> and <CODE>$y</CODE> will be set to
- the respective sizes. They will still be variants. In the print
- statement the overloading converts them to string representation
- automatically.</P>
- <P>VT_BYREF is now supported for all variant types (including SAFEARRAYs).
- It can also be used to pass an OLE object by reference:</P>
- <PRE>
- my $Results = $App->CreateResultsObject;
- $Object->Method(Variant(VT_DISPATCH|VT_BYREF, $Results));</PRE>
- <P>
- <HR>
- <H1><A NAME="authors/copyright">AUTHORS/COPYRIGHT</A></H1>
- <P>This module is part of the Win32::OLE distribution.</P>
- <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
- <TR><TD CLASS=block VALIGN=MIDDLE WIDTH=100% BGCOLOR="#cccccc">
- <STRONG><P CLASS=block> Win32::OLE::Variant - Create and modify OLE VARIANT variables</P></STRONG>
- </TD></TR>
- </TABLE>
-
- </BODY>
-
- </HTML>
-