Update of /cvsroot/pywin32/pywin32/com/TestSources/PyCOMTest
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7696/com/TestSources/PyCOMTest
Modified Files:
PyCOMImpl.cpp PyCOMImpl.h PyCOMTest.idl
Log Message:
Much better support for 'named params' in Python gateways. Fixes
[ 1648655 ] Wrong args order with event handler
Index: PyCOMTest.idl
===================================================================
RCS file: /cvsroot/pywin32/pywin32/com/TestSources/PyCOMTest/PyCOMTest.idl,v
retrieving revision 1.15
retrieving revision 1.16
diff -C2 -d -r1.15 -r1.16
*** PyCOMTest.idl 11 Feb 2007 12:39:05 -0000 1.15
--- PyCOMTest.idl 4 Sep 2007 10:53:29 -0000 1.16
***************
*** 294,297 ****
--- 294,298 ----
import "oaidl.idl";
HRESULT Fire([in]long nID);
+ HRESULT FireWithNamedParams([in]long nID, [in]QsBoolean b, [in, out]int *outVal, [in, out]int *outVal2);
};
[
Index: PyCOMImpl.h
===================================================================
RCS file: /cvsroot/pywin32/pywin32/com/TestSources/PyCOMTest/PyCOMImpl.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -d -r1.14 -r1.15
*** PyCOMImpl.h 11 Feb 2007 12:39:05 -0000 1.14
--- PyCOMImpl.h 4 Sep 2007 10:53:29 -0000 1.15
***************
*** 85,88 ****
--- 85,89 ----
// method to broadcast a call on the current connections
STDMETHOD(Fire)(long nID);
+ STDMETHOD(FireWithNamedParams)(long nID, QsBoolean b, int *outVal1, int *outVal2);
STDMETHOD(TestOptionals)(BSTR strArg, short sarg, long larg, double darg, SAFEARRAY **pRet);
STDMETHOD(TestOptionals2)(double dval, BSTR strval, short sval, SAFEARRAY **pRet);
Index: PyCOMImpl.cpp
===================================================================
RCS file: /cvsroot/pywin32/pywin32/com/TestSources/PyCOMTest/PyCOMImpl.cpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -C2 -d -r1.15 -r1.16
*** PyCOMImpl.cpp 11 Feb 2007 12:39:05 -0000 1.15
--- PyCOMImpl.cpp 4 Sep 2007 10:53:29 -0000 1.16
***************
*** 323,328 ****
*counter = new CCounter();
- (*counter)->AddRef();
if (*counter==NULL) return E_OUTOFMEMORY;
return S_OK;
}
--- 323,328 ----
*counter = new CCounter();
if (*counter==NULL) return E_OUTOFMEMORY;
+ (*counter)->AddRef();
return S_OK;
}
***************
*** 361,365 ****
CComVariant v(nID);
DISPPARAMS params = { &v, NULL, 1, 0 };
! pEvent->Invoke(dispid, IID_NULL, 0, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL);
}
// IPyCOMTestEvent* pIEvent = (IPyCOMTestEvent*)*pp;
--- 361,476 ----
CComVariant v(nID);
DISPPARAMS params = { &v, NULL, 1, 0 };
! hr = pEvent->Invoke(dispid, IID_NULL, 0, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL);
! }
! if (FAILED(hr))
! break;
! // call FireWithNamedParams a variety of ways.
! // See http://msdn2.microsoft.com/en-us/library/ms221653.aspx
! // "Passing Parameters (Component Automation)" for details.
!
! OLECHAR *names2[] = { L"OnFireWithNamedParams" };
! hr = pEvent->GetIDsOfNames(IID_NULL, names2, 1, 0, &dispid);
! if (SUCCEEDED(hr)) {
! // First call without named params - order is reversed
! // (ie, last in array is first presented to Python.)
! LONG out_result1 = nID+1;
! LONG out_result2 = nID+2;
! CComVariant v[4];
! // the "out2" outVal;
! V_VT(&v[0]) = VT_I4 | VT_BYREF;
! v[0].plVal = &out_result2;
! // the "out1" outVal;
! V_VT(&v[1]) = VT_I4 | VT_BYREF;
! v[1].plVal = &out_result1;
! // the bool
! v[2] = VARIANT_TRUE; // the bool
! V_VT(&v[2]) = VT_BOOL;
! // the first param.
! v[3] = nID;
! DISPPARAMS params = { v, NULL, 4, 0 };
! hr = pEvent->Invoke(dispid, IID_NULL, 0, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL);
! // all known impls return these values in the out pointer.
! _ASSERTE(out_result1==nID+3);
! _ASSERTE(out_result2==nID+4);
! }
! // Now with various combinations of named args. Like Python, this
! // assumes that param DISPIDs start with zero, are sequential and
! // in the same order as the IDL signature.
! if (SUCCEEDED(hr)) {
! // Call again - this time with named params.
! LONG out_result1 = nID+1;
! LONG out_result2 = nID+2;
! CComVariant v[4];
!
! // the "out2" outVal;
! V_VT(&v[3]) = VT_I4 | VT_BYREF;
! v[3].plVal = &out_result2;
! // the "out1" outVal;
! V_VT(&v[2]) = VT_I4 | VT_BYREF;
! v[2].plVal = &out_result1;
! // the bool
! v[1] = VARIANT_TRUE; // the bool
! V_VT(&v[1]) = VT_BOOL;
! // the first param.
! v[0] = nID;
! // Build 210 and earlier, this was the only way params *could* be passed,
! // which happily was the same way MSOffice did it.
! DISPID namedIDs[4] = {0, 1, 2, 3};
! DISPPARAMS params = { v, namedIDs, 4, 4 };
! hr = pEvent->Invoke(dispid, IID_NULL, 0, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL);
! // all known impls return nID+1 in the out pointer.
! _ASSERTE(out_result1==nID+3);
! _ASSERTE(out_result2==nID+4);
! }
! // Try some other funky combinations to mess with Python :)
! if (SUCCEEDED(hr)) {
! // First 2 positional, 2nd 2 by name.
! LONG out_result1 = nID+1;
! LONG out_result2 = nID+2;
!
! CComVariant v[4];
! // the first param.
! v[3] = nID;
! // 2nd positional
! v[2] = VARIANT_TRUE; // the bool
! V_VT(&v[2]) = VT_BOOL;
! // named ones up front.
!
! // the "out2" outVal (dispid=3)
! V_VT(&v[1]) = VT_I4 | VT_BYREF;
! v[1].plVal = &out_result2;
! // the "out1" outVal (dispid=2)
! V_VT(&v[0]) = VT_I4 | VT_BYREF;
! v[0].plVal = &out_result1;
!
! DISPID namedIDs[2] = {2, 3};
! DISPPARAMS params = { v, namedIDs, 4, 2 };
! hr = pEvent->Invoke(dispid, IID_NULL, 0, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL);
! // all known impls return nID+1 in the out pointer.
! _ASSERTE(out_result1==nID+3);
! _ASSERTE(out_result2==nID+4);
! }
!
! if (SUCCEEDED(hr)) {
! // Only pass the 2 out params - Python must ensure earlier
! // ones are also passed.
! LONG out_result1 = nID+1;
! LONG out_result2 = nID+2;
!
! CComVariant v[4];
! // the "out2" outVal (dispid=3)
! V_VT(&v[0]) = VT_I4 | VT_BYREF;
! v[0].plVal = &out_result2;
! // the "out1" outVal (dispid=2)
! V_VT(&v[1]) = VT_I4 | VT_BYREF;
! v[1].plVal = &out_result1;
!
! DISPID namedIDs[2] = {3, 2};
! DISPPARAMS params = { v, namedIDs, 2, 2 };
!
! hr = pEvent->Invoke(dispid, IID_NULL, 0, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL);
! // all known impls return nID+1 in the out pointer.
! _ASSERTE(out_result1==nID+3);
! _ASSERTE(out_result2==nID+4);
}
// IPyCOMTestEvent* pIEvent = (IPyCOMTestEvent*)*pp;
***************
*** 369,375 ****
--- 480,497 ----
}
Unlock();
+ _ASSERTE(SUCCEEDED(hr));
return hr;
}
+ HRESULT CPyCOMTest::FireWithNamedParams(long nID, VARIANT_BOOL b, int *outVal1, int *outVal2)
+ {
+ _ASSERTE(b==VARIANT_TRUE);
+ _ASSERTE(nID+1==*outVal1);
+ _ASSERTE(nID+2==*outVal2);
+ *outVal1 = (int)nID+3;
+ *outVal2 = (int)nID+4;
+ return S_OK;
+ }
+
HRESULT CPyCOMTest::TestOptionals(BSTR strArg, short sarg, long larg, double darg, SAFEARRAY **pRet)
{
|