diff --git a/docs/source/com_interfaces.rst b/docs/source/com_interfaces.rst index af4907c9e..827610e0a 100644 --- a/docs/source/com_interfaces.rst +++ b/docs/source/com_interfaces.rst @@ -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 @@ -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 + + >>> from comtypes.gen import Scripting + >>> dic = CreateObject(Scripting.Dictionary) + >>> dic # doctest: +ELLIPSIS + + >>> dic.QueryInterface(IDispatch) # doctest: +ELLIPSIS + + >>> dic.QueryInterface(IUnknown) # doctest: +ELLIPSIS + + >>> 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 `_. @@ -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 @@ -103,7 +130,11 @@ The ``IUnknown`` as a Python class >>> 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: Traceback (most recent call last): ... @@ -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 `_). Python (and C/C++) are case sensitive languages, so |comtypes| is also case sensitive. This means that you have to call diff --git a/docs/source/index.rst b/docs/source/index.rst index 6a546b673..13362880a 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -34,7 +34,7 @@ Functionalities Links ***** -Kourovtsev, Yaroslav (2008). `"Working with Custom COM Interfaces from Python" `_ +Kourovtsev, Yaroslav (2008). `"Working with Custom COM Interfaces from Python" `_ This article describes how to use |comtypes| to access a custom COM object. diff --git a/docs/source/server.rst b/docs/source/server.rst index f732acb84..a4b89a7a6 100644 --- a/docs/source/server.rst +++ b/docs/source/server.rst @@ -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.