The pywin32 package provides COM Record support for late-bound and early-bound objects. In both cases it is required that the Type Library which defines the COM Record has been registered in Windows.
For late-bound objects, were makepy-support is not available, it is possible to create a particular COM Record if the following is known:
- GUID of the Type Library were the Record is defined
- Major version of the registered Type Library
- Minor version of the registered Type Library
- LCID of the registered Type Library
- GUID of the COM Record in this Type Library
An instance of the COM Record is created with pythoncom.GetRecordFromGuids
, e.g.:
import pythoncom
PyCOMTestLib_GUID = '{6bcdcb60-5605-11d0-ae5f-cadd4c000000}'
MAJVER = 1
MINVER = 1
LCID = 0
TestStruct1_GUID = '{7a4ce6a7-7959-4e85-a3c0-b41442ff0f67}'
record1 = pythoncom.GetRecordFromGuids(PyCOMTestLib_GUID, MAJVER, MINVER, LCID, TestStruct1_GUID)
The Python type of the returned COM Record instance is:
>>> type(record1)
<class 'com_record'>
which is a generic type that is returned for all COM Records, i.e. COM Records with different GUIDs nevertheless all have the same Python type pythoncom.com_record
.
Instances of <class 'com_record'>
can be used as method parameters and are returned by COM methods that return a COM Record. However, it is not possible to differentiate the COM Record Types, i.e. COM Records of different GUID at runtime.
The availability of makepy-support does in its basic form offer the convenience function win32com.client.Record
to create COM Record instances using the COM Record name from the Type Library and an interface object of the same Type Library:
import win32com.client
com_test = win32com.client.Dispatch("PyCOMTest.PyCOMTest")
record1 = win32com.client.Record('TestStruct1' ,com_test)
Still the Python type of the returned COM Record instance is:
>>> type(record1)
<class 'com_record'>
i.e. the generic base type of all COM Records.
It is possible to create subclasses of the base pythoncom.com_record
type and register such a subclass for a particular COM Record type. As a prerequisite, it is mandatory for the subclass to define the following class attributes:
- TLBID : The GUID of the containing TypeLibrary as a string
- MJVER : The major version number of the TypeLibrary as an integer
- MNVER : The minor version number of the TypeLibrary as an integer
- LCID : The LCID of the TypeLibrary as an integer
- GUID : The GUID of the COM Record as a string
with GUID strings in {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} notation, e.g.:
import pythoncom
class TestStruct1(pythoncom.com_record):
TLBID = '{6bcdcb60-5605-11d0-ae5f-cadd4c000000}'
MJVER = 1
MNVER = 1
LCID = 0
GUID = '{7a4ce6a7-7959-4e85-a3c0-b41442ff0f67}'
Before this subclass can be used to create TestStruct1 instances, it has to be registered with win32com.client.register_record_class
, e.g.:
from win32com.client import register_record_class
register_record_class(TestStruct1)
With such a class, registered for a particular COM Record type, it is possible to identify the COM Record type at runtime:
>>> record1 = TestStruct1()
>>> type(record1)
<class 'main.TestStruct1'>
Also COM methods that return a COM Record type for which a Python class was registered as described above, will return values of the proper Python class type, e.g.:
>>> # Given the following definition in the Type Library IDL-file:
>>> # HRESULT GetStruct([out, retval]TestStruct1 *ret);
>>> retval = GetStruct()
>>> type(retval)
<class 'main.TestStruct1'>
COM methods that return a COM Record type for which no Python class was registered will continue to return values of the generic type pythoncom.com_record
, e.g.:
>>> # Given the following definition in the Type Library IDL-file:
>>> # HRESULT GetOtherStruct([out, retval]AnotherStruct *ret);
>>> retval = GetOtherStruct()
>>> type(retval)
<class 'com_record'>