summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlperl/lib/Win32/OLE/Variant.pm
diff options
context:
space:
mode:
Diffstat (limited to 'Master/tlpkg/tlperl/lib/Win32/OLE/Variant.pm')
-rw-r--r--Master/tlpkg/tlperl/lib/Win32/OLE/Variant.pm577
1 files changed, 577 insertions, 0 deletions
diff --git a/Master/tlpkg/tlperl/lib/Win32/OLE/Variant.pm b/Master/tlpkg/tlperl/lib/Win32/OLE/Variant.pm
new file mode 100644
index 00000000000..49e363da334
--- /dev/null
+++ b/Master/tlpkg/tlperl/lib/Win32/OLE/Variant.pm
@@ -0,0 +1,577 @@
+# The documentation is at the __END__
+
+package Win32::OLE::Variant;
+require Win32::OLE; # Make sure the XS bootstrap has been called
+
+use strict;
+use vars qw(@ISA @EXPORT @EXPORT_OK);
+
+use Exporter;
+@ISA = qw(Exporter);
+
+@EXPORT = qw(
+ Variant
+ 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
+ VT_ARRAY VT_BYREF
+ );
+
+@EXPORT_OK = qw(CP_ACP CP_OEMCP nothing nullstring);
+
+# Automation data types.
+sub VT_EMPTY {0;}
+sub VT_NULL {1;}
+sub VT_I2 {2;}
+sub VT_I4 {3;}
+sub VT_R4 {4;}
+sub VT_R8 {5;}
+sub VT_CY {6;}
+sub VT_DATE {7;}
+sub VT_BSTR {8;}
+sub VT_DISPATCH {9;}
+sub VT_ERROR {10;}
+sub VT_BOOL {11;}
+sub VT_VARIANT {12;}
+sub VT_UNKNOWN {13;}
+sub VT_DECIMAL {14;} # Officially not allowed in VARIANTARGs
+sub VT_UI1 {17;}
+
+sub VT_ARRAY {0x2000;}
+sub VT_BYREF {0x4000;}
+
+
+# For backward compatibility
+sub CP_ACP {0;} # ANSI codepage
+sub CP_OEMCP {1;} # OEM codepage
+
+use overload
+ # '+' => 'Add', '-' => 'Sub', '*' => 'Mul', '/' => 'Div',
+ '""' => sub {$_[0]->As(VT_BSTR)},
+ '0+' => sub {$_[0]->As(VT_R8)},
+ fallback => 1;
+
+sub Variant {
+ return Win32::OLE::Variant->new(@_);
+}
+
+sub nothing {
+ return Win32::OLE::Variant->new(VT_DISPATCH);
+}
+
+sub nullstring {
+ return Win32::OLE::Variant->new(VT_BSTR);
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Win32::OLE::Variant - Create and modify OLE VARIANT variables
+
+=head1 SYNOPSIS
+
+ use Win32::OLE::Variant;
+ my $var = Variant(VT_DATE, 'Jan 1,1970');
+ $OleObject->{value} = $var;
+ $OleObject->Method($var);
+
+
+=head1 DESCRIPTION
+
+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.
+
+=head2 Functions
+
+=over 8
+
+=item nothing()
+
+The nothing() function returns an empty VT_DISPATCH variant. It can be
+used to clear an object reference stored in a property
+
+ use Win32::OLE::Variant qw(:DEFAULT nothing);
+ # ...
+ $object->{Property} = nothing;
+
+This has the same effect as the Visual Basic statement
+
+ Set object.Property = Nothing
+
+The nothing() function is B<not> exported by default.
+
+=item nullstring()
+
+The nullstring() function returns a VT_BSTR variant with a NULL string
+pointer. This is B<not> the same as a VT_BSTR variant with an empty
+string "". The nullstring() value is the same as the vbNullString
+constant in Visual Basic.
+
+The nullstring() function is B<not> exported by default.
+
+=item Variant(TYPE, DATA)
+
+This is just a function alias of the C<Win32::OLE::Variant->new()>
+method (see below). This function is exported by default.
+
+=back
+
+=head2 Methods
+
+=over 8
+
+=item new(TYPE, DATA)
+
+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 L<Variants> below for details.
+
+For VT_EMPTY and VT_NULL variants, the DATA argument may be omitted.
+For all non-VT_ARRAY variants DATA specifies the initial value.
+
+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:
+
+ my $Array = Win32::OLE::Variant->new(VT_ARRAY|VT_R8, [1,2], 2);
+
+This creates a 2-dimensional SAFEARRAY of doubles with 4 elements:
+(1,0), (1,1), (2,0) and (2,1).
+
+A special case is the the creation of one-dimensional VT_UI1 arrays with
+a string DATA argument:
+
+ my $String = Variant(VT_ARRAY|VT_UI1, "String");
+
+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:
+
+ my $String = Variant(VT_UI1, "String");
+
+If you really need a single character VT_UI1 variant, you have to create
+it using a numeric intializer:
+
+ my $Char = Variant(VT_UI1, ord('A'));
+
+=item As(TYPE)
+
+C<As> 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 C<$variant->As(VT_R8)> will correctly return the floating
+point value.
+
+The underlying variant object is NOT changed by this method.
+
+=item ChangeType(TYPE)
+
+This method changes the type of the contained VARIANT in place. It
+returns the object itself, not the converted value.
+
+=item Copy([DIM])
+
+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.
+
+ my $Var = Variant(VT_I4|VT_ARRAY|VT_BYREF, [1,5], 3);
+ my $Copy = $Var->Copy;
+
+The type of C<$Copy> is now VT_I4|VT_ARRAY and the value is a copy of
+the other SAFEARRAY. Changes to elements of C<$Var> will not be reflected
+in C<$Copy> and vice versa.
+
+The C<Copy> 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:
+
+ my $Int = $Var->Copy(1, 2);
+
+C<$Int> is now a VT_I4 Variant object containing the value of element (1,2).
+
+=item Currency([FORMAT[, LCID]])
+
+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:
+
+ use Win32::OLE::NLS qw(:LOCALE);
+
+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.
+
+The hash reference could contain the following keys:
+
+ 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
+
+For example:
+
+ 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";
+
+will print:
+
+ -922.337.203.685.477,58 Tuits
+
+=item Date([FORMAT[, LCID]])
+
+Converts the VARIANT into a formatted date string. FORMAT can be either
+one of the following integer constants or a format string:
+
+ 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
+
+The constants are available from the Win32::OLE::NLS module:
+
+ use Win32::OLE::NLS qw(:LOCALE :DATE);
+
+The following elements can be used to construct a date format string.
+Characters must be specified exactly as given below (e.g. "dd" B<not> "DD").
+Spaces can be inserted anywhere between formating codes, other verbatim
+text should be included in single quotes.
+
+ 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
+
+For example:
+
+ my $v = Variant(VT_DATE, "April 1 99");
+ print $v->Date(DATE_LONGDATE), "\n";
+ print $v->Date("ddd',' MMM dd yy"), "\n";
+
+will print:
+
+ Thursday, April 01, 1999
+ Thu, Apr 01 99
+
+=item Dim()
+
+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:
+
+ my @Dim = $Var->Dim;
+
+Now C<@Dim> contains the following list: C<([1,5], [0,2])>.
+
+=item Get(DIM)
+
+For normal variants C<Get> returns the value of the variant, just like the
+C<Value> method. For VT_ARRAY variants C<Get> retrieves the value of a single
+array element. In this case C<DIM> must be a list of array indices. E.g.
+
+ my $Val = $Var->Get(2,0);
+
+As a special case for one dimensional VT_UI1|VT_ARRAY variants the C<Get>
+method without arguments returns the character array as a Perl string.
+
+ print $String->Get, "\n";
+
+=item IsNothing()
+
+Tests if the object is an empty VT_DISPATCH variant. See also nothing().
+
+=item IsNullString()
+
+Tests if the object is an empty VT_BSTR variant. See also nullstring().
+
+=item LastError()
+
+The use of the C<Win32::OLE::Variant->LastError()> method is deprecated.
+Please use the C<Win32::OLE->LastError()> class method instead.
+
+=item Number([FORMAT[, LCID]])
+
+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:
+
+ use Win32::OLE::NLS qw(:LOCALE);
+
+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.
+
+The hash reference could contain the following keys:
+
+ 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>
+
+=item Put(DIM, VALUE)
+
+The C<Put> 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.:
+
+ my $Var = Variant(VT_I4, 42);
+ $Var->Put(3.1415);
+
+This changes the value of the variant to C<3> because the type is VT_I4.
+
+For VT_ARRAY type variants the indices for each dimension of the contained
+SAFEARRAY must be specified in front of the new value:
+
+ $Array->Put(1, 1, 2.7);
+
+It is also possible to assign values to *every* element of the SAFEARRAY at
+once using a single Put() method call:
+
+ $Array->Put([[1,2], [3,4]]);
+
+In this case the argument to Put() must be an array reference and the
+dimensions of the Perl list-of-lists must match the dimensions of the
+SAFEARRAY exactly.
+
+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:
+
+ my $String = Variant(VT_UI1|VT_ARRAY, "ABCDE");
+ $String->Put(1, "123");
+ $String->Put(3, ord('Z'));
+ $String->Put(4, '');
+
+This will set the value of C<$String> to C<"A1CZ\0">. 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:
+
+ $String->Put("String");
+
+Now C<$String> contains the value "Strin".
+
+C<Put> returns the Variant object itself so that multiple C<Put> calls can be
+chained together:
+
+ $Array->Put(0,0,$First_value)->Put(0,1,$Another_value);
+
+=item Time([FORMAT[, LCID]])
+
+Converts the VARIANT into a formatted time string. FORMAT can be either
+one of the following integer constants or a format string:
+
+ 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
+
+The constants are available from the Win32::OLE::NLS module:
+
+ use Win32::OLE::NLS qw(:LOCALE :TIME);
+
+The following elements can be used to construct a time format string.
+Characters must be specified exactly as given below (e.g. "dd" B<not> "DD").
+Spaces can be inserted anywhere between formating codes, other verbatim
+text should be included in single quotes.
+
+ 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
+
+For example:
+
+ 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";
+
+will print:
+
+ 2:23:00 PM
+ 14:23:00
+ 02.23.00 PM
+
+=item Type()
+
+The C<Type> method returns the variant type of the contained VARIANT.
+
+=item Unicode()
+
+The C<Unicode> method returns a C<Unicode::String> 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.
+
+=item Value()
+
+The C<Value> 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.
+
+=back
+
+=head2 Overloading
+
+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 C<Value>
+method first.
+
+=head2 Class Variables
+
+The Win32::OLE::Variant class used to have its own set of class variables
+like C<$CP>, C<$LCID> and C<$Warn>. 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 C<Win32::OLE-&gt;Option> class method.
+
+
+=head2 Constants
+
+These constants are exported by default:
+
+ 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
+
+ VT_ARRAY
+ VT_BYREF
+
+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.
+
+=head2 Variants
+
+A Variant is a data type that is used to pass data between OLE
+connections.
+
+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:
+
+ 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
+
+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 C<Variant()> 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:
+
+ 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
+
+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 C<VariantChangeType()> OLE API function.
+See L<Win32::OLE/EXAMPLES> for how these types can be used.
+
+=head2 Variant arrays
+
+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. C<VT_I4 | VT_ARRAY> 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: C<VT_VARIANT | VT_ARRAY>. 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.
+
+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).
+
+=head2 Variants by reference
+
+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:
+
+ 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";
+
+After the C<GetSize> method call C<$x> and C<$y> will be set to
+the respective sizes. They will still be variants. In the print
+statement the overloading converts them to string representation
+automatically.
+
+VT_BYREF is now supported for all variant types (including SAFEARRAYs).
+It can also be used to pass an OLE object by reference:
+
+ my $Results = $App->CreateResultsObject;
+ $Object->Method(Variant(VT_DISPATCH|VT_BYREF, $Results));
+
+=head1 AUTHORS/COPYRIGHT
+
+This module is part of the Win32::OLE distribution.
+
+=cut