diff --git a/comtypes/test/test_typeinfo.py b/comtypes/test/test_typeinfo.py index 7be16de9..76f25bbb 100644 --- a/comtypes/test/test_typeinfo.py +++ b/comtypes/test/test_typeinfo.py @@ -2,13 +2,11 @@ import os import sys import unittest +from _ctypes import COMError from ctypes.wintypes import MAX_PATH -import comtypes.hresult -from comtypes import GUID, COMError +from comtypes import GUID, hresult, typeinfo from comtypes.typeinfo import ( - TKIND_DISPATCH, - TKIND_INTERFACE, GetModuleFileName, LoadRegTypeLib, LoadTypeLibEx, @@ -69,7 +67,7 @@ def test_TypeInfo(self): c_tlib, c_index = ti.GetContainingTypeLib() self.assert_tlibattr_equal(c_tlib, tlib) self.assertEqual(c_index, index) - if ta.typekind in (TKIND_INTERFACE, TKIND_DISPATCH): + if ta.typekind in (typeinfo.TKIND_INTERFACE, typeinfo.TKIND_DISPATCH): if ta.cImplTypes: href = ti.GetRefTypeOfImplType(0) base = ti.GetRefTypeInfo(href) @@ -87,7 +85,7 @@ def test_TypeInfo(self): guid_null = GUID() with self.assertRaises(COMError) as cm: tlib.GetTypeInfoOfGuid(guid_null) - self.assertEqual(comtypes.hresult.TYPE_E_ELEMENTNOTFOUND, cm.exception.hresult) + self.assertEqual(hresult.TYPE_E_ELEMENTNOTFOUND, cm.exception.hresult) IID_IFile = GUID("{C7C3F5A4-88A3-11D0-ABCB-00A0C90FFFC0}") ti = tlib.GetTypeInfoOfGuid(IID_IFile) @@ -97,6 +95,42 @@ def test_TypeInfo(self): self.assertEqual(c_ti, ti) self.assertEqual(IID_IFile, ti.GetTypeAttr().guid) + def test_pure_dispatch_ITypeInfo(self): + tlib = LoadTypeLibEx("msi.dll") + IID_Installer = GUID("{000C1090-0000-0000-C000-000000000046}") + ti = tlib.GetTypeInfoOfGuid(IID_Installer) + ta = ti.GetTypeAttr() + self.assertEqual(ta.typekind, typeinfo.TKIND_DISPATCH) + with self.assertRaises(COMError) as cm: + ti.GetRefTypeOfImplType(-1) + self.assertEqual(hresult.TYPE_E_ELEMENTNOTFOUND, cm.exception.hresult) + self.assertFalse(ti.GetTypeAttr().wTypeFlags & typeinfo.TYPEFLAG_FDUAL) + + def test_custom_interface_ITypeInfo(self): + tlib = LoadTypeLibEx("UIAutomationCore.dll") + IID_IUIAutomation = GUID("{30CBE57D-D9D0-452A-AB13-7AC5AC4825EE}") + ti = tlib.GetTypeInfoOfGuid(IID_IUIAutomation) + ta = ti.GetTypeAttr() + self.assertEqual(ta.typekind, typeinfo.TKIND_INTERFACE) + with self.assertRaises(COMError) as cm: + ti.GetRefTypeOfImplType(-1) + self.assertEqual(hresult.TYPE_E_ELEMENTNOTFOUND, cm.exception.hresult) + self.assertFalse(ti.GetTypeAttr().wTypeFlags & typeinfo.TYPEFLAG_FDUAL) + + def test_dual_interface_ITypeInfo(self): + tlib = LoadTypeLibEx("scrrun.dll") + IID_IDictionary = GUID("{42C642C1-97E1-11CF-978F-00A02463E06F}") + ti = tlib.GetTypeInfoOfGuid(IID_IDictionary) + ta = ti.GetTypeAttr() + self.assertEqual(ta.typekind, typeinfo.TKIND_DISPATCH) + self.assertTrue(ta.wTypeFlags & typeinfo.TYPEFLAG_FDUAL) + refti = ti.GetRefTypeInfo(ti.GetRefTypeOfImplType(-1)) + refta = refti.GetTypeAttr() + self.assertEqual(IID_IDictionary, refti.GetTypeAttr().guid) + self.assertTrue(refta.wTypeFlags & typeinfo.TYPEFLAG_FDUAL) + self.assertEqual(refta.typekind, typeinfo.TKIND_INTERFACE) + self.assertEqual(ti, refti.GetRefTypeInfo(refti.GetRefTypeOfImplType(-1))) + class Test_GetModuleFileName(unittest.TestCase): @unittest.skipUnless( diff --git a/comtypes/tools/tlbparser.py b/comtypes/tools/tlbparser.py index ef400bb8..cad940d7 100644 --- a/comtypes/tools/tlbparser.py +++ b/comtypes/tools/tlbparser.py @@ -624,6 +624,7 @@ def parse_typeinfo(self, tinfo: typeinfo.ITypeInfo) -> Any: try: # GetRefTypeOfImplType(-1) returns the custom portion # of a dispinterface, if it is dual + # See https://learn.microsoft.com/en-us/windows/win32/api/oaidl/nf-oaidl-itypeinfo-getreftypeofimpltype#remarks href = tinfo.GetRefTypeOfImplType(-1) except COMError: # no dual interface