Skip to content

Conversation

geppi
Copy link
Collaborator

@geppi geppi commented Apr 22, 2025

This PR does add a minimal documentation for the COM Record support including the features introduced with PR #2437.

Maybe I missed it but when skimming through the pywin32 documentation I was surprised to find zero documentation for the COM Record support. Even the factory function win32com.client.Record seems to be mentioned nowhere. Or am I just too blind to see it?

Therefore I was not sure where to put this documentation and finally decided to include it in the HTML documentation under the win32com folder, although HTML seems not to be the best format when looking for documentation online on github.

It seems to me that offering the documentation formatted with Markup would be a better fit, so I put it here as well.
I'm not sure where this should go in the tree.

COM Record support in pywin32

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.

Late-bound objects

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.

Early-bound objects

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.

Defining subclasses of pythoncom.com_record

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

<P><A HREF="package.html">A brief description of the win32com package structure</A></P>
<P><A HREF="PythonCOM.html">Python COM Implementation documentation</A></P>
<P><A HREF="misc.html">Misc stuff I dont know where to put anywhere else</A></P>
<P><A HREF="misc.html">Misc stuff I dont know where to put anywhere else</A></P>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, encoding issue

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Damn, this encoding stuff is haunting us.
I didn't pay attention that the HTML has charset=windows-1252 but VS Code had opened the file as UTF-8 encoded.
Interestingly Notepad++ opens it right away as Windows-1252 encoded and if you select to reopen the file with a different encoding also VS Code proposes Windows-1252 'guessed from the content'. Hmm, is there probably a setting in VS Code to open it right away with what it would guess?

However, I would propose a different fix, i.e. change:
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
to
<META HTTP-EQUIV="Content-Type" CONTENT="text/html" charset="utf-8">
in addition to

Suggested change
<P><A HREF="misc.html">Misc stuff I dont know where to put anywhere else</A></P>
<P><A HREF="misc.html">Misc stuff I don't know where to put anywhere else</A></P>

What do you think?

Copy link
Collaborator

@Avasam Avasam Apr 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To quote @mhammond:
#2496 (comment)

I'd be fine with making everyting utf-8 except there the encoding really does specifically matter.

So yeah, if these can be UTF-8 (depends if help files work in utf-8), let's just remove the charset specification where we can (the entire <meta[http-equiv]> tag can probably go). That's imilar to #2496 but I didn't cover HTML files.

I also personally don't mind changing the apostrophe to a simpler single quote. Given how prevalent it is in code comments.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, so I've also changed the encoding in the other HTML files and replaced the apostrophe with a single quote and the special ellipsis character with three consecutive dots where necessary. I did not use the unicode character U+2026 for the ellipsis because I didn't see any advantage in using a multibyte character here. At the end of the day these HTML pages will not win a web design contest.

Copy link
Owner

@mhammond mhammond left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks - it's a shame there's no better option than adding html, but it is what it is!

@mhammond mhammond merged commit f8f9441 into mhammond:main Apr 27, 2025
30 checks passed
@geppi geppi deleted the record_doc branch April 28, 2025 11:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants