Uploaded Test files
This commit is contained in:
parent
f584ad9d97
commit
2e81cb7d99
16627 changed files with 2065359 additions and 102444 deletions
162
venv/Lib/site-packages/win32com/HTML/variant.html
Normal file
162
venv/Lib/site-packages/win32com/HTML/variant.html
Normal file
|
@ -0,0 +1,162 @@
|
|||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>win32com.client.VARIANT</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
|
||||
<H2>Introduction</H2>
|
||||
<p>
|
||||
win32com attempts to provide a seamless COM interface and hide many COM
|
||||
implementation details, including the use of COM VARIANT structures. This
|
||||
means that in most cases, you just call a COM object using normal Python
|
||||
objects as parameters and get back normal Python objects as results.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
However, in some cases this doesn't work very well, particularly when using
|
||||
"dynamic" (aka late-bound) objects, or when using "makepy" (aka early-bound)
|
||||
objects which only declare a parameter is a VARIANT.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The <code>win32com.client.VARIANT</code> object is designed to overcome these
|
||||
problems.
|
||||
</p>
|
||||
|
||||
<h2>Drawbacks</h2>
|
||||
The primary issue with this approach is that the programmer must learn more
|
||||
about COM VARIANTs than otherwise - they need to know concepts such as
|
||||
variants being <em>byref</em>, holding arrays, or that some may hold 32bit
|
||||
unsigned integers while others hold 64bit signed ints, and they need to
|
||||
understand this in the context of a single method call. In short, this is
|
||||
a relatively advanced feature. The good news though is that use of these
|
||||
objects should never cause your program to hard-crash - the worst you should
|
||||
expect are Python or COM exceptions being thrown.
|
||||
|
||||
<h2>The VARIANT object</h2>
|
||||
|
||||
The VARIANT object lives in <code>win32com.client</code>. The constructor
|
||||
takes 2 parameters - the 'variant type' and the value. The 'variant type' is
|
||||
an integer and can be one or more of the <code>pythoncom.VT_*</code> values,
|
||||
possibly or'd together.
|
||||
|
||||
<p>For example, to create a VARIANT object which defines a byref array of
|
||||
32bit integers, you could use:
|
||||
|
||||
<pre>
|
||||
>>> from win32com.client import VARIANT
|
||||
>>> import pythoncom
|
||||
>>> v = VARIANT(pythoncom.VT_BYREF | pythoncom.VT_ARRAY | pythoncom.VT_I4,
|
||||
... [1,2,3,4])
|
||||
>>> v
|
||||
win32com.client.VARIANT(24579, [1, 2, 3, 4])
|
||||
>>>
|
||||
</pre>
|
||||
|
||||
This variable can then be used whereever a COM VARIANT is expected.
|
||||
|
||||
<h2>Example usage with dynamic objects.</h2>
|
||||
|
||||
For this example we will use the COM object used for win32com testing,
|
||||
<code>PyCOMTest.PyCOMTest</code>. This object defines a method which is
|
||||
defined in IDL as:
|
||||
<pre>
|
||||
HRESULT DoubleInOutString([in,out] BSTR *str);
|
||||
</pre>
|
||||
|
||||
As you can see, it takes a single string parameter which is also used as
|
||||
an "out" parameter - the single parameter will be updated after the call.
|
||||
The implementation of the method simply "doubles" the string.
|
||||
|
||||
<p>If the object has a type-library, this method works fine with makepy
|
||||
generated support. For example:
|
||||
|
||||
<pre>
|
||||
>>> from win32com.client.gencache import EnsureDispatch
|
||||
>>> ob = EnsureDispatch("PyCOMTest.PyCOMTest")
|
||||
>>> ob.DoubleInOutString("Hello")
|
||||
u'HelloHello'
|
||||
>>>
|
||||
</pre>
|
||||
|
||||
However, if makepy support is not available the method does not work as
|
||||
expected. For the next example we will use <code>DumbDispatch</code> to
|
||||
simulate the object not having a type-library.
|
||||
|
||||
<pre>
|
||||
>>> import win32com.client.dynamic
|
||||
>>> ob = win32com.client.dynamic.DumbDispatch("PyCOMTest.PyCOMTest")
|
||||
>>> ob.DoubleInOutString("Hello")
|
||||
>>>
|
||||
</pre>
|
||||
|
||||
As you can see, no result came back from the function. This is because
|
||||
win32com has no type information available to use, so doesn't know the
|
||||
parameter should be passed as a <code>byref</code> parameter. To work
|
||||
around this, we can use the <code>VARIANT</code> object.
|
||||
|
||||
<p>The following example explicitly creates a VARIANT object with a
|
||||
variant type of a byref string and a value 'Hello'. After making the
|
||||
call with this VARIANT the value is updated.
|
||||
|
||||
<pre>
|
||||
>>> import win32com.client.dynamic
|
||||
>>> from win32com.client import VARIANT
|
||||
>>> import pythoncom
|
||||
>>> ob = win32com.client.dynamic.DumbDispatch("PyCOMTest.PyCOMTest")
|
||||
>>> variant = VARIANT(pythoncom.VT_BYREF | pythoncom.VT_BSTR, "Hello")
|
||||
>>> variant.value # check the value before the call.
|
||||
'Hello'
|
||||
>>> ob.DoubleInOutString(variant)
|
||||
>>> variant.value
|
||||
u'HelloHello'
|
||||
>>>
|
||||
</pre>
|
||||
|
||||
<h2>Usage with generated objects</h2>
|
||||
|
||||
In most cases, objects with makepy support (ie, 'generated' objects) don't
|
||||
need to use the VARIANT object - the type information means win32com can guess
|
||||
the right thing to pass. However, in some cases the VARIANT object can still
|
||||
be useful.
|
||||
|
||||
Imagine a poorly specified object with IDL like:
|
||||
|
||||
<pre>
|
||||
HRESULT DoSomething([in] VARIANT value);
|
||||
</pre>
|
||||
|
||||
But also imagine that the object has a limitation that if the parameter is an
|
||||
integer, it must be a 32bit unsigned value - any other integer representation
|
||||
will fail.
|
||||
|
||||
<p>If you just pass a regular Python integer to this function, it will
|
||||
generally be passed as a 32bit signed integer and given the limitation above,
|
||||
will fail. The VARIANT object allows you to work around the limitation - just
|
||||
create a variant object <code>VARIANT(pythoncom.VT_UI4, int_value)</code> and
|
||||
pass that - the function will then be called with the explicit type you
|
||||
specified and will succeed.
|
||||
|
||||
<p>Note that you can not use a VARIANT object to override the types described
|
||||
in a type library. If a makepy generated class specifies that a VT_UI2 is
|
||||
expected, attempting to pass a VARIANT object will fail. In this case you
|
||||
would need to hack around the problem. For example, imagine <code>ob</code>
|
||||
was a COM object which a method called <code>foo</code> and you wanted to
|
||||
override the type declaration for <code>foo</code> by passing a VARIANT.
|
||||
You could do something like:
|
||||
|
||||
<pre>
|
||||
>>> import win32com.client.dynamic
|
||||
>>> from win32com.client import VARIANT
|
||||
>>> import pythoncom
|
||||
>>> dumbob = win32com.client.dynamic.DumbDispatch(ob)
|
||||
>>> variant = VARIANT(pythoncom.VT_BYREF | pythoncom.VT_BSTR, "Hello")
|
||||
>>> dumbob.foo(variant)
|
||||
</pre>
|
||||
|
||||
The code above converts the makepy supported <code>ob</code> into a
|
||||
'dumb' (ie, non-makepy supported) version of the object, which will then
|
||||
allow you to use VARIANT objects for the problematic methods.
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
Loading…
Add table
Add a link
Reference in a new issue