Skip to content

Commit

Permalink
Improve documents. (#729)
Browse files Browse the repository at this point in the history
  • Loading branch information
junkmd authored Dec 28, 2024
1 parent 2b24220 commit 494cd77
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 28 deletions.
56 changes: 44 additions & 12 deletions docs/source/com_interfaces.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,14 @@ into another location and customize the classes with hand written
methods (this is how much of the interfaces in the |comtypes| package
have been created).

The COM interfaces in |comtypes| are abstract classes, they should
never be instantiated.
The COM interfaces in |comtypes| should never be instantiated. To
use the methods of a COM object, it is necessary to call them from
the pointer instance to that interface.

.. note::

The functions for creating and accessing an interface pointer is
described in the :doc:`client` document.


Defining COM interfaces
Expand Down Expand Up @@ -68,6 +74,26 @@ The ``IUnknown`` as a Python class
of ``-2147467262`` (``E_NOINTERFACE``, ``'0x80004002'`` in
signed-32bit hex)

.. doctest::

>>> from comtypes.client import CreateObject, GetModule
>>> from comtypes import IUnknown
>>> from comtypes.automation import IDispatch
>>> GetModule('scrrun.dll') # doctest: +ELLIPSIS
<module 'comtypes.gen.Scripting' from ...>
>>> from comtypes.gen import Scripting
>>> dic = CreateObject(Scripting.Dictionary)
>>> dic # doctest: +ELLIPSIS
<POINTER(IDictionary) ptr=... at ...>
>>> dic.QueryInterface(IDispatch) # doctest: +ELLIPSIS
<POINTER(IDispatch) ptr=... at ...>
>>> dic.QueryInterface(IUnknown) # doctest: +ELLIPSIS
<POINTER(IUnknown) ptr=... at ...>
>>> dic.QueryInterface(Scripting.IFileSystem) # doctest: +ELLIPSIS
Traceback (most recent call last):
...
_ctypes.COMError: (-2147467262, ..., (None, None, None, 0, None))

.. py:method:: Add()
This wraps the `IUnknown::AddRef <https://learn.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-addref>`_.
Expand All @@ -81,19 +107,20 @@ The ``IUnknown`` as a Python class
object and returns the new reference count.

In other COM technologies, it is necessary to explicitly
release COM pointers that have been created or copied by
calling ``Release``. However, in |comtypes|, explicit release
is not required because ``Release`` is automatically invoked
via ``atexit`` hooks or metaclasses when the Python
interpreter exits or when the Python instance is about to be
destroyed.
release COM pointers by calling ``Release``. However, in
|comtypes|, that is not required because ``Release`` is
automatically invoked via ``atexit`` hooks or metaclasses
when the Python interpreter exits or when the Python instance
is about to be destroyed.

In fact, explicitly releasing the pointer can cause issues;
if ``Release`` is called at the aforementioned timing, it may
raise an ``OSError``.
raise an ``OSError`` and be ignored in ``__del__``.

.. sourcecode:: pycon
.. doctest::

>>> import contextlib
>>> import io
>>> from comtypes.client import CreateObject, GetModule
>>> GetModule('UIAutomationCore.dll') # doctest: +ELLIPSIS
<module 'comtypes.gen.UIAutomationClient' from ...>
Expand All @@ -103,7 +130,11 @@ The ``IUnknown`` as a Python class
<POINTER(IUIAutomation) ptr=... at ...>
>>> iuia.Release()
0
>>> del iuia # doctest: +ELLIPSIS
>>> stderr = io.StringIO()
>>> with contextlib.redirect_stderr(stderr):
... del iuia
...
>>> print(stderr.getvalue()[:-1]) # doctest: +ELLIPSIS
Exception ignored in: <function _compointer_base.__del__ at ...>
Traceback (most recent call last):
...
Expand Down Expand Up @@ -397,7 +428,8 @@ Case sensitivity
In principle, COM is a case insensitive technology (probably because
of Visual Basic). Type libraries generated from IDL files, however,
do *not* always even preserve the case of identifiers; see for example
http://support.microsoft.com/kb/220137.
http://support.microsoft.com/kb/220137 (This page is broken, see web
archive `here <https://web.archive.org/web/20100722053900/ttp://support.microsoft.com/kb/220137>`_).

Python (and C/C++) are case sensitive languages, so |comtypes| is
also case sensitive. This means that you have to call
Expand Down
2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Functionalities
Links
*****

Kourovtsev, Yaroslav (2008). `"Working with Custom COM Interfaces from Python" <http://www.codeproject.com/KB/COM/python-comtypes-interop.aspx>`_
Kourovtsev, Yaroslav (2008). `"Working with Custom COM Interfaces from Python" <https://www.codeproject.com/KB/COM/python-comtypes-interop.aspx>`_

This article describes how to use |comtypes| to access a custom
COM object.
Expand Down
41 changes: 26 additions & 15 deletions docs/source/server.rst
Original file line number Diff line number Diff line change
Expand Up @@ -101,25 +101,36 @@ are not in the type library.

The meaning of the attributes:

``_reg_threading_`` must be set to "Both", "Free", or "Apartment".
It specifies the apartment model in which the server runs.
.. py:attribute:: _reg_threading_
``_reg_progid_`` and ``_reg_novers_progid`` are optional short
names that can later be used to specify your object, instead of
the CLSID in type library. Typically the type library name plus
the coclass name plus a version number are combined to form the
progid, and the type library name plus the coclass name are
combined to form the version independend progid.
Must be set to "Both", "Free", or "Apartment".
It specifies the apartment model in which the server runs.

``_reg_desc_`` is the (optional) name of the coclass.
.. py:attribute:: _reg_progid_
.. py:attribute:: _reg_novers_progid_
The ``_reg_clsctx_`` constant specifies in which contexts the com
server can operate.
(optional) The short names that can later be used to specify
your object, instead of the CLSID in type library. Typically
the type library name plus the coclass name plus a version
number are combined to form the progid, and the type library
name plus the coclass name are combined to form the version
independend progid.

The optional ``_regcls_`` constant is only used for com objects
that run in their own process, see the MSDN docs for more info.
In |comtypes|, several REGCLS values are defined in the
``comtyper.server.localserver`` module.
.. py:attribute:: _reg_desc_
(optional) The name of the coclass.

.. py:attribute:: _reg_clsctx_
The constant specifies in which contexts the COM server can
operate.

.. py:attribute:: _regcls_
(optional) The constant is only used for com objects that
run in their own process, see the MSDN docs for more info.
In |comtypes|, several REGCLS values are defined in the
``comtyper.server.localserver`` module.

You do not yet implement any methods on the class, because basic
functionality is already present.
Expand Down

0 comments on commit 494cd77

Please sign in to comment.