comtypes
comtypes copied to clipboard
Error setting a value on VARIANT out param
Some VARIANT
out params are not initialised before being passed to a callback, setting these to a value results in WindowsError: [Error -2147352568] Bad variable type
because comtypes attempts to clear the variant before setting the value.
Our situation:
- Setting up an
accPropServer
, with methodGetPropValue
- the
VARIANT
out parampVarValue
has not been initialised (at least on my version of Windows Version1903
Build18362.239
). - Setting a value on this
VARIANT
results inautomation.py
calling_VariantClear
prior to setting the value. This leads to the "bad variable type" error and then also the issue fixed with https://github.com/enthought/comtypes/pull/187. - When using a high level callback function, returning the out params, there is no way to initialise the out params before setting a value.
We have worked around this issue with https://github.com/nvaccess/nvda/pull/9900
Our work around is to use a low level callback, and initialise the out param VARIANT
before assigning a value. Note this is what the Microsoft sample does.
Setting the accPropServer:
from IAccessibleHandler import accPropServices
accPropServices.SetHwndPropServer(
hwnd=self.hwnd,
idObject=winUser.OBJID_CLIENT,
idChild=0,
paProps=self.properties_GUIDPTR,
cProps=len(self.properties_GUIDPTR),
pServer=self,
AnnoScope=ANNO_CONTAINER if annotateChildren else ANNO_THIS
)
Initialise the VARIANT
before setting a value in the GetPropValue
.
def GetPropValue(
self, this, # unused "this" used to indicate to comTypes we want a low level implementation
pIDString: str,
dwIDStringLen: int,
idProp: GUID,
pvarValue: POINTER(VARIANT),
pfGotProp: POINTER(BOOL)
) -> int:
try:
# Preset values for "no prop value", in case we return early.
pfGotProp.contents.value = self.DOES_NOT_HAVE_PROP
_VariantInit(pvarValue)
To fix this in comtypes, inspect the code in _comobjec.py
in functions hack
, call_with_this
, and call_without_this
. Out params of type VARIANT
should be initialised with _VariantInit
. Note: inout params should not be initialised, as it is expected that they contain valid arguments.