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,8 +1,7 @@
|
|
|
1
1
|
import array
|
|
2
2
|
import datetime
|
|
3
3
|
import unittest
|
|
4
|
-
from ctypes import POINTER,
|
|
5
|
-
from ctypes.wintypes import BOOL
|
|
4
|
+
from ctypes import POINTER, c_long
|
|
6
5
|
from decimal import Decimal
|
|
7
6
|
|
|
8
7
|
from comtypes import BSTR, IUnknown
|
|
@@ -19,7 +18,6 @@ from comtypes.automation import (
|
|
|
19
18
|
_midlSAFEARRAY,
|
|
20
19
|
)
|
|
21
20
|
from comtypes.safearray import safearray_as_ndarray
|
|
22
|
-
from comtypes.test import is_resource_enabled
|
|
23
21
|
from comtypes.test.find_memleak import find_memleak
|
|
24
22
|
|
|
25
23
|
|
|
@@ -223,93 +221,6 @@ class SafeArrayTestCase(unittest.TestCase):
|
|
|
223
221
|
del sa
|
|
224
222
|
self.assertEqual((a, b), (com_refcnt(plib), com_refcnt(punk)))
|
|
225
223
|
|
|
226
|
-
@unittest.skip(
|
|
227
|
-
"This fails with a 'library not registered' error. Need to figure out how to "
|
|
228
|
-
"register TestComServerLib (without admin if possible)."
|
|
229
|
-
)
|
|
230
|
-
def test_UDT(self):
|
|
231
|
-
from comtypes.gen.TestComServerLib import MYCOLOR
|
|
232
|
-
|
|
233
|
-
t = _midlSAFEARRAY(MYCOLOR)
|
|
234
|
-
self.assertTrue(t is _midlSAFEARRAY(MYCOLOR))
|
|
235
|
-
|
|
236
|
-
sa = t.from_param([MYCOLOR(0, 0, 0), MYCOLOR(1, 2, 3)])
|
|
237
|
-
|
|
238
|
-
self.assertEqual(
|
|
239
|
-
[(x.red, x.green, x.blue) for x in sa[0]],
|
|
240
|
-
[(0.0, 0.0, 0.0), (1.0, 2.0, 3.0)],
|
|
241
|
-
)
|
|
242
|
-
|
|
243
|
-
def doit():
|
|
244
|
-
t.from_param([MYCOLOR(0, 0, 0), MYCOLOR(1, 2, 3)])
|
|
245
|
-
|
|
246
|
-
bytes = find_memleak(doit)
|
|
247
|
-
self.assertFalse(bytes, "Leaks %d bytes" % bytes)
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
if is_resource_enabled("pythoncom"):
|
|
251
|
-
try:
|
|
252
|
-
import pythoncom
|
|
253
|
-
except ImportError:
|
|
254
|
-
# pywin32 not installed...
|
|
255
|
-
pass
|
|
256
|
-
else:
|
|
257
|
-
# pywin32 is available. The pythoncom dll contains two handy
|
|
258
|
-
# exported functions that allow to create a VARIANT from a Python
|
|
259
|
-
# object, also a function that unpacks a VARIANT into a Python
|
|
260
|
-
# object.
|
|
261
|
-
#
|
|
262
|
-
# This allows us to create und unpack SAFEARRAY instances
|
|
263
|
-
# contained in VARIANTs, and check for consistency with the
|
|
264
|
-
# comtypes code.
|
|
265
|
-
|
|
266
|
-
_dll = PyDLL(pythoncom.__file__)
|
|
267
|
-
|
|
268
|
-
# c:/sf/pywin32/com/win32com/src/oleargs.cpp 213
|
|
269
|
-
# PyObject *PyCom_PyObjectFromVariant(const VARIANT *var)
|
|
270
|
-
unpack = _dll.PyCom_PyObjectFromVariant
|
|
271
|
-
unpack.restype = py_object
|
|
272
|
-
unpack.argtypes = (POINTER(VARIANT),)
|
|
273
|
-
|
|
274
|
-
# c:/sf/pywin32/com/win32com/src/oleargs.cpp 54
|
|
275
|
-
# BOOL PyCom_VariantFromPyObject(PyObject *obj, VARIANT *var)
|
|
276
|
-
_pack = _dll.PyCom_VariantFromPyObject
|
|
277
|
-
_pack.argtypes = py_object, POINTER(VARIANT)
|
|
278
|
-
_pack.restype = BOOL
|
|
279
|
-
|
|
280
|
-
def pack(obj):
|
|
281
|
-
var = VARIANT()
|
|
282
|
-
_pack(obj, byref(var))
|
|
283
|
-
return var
|
|
284
|
-
|
|
285
|
-
class PyWinTest(unittest.TestCase):
|
|
286
|
-
def test_1dim(self):
|
|
287
|
-
data = (1, 2, 3)
|
|
288
|
-
variant = pack(data)
|
|
289
|
-
self.assertEqual(variant.value, data)
|
|
290
|
-
self.assertEqual(unpack(variant), data)
|
|
291
|
-
|
|
292
|
-
def test_2dim(self):
|
|
293
|
-
data = ((1, 2, 3), (4, 5, 6), (7, 8, 9))
|
|
294
|
-
variant = pack(data)
|
|
295
|
-
self.assertEqual(variant.value, data)
|
|
296
|
-
self.assertEqual(unpack(variant), data)
|
|
297
|
-
|
|
298
|
-
def test_3dim(self):
|
|
299
|
-
data = (((1, 2), (3, 4), (5, 6)), ((7, 8), (9, 10), (11, 12)))
|
|
300
|
-
variant = pack(data)
|
|
301
|
-
self.assertEqual(variant.value, data)
|
|
302
|
-
self.assertEqual(unpack(variant), data)
|
|
303
|
-
|
|
304
|
-
def test_4dim(self):
|
|
305
|
-
data = (
|
|
306
|
-
(((1, 2), (3, 4)), ((5, 6), (7, 8))),
|
|
307
|
-
(((9, 10), (11, 12)), ((13, 14), (15, 16))),
|
|
308
|
-
)
|
|
309
|
-
variant = pack(data)
|
|
310
|
-
self.assertEqual(variant.value, data)
|
|
311
|
-
self.assertEqual(unpack(variant), data)
|
|
312
|
-
|
|
313
224
|
|
|
314
225
|
if __name__ == "__main__":
|
|
315
226
|
unittest.main()
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import unittest
|
|
3
|
+
|
|
4
|
+
import comtypes.client
|
|
5
|
+
import comtypes.typeinfo
|
|
6
|
+
|
|
7
|
+
# Force module to raise.
|
|
8
|
+
raise unittest.SkipTest("This test module cannot run as-is. Investigate why")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TypeLib(object):
|
|
12
|
+
"""This class collects IDL code fragments and eventually writes
|
|
13
|
+
them into a .IDL file. The compile() method compiles the IDL file
|
|
14
|
+
into a typelibrary and registers it. A function is also
|
|
15
|
+
registered with atexit that will unregister the typelib at program
|
|
16
|
+
exit.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(self, lib):
|
|
20
|
+
self.lib = lib
|
|
21
|
+
self.interfaces = []
|
|
22
|
+
self.coclasses = []
|
|
23
|
+
|
|
24
|
+
def interface(self, header):
|
|
25
|
+
itf = Interface(header)
|
|
26
|
+
self.interfaces.append(itf)
|
|
27
|
+
return itf
|
|
28
|
+
|
|
29
|
+
def coclass(self, definition):
|
|
30
|
+
self.coclasses.append(definition)
|
|
31
|
+
|
|
32
|
+
def __str__(self):
|
|
33
|
+
header = (
|
|
34
|
+
"""import "oaidl.idl";
|
|
35
|
+
import "ocidl.idl";
|
|
36
|
+
%s {"""
|
|
37
|
+
% self.lib
|
|
38
|
+
)
|
|
39
|
+
body = "\n".join([str(itf) for itf in self.interfaces])
|
|
40
|
+
footer = "\n".join(self.coclasses) + "}"
|
|
41
|
+
return "\n".join((header, body, footer))
|
|
42
|
+
|
|
43
|
+
def compile(self):
|
|
44
|
+
"""Compile and register the typelib"""
|
|
45
|
+
code = str(self)
|
|
46
|
+
curdir = os.path.dirname(__file__)
|
|
47
|
+
idl_path = os.path.join(curdir, "mylib.idl")
|
|
48
|
+
tlb_path = os.path.join(curdir, "mylib.tlb")
|
|
49
|
+
if not os.path.isfile(idl_path) or open(idl_path, "r").read() != code:
|
|
50
|
+
open(idl_path, "w").write(code)
|
|
51
|
+
os.system(
|
|
52
|
+
r'call "%%VS71COMNTOOLS%%vsvars32.bat" && '
|
|
53
|
+
r"midl /nologo %s /tlb %s" % (idl_path, tlb_path)
|
|
54
|
+
)
|
|
55
|
+
# Register the typelib...
|
|
56
|
+
tlib = comtypes.typeinfo.LoadTypeLib(tlb_path)
|
|
57
|
+
# create the wrapper module...
|
|
58
|
+
comtypes.client.GetModule(tlb_path)
|
|
59
|
+
# Unregister the typelib at interpreter exit...
|
|
60
|
+
attr = tlib.GetLibAttr()
|
|
61
|
+
guid, major, minor = attr.guid, attr.wMajorVerNum, attr.wMinorVerNum
|
|
62
|
+
## atexit.register(comtypes.typeinfo.UnRegisterTypeLib,
|
|
63
|
+
## guid, major, minor)
|
|
64
|
+
return tlb_path
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class Interface(object):
|
|
68
|
+
def __init__(self, header):
|
|
69
|
+
self.header = header
|
|
70
|
+
self.code = ""
|
|
71
|
+
|
|
72
|
+
def add(self, text):
|
|
73
|
+
self.code += text + "\n"
|
|
74
|
+
return self
|
|
75
|
+
|
|
76
|
+
def __str__(self):
|
|
77
|
+
return self.header + " {\n" + self.code + "}\n"
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
################################################################
|
|
81
|
+
import comtypes
|
|
82
|
+
from comtypes.client import wrap
|
|
83
|
+
|
|
84
|
+
tlb = TypeLib("[uuid(f4f74946-4546-44bd-a073-9ea6f9fe78cb)] library TestLib")
|
|
85
|
+
|
|
86
|
+
itf = tlb.interface(
|
|
87
|
+
"""[object,
|
|
88
|
+
oleautomation,
|
|
89
|
+
dual,
|
|
90
|
+
uuid(ed978f5f-cc45-4fcc-a7a6-751ffa8dfedd)]
|
|
91
|
+
interface IMyInterface : IDispatch"""
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
outgoing = tlb.interface(
|
|
95
|
+
"""[object,
|
|
96
|
+
oleautomation,
|
|
97
|
+
dual,
|
|
98
|
+
uuid(f7c48a90-64ea-4bb8-abf1-b3a3aa996848)]
|
|
99
|
+
interface IMyEventInterface : IDispatch"""
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
tlb.coclass(
|
|
103
|
+
"""
|
|
104
|
+
[uuid(fa9de8f4-20de-45fc-b079-648572428817)]
|
|
105
|
+
coclass MyServer {
|
|
106
|
+
[default] interface IMyInterface;
|
|
107
|
+
[default, source] interface IMyEventInterface;
|
|
108
|
+
};
|
|
109
|
+
"""
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
# The purpose of the MyServer class is to locate three separate code
|
|
113
|
+
# section snippets closely together:
|
|
114
|
+
#
|
|
115
|
+
# 1. The IDL method definition for a COM interface method
|
|
116
|
+
# 2. The Python implementation of the COM method
|
|
117
|
+
# 3. The unittest(s) for the COM method.
|
|
118
|
+
#
|
|
119
|
+
from comtypes.server.connectionpoints import ConnectableObjectMixin
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class MyServer(comtypes.CoClass, ConnectableObjectMixin):
|
|
123
|
+
_reg_typelib_ = ("{f4f74946-4546-44bd-a073-9ea6f9fe78cb}", 0, 0)
|
|
124
|
+
_reg_clsid_ = comtypes.GUID("{fa9de8f4-20de-45fc-b079-648572428817}")
|
|
125
|
+
|
|
126
|
+
################
|
|
127
|
+
# definition
|
|
128
|
+
itf.add(
|
|
129
|
+
"""[id(100), propget] HRESULT Name([out, retval] BSTR *pname);
|
|
130
|
+
[id(100), propput] HRESULT Name([in] BSTR name);"""
|
|
131
|
+
)
|
|
132
|
+
# implementation
|
|
133
|
+
Name = "foo"
|
|
134
|
+
|
|
135
|
+
# test
|
|
136
|
+
def test_Name(self):
|
|
137
|
+
p = wrap(self.create())
|
|
138
|
+
self.assertEqual((p.Name, p.name, p.nAME), ("foo",) * 3)
|
|
139
|
+
p.NAME = "spam"
|
|
140
|
+
self.assertEqual((p.Name, p.name, p.nAME), ("spam",) * 3)
|
|
141
|
+
|
|
142
|
+
################
|
|
143
|
+
# definition
|
|
144
|
+
itf.add(
|
|
145
|
+
"[id(101)] HRESULT MixedInOut([in] int a, [out] int *b, [in] int c, [out] int *d);"
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
# implementation
|
|
149
|
+
def MixedInOut(self, a, c):
|
|
150
|
+
return a + 1, c + 1
|
|
151
|
+
|
|
152
|
+
# test
|
|
153
|
+
def test_MixedInOut(self):
|
|
154
|
+
p = wrap(self.create())
|
|
155
|
+
self.assertEqual(p.MixedInOut(1, 2), (2, 3))
|
|
156
|
+
|
|
157
|
+
################
|
|
158
|
+
# definition
|
|
159
|
+
itf.add("[id(102)] HRESULT MultiInOutArgs([in, out] int *pa, [in, out] int *pb);")
|
|
160
|
+
|
|
161
|
+
# implementation
|
|
162
|
+
def MultiInOutArgs(self, pa, pb):
|
|
163
|
+
return pa[0] * 3, pb[0] * 4
|
|
164
|
+
|
|
165
|
+
# test
|
|
166
|
+
def test_MultiInOutArgs(self):
|
|
167
|
+
p = wrap(self.create())
|
|
168
|
+
self.assertEqual(p.MultiInOutArgs(1, 2), (3, 8))
|
|
169
|
+
|
|
170
|
+
################
|
|
171
|
+
# definition
|
|
172
|
+
itf.add("HRESULT MultiInOutArgs2([in, out] int *pa, [out] int *pb);")
|
|
173
|
+
## # implementation
|
|
174
|
+
## def MultiInOutArgs2(self, pa):
|
|
175
|
+
## return pa[0] * 3, pa[0] * 4
|
|
176
|
+
## # test
|
|
177
|
+
## def test_MultiInOutArgs2(self):
|
|
178
|
+
## p = wrap(self.create())
|
|
179
|
+
## self.assertEqual(p.MultiInOutArgs2(42), (126, 168))
|
|
180
|
+
|
|
181
|
+
################
|
|
182
|
+
# definition
|
|
183
|
+
itf.add("HRESULT MultiInOutArgs3([out] int *pa, [out] int *pb);")
|
|
184
|
+
|
|
185
|
+
# implementation
|
|
186
|
+
def MultiInOutArgs3(self):
|
|
187
|
+
return 42, 43
|
|
188
|
+
|
|
189
|
+
# test
|
|
190
|
+
def test_MultiInOutArgs3(self):
|
|
191
|
+
p = wrap(self.create())
|
|
192
|
+
self.assertEqual(p.MultiInOutArgs3(), (42, 43))
|
|
193
|
+
|
|
194
|
+
################
|
|
195
|
+
# definition
|
|
196
|
+
itf.add("HRESULT MultiInOutArgs4([out] int *pa, [in, out] int *pb);")
|
|
197
|
+
|
|
198
|
+
# implementation
|
|
199
|
+
def MultiInOutArgs4(self, pb):
|
|
200
|
+
return pb[0] + 3, pb[0] + 4
|
|
201
|
+
|
|
202
|
+
# test
|
|
203
|
+
def test_MultiInOutArgs4(self):
|
|
204
|
+
p = wrap(self.create())
|
|
205
|
+
res = p.MultiInOutArgs4(pb=32)
|
|
206
|
+
|
|
207
|
+
## print "MultiInOutArgs4", res
|
|
208
|
+
|
|
209
|
+
itf.add(
|
|
210
|
+
"""HRESULT GetStackTrace([in] ULONG FrameOffset,
|
|
211
|
+
[in, out] INT *Frames,
|
|
212
|
+
[in] ULONG FramesSize,
|
|
213
|
+
[out, optional] ULONG *FramesFilled);"""
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
def GetStackTrace(self, this, *args):
|
|
217
|
+
## print "GetStackTrace", args
|
|
218
|
+
return 0
|
|
219
|
+
|
|
220
|
+
def test_GetStackTrace(self):
|
|
221
|
+
p = wrap(self.create())
|
|
222
|
+
from ctypes import POINTER, c_int, pointer
|
|
223
|
+
|
|
224
|
+
frames = (c_int * 5)()
|
|
225
|
+
res = p.GetStackTrace(42, frames, 5)
|
|
226
|
+
## print "RES_1", res
|
|
227
|
+
|
|
228
|
+
frames = pointer(c_int(5))
|
|
229
|
+
res = p.GetStackTrace(42, frames, 0)
|
|
230
|
+
|
|
231
|
+
## print "RES_2", res
|
|
232
|
+
|
|
233
|
+
# It is unlear to me if this is allowed or not. Apparently there
|
|
234
|
+
# are typelibs that define such an argument type, but it may be
|
|
235
|
+
# that these are buggy.
|
|
236
|
+
#
|
|
237
|
+
# Point is that SafeArrayCreateEx(VT_VARIANT|VT_BYREF, ..) fails.
|
|
238
|
+
# The MSDN docs for SafeArrayCreate() have a notice that neither
|
|
239
|
+
# VT_ARRAY not VT_BYREF may be set, this notice is missing however
|
|
240
|
+
# for SafeArrayCreateEx().
|
|
241
|
+
#
|
|
242
|
+
# We have this code here to make sure that comtypes can import
|
|
243
|
+
# such a typelib, although calling ths method will fail because
|
|
244
|
+
# such an array cannot be created.
|
|
245
|
+
itf.add("""HRESULT dummy([in] SAFEARRAY(VARIANT *) foo);""")
|
|
246
|
+
|
|
247
|
+
# Test events.
|
|
248
|
+
itf.add("""HRESULT DoSomething();""")
|
|
249
|
+
outgoing.add("""[id(103)] HRESULT OnSomething();""")
|
|
250
|
+
|
|
251
|
+
# implementation
|
|
252
|
+
def DoSomething(self):
|
|
253
|
+
"Implement the DoSomething method"
|
|
254
|
+
self.Fire_Event(0, "OnSomething")
|
|
255
|
+
|
|
256
|
+
# test
|
|
257
|
+
def test_events(self):
|
|
258
|
+
p = wrap(self.create())
|
|
259
|
+
|
|
260
|
+
class Handler(object):
|
|
261
|
+
called = 0
|
|
262
|
+
|
|
263
|
+
def OnSomething(self, this):
|
|
264
|
+
"Handles the OnSomething event"
|
|
265
|
+
self.called += 1
|
|
266
|
+
|
|
267
|
+
handler = Handler()
|
|
268
|
+
ev = comtypes.client.GetEvents(p, handler)
|
|
269
|
+
p.DoSomething()
|
|
270
|
+
self.assertEqual(handler.called, 1)
|
|
271
|
+
|
|
272
|
+
class Handler(object):
|
|
273
|
+
called = 0
|
|
274
|
+
|
|
275
|
+
def IMyEventInterface_OnSomething(self):
|
|
276
|
+
"Handles the OnSomething event"
|
|
277
|
+
self.called += 1
|
|
278
|
+
|
|
279
|
+
handler = Handler()
|
|
280
|
+
ev = comtypes.client.GetEvents(p, handler)
|
|
281
|
+
p.DoSomething()
|
|
282
|
+
self.assertEqual(handler.called, 1)
|
|
283
|
+
|
|
284
|
+
# events with out-parameters (these are probably very unlikely...)
|
|
285
|
+
itf.add("""HRESULT DoSomethingElse();""")
|
|
286
|
+
outgoing.add("""[id(104)] HRESULT OnSomethingElse([out, retval] int *px);""")
|
|
287
|
+
|
|
288
|
+
def DoSomethingElse(self):
|
|
289
|
+
"Implement the DoSomething method"
|
|
290
|
+
self.Fire_Event(0, "OnSomethingElse")
|
|
291
|
+
|
|
292
|
+
def test_DoSomethingElse(self):
|
|
293
|
+
p = wrap(self.create())
|
|
294
|
+
|
|
295
|
+
class Handler(object):
|
|
296
|
+
called = 0
|
|
297
|
+
|
|
298
|
+
def OnSomethingElse(self):
|
|
299
|
+
"Handles the OnSomething event"
|
|
300
|
+
self.called += 1
|
|
301
|
+
return 42
|
|
302
|
+
|
|
303
|
+
handler = Handler()
|
|
304
|
+
ev = comtypes.client.GetEvents(p, handler)
|
|
305
|
+
p.DoSomethingElse()
|
|
306
|
+
self.assertEqual(handler.called, 1)
|
|
307
|
+
|
|
308
|
+
class Handler(object):
|
|
309
|
+
called = 0
|
|
310
|
+
|
|
311
|
+
def OnSomethingElse(self, this, presult):
|
|
312
|
+
"Handles the OnSomething event"
|
|
313
|
+
self.called += 1
|
|
314
|
+
presult[0] = 42
|
|
315
|
+
|
|
316
|
+
handler = Handler()
|
|
317
|
+
ev = comtypes.client.GetEvents(p, handler)
|
|
318
|
+
p.DoSomethingElse()
|
|
319
|
+
self.assertEqual(handler.called, 1)
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
################################################################
|
|
323
|
+
|
|
324
|
+
path = tlb.compile()
|
|
325
|
+
from comtypes.connectionpoints import IConnectionPointContainer
|
|
326
|
+
from comtypes.gen import TestLib
|
|
327
|
+
from comtypes.typeinfo import IProvideClassInfo, IProvideClassInfo2
|
|
328
|
+
|
|
329
|
+
MyServer._com_interfaces_ = [
|
|
330
|
+
TestLib.IMyInterface,
|
|
331
|
+
IProvideClassInfo2,
|
|
332
|
+
IConnectionPointContainer,
|
|
333
|
+
]
|
|
334
|
+
MyServer._outgoing_interfaces_ = [TestLib.IMyEventInterface]
|
|
335
|
+
|
|
336
|
+
################################################################
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
class Test(unittest.TestCase, MyServer):
|
|
340
|
+
def __init__(self, *args):
|
|
341
|
+
unittest.TestCase.__init__(self, *args)
|
|
342
|
+
MyServer.__init__(self)
|
|
343
|
+
|
|
344
|
+
def create(self):
|
|
345
|
+
obj = MyServer()
|
|
346
|
+
return obj.QueryInterface(comtypes.IUnknown)
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
if __name__ == "__main__":
|
|
350
|
+
unittest.main()
|