win32com: Setting ByRef parameters in an event
Paul Moore
paul.moore at uk.origin-it.com
Fri Aug 24 09:18:04 EDT 2001
On Fri, 17 Aug 2001 01:32:46 +0200, Mark Hammond <MarkH at ActiveState.com>
wrote:
>Paul Moore wrote:
>>> import win32com.client
>>>
>>> class wexEvents:
>>> def OnTick(self, Remaining, WakeUp):
>>> print "Tick...", Remaining
>>> return -1
>>>
>>> wex = win32com.client.DispatchWithEvents("WshToolbox.WScriptEx",
>>> wexEvents)
>>>
>>> wex.Sleep(10000,1000)
>>>
>>>But this doesn't seem to work!
>
>It should :( The Excel etc demos all work fine with very similar
>constructs. You could try:
>
> return 1==1
>
>which due to an implementation detail will ensure that a VT_BOOL is
>returned - however, this should not be necessary.
>
>So no real clue I am afraid :( If I could repro the error, I could
>probably determine the problem.
Right, I've got it sorted. There are two separate issues:
1. The component was explicitly checking for VT_BOOL, rather than converting
whatever is sent. This is a component bug (and will be fixed). Using 1==1 to
force a VT_BYREF fixes this problem, but it would be nice to have a way (a
PyVARIANT type?) of explicitly passing a specific variant type.
2. The event handler needs *two* values returning. The first is sent to the
"result" of the IDispatch->Invoke() call, and the remaining are used to set
the ByRef parameters from the call. [This is in the source file
PyWin32\com\win32com\src\PyGatewayBase.cpp in function invoke_finish]
The problem with issue (2) is that it doesn't seem consistent - Mark comments
that the Excel tests work. I assume that this is because Excel's Connection
Point implementation passes a NULL for the pVarResult parameter of the
Invoke() method. However, ATL-generated COM objects pass a non-NULL
pVarResult, and use its scode (without checking for a type of VT_ERROR!) for
the HRESULT from the Fire_<event> call. [You can see this by generating a
trivial ATL project with an object implementing connection point support].
The big issue is that *no-one* is going to document this difference in
behaviour, so users are left with guesswork as the only way to know whether to
return an extra initial result.
I believe that win32com should ideally handle event methods specially, and
*ignore* the pVarResult for such methods (after all, events will always be
"logically" void procedures). The problem is that I can't see how it might be
possible, this far down in the infrastructure, to determine whether
PyGatewayBase::Invoke is being called from an event handler or a normal method
:-(
In the meantime, at least I have a workaround...
Phew!
Paul.
More information about the Python-list
mailing list