[python-win32] How to use COM when there isn't a type library or IDL file

Thomas Heller theller at ctypes.org
Fri Oct 9 20:43:55 CEST 2009


Mark Hammond schrieb:
> This is very tricky to do in pure-python.  Other interfaces with this 
> issue (eg, the shell interfaces) tend to use custom c++ code (often 
> generated by the 'makegw' package then heavily edited) to implement a 
> win32com 'sub-module'.  The best alternative for you may be to 
> investigate how comtypes might help...

comtypes: If neither a type library nor an idl file is available,
then you can still create the interface definition manually.
You can probably, given some experience, define the interface
by looking at the header file.  I started this for the first few
methods of the IRealTimeStylus interface:

"""
# module realtimestylus.py
from ctypes import *
from ctypes.wintypes import *
from comtypes import IUnknown
from comtypes import GUID
from comtypes import COMMETHOD

class IRealTimeStylus(IUnknown):
    _iid_ = GUID('{A8BB5D22-3144-4A7B-93CD-F34A16BE513A}')

IRealTimeStylus._methods_ = [
    COMMETHOD(['propget'], HRESULT, 'Enabled',
              ( ['retval', 'out'], POINTER(c_int), 'pfEnable' )),
    COMMETHOD(['propput'], HRESULT, 'Enabled',
              ( ['in'], c_int, 'pfEnable' )),

    COMMETHOD(['propget'], HRESULT, 'HWND',
              ( ['retval', 'out'], POINTER(c_int), 'phwnd' )),
    COMMETHOD(['propput'], HRESULT, 'HWND',
              ( ['in'], c_int, 'phwnd' )),

    COMMETHOD(['propget'], HRESULT, 'WindowInputRectangle',
              ( ['retval', 'out'], POINTER(RECT), 'prcWndInputRect' )),
    COMMETHOD(['propput'], HRESULT, 'WindowInputRectangle',
              ( ['in'], c_int, 'prcWndInputRect' )),

    # here are quite some methods missing...
]
"""

Then you can create such an object, QI for the interface, and try to use it.
I had to look up the CLSID for the RealTimeStylus class in the registry.

>>> p = CreateObject("{E26B366D-F998-43CE-836F-CB6D904432B0}")
>>> print p
<POINTER(IUnknown) ptr=0x12e0848 at 1bfa3a0>
>>> p.QueryInterface(IRealTimeStylus)
<POINTER(IRealTimeStylus) ptr=0x12e0848 at 189e120>
>>> s = p.QueryInterface(IRealTimeStylus)
>>> s.Enabled
0
>>> s.Enabled = 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "comtypes\__init__.py", line 278, in __setattr__
    value)
_ctypes.COMError: (-2144862203, 'The clear disable flag is set and all clear operations now require physical access.', (None, None, None, 0, None))
>>>


However, I would only recommend this approach to an experienced
COM developer.

Thomas



More information about the python-win32 mailing list