comtypes 1.4.8__zip → 1.4.9__zip
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {comtypes-1.4.8 → comtypes-1.4.9}/CHANGES.txt +21 -0
- {comtypes-1.4.8/comtypes.egg-info → comtypes-1.4.9}/PKG-INFO +2 -2
- {comtypes-1.4.8 → comtypes-1.4.9}/README.md +1 -1
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/GUID.py +6 -5
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/__init__.py +16 -5
- comtypes-1.4.9/comtypes/_comobject.py +507 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_memberspec.py +80 -8
- comtypes-1.4.9/comtypes/_post_coinit/_cominterface_meta_patcher.py +153 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_post_coinit/misc.py +1 -1
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_post_coinit/unknwn.py +25 -171
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_safearray.py +1 -2
- comtypes-1.4.9/comtypes/_vtbl.py +448 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/automation.py +36 -45
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/_code_cache.py +4 -4
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/_constants.py +1 -1
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/_events.py +1 -1
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/_generate.py +4 -8
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/lazybind.py +2 -2
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/errorinfo.py +3 -3
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/git.py +1 -2
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/hints.pyi +7 -15
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/safearray.py +10 -0
- comtypes-1.4.9/comtypes/server/__init__.py +86 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/server/inprocserver.py +22 -17
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/server/localserver.py +28 -16
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/server/register.py +61 -73
- comtypes-1.4.9/comtypes/server/w_getopt.py +48 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/shelllink.py +3 -26
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/__init__.py +9 -11
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_BSTR.py +4 -7
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_avmc.py +1 -1
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_casesensitivity.py +3 -5
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_collections.py +3 -3
- comtypes-1.4.9/comtypes/test/test_comobject.py +146 -0
- comtypes-1.4.9/comtypes/test/test_comserver.py +319 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_createwrappers.py +2 -4
- comtypes-1.4.9/comtypes/test/test_dispinterface.py +153 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_excel.py +22 -12
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_ie.py +2 -5
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_inout_args.py +7 -4
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_midl_safearray_create.py +9 -1
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_outparam.py +17 -10
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_safearray.py +1 -90
- comtypes-1.4.9/comtypes/test/test_server.py +350 -0
- comtypes-1.4.9/comtypes/test/test_server_register.py +536 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_showevents.py +7 -17
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_variant.py +0 -17
- comtypes-1.4.9/comtypes/test/test_w_getopt.py +29 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_win32com_interop.py +80 -36
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_wmi.py +0 -3
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/codegenerator.py +62 -68
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/helpers.py +8 -8
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/packing.py +4 -4
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/typeannotator.py +7 -7
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/typedesc.py +1 -6
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/typeinfo.py +11 -22
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/viewobject.py +1 -5
- {comtypes-1.4.8 → comtypes-1.4.9/comtypes.egg-info}/PKG-INFO +2 -2
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes.egg-info/SOURCES.txt +6 -3
- {comtypes-1.4.8 → comtypes-1.4.9}/pyproject.toml +1 -0
- comtypes-1.4.8/comtypes/_comobject.py +0 -833
- comtypes-1.4.8/comtypes/_idl_stuff.py +0 -67
- comtypes-1.4.8/comtypes/server/__init__.py +0 -70
- comtypes-1.4.8/comtypes/server/w_getopt.py +0 -75
- comtypes-1.4.8/comtypes/test/test_comserver.py +0 -239
- comtypes-1.4.8/comtypes/test/test_dispinterface.py +0 -137
- comtypes-1.4.8/comtypes/test/test_propputref.py +0 -40
- comtypes-1.4.8/comtypes/test/test_server.py +0 -354
- {comtypes-1.4.8 → comtypes-1.4.9}/LICENSE.txt +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/MANIFEST.in +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_meta.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_npsupport.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_post_coinit/__init__.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_post_coinit/bstr.py +0 -0
- /comtypes-1.4.8/comtypes/_py_instance_method.py → /comtypes-1.4.9/comtypes/_post_coinit/instancemethod.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_tlib_version_checker.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/clear_cache.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/__init__.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/dynamic.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/connectionpoints.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/hresult.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/logutil.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/messageloop.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/patcher.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/persist.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/server/automation.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/server/connectionpoints.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/stream.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestComServer.idl +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestComServer.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestComServer.tlb +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestDispServer.idl +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestDispServer.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestDispServer.tlb +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/find_memleak.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/mylib.idl +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/mylib.tlb +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/mytypelib.idl +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/runtests.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/setup.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_DISPPARAMS.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_GUID.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_QueryService.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_agilent.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_basic.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_clear_cache.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_client.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_client_dynamic.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_client_regenerate_modules.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_dict.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_dispifc_records.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_dispifc_safearrays.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_dyndispatch.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_findgendir.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_getactiveobj.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_ienum.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_imfattributes.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_jscript.js +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_monikers.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_msscript.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_npsupport.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_persist.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_pump_events.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_recordinfo.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_sapi.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_shelllink.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_storage.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_stream.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_subinterface.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_typeannotator.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_typeinfo.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_urlhistory.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_word.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/urlhist.tlb +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/__init__.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/__init__.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/modulenamer.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/namespaces.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/tlbparser.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/typedesc_base.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/util.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes.egg-info/dependency_links.txt +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes.egg-info/entry_points.txt +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes.egg-info/top_level.txt +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/setup.cfg +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/setup.py +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import ctypes
|
|
2
|
-
from typing import Any, NamedTuple
|
|
2
|
+
from typing import Any, Literal, NamedTuple
|
|
3
3
|
from typing import Dict, List, Tuple, Type
|
|
4
4
|
from typing import Optional, Union as _UnionT
|
|
5
5
|
from typing import Callable, Iterator
|
|
@@ -64,7 +64,7 @@ def _resolve_argspec(
|
|
|
64
64
|
elif typ is ctypes.POINTER(VARIANT):
|
|
65
65
|
defval = ctypes.pointer(VARIANT.missing)
|
|
66
66
|
else:
|
|
67
|
-
# msg =
|
|
67
|
+
# msg = f"'optional' only allowed for VARIANT and VARIANT*, not for {typ.__name__}"
|
|
68
68
|
# warnings.warn(msg, IDLWarning, stacklevel=2)
|
|
69
69
|
defval = typ()
|
|
70
70
|
if defval is _NOTHING:
|
|
@@ -92,7 +92,7 @@ class _ComMemberSpec(NamedTuple):
|
|
|
92
92
|
class _DispMemberSpec(NamedTuple):
|
|
93
93
|
"""Specifier for a slot of dispinterface method or property."""
|
|
94
94
|
|
|
95
|
-
what:
|
|
95
|
+
what: Literal["DISPMETHOD", "DISPPROPERTY"]
|
|
96
96
|
name: str
|
|
97
97
|
idlflags: Tuple[_UnionT[str, int], ...]
|
|
98
98
|
restype: Optional[Type[_CData]]
|
|
@@ -118,6 +118,78 @@ def _is_spec_prop(m: _MemberSpec):
|
|
|
118
118
|
return any(f in ("propget", "propput", "propputref") for f in m.idlflags)
|
|
119
119
|
|
|
120
120
|
|
|
121
|
+
################################################################
|
|
122
|
+
# IDL stuff
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class helpstring(str):
|
|
126
|
+
"Specifies the helpstring for a COM method or property."
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class defaultvalue(object):
|
|
130
|
+
"Specifies the default value for parameters marked optional."
|
|
131
|
+
|
|
132
|
+
def __init__(self, value):
|
|
133
|
+
self.value = value
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class dispid(int):
|
|
137
|
+
"Specifies the DISPID of a method or property."
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
# XXX STDMETHOD, COMMETHOD, DISPMETHOD, and DISPPROPERTY should return
|
|
141
|
+
# instances with more methods or properties, and should not behave as an unpackable.
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def STDMETHOD(restype, name, argtypes=()) -> _ComMemberSpec:
|
|
145
|
+
"Specifies a COM method slot without idlflags"
|
|
146
|
+
return _ComMemberSpec(restype, name, argtypes, None, (), None)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def DISPMETHOD(idlflags, restype, name, *argspec) -> _DispMemberSpec:
|
|
150
|
+
"Specifies a method of a dispinterface"
|
|
151
|
+
return _DispMemberSpec("DISPMETHOD", name, tuple(idlflags), restype, argspec)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def DISPPROPERTY(idlflags, proptype, name) -> _DispMemberSpec:
|
|
155
|
+
"Specifies a property of a dispinterface"
|
|
156
|
+
return _DispMemberSpec("DISPPROPERTY", name, tuple(idlflags), proptype, ())
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# tuple(idlflags) is for the method itself: (dispid, 'readonly')
|
|
160
|
+
|
|
161
|
+
# sample generated code:
|
|
162
|
+
# DISPPROPERTY([5, 'readonly'], OLE_YSIZE_HIMETRIC, 'Height'),
|
|
163
|
+
# DISPMETHOD(
|
|
164
|
+
# [6], None, 'Render', ([], c_int, 'hdc'), ([], c_int, 'x'), ([], c_int, 'y')
|
|
165
|
+
# )
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def COMMETHOD(idlflags, restype, methodname, *argspec) -> _ComMemberSpec:
|
|
169
|
+
"""Specifies a COM method slot with idlflags.
|
|
170
|
+
|
|
171
|
+
XXX should explain the sematics of the arguments.
|
|
172
|
+
"""
|
|
173
|
+
# collect all helpstring instances
|
|
174
|
+
# We should suppress docstrings when Python is started with -OO
|
|
175
|
+
# join them together(does this make sense?) and replace by None if empty.
|
|
176
|
+
helptext = "".join(t for t in idlflags if isinstance(t, helpstring)) or None
|
|
177
|
+
paramflags, argtypes = _resolve_argspec(argspec)
|
|
178
|
+
if "propget" in idlflags:
|
|
179
|
+
name = f"_get_{methodname}"
|
|
180
|
+
elif "propput" in idlflags:
|
|
181
|
+
name = f"_set_{methodname}"
|
|
182
|
+
elif "propputref" in idlflags:
|
|
183
|
+
name = f"_setref_{methodname}"
|
|
184
|
+
else:
|
|
185
|
+
name = methodname
|
|
186
|
+
return _ComMemberSpec(
|
|
187
|
+
restype, name, argtypes, paramflags, tuple(idlflags), helptext
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
################################################################
|
|
192
|
+
|
|
121
193
|
_PropFunc = Optional[Callable[..., Any]]
|
|
122
194
|
_DocType = Optional[str]
|
|
123
195
|
|
|
@@ -310,7 +382,7 @@ class PropertyGenerator(object):
|
|
|
310
382
|
# Hm, must be a descriptor where the __get__ method
|
|
311
383
|
# returns a bound object having __getitem__ and
|
|
312
384
|
# __setitem__ methods.
|
|
313
|
-
prop = named_property("
|
|
385
|
+
prop = named_property(f"{self._cls_name}.{name}", fget, fset, doc)
|
|
314
386
|
yield (name, prop)
|
|
315
387
|
|
|
316
388
|
def to_propget_keys(self, m: _MemberSpec) -> Tuple[str, _DocType, int]:
|
|
@@ -360,7 +432,7 @@ class DispPropertyGenerator(PropertyGenerator):
|
|
|
360
432
|
|
|
361
433
|
|
|
362
434
|
class ComMemberGenerator(object):
|
|
363
|
-
def __init__(self, cls_name: str, vtbl_offset: int, iid: comtypes.GUID) -> None:
|
|
435
|
+
def __init__(self, cls_name: str, vtbl_offset: int, iid: "comtypes.GUID") -> None:
|
|
364
436
|
self._vtbl_offset = vtbl_offset
|
|
365
437
|
self._iid = iid
|
|
366
438
|
self._props = ComPropertyGenerator(cls_name)
|
|
@@ -533,11 +605,11 @@ class bound_named_property(object):
|
|
|
533
605
|
self.fset(self.instance, index, value)
|
|
534
606
|
|
|
535
607
|
def __repr__(self):
|
|
536
|
-
return "<bound_named_property
|
|
608
|
+
return f"<bound_named_property {self.name!r} at {id(self):x}>"
|
|
537
609
|
|
|
538
610
|
def __iter__(self):
|
|
539
611
|
"""Explicitly disallow iteration."""
|
|
540
|
-
msg = "
|
|
612
|
+
msg = f"{self.name!r} is not iterable"
|
|
541
613
|
raise TypeError(msg)
|
|
542
614
|
|
|
543
615
|
|
|
@@ -558,4 +630,4 @@ class named_property(object):
|
|
|
558
630
|
raise AttributeError("Unsettable attribute")
|
|
559
631
|
|
|
560
632
|
def __repr__(self):
|
|
561
|
-
return "<named_property
|
|
633
|
+
return f"<named_property {self.name!r} at {id(self):x}>"
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import types
|
|
2
|
+
from _ctypes import COMError
|
|
3
|
+
from typing import Type
|
|
4
|
+
|
|
5
|
+
from comtypes import patcher
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
_all_slice = slice(None, None, None)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def case_insensitive(p: Type) -> None:
|
|
12
|
+
@patcher.Patch(p)
|
|
13
|
+
class CaseInsensitive(object):
|
|
14
|
+
# case insensitive attributes for COM methods and properties
|
|
15
|
+
def __getattr__(self, name):
|
|
16
|
+
"""Implement case insensitive access to methods and properties"""
|
|
17
|
+
try:
|
|
18
|
+
fixed_name = self.__map_case__[name.lower()]
|
|
19
|
+
except KeyError:
|
|
20
|
+
raise AttributeError(name) # Should we use exception-chaining?
|
|
21
|
+
if fixed_name != name: # prevent unbounded recursion
|
|
22
|
+
return getattr(self, fixed_name)
|
|
23
|
+
raise AttributeError(name)
|
|
24
|
+
|
|
25
|
+
# __setattr__ is pretty heavy-weight, because it is called for
|
|
26
|
+
# EVERY attribute assignment. Settings a non-com attribute
|
|
27
|
+
# through this function takes 8.6 usec, while without this
|
|
28
|
+
# function it takes 0.7 sec - 12 times slower.
|
|
29
|
+
#
|
|
30
|
+
# How much faster would this be if implemented in C?
|
|
31
|
+
def __setattr__(self, name, value):
|
|
32
|
+
"""Implement case insensitive access to methods and properties"""
|
|
33
|
+
object.__setattr__(self, self.__map_case__.get(name.lower(), name), value)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def reference_fix(pp: Type) -> None:
|
|
37
|
+
@patcher.Patch(pp)
|
|
38
|
+
class ReferenceFix(object):
|
|
39
|
+
def __setitem__(self, index, value):
|
|
40
|
+
# We override the __setitem__ method of the
|
|
41
|
+
# POINTER(POINTER(interface)) type, so that the COM
|
|
42
|
+
# reference count is managed correctly.
|
|
43
|
+
#
|
|
44
|
+
# This is so that we can implement COM methods that have to
|
|
45
|
+
# return COM pointers more easily and consistent. Instead of
|
|
46
|
+
# using CopyComPointer in the method implementation, we can
|
|
47
|
+
# simply do:
|
|
48
|
+
#
|
|
49
|
+
# def GetTypeInfo(self, this, ..., pptinfo):
|
|
50
|
+
# if not pptinfo: return E_POINTER
|
|
51
|
+
# pptinfo[0] = a_com_interface_pointer
|
|
52
|
+
# return S_OK
|
|
53
|
+
if index != 0:
|
|
54
|
+
# CopyComPointer, which is in _ctypes, does only
|
|
55
|
+
# handle an index of 0. This code does what
|
|
56
|
+
# CopyComPointer should do if index != 0.
|
|
57
|
+
if bool(value):
|
|
58
|
+
value.AddRef()
|
|
59
|
+
super(pp, self).__setitem__(index, value) # type: ignore
|
|
60
|
+
return
|
|
61
|
+
from _ctypes import CopyComPointer
|
|
62
|
+
|
|
63
|
+
CopyComPointer(value, self) # type: ignore
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def sized(itf: Type) -> None:
|
|
67
|
+
@patcher.Patch(itf)
|
|
68
|
+
class _(object):
|
|
69
|
+
def __len__(self):
|
|
70
|
+
"Return the the 'self.Count' property."
|
|
71
|
+
return self.Count
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def callable_and_subscriptable(itf: Type) -> None:
|
|
75
|
+
@patcher.Patch(itf)
|
|
76
|
+
class _(object):
|
|
77
|
+
# 'Item' is the 'default' value. Make it available by
|
|
78
|
+
# calling the instance (Not sure this makes sense, but
|
|
79
|
+
# win32com does this also).
|
|
80
|
+
def __call__(self, *args, **kw):
|
|
81
|
+
"Return 'self.Item(*args, **kw)'"
|
|
82
|
+
return self.Item(*args, **kw)
|
|
83
|
+
|
|
84
|
+
# does this make sense? It seems that all standard typelibs I've
|
|
85
|
+
# seen so far that support .Item also support ._NewEnum
|
|
86
|
+
@patcher.no_replace
|
|
87
|
+
def __getitem__(self, index):
|
|
88
|
+
"Return 'self.Item(index)'"
|
|
89
|
+
# Handle tuples and all-slice
|
|
90
|
+
if isinstance(index, tuple):
|
|
91
|
+
args = index
|
|
92
|
+
elif index == _all_slice:
|
|
93
|
+
args = ()
|
|
94
|
+
else:
|
|
95
|
+
args = (index,)
|
|
96
|
+
|
|
97
|
+
try:
|
|
98
|
+
result = self.Item(*args)
|
|
99
|
+
except COMError as err:
|
|
100
|
+
(hresult, text, details) = err.args
|
|
101
|
+
if hresult == -2147352565: # DISP_E_BADINDEX
|
|
102
|
+
raise IndexError("invalid index")
|
|
103
|
+
else:
|
|
104
|
+
raise
|
|
105
|
+
|
|
106
|
+
# Note that result may be NULL COM pointer. There is no way
|
|
107
|
+
# to interpret this properly, so it is returned as-is.
|
|
108
|
+
|
|
109
|
+
# Hm, should we call __ctypes_from_outparam__ on the
|
|
110
|
+
# result?
|
|
111
|
+
return result
|
|
112
|
+
|
|
113
|
+
@patcher.no_replace
|
|
114
|
+
def __setitem__(self, index, value):
|
|
115
|
+
"Attempt 'self.Item[index] = value'"
|
|
116
|
+
try:
|
|
117
|
+
self.Item[index] = value
|
|
118
|
+
except COMError as err:
|
|
119
|
+
(hresult, text, details) = err.args
|
|
120
|
+
if hresult == -2147352565: # DISP_E_BADINDEX
|
|
121
|
+
raise IndexError("invalid index")
|
|
122
|
+
else:
|
|
123
|
+
raise
|
|
124
|
+
except TypeError:
|
|
125
|
+
msg = f"{type(self)!r} object does not support item assignment"
|
|
126
|
+
raise TypeError(msg)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def iterator(itf: Type) -> None:
|
|
130
|
+
@patcher.Patch(itf)
|
|
131
|
+
class _(object):
|
|
132
|
+
def __iter__(self):
|
|
133
|
+
"Return an iterator over the _NewEnum collection."
|
|
134
|
+
# This method returns a pointer to _some_ _NewEnum interface.
|
|
135
|
+
# It relies on the fact that the code generator creates next()
|
|
136
|
+
# methods for them automatically.
|
|
137
|
+
#
|
|
138
|
+
# Better would maybe to return an object that
|
|
139
|
+
# implements the Python iterator protocol, and
|
|
140
|
+
# forwards the calls to the COM interface.
|
|
141
|
+
enum = self._NewEnum
|
|
142
|
+
if isinstance(enum, types.MethodType):
|
|
143
|
+
# _NewEnum should be a propget property, with dispid -4.
|
|
144
|
+
#
|
|
145
|
+
# Sometimes, however, it is a method.
|
|
146
|
+
enum = enum()
|
|
147
|
+
if hasattr(enum, "Next"):
|
|
148
|
+
return enum
|
|
149
|
+
# _NewEnum returns an IUnknown pointer, QueryInterface() it to
|
|
150
|
+
# IEnumVARIANT
|
|
151
|
+
from comtypes.automation import IEnumVARIANT
|
|
152
|
+
|
|
153
|
+
return enum.QueryInterface(IEnumVARIANT)
|
|
@@ -16,9 +16,9 @@ if TYPE_CHECKING:
|
|
|
16
16
|
from comtypes import hints as hints # noqa # type: ignore
|
|
17
17
|
|
|
18
18
|
from comtypes import GUID
|
|
19
|
-
from comtypes._idl_stuff import COMMETHOD # noqa
|
|
20
19
|
from comtypes import CLSCTX_SERVER, CLSCTX_LOCAL_SERVER, CLSCTX_REMOTE_SERVER
|
|
21
20
|
from comtypes import _ole32, oledll, DWORD
|
|
21
|
+
from comtypes._memberspec import COMMETHOD
|
|
22
22
|
from comtypes._post_coinit.unknwn import IUnknown
|
|
23
23
|
|
|
24
24
|
|
|
@@ -1,23 +1,17 @@
|
|
|
1
1
|
# https://learn.microsoft.com/en-us/windows/win32/api/unknwn/
|
|
2
2
|
|
|
3
|
-
from ctypes import byref, c_ulong, c_void_p, HRESULT, POINTER
|
|
4
|
-
from _ctypes import COMError
|
|
5
|
-
|
|
6
3
|
import logging
|
|
7
4
|
import sys
|
|
8
|
-
import
|
|
9
|
-
from typing import ClassVar,
|
|
10
|
-
from typing import Optional
|
|
11
|
-
from typing import List, Type
|
|
12
|
-
|
|
13
|
-
from comtypes import GUID, patcher, _ole32_nohresult, com_interface_registry
|
|
14
|
-
from comtypes._idl_stuff import STDMETHOD
|
|
15
|
-
from comtypes._memberspec import ComMemberGenerator, DispMemberGenerator
|
|
16
|
-
from comtypes._memberspec import _ComMemberSpec, _DispMemberSpec
|
|
17
|
-
from comtypes._py_instance_method import instancemethod
|
|
5
|
+
from ctypes import HRESULT, POINTER, byref, c_ulong, c_void_p
|
|
6
|
+
from typing import TYPE_CHECKING, ClassVar, List, Optional, Type, TypeVar
|
|
18
7
|
|
|
8
|
+
from comtypes import GUID, _ole32_nohresult, com_interface_registry
|
|
9
|
+
from comtypes._memberspec import STDMETHOD, ComMemberGenerator, DispMemberGenerator
|
|
10
|
+
from comtypes._post_coinit import _cominterface_meta_patcher as _meta_patch
|
|
11
|
+
from comtypes._post_coinit.instancemethod import instancemethod
|
|
19
12
|
|
|
20
|
-
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from comtypes._memberspec import _ComMemberSpec, _DispMemberSpec
|
|
21
15
|
|
|
22
16
|
logger = logging.getLogger(__name__)
|
|
23
17
|
|
|
@@ -58,8 +52,8 @@ class _cominterface_meta(type):
|
|
|
58
52
|
|
|
59
53
|
_case_insensitive_: bool
|
|
60
54
|
_iid_: GUID
|
|
61
|
-
_methods_: List[_ComMemberSpec]
|
|
62
|
-
_disp_methods_: List[_DispMemberSpec]
|
|
55
|
+
_methods_: List["_ComMemberSpec"]
|
|
56
|
+
_disp_methods_: List["_DispMemberSpec"]
|
|
63
57
|
|
|
64
58
|
# This flag is set to True by the atexit handler which calls
|
|
65
59
|
# CoUninitialize.
|
|
@@ -136,68 +130,11 @@ class _cominterface_meta(type):
|
|
|
136
130
|
_pointer_type_cache[self] = p
|
|
137
131
|
|
|
138
132
|
if self._case_insensitive_:
|
|
139
|
-
|
|
140
|
-
|
|
133
|
+
_meta_patch.case_insensitive(p)
|
|
134
|
+
_meta_patch.reference_fix(POINTER(p)) # type: ignore
|
|
141
135
|
|
|
142
136
|
return self
|
|
143
137
|
|
|
144
|
-
@staticmethod
|
|
145
|
-
def _patch_case_insensitive_to_ptr_type(p: Type) -> None:
|
|
146
|
-
@patcher.Patch(p)
|
|
147
|
-
class CaseInsensitive(object):
|
|
148
|
-
# case insensitive attributes for COM methods and properties
|
|
149
|
-
def __getattr__(self, name):
|
|
150
|
-
"""Implement case insensitive access to methods and properties"""
|
|
151
|
-
try:
|
|
152
|
-
fixed_name = self.__map_case__[name.lower()]
|
|
153
|
-
except KeyError:
|
|
154
|
-
raise AttributeError(name) # Should we use exception-chaining?
|
|
155
|
-
if fixed_name != name: # prevent unbounded recursion
|
|
156
|
-
return getattr(self, fixed_name)
|
|
157
|
-
raise AttributeError(name)
|
|
158
|
-
|
|
159
|
-
# __setattr__ is pretty heavy-weight, because it is called for
|
|
160
|
-
# EVERY attribute assignment. Settings a non-com attribute
|
|
161
|
-
# through this function takes 8.6 usec, while without this
|
|
162
|
-
# function it takes 0.7 sec - 12 times slower.
|
|
163
|
-
#
|
|
164
|
-
# How much faster would this be if implemented in C?
|
|
165
|
-
def __setattr__(self, name, value):
|
|
166
|
-
"""Implement case insensitive access to methods and properties"""
|
|
167
|
-
object.__setattr__(
|
|
168
|
-
self, self.__map_case__.get(name.lower(), name), value
|
|
169
|
-
)
|
|
170
|
-
|
|
171
|
-
@staticmethod
|
|
172
|
-
def _patch_reference_fix_to_ptrptr_type(pp: Type) -> None:
|
|
173
|
-
@patcher.Patch(pp)
|
|
174
|
-
class ReferenceFix(object):
|
|
175
|
-
def __setitem__(self, index, value):
|
|
176
|
-
# We override the __setitem__ method of the
|
|
177
|
-
# POINTER(POINTER(interface)) type, so that the COM
|
|
178
|
-
# reference count is managed correctly.
|
|
179
|
-
#
|
|
180
|
-
# This is so that we can implement COM methods that have to
|
|
181
|
-
# return COM pointers more easily and consistent. Instead of
|
|
182
|
-
# using CopyComPointer in the method implementation, we can
|
|
183
|
-
# simply do:
|
|
184
|
-
#
|
|
185
|
-
# def GetTypeInfo(self, this, ..., pptinfo):
|
|
186
|
-
# if not pptinfo: return E_POINTER
|
|
187
|
-
# pptinfo[0] = a_com_interface_pointer
|
|
188
|
-
# return S_OK
|
|
189
|
-
if index != 0:
|
|
190
|
-
# CopyComPointer, which is in _ctypes, does only
|
|
191
|
-
# handle an index of 0. This code does what
|
|
192
|
-
# CopyComPointer should do if index != 0.
|
|
193
|
-
if bool(value):
|
|
194
|
-
value.AddRef()
|
|
195
|
-
super(pp, self).__setitem__(index, value) # type: ignore
|
|
196
|
-
return
|
|
197
|
-
from _ctypes import CopyComPointer
|
|
198
|
-
|
|
199
|
-
CopyComPointer(value, self) # type: ignore
|
|
200
|
-
|
|
201
138
|
def __setattr__(self, name, value):
|
|
202
139
|
if name == "_methods_":
|
|
203
140
|
# XXX I'm no longer sure why the code generator generates
|
|
@@ -225,94 +162,11 @@ class _cominterface_meta(type):
|
|
|
225
162
|
|
|
226
163
|
# XXX These special methods should be generated by the code generator.
|
|
227
164
|
if has_name("Count"):
|
|
228
|
-
|
|
229
|
-
@patcher.Patch(self)
|
|
230
|
-
class _(object):
|
|
231
|
-
def __len__(self):
|
|
232
|
-
"Return the the 'self.Count' property."
|
|
233
|
-
return self.Count
|
|
234
|
-
|
|
165
|
+
_meta_patch.sized(self)
|
|
235
166
|
if has_name("Item"):
|
|
236
|
-
|
|
237
|
-
@patcher.Patch(self)
|
|
238
|
-
class _(object):
|
|
239
|
-
# 'Item' is the 'default' value. Make it available by
|
|
240
|
-
# calling the instance (Not sure this makes sense, but
|
|
241
|
-
# win32com does this also).
|
|
242
|
-
def __call__(self, *args, **kw):
|
|
243
|
-
"Return 'self.Item(*args, **kw)'"
|
|
244
|
-
return self.Item(*args, **kw)
|
|
245
|
-
|
|
246
|
-
# does this make sense? It seems that all standard typelibs I've
|
|
247
|
-
# seen so far that support .Item also support ._NewEnum
|
|
248
|
-
@patcher.no_replace
|
|
249
|
-
def __getitem__(self, index):
|
|
250
|
-
"Return 'self.Item(index)'"
|
|
251
|
-
# Handle tuples and all-slice
|
|
252
|
-
if isinstance(index, tuple):
|
|
253
|
-
args = index
|
|
254
|
-
elif index == _all_slice:
|
|
255
|
-
args = ()
|
|
256
|
-
else:
|
|
257
|
-
args = (index,)
|
|
258
|
-
|
|
259
|
-
try:
|
|
260
|
-
result = self.Item(*args)
|
|
261
|
-
except COMError as err:
|
|
262
|
-
(hresult, text, details) = err.args
|
|
263
|
-
if hresult == -2147352565: # DISP_E_BADINDEX
|
|
264
|
-
raise IndexError("invalid index")
|
|
265
|
-
else:
|
|
266
|
-
raise
|
|
267
|
-
|
|
268
|
-
# Note that result may be NULL COM pointer. There is no way
|
|
269
|
-
# to interpret this properly, so it is returned as-is.
|
|
270
|
-
|
|
271
|
-
# Hm, should we call __ctypes_from_outparam__ on the
|
|
272
|
-
# result?
|
|
273
|
-
return result
|
|
274
|
-
|
|
275
|
-
@patcher.no_replace
|
|
276
|
-
def __setitem__(self, index, value):
|
|
277
|
-
"Attempt 'self.Item[index] = value'"
|
|
278
|
-
try:
|
|
279
|
-
self.Item[index] = value
|
|
280
|
-
except COMError as err:
|
|
281
|
-
(hresult, text, details) = err.args
|
|
282
|
-
if hresult == -2147352565: # DISP_E_BADINDEX
|
|
283
|
-
raise IndexError("invalid index")
|
|
284
|
-
else:
|
|
285
|
-
raise
|
|
286
|
-
except TypeError:
|
|
287
|
-
msg = "%r object does not support item assignment"
|
|
288
|
-
raise TypeError(msg % type(self))
|
|
289
|
-
|
|
167
|
+
_meta_patch.callable_and_subscriptable(self)
|
|
290
168
|
if has_name("_NewEnum"):
|
|
291
|
-
|
|
292
|
-
@patcher.Patch(self)
|
|
293
|
-
class _(object):
|
|
294
|
-
def __iter__(self):
|
|
295
|
-
"Return an iterator over the _NewEnum collection."
|
|
296
|
-
# This method returns a pointer to _some_ _NewEnum interface.
|
|
297
|
-
# It relies on the fact that the code generator creates next()
|
|
298
|
-
# methods for them automatically.
|
|
299
|
-
#
|
|
300
|
-
# Better would maybe to return an object that
|
|
301
|
-
# implements the Python iterator protocol, and
|
|
302
|
-
# forwards the calls to the COM interface.
|
|
303
|
-
enum = self._NewEnum
|
|
304
|
-
if isinstance(enum, types.MethodType):
|
|
305
|
-
# _NewEnum should be a propget property, with dispid -4.
|
|
306
|
-
#
|
|
307
|
-
# Sometimes, however, it is a method.
|
|
308
|
-
enum = enum()
|
|
309
|
-
if hasattr(enum, "Next"):
|
|
310
|
-
return enum
|
|
311
|
-
# _NewEnum returns an IUnknown pointer, QueryInterface() it to
|
|
312
|
-
# IEnumVARIANT
|
|
313
|
-
from comtypes.automation import IEnumVARIANT
|
|
314
|
-
|
|
315
|
-
return enum.QueryInterface(IEnumVARIANT)
|
|
169
|
+
_meta_patch.iterator(self)
|
|
316
170
|
|
|
317
171
|
def _make_case_insensitive(self):
|
|
318
172
|
# The __map_case__ dictionary maps lower case names to the
|
|
@@ -325,7 +179,7 @@ class _cominterface_meta(type):
|
|
|
325
179
|
d.update(getattr(self, "__map_case__", {}))
|
|
326
180
|
self.__map_case__ = d
|
|
327
181
|
|
|
328
|
-
def _make_dispmethods(self, methods: List[_DispMemberSpec]) -> None:
|
|
182
|
+
def _make_dispmethods(self, methods: List["_DispMemberSpec"]) -> None:
|
|
329
183
|
if self._case_insensitive_:
|
|
330
184
|
self._make_case_insensitive()
|
|
331
185
|
# create dispinterface methods and properties on the interface 'self'
|
|
@@ -357,7 +211,7 @@ class _cominterface_meta(type):
|
|
|
357
211
|
raise TypeError(f"baseinterface '{itf.__name__}' has no _methods_")
|
|
358
212
|
return result
|
|
359
213
|
|
|
360
|
-
def _make_methods(self, methods: List[_ComMemberSpec]) -> None:
|
|
214
|
+
def _make_methods(self, methods: List["_ComMemberSpec"]) -> None:
|
|
361
215
|
if self._case_insensitive_:
|
|
362
216
|
self._make_case_insensitive()
|
|
363
217
|
# register com interface. we insist on an _iid_ in THIS class!
|
|
@@ -375,12 +229,12 @@ class _cominterface_meta(type):
|
|
|
375
229
|
member_gen.add(m)
|
|
376
230
|
for name, func, raw_func, is_prop in member_gen.methods():
|
|
377
231
|
raw_mth = instancemethod(raw_func, None, self)
|
|
378
|
-
setattr(self, "_
|
|
232
|
+
setattr(self, f"_{self.__name__}__com_{name}", raw_mth)
|
|
379
233
|
mth = instancemethod(func, None, self)
|
|
380
234
|
if not is_prop:
|
|
381
235
|
# We install the method in the class, except when it's a property.
|
|
382
236
|
# And we make sure we don't overwrite a property that's already present.
|
|
383
|
-
mthname = name if not hasattr(self, name) else
|
|
237
|
+
mthname = name if not hasattr(self, name) else f"_{name}"
|
|
384
238
|
setattr(self, mthname, mth)
|
|
385
239
|
# For a method, this is the real name.
|
|
386
240
|
# For a property, this is the name WITHOUT the _set_ or _get_ prefix.
|
|
@@ -391,7 +245,7 @@ class _cominterface_meta(type):
|
|
|
391
245
|
# create public properties / attribute accessors
|
|
392
246
|
for name, accessor in member_gen.properties():
|
|
393
247
|
# Again, we should not overwrite class attributes that are already present.
|
|
394
|
-
propname = name if not hasattr(self, name) else
|
|
248
|
+
propname = name if not hasattr(self, name) else f"_{name}"
|
|
395
249
|
setattr(self, propname, accessor)
|
|
396
250
|
# COM is case insensitive
|
|
397
251
|
if self._case_insensitive_:
|
|
@@ -423,7 +277,7 @@ class _compointer_base(c_void_p, metaclass=_compointer_meta):
|
|
|
423
277
|
#
|
|
424
278
|
if not type(self)._com_shutting_down:
|
|
425
279
|
_debug("Release %s", self)
|
|
426
|
-
self.Release()
|
|
280
|
+
self.Release() # type: ignore
|
|
427
281
|
|
|
428
282
|
def __eq__(self, other):
|
|
429
283
|
if not isinstance(other, _compointer_base):
|
|
@@ -446,7 +300,7 @@ class _compointer_base(c_void_p, metaclass=_compointer_meta):
|
|
|
446
300
|
|
|
447
301
|
def __repr__(self):
|
|
448
302
|
ptr = super(_compointer_base, self).value
|
|
449
|
-
return "
|
|
303
|
+
return f"<{self.__class__.__name__} ptr=0x{ptr or 0:x} at {id(self):x}>"
|
|
450
304
|
|
|
451
305
|
# This fixes the problem when there are multiple python interface types
|
|
452
306
|
# wrapping the same COM interface. This could happen because some interfaces
|
|
@@ -482,8 +336,8 @@ class _compointer_base(c_void_p, metaclass=_compointer_meta):
|
|
|
482
336
|
# a kind of QueryInterface
|
|
483
337
|
return table[cls._iid_]
|
|
484
338
|
except KeyError:
|
|
485
|
-
raise TypeError("Interface
|
|
486
|
-
return value.QueryInterface(cls.__com_interface__)
|
|
339
|
+
raise TypeError(f"Interface {cls._iid_} not supported")
|
|
340
|
+
return value.QueryInterface(cls.__com_interface__) # type: ignore
|
|
487
341
|
|
|
488
342
|
|
|
489
343
|
################################################################
|
|
@@ -524,7 +378,7 @@ class IUnknown(_IUnknown_Base, metaclass=_cominterface_meta):
|
|
|
524
378
|
|
|
525
379
|
_case_insensitive_: ClassVar[bool] = False
|
|
526
380
|
_iid_: ClassVar[GUID] = GUID("{00000000-0000-0000-C000-000000000046}")
|
|
527
|
-
_methods_: ClassVar[List[_ComMemberSpec]] = [
|
|
381
|
+
_methods_: ClassVar[List["_ComMemberSpec"]] = [
|
|
528
382
|
STDMETHOD(HRESULT, "QueryInterface", [POINTER(GUID), POINTER(c_void_p)]),
|
|
529
383
|
STDMETHOD(c_ulong, "AddRef"),
|
|
530
384
|
STDMETHOD(c_ulong, "Release"),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""SAFEARRAY api functions, data types, and constants."""
|
|
2
2
|
|
|
3
3
|
from ctypes import c_uint, c_ushort, c_void_p, POINTER, Structure, WinDLL
|
|
4
|
-
from ctypes.wintypes import DWORD, LONG, UINT
|
|
4
|
+
from ctypes.wintypes import DWORD, LONG, UINT, USHORT
|
|
5
5
|
|
|
6
6
|
from comtypes import HRESULT, GUID
|
|
7
7
|
|
|
@@ -19,7 +19,6 @@ from comtypes import HRESULT, GUID
|
|
|
19
19
|
|
|
20
20
|
VARTYPE = c_ushort
|
|
21
21
|
PVOID = c_void_p
|
|
22
|
-
USHORT = c_ushort
|
|
23
22
|
|
|
24
23
|
_oleaut32 = WinDLL("oleaut32")
|
|
25
24
|
|