From 9880f6b43cb5475f7c4917fd88d067969b9ef380 Mon Sep 17 00:00:00 2001 From: Jun Komoda <45822440+junkmd@users.noreply.github.com> Date: Tue, 28 May 2024 09:09:35 +0000 Subject: [PATCH] add --- comtypes/automation.py | 23 +++++++++++------------ comtypes/hints.pyi | 13 ++++++++++++- comtypes/typeinfo.py | 5 +++++ 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/comtypes/automation.py b/comtypes/automation.py index 664caa31..9875bb99 100644 --- a/comtypes/automation.py +++ b/comtypes/automation.py @@ -347,10 +347,7 @@ def _set_value(self, value): memmove(byref(self._), byref(obj), sizeof(obj)) self.vt = VT_ARRAY | obj._vartype_ elif isinstance(value, Structure) and hasattr(value, "_recordinfo_"): - guids = value._recordinfo_ - from comtypes.typeinfo import GetRecordInfoFromGuids - - ri = GetRecordInfoFromGuids(*guids) + ri = _get_recordinfo(value) # type: ignore self.vt = VT_RECORD # Assigning a COM pointer to a structure field does NOT # call AddRef(), have to call it manually: @@ -394,10 +391,7 @@ def _set_value(self, value): self._.c_void_p = addressof(ref) self.__keepref = value if isinstance(ref, Structure) and hasattr(ref, "_recordinfo_"): - guids = ref._recordinfo_ - from comtypes.typeinfo import GetRecordInfoFromGuids - - ri = GetRecordInfoFromGuids(*guids) + ri = _get_recordinfo(ref) # type: ignore self.vt = VT_RECORD | VT_BYREF # Assigning a COM pointer to a structure field does NOT # call AddRef(), have to call it manually: @@ -411,10 +405,7 @@ def _set_value(self, value): self._.c_void_p = addressof(ref) self.__keepref = value if isinstance(ref, Structure) and hasattr(ref, "_recordinfo_"): - guids = ref._recordinfo_ - from comtypes.typeinfo import GetRecordInfoFromGuids - - ri = GetRecordInfoFromGuids(*guids) + ri = _get_recordinfo(ref) # type: ignore self.vt = VT_RECORD | VT_BYREF # Assigning a COM pointer to a structure field does NOT # call AddRef(), have to call it manually: @@ -603,6 +594,14 @@ def ChangeType(self, typecode): del v _carg_obj = type(byref(c_int())) + + +def _get_recordinfo(struct: "hints.HasSinderRecordInfo") -> "hints.IRecordInfo": + from comtypes.typeinfo import GetRecordInfoFromGuids + + return GetRecordInfoFromGuids(*struct._recordinfo_) + + from ctypes import Array as _CArrayType diff --git a/comtypes/hints.pyi b/comtypes/hints.pyi index b0315822..ee39d970 100644 --- a/comtypes/hints.pyi +++ b/comtypes/hints.pyi @@ -39,7 +39,7 @@ else: import comtypes from comtypes.automation import IDispatch as IDispatch, VARIANT as VARIANT from comtypes.server import IClassFactory as IClassFactory -from comtypes.typeinfo import ITypeInfo as ITypeInfo +from comtypes.typeinfo import ITypeInfo as ITypeInfo, IRecordInfo as IRecordInfo Incomplete: TypeAlias = Any """The type symbol is used temporarily until the COM library parsers or @@ -61,6 +61,17 @@ class FirstComItfOf(Generic[_T_coclass]): as an argument. """ +class HasSinderRecordInfo(Protocol): + _recordinfo_: Tuple[str, int, int, int, str] + """ + A fixed-length array composed of five elements: + - Type library GUID string + - Major version number of the type library + - Minor version number of the type library + - Language code ID number + - Type information GUID string + """ + class _MethodTypeDesc(Protocol): arguments: List[Tuple[Any, str, List[str], Optional[Any]]] idlflags: List[str] diff --git a/comtypes/typeinfo.py b/comtypes/typeinfo.py index 2313f1cb..9e239dad 100644 --- a/comtypes/typeinfo.py +++ b/comtypes/typeinfo.py @@ -500,6 +500,11 @@ def GetFieldNames(self, *args: Any) -> List[Optional[str]]: # XXX Should SysFreeString the array contents. How to? return result + if TYPE_CHECKING: + + def RecordCreateCopy(self, pvSource: Any) -> Optional[int]: + ... + IRecordInfo._methods_ = [ COMMETHOD([], HRESULT, "RecordInit", (["in"], c_void_p, "pvNew")),