diff options
Diffstat (limited to 'private/oleauto/tests/disptest')
34 files changed, 11483 insertions, 0 deletions
diff --git a/private/oleauto/tests/disptest/cbind.cpp b/private/oleauto/tests/disptest/cbind.cpp new file mode 100644 index 000000000..6b5a611cd --- /dev/null +++ b/private/oleauto/tests/disptest/cbind.cpp @@ -0,0 +1,393 @@ +/*** +*cbind.cpp +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* This file implements the CBindSuite test object. +* +*Revision History: +* +* [00] 11-Nov-92 bradlo: Created. +* +*Implementation Notes: +* +*****************************************************************************/ + +#include "disptest.h" +#include "tstsuite.h" +#include "clsid.h" + + +extern OLECHAR FAR* g_szCSArray; +extern OLECHAR FAR* g_szCDispTst; + +struct TEST { + HRESULT (*pfnTest)(void); + OLECHAR FAR* szName; +}; + +HRESULT BindTest1(); +HRESULT BindTest2(); +HRESULT BindTest3(); +HRESULT GetObject1(); +HRESULT GetObject2(); +HRESULT GetObject3(); + +static TEST rgtest[] = { + { BindTest1, OLESTR("binding test #1") } + , { BindTest2, OLESTR("binding test #2") } + , { BindTest3, OLESTR("binding test #3") } + , { GetObject1, OLESTR("GetObject test #1") } + , { GetObject2, OLESTR("GetObject test #2") } + , { GetObject3, OLESTR("GetObject test #3") } +}; + + +SUITE_CONSTRUCTION_IMPL(CBindSuite) + +SUITE_IUNKNOWN_IMPL(CBindSuite) + + +//--------------------------------------------------------------------- +// ITestSuite Methods +//--------------------------------------------------------------------- + + +STDMETHODIMP +CBindSuite::GetNameOfSuite(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("Object binding"), pbstr); +} + +STDMETHODIMP +CBindSuite::GetNameOfLogfile(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("bind.log"), pbstr); +} + +STDMETHODIMP +CBindSuite::GetTestCount(unsigned int FAR* pcTests) +{ + *pcTests = DIM(rgtest); + + return NOERROR; +} + +STDMETHODIMP +CBindSuite::GetNameOfTest(unsigned int iTest, BSTR FAR* pbstr) +{ + if(iTest >= DIM(rgtest)) + return RESULT(E_INVALIDARG); + + return ErrBstrAlloc(rgtest[iTest].szName, pbstr); +} + +/*** +*HRESULT CBindSuite::DoTest(unsigned int) +*Purpose: +* Execute a single CBindSuite test. +* +*Entry: +* iTest = the index of the test to execute +* +*Exit: +* return value = HRESULT +* +***********************************************************************/ +STDMETHODIMP +CBindSuite::DoTest(unsigned int iTest) +{ + if(iTest >= DIM(rgtest)) + return RESULT(E_INVALIDARG); + + return rgtest[iTest].pfnTest(); +} + +// Create and isntance of our test and sample objects, QI them to +// IDispatch, and then immediately release. +// +HRESULT +BindTest1() +{ + IUnknown FAR* punk; + IDispatch FAR* pdisp; + +static struct { + const CLSID FAR* pclsid; + char FAR* psz; +} rg[] = { +#define DAT(X) {&X, #X} + DAT(CLSID_CPoly) + , DAT(CLSID_CPoly2) + , DAT(CLSID_CCalc) + , DAT(CLSID_SDispTst_CDispTst) +#undef DAT +}; + + for(int i = 0; i < DIM(rg); ++i){ + DbPrintf("CoCreateInstance(%s)\n", rg[i].psz); + IfFailRet( + CoCreateInstance( + *rg[i].pclsid, + NULL, CLSCTX_LOCAL_SERVER, IID_IUnknown, (void FAR* FAR*)&punk)); + DbPrintf(" QueryInterface(IID_IDispatch)\n"); + IfFailRet(punk->QueryInterface(IID_IDispatch, (void FAR* FAR*)&pdisp)); + pdisp->Release(); + punk->Release(); + } + return NOERROR; +} + +// bind to a new instance of the sdisptst application object, and +// dump its typeinfos. + +HRESULT +BindTest2() +{ + unsigned int u, ctinfo; + HRESULT hresult; + IDispatch FAR* pdisp; + ITypeInfo FAR* ptinfo; + + IfFailGo(CreateObject(OLESTR("sdisptst.application"), &pdisp), LError0); + + IfFailGo(pdisp->GetTypeInfoCount(&ctinfo), LError1); + + for(u = 0; u < ctinfo; ++u){ + IfFailGo(pdisp->GetTypeInfo(u, 0, &ptinfo), LError1); + + // dump the type info + PrTi(ptinfo); + ptinfo->Release(); + } + +LError1:; + pdisp->Release(); + +LError0:; + return hresult; +} + +// same as BindTest2 - but dump the typeinfo for dspcalc2. +// +HRESULT +BindTest3() +{ + unsigned int u, ctinfo; + HRESULT hresult; + IDispatch FAR* pdisp; + ITypeInfo FAR* ptinfo; + + IfFailGo(CreateObject(OLESTR("Dspcalc2.Application"), &pdisp), LError0); + + IfFailGo(pdisp->GetTypeInfoCount(&ctinfo), LError1); + + for(u = 0; u < ctinfo; ++u){ + IfFailGo(pdisp->GetTypeInfo(u, 0, &ptinfo), LError1); + + // dump the type info + PrTi(ptinfo); + ptinfo->Release(); + } + +LError1:; + pdisp->Release(); + +LError0:; + return hresult; +} + +// Test GetActiveObject() +HRESULT +GetObject1() +{ + HRESULT hresult; + IUnknown FAR* punk; + IDispatch FAR* pdispApp; + IDispatch FAR* pdispCDispTst; + + VARIANT varResult; + VARIANTARG rgvarg[1]; + DISPID rgdispid[1]; + DISPPARAMS dispparams; + OLECHAR FAR* rgszNames[1]; + +#if OE_WIN16 + // make sure the server is running first + if(!WinExec("sdisptst", SW_NORMAL)) + return RESULT(E_UNEXPECTED); +#endif + + // get the active application object + IfFailGo( + GetActiveObject(CLSID_SDispTst_CAppObject, NULL, &punk), + LError0); + + IfFailGo( + punk->QueryInterface(IID_IDispatch, (void FAR* FAR*)&pdispApp), + LError1); + + // invoke the NewCDispTst method on the application object to + // create an instance of the CDispTst object. + + rgszNames[0] = OLESTR("newcdisptst"); + IfFailGo( + pdispApp->GetIDsOfNames( + IID_NULL, rgszNames, 1, LOCALE_USER_DEFAULT, rgdispid), + LError2); + + dispparams.cArgs = 1; + dispparams.cNamedArgs = 0; + dispparams.rgvarg = rgvarg; + pdispCDispTst = NULL; + V_VT(&rgvarg[0]) = VT_BYREF | VT_DISPATCH; + V_DISPATCHREF(&rgvarg[0]) = &pdispCDispTst; + VariantInit(&varResult); + IfFailGo( + DoInvoke(pdispApp, rgdispid[0], &dispparams, &varResult, NULL, NULL), + LError2); + + // invoke CDispTst::Hello(), just to make sure this is really working + + rgszNames[0] = OLESTR("hello"); + IfFailGo( + pdispCDispTst->GetIDsOfNames( + IID_NULL, rgszNames, 1, LOCALE_USER_DEFAULT, rgdispid), + LError2); + + dispparams.cArgs = 0; + dispparams.cNamedArgs = 0; + IfFailGo( + DoInvoke(pdispCDispTst, rgdispid[0], &dispparams, NULL, NULL, NULL), + LError3); + + hresult = NOERROR; + +LError3:; + pdispCDispTst->Release(); + +LError2:; + pdispApp->Release(); + +LError1:; + punk->Release(); + +LError0:; + return hresult; +} + +HRESULT +GetObject2() +{ + HRESULT hresult; + IUnknown FAR* punkCalcGet; + IDispatch FAR* pdispCalcGet; + IDispatch FAR* pdispCalcCreate; + + DISPID rgdispid[1]; + DISPPARAMS dispparams; + OLECHAR FAR* rgszNames[1]; + + // make sure the server is running + DbPrintf("CreateObject(\"Dispcalc.Application\",)\n"); + IfFailGo(CreateObject(OLESTR("Dispcalc.Application"), &pdispCalcCreate), + LError0); + +#ifdef _MAC + // REVIEW: currently a problem with GetActiveObj on the mac + IfFailGo(pdispCalcCreate->QueryInterface(IID_IUnknown, (void FAR* FAR*) &punkCalcGet), LError0); +#else + // get the active application object + DbPrintf("GetActiveObject(CLSID_CCalc,)\n"); + IfFailGo(GetActiveObject(CLSID_CCalc, NULL, &punkCalcGet), LError1); +#endif + + DbPrintf("QueryInterface(IID_IDispatch,)\n"); + IfFailGo( + punkCalcGet->QueryInterface( + IID_IDispatch, (void FAR* FAR*)&pdispCalcGet), LError2); + + // REVIEW: set accum on the create version, and get the accum on + // the get version - then check to see that its the same value + + DbPrintf("GetIDsOfNames(\"quit\",)\n"); + rgszNames[0] = OLESTR("quit"); + IfFailGo( + pdispCalcGet->GetIDsOfNames(IID_NULL, rgszNames, 1, 0, rgdispid), + LError3); + + DbPrintf("Invoke(\"quit\",)\n"); + dispparams.cArgs = 0; + dispparams.cNamedArgs = 0; + dispparams.rgvarg = NULL; + IfFailGo( + DoInvoke(pdispCalcGet, rgdispid[0], &dispparams, NULL, NULL, NULL), + LError3); + + hresult = NOERROR; + +LError3:; + pdispCalcGet->Release(); + +LError2:; + punkCalcGet->Release(); + +LError1:; +#if !defined(WIN32) // BUGBUG: ole32.dll GPF is channel code... + // cause and identity table assertion to occur + pdispCalcCreate->Release(); +#endif + +LError0:; + return hresult; +} + + +// test repeatedly getting and releasing an active object + +HRESULT +GetObject3() +{ + int i; + HRESULT hresult; + IUnknown FAR* punk; + IDispatch FAR* pdisp; + + punk = NULL; + pdisp = NULL; + + // make sure the server is running + hresult = CreateObject(OLESTR("Dispcalc.Application"), &pdisp); + if(hresult != NOERROR) + goto LError0; + + // the calculator stays in memory until the quit method is invoked + pdisp->Release(); + pdisp = NULL; + + for(i = 0; i < 10; ++i){ + // get the active application object + IfFailGo(GetActiveObject(CLSID_CCalc, NULL, &punk), LError0); + + IfFailGo( + punk->QueryInterface(IID_IDispatch, (void FAR* FAR*)&pdisp), + LError0); + + punk->Release(); + punk = NULL; + + pdisp->Release(); + pdisp = NULL; + } + +LError0:; + if(pdisp!=NULL) + pdisp->Release(); + if(punk!=NULL) + punk->Release(); + + return hresult; +} + diff --git a/private/oleauto/tests/disptest/cbstr.cpp b/private/oleauto/tests/disptest/cbstr.cpp new file mode 100644 index 000000000..a0d2689ee --- /dev/null +++ b/private/oleauto/tests/disptest/cbstr.cpp @@ -0,0 +1,313 @@ +/*** +*cbstr.cpp +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* This file implements the CBstrSuite test object. +* +*Revision History: +* +* [00] 30-Oct-92 bradlo: Created. +* +*Implementation Notes: +* +*****************************************************************************/ + +#include <limits.h> + +#include "disptest.h" +#include "tstsuite.h" + + +struct TEST { + HRESULT (*pfnTest)(void); + OLECHAR FAR* szName; +}; + +HRESULT BstrLimits(void); +HRESULT BstrOleprog5(void); +HRESULT BstrOleprog8(void); +HRESULT BstrOleprog65(void); +HRESULT BstrOleprog234(void); + +static TEST rgtest[] = { + { BstrOleprog5, OLESTR("raid!oleprog#5") } +#if !OE_MAC + , { BstrOleprog8, OLESTR("raid!oleprog#8") } +#endif + , { BstrOleprog65, OLESTR("raid!oleprog#65") } + , { BstrOleprog234, OLESTR("raid!oleprog#234") } + , { BstrLimits, OLESTR("Bstr limits") } +}; + + +SUITE_CONSTRUCTION_IMPL(CBstrSuite) + +SUITE_IUNKNOWN_IMPL(CBstrSuite) + + +//--------------------------------------------------------------------- +// ITestSuite Methods +//--------------------------------------------------------------------- + + +STDMETHODIMP +CBstrSuite::GetNameOfSuite(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("BSTR API"), pbstr); +} + +STDMETHODIMP +CBstrSuite::GetNameOfLogfile(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("bstrapi.log"), pbstr); +} + +STDMETHODIMP +CBstrSuite::GetTestCount(unsigned int FAR* pcTests) +{ + *pcTests = DIM(rgtest); + + return NOERROR; +} + +STDMETHODIMP +CBstrSuite::GetNameOfTest(unsigned int iTest, BSTR FAR* pbstr) +{ + if(iTest >= DIM(rgtest)) + return RESULT(E_INVALIDARG); + + *pbstr = SysAllocString(rgtest[iTest].szName); + return NOERROR; +} + +/*** +*HRESULT CBstrSuite::DoTest(unsigned int) +*Purpose: +* Execute a single CBstrSuite test. +* +*Entry: +* iTest = the index of the test to execute +* +*Exit: +* return value = HRESULT +* +***********************************************************************/ +STDMETHODIMP +CBstrSuite::DoTest(unsigned int iTest) +{ + if(iTest >= DIM(rgtest)) + return RESULT(E_INVALIDARG); + + return rgtest[iTest].pfnTest(); +} + +HRESULT +BstrLimits() +{ + unsigned long u; + BSTR bstr; + +#if OE_WIN32 /* { */ + + +static unsigned long s2M = 2097152; +static unsigned long INCREMENT = 262144; + + DbPrintf("SysAllocStringLen()\n"); + + DbPrintf("linear increasing...\n"); + for(u = 1; u < s2M; u+=INCREMENT){ + DbPrintf("%lu\n", u); + bstr = SysAllocStringLen(NULL, (unsigned int)u); + IfWin(Yield()); + if(bstr == NULL) + break; + SysFreeString(bstr); + } + DbPrintf("max len = %lu\n", u-1); + + DbPrintf("linear decreasing...\n"); + for(u = s2M; u > 0; u-=INCREMENT){ + DbPrintf("%lu\n", u); + bstr = SysAllocStringLen(NULL, (unsigned int)u); + IfWin(Yield()); + if(bstr == NULL) + break; + SysFreeString(bstr); + } + DbPrintf("max len = %lu\n", u); + + return NOERROR; + +#else + +#if OE_MAC +static unsigned long s64k = 64000; +#else +static unsigned long s64k = UINT_MAX; +#endif + DbPrintf("SysAllocStringLen()\n"); + + DbPrintf("linear increasing...\n"); + for(u = s64k-(1024*4); u < s64k; ++u){ + if((u%1024) == 0){ + DbPrintf("%lu\n", u); + } + bstr = SysAllocStringLen(NULL, (unsigned int)u); + IfWin(Yield()); + if(bstr == NULL) + break; + SysFreeString(bstr); + } + DbPrintf("max len = %lu\n", u-1); + + DbPrintf("linear decreasing...\n"); + for(u = s64k; u > 0; --u){ + bstr = SysAllocStringLen(NULL, (unsigned int)u); + IfWin(Yield()); + if(bstr != NULL){ + SysFreeString(bstr); + break; + } + } + DbPrintf("max len = %lu\n", u); + + return NOERROR; + +#endif /* } */ +} + + +// regression test for raid!oleprog:5 +// +HRESULT +BstrOleprog5() +{ + unsigned int len; + BSTR bstr; +static OLECHAR a_string[] = OLESTR("a string"); +static OLECHAR another_string[] = OLESTR("another (longer) string"); + + bstr = SysAllocString(a_string); + if(bstr == NULL) + return RESULT(E_OUTOFMEMORY); + + len = SysStringLen(bstr); +#if (defined(WIN32) && !defined(UNICODE)) + if(len != (unsigned int)wcslen(a_string)) +#else + if(len != STRLEN(a_string)) +#endif + return RESULT(E_FAIL); + + if(!SysReAllocString(&bstr, another_string)) + return RESULT(E_OUTOFMEMORY); + + len = SysStringLen(bstr); +#if (defined(WIN32) && !defined(UNICODE)) + if(len != (unsigned int)wcslen(another_string)) +#else + if(len != STRLEN(another_string)) +#endif + return RESULT(E_FAIL); + + SysFreeString(bstr); + + return NOERROR; +} + +// regression test for raid!oleprog:8 +// +HRESULT +BstrOleprog8() +{ + unsigned int len; + HRESULT hresult; + BSTR bstr1, bstr2; +#define LARGE_BSTR_SIZE 64300 + + if((bstr1 = SysAllocStringLen(NULL, LARGE_BSTR_SIZE)) == NULL){ + hresult = RESULT(E_OUTOFMEMORY); + goto LError0; + } + + if((bstr2 = SysAllocString(OLESTR("hello world"))) == NULL){ + hresult = RESULT(E_OUTOFMEMORY); + goto LError1; + } + + if((len = SysStringLen(bstr1)) != LARGE_BSTR_SIZE){ + hresult = RESULT(E_FAIL); + goto LError2; + } + + hresult = NOERROR; + +LError2:; + SysFreeString(bstr1); + +LError1:; + SysFreeString(bstr2); + +LError0:; + return hresult; + +#undef LARGE_BSTR_SIZE +} + +// regression test for raid!oleprog:8 +// +// SysAllocString of a string containing an embedded '\0' stops +// copying at the '\0'; +// +HRESULT +BstrOleprog65() +{ + BSTR bstr; + HRESULT hresult; + static OLECHAR sz_embedded_null[] = + OLESTR("a string \0 with an embedded null"); + + + bstr = SysAllocStringLen(sz_embedded_null, SIZEOFCH(sz_embedded_null)); + + hresult = (MEMCMP(bstr, sz_embedded_null, sizeof(sz_embedded_null)) == 0) + ? NOERROR + : RESULT(E_UNEXPECTED); + + SysFreeString(bstr); + + return hresult; +} + +// regression test for raid!oleprog:234 +// +// make sure we are properly handling Reallocing a bstr thats Null. +// +HRESULT +BstrOleprog234() +{ + unsigned int len; + BSTR bstr; + static OLECHAR szHooHa[] = OLESTR("HooHa"); + + bstr = NULL; + if(!SysReAllocString(&bstr, szHooHa)) + return RESULT(E_OUTOFMEMORY); + + len = SysStringLen(bstr); +#if (defined(WIN32) && !defined(UNICODE)) + if(len != (unsigned int)wcslen(szHooHa)) +#else + if(len != STRLEN(szHooHa)) +#endif + return RESULT(E_FAIL); + + SysFreeString(bstr); + + return NOERROR; +} + diff --git a/private/oleauto/tests/disptest/ccollect.cpp b/private/oleauto/tests/disptest/ccollect.cpp new file mode 100644 index 000000000..91aa5d101 --- /dev/null +++ b/private/oleauto/tests/disptest/ccollect.cpp @@ -0,0 +1,422 @@ +/*** +*ccollect.cpp +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* This file implements the CCollectionSuite test object. +* +*Revision History: +* +* [00] 06-Dec-92 bradlo: Created. +* +*Implementation Notes: +* +*****************************************************************************/ + +#include "disptest.h" + +#include <math.h> + +#include "tstsuite.h" +#include "disphelp.h" +#include "clsid.h" +#include "crempoly.h" + +ASSERTDATA + + +extern OLECHAR FAR* g_CPoly; + + +HRESULT CollectionTest0(void); +HRESULT CollectionTest1(void); + +static struct TEST { + HRESULT (*pfnTest)(void); + OLECHAR FAR* szName; +} rgtest[] = { + { CollectionTest0, OLESTR("collection test #0") } + , { CollectionTest1, OLESTR("collection test #1") } +}; + + +SUITE_CONSTRUCTION_IMPL(CCollectionSuite) + +SUITE_IUNKNOWN_IMPL(CCollectionSuite) + + +//--------------------------------------------------------------------- +// ITestSuite Methods +//--------------------------------------------------------------------- + + +STDMETHODIMP +CCollectionSuite::GetNameOfSuite(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("Collections"), pbstr); +} + +STDMETHODIMP +CCollectionSuite::GetNameOfLogfile(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("collect.log"), pbstr); +} + +STDMETHODIMP +CCollectionSuite::GetTestCount(unsigned int FAR* pcTests) +{ + *pcTests = DIM(rgtest); + + return NOERROR; +} + + +STDMETHODIMP +CCollectionSuite::GetNameOfTest(unsigned int iTest, BSTR FAR* pbstr) +{ + if(iTest >= DIM(rgtest)) + return RESULT(E_INVALIDARG); + + return ErrBstrAlloc(rgtest[iTest].szName, pbstr); +} + + +/*** +*HRESULT CCollectionSuite::DoTest(unsigned int) +*Purpose: +* Execute a single CCollectionSuite test. +* +*Entry: +* iTest = the index of the test to execute +* +*Exit: +* return value = HRESULT +* +***********************************************************************/ +STDMETHODIMP +CCollectionSuite::DoTest(unsigned int iTest) +{ + if(iTest >= DIM(rgtest)) + return RESULT(E_INVALIDARG); + + return rgtest[iTest].pfnTest(); +} + + +HRESULT +DoInvokeName( + IDispatch FAR* pdisp, + OLECHAR FAR* szMethod, + VARIANT FAR* pvarResult, + DISPPARAMS FAR* pdispparams) +{ + DISPID dispid; + OLECHAR FAR* rgsz[1]; + DISPPARAMS dispparams; + + if(pdispparams == NULL){ + pdispparams = &dispparams; + pdispparams->cArgs = 0; + pdispparams->rgvarg = NULL; + pdispparams->cNamedArgs = 0; + pdispparams->rgdispidNamedArgs = NULL; + } + + rgsz[0] = szMethod; + IfFailRet( + pdisp->GetIDsOfNames( + IID_NULL, rgsz, 1, LOCALE_SYSTEM_DEFAULT, &dispid)); + + return DoInvoke(pdisp, dispid, pdispparams, pvarResult, NULL, NULL); +} + + +HRESULT +VtIs(VARIANT FAR* pvar, VARTYPE vt) +{ + return (V_VT(pvar) != vt) ? RESULT(E_INVALIDARG) : NOERROR; +} + +struct oledisp_point { short x,y; }; + +static struct oledisp_point rgptTriangle[] = { + {50, 0}, + {0, 100}, + {100, 100} +}; + +static struct oledisp_point rgptSquare[] = { + {0, 0}, + {0, 100}, + {100, 100}, + {100, 0}, +}; + +static struct oledisp_point rgptOctagon[] = { + {25, 0}, + {75, 0}, + {100, 25}, + {100, 75}, + {75, 100}, + {25, 100}, + {0, 75}, + {0, 25} +}; + +struct oledisp_shape { + struct oledisp_point ptOrigin; + unsigned int cPoints; + struct oledisp_point FAR* rgpt; +} g_rgshape[] = { + {{100, 50}, DIM(rgptTriangle), rgptTriangle}, + {{200, 50}, DIM(rgptSquare), rgptSquare}, + {{300, 50}, DIM(rgptOctagon), rgptOctagon} +}; + + +HRESULT +BuildShape(CRemPoly FAR* ppoly, struct oledisp_shape FAR* pshape) +{ + unsigned int i; + + IfFailRet(ppoly->SetWidth(1)); + IfFailRet(ppoly->set_red(0)); + IfFailRet(ppoly->set_green(0)); + IfFailRet(ppoly->set_blue(0)); + IfFailRet(ppoly->SetXOrigin((short)pshape->ptOrigin.x)); + IfFailRet(ppoly->SetYOrigin((short)pshape->ptOrigin.y)); + for(i = 0; i < pshape->cPoints; ++i) + IfFailRet( + ppoly->AddPoint((short)pshape->rgpt[i].x, (short)pshape->rgpt[i].y)); + + return NOERROR; +} + +static struct { + short red, green, blue; +} g_rgrgbColors[] = { +#if OE_MAC + { 0, 0, 0} + , { 0, 0, 0x7fff} + , { 0, 0x7fff, 0} + , {0x7fff, 0, 0} + , {0x7fff, 0, 0x7fff} + , {0x7fff, 0x7fff, 0} + , {0x7fff, 0x7fff, 0x7fff} + , { 0, 0, 0xffff} + , { 0, 0xffff, 0} + , {0xffff, 0, 0} + , {0xffff, 0, 0xffff} + , {0xffff, 0xffff, 0} +#else + { 0, 0, 0} + , { 0, 0, 127} + , { 0, 127, 0} + , {127, 0, 0} + , {127, 0, 127} + , {127, 127, 0} + , {127, 127, 127} + , { 0, 0, 255} + , { 0, 255, 0} + , {255, 0, 0} + , {255, 0, 255} + , {255, 255, 0} +#endif +}; + +HRESULT +MoveShape(CRemPoly FAR* ppoly) +{ + short s; + int i, ix; + HRESULT hresult; + unsigned long celtFetched; + IDispatch FAR* pdisp; + IEnumVARIANT FAR* penum; + DISPPARAMS dispparams; + VARIANT varX, varY, varElt; + + double delta_rads; + + + // get an enumerator for the points we just added. + // + IfFailGo(ppoly->EnumPoints(&penum), LError0); + + // degrees -> radians + delta_rads = ((double)20.0 * 3.14159) / 180.0; + + for(i = 0; i < 15; ++i){ + IfFailGo(penum->Reset(), LError1); + + VariantInit(&varElt); + while((hresult = penum->Next(1, &varElt, &celtFetched)) == NOERROR){ + // make sure we got what we expected. + // + ASSERT(celtFetched == 1); + IfFailGo(VtIs(&varElt, VT_DISPATCH), LError1); + + pdisp = V_DISPATCH(&varElt); + V_VT(&varElt) = VT_EMPTY; + + // get the X and Y coordinates + + VariantInit(&varX); + IfFailGo(DoInvokeName(pdisp, OLESTR("getx"), &varX, NULL), LError2); + IfFailGo(VtIs(&varX, VT_I2), LError3); + + VariantInit(&varY); + IfFailGo(DoInvokeName(pdisp, OLESTR("gety"), &varY, NULL), LError3); + IfFailGo(VtIs(&varY, VT_I2), LError4); + + // rotate the point + + double x = (double)V_I2(&varX); + double y = (double)V_I2(&varY); + double radius = sqrt((x*x) + (y*y)); + double theta = ((x == 0.0) && (y == 0.0) ? 0.0 : atan2(y, x)) + + delta_rads; + + V_I2(&varX) = (short)(radius * cos(theta)); + V_I2(&varY) = (short)(radius * sin(theta)); + + // set the new X and Y coordinates + + dispparams.cArgs = 1; + dispparams.rgvarg = &varX; + dispparams.cNamedArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + IfFailGo(DoInvokeName(pdisp, OLESTR("setx"), NULL, &dispparams), LError4); + + dispparams.cArgs = 1; + dispparams.rgvarg = &varY; + dispparams.cNamedArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + IfFailGo(DoInvokeName(pdisp, OLESTR("sety"), NULL, &dispparams), LError4); + + VariantClear(&varY); + VariantClear(&varX); + + pdisp->Release(); + pdisp = NULL; + } + + if(HRESULT_FAILED(hresult)) + goto LError1; + + ASSERT(GetScode(hresult) == S_FALSE); + + IfFailGo(ppoly->SetWidth(i), LError1); + + IfFailGo(ppoly->GetXOrigin(&s), LError1); + IfFailGo(ppoly->SetXOrigin(i + i + s), LError1); + + IfFailGo(ppoly->GetYOrigin(&s), LError1); + IfFailGo(ppoly->SetYOrigin(i + i + s), LError1); + + ix = i % DIM(g_rgrgbColors); + IfFailGo(ppoly->set_red(g_rgrgbColors[i].red), LError1); + IfFailGo(ppoly->set_green(g_rgrgbColors[i].green), LError1); + IfFailGo(ppoly->set_blue(g_rgrgbColors[i].blue), LError1); + + IfFailGo(ppoly->Draw(), LError1); + + IfWin(Yield()); + } + + penum->Release(); + + return NOERROR; + + +LError4:; + VariantClear(&varY); + +LError3:; + VariantClear(&varX); + +LError2:; + pdisp->Release(); + +LError1:; + penum->Release(); + +LError0:; + return hresult; +} + + +HRESULT +CollectionTest1() +{ + int i, j; + HRESULT hresult; + CRemPoly FAR* ppoly[2]; + + for(i = 0; i < DIM(ppoly); ++i) + ppoly[i] = NULL; + + IfFailGo(CRemPoly::Create(OLESTR("SPoly.Application"), &ppoly[0]), LError0); + IfFailGo(CRemPoly::Create(OLESTR("SPoly2.Application"), &ppoly[1]), LError0); + + for(j = 0; j < DIM(g_rgshape); ++j) + { + for(i = 0; i < DIM(ppoly); ++i) + IfFailGo(BuildShape(ppoly[i], &g_rgshape[j]), LError0); + + for(i = 0; i < DIM(ppoly); ++i){ + IfFailGo(ppoly[i]->Draw(), LError0); + IfFailGo(MoveShape(ppoly[i]), LError0); + } + + for(i = 0; i < DIM(ppoly); ++i) + IfFailGo(ppoly[i]->Reset(), LError0); + } + + hresult = NOERROR; + +LError0:; + for(i = 0; i < DIM(ppoly); ++i) + if(ppoly[i] != NULL) + ppoly[i]->Release(); + + return hresult; +} + + +HRESULT +CollectionTest0() +{ + HRESULT hresult; + CRemPoly FAR* ppoly; + IEnumVARIANT FAR* penum; + IEnumVARIANT FAR* penumClone; + + IfFailGo(CRemPoly::Create(OLESTR("SPoly.Application"), &ppoly), LError0); + + ppoly->AddPoint(0, 0); + ppoly->AddPoint(0, 50); + ppoly->AddPoint(50, 0); + ppoly->AddPoint(50, 50); + ppoly->Draw(); + + IfFailGo(ppoly->EnumPoints(&penum), LError1); + + IfFailGo(penum->Clone(&penumClone), LError2); + + hresult = NOERROR; + + penumClone->Release(); + +LError2:; + penum->Release(); + +LError1:; + ppoly->Release(); + +LError0:; + return hresult; +} + diff --git a/private/oleauto/tests/disptest/cdatecnv.cpp b/private/oleauto/tests/disptest/cdatecnv.cpp new file mode 100644 index 000000000..70ebdd436 --- /dev/null +++ b/private/oleauto/tests/disptest/cdatecnv.cpp @@ -0,0 +1,491 @@ +/*** +*cdatecnv.cpp +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* This file implements the CDateCoersionSuite. This suite tests date/time +* coersions - primarrily date<->bstr. +* +*Revision History: +* +* [00] 30-Oct-92 bradlo: Created. +* +*Implementation Notes: +* +*****************************************************************************/ + +#include <stdio.h> +#include "disptest.h" +#include "tstsuite.h" + + +static LCID rglcid[] = { + 0 + , 0x040c + , 0x0407 + , 0x0409 + , 0x0809 + , 0x0c09 + , 0x1009 + , 0x1409 + , 0x0406 + , 0x0413 + , 0x0813 + , 0x040b + , 0x080c + , 0x0c0c + , 0x100c + , 0x0807 + , 0x0c07 + , 0x0410 + , 0x0810 + , 0x040a + , 0x080a + , 0x0c0a + , 0x041d + , 0x0414 + , 0x0416 + , 0x0816 + , 0x0405 + , 0x040e + , 0x0415 + , 0x041b + , 0x0419 +}; + +static OLECHAR FAR* rgpszSimpleDate[] = +{ + OLESTR("1-7-66") + , OLESTR("1.20") + , OLESTR("1-7-100") + , OLESTR("1-7-1966") + , OLESTR("01-7-66") + , OLESTR("01-07-66") + , OLESTR("01-07-0100") + , OLESTR("01-07-1966") + , OLESTR("1/7/66") + , OLESTR("1/7/100") + , OLESTR("1/7/1966") + , OLESTR("1-7/66") + , OLESTR("1-7/100") + , OLESTR("1-7/1966") + , OLESTR("1/7-66") + , OLESTR("1/7-100") + , OLESTR("1/7-1966") + , OLESTR("1-7-66") + , OLESTR("1-7-100") + , OLESTR("1-7-1966") + , OLESTR("1 - 7 - 66") + , OLESTR("1 - 7 - 100") + , OLESTR("1 - 7 - 1966") + , OLESTR(" 1/7/1966") + , OLESTR("1/7/1966 ") + , OLESTR(" 1 / 07 / 66 ") + , OLESTR("\t1\t/\t07\t/\t66\t") + , NULL +}; + +static OLECHAR FAR* rgpszShortMonth[] = +{ + OLESTR("jan 10, 22") + , OLESTR("feb 03, 1999") + , OLESTR("mar 31, 1945") + , OLESTR("apr 1, 2002") + , OLESTR("may 15, 2020") + , OLESTR("jun 08, 1978") + , OLESTR("jul 30 1492") + , OLESTR("aug 12 1010") + , OLESTR("sep 3 1877") + , OLESTR(" oct 4, 1214") + , OLESTR("nov 12 1313 ") + , OLESTR(" dec 7, 1942 ") + , OLESTR("10 jan 22") + , OLESTR("03 feb 1999") + , OLESTR("31, mar 1945") + , OLESTR("1, apr 2002") + , OLESTR("15, may 2020") + , OLESTR("08 jun, 1978") + , OLESTR("30 jul 1492") + , OLESTR("12 aug 1010") + , OLESTR(" 3 sep 1877") + , OLESTR("004 oct, 1214") + , OLESTR("12 nov 1313 ") + , OLESTR("7, dec, 1942 ") + , OLESTR("\t7\t,\tdec\t,\t1942\t") + , NULL +}; + +static OLECHAR FAR* rgpszLongMonth[] = +{ + OLESTR("january 10, 22") + , OLESTR("february 03, 1999") + , OLESTR("march 31, 1945") + , OLESTR("april 1, 2002") + , OLESTR("may 15, 2020") + , OLESTR("june 08, 1978") + , OLESTR("july 30 1492") + , OLESTR("august 12 1010") + , OLESTR("september 3 1877") + , OLESTR(" october 4, 1214") + , OLESTR("november 12 1313 ") + , OLESTR(" december 7, 1942 ") + , OLESTR("10 January 22") + , OLESTR("03 February 1999") + , OLESTR("31, March 1945") + , OLESTR("1, April 2002") + , OLESTR("15, May 2020") + , OLESTR("08 June, 1978") + , OLESTR("30 JULY 1492") + , OLESTR("12 AugUST 1010") + , OLESTR(" 3 SePtEmBeR 1877") + , OLESTR("004 OCTOBER, 1214") + , OLESTR("12 NOVembER 1313 ") + , OLESTR("7, DeceMBeR, 1942 ") + , OLESTR("\t7,\tDeceMBeR,\t1942\t") + , NULL +}; + +static OLECHAR FAR* rgpszPartialDate[] = +{ + OLESTR("1-10") + , OLESTR("2-99") + , OLESTR("mar 15") + , OLESTR("15 april") + , OLESTR("may 45") + , OLESTR("99 JUN") + , OLESTR(" 1/20") + , OLESTR(" 12-15 ") + , NULL +}; + +static OLECHAR FAR* rgpszSimpleTime[] = { + OLESTR("0:0:0") + , OLESTR("0:0:0 am") + , OLESTR("0:0:0 pm") + , OLESTR("1:0:0") + , OLESTR("1:0:0 am") + , OLESTR("1:0:0 pm") + , OLESTR("11:0:0") + , OLESTR("11:0:0 am") + , OLESTR("11:0:0 pm") + , OLESTR("12:0:0") + , OLESTR("12:0:0 am") + , OLESTR("12:0:0 pm") + , OLESTR("13:0:0") + , OLESTR("23:0:0") + , OLESTR("1:2:3") + , OLESTR("01:2:3") + , OLESTR("1:02:3") + , OLESTR("01:2:03") + , OLESTR("01:02:03") + , OLESTR("1.2.3") + , OLESTR("01.2.3") + , OLESTR("1.02.3") + , OLESTR("01.2.03") + , OLESTR("01.02.03") + , OLESTR("1.2.3 am") + , OLESTR("01.2.3 am") + , OLESTR("1.02.3 am") + , OLESTR("01.2.03 am") + , OLESTR("01.02.03 am") + , OLESTR("1.2.3 pm") + , OLESTR("01.2.3 pm") + , OLESTR("1.02.3 pm") + , OLESTR("01.2.03 pm") + , OLESTR("01.02.03 pm") + , OLESTR("1.2.3 a") + , OLESTR("01.2.3 a") + , OLESTR("1.02.3 a") + , OLESTR("01.2.03 a") + , OLESTR("01.02.03 a") + , OLESTR("1.2.3 p") + , OLESTR("01.2.3 p") + , OLESTR("1.02.3 p") + , OLESTR("01.2.03 p") + , OLESTR("01.02.03 p") + , OLESTR(" 1. 2. 3 ") + , OLESTR(" 01. 2. 3 am ") + , OLESTR(" 1.02: 3 p ") + , OLESTR(" 01: 2.03 pm ") + , OLESTR(" 01:02:03 p ") + , OLESTR(" 25:0 ") + , OLESTR("1.61 p") + , OLESTR("1.2.99") + , NULL +}; + +static OLECHAR FAR* rgpszPartialTime[] = { + OLESTR("1 a") + , OLESTR("2 am") + , OLESTR("3 p ") + , OLESTR("04 pm") + , OLESTR("5:50") + , OLESTR("6:6 a") + , OLESTR("7:7 am") + , OLESTR("08:08 p") + , OLESTR("09:09 pm") + , OLESTR("10:10") + , OLESTR("11:11 ") + , OLESTR(" 12:12") + , OLESTR(" 13:13 ") + , OLESTR("14.14") + , OLESTR("15.15 ") + , OLESTR(" 16.16") + , OLESTR(" 17.17 ") + , OLESTR("18:18") + , OLESTR("19:19 ") + , OLESTR(" 20:20") + , OLESTR(" 21.21 ") + , OLESTR("22.22") + , OLESTR("23.59 ") + , NULL +}; + +static OLECHAR FAR* rgpszDateTime[] = { + OLESTR("1-7-66 12:14:00") + , OLESTR("1/7/1966 12:14") + , OLESTR("1/7 12:14") + , OLESTR("jan 7, 1966 12:14 am") + , OLESTR("jan 7 12:14") + , OLESTR("january 7 1993 1:20 pm") + , OLESTR("feb 18, 2002 23:59:50") + , OLESTR("mar 12 1 am") + , OLESTR("apr 30 45 2 a") + , OLESTR("may/7, 1475 10.02") + , OLESTR("1 7 5 am") + , OLESTR("7 jan 1966 12:14 am") + , OLESTR("17 jan 12:14") + , OLESTR("7 january 1993 1:20 pm") + , OLESTR("18 feb, 2002 23:59:50") + , OLESTR("12 mar 1 am") + , OLESTR("30 apr 45 2 a") + , OLESTR("7/may, 1475 10.02") + , NULL +}; + +static OLECHAR FAR* rgpszTimeDate[] = { + OLESTR("12:14:00 1-7-66") + , OLESTR("12:14 1/7/1966") + , OLESTR("12:14 1/7") + , OLESTR("12:14 am jan 7, 1966") + , OLESTR("12:14:00 jan 7") + , OLESTR("1:20 pm january 7 1993") + , OLESTR("23.59:50 feb 18, 2002") + , OLESTR("1 am mar 12") + , OLESTR("2 a apr 30 45") + , OLESTR("10.02 may/7, 1475 ") + , OLESTR("5 am 1 7") + , OLESTR(" 12:14 am 7 jan 1966 ") + , OLESTR("02.04 17 jan") + , OLESTR("1.20 pm 7 january 1993") + , OLESTR("23:59.50 18 feb, 2002") + , OLESTR("1 am 12 mar ") + , OLESTR(" 2 a 30 apr 45") + , OLESTR(" 10.02 7/may, 1475 ") + , NULL +}; + +// the following date strings are invalid formats and should generate errors + +static OLECHAR FAR* rgpszErrors[] = { + OLESTR("") + , OLESTR(" ") + , OLESTR("\t") + , OLESTR("1") + , OLESTR("33/33") + , OLESTR("1-2-3-4") + , OLESTR("1-2-3 4") + , OLESTR("1-2 3 4") + , OLESTR("1 2 3 4") + , OLESTR("1/2/3/4") + , OLESTR("1/2/3 4") + , OLESTR("1/2 3 4") + , OLESTR("1 2 3 4") + , OLESTR("1/") + , OLESTR("1-") + , OLESTR("-1") + , OLESTR("/1") + , OLESTR("jan") + , OLESTR("august") + , OLESTR("1:") + , OLESTR(":1") + , OLESTR("1:.2") + , OLESTR("1.2.3.4") + , OLESTR("1 am 2") + , OLESTR("2 p 3.3") + , OLESTR("1-7-66 2:20 pm 1-7-66") + , OLESTR("2:20 1-7 2 pm") + , OLESTR("25 p") + , OLESTR("1.60") + , OLESTR("1.2.60") + , NULL +}; + +static OLECHAR FAR* rgpszBugs[] = { + OLESTR("1993-04-01") + , OLESTR("2:30:30 5:40:") // error + , OLESTR("2:30:30p") + , OLESTR("2/3/4 3.4.5") + , OLESTR("13.13.13") + , OLESTR("1,2,3") + , OLESTR("March 23, 1900") + , OLESTR("September 2000") + , OLESTR("1/68") + , OLESTR("3/13") + , OLESTR("3/31") + , OLESTR("3/32") + , OLESTR("2.3.4 3.4.5") // error + , OLESTR("1993-02-01") + , OLESTR("1993/2/28") + , NULL +}; + +static OLECHAR FAR* FAR* rgprgszTests[] = { + rgpszBugs + , rgpszSimpleDate + , rgpszShortMonth + , rgpszLongMonth + , rgpszPartialDate + , rgpszSimpleTime + , rgpszPartialTime + , rgpszDateTime + , rgpszTimeDate + , rgpszErrors +}; + + +SUITE_CONSTRUCTION_IMPL(CDateCoersionSuite) + +SUITE_IUNKNOWN_IMPL(CDateCoersionSuite) + + +//--------------------------------------------------------------------- +// ITestSuite Methods +//--------------------------------------------------------------------- + + +STDMETHODIMP +CDateCoersionSuite::GetNameOfSuite(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("Date Coersions"), pbstr); +} + +STDMETHODIMP +CDateCoersionSuite::GetNameOfLogfile(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("bstrdate.log"), pbstr); +} + +STDMETHODIMP +CDateCoersionSuite::GetTestCount(unsigned int FAR* pcTests) +{ + *pcTests = DIM(rglcid); + return NOERROR; +} + +STDMETHODIMP +CDateCoersionSuite::GetNameOfTest(unsigned int iTest, BSTR FAR* pbstr) +{ + TCHAR rgch[32]; + + if(iTest >= DIM(rglcid)) + return RESULT(E_INVALIDARG); + + SPRINTF(rgch, TSTR("(lcid=0x%lx) bstr->date"), rglcid[iTest]); + *pbstr = SysAllocString(WIDESTRING(rgch)); + return NOERROR; +} + +// run a single set of date->bstr coersion tests +HRESULT +DoDateOfBstr(LCID lcid, int index) +{ + int i; + HRESULT hresult; + VARIANT varBstr, varDate; + OLECHAR FAR* FAR* rgpsz, FAR* psz; + + rgpsz = rgprgszTests[index]; + + for(i = 0; rgpsz[i] != NULL; ++i){ + + psz = rgpsz[i]; + + VariantInit(&varBstr); + VariantInit(&varDate); + + V_VT(&varBstr) = VT_BSTR; + if((V_BSTR(&varBstr) = SysAllocString(psz)) == NULL) + return RESULT(E_OUTOFMEMORY); + + DbPrintf("\"%Fs\" =>", STRING(V_BSTR(&varBstr))); + + hresult = VariantChangeTypeEx(&varDate, &varBstr, lcid, 0, VT_DATE); + + if(hresult != NOERROR){ + + DbPrintf(" [%Fs]", DbSzOfScode(GetScode(hresult))); + + }else{ + + DbPrintf(" %g => ", V_DATE(&varDate)); + + VariantClear(&varBstr); + + hresult = VariantChangeTypeEx(&varBstr, &varDate, lcid, 0, VT_BSTR); + + if(hresult != NOERROR){ + + DbPrintf(" [%Fs]", DbSzOfScode(GetScode(hresult))); + + }else{ + + DbPrintf(" \"%Fs\"", STRING(V_BSTR(&varBstr))); + + } + } + + DbPrintf("\n"); + + VariantClear(&varDate); + VariantClear(&varBstr); + } + + return NOERROR; +} + +// run all of the bstr-date coersion tests for a given locale +HRESULT +DateOfBstr(LCID lcid) +{ + int i; + + for(i = 0; i < DIM(rgprgszTests); ++i){ + IfFailRet(DoDateOfBstr(lcid, i)); + } + return NOERROR; +} + +/*** +*HRESULT CDateCoersionSuite::DoTest(unsigned int) +*Purpose: +* Execute a single CDateCoersionSuite test. +* +*Entry: +* iTest = the index of the test to execute +* +*Exit: +* return value = HRESULT +* +***********************************************************************/ +STDMETHODIMP +CDateCoersionSuite::DoTest(unsigned int iTest) +{ + if(iTest >= DIM(rglcid)) + return RESULT(E_INVALIDARG); + + return DateOfBstr(rglcid[iTest]); +} + diff --git a/private/oleauto/tests/disptest/cdisptst.def b/private/oleauto/tests/disptest/cdisptst.def new file mode 100644 index 000000000..632886c5f --- /dev/null +++ b/private/oleauto/tests/disptest/cdisptst.def @@ -0,0 +1,13 @@ +NAME DispTest + +EXETYPE WINDOWS + +CODE PRELOAD MOVEABLE DISCARDABLE + +DATA PRELOAD MOVEABLE MULTIPLE + +HEAPSIZE 1024 +STACKSIZE 16384 + +;EXPORTS +; MainWndProc @1 diff --git a/private/oleauto/tests/disptest/cdisptst.r b/private/oleauto/tests/disptest/cdisptst.r new file mode 100644 index 000000000..a20ae22f6 --- /dev/null +++ b/private/oleauto/tests/disptest/cdisptst.r @@ -0,0 +1,329 @@ +#ifdef _PPCMAC +include "cfrg.rsc"; +#endif + +#include "systypes.r" +#include "types.r" +#include "macmain.h" + +resource 'vers' (1) { + 0x02, 0x00, release, 0x00, + verUS, + "1.02", + "1.02, Copyright \251 1993 Microsoft." +}; + +/* we use an MBAR resource to conveniently load all the menus */ + +resource 'MBAR' (rMenuBar, preload) { + { mApple, mFile, mEdit, mSuite, mOptions }; +}; + + +resource 'MENU' (mApple, preload) { + mApple, textMenuProc, + 0b1111111111111111111111111111101, + enabled, apple, + { + "About CDispTst\311", + noicon, nokey, nomark, plain; + "-", + noicon, nokey, nomark, plain + } +}; + +resource 'MENU' (mFile, preload) { + mFile, textMenuProc, + 0b0000000000000000000100000000000, + enabled, "File", + { + "New", + noicon, "N", nomark, plain; + "Open", + noicon, "O", nomark, plain; + "-", + noicon, nokey, nomark, plain; + "Close", + noicon, "W", nomark, plain; + "Save", + noicon, "S", nomark, plain; + "Save As\311", + noicon, nokey, nomark, plain; + "Revert", + noicon, nokey, nomark, plain; + "-", + noicon, nokey, nomark, plain; + "Page Setup\311", + noicon, nokey, nomark, plain; + "Print\311", + noicon, nokey, nomark, plain; + "-", + noicon, nokey, nomark, plain; + "Quit", + noicon, "Q", nomark, plain + } +}; + +resource 'MENU' (mEdit, preload) { + mEdit, textMenuProc, + 0b0000000000000000000000000000000, + enabled, "Edit", + { + "Undo", + noicon, "Z", nomark, plain; + "-", + noicon, nokey, nomark, plain; + "Cut", + noicon, "X", nomark, plain; + "Copy", + noicon, "C", nomark, plain; + "Paste", + noicon, "V", nomark, plain; + "Clear", + noicon, nokey, nomark, plain + } +}; + +resource 'MENU' (mSuite, preload) { + mSuite, textMenuProc, + 0b0000000000000000000111111111111, + enabled, "Suite", + { + "Bstr API", + noicon, nokey, nomark, plain; + "Time API", + noicon, nokey, nomark, plain; + "Date Coersions", + noicon, nokey, nomark, plain; + "Variant API", + noicon, nokey, nomark, plain; + "SafeArray API", + noicon, nokey, nomark, plain; + "NLS API", + noicon, nokey, nomark, plain; + "Binding", + noicon, nokey, nomark, plain; + "Invoke ByVal", + noicon, nokey, nomark, plain; + "Invoke ByRef", + noicon, nokey, nomark, plain; + "Invoke Array", + noicon, nokey, nomark, plain; + "Invoke Excepinfo", + noicon, nokey, nomark, plain; + "Collections", + noicon, nokey, nomark, plain + } +}; + +resource 'MENU' (mOptions, preload) { + mOptions, textMenuProc, + 0b0000000000000000000000000000011, + enabled, "Options", + { + "Clear", + noicon, "C", nomark, plain; + "Debugger", + noicon, nokey, nomark, plain + } +}; + + +/* this ALRT and DITL are used as an About screen */ + +resource 'ALRT' (rAboutAlert, purgeable) { + {40, 20, 160, 296}, rAboutAlert, { + OK, visible, silent; + OK, visible, silent; + OK, visible, silent; + OK, visible, silent + }; +}; + +resource 'DITL' (rAboutAlert, purgeable) { + { /* array DITLarray: 5 elements */ + /* [1] */ + {88, 184, 108, 264}, + Button { + enabled, + "OK" + }, + /* [2] */ + {8, 8, 24, 274}, + StaticText { + disabled, + "IDispatch Test Application" + }, + /* [3] */ + {32, 8, 48, 237}, + StaticText { + disabled, + "Copyright \251 1993 Microsoft" + }, + /* [4] */ + {56, 8, 72, 136}, + StaticText { + disabled, + "Brought to you by:" + }, + /* [5] */ + {80, 24, 112, 167}, + StaticText { + disabled, + "The Ole Automation Team" + } + } +}; + + +/* this ALRT and DITL are used as an error screen */ + +resource 'ALRT' (rUserAlert, purgeable) { + {40, 20, 150, 260}, + rUserAlert, + { /* array: 4 elements */ + /* [1] */ + OK, visible, silent, + /* [2] */ + OK, visible, silent, + /* [3] */ + OK, visible, silent, + /* [4] */ + OK, visible, silent + } +}; + + +resource 'DITL' (rUserAlert, purgeable) { + { /* array DITLarray: 3 elements */ + /* [1] */ + {80, 150, 100, 230}, + Button { + enabled, + "OK" + }, + /* [2] */ + {10, 60, 60, 230}, + StaticText { + disabled, + "Error. ^0." + }, + /* [3] */ + {8, 8, 40, 40}, + Icon { + disabled, + 2 + } + } +}; + + +resource 'WIND' (rDocWindow, preload, purgeable) { + {64, 60, 314, 460}, + zoomDocProc, invisible, goAway, 0x0, "untitled" +}; + + +resource 'CNTL' (rVScroll, preload, purgeable) { + {-1, 385, 236, 401}, + 0, visible, 0, 0, scrollBarProc, 0, "" +}; + + +resource 'CNTL' (rHScroll, preload, purgeable) { + {235, -1, 251, 386}, + 0, visible, 0, 0, scrollBarProc, 0, "" +}; + +resource 'STR#' (kErrStrings, purgeable) { + { + "You must run on 512Ke or later"; + "Application Memory Size is too small"; + "Not enough memory to run CDispTst"; + "Not enough memory to do Cut"; + "Cannot do Cut"; + "Cannot do Copy"; + "Cannot exceed 32,000 characters with Paste"; + "Not enough memory to do Paste"; + "Cannot create window"; + "Cannot exceed 32,000 characters"; + "Cannot do Paste" + } +}; + +resource 'SIZE' (-1) { + dontSaveScreen, + acceptSuspendResumeEvents, + enableOptionSwitch, + canBackground, + multiFinderAware, + backgroundAndForeground, + dontGetFrontClicks, + ignoreChildDiedEvents, + is32BitCompatible, + isHighLevelEventAware, + localAndRemoteHLEvents, + reserved, + reserved, + reserved, + reserved, + reserved, + kPrefSize * 1024, + kMinSize * 1024 +}; + + +type 'MOOT' as 'STR '; + + +resource 'MOOT' (0) { + "MultiFinder-Aware TextEdit Sample Application" +}; + + +resource 'BNDL' (128) { + 'MOOT', + 0, + { + 'ICN#', + { + 0, 128 + }, + 'FREF', + { + 0, 128 + } + } +}; + + +resource 'FREF' (128) { + 'APPL', + 0, + "" +}; + + +resource 'ICN#' (128) { + { /* array: 2 elements */ + /* [1] */ + $"04 30 40 00 0A 50 A0 00 0B 91 10 02 08 22 08 03" + $"12 24 04 05 20 28 02 09 40 10 01 11 80 0C 00 A1" + $"80 03 FF C2 7E 00 FF 04 01 00 7F 04 03 00 1E 08" + $"04 E0 00 0C 08 E0 00 0A 10 E0 00 09 08 C0 00 06" + $"04 87 FE 04 02 88 01 04 01 88 00 84 00 88 00 44" + $"00 88 00 44 00 88 00 C4 01 10 01 88 02 28 03 10" + $"01 C4 04 E0 00 02 08 00 73 BF FB EE 4C A2 8A 2A" + $"40 AA AA EA 52 AA AA 24 5E A2 8A EA 73 BE FB 8E", + /* [2] */ + $"04 30 40 00 0E 70 E0 00 0F F1 F0 02 0F E3 F8 03" + $"1F E7 FC 07 3F EF FE 0F 7F FF FF 1F FF FF FF BF" + $"FF FF FF FE 7F FF FF FC 01 FF FF FC 03 FF FF F8" + $"07 FF FF FC 0F FF FF FE 1F FF FF FF 0F FF FF FE" + $"07 FF FF FC 03 FF FF FC 01 FF FF FC 00 FF FF FC" + $"00 FF FF FC 00 FF FF FC 01 FF FF F8 03 EF FF F0" + $"01 C7 FC E0 00 03 F8 00 73 BF FB EE 7F BE FB EE" + $"7F BE FB EE 7F BE FB E4 7F BE FB EE 73 BE FB 8E" + } +}; + diff --git a/private/oleauto/tests/disptest/cdisptst.rc b/private/oleauto/tests/disptest/cdisptst.rc new file mode 100644 index 000000000..848ccda54 --- /dev/null +++ b/private/oleauto/tests/disptest/cdisptst.rc @@ -0,0 +1,87 @@ +/*** +*cdisptst.rc +* +* Copyright (C) 1992-93, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* Resource script for cdisptst.exe +* +* +*Revision History: +* +* [00] 27-Apr-93 bradlo: Created (added header). +* +*Implementation Notes: +* +*****************************************************************************/ + +#ifdef _MAC +# include <wlm.h> +#else +# include <windows.h> +#endif +#include "resource.h" + +#include "assert.dlg" + +SUITEDLG DIALOG DISCARDABLE 0, 0, 177, 114 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Executing..." +FONT 8, "MS Sans Serif" +BEGIN + PUSHBUTTON "Cancel",IDCANCEL,65,91,47,17 + LTEXT "",IDD_SUITE_NAME,17,20,145,8 + LTEXT "",IDD_SUITE_TESTNAME,17,42,145,8 + LTEXT "",IDD_SUITE_GUAGE,16,58,145,12 + CTEXT "",IDD_SUITE_PERCENT,78,75,20,9 + LTEXT "Suite:",1002,17,11,20,8 + LTEXT "Test:",1003,17,33,20,8 +END + +AboutBox DIALOG 22, 17, 144, 75 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About IDispatch Test App" +BEGIN + CTEXT "Microsoft Windows" -1, 0, 5, 144, 8 + CTEXT "IDispatch Test Application" -1, 0, 14, 144, 8 + CTEXT "Version 1.0" -1, 0, 34, 144, 8 + DEFPUSHBUTTON "OK" IDOK, 53, 59, 32, 14, WS_GROUP +END + + +DISPTESTMENU MENU DISCARDABLE +BEGIN + MENUITEM "All", IDM_ALL + POPUP "Suite" + BEGIN + MENUITEM "Bstr API", IDM_SUITE_BSTR + MENUITEM "Time API", IDM_SUITE_TIME + MENUITEM "Date Coersions", IDM_SUITE_DATECNV + MENUITEM "Variant API", IDM_SUITE_VARIANT + MENUITEM "SafeArray API", IDM_SUITE_SAFEARRAY + MENUITEM "NLS API", IDM_SUITE_NLS + MENUITEM "Binding", IDM_SUITE_BIND + MENUITEM "Invoke ByVal", IDM_SUITE_INVOKE_BYVAL + MENUITEM "Invoke ByRef", IDM_SUITE_INVOKE_BYREF + MENUITEM "Invoke Multiple", IDM_SUITE_INVOKE_MULTIPLE, GRAYED + MENUITEM "Invoke Array", IDM_SUITE_INVOKE_SAFEARRAY + MENUITEM "Invoke Excepinfo", IDM_SUITE_INVOKE_EXCEPINFO + MENUITEM "Collections", IDM_SUITE_COLLECTION +#if VBA2 + MENUITEM "Early binding", IDM_SUITE_EARLY +#endif + + END + POPUP "Options" + BEGIN + MENUITEM "Named", IDM_OPTIONS_NAMED + MENUITEM "Trace", IDM_OPTIONS_TRACE + MENUITEM "MultiThread", IDM_OPTIONS_MULTITHREAD + END + POPUP "Help" + BEGIN + MENUITEM "About IDispatch Test App...", IDM_HELP_ABOUT + + END +END diff --git a/private/oleauto/tests/disptest/cearly.cpp b/private/oleauto/tests/disptest/cearly.cpp new file mode 100644 index 000000000..17671f7c4 --- /dev/null +++ b/private/oleauto/tests/disptest/cearly.cpp @@ -0,0 +1,319 @@ +/*** +*cearly.cpp +* +* Copyright (C) 1994, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* This file implements the CEarlySuite test object. +* +*Revision History: +* +* [00] 30-Jun-94 bradlo: Created. +* +*Implementation Notes: +* +*****************************************************************************/ + +#include <stdio.h> +#include "disptest.h" +#include "tstsuite.h" +#include "clsid.h" +#include "dualtst.h" + +ASSERTDATA + +HRESULT Properties(IDualTst FAR* pdual); +HRESULT Methods0(IDualTst FAR* pdual); +HRESULT Methods1(IDualTst FAR* pdual); +HRESULT ErrorInfo(IDualTst FAR* pdual); + +struct TEST{ + HRESULT (*pfnTest)(IDualTst FAR*); + OLECHAR FAR* szName; +}; + +#if OE_WIN32 +# define TESTCASE(X) X, L#X +#else +# define TESTCASE(X) X, #X +#endif + + +static TEST rgtest[] = +{ + { TESTCASE(Properties) } + , { TESTCASE(Methods0) } + , { TESTCASE(Methods1) } + , { TESTCASE(ErrorInfo) } +}; + +SUITE_CONSTRUCTION_IMPL(CEarlySuite) + +SUITE_IUNKNOWN_IMPL(CEarlySuite) + + +//--------------------------------------------------------------------- +// ITestSuite Methods +//--------------------------------------------------------------------- + + +STDMETHODIMP +CEarlySuite::GetNameOfSuite(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("Early"), pbstr); +} + +STDMETHODIMP +CEarlySuite::GetNameOfLogfile(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("early.log"), pbstr); +} + +STDMETHODIMP +CEarlySuite::GetTestCount(unsigned int FAR* pcTests) +{ + *pcTests = DIM(rgtest); + return NOERROR; +} + +STDMETHODIMP +CEarlySuite::GetNameOfTest(unsigned int iTest, BSTR FAR* pbstr) +{ + TCHAR *szFmt; + TCHAR buf[128]; + + szFmt = TSTR("Early binding - Universal marshaler"); + + SPRINTF(buf, szFmt, STRING(rgtest[iTest].szName)); + *pbstr = SysAllocString(WIDESTRING(buf)); + return NOERROR; +} + +/*** +*HRESULT CEarlySuite::DoTest(unsigned int) +*Purpose: +* Execute a single CEarlySuite test. +* +*Entry: +* iTest = the index of the test to execute +* +*Exit: +* return value = HRESULT +* +***********************************************************************/ +STDMETHODIMP +CEarlySuite::DoTest(unsigned int iTest) +{ + HRESULT hresult; + IDualTst FAR* pdual; + IDispatch FAR* pdisp; + + if(iTest >= DIM(rgtest)) + return RESULT(E_FAIL); + + pdisp = NULL; + pdual =NULL; + + IfFailGo(CreateObject(OLESTR("sdisptst.cdualtst"), &pdisp), Error); + IfFailGo(pdisp->QueryInterface(IID_IDualTst, (void FAR* FAR*)&pdual), Error); + IfFailGo(rgtest[iTest].pfnTest(pdual), Error); + + hresult = NOERROR; + +Error:; + if(pdisp != NULL) + pdisp->Release(); + if(pdual != NULL) + pdual->Release(); + return hresult; +} + +HRESULT +Properties(IDualTst FAR* pdual) +{ + unsigned char ui1; + short i2; + long i4; + float r4; + double r8; + CY cy; + DATE date; + BSTR bstr; + VARIANT var; + IDispatch FAR* pdisp; + HRESULT hresult; + + bstr = NULL; + pdisp = NULL; + VariantInit(&var); + + IfFailGo(pdual->get_ui1(&ui1), Error); + IfFailGo(pdual->put_ui1(ui1+1), Error); + + IfFailGo(pdual->get_i2(&i2), Error); + IfFailGo(pdual->put_i2(i2+1), Error); + + IfFailGo(pdual->get_i4(&i4), Error); + IfFailGo(pdual->put_i4(i4+1), Error); + + IfFailGo(pdual->get_r4(&r4), Error); + IfFailGo(pdual->put_r4(r4+(float)1.0), Error); + + IfFailGo(pdual->get_r8(&r8), Error); + IfFailGo(pdual->put_r8(r8+1.0), Error); + + IfFailGo(pdual->get_cy(&cy), Error); + cy.Hi += 1; + cy.Lo += 1; + IfFailGo(pdual->put_cy(cy), Error); + + IfFailGo(pdual->get_date(&date), Error); + IfFailGo(pdual->put_date(date+1.0), Error); + + IfFailGo(pdual->get_bstr(&bstr), Error); + IfFailGo(pdual->put_bstr(bstr), Error); + + IfFailGo(pdual->get_disp(&pdisp), Error); + IfFailGo(pdual->putref_disp(pdisp), Error); + IfFailGo(pdual->putref_disp(NULL), Error); + + IfFailGo(pdual->get_var(&var), Error); + VariantClear(&var); + V_VT(&var) = VT_I2; + V_I2(&var) = 42; + IfFailGo(pdual->putref_var(var), Error); + + hresult = NOERROR; + +Error:; + if(pdisp != NULL) + pdisp->Release(); + SysFreeString(bstr); + VariantClear(&var); + return hresult; +} + +HRESULT +Methods0(IDualTst FAR* pdual) +{ + CY cy; + BSTR bstr; + VARIANT var; + IDispatch FAR* pdisp; + HRESULT hresult; + + bstr = NULL; + pdisp = NULL; + VariantInit(&var); + MEMSET(&cy, 0, sizeof(cy)); + + IfFailRet(pdual->QueryInterface(IID_IDispatch, (void FAR* FAR*)&pdisp)); + bstr = SysAllocString(OLESTR("A string!")); + + IfFailGo(pdual->m0(41, 42, 43, 4.2, 4.3, cy, 4.4, bstr, pdisp, var), Error); + IfFailGo(pdual->putref_disp(NULL), Error); // cleanup cycle + + hresult = NOERROR; + +Error:; + if(pdisp != NULL) + pdisp->Release(); + SysFreeString(bstr); + VariantClear(&var); + return hresult; +} + +HRESULT +Methods1(IDualTst FAR* pdual) +{ + unsigned char ui1 = 0; + short i2 = 0; + long i4 = 0; + float r4 = 0; + double r8 = 0; + CY cy; + DATE date = 0; + BSTR bstr; + VARIANT var; + IDispatch FAR* pdisp; + HRESULT hresult; + + cy.Hi = 0; + cy.Lo = 0; + bstr = NULL; + pdisp = NULL; + VariantInit(&var); + + IfFailGo(pdual->m1(&ui1, &i2, &i4, &r4, &r8, &cy, &date, &bstr, &pdisp, &var), Error); + IfFailGo(pdual->m1(&ui1, &i2, &i4, &r4, &r8, &cy, &date, &bstr, &pdisp, &var), Error); + hresult = NOERROR; + +Error:; + if(pdisp != NULL) + pdisp->Release(); + SysFreeString(bstr); + VariantClear(&var); + return hresult; +} + +HRESULT +ErrorInfo(IDualTst FAR* pdual) +{ + HRESULT hresult; + IErrorInfo FAR* perrinfo; + unsigned long dwHelpContext; + BSTR bstrSource, bstrDescription, bstrHelpFile; +#if OE_WIN32 + char rgchTemp[128]; //Unicode-to-ansi conversion buffer +#endif + + perrinfo = NULL; + bstrSource = SysAllocString(OLESTR("foobar - (source)")); + bstrDescription = SysAllocString(OLESTR("a foo type bar (description)")); + bstrHelpFile = SysAllocString(OLESTR("foobar.hlp")); + + hresult = pdual->raise(42, bstrSource, bstrDescription, 13, bstrHelpFile); + + SysFreeString(bstrSource); + SysFreeString(bstrDescription); + SysFreeString(bstrHelpFile); + bstrSource = NULL; + bstrDescription = NULL; + bstrHelpFile = NULL; + + DbPrintf("hresult=0x%lx\n", GetScode(hresult)); + if(GetErrorInfo(0L, &perrinfo) == NOERROR){ + perrinfo->GetSource(&bstrSource); + perrinfo->GetDescription(&bstrDescription); + perrinfo->GetHelpFile(&bstrHelpFile); + perrinfo->GetHelpContext(&dwHelpContext); +#if OE_WIN32 + WideCharToMultiByte(CP_ACP, 0, bstrSource, SysStringLen(bstrSource)+1, + rgchTemp, sizeof(rgchTemp), NULL, NULL); + DbPrintf("Source=\"%Fs\"\n", rgchTemp); + WideCharToMultiByte(CP_ACP, 0, bstrDescription, SysStringLen(bstrDescription)+1, + rgchTemp, sizeof(rgchTemp), NULL, NULL); + DbPrintf("Description=\"%Fs\"\n", rgchTemp); + WideCharToMultiByte(CP_ACP, 0, bstrHelpFile, SysStringLen(bstrHelpFile)+1, + rgchTemp, sizeof(rgchTemp), NULL, NULL); + DbPrintf("HelpFile=\"%Fs\"\n", rgchTemp); +#else + DbPrintf("Source=\"%Fs\"\n", bstrSource); + DbPrintf("Description=\"%Fs\"\n", bstrDescription); + DbPrintf("HelpFile=\"%Fs\"\n", bstrHelpFile); +#endif + DbPrintf("HelpContext=%ld\n", dwHelpContext); + }else{ + DbPrintf("No error info!\n"); + } + + hresult = NOERROR; + + if(perrinfo != NULL) + perrinfo->Release(); + SysFreeString(bstrSource); + SysFreeString(bstrDescription); + SysFreeString(bstrHelpFile); + return hresult; +} diff --git a/private/oleauto/tests/disptest/cinvex.cpp b/private/oleauto/tests/disptest/cinvex.cpp new file mode 100644 index 000000000..d17f86294 --- /dev/null +++ b/private/oleauto/tests/disptest/cinvex.cpp @@ -0,0 +1,156 @@ +/*** +*cinvex.cpp +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* This file implements the CInvokeExcepinfoSuite test object. The +* purpose of this object is to drive testing of the EXCEPINFO +* remoting support. +* +*Revision History: +* +* [00] 02-Dec-92 bradlo: Created. +* +*Implementation Notes: +* +*****************************************************************************/ + +#include "disptest.h" +#include "tstsuite.h" + + +extern OLECHAR FAR* g_szCExcepinfo; + +struct TEST{ + HRESULT (*pfnTest)(int); + NAMEDESC namedesc; + OLECHAR FAR* szName; +}; + +OLECHAR FAR* rgszExcepinfo0[] = { OLESTR("excepinfo0") }; +OLECHAR FAR* rgszExcepinfo1[] = { OLESTR("excepinfo1") }; +OLECHAR FAR* rgszExcepinfo2[] = { OLESTR("excepinfo2") }; + +HRESULT DefExcepinfoTest(int iTest); +HRESULT DefExcepinfoTestW(int iTest); + +static TEST rgtest[] = +{ + { DefExcepinfoTest, + {rgszExcepinfo0, DIM(rgszExcepinfo0)}, + OLESTR("excepinfo-0") + }, + + { DefExcepinfoTest, + {rgszExcepinfo1, DIM(rgszExcepinfo1)}, + OLESTR("excepinfo-1") + }, + + { DefExcepinfoTest, + {rgszExcepinfo2, DIM(rgszExcepinfo2)}, + OLESTR("excepinfo-2") + }, +}; + + +SUITE_CONSTRUCTION_IMPL(CInvokeExcepinfoSuite) + +SUITE_IUNKNOWN_IMPL(CInvokeExcepinfoSuite) + +//--------------------------------------------------------------------- +// ITestSuite Methods +//--------------------------------------------------------------------- + +STDMETHODIMP +CInvokeExcepinfoSuite::GetNameOfSuite(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("Invoke Excepinfo"), pbstr); +} + +STDMETHODIMP +CInvokeExcepinfoSuite::GetNameOfLogfile(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("invex.log"), pbstr); +} + +STDMETHODIMP +CInvokeExcepinfoSuite::GetTestCount(unsigned int FAR* pcTests) +{ + *pcTests = DIM(rgtest); + return NOERROR; +} + +STDMETHODIMP +CInvokeExcepinfoSuite::GetNameOfTest(unsigned int iTest, BSTR FAR* pbstr) +{ + if(iTest >= DIM(rgtest)) + return RESULT(E_FAIL); + return ErrBstrAlloc(rgtest[iTest].szName, pbstr); +} + +HRESULT +DefExcepinfoTest(int iTest) +{ + HRESULT hresult; + EXCEPINFO excepinfo; + DISPID FAR* rgdispid; + IDispatch FAR* pdisp; + DISPPARAMS dispparams; + + + IfFailGo(CreateObject(g_szCExcepinfo, &pdisp), LError0); + + IfFailGo( + GetDISPIDs(pdisp, &rgtest[iTest].namedesc, &rgdispid), + LError1); + + dispparams.cArgs = 0; + dispparams.cNamedArgs = 0; + + excepinfo.bstrSource = NULL; + excepinfo.bstrHelpFile = NULL; + excepinfo.bstrDescription = NULL; + hresult = DoInvoke(pdisp, rgdispid[0], &dispparams, NULL, &excepinfo, NULL); + if(GetScode(hresult) != DISP_E_EXCEPTION) + goto LError2; + + DbPrExcepinfo(&excepinfo); + + SysFreeString(excepinfo.bstrSource); + SysFreeString(excepinfo.bstrDescription); + SysFreeString(excepinfo.bstrHelpFile); + + hresult = NOERROR; + +LError2:; + delete rgdispid; + +LError1:; + pdisp->Release(); + +LError0:; + return hresult; +} + +/*** +*HRESULT CInvokeExcepinfoSuite::DoTest(unsigned int) +*Purpose: +* Execute a single CInvokeExcepinfoSuite test. +* +*Entry: +* iTest = the index of the test to execute +* +*Exit: +* return value = HRESULT +* +***********************************************************************/ +STDMETHODIMP +CInvokeExcepinfoSuite::DoTest(unsigned int iTest) +{ + IfFailRet(rgtest[iTest].pfnTest(iTest)); + + return NOERROR; +} + diff --git a/private/oleauto/tests/disptest/cinvref.cpp b/private/oleauto/tests/disptest/cinvref.cpp new file mode 100644 index 000000000..ca10f566d --- /dev/null +++ b/private/oleauto/tests/disptest/cinvref.cpp @@ -0,0 +1,545 @@ +/*** +*cinvref.cpp +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* This file implements the CInvokeByRefSuite test object. +* +*Revision History: +* +* [00] 30-Oct-92 bradlo: Created. +* +*Implementation Notes: +* +*****************************************************************************/ + +#include <stdio.h> +#include "disptest.h" +#include "tstsuite.h" + +ASSERTDATA + + +extern OLECHAR FAR* g_szCDispTst; + +struct TEST{ + HRESULT (*pfnTest)(IDispatch FAR*, int, int); + NAMEDESC namedesc; + OLECHAR FAR* szName; + VARTYPE vt; +}; + +#if VBA2 +OLECHAR FAR* rgszUI1Ref[] = { OLESTR("ui1ref"), OLESTR("pbval") }; +OLECHAR FAR* rgszUI1RefC[] = { OLESTR("ui1refC"), OLESTR("pbval") }; +#endif //VBA2 +OLECHAR FAR* rgszI2Ref[] = { OLESTR("i2ref"), OLESTR("psval") }; +OLECHAR FAR* rgszI2RefC[] = { OLESTR("i2refC"), OLESTR("psval") }; +OLECHAR FAR* rgszI4Ref[] = { OLESTR("i4ref"), OLESTR("plval") }; +OLECHAR FAR* rgszI4RefC[] = { OLESTR("i4refC"), OLESTR("plval") }; +OLECHAR FAR* rgszR4Ref[] = { OLESTR("r4ref"), OLESTR("pfltval") }; +OLECHAR FAR* rgszR4RefC[] = { OLESTR("r4refC"), OLESTR("pfltval") }; +OLECHAR FAR* rgszR8Ref[] = { OLESTR("r8ref"), OLESTR("pdblval") }; +OLECHAR FAR* rgszR8RefC[] = { OLESTR("r8refC"), OLESTR("pdblval") }; +OLECHAR FAR* rgszCyRef[] = { OLESTR("cyref"), OLESTR("pcyval") }; +OLECHAR FAR* rgszCyRefC[] = { OLESTR("cyrefC"), OLESTR("pcyval") }; +OLECHAR FAR* rgszBstrRef[] = { OLESTR("bstrref"), OLESTR("pbstr") }; +OLECHAR FAR* rgszBstrRefC[] = { OLESTR("bstrrefC"), OLESTR("pbstr") }; +OLECHAR FAR* rgszWBstrRef[] = { OLESTR("wbstrref"), OLESTR("pwbstr") }; +OLECHAR FAR* rgszWBstrRefC[] = { OLESTR("wbstrrefC"), OLESTR("pwbstr") }; +OLECHAR FAR* rgszDateRef[] = { OLESTR("dateref"), OLESTR("pdate") }; +OLECHAR FAR* rgszDateRefC[] = { OLESTR("daterefC"), OLESTR("pdate") }; +OLECHAR FAR* rgszErrorRef[] = { OLESTR("scoderef"), OLESTR("pscode") }; +OLECHAR FAR* rgszErrorRefC[] = { OLESTR("scoderefC"), OLESTR("pscode") }; +OLECHAR FAR* rgszBoolRef[] = { OLESTR("boolref"), OLESTR("pbool") }; +OLECHAR FAR* rgszBoolRefC[] = { OLESTR("boolrefC"), OLESTR("pbool") }; +OLECHAR FAR* rgszDispRef[] = { OLESTR("dispref"), OLESTR("ppdisp") }; + +HRESULT DefByRefTest(IDispatch FAR*, int, int); +HRESULT DispByRefTest(IDispatch FAR*, int, int); + +#if OE_WIN32 +#define TESTCASE(X,Y) X, {rgsz ## Y, DIM( rgsz ## Y)}, L#Y +#else +#define TESTCASE(X,Y) X, {rgsz ## Y, DIM( rgsz ## Y)}, #Y +#endif + +static TEST rgtest[] = +{ + // UNDONE: move this back to the end once its debugged + { TESTCASE(DispByRefTest, DispRef), VT_DISPATCH} + + , { TESTCASE(DefByRefTest, I2Ref), VT_I2} + , { TESTCASE(DefByRefTest, I2RefC), VT_I2} +#if VBA2 + , { TESTCASE(DefByRefTest, UI1Ref), VT_UI1} + , { TESTCASE(DefByRefTest, UI1RefC), VT_UI1} +#endif //VBA2 + , { TESTCASE(DefByRefTest, I4Ref), VT_I4} + , { TESTCASE(DefByRefTest, I4RefC), VT_I4} + , { TESTCASE(DefByRefTest, R4Ref), VT_R4} + , { TESTCASE(DefByRefTest, R8Ref), VT_R8} +#if OE_WIN32 && 0 + , { TESTCASE(DefByRefTest, R4RefC), VT_R4} + , { TESTCASE(DefByRefTest, R8RefC), VT_R8} +#endif + , { TESTCASE(DefByRefTest, CyRef), VT_CY} + , { TESTCASE(DefByRefTest, CyRefC), VT_CY} + , { TESTCASE(DefByRefTest, DateRef), VT_DATE} +#if OE_WIN32 && 0 + , { TESTCASE(DefByRefTest, DateRefC), VT_DATE} +#endif + , { TESTCASE(DefByRefTest, BstrRef), VT_BSTR} + , { TESTCASE(DefByRefTest, BstrRefC), VT_BSTR} + , { TESTCASE(DefByRefTest, ErrorRef), VT_ERROR} + , { TESTCASE(DefByRefTest, ErrorRefC), VT_ERROR} + , { TESTCASE(DefByRefTest, BoolRef), VT_BOOL} + , { TESTCASE(DefByRefTest, BoolRefC), VT_BOOL} + + // REVIEW: needs tests for ByRef IUnknown and IDispatch +}; + +SUITE_CONSTRUCTION_IMPL(CInvokeByRefSuite) + +SUITE_IUNKNOWN_IMPL(CInvokeByRefSuite) + + +//--------------------------------------------------------------------- +// ITestSuite Methods +//--------------------------------------------------------------------- + + +STDMETHODIMP +CInvokeByRefSuite::GetNameOfSuite(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("Invoke ByRef"), pbstr); +} + +STDMETHODIMP +CInvokeByRefSuite::GetNameOfLogfile(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("invref.log"), pbstr); +} + +STDMETHODIMP +CInvokeByRefSuite::GetTestCount(unsigned int FAR* pcTests) +{ + *pcTests = DIM(rgtest); + return NOERROR; +} + +STDMETHODIMP +CInvokeByRefSuite::GetNameOfTest(unsigned int iTest, BSTR FAR* pbstr) +{ + TCHAR *szFmt; + TCHAR buf[128]; + +#if HC_MPW + szFmt = "IDispatch::Invoke(%s)"; +#else + szFmt = TSTR("IDispatch::Invoke(%Fs)"); +#endif + + SPRINTF(buf, szFmt, STRING(rgtest[iTest].szName)); + *pbstr = SysAllocString(WIDESTRING(buf)); + return NOERROR; +} + +#define VT_MAXSIZE VT_UI1 + 1 + +VARIANT g_varRefMem[VT_MAXSIZE]; +VARIANTARG g_vargRef[VT_MAXSIZE]; + +static HRESULT +init() +{ + int i; + CY cy; + VARIANT FAR* pvarRef; + VARIANTARG FAR* pvarg; + + for(i = 0; i < DIM(g_vargRef); ++i){ + V_VT(&g_vargRef[i]) = VT_EMPTY; + V_VT(&g_varRefMem[i]) = VT_EMPTY; + } + +#define VAR_MAKE_BYREF(TYPE, VALUE) \ + pvarRef = &g_varRefMem[VT_ ## TYPE]; \ + pvarg = &g_vargRef[VT_ ## TYPE]; \ + V_VT(pvarRef) = VT_ ## TYPE; \ + V_ ## TYPE ## (pvarRef) = VALUE; \ + V_VT(pvarg) = VT_ ## TYPE | VT_BYREF; \ + V_BYREF(pvarg) = &V_NONE(pvarRef); + +#if VBA2 + VAR_MAKE_BYREF(UI1, 41); +#endif //VBA2 + + VAR_MAKE_BYREF(I2, 42); + + VAR_MAKE_BYREF(I4, 43L); + + VAR_MAKE_BYREF(R4, (float) 42.42); + + VAR_MAKE_BYREF(R8, 43.43); + + cy.Hi=107, cy.Lo=66; + VAR_MAKE_BYREF(CY, cy); + + VAR_MAKE_BYREF(DATE, 107.66); + + VAR_MAKE_BYREF(BSTR, SysAllocString(OLESTR("a binary string"))); + + VAR_MAKE_BYREF(ERROR, S_OK); + + VAR_MAKE_BYREF(BOOL, -1); + + return NOERROR; + +#undef VAR_MAKE_BYREF +} + +static HRESULT +clear() +{ + int i; + + for(i = 0; i < DIM(g_vargRef); ++i) + IfFailRet(VariantClearAll(&g_vargRef[i])); + + return NOERROR; +} + +HRESULT +DefByRefTest(IDispatch FAR* pdisp, int iTest, int fNamed) +{ + VARTYPE vt; + unsigned int uArgErr; + VARIANT varResult; + DISPID FAR* rgdispid; + DISPPARAMS dispparams; + HRESULT hresult, hresultTmp; + VARIANTARG vargExpected, vargExpectedRef; + + + vt = rgtest[iTest].vt; + ASSERT(vt < DIM(g_vargRef)); + + IfFailGo(init(), LError0); + ASSERT((V_VT(&g_vargRef[vt]) & VT_BYREF) != 0); + + IfFailGo( + GetDISPIDs(pdisp, &rgtest[iTest].namedesc, &rgdispid), + LError1); + + // build a variant for the expected out parameter. + // + VariantInit(&vargExpected); + + MEMCPY(&vargExpectedRef, &g_varRefMem[vt], sizeof(vargExpectedRef)); + + V_VT(&vargExpectedRef) = vt; + + // update the in value in the same way we expect the callee to... + // + switch(vt){ +#if VBA2 + case VT_UI1: + ++V_UI1(&vargExpectedRef); + break; +#endif //VBA2 + case VT_I2: + ++V_I2(&vargExpectedRef); + break; + case VT_I4: + ++V_I4(&vargExpectedRef); + break; + case VT_R4: + V_R4(&vargExpectedRef) += (float)1.0; + break; + case VT_R8: + case VT_DATE: + V_R8(&vargExpectedRef) += 1.0; + break; + case VT_CY: + ++V_CY(&vargExpectedRef).Hi; + ++V_CY(&vargExpectedRef).Lo; + break; + case VT_BSTR: + V_BSTR(&vargExpectedRef) = SysAllocString(V_BSTR(&vargExpectedRef)); +#if OE_WIN32 + _wcsupr(V_BSTR(&vargExpectedRef)); +#else + STRUPR(V_BSTR(&vargExpectedRef)); +#endif + break; + case VT_ERROR: + V_ERROR(&vargExpectedRef) = E_FAIL; + break; + case VT_BOOL: + V_BOOL(&vargExpectedRef) = 0; + break; + default: + ASSERT(UNREACHED); + break; + } + + V_VT(&vargExpected) = VT_BYREF | vt; + V_BYREF(&vargExpected) = &V_NONE(&vargExpectedRef); + + dispparams.cArgs = 1; + dispparams.rgvarg = &g_vargRef[rgtest[iTest].vt]; + if(fNamed){ + dispparams.cNamedArgs = 1; + dispparams.rgdispidNamedArgs = &rgdispid[1]; + }else{ + dispparams.cNamedArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + } + + uArgErr = 0; + VariantInit(&varResult); + IfFailGo( + DoInvoke(pdisp, rgdispid[0], &dispparams, &varResult, NULL, &uArgErr), + LError2); + + if(V_VT(&varResult) != VT_ERROR + || V_ERROR(&varResult) != NOERROR + || !VariantCompare(&dispparams.rgvarg[0], &vargExpected)) + { + hresult = RESULT(E_FAIL); + goto LError2; + } + + hresult = NOERROR; + +LError2:; + hresultTmp = VariantClear(&varResult); + ASSERT(hresultTmp == NOERROR); + + hresultTmp = VariantClearAll(&dispparams.rgvarg[0]); + ASSERT(hresultTmp == NOERROR); + + hresultTmp = VariantClearAll(&vargExpected); + ASSERT(hresultTmp == NOERROR); + + delete rgdispid; + +LError1:; + hresultTmp = clear(); + ASSERT(hresultTmp == NOERROR); + +LError0:; + return hresult; +} + +/*** +*HRESULT CInvokeByRefSuite::DoTest(unsigned int) +*Purpose: +* Execute a single CInvokeByRefSuite test. +* +*Entry: +* iTest = the index of the test to execute +* +*Exit: +* return value = HRESULT +* +***********************************************************************/ +STDMETHODIMP +CInvokeByRefSuite::DoTest(unsigned int iTest) +{ + HRESULT hresult; + IDispatch FAR* pdisp; +#if OE_WIN32 && 0 + IDispatchW FAR* pdispW; +#endif + + if(iTest >= DIM(rgtest)) + return RESULT(E_FAIL); + + pdisp = NULL; + + IfFailRet(CreateObject(g_szCDispTst, &pdisp)); + IfFailGo(rgtest[iTest].pfnTest(pdisp, iTest, FALSE), LError0); + IfFailGo(rgtest[iTest].pfnTest(pdisp, iTest, TRUE), LError0); + + hresult = NOERROR; + +LError0:; + if(pdisp != NULL) + pdisp->Release(); + + return hresult; +} + + +// +// A little do-nothing IDispatch object +// + +class CNopDisp : public IDispatch +{ +public: + STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj); + STDMETHOD_(unsigned long, AddRef)(void); + STDMETHOD_(unsigned long, Release)(void); + + STDMETHOD(GetTypeInfoCount)(unsigned int FAR* pctinfo); + + STDMETHOD(GetTypeInfo)(unsigned int itinfo, + LCID lcid, + ITypeInfo FAR* FAR* pptinfo); + + STDMETHOD(GetIDsOfNames)(REFIID riid, + OLECHAR FAR* FAR* rgszNames, + unsigned int cNames, + LCID lcid, + DISPID FAR* rgdispid); + + STDMETHOD(Invoke)(DISPID dispidMember, + REFIID riid, + LCID lcid, + unsigned short wFlags, + DISPPARAMS FAR* pdispparams, + VARIANT FAR* pvarResult, + EXCEPINFO FAR* pexcepinfo, + unsigned int FAR* puArgErr); + + CNopDisp(); + +private: + unsigned long m_cRefs; +}; + +CNopDisp::CNopDisp() +{ + m_cRefs = 1; +} + +STDMETHODIMP +CNopDisp::QueryInterface(REFIID riid, void FAR* FAR* ppv) +{ + if(riid == IID_IUnknown || riid == IID_IDispatch){ + *ppv = this; + }else{ + *ppv = NULL; + return RESULT(E_NOINTERFACE); + } + ++m_cRefs; + return NOERROR; +} + +STDMETHODIMP_(unsigned long) +CNopDisp::AddRef() +{ + return ++m_cRefs; +} + +STDMETHODIMP_(unsigned long) +CNopDisp::Release() +{ + if(--m_cRefs == 0){ + delete this; + return 0; + } + return m_cRefs; +} + +STDMETHODIMP +CNopDisp::GetTypeInfoCount(unsigned int FAR* pctinfo) +{ + *pctinfo = 0; + return NOERROR; +} + +STDMETHODIMP +CNopDisp::GetTypeInfo(unsigned int itinfo, + LCID lcid, + ITypeInfo FAR* FAR* pptinfo) +{ + return RESULT(DISP_E_BADINDEX); // we dont return any +} + +STDMETHODIMP +CNopDisp::GetIDsOfNames(REFIID riid, + OLECHAR FAR* FAR* rgszNames, + unsigned int cNames, + LCID lcid, + DISPID FAR* rgdispid) +{ + return RESULT(DISP_E_UNKNOWNNAME); // because there are no names +} + +STDMETHODIMP +CNopDisp::Invoke(DISPID dispidMember, + REFIID riid, + LCID lcid, + unsigned short wFlags, + DISPPARAMS FAR* pdispparams, + VARIANT FAR* pvarResult, + EXCEPINFO FAR* pexcepinfo, + unsigned int FAR* puArgErr) +{ + return RESULT(DISP_E_MEMBERNOTFOUND); // because there are no members +} + + + +// Tests passing a ByRef IDispatch* +HRESULT +DispByRefTest(IDispatch FAR* pdisp, int unused1, int unused2) +{ + DISPID dispid; + HRESULT hresult; + VARIANTARG varg; + VARIANT varResult; + unsigned int uArgErr = 0; + DISPPARAMS dispparams; + OLECHAR FAR* rgszNames[1]; + IDispatch FAR* pdispLocal; + + pdispLocal = NULL; + + if((pdispLocal = new CNopDisp()) == NULL) + return RESULT(E_OUTOFMEMORY); + + rgszNames[0] = OLESTR("dispref"); + IfFailGo(pdisp->GetIDsOfNames(IID_NULL, + rgszNames, 1, + LOCALE_USER_DEFAULT, + &dispid), Error); + + + V_VT(&varg) = VT_BYREF | VT_DISPATCH; + V_DISPATCHREF(&varg) = &pdispLocal; + + dispparams.cArgs = 1; + dispparams.cNamedArgs = 0; + dispparams.rgvarg = &varg; + dispparams.rgdispidNamedArgs = NULL; + + VariantInit(&varResult); + + IfFailGo(DoInvoke(pdisp, + dispid, + &dispparams, + &varResult, + NULL, + &uArgErr), Error); + + if(V_VT(&varResult) != VT_ERROR || V_ERROR(&varResult) != NOERROR){ + hresult = RESULT(E_FAIL); + goto Error; + } + + hresult = NOERROR; + +Error:; + if(pdispLocal != NULL) + pdispLocal->Release(); + return hresult; +} + + diff --git a/private/oleauto/tests/disptest/cinvsary.cpp b/private/oleauto/tests/disptest/cinvsary.cpp new file mode 100644 index 000000000..d9a24bd74 --- /dev/null +++ b/private/oleauto/tests/disptest/cinvsary.cpp @@ -0,0 +1,641 @@ +/*** +*cinvsary.cpp +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* This file implements the CInvokeSafeArraySuite test object. +* +*Revision History: +* +* [00] 30-Oct-92 bradlo: Created. +* +*Implementation Notes: +* +*****************************************************************************/ + +#include "disptest.h" +#include "tstsuite.h" + +ASSERTDATA + + +#if VBA2 +static OLECHAR FAR* rgszUI1SafeArray[] = {OLESTR("ui1safearray"), OLESTR("psa")}; +#endif //VBA2 +static OLECHAR FAR* rgszI2SafeArray[] = {OLESTR("i2safearray"), OLESTR("psa")}; +static OLECHAR FAR* rgszI4SafeArray[] = {OLESTR("i4safearray"), OLESTR("psa")}; +static OLECHAR FAR* rgszR4SafeArray[] = {OLESTR("r4safearray"), OLESTR("psa")}; +static OLECHAR FAR* rgszR8SafeArray[] = {OLESTR("r8safearray"), OLESTR("psa")}; +static OLECHAR FAR* rgszCySafeArray[] = {OLESTR("cysafearray"), OLESTR("psa")}; +static OLECHAR FAR* rgszDateSafeArray[] = {OLESTR("datesafearray"), OLESTR("psa")}; +static OLECHAR FAR* rgszBstrSafeArray[] = {OLESTR("bstrsafearray"), OLESTR("psa")}; +static OLECHAR FAR* rgszScodeSafeArray[] = {OLESTR("scodesafearray"), OLESTR("psa")}; +static OLECHAR FAR* rgszBoolSafeArray[] = {OLESTR("boolsafearray"), OLESTR("psa")}; +static OLECHAR FAR* rgszVarSafeArray[] = {OLESTR("varsafearray"), OLESTR("psa")}; +// REVIEW: DispSafeArray() ? + +#if VBA2 +static OLECHAR FAR* rgszUI1SafeArrayRef[] = {OLESTR("ui1safearrayref"), OLESTR("psa")}; +#endif //VBA2 +static OLECHAR FAR* rgszI2SafeArrayRef[] = {OLESTR("i2safearrayref"), OLESTR("psa")}; +static OLECHAR FAR* rgszI4SafeArrayRef[] = {OLESTR("i4safearrayref"), OLESTR("psa")}; +static OLECHAR FAR* rgszR4SafeArrayRef[] = {OLESTR("r4safearrayref"), OLESTR("psa")}; +static OLECHAR FAR* rgszR8SafeArrayRef[] = {OLESTR("r8safearrayref"), OLESTR("psa")}; +static OLECHAR FAR* rgszCySafeArrayRef[] = {OLESTR("cysafearrayref"), OLESTR("psa")}; +static OLECHAR FAR* rgszDateSafeArrayRef[] = {OLESTR("datesafearrayref"), OLESTR("psa")}; +static OLECHAR FAR* rgszBstrSafeArrayRef[] = {OLESTR("bstrsafearrayref"), OLESTR("psa")}; +static OLECHAR FAR* rgszScodeSafeArrayRef[] = {OLESTR("scodesafearrayref"), OLESTR("psa")}; +static OLECHAR FAR* rgszBoolSafeArrayRef[] = {OLESTR("boolsafearrayref"), OLESTR("psa")}; +static OLECHAR FAR* rgszVarSafeArrayRef[] = {OLESTR("varsafearrayref"), OLESTR("psa")}; + +#if VBA2 +static OLECHAR FAR* rgszUI1SafeArrayErase[] = {OLESTR("ui1safearrayerase"), OLESTR("psa")}; +#endif //VBA2 +static OLECHAR FAR* rgszI2SafeArrayErase[] = {OLESTR("i2safearrayerase"), OLESTR("psa")}; +static OLECHAR FAR* rgszI4SafeArrayErase[] = {OLESTR("i4safearrayerase"), OLESTR("psa")}; +static OLECHAR FAR* rgszR4SafeArrayErase[] = {OLESTR("r4safearrayerase"), OLESTR("psa")}; +static OLECHAR FAR* rgszR8SafeArrayErase[] = {OLESTR("r8safearrayerase"), OLESTR("psa")}; +static OLECHAR FAR* rgszCySafeArrayErase[] = {OLESTR("cysafearrayerase"), OLESTR("psa")}; +static OLECHAR FAR* rgszDateSafeArrayErase[] = {OLESTR("datesafearrayerase"), OLESTR("psa")}; +static OLECHAR FAR* rgszBstrSafeArrayErase[] = {OLESTR("bstrsafearrayerase"), OLESTR("psa")}; +static OLECHAR FAR* rgszScodeSafeArrayErase[] = {OLESTR("scodesafearrayerase"), OLESTR("psa")}; +static OLECHAR FAR* rgszBoolSafeArrayErase[] = {OLESTR("boolsafearrayerase"), OLESTR("psa")}; +static OLECHAR FAR* rgszVarSafeArrayErase[] = {OLESTR("varsafearrayerase"), OLESTR("psa")}; + +#if VBA2 +static OLECHAR FAR* rgszUI1SafeArrayAlloc[] = {OLESTR("ui1safearrayalloc"), OLESTR("psa")}; +#endif //VBA2 +static OLECHAR FAR* rgszI2SafeArrayAlloc[] = {OLESTR("i2safearrayalloc"), OLESTR("psa")}; +static OLECHAR FAR* rgszI4SafeArrayAlloc[] = {OLESTR("i4safearrayalloc"), OLESTR("psa")}; +static OLECHAR FAR* rgszR4SafeArrayAlloc[] = {OLESTR("r4safearrayalloc"), OLESTR("psa")}; +static OLECHAR FAR* rgszR8SafeArrayAlloc[] = {OLESTR("r8safearrayalloc"), OLESTR("psa")}; +static OLECHAR FAR* rgszCySafeArrayAlloc[] = {OLESTR("cysafearrayalloc"), OLESTR("psa")}; +static OLECHAR FAR* rgszDateSafeArrayAlloc[] = {OLESTR("datesafearrayalloc"), OLESTR("psa")}; +static OLECHAR FAR* rgszBstrSafeArrayAlloc[] = {OLESTR("bstrsafearrayalloc"), OLESTR("psa")}; +static OLECHAR FAR* rgszScodeSafeArrayAlloc[] = {OLESTR("scodesafearrayalloc"), OLESTR("psa")}; +static OLECHAR FAR* rgszBoolSafeArrayAlloc[] = {OLESTR("boolsafearrayalloc"), OLESTR("psa")}; +static OLECHAR FAR* rgszVarSafeArrayAlloc[] = {OLESTR("varsafearrayalloc"), OLESTR("psa")}; + +extern OLECHAR FAR* g_szCSArray; + +// REVIEW: DispSafeArrayRef() ? + +struct TEST { + HRESULT (*pfnTest)(TEST FAR* ptinfo); + NAMEDESC namedesc; + OLECHAR FAR* szName; // test name + VARTYPE vt; +}; + +HRESULT DefSafeArrayTest(TEST FAR* ptinfo); +HRESULT EraseSafeArrayTest(TEST FAR* ptinfo); +HRESULT AllocSafeArrayTest(TEST FAR* ptinfo); +HRESULT SafeArrayCalleeRedim(TEST FAR* ptinfoDummy); +HRESULT SafeArrayReturn(TEST FAR* ptinfoDummy); + +#if OE_WIN32 +#define TESTCASE(X,Y) X, {rgsz ## Y, DIM( rgsz ## Y)}, L#Y +#else +#define TESTCASE(X,Y) X, {rgsz ## Y, DIM( rgsz ## Y)}, #Y +#endif + +static TEST rgtest[] = +{ + {TESTCASE(DefSafeArrayTest, I2SafeArray), VT_I2} +#if VBA2 + , {TESTCASE(DefSafeArrayTest, UI1SafeArray), VT_UI1} +#endif //VBA2 + , {TESTCASE(DefSafeArrayTest, I4SafeArray), VT_I4} + , {TESTCASE(DefSafeArrayTest, R4SafeArray), VT_R4} + , {TESTCASE(DefSafeArrayTest, R8SafeArray), VT_R8} + , {TESTCASE(DefSafeArrayTest, CySafeArray), VT_CY} + , {TESTCASE(DefSafeArrayTest, DateSafeArray), VT_DATE} + , {TESTCASE(DefSafeArrayTest, BstrSafeArray), VT_BSTR} + , {TESTCASE(DefSafeArrayTest, ScodeSafeArray), VT_ERROR} + , {TESTCASE(DefSafeArrayTest, BoolSafeArray), VT_BOOL} + , {TESTCASE(DefSafeArrayTest, VarSafeArray), VT_VARIANT} + + , {TESTCASE(DefSafeArrayTest, I2SafeArrayRef), VT_BYREF|VT_I2} +#if VBA2 + , {TESTCASE(DefSafeArrayTest, UI1SafeArrayRef), VT_BYREF|VT_UI1} +#endif //VBA2 + , {TESTCASE(DefSafeArrayTest, I4SafeArrayRef), VT_BYREF|VT_I4} + , {TESTCASE(DefSafeArrayTest, R4SafeArrayRef), VT_BYREF|VT_R4} + , {TESTCASE(DefSafeArrayTest, R8SafeArrayRef), VT_BYREF|VT_R8} + , {TESTCASE(DefSafeArrayTest, CySafeArrayRef), VT_BYREF|VT_CY} + , {TESTCASE(DefSafeArrayTest, DateSafeArrayRef), VT_BYREF|VT_DATE} + , {TESTCASE(DefSafeArrayTest, BstrSafeArrayRef), VT_BYREF|VT_BSTR} + , {TESTCASE(DefSafeArrayTest, ScodeSafeArrayRef), VT_BYREF|VT_ERROR} + , {TESTCASE(DefSafeArrayTest, BoolSafeArrayRef), VT_BYREF|VT_BOOL} + , {TESTCASE(DefSafeArrayTest, VarSafeArrayRef), VT_BYREF|VT_VARIANT} + + , {SafeArrayCalleeRedim, {NULL, 0}, OLESTR("SafeArray callee redim"), 0} + , {SafeArrayReturn, {NULL, 0}, OLESTR("SafeArray return"), 0} + + , {TESTCASE(EraseSafeArrayTest, I2SafeArrayErase), VT_BYREF|VT_I2} +#if VBA2 + , {TESTCASE(EraseSafeArrayTest, UI1SafeArrayErase), VT_BYREF|VT_UI1} +#endif //VBA2 + , {TESTCASE(EraseSafeArrayTest, I4SafeArrayErase), VT_BYREF|VT_I4} + , {TESTCASE(EraseSafeArrayTest, R4SafeArrayErase), VT_BYREF|VT_R4} + , {TESTCASE(EraseSafeArrayTest, R8SafeArrayErase), VT_BYREF|VT_R8} + , {TESTCASE(EraseSafeArrayTest, CySafeArrayErase), VT_BYREF|VT_CY} + , {TESTCASE(EraseSafeArrayTest, DateSafeArrayErase),VT_BYREF|VT_DATE} + , {TESTCASE(EraseSafeArrayTest, BstrSafeArrayErase),VT_BYREF|VT_BSTR} + , {TESTCASE(EraseSafeArrayTest, ScodeSafeArrayErase),VT_BYREF|VT_ERROR} + , {TESTCASE(EraseSafeArrayTest, BoolSafeArrayErase),VT_BYREF|VT_BOOL} + , {TESTCASE(EraseSafeArrayTest, VarSafeArrayErase), VT_BYREF|VT_VARIANT} + + , {TESTCASE(AllocSafeArrayTest, I2SafeArrayAlloc), VT_BYREF|VT_I2} +#if VBA2 + , {TESTCASE(AllocSafeArrayTest, UI1SafeArrayAlloc), VT_BYREF|VT_UI1} +#endif //VBA2 + , {TESTCASE(AllocSafeArrayTest, I4SafeArrayAlloc), VT_BYREF|VT_I4} + , {TESTCASE(AllocSafeArrayTest, R4SafeArrayAlloc), VT_BYREF|VT_R4} + , {TESTCASE(AllocSafeArrayTest, R8SafeArrayAlloc), VT_BYREF|VT_R8} + , {TESTCASE(AllocSafeArrayTest, CySafeArrayAlloc), VT_BYREF|VT_CY} + , {TESTCASE(AllocSafeArrayTest, DateSafeArrayAlloc),VT_BYREF|VT_DATE} + , {TESTCASE(AllocSafeArrayTest, BstrSafeArrayAlloc),VT_BYREF|VT_BSTR} + , {TESTCASE(AllocSafeArrayTest, ScodeSafeArrayAlloc),VT_BYREF|VT_ERROR} + , {TESTCASE(AllocSafeArrayTest, BoolSafeArrayAlloc),VT_BYREF|VT_BOOL} + , {TESTCASE(AllocSafeArrayTest, VarSafeArrayAlloc), VT_BYREF|VT_VARIANT} +}; + +static SARRAYDESC +rgsarraydesc[] = +{ + {0, {{0,0}, {0,0}, {0,0}, {0,0}, {0,0}}} + , {1, {{2,0}, {0,0}, {0,0}, {0,0}, {0,0}}} + , {1, {{1024,0}, {0,0}, {0,0}, {0,0}, {0,0}}} + , {2, {{2,0}, {2,0}, {0,0}, {0,0}, {0,0}}} + , {2, {{32,0}, {32,0}, {0,0}, {0,0}, {0,0}}} + , {3, {{2,0}, {2,0}, {2,0}, {0,0}, {0,0}}} + , {3, {{10,0}, {10,0}, {10,0}, {0,0}, {0,0}}} + , {4, {{2,0}, {2,0}, {2,0}, {2,0}, {0,0}}} + , {4, {{6,0}, {6,0}, {6,0}, {6,0}, {0,0}}} +}; + + +SUITE_CONSTRUCTION_IMPL(CInvokeSafeArraySuite) + +SUITE_IUNKNOWN_IMPL(CInvokeSafeArraySuite) + + +//--------------------------------------------------------------------- +// ITestSuite Methods +//--------------------------------------------------------------------- + + +STDMETHODIMP +CInvokeSafeArraySuite::GetNameOfSuite(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("Invoke SafeArray"), pbstr); +} + +STDMETHODIMP +CInvokeSafeArraySuite::GetNameOfLogfile(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("invsary.log"), pbstr); +} + +STDMETHODIMP +CInvokeSafeArraySuite::GetTestCount(unsigned int FAR* pcTests) +{ + *pcTests = DIM(rgtest); + return NOERROR; +} + +STDMETHODIMP +CInvokeSafeArraySuite::GetNameOfTest(unsigned int iTest, BSTR FAR* pbstr) +{ + if(iTest >= DIM(rgtest)) + return RESULT(E_INVALIDARG); + + return BuildBstr( + pbstr, + rgtest[iTest].szName); +} + +/*** +*HRESULT CInvokeSafeArraySuite::DoTest(unsigned int) +*Purpose: +* Execute a single CInvokeSafeArraySuite test. +* +*Entry: +* iTest = the index of the test to execute +* +*Exit: +* return value = HRESULT +* +***********************************************************************/ +STDMETHODIMP +CInvokeSafeArraySuite::DoTest(unsigned int iTest) +{ + if(iTest >= DIM(rgtest)) + return RESULT(E_INVALIDARG); + + IfFailRet(rgtest[iTest].pfnTest(&rgtest[iTest])); + return NOERROR; +} + +HRESULT +DefSafeArrayTest(TEST FAR* ptinfo) +{ + long ofs; + unsigned long rcnt; + int i, fNames; + HRESULT hresult; + VARTYPE vt, vtBase; + VARIANT varResult; + SAFEARRAY FAR* psa; + DISPID FAR* rgdispid; + IDispatch FAR* pdisp; + VARIANTARG rgvarg[1]; + DISPPARAMS dispparams; + SARRAYDESC FAR* psadesc; + + + // REVIEW : This is really ugly! The use of templates or abstract + // classes would be much cleaner. + + vt = ptinfo->vt; + vtBase = vt & ~VT_BYREF; + + // if this is a ByRef array test then the "identity offset" is 1, + // because we know that all ByRef methods that we invoke add 1 + // to each element of their given array. (this is how the test + // is defined). + // + ofs = (vt & VT_BYREF) ? 1 : 0; + + IfFailRet(CreateObject(g_szCSArray, &pdisp)); + IfFailGo(GetDISPIDs(pdisp, &ptinfo->namedesc, &rgdispid), LError1); + + VariantInit(&varResult); + for(fNames = 0; fNames <= 1; ++fNames) + { + for(i = 0; i < DIM(rgsarraydesc); ++i) + { + psadesc = &rgsarraydesc[i]; + + if(psadesc->cDims == 0){ + psa = NULL; + }else{ + IfFailGo(SafeArrayCreateIdentity(vtBase, psadesc, &psa), LError2); + } + + V_VT(rgvarg) = VT_ARRAY | vt; + if(vt & VT_BYREF){ + V_ARRAYREF(rgvarg) = &psa; + }else{ + V_ARRAY(rgvarg) = psa; + } + dispparams.cArgs = 1; + dispparams.rgvarg = rgvarg; + + if(fNames){ + dispparams.cNamedArgs = 1; + dispparams.rgdispidNamedArgs = &rgdispid[1]; + }else{ + dispparams.cNamedArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + } + + IfFailGo( + DoInvoke(pdisp, rgdispid[0], &dispparams, &varResult, NULL, NULL), + LError2); + + if(V_VT(&varResult) != VT_ERROR || V_ERROR(&varResult) != NOERROR) + hresult = RESULT(E_FAIL); + + VariantClear(&varResult); + + if(HRESULT_FAILED(hresult)) + goto LError2; + if(psa != NULL){ + IfFailGo(SafeArrayValidateIdentity(vtBase, psa, ofs), LError2); + IfFailGo(SafeArrayDestroy(psa), LError2); + } + } + } + + hresult = NOERROR; + + +LError2:; + delete rgdispid; + +LError1:; + rcnt = pdisp->Release(); + //ASSERT(rcnt == 0); + return hresult; +} + +// Call ByRef SafeArray methods where the callee erases the given array +// +HRESULT +EraseSafeArrayTest(TEST FAR* ptinfo) +{ + int i, fNames; + HRESULT hresult; + unsigned long rcnt; + VARTYPE vt, vtBase; + VARIANT varResult; + SAFEARRAY FAR* psa; + DISPID FAR* rgdispid; + IDispatch FAR* pdisp; + VARIANTARG rgvarg[1]; + DISPPARAMS dispparams; + SARRAYDESC FAR* psadesc; + + vt = ptinfo->vt; + vtBase = vt & ~VT_BYREF; + + IfFailRet(CreateObject(g_szCSArray, &pdisp)); + IfFailGo(GetDISPIDs(pdisp, &ptinfo->namedesc, &rgdispid), LError1); + + VariantInit(&varResult); + for(fNames = 0; fNames <= 1; ++fNames) + { + for(i = 0; i < DIM(rgsarraydesc); ++i) + { + psadesc = &rgsarraydesc[i]; + + if(psadesc->cDims == 0){ + psa = NULL; + }else{ + IfFailGo(SafeArrayCreateIdentity(vtBase, psadesc, &psa), LError2); + } + + ASSERT((vt & VT_BYREF) != 0); + V_VT(rgvarg) = VT_ARRAY | vt; + V_ARRAYREF(rgvarg) = &psa; + dispparams.cArgs = 1; + dispparams.rgvarg = rgvarg; + + if(fNames){ + dispparams.cNamedArgs = 1; + dispparams.rgdispidNamedArgs = &rgdispid[1]; + }else{ + dispparams.cNamedArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + } + + IfFailGo( + DoInvoke(pdisp, rgdispid[0], &dispparams, &varResult, NULL, NULL), + LError2); + + if(V_VT(&varResult) != VT_ERROR || V_ERROR(&varResult) != NOERROR) + hresult = RESULT(E_FAIL); + + VariantClear(&varResult); + + if(HRESULT_FAILED(hresult)) + goto LError2; + + // These methods are supposed to erase the passed array + if(*V_ARRAYREF(&dispparams.rgvarg[0]) != NULL){ + hresult = RESULT(E_FAIL); + goto LError2; + } + } + } + + hresult = NOERROR; + +LError2:; + delete rgdispid; + +LError1:; + rcnt = pdisp->Release(); + //ASSERT(rcnt == 0); + return hresult; +} + +// Call ByRef SafeArray methods where the callee erases the given array +// +HRESULT +AllocSafeArrayTest(TEST FAR* ptinfo) +{ + unsigned long rcnt; + int i, fNames; + HRESULT hresult; + VARTYPE vt, vtBase; + VARIANT varResult; + SAFEARRAY FAR* psa; + DISPID FAR* rgdispid; + IDispatch FAR* pdisp; + VARIANTARG rgvarg[1]; + DISPPARAMS dispparams; + SARRAYDESC FAR* psadesc; + + vt = ptinfo->vt; + vtBase = vt & ~VT_BYREF; + + IfFailRet(CreateObject(g_szCSArray, &pdisp)); + IfFailGo(GetDISPIDs(pdisp, &ptinfo->namedesc, &rgdispid), LError1); + + VariantInit(&varResult); + for(fNames = 0; fNames <= 1; ++fNames) + { + for(i = 0; i < DIM(rgsarraydesc); ++i) + { + psadesc = &rgsarraydesc[i]; + + ASSERT((vt & VT_BYREF) != 0); + + psa = NULL; + V_VT(rgvarg) = VT_ARRAY | vt; + V_ARRAYREF(rgvarg) = &psa; + dispparams.cArgs = 1; + dispparams.rgvarg = rgvarg; + + if(fNames){ + dispparams.cNamedArgs = 1; + dispparams.rgdispidNamedArgs = &rgdispid[1]; + }else{ + dispparams.cNamedArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + } + + IfFailGo( + DoInvoke(pdisp, rgdispid[0], &dispparams, &varResult, NULL, NULL), + LError2); + + if(V_VT(&varResult) != VT_ERROR || V_ERROR(&varResult) != NOERROR) + hresult = RESULT(E_FAIL); + + VariantClear(&varResult); + + if(HRESULT_FAILED(hresult)) + goto LError2; + + // These methods are supposed to allocate an array, and return + // via the out param. + psa = *V_ARRAYREF(&dispparams.rgvarg[0]); + if(psa == NULL){ + hresult = RESULT(E_FAIL); + goto LError2; + } + IfFailGo(SafeArrayValidateIdentity(vtBase, psa, 0L), LError2); + IfFailGo(SafeArrayDestroy(psa), LError2); + } + } + + hresult = NOERROR; + +LError2:; + delete rgdispid; + +LError1:; + rcnt = pdisp->Release(); + //ASSERT(rcnt == 0); + return hresult; +} + +HRESULT +SafeArrayCalleeRedim(TEST FAR* ptinfoDummy) +{ + int i; + unsigned long rcnt; + VARTYPE vt; + HRESULT hresult; + SAFEARRAY FAR* psa; + DISPID FAR* rgdispid; + IDispatch FAR* pdisp; + VARIANTARG rgvarg[2]; + DISPPARAMS dispparams; + VARIANT varResult; + SARRAYDESC FAR* psadesc; +static OLECHAR FAR* rgszNames[] = {OLESTR("safearrayredim"), OLESTR("vt"), OLESTR("ppsa")}; +static NAMEDESC namedesc = {rgszNames, DIM(rgszNames)}; + + UNUSED(ptinfoDummy); + + vt = VT_VARIANT; + + IfFailRet(CreateObject(g_szCSArray, &pdisp)); + IfFailGo(GetDISPIDs(pdisp, &namedesc, &rgdispid), LError1); + + VariantInit(&varResult); + + for(i = 0; i < DIM(rgsarraydesc); ++i){ + psadesc = &rgsarraydesc[i]; + + if(psadesc->cDims == 0) // ignore this one + continue; + + IfFailGo(SafeArrayCreateIdentity(vt, psadesc, &psa), LError2); + + V_VT(&rgvarg[0]) = VT_ARRAY | VT_BYREF | vt; + V_ARRAYREF(&rgvarg[0]) = &psa; + + V_VT(&rgvarg[1]) = VT_I2; + V_I2(&rgvarg[1]) = vt; + + dispparams.cArgs = 2; + dispparams.rgvarg = rgvarg; + dispparams.cNamedArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + IfFailGo( + DoInvoke(pdisp, rgdispid[0], &dispparams, &varResult, NULL, NULL), + LError2); + + if(V_VT(&varResult) != VT_ERROR || V_ERROR(&varResult) != NOERROR) + hresult = RESULT(E_FAIL); + + VariantClear(&varResult); + + if(HRESULT_FAILED(hresult)) + goto LError2; + IfFailGo(SafeArrayValidateIdentity(vt, psa, 0L), LError2); + IfFailGo(SafeArrayDestroy(psa), LError2); + } + + hresult = NOERROR; + +LError2:; + delete rgdispid; + +LError1:; + rcnt = pdisp->Release(); + //ASSERT(rcnt == 0); + return hresult; +} + +// test invoking a method that returns a SafeArray +HRESULT +SafeArrayReturn(TEST FAR* ptinfoDummy) +{ + unsigned long rcnt; + VARTYPE vt; + NAMEDESC namedesc; + SARRAYDESC sadesc; + VARIANT varResult; + SAFEARRAY FAR* psa; + DISPID FAR* rgdispid; + IDispatch FAR* pdisp; + VARIANTARG rgvarg[2]; + DISPPARAMS dispparams; + HRESULT hresult, hrTmp; + +static OLECHAR FAR* rgszNames[] = {OLESTR("i2safearrayret"), OLESTR("var")}; + + UNUSED(ptinfoDummy); + + namedesc.rgszNames = rgszNames; + namedesc.cNames = DIM(rgszNames); + + sadesc.cDims = 1; + sadesc.rgsabound[0].lLbound = 0; + sadesc.rgsabound[0].cElements = 2; + + vt = VT_I2; + psa = NULL; + rgdispid = NULL; + VariantInit(&varResult); + + IfFailGo(CreateObject(g_szCSArray, &pdisp), LError0); + IfFailGo(GetDISPIDs(pdisp, &namedesc, &rgdispid), LError0); + + IfFailGo(SafeArrayCreateIdentity(vt, &sadesc, &psa), LError0); + + V_VT(&rgvarg[0]) = VT_ARRAY | vt; + V_ARRAY(&rgvarg[0]) = psa; + + dispparams.cArgs = 1; + dispparams.rgvarg = rgvarg; + dispparams.cNamedArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + + IfFailGo(DoInvoke(pdisp, rgdispid[0], &dispparams, + &varResult, NULL, NULL), + LError0); + if(V_VT(&varResult) != (VT_ARRAY | VT_I2)){ + hresult = RESULT(E_FAIL); + goto LError0; + } + + IfFailGo(SafeArrayValidateIdentity(vt, psa, 0L), LError0); + + hresult = NOERROR; + +LError0:; + VariantClear(&varResult); + + if(psa != NULL){ + hrTmp = SafeArrayDestroy(psa); + ASSERT(hrTmp == NOERROR); + } + + if(pdisp != NULL){ + rcnt = pdisp->Release(); + //ASSERT(rcnt == 0); + } + if(rgdispid != NULL) + delete rgdispid; + + return hresult; +} diff --git a/private/oleauto/tests/disptest/cinvval.cpp b/private/oleauto/tests/disptest/cinvval.cpp new file mode 100644 index 000000000..3ec3245eb --- /dev/null +++ b/private/oleauto/tests/disptest/cinvval.cpp @@ -0,0 +1,571 @@ +/*** +*cinvval.cpp +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* This file implements the CInvokeByValSuite test object. +* +*Revision History: +* +* [00] 30-Oct-92 bradlo: Created. +* +*Implementation Notes: +* +*****************************************************************************/ + +#include <stdio.h> +#include "disptest.h" +#include "tstsuite.h" + +ASSERTDATA + +extern OLECHAR FAR* g_szCDispTst; + +struct TEST{ + HRESULT (*pfnTest)(IDispatch FAR*, int, int); + NAMEDESC namedesc; + OLECHAR FAR* szName; +}; + +OLECHAR FAR* rgszHello[] = { OLESTR("hello") }; +#if VBA2 +OLECHAR FAR* rgszUI1[] = { OLESTR("ui1"), OLESTR("bval") }; +OLECHAR FAR* rgszUI1C[] = { OLESTR("ui1C"), OLESTR("bval") }; +#endif //VBA2 +OLECHAR FAR* rgszI2[] = { OLESTR("i2"), OLESTR("sval") }; +OLECHAR FAR* rgszI2C[] = { OLESTR("i2C"), OLESTR("sval") }; +OLECHAR FAR* rgszI4[] = { OLESTR("i4"), OLESTR("lval") }; +OLECHAR FAR* rgszI4C[] = { OLESTR("i4C"), OLESTR("lval") }; +OLECHAR FAR* rgszR4[] = { OLESTR("r4"), OLESTR("fltval") }; +OLECHAR FAR* rgszR4C[] = { OLESTR("r4C"), OLESTR("fltval") }; +OLECHAR FAR* rgszR8[] = { OLESTR("r8"), OLESTR("dblval") }; +OLECHAR FAR* rgszR8C[] = { OLESTR("r8C"), OLESTR("dblval") }; +OLECHAR FAR* rgszCy[] = { OLESTR("cy"), OLESTR("cyval") }; +OLECHAR FAR* rgszCyC[] = { OLESTR("cyC"), OLESTR("cyval") }; +OLECHAR FAR* rgszDate[] = { OLESTR("date"), OLESTR("date") }; +OLECHAR FAR* rgszDateC[] = { OLESTR("dateC"), OLESTR("date") }; +OLECHAR FAR* rgszBstr[] = { OLESTR("bstr"), OLESTR("bstr") }; +OLECHAR FAR* rgszBstrC[] = { OLESTR("bstrC"), OLESTR("bstr") }; +OLECHAR FAR* rgszScode[] = { OLESTR("scode"), OLESTR("scode") }; +OLECHAR FAR* rgszScodeC[] = { OLESTR("scodeC"), OLESTR("scode") }; +OLECHAR FAR* rgszBool[] = { OLESTR("bool"), OLESTR("bool") }; +OLECHAR FAR* rgszBoolC[] = { OLESTR("boolC"), OLESTR("bool") }; +OLECHAR FAR* rgszVariant[] = { OLESTR("var"), OLESTR("varg") }; +OLECHAR FAR* rgszVariantC[] = { OLESTR("varC"), OLESTR("varg") }; +OLECHAR FAR* rgszDispatch[] = { OLESTR("NewCDispTst") }; +OLECHAR FAR* rgszDispatchC[]= { OLESTR("NewCDispTstC") }; + +OLECHAR FAR* rgszStdI2I4R4R8[] = { + OLESTR("stdI2I4R4R8") +#if VBA2 + , OLESTR("bval") +#endif //VBA2 + , OLESTR("sval") + , OLESTR("lval") + , OLESTR("fltval") + , OLESTR("dblval") +}; +OLECHAR FAR* rgszAltI2I4R4R8[] = { + OLESTR("altI2I4R4R8") +#if VBA2 + , OLESTR("bval") +#endif //VBA2 + , OLESTR("sval") + , OLESTR("lval") + , OLESTR("fltval") + , OLESTR("dblval") +}; + +OLECHAR FAR* rgszStdAll[] = { + OLESTR("stdall") +#if VBA2 + , OLESTR("bval") +#endif //VBA2 + , OLESTR("sval") + , OLESTR("lval") + , OLESTR("fltval") + , OLESTR("dblval") + , OLESTR("cyval") + , OLESTR("date") + , OLESTR("bstr") + , OLESTR("sc") + , OLESTR("bool") +}; +OLECHAR FAR* rgszAltAll[] = { + OLESTR("altall") +#if VBA2 + , OLESTR("bval") +#endif //VBA2 + , OLESTR("sval") + , OLESTR("lval") + , OLESTR("fltval") + , OLESTR("dblval") + , OLESTR("cyval") + , OLESTR("date") + , OLESTR("bstr") + , OLESTR("sc") + , OLESTR("bool") +}; + +HRESULT InvokeByValHello(IDispatch FAR*, int, int); +HRESULT InvokeByValDefault(IDispatch FAR*, int, int); +HRESULT InvokeByValDisp(IDispatch FAR*, int, int); + +#if OE_WIN32 +# define TESTCASE(X,Y) X, {rgsz ## Y, DIM( rgsz ## Y)}, L#Y +#else +# define TESTCASE(X,Y) X, {rgsz ## Y, DIM( rgsz ## Y)}, #Y +#endif + + +static TEST rgtest[] = +{ + { TESTCASE(InvokeByValHello,Hello) } +#if VBA2 + , { TESTCASE(InvokeByValDefault,UI1) } + , { TESTCASE(InvokeByValDefault,UI1C) } +#endif //VBA2 + , { TESTCASE(InvokeByValDefault,I2) } + , { TESTCASE(InvokeByValDefault,I2C) } + , { TESTCASE(InvokeByValDefault,I4) } + , { TESTCASE(InvokeByValDefault,I4C) } +#if !OE_WIN16 + , { TESTCASE(InvokeByValDefault,R4) } +#endif + , { TESTCASE(InvokeByValDefault,R4C) } + +#if !OE_WIN16 + , { TESTCASE(InvokeByValDefault,R8) } +#endif + , { TESTCASE(InvokeByValDefault,R8C) } + + , { TESTCASE(InvokeByValDefault,Cy) } + , { TESTCASE(InvokeByValDefault,CyC) } +#if !OE_WIN16 + , { TESTCASE(InvokeByValDefault,Date) } +#endif + + , { TESTCASE(InvokeByValDefault,DateC) } + + , { TESTCASE(InvokeByValDefault,Bstr) } + , { TESTCASE(InvokeByValDefault,BstrC) } + + , { TESTCASE(InvokeByValDefault,Scode) } + , { TESTCASE(InvokeByValDefault,ScodeC) } + , { TESTCASE(InvokeByValDefault,Bool) } + , { TESTCASE(InvokeByValDefault,BoolC) } + , { TESTCASE(InvokeByValDefault,Variant) } + , { TESTCASE(InvokeByValDefault,VariantC) } + , { TESTCASE(InvokeByValDisp,Dispatch) } + , { TESTCASE(InvokeByValDisp,DispatchC) } + + , { TESTCASE(InvokeByValDefault,StdI2I4R4R8) } + , { TESTCASE(InvokeByValDefault,AltI2I4R4R8) } + , { TESTCASE(InvokeByValDefault,StdAll) } + , { TESTCASE(InvokeByValDefault,AltAll) } +}; + +SUITE_CONSTRUCTION_IMPL(CInvokeByValSuite) + +SUITE_IUNKNOWN_IMPL(CInvokeByValSuite) + + +//--------------------------------------------------------------------- +// ITestSuite Methods +//--------------------------------------------------------------------- + + +STDMETHODIMP +CInvokeByValSuite::GetNameOfSuite(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("Invoke ByVal"), pbstr); +} + +STDMETHODIMP +CInvokeByValSuite::GetNameOfLogfile(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("invval.log"), pbstr); +} + +STDMETHODIMP +CInvokeByValSuite::GetTestCount(unsigned int FAR* pcTests) +{ + *pcTests = DIM(rgtest); + + return NOERROR; +} + +STDMETHODIMP +CInvokeByValSuite::GetNameOfTest(unsigned int iTest, BSTR FAR* pbstr) +{ + TCHAR *szFmt; + TCHAR buf[128]; + + szFmt = TSTR("IDispatch::Invoke(%Fs)"); + + SPRINTF(buf, szFmt, STRING(rgtest[iTest].szName)); + *pbstr = SysAllocString(WIDESTRING(buf)); + return NOERROR; +} + +/*** +*HRESULT CInvokeByValSuite::DoTest(unsigned int) +*Purpose: +* Execute a single CInvokeByValSuite test. +* +*Entry: +* iTest = the index of the test to execute +* +*Exit: +* return value = HRESULT +* +***********************************************************************/ +STDMETHODIMP +CInvokeByValSuite::DoTest(unsigned int iTest) +{ + HRESULT hresult; + IDispatch FAR* pdisp; + + + if(iTest >= DIM(rgtest)) + return RESULT(E_FAIL); + + pdisp = NULL; + + IfFailRet(CreateObject(g_szCDispTst, &pdisp)); + IfFailGo(rgtest[iTest].pfnTest(pdisp, iTest, FALSE), LError0); + IfFailGo(rgtest[iTest].pfnTest(pdisp, iTest, TRUE), LError0); + + hresult = NOERROR; + +LError0:; + if(pdisp != NULL) + pdisp->Release(); + + return hresult; +} + + +#if VBA2 +VARIANTARG g_rgvarg[21]; +#else //VBA2 +VARIANTARG g_rgvarg[20]; +#endif //VBA2 + +static HRESULT +init() +{ + VARIANTARG FAR* pvarg; + + pvarg = g_rgvarg; + + V_VT(pvarg) = VT_EMPTY; + pvarg++; + + V_VT(pvarg) = VT_NULL; + pvarg++; + +#if VBA2 + V_VT(pvarg) = VT_UI1; V_UI1(pvarg) = 41; + pvarg++; +#endif //VBA2 + + V_VT(pvarg) = VT_I2; V_I2(pvarg) = 42; + pvarg++; + + V_VT(pvarg) = VT_I4; V_I4(pvarg) = 43L; + pvarg++; + + V_VT(pvarg) = VT_R4; V_R4(pvarg) = 42.42; + pvarg++; + + V_VT(pvarg) = VT_R8; V_R8(pvarg) = 43.43; + pvarg++; + + V_VT(pvarg) = VT_CY; V_CY(pvarg).Hi = 0; V_CY(pvarg).Lo = 6; + pvarg++; + + V_VT(pvarg) = VT_CY; V_CY(pvarg).Hi = 107; V_CY(pvarg).Lo = 66; + pvarg++; + + V_VT(pvarg) = VT_DATE; V_DATE(pvarg) = 0.6; + pvarg++; + + V_VT(pvarg) = VT_DATE; V_DATE(pvarg) = 107.66; + pvarg++; + + V_VT(pvarg) = VT_BSTR; V_BSTR(pvarg) = SysAllocString(OLESTR("binary string")); + pvarg++; + + V_VT(pvarg) = VT_BSTR; V_BSTR(pvarg) = SysAllocString(NULL); + pvarg++; + + V_VT(pvarg) = VT_BSTR; V_BSTR(pvarg) = SysAllocString(OLESTR("42")); + pvarg++; + + V_VT(pvarg) = VT_BSTR; V_BSTR(pvarg) = SysAllocString(OLESTR("43.43")); + pvarg++; + + V_VT(pvarg) = VT_BSTR; V_BSTR(pvarg) = SysAllocString(OLESTR("#TRUE#")); + pvarg++; + + V_VT(pvarg) = VT_BSTR; V_BSTR(pvarg) = SysAllocString(OLESTR("#FALSE#")); + pvarg++; + + V_VT(pvarg) = VT_ERROR; V_ERROR(pvarg) = S_OK; + pvarg++; + + V_VT(pvarg) = VT_ERROR; V_ERROR(pvarg) = E_FAIL; + pvarg++; + + V_VT(pvarg) = VT_BOOL; V_BOOL(pvarg) = 0; + pvarg++; + + V_VT(pvarg) = VT_BOOL; V_BOOL(pvarg) = -1; + pvarg++; + + ASSERT(pvarg == &g_rgvarg[DIM(g_rgvarg)]); + + return NOERROR; +} + +static HRESULT +clear() +{ + VARIANTARG FAR* pvarg; + + for(pvarg = g_rgvarg; pvarg < &g_rgvarg[DIM(g_rgvarg)]; ++pvarg){ + IfFailRet(VariantClear(pvarg)); + } + + return NOERROR; +} + +HRESULT +InvokeByValDefault(IDispatch FAR* pdisp, int iTest, int fNamed) +{ + unsigned int uArgErr; + int i, j, cArgs; + NAMEDESC FAR* pnd; + VARIANT varResult; + DISPID FAR* rgdispid; + DISPPARAMS dispparams; + HRESULT hresult, hresultTmp; + + + pnd = &rgtest[iTest].namedesc; + hresult = GetDISPIDs(pdisp, pnd, &rgdispid); + + if(HRESULT_FAILED(hresult)){ +#if OE_WIN32 +// when doing 16/32 interop, 3 tests aren't available when talking to a +// 16-bit server. No easy away to tell, so if we get the right error +// on the right 3 tests, we'll pretend it worked. Baselines will catch +// us if there's a problem doing 32-32. + SCODE sc = GetScode(hresult); + if (sc == DISP_E_UNKNOWNNAME) { + if (!wcsicmp(OLESTR("r4"), pnd->rgszNames[0]) + || !wcsicmp(OLESTR("r8"), pnd->rgszNames[0]) + || !wcsicmp(OLESTR("date"), pnd->rgszNames[0])) { + return NOERROR; // pretend we worked + } + } +#endif //OE_WIN32 + return hresult; + } + + cArgs = pnd->cNames - 1; + + dispparams.cArgs = cArgs; + dispparams.rgvarg = NULL; + if(!fNamed){ + dispparams.cNamedArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + }else{ + dispparams.cNamedArgs = cArgs; + dispparams.rgdispidNamedArgs = &rgdispid[1]; + } + + if(cArgs > 0){ + if((dispparams.rgvarg = new FAR VARIANT [cArgs]) == NULL) + return RESULT(E_OUTOFMEMORY); + for(j = 0; j < cArgs; ++j) + VariantInit(&dispparams.rgvarg[j]); + } + + init(); + + for(i = 0; i < DIM(g_rgvarg); ++i){ + + if(i > 0 && V_VT(&g_rgvarg[i]) == VT_EMPTY) + continue; + + for(j = 0; j < cArgs; ++j){ + IfFailGo(VariantCopy(&dispparams.rgvarg[j], &g_rgvarg[i]), LError0); + } + + uArgErr = 0; + MEMSET(&varResult, -1, sizeof(varResult)); + VariantInit(&varResult); + + hresult = DoInvoke( + pdisp, rgdispid[0], &dispparams, &varResult, NULL, &uArgErr); + + for(j = 0; j < cArgs; ++j){ + hresultTmp = VariantClear(&dispparams.rgvarg[j]); + ASSERT(hresultTmp == NOERROR); + } + + hresultTmp = VariantClear(&varResult); + ASSERT(hresultTmp == NOERROR); + + if(HRESULT_FAILED(hresult)){ + SCODE sc = GetScode(hresult); + if (sc != E_NOTIMPL + && sc != DISP_E_OVERFLOW + && sc != DISP_E_TYPEMISMATCH) + goto LError0; + } + } + + hresult = NOERROR; + +LError0:; + if(dispparams.rgvarg != NULL) + delete dispparams.rgvarg; + + hresultTmp = clear(); + ASSERT(hresultTmp == NOERROR); + + delete rgdispid; + + return hresult; +} + +HRESULT +InvokeByValHello(IDispatch FAR* pdisp, int iTest, int fNamed) +{ + HRESULT hresult; + DISPID FAR* rgdispid; + DISPPARAMS dispparams; + + UNUSED(fNamed); + + IfFailRet( + GetDISPIDs( + pdisp, &rgtest[iTest].namedesc, &rgdispid)); + + dispparams.cArgs = 0; + dispparams.cNamedArgs = 0; + IfFailGo( + DoInvoke(pdisp, rgdispid[0], &dispparams, NULL, NULL, NULL), + LError0); + + hresult = NOERROR; + +LError0:; + delete rgdispid; + + return hresult; +} + +HRESULT +InvokeByValDisp(IDispatch FAR* pdisp, int iTest, int fNamed) +{ + HRESULT hresult; + VARIANT varResult; + DISPID dispidMember; + DISPID FAR* rgdispid; + DISPPARAMS dispparams; + OLECHAR FAR* rgszNames[1]; + + IUnknown FAR* punk; + IDispatch FAR* pdisp0, FAR* pdisp1; + + UNUSED(fNamed); + + hresult = NOERROR; + + IfFailRet( + GetDISPIDs(pdisp, &rgtest[iTest].namedesc, &rgdispid)); + + dispparams.cArgs = 0; + dispparams.rgvarg = NULL; + dispparams.cNamedArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + + MEMSET(&varResult, -1, sizeof(varResult)); + VariantInit(&varResult); + + IfFailGo( + DoInvoke(pdisp, rgdispid[0], &dispparams, &varResult, NULL, NULL), + LError0); + + if(V_VT(&varResult) != VT_DISPATCH){ + hresult = RESULT(E_FAIL); + goto LError0; + } + + /* check out the IDispatch* we got back */ + + // QI to IUnknown and back + + pdisp0 = V_DISPATCH(&varResult); + pdisp0->AddRef(); + + hresult = VariantClear(&varResult); + ASSERT(!HRESULT_FAILED(hresult)); + + hresult = pdisp0->QueryInterface(IID_IUnknown, (void FAR* FAR*)&punk); + DbPrintf("QueryInterface(IUnknown) => %s\n", + DbSzOfScode(GetScode(hresult))); + if(HRESULT_FAILED(hresult)) + goto LError1; + + hresult = punk->QueryInterface(IID_IDispatch, (void FAR* FAR*)&pdisp1); + DbPrintf("QueryInterface(IDispatch) => %s\n", + DbSzOfScode(GetScode(hresult))); + if(HRESULT_FAILED(hresult)) + goto LError2; + + /* invoke Hello() method on pdisp0 and pdisp1 */ + + dispparams.cArgs = 0; + dispparams.cNamedArgs = 0; + + rgszNames[0] = OLESTR("hello"); + + IfFailGo( + pdisp0->GetIDsOfNames( + IID_NULL, rgszNames, 1, LOCALE_USER_DEFAULT, &dispidMember), + LError3); + + IfFailGo( + DoInvoke(pdisp0, dispidMember, &dispparams, NULL, NULL, NULL), LError3); + + IfFailGo( + pdisp1->GetIDsOfNames( + IID_NULL, rgszNames, 1, LOCALE_USER_DEFAULT, &dispidMember), + LError3); + + IfFailGo( + DoInvoke(pdisp1, dispidMember, &dispparams, NULL, NULL, NULL), LError3); + + hresult = NOERROR; + +LError3: + pdisp1->Release(); + +LError2: + punk->Release(); + +LError1: + pdisp0->Release(); + +LError0:; + delete rgdispid; + + return hresult; +} diff --git a/private/oleauto/tests/disptest/clsid.h b/private/oleauto/tests/disptest/clsid.h new file mode 100644 index 000000000..9a62d1290 --- /dev/null +++ b/private/oleauto/tests/disptest/clsid.h @@ -0,0 +1,31 @@ +/*** +*clsid.h +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +`* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* This file defines the CLSIDs referenced by the IDispatch test app. +* +*Implementation Notes: +* +*****************************************************************************/ + +DEFINE_OLEGUID(IID_ITestSuite, 0x00020440, 0, 0); + +DEFINE_OLEGUID(CLSID_CPoly, 0x00020462, 0, 0); +DEFINE_OLEGUID(CLSID_CPoint, 0x00020463, 0, 0); + +DEFINE_OLEGUID(CLSID_CPoly2, 0x00020464, 0, 0); +DEFINE_OLEGUID(CLSID_CPoint2, 0x00020465, 0, 0); + +DEFINE_OLEGUID(CLSID_CCalc, 0x00020467, 0, 0); + +DEFINE_OLEGUID(CLSID_SDispTst_CSArray, 0x00020461, 0, 0); +DEFINE_OLEGUID(CLSID_SDispTst_CDispTst, 0x00020460, 0, 0); +DEFINE_OLEGUID(CLSID_SDispTst_CExcepinfo, 0x00020466, 0, 0); +DEFINE_OLEGUID(CLSID_SDispTst_CAppObject, 0x00020468, 0, 0); + +#if VBA2 +DEFINE_OLEGUID(IID_IDualTst, 0x00020475, 0, 0); +#endif diff --git a/private/oleauto/tests/disptest/cnls.cpp b/private/oleauto/tests/disptest/cnls.cpp new file mode 100644 index 000000000..540300f85 --- /dev/null +++ b/private/oleauto/tests/disptest/cnls.cpp @@ -0,0 +1,421 @@ +/*** +*cnls.cpp +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* This file implements the CNlsSuite test object. +* +*Revision History: +* +* [00] 30-Oct-92 bradlo: Created. +* +*Implementation Notes: +* +*****************************************************************************/ + +#include "disptest.h" +#include "tstsuite.h" + + +struct TEST { + HRESULT (*pfnTest)(LCID); + OLECHAR FAR* szName; + LCID lcid; +}; + +HRESULT DumpNlsInfo(LCID lcid); +HRESULT NlsAPIRaid28(LCID ignore); +HRESULT NlsAPIRaid418(LCID ignore); +HRESULT OB4589(LCID ignore); +HRESULT NlsCurrentLCID(LCID ignore); + +#if !defined(WIN32) +#define NLSTEST(X) { DumpNlsInfo, OLESTR("lcid = ") #X, X } +#endif +static TEST rgtest[] = { +#if defined(WIN32) + { DumpNlsInfo, OLESTR("lcid = 0x0409"), 0x0409} + , { NlsCurrentLCID, OLESTR("CurrentLcid"), 0 } +#else //WIN32 + NLSTEST(0x040c) + , NLSTEST(0x0407) + , NLSTEST(0x0409) + , NLSTEST(0x0809) + , NLSTEST(0x0c09) + , NLSTEST(0x1009) + , NLSTEST(0x1409) + , NLSTEST(0x0406) + , NLSTEST(0x0413) + , NLSTEST(0x0813) + , NLSTEST(0x040b) + , NLSTEST(0x080c) + , NLSTEST(0x0c0c) + , NLSTEST(0x100c) + , NLSTEST(0x0807) + , NLSTEST(0x0c07) + , NLSTEST(0x0410) + , NLSTEST(0x0810) + , NLSTEST(0x040a) + , NLSTEST(0x080a) + , NLSTEST(0x0c0a) + , NLSTEST(0x041d) + , NLSTEST(0x0414) + , NLSTEST(0x0416) + , NLSTEST(0x0816) + , NLSTEST(0x0405) + , NLSTEST(0x040e) + , NLSTEST(0x0415) + , NLSTEST(0x041b) + , NLSTEST(0x0419) + , NLSTEST(0x0403) + , NLSTEST(0x0408) + , NLSTEST(0x040f) + , NLSTEST(0x041f) + , NLSTEST(0x0814) + , NLSTEST(0x1809) +// BIDI locales + , NLSTEST(0x040d) + , NLSTEST(0x0401) + , NLSTEST(0x0801) + , NLSTEST(0x0c01) + , NLSTEST(0x1001) + , NLSTEST(0x1401) + , NLSTEST(0x1801) + , NLSTEST(0x1c01) + , NLSTEST(0x2001) + , NLSTEST(0x2401) + , NLSTEST(0x2801) + , NLSTEST(0x2c01) + , NLSTEST(0x3001) + , NLSTEST(0x3401) + , NLSTEST(0x3801) + , NLSTEST(0x3C01) + , NLSTEST(0x4001) + , NLSTEST(0x0429) + +// DBCS locales + , NLSTEST(0x0404) + , NLSTEST(0x0804) + , NLSTEST(0x0411) + , NLSTEST(0x0412) + + , { NlsCurrentLCID, OLESTR("CurrentLcid"), 0 } + + // regression tests + , { NlsAPIRaid28, OLESTR("raid:oleprog#28"), 0 } + , { NlsAPIRaid418, OLESTR("raid:oleprog#418"), 0 } + , { OB4589, OLESTR("raid:ob#4589"), 0 } +#endif //WIN32 +}; +#undef NLSTEST + + +SUITE_CONSTRUCTION_IMPL(CNlsSuite) + +SUITE_IUNKNOWN_IMPL(CNlsSuite) + +//--------------------------------------------------------------------- +// ITestSuite Methods +//--------------------------------------------------------------------- + +STDMETHODIMP +CNlsSuite::GetNameOfSuite(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("NLS API"), pbstr); +} + +STDMETHODIMP +CNlsSuite::GetNameOfLogfile(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("nlsapi.log"), pbstr); +} + +STDMETHODIMP +CNlsSuite::GetTestCount(unsigned int FAR* pcTests) +{ + *pcTests = DIM(rgtest); + return NOERROR; +} + +STDMETHODIMP +CNlsSuite::GetNameOfTest(unsigned int iTest, BSTR FAR* pbstr) +{ + if(iTest >= DIM(rgtest)) + return RESULT(E_INVALIDARG); + + return ErrBstrAlloc(rgtest[iTest].szName, pbstr); +} + +/*** +*HRESULT CNlsSuite::DoTest(unsigned int) +*Purpose: +* Execute a single CNlsSuite test. +* +*Entry: +* iTest = the index of the test to execute +* +*Exit: +* return value = HRESULT +* +***********************************************************************/ +STDMETHODIMP +CNlsSuite::DoTest(unsigned int iTest) +{ + if(iTest >= DIM(rgtest)) + return RESULT(E_INVALIDARG); + + return rgtest[iTest].pfnTest(rgtest[iTest].lcid); +} + +#define LCINIT(X) {X, #X} +static struct { + LCTYPE lctype; + char FAR* szLctype; +} rglctype[] = { + LCINIT(LOCALE_ILANGUAGE) /* language id */ + , LCINIT(LOCALE_SLANGUAGE) /* localized name of language */ + , LCINIT(LOCALE_SENGLANGUAGE) /* English name of language */ + , LCINIT(LOCALE_SABBREVLANGNAME) /* abbreviated language name */ + , LCINIT(LOCALE_SNATIVELANGNAME) /* native name of language */ + , LCINIT(LOCALE_ICOUNTRY) /* country code */ + , LCINIT(LOCALE_SCOUNTRY) /* localized name of country */ + , LCINIT(LOCALE_SENGCOUNTRY) /* English name of country */ + , LCINIT(LOCALE_SABBREVCTRYNAME) /* abbreviated country name */ + , LCINIT(LOCALE_SNATIVECTRYNAME) /* native name of country */ + , LCINIT(LOCALE_IDEFAULTLANGUAGE) /* default language id */ + , LCINIT(LOCALE_IDEFAULTCOUNTRY) /* default country code */ + , LCINIT(LOCALE_IDEFAULTCODEPAGE) /* default code page */ + , LCINIT(LOCALE_SLIST) /* list item separator */ + , LCINIT(LOCALE_IMEASURE) /* 0 = metric, 1 = US */ + , LCINIT(LOCALE_SDECIMAL) /* decimal separator */ + , LCINIT(LOCALE_STHOUSAND) /* thousand separator */ + , LCINIT(LOCALE_SGROUPING) /* digit grouping */ + , LCINIT(LOCALE_IDIGITS) /* number of fractional digits */ + , LCINIT(LOCALE_ILZERO) /* leading zeros for decimal */ + , LCINIT(LOCALE_SNATIVEDIGITS) /* native ascii 0-9 */ + , LCINIT(LOCALE_SCURRENCY) /* local monetary symbol */ + , LCINIT(LOCALE_SINTLSYMBOL) /* intl monetary symbol */ + , LCINIT(LOCALE_SMONDECIMALSEP) /* monetary decimal separator */ + , LCINIT(LOCALE_SMONTHOUSANDSEP) /* monetary thousand separator */ + , LCINIT(LOCALE_SMONGROUPING) /* monetary grouping */ + , LCINIT(LOCALE_ICURRDIGITS) /* # local monetary digits */ + , LCINIT(LOCALE_IINTLCURRDIGITS) /* # intl monetary digits */ + , LCINIT(LOCALE_ICURRENCY) /* positive currency mode */ + , LCINIT(LOCALE_INEGCURR) /* negative currency mode */ + , LCINIT(LOCALE_SDATE) /* date separator */ + , LCINIT(LOCALE_STIME) /* time separator */ + , LCINIT(LOCALE_SSHORTDATE) /* short date-time separator */ + , LCINIT(LOCALE_SLONGDATE) /* long date-time separator */ + , LCINIT(LOCALE_IDATE) /* short date format ordering */ + , LCINIT(LOCALE_ILDATE) /* long date format ordering */ + , LCINIT(LOCALE_ITIME) /* time format specifier */ + , LCINIT(LOCALE_ICENTURY) /* century format specifier */ + , LCINIT(LOCALE_ITLZERO) /* leading zeros in time field */ + , LCINIT(LOCALE_IDAYLZERO) /* leading zeros in day field */ + , LCINIT(LOCALE_IMONLZERO) /* leading zeros in month field */ + , LCINIT(LOCALE_S1159) /* AM designator */ + , LCINIT(LOCALE_S2359) /* PM designator */ + , LCINIT(LOCALE_SDAYNAME1) /* long name for Monday */ + , LCINIT(LOCALE_SDAYNAME2) /* long name for Tuesday */ + , LCINIT(LOCALE_SDAYNAME3) /* long name for Wednesday */ + , LCINIT(LOCALE_SDAYNAME4) /* long name for Thursday */ + , LCINIT(LOCALE_SDAYNAME5) /* long name for Friday */ + , LCINIT(LOCALE_SDAYNAME6) /* long name for Saturday */ + , LCINIT(LOCALE_SDAYNAME7) /* long name for Sunday */ + , LCINIT(LOCALE_SABBREVDAYNAME1) /* abbreviated name for Monday */ + , LCINIT(LOCALE_SABBREVDAYNAME2) /* abbreviated name for Tuesday */ + , LCINIT(LOCALE_SABBREVDAYNAME3) /* abbreviated name for Wednesday */ + , LCINIT(LOCALE_SABBREVDAYNAME4) /* abbreviated name for Thursday */ + , LCINIT(LOCALE_SABBREVDAYNAME5) /* abbreviated name for Friday */ + , LCINIT(LOCALE_SABBREVDAYNAME6) /* abbreviated name for Saturday */ + , LCINIT(LOCALE_SABBREVDAYNAME7) /* abbreviated name for Sunday */ + , LCINIT(LOCALE_SMONTHNAME1) /* long name for January */ + , LCINIT(LOCALE_SMONTHNAME2) /* long name for February */ + , LCINIT(LOCALE_SMONTHNAME3) /* long name for March */ + , LCINIT(LOCALE_SMONTHNAME4) /* long name for April */ + , LCINIT(LOCALE_SMONTHNAME5) /* long name for May */ + , LCINIT(LOCALE_SMONTHNAME6) /* long name for June */ + , LCINIT(LOCALE_SMONTHNAME7) /* long name for July */ + , LCINIT(LOCALE_SMONTHNAME8) /* long name for August */ + , LCINIT(LOCALE_SMONTHNAME9) /* long name for September */ + , LCINIT(LOCALE_SMONTHNAME10) /* long name for October */ + , LCINIT(LOCALE_SMONTHNAME11) /* long name for November */ + , LCINIT(LOCALE_SMONTHNAME12) /* long name for December */ + , LCINIT(LOCALE_SABBREVMONTHNAME1) /* abbreviated name for January */ + , LCINIT(LOCALE_SABBREVMONTHNAME2) /* abbreviated name for February */ + , LCINIT(LOCALE_SABBREVMONTHNAME3) /* abbreviated name for March */ + , LCINIT(LOCALE_SABBREVMONTHNAME4) /* abbreviated name for April */ + , LCINIT(LOCALE_SABBREVMONTHNAME5) /* abbreviated name for May */ + , LCINIT(LOCALE_SABBREVMONTHNAME6) /* abbreviated name for June */ + , LCINIT(LOCALE_SABBREVMONTHNAME7) /* abbreviated name for July */ + , LCINIT(LOCALE_SABBREVMONTHNAME8) /* abbreviated name for August */ + , LCINIT(LOCALE_SABBREVMONTHNAME9) /* abbreviated name for September */ + , LCINIT(LOCALE_SABBREVMONTHNAME10) /* abbreviated name for October */ + , LCINIT(LOCALE_SABBREVMONTHNAME11) /* abbreviated name for November */ + , LCINIT(LOCALE_SABBREVMONTHNAME12) /* abbreviated name for December */ + , LCINIT(LOCALE_SPOSITIVESIGN) /* positive sign */ + , LCINIT(LOCALE_SNEGATIVESIGN) /* negative sign */ + , LCINIT(LOCALE_IPOSSIGNPOSN) /* positive sign position */ + , LCINIT(LOCALE_INEGSIGNPOSN) /* negative sign position */ + , LCINIT(LOCALE_IPOSSYMPRECEDES) /* mon sym precedes pos amt */ + , LCINIT(LOCALE_IPOSSEPBYSPACE) /* mon sym sep by space from pos */ + , LCINIT(LOCALE_INEGSYMPRECEDES) /* mon sym precedes neg amt */ + , LCINIT(LOCALE_INEGSEPBYSPACE) /* mon sym sep by space from neg */ + , LCINIT(LOCALE_IFIRSTDAYOFWEEK) + , LCINIT(LOCALE_IFIRSTWEEKOFYEAR) + , LCINIT(LOCALE_IDEFAULTANSICODEPAGE) + , LCINIT(LOCALE_INEGNUMBER) + , LCINIT(LOCALE_STIMEFORMAT) + , LCINIT(LOCALE_ITIMEMARKPOSN) + , LCINIT(LOCALE_ICALENDARTYPE) + , LCINIT(LOCALE_IOPTIONALCALENDAR) + , LCINIT(LOCALE_SMONTHNAME13) + , LCINIT(LOCALE_SABBREVMONTHNAME13) +}; + +// dump all nls info for all our supported locales! +HRESULT +DumpNlsInfo(LCID lcid) +{ + BSTR bstr; + LCTYPE lctype; + int iLctype, size, fetched; + BSTR bstrDecimal = NULL; + BSTR bstrThousand = NULL; + + + DbPrintf("LCID = %ld\n", lcid); + + for(iLctype = 0; iLctype < DIM(rglctype); ++iLctype){ + DbPrintf(HC_MPW ? "%s = " : "%Fs = ", + (char FAR*)rglctype[iLctype].szLctype); + + lctype = rglctype[iLctype].lctype; + + size = GetLocaleInfoA(lcid, lctype, NULL, 0); + if(size == 0) + return RESULT(E_FAIL); + +#ifndef SysAllocStringByteLen +#define SysAllocStringByteLen SysAllocStringLen +#endif + bstr = SysAllocStringByteLen(NULL, size); + if(bstr == NULL) + return RESULT(E_OUTOFMEMORY); + + fetched = GetLocaleInfoA(lcid, lctype, (char FAR *)bstr, size); + + DbPrintf(HC_MPW ? "\"%s\"\n" : "\"%Fs\"\n", (char FAR *)bstr); + + switch (lctype) { + // save these for later checking + case LOCALE_SDECIMAL: + bstrDecimal = bstr; + break; + case LOCALE_STHOUSAND: + bstrThousand = bstr; + break; + default: + SysFreeString(bstr); + } + + if(fetched != size) + return RESULT(E_FAIL); + } +#if defined(WIN32) + if (!wcscmp(bstrDecimal, bstrThousand)) +#else //WIN32 + if (!lstrcmp(bstrDecimal, bstrThousand)) +#endif //WIN32 + { + DbPrintf("ERROR: decimal and thousands separators are the same for lcid = 0x%lx\n", lcid); + } + SysFreeString(bstrDecimal); + SysFreeString(bstrThousand); + + DbPrintf("\n"); + + return NOERROR; +} + +HRESULT +NlsCurrentLCID(LCID ignore) +{ + UNUSED(ignore); + + return DumpNlsInfo(GetSystemDefaultLCID()); +} + +// regression test for raid!oleprog#28 (sublanguages dont work) +// +HRESULT +NlsAPIRaid28(LCID ignore) +{ + int size; + LCID lcid; + + UNUSED(ignore); + +#if !defined(WIN32) // UNDONE: TEMPORARY + lcid = MAKELCID(MAKELANGID(LANG_GERMAN, SUBLANG_NEUTRAL)); + size = GetLocaleInfoA(lcid, LOCALE_ILANGUAGE, NULL, 0); + if(size <= 0) + return RESULT(E_FAIL); + + lcid = MAKELCID(MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN_SWISS)); + size = GetLocaleInfoA(lcid, LOCALE_ILANGUAGE, NULL, 0); + if(size <= 0) + return RESULT(E_FAIL); +#endif //!WIN32 + + return NOERROR; +} + +// regression test for raid!oleprog#418 +// +// problem: LCMapStringA is returning 0 (error) for some characters +// in some locales. +// +HRESULT +NlsAPIRaid418(LCID ignore) +{ + int res; + char rgchIn[2], rgchOut[32]; + + rgchIn[0] = (BYTE)0x8C; + + res = LCMapStringA( + 0x0407, + LCMAP_SORTKEY|NORM_IGNORECASE|NORM_IGNORENONSPACE, + rgchIn, 1, rgchOut, 32); + + if(res == 0) + return RESULT(E_FAIL); + return NOERROR; +} + +HRESULT +OB4589(LCID ignore) +{ + int cmp; + char rgch1[2], rgch2[2]; + + UNUSED(ignore); + + rgch1[0] = 'a'; + rgch2[0] = 'A'; + cmp = CompareStringA(0x0409, NORM_IGNORENONSPACE, rgch1, 1, rgch2, 1); + DbPrintf( + "CompareStringA(0409, NORM_IGNORENONSPACE, 'a', 'A') = %d\n", cmp); + + rgch1[0] = 'a'; + rgch2[0] = 'C'; + cmp = CompareStringA(0x0409, NORM_IGNORENONSPACE, rgch1, 1, rgch2, 1); + DbPrintf( + "CompareStringA(0409, NORM_IGNORENONSPACE, 'a', 'C') = %d\n", cmp); + + return NOERROR; +} + diff --git a/private/oleauto/tests/disptest/csarray.cpp b/private/oleauto/tests/disptest/csarray.cpp new file mode 100644 index 000000000..7dd783aa7 --- /dev/null +++ b/private/oleauto/tests/disptest/csarray.cpp @@ -0,0 +1,371 @@ +/*** +*csarray.cpp +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* This file implements the CSafeArraySuite test object. +* +*Revision History: +* +* [00] 30-Oct-92 bradlo: Created. +* +*Implementation Notes: +* +*****************************************************************************/ + +#include <stdio.h> + +#include "disptest.h" +#include "tstsuite.h" + +ASSERTDATA + +HRESULT SafeArrayRedimTest(VARTYPE vt, SAFEARRAY FAR* psa); +HRESULT SafeArrayOleprog181(); +HRESULT SafeArrayOleprog302(); + + +static SARRAYDESC rgsarraydesc[] = +{ + + {1, {{1,0}, {0,0}, {0,0}, {0,0}, {0,0}}} + , {1, {{2,0}, {0,0}, {0,0}, {0,0}, {0,0}}} + , {1, {{4,0}, {0,0}, {0,0}, {0,0}, {0,0}}} + , {1, {{8,0}, {0,0}, {0,0}, {0,0}, {0,0}}} + , {1, {{16,0}, {0,0}, {0,0}, {0,0}, {0,0}}} + , {1, {{32,0}, {0,0}, {0,0}, {0,0}, {0,0}}} + , {1, {{64,0}, {0,0}, {0,0}, {0,0}, {0,0}}} + , {1, {{128,0}, {0,0}, {0,0}, {0,0}, {0,0}}} + , {1, {{256,0}, {0,0}, {0,0}, {0,0}, {0,0}}} + , {1, {{512,0}, {0,0}, {0,0}, {0,0}, {0,0}}} + , {1, {{1024,0}, {0,0}, {0,0}, {0,0}, {0,0}}} + , {1, {{2048,0}, {0,0}, {0,0}, {0,0}, {0,0}}} + , {1, {{4096,0}, {0,0}, {0,0}, {0,0}, {0,0}}} + , {1, {{5,100}, {0,0}, {0,0}, {0,0}, {0,0}}} + , {1, {{5,-100}, {0,0}, {0,0}, {0,0}, {0,0}}} + + , {2, {{1,0}, {1,0}, {0,0}, {0,0}, {0,0}}} + , {2, {{2,0}, {1,0}, {0,0}, {0,0}, {0,0}}} + , {2, {{4,0}, {1,0}, {0,0}, {0,0}, {0,0}}} + , {2, {{8,0}, {1,0}, {0,0}, {0,0}, {0,0}}} + , {2, {{16,0}, {16,0}, {0,0}, {0,0}, {0,0}}} + , {2, {{32,0}, {32,0}, {0,0}, {0,0}, {0,0}}} + , {2, {{64,0}, {64,0}, {0,0}, {0,0}, {0,0}}} + , {2, {{5,100}, {5,100}, {0,0}, {0,0}, {0,0}}} + , {2, {{5,-100}, {5,-100}, {0,0}, {0,0}, {0,0}}} + + , {3, {{1,0}, {1,0}, {1,0}, {0,0}, {0,0}}} + , {3, {{2,0}, {2,0}, {2,0}, {0,0}, {0,0}}} + , {3, {{4,0}, {4,0}, {4,0}, {0,0}, {0,0}}} + , {3, {{8,0}, {8,0}, {8,0}, {0,0}, {0,0}}} + , {3, {{16,0}, {16,0}, {16,0}, {0,0}, {0,0}}} + , {3, {{5,100}, {5,100}, {5,100}, {0,0}, {0,0}}} + , {3, {{5,-100}, {5,-100}, {5,-100}, {0,0}, {0,0}}} + + , {4, {{1,0}, {1,0}, {1,0}, {1,0}, {0,0}}} + , {4, {{2,0}, {2,0}, {2,0}, {2,0}, {0,0}}} + , {4, {{4,0}, {4,0}, {4,0}, {4,0}, {0,0}}} + , {4, {{8,0}, {8,0}, {8,0}, {8,0}, {0,0}}} + , {4, {{5,100}, {5,100}, {5,100}, {5,100}, {0,0}}} + , {4, {{5,-100}, {5,-100}, {5,-100}, {5,-100}, {0,0}}} +}; + +static OLECHAR FAR* rgszSArrayDesc[] = +{ + OLESTR("(1)"), + OLESTR("(2)"), + OLESTR("(4)"), + OLESTR("(8)"), + OLESTR("(16)"), + OLESTR("(32)"), + OLESTR("(64)"), + OLESTR("(128)"), + OLESTR("(256)"), + OLESTR("(512)"), + OLESTR("(1024)"), + OLESTR("(2048)"), + OLESTR("(4096)"), + OLESTR("(100 To 105)"), + OLESTR("(-100 To -95)"), + + OLESTR("(1, 1)"), + OLESTR("(2, 2)"), + OLESTR("(4, 4)"), + OLESTR("(8, 8)"), + OLESTR("(16, 16)"), + OLESTR("(32, 32)"), + OLESTR("(64, 64)"), + OLESTR("(100 To 105, 100 To 105)"), + OLESTR("(-100 To -95, -100 To -95)"), + + OLESTR("(1, 1, 1)"), + OLESTR("(2, 2, 2)"), + OLESTR("(4, 4, 4)"), + OLESTR("(8, 8, 8)"), + OLESTR("(16, 16, 16)"), + OLESTR("(100 To 105, 100 To 105, 100 To 105)"), + OLESTR("(-100 To -95, -100 To -95, -100 To -95)"), + + OLESTR("(1, 1, 1, 1)"), + OLESTR("(2, 2, 2, 2)"), + OLESTR("(4, 4, 4, 4)"), + OLESTR("(8, 8, 8, 8)"), + + OLESTR("(100 To 105, 100 To 105, 100 To 105, 100 To 105)"), + OLESTR("(-100 To -95, -100 To -95, -100 To -95, -100 To -95)") +}; + +static VARTYPE rgvtArrayTypes[] = +{ + VT_I2 +#if VBA2 + , VT_UI1 +#endif //VBA2 + , VT_I4 + , VT_R4 + , VT_R8 + , VT_CY + , VT_DATE + , VT_BSTR + , VT_ERROR + , VT_BOOL + , VT_VARIANT + , VT_UNKNOWN + , VT_DISPATCH +}; + + + +struct TEST { + HRESULT (*pfnTest)(); + OLECHAR FAR* szName; +}; + +static TEST rgtest[] = +{ + { SafeArrayOleprog181, OLESTR("raid:oleprog#181")} + , { SafeArrayOleprog302, OLESTR("raid!oleprog#302")} +}; + + +SUITE_CONSTRUCTION_IMPL(CSafeArraySuite) + +SUITE_IUNKNOWN_IMPL(CSafeArraySuite) + +//--------------------------------------------------------------------- +// ITestSuite Methods +//--------------------------------------------------------------------- + +STDMETHODIMP +CSafeArraySuite::GetNameOfSuite(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("SafeArray API"), pbstr); +} + +STDMETHODIMP +CSafeArraySuite::GetNameOfLogfile(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("saryapi.log"), pbstr); +} + +STDMETHODIMP +CSafeArraySuite::GetTestCount(unsigned int FAR* pcTests) +{ + *pcTests = DIM(rgvtArrayTypes) * DIM(rgsarraydesc) + DIM(rgtest); + return NOERROR; +} + +STDMETHODIMP +CSafeArraySuite::GetNameOfTest(unsigned int iTest, BSTR FAR* pbstr) +{ + TCHAR buf[128]; + int iVt, iDesc; + + if(iTest >= (DIM(rgvtArrayTypes) * DIM(rgsarraydesc) + DIM(rgtest))) + return RESULT(E_INVALIDARG); // out-of-bounds really + + if(iTest < (DIM(rgvtArrayTypes) * DIM(rgsarraydesc))) { + iVt = iTest / DIM(rgsarraydesc); + iDesc = iTest % DIM(rgsarraydesc); + + ASSERT(iVt < DIM(rgvtArrayTypes)); + ASSERT(iDesc < DIM(rgsarraydesc)); + ASSERT(iDesc < DIM(rgszSArrayDesc)); + +#if HC_MPW + sprintf(buf, "Dim <Array> %s As %s", +#else + SPRINTF(buf, TSTR("Dim <Array> %Fs As %Fs"), +#endif + rgszSArrayDesc[iDesc], + DbSzOfVt(rgvtArrayTypes[iVt])); + + *pbstr = SysAllocString(WIDESTRING(buf)); + return NOERROR; + } + + iTest -= (DIM(rgvtArrayTypes) * DIM(rgsarraydesc)); + return ErrBstrAlloc(rgtest[iTest].szName, pbstr); +} + +/*** +*HRESULT CSafeArraySuite::DoTest(unsigned int) +*Purpose: +* Execute a single SafeArray test. +* +*Entry: +* iTest = the index of the test to execute +* +*Exit: +* return value = HRESULT +* +***********************************************************************/ +STDMETHODIMP +CSafeArraySuite::DoTest(unsigned int iTest) +{ + VARTYPE vt; + int iVt, iDesc; + SAFEARRAY FAR* psa; + SARRAYDESC FAR* psadesc; + HRESULT hresult, hresultTmp; + + + if(iTest >= (DIM(rgvtArrayTypes) * DIM(rgsarraydesc) + DIM(rgtest))) + return RESULT(E_INVALIDARG); // out-of-bounds really + + if(iTest >= (DIM(rgvtArrayTypes) * DIM(rgsarraydesc))) { + iTest -= (DIM(rgvtArrayTypes) * DIM(rgsarraydesc)); + return rgtest[iTest].pfnTest(); + + } else { + iVt = iTest / DIM(rgsarraydesc); + iDesc = iTest % DIM(rgsarraydesc); + + ASSERT(iVt < DIM(rgvtArrayTypes)); + ASSERT(iDesc < DIM(rgsarraydesc)); + + vt = rgvtArrayTypes[iVt]; + psadesc = &rgsarraydesc[iDesc]; + + IfFailGo(SafeArrayCreateIdentity(vt, psadesc, &psa), LError0); + + DbPrSafeArray(psa, vt); + + IfFailGo(SafeArrayValidateIdentity(vt, psa, 0L), LError1); + + IfFailGo(SafeArrayRedimTest(vt, psa), LError1); + hresult = NOERROR; + } + +LError1:; + hresultTmp = SafeArrayDestroy(psa); + ASSERT(hresultTmp == NOERROR); + +LError0:; + return hresult; +} + +HRESULT +SafeArrayRedimTest(VARTYPE vt, SAFEARRAY FAR* psa) +{ + unsigned long cElements; + HRESULT hresult; + SAFEARRAYBOUND sabound; + + sabound = psa->rgsabound[0]; + + cElements = sabound.cElements; + + sabound.cElements = cElements*2; + if((hresult = SafeArrayRedim(psa, &sabound)) != NOERROR){ + if(GetScode(hresult) != E_OUTOFMEMORY) + return hresult; + // try once more with a smaller increase + sabound.cElements = cElements + 5; + IfFailRet(SafeArrayRedim(psa, &sabound)); + } + + DbPrSafeArray(psa, vt); + + if(cElements == 1) + return NOERROR; + + sabound.cElements = cElements/2; + IfFailRet(SafeArrayRedim(psa, &sabound)); + DbPrSafeArray(psa, vt); + + return NOERROR; +} + +// regression test for oleprog#181: infinite loop in SafeArrayCopy +// if the array is a simple type (ie, not unknown/dispatch/bstr/variant). + +HRESULT +SafeArrayOleprog181() +{ + SARRAYDESC sadesc; + HRESULT hresult, hresultTmp; + SAFEARRAY FAR* psaSrc, FAR* psaDst; + + sadesc.cDims = 2; + sadesc.rgsabound[0].lLbound = 0; + sadesc.rgsabound[0].cElements = 4; + sadesc.rgsabound[1].lLbound = 0; + sadesc.rgsabound[1].cElements = 4; + + + IfFailGo(SafeArrayCreateIdentity(VT_I2, &sadesc, &psaSrc), LError0); + + DbPrSafeArray(psaSrc, VT_I2); + + IfFailGo(SafeArrayCopy(psaSrc, &psaDst), LError1); + + DbPrSafeArray(psaDst, VT_I2); + + hresult = NOERROR; + + hresultTmp = SafeArrayDestroy(psaDst); + ASSERT(hresultTmp == NOERROR); + +LError1: + hresultTmp = SafeArrayDestroy(psaSrc); + ASSERT(hresultTmp == NOERROR); + +LError0: + return hresult; +} + + +// regression test for oleprog#302: Creating a multi-dim SafeArray with a +// dimension element of zero should return a psa of NULL +// + +HRESULT +SafeArrayOleprog302() +{ + SAFEARRAYBOUND rgsabound[4]; + SAFEARRAY FAR* psa; + int cDims; + + cDims = 4; + rgsabound[0].lLbound = 0; + rgsabound[0].cElements = 10; + rgsabound[1].lLbound = 0; + rgsabound[1].cElements = 10; + rgsabound[2].lLbound = 0; + rgsabound[2].cElements = 0; + rgsabound[3].lLbound = 0; + rgsabound[3].cElements = 10; + + psa = SafeArrayCreate(VT_I2, cDims, rgsabound); + + if (psa == NULL) + return NOERROR; + + SafeArrayDestroy(psa); + return RESULT(E_FAIL); +} + + diff --git a/private/oleauto/tests/disptest/ctime.cpp b/private/oleauto/tests/disptest/ctime.cpp new file mode 100644 index 000000000..fd8303d41 --- /dev/null +++ b/private/oleauto/tests/disptest/ctime.cpp @@ -0,0 +1,266 @@ +/*** +*ctime.cpp +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* This file implements the CTimeSuite test object. +* +*Revision History: +* +* [00] 30-Oct-92 bradlo: Created. +* +*Implementation Notes: +* +*****************************************************************************/ + +#include "disptest.h" +#include "tstsuite.h" + + +void DbPrDosDateTime(unsigned short, unsigned short); + +struct TEST { + HRESULT (*pfnTest)(void); + OLECHAR FAR* szName; +}; + +HRESULT DosToVariant(void); +HRESULT VariantToDos(void); + +static TEST rgtest[] = { + { DosToVariant, OLESTR("DosDateTimeToVariantTime") }, + { VariantToDos, OLESTR("VariantTimeToDosDateTime") } +}; + + +SUITE_CONSTRUCTION_IMPL(CTimeSuite) + +SUITE_IUNKNOWN_IMPL(CTimeSuite) + + +//--------------------------------------------------------------------- +// ITestSuite Methods +//--------------------------------------------------------------------- + +STDMETHODIMP +CTimeSuite::GetNameOfSuite(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("Time API"), pbstr); +} + +STDMETHODIMP +CTimeSuite::GetNameOfLogfile(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("timeapi.log"), pbstr); +} + +STDMETHODIMP +CTimeSuite::GetTestCount(unsigned int FAR* pcTests) +{ + *pcTests = DIM(rgtest); + return NOERROR; +} + +STDMETHODIMP +CTimeSuite::GetNameOfTest(unsigned int iTest, BSTR FAR* pbstr) +{ + if(iTest >= DIM(rgtest)) + return RESULT(E_INVALIDARG); + + return ErrBstrAlloc(rgtest[iTest].szName, pbstr); +} + +/*** +*HRESULT CTimeSuite::DoTest(unsigned int) +*Purpose: +* Execute a single CTimeSuite test. +* +*Entry: +* iTest = the index of the test to execute +* +*Exit: +* return value = HRESULT +* +***********************************************************************/ +STDMETHODIMP +CTimeSuite::DoTest(unsigned int iTest) +{ + if(iTest >= DIM(rgtest)) + return RESULT(E_INVALIDARG); + + return rgtest[iTest].pfnTest(); +} + +#define DOSDATE(MONTH, DAY, YEAR)\ + ((((YEAR)-1980) << 9) + ((MONTH) << 5) + (DAY)) + +#define DOSTIME(HOUR, MIN, SEC)\ + (((HOUR) << 11) + ((MIN) << 5) + ((SEC) / 2)) + +HRESULT +DosToVariant() +{ + int i; + VARIANT var; + unsigned short wDosDate, wDosTime; +static struct { + unsigned short wDosDate; + unsigned short wDosTime; +} rgdostime[] = { + { DOSDATE(1, 1, 1980), DOSTIME(0, 0, 0) } + , { DOSDATE(1, 1, 1990), DOSTIME(0, 0, 0) } + , { DOSDATE(1, 1, 2000), DOSTIME(0, 0, 0) } + , { DOSDATE(1, 1, 2099), DOSTIME(0, 0, 0) } + , { DOSDATE(1, 1, 1980), DOSTIME(1, 0, 0) } + , { DOSDATE(1, 1, 1980), DOSTIME(1, 1, 0) } + , { DOSDATE(1, 1, 1980), DOSTIME(1, 1, 1) } + , { DOSDATE(1, 1, 1980), DOSTIME(1, 1, 2) } + , { DOSDATE(1, 1, 1980), DOSTIME(1, 1, 3) } + , { DOSDATE(1, 1, 1980), DOSTIME(1, 1, 4) } + , { DOSDATE(5, 8, 1983), DOSTIME(12, 22, 4) } + , { DOSDATE(10, 23, 2000), DOSTIME(1, 1, 9) } + , { DOSDATE(10, 23, 2015), DOSTIME(1, 1, 22) } + , { DOSDATE(11, 30, 2099), DOSTIME(23, 59, 59) } +}; + + for(i = 0; i < DIM(rgdostime); ++i){ + wDosDate = rgdostime[i].wDosDate; + wDosTime = rgdostime[i].wDosTime; + + DbPrDosDateTime(wDosDate, wDosTime); + DbPrintf(" = "); + + V_VT(&var) = VT_DATE; + V_DATE(&var) = 0.0; + if(DosDateTimeToVariantTime(wDosDate, wDosTime, &V_DATE(&var)) == 0){ + DbPrintf("False\n"); + }else{ + DbPrintf("vartime(%#g) = ", V_DATE(&var)); + if(VariantChangeType(&var, &var, 0, VT_BSTR) != NOERROR) + return RESULT(E_FAIL); +#if HC_MPW + DbPrintf("%s\n", V_BSTR(&var)); +#else + DbPrintf("%Fs\n", STRING(V_BSTR(&var))); +#endif + } + if(VariantClear(&var) != NOERROR) + return RESULT(E_FAIL); + } + + return NOERROR; +} + +HRESULT +VariantToDos() +{ + int i; + VARIANT var; + unsigned short wDosDate; + unsigned short wDosTime; + +static OLECHAR FAR* rgszTime[] = { + OLESTR("1/1/1980") + , OLESTR("1/1/1990") + , OLESTR("1/1/2000") + , OLESTR("1/1/2099") + , OLESTR("1/1/1980 1:0:0") + , OLESTR("1/1/1980 1:1:0") + , OLESTR("1/1/1980 1:1:1") + , OLESTR("1/1/1980 1:1:2") + , OLESTR("1/1/1980 1:1:3") + , OLESTR("1/1/1980 1:1:4") + , OLESTR("5/8/1983 12:22:4") + , OLESTR("10/10/2000 1:1:18") + , OLESTR("11/30/2099 23:59:59") +}; + + VariantInit(&var); + for(i = 0; i < DIM(rgszTime); ++i){ +#if HC_MPW + DbPrintf("\'%s' = ", rgszTime[i]); +#else + DbPrintf("\'%Fs' = ", STRING(rgszTime[i])); +#endif + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(rgszTime[i]); + if(VariantChangeType(&var, &var, 0, VT_DATE) != NOERROR) + return RESULT(E_FAIL); + DbPrintf("vartime(%#g) = ", V_DATE(&var)); + if(VariantTimeToDosDateTime(V_DATE(&var), &wDosDate, &wDosTime) == 0){ + DbPrintf("False\n"); + }else{ + DbPrDosDateTime(wDosDate, wDosTime); + DbPrintf("\n"); + } + if(VariantClear(&var) != NOERROR) + return RESULT(E_FAIL); + } + + return NOERROR; +} + +unsigned short +YearOfDosDate(unsigned short wDosDate) +{ + return ((wDosDate >> 9) & 0x007f); +} + +unsigned short +MonthOfDosDate(unsigned short wDosDate) +{ + return ((wDosDate >> 5) & 0x000f); +} + +unsigned short +DayOfDosDate(unsigned short wDosDate) +{ + return ((wDosDate) & 0x001f); +} + +void +DbPrDosDate(unsigned short wDosDate) +{ + DbPrintf("%d-%d-%d", + MonthOfDosDate(wDosDate), + DayOfDosDate(wDosDate), + YearOfDosDate(wDosDate)); +} + +unsigned short +HourOfDosTime(unsigned short wDosTime) +{ + return ((wDosTime >> 11) & 0x001f); +} + +unsigned short +MinOfDosTime(unsigned short wDosTime) +{ + return ((wDosTime >> 5) & 0x003f); +} + +unsigned short +SecOfDosTime(unsigned short wDosTime) +{ + return ((wDosTime) & 0x001f); +} + +void +DbPrDosTime(unsigned short wDosTime) +{ + DbPrintf("%d:%d:%d", + HourOfDosTime(wDosTime), + MinOfDosTime(wDosTime), + SecOfDosTime(wDosTime)); +} + +void +DbPrDosDateTime(unsigned short wDosDate, unsigned short wDosTime) +{ + DbPrDosDate(wDosDate); + DbPrintf(" "); + DbPrDosTime(wDosTime); +} + diff --git a/private/oleauto/tests/disptest/cvariant.cpp b/private/oleauto/tests/disptest/cvariant.cpp new file mode 100644 index 000000000..3b62c9d4c --- /dev/null +++ b/private/oleauto/tests/disptest/cvariant.cpp @@ -0,0 +1,1617 @@ +/*** +*cvariant.cpp +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* This file implements the CVariantSuite test object. +* +*Revision History: +* +* [00] 30-Oct-92 bradlo: Created. +* +*Implementation Notes: +* +*****************************************************************************/ + +#include "disptest.h" + +#include <float.h> /* for DBL_MAX */ + +#include "tstsuite.h" +#include "cunk.h" +#include "cdisp.h" + +ASSERTDATA + +#ifdef _MAC +# define CY_(HI,LO) {HI,LO} +#else +# define CY_(HI,LO) {LO,HI} +#endif + + +// return on an hresult that is not success, and *not* one of the +// errors we are expecting/allowing. +// +#define IFFAILRET(X) \ + { HRESULT hresultTmp = (X); \ + if(HRESULT_FAILED(hresultTmp)){ \ + SCODE sc = GetScode(hresultTmp); \ + if (sc != E_NOTIMPL \ + && sc != DISP_E_OVERFLOW \ + && sc != E_NOINTERFACE \ + && sc != DISP_E_TYPEMISMATCH) \ + return hresultTmp; \ + } \ + } + + +long rgEmptyVal[] = {0}; + +long rgNullVal[] = {0}; + +#if VBA2 +unsigned char rgUI1Val[] = {0, 1, 128, 255}; +#endif //VBA2 + +short rgI2Val[] = {0, 1, -1, 42}; + +long rgI4Val[] = {0, 1, -1, 42000}; + +float rgR4Val[] = {(float)0.0, (float)42.42, (float)107.66, (float)-2147483648.0}; + +double rgR8Val[] = {0.0, 42.42, 107.66}; + +CY rgCyVal[] = {CY_(0,0), CY_(0,2), CY_(42,43), CY_(107,66), CY_(5000,0)}; + +DATE rgDateVal[] = {0.0, 42.42, 107.66}; + +OLECHAR FAR* rgBstrVal[] = { + OLESTR("a binary string") + , OLESTR("42") + , OLESTR("42000") + , OLESTR("92233800000") + , OLESTR("42.42") + , OLESTR("#TRUE#") + , OLESTR("#FALSE#") + , OLESTR("1/7/66") + , OLESTR("1:20 pm") +}; + + +SCODE rgErrorVal[] = {S_OK, DISP_E_TYPEMISMATCH}; + +VARIANT_BOOL rgBoolVal[] = {0, -1}; + +struct VARIANT_TEST_INFO{ + VARTYPE vtFrom; + int nValues; + void FAR* rgValues; +}; + +HRESULT VariantOB1469(VARIANT_TEST_INFO FAR*); +HRESULT VariantOB2078(VARIANT_TEST_INFO FAR*); +HRESULT VariantOB2834(VARIANT_TEST_INFO FAR*); +HRESULT VariantOB3028(VARIANT_TEST_INFO FAR*); +HRESULT VariantOB3336(VARIANT_TEST_INFO FAR*); +HRESULT VariantOB3354(VARIANT_TEST_INFO FAR*); +HRESULT VariantOB3603(VARIANT_TEST_INFO FAR*); +HRESULT VariantOB3875(VARIANT_TEST_INFO FAR*); +HRESULT VariantOB3876(VARIANT_TEST_INFO FAR*); +HRESULT VariantOleprog10(VARIANT_TEST_INFO FAR*); +HRESULT VariantOleprog11(VARIANT_TEST_INFO FAR*); +HRESULT VariantOleprog12(VARIANT_TEST_INFO FAR*); +HRESULT VariantOleprog27(VARIANT_TEST_INFO FAR*); +HRESULT VariantOleprog50(VARIANT_TEST_INFO FAR*); +HRESULT VariantOleprog82(VARIANT_TEST_INFO FAR*); +HRESULT VariantOleprog84(VARIANT_TEST_INFO FAR*); +HRESULT VariantOleprog94(VARIANT_TEST_INFO FAR*); +HRESULT VariantOleprog235(VARIANT_TEST_INFO FAR*); +HRESULT VariantOleprog351(VARIANT_TEST_INFO FAR*); +HRESULT VariantBug0(VARIANT_TEST_INFO FAR*); +HRESULT VariantBug1(VARIANT_TEST_INFO FAR*); +HRESULT OverflowTests(VARIANT_TEST_INFO FAR*); +HRESULT DefVariantTest(VARIANT_TEST_INFO FAR*); + + +struct TEST { + HRESULT (*pfnTest)(VARIANT_TEST_INFO FAR*); + OLECHAR FAR* szName; + struct VARIANT_TEST_INFO vti; +}; + +static TEST rgtest[] = +{ + { VariantBug1, OLESTR("bug#1"), {0, 0, NULL}} + + , { VariantOleprog10, OLESTR("raid!oleprog#10"), {0, 0, NULL}} + , { VariantOleprog11, OLESTR("raid!oleprog#11"), {0, 0, NULL}} + , { VariantOleprog12, OLESTR("raid!oleprog#12"), {0, 0, NULL}} + , { VariantOleprog27, OLESTR("raid!oleprog#27"), {0, 0, NULL}} + , { VariantOleprog50, OLESTR("raid!oleprog#50"), {0, 0, NULL}} + , { VariantOleprog82, OLESTR("raid!oleprog#82"), {0, 0, NULL}} + , { VariantOleprog84, OLESTR("raid!oleprog#84"), {0, 0, NULL}} + , { VariantOleprog94, OLESTR("raid!oleprog#94"), {0, 0, NULL}} + , { VariantOleprog235,OLESTR("raid!oleprog#235"),{0, 0, NULL}} + , { VariantOleprog351,OLESTR("raid!oleprog#351"),{0, 0, NULL}} + + , { VariantOB1469, OLESTR("raid!ob#1469"), {0,0,NULL}} +// , { VariantOB2078, OLESTR("raid!ob#2078"), {0,0,NULL}} + , { VariantOB2834, OLESTR("raid!ob#2834"), {0,0,NULL}} +// , { VariantOB3028 OLESTR("raid!ob#3028"), {0,0,NULL}} + , { VariantOB3336, OLESTR("raid!ob#3336"), {0,0,NULL}} + , { VariantOB3354, OLESTR("raid!ob#3354"), {0,0,NULL}} + , { VariantOB3603, OLESTR("raid!ob#3603"), {0,0,NULL}} +// , { VariantOB3875, OLESTR("raid!ob#3875"), {0,0,NULL}} + , { VariantOB3876, OLESTR("raid!ob#3876"), {0,0,NULL}} + + , { VariantBug0, OLESTR("bug#0"), {0, 0, NULL}} + + , { DefVariantTest, OLESTR("VT_EMPTY To *"), + {VT_EMPTY, DIM(rgEmptyVal),rgEmptyVal}} + + , { DefVariantTest, OLESTR("VT_NULL To *"), + {VT_NULL, DIM(rgNullVal), rgNullVal}} + +#if VBA2 + , { DefVariantTest, OLESTR("VT_UI1 To *"), + {VT_UI1, DIM(rgUI1Val), rgUI1Val}} +#endif //VBA2 + + , { DefVariantTest, OLESTR("VT_I2 To *"), + {VT_I2, DIM(rgI2Val), rgI2Val}} + + , { DefVariantTest, OLESTR("VT_I4 To *"), + {VT_I4, DIM(rgI4Val), rgI4Val}} + + , { DefVariantTest, OLESTR("VT_R4 To *"), + {VT_R4, DIM(rgR4Val), rgR4Val}} + + , { DefVariantTest, OLESTR("VT_R8 To *"), + {VT_R8, DIM(rgR8Val), rgR8Val}} + + , { DefVariantTest, OLESTR("VT_CY To *"), + {VT_CY, DIM(rgCyVal), rgCyVal}} + + , { DefVariantTest, OLESTR("VT_DATE To *"), + {VT_DATE, DIM(rgDateVal), rgDateVal}} + + , { DefVariantTest, OLESTR("VT_BSTR To *"), + {VT_BSTR, DIM(rgBstrVal), rgBstrVal}} + + , { DefVariantTest, OLESTR("VT_DISPATCH To *"), + {VT_DISPATCH, 1, NULL}} + + , { DefVariantTest, OLESTR("VT_ERROR To *"), + {VT_ERROR, DIM(rgErrorVal),rgErrorVal}} + + , { DefVariantTest, OLESTR("VT_BOOL To *"), + {VT_BOOL, DIM(rgBoolVal), rgBoolVal}} + + , { DefVariantTest, OLESTR("VT_UNKNOWN To *"), + {VT_UNKNOWN, 1, NULL}} + +#if VBA2 + , { DefVariantTest, OLESTR("VT_UI1Ref To *"), + {VT_BYREF | VT_UI1, DIM(rgUI1Val), rgUI1Val}} +#endif //VBA2 + + , { DefVariantTest, OLESTR("VT_I2Ref To *"), + {VT_BYREF | VT_I2, DIM(rgI2Val), rgI2Val}} + + , { DefVariantTest, OLESTR("VT_I4Ref To *"), + {VT_BYREF | VT_I4, DIM(rgI4Val), rgI4Val}} + + , { DefVariantTest, OLESTR("VT_R4Ref To *"), + {VT_BYREF | VT_R4, DIM(rgR4Val), rgR4Val}} + + , { DefVariantTest, OLESTR("VT_R8Ref To *"), + {VT_BYREF | VT_R8, DIM(rgR8Val), rgR8Val}} + + , { DefVariantTest, OLESTR("VT_CYRef To *"), + {VT_BYREF | VT_CY, DIM(rgCyVal), rgCyVal}} + + , { DefVariantTest, OLESTR("VT_DATERef To *"), + {VT_BYREF | VT_DATE, DIM(rgDateVal), rgDateVal}} + + , { DefVariantTest, OLESTR("VT_BSTRRef To *"), + {VT_BYREF | VT_BSTR, DIM(rgBstrVal), rgBstrVal}} + + , { DefVariantTest, OLESTR("VT_DISPATCHRef To *"), + {VT_BYREF | VT_DISPATCH, 1, NULL}} + + , { DefVariantTest, OLESTR("VT_ERRORRef To *"), + {VT_BYREF | VT_ERROR, DIM(rgErrorVal), rgErrorVal}} + + , { DefVariantTest, OLESTR("VT_BOOLRef To *"), + {VT_BYREF | VT_BOOL, DIM(rgBoolVal), rgBoolVal}} + +#if 0 /* REVIEW: need a bit more work for this test */ + , { DefVariantTest, OLESTR("VT_VARIANTRef To *"), + {VT_BYREF | VT_VARIANT, 1, NULL}} +#endif + + , { DefVariantTest, OLESTR("VT_UNKNOWNRef To *"), + {VT_BYREF | VT_UNKNOWN, 1, NULL}} +}; + +SUITE_CONSTRUCTION_IMPL(CVariantSuite) + +SUITE_IUNKNOWN_IMPL(CVariantSuite) + +//--------------------------------------------------------------------- +// ITestSuite Methods +//--------------------------------------------------------------------- + + +/*** +*HRESULT CVariantSuite::GetNameOfSuite(BSTR*) +*Purpose: +* Return the name of this test suite. +* +*Entry: +* None +* +*Exit: +* return value = HRESULT +* +* *pbstr = BSTR containing the name of the suite +* +***********************************************************************/ +STDMETHODIMP +CVariantSuite::GetNameOfSuite(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("Variant API"), pbstr); +} + +STDMETHODIMP +CVariantSuite::GetNameOfLogfile(BSTR FAR* pbstr) +{ + return ErrBstrAlloc(OLESTR("varapi.log"), pbstr); +} + +/*** +*HRESULT CVariantSuite::GetTestCount(unsigned int*) +*Purpose: +* Return a count of the number of tests in this suite. +* +*Entry: +* None +* +*Exit: +* return value = HRESULT +* +* *pcTests = The count of tests +* +***********************************************************************/ +STDMETHODIMP +CVariantSuite::GetTestCount(unsigned int FAR* pcTests) +{ + *pcTests = DIM(rgtest); + return NOERROR; +} + +/*** +*HRESULT CVariant::GetNameOfTest(unsigned int, BSTR*) +*Purpose: +* Return the name of the test associated with the given test index. +* +*Entry: +* iTest = index of the test whose name is requested +* +*Exit: +* return value = HRESULT +* S_OK, E_INVALIDARG +* +* *pbstr = BSTR containing the name of the test +* +***********************************************************************/ +STDMETHODIMP +CVariantSuite::GetNameOfTest(unsigned int iTest, BSTR FAR* pbstr) +{ + if(iTest >= DIM(rgtest)) + return RESULT(E_INVALIDARG); + + return ErrBstrAlloc(rgtest[iTest].szName, pbstr); +} + +/*** +*HRESULT CVariantSuite::DoTest(unsigned int) +*Purpose: +* Execute a single SafeArray test. +* +*Entry: +* iTest = the index of the test to execute +* +*Exit: +* return value = HRESULT +* +***********************************************************************/ +STDMETHODIMP +CVariantSuite::DoTest(unsigned int iTest) +{ + if(iTest >= DIM(rgtest)) + return RESULT(E_INVALIDARG); // out-of-bounds really + + return rgtest[iTest].pfnTest(&rgtest[iTest].vti); +} + +HRESULT +VariantFromVariantTestInfo( + VARIANT_TEST_INFO FAR* pvti, + int ix, + VARIANTARG FAR* pvarg, + VARIANT FAR* pvarRefMem) +{ + VARTYPE vt; + HRESULT hresult; + + V_VT(pvarg) = vt = pvti->vtFrom; + + switch(vt & ~VT_BYREF){ + case VT_NULL: + case VT_EMPTY: + break; + +#if VBA2 + case VT_UI1: + V_UI1(pvarg) = ((unsigned char FAR*)pvti->rgValues)[ix]; + break; +#endif //VBA2 + + case VT_I2: + case VT_BOOL: + V_I2(pvarg) = ((short FAR*)pvti->rgValues)[ix]; + break; + + case VT_I4: + case VT_ERROR: + V_I4(pvarg) = ((long FAR*)pvti->rgValues)[ix]; + break; + + case VT_R4: + V_R4(pvarg) = ((float FAR*)pvti->rgValues)[ix]; + break; + + case VT_R8: + case VT_DATE: + V_R8(pvarg) = ((double FAR*)pvti->rgValues)[ix]; + break; + + case VT_CY: + V_CY(pvarg) = ((CY FAR*)pvti->rgValues)[ix]; + break; + + case VT_BSTR: + V_BSTR(pvarg) = SysAllocString(((OLECHAR FAR* FAR*)pvti->rgValues)[ix]); + ASSERT(V_BSTR(pvarg) != NULL); + break; + + case VT_DISPATCH: + hresult = CDisp::Create(&V_DISPATCH(pvarg)); + ASSERT(hresult == NOERROR); + break; + + case VT_UNKNOWN: + hresult = CUnk::Create(&V_UNKNOWN(pvarg)); + ASSERT(hresult == NOERROR); + break; + + default: + ASSERT(UNREACHED); + } + + if(vt & VT_BYREF){ + MEMCPY(pvarRefMem, pvarg, sizeof(VARIANTARG)); + V_BYREF(pvarg) = &V_NONE(pvarRefMem); + } + + return NOERROR; +} + +HRESULT +doCoerce(VARIANTARG FAR* pvargFrom, VARTYPE vtTo) +{ + VARIANTARG vargTo; + HRESULT hresult, hrTmp; + + VariantInit(&vargTo); + + DbPrVarg(pvargFrom); + DbPrintf(" to "); + + hresult = VariantChangeType(&vargTo, pvargFrom, 0, vtTo); + + if(!HRESULT_FAILED(hresult)){ + DbPrVarg(&vargTo); + }else{ + DbPrVt(vtTo); +#if HC_MPW + DbPrintf(" => [%s]", DbSzOfScode(GetScode(hresult))); +#else + DbPrintf(" => [%Fs]", DbSzOfScode(GetScode(hresult))); +#endif + } + DbPrintf("\n"); + + hrTmp = VariantClear(&vargTo); + ASSERT(hrTmp == NOERROR); + + return hresult; +} + +/*** +*HRESULT coerce(VARIANTARG*) +*Purpose: +* Attempt to coerce the given VARIANTARG to each of the integral types. +* +*Entry: +* pvargFrom = the VARIANTARG to coerce 'from' +* +*Exit: +* return value = HRESULT +* +***********************************************************************/ +HRESULT +coerce(VARIANTARG FAR* pvargFrom) +{ + IFFAILRET(doCoerce(pvargFrom, VT_EMPTY)); + IFFAILRET(doCoerce(pvargFrom, VT_NULL)); +#if VBA2 + IFFAILRET(doCoerce(pvargFrom, VT_UI1)); +#endif //VBA2 + IFFAILRET(doCoerce(pvargFrom, VT_I2)); + IFFAILRET(doCoerce(pvargFrom, VT_I4)); + IFFAILRET(doCoerce(pvargFrom, VT_R4)); + IFFAILRET(doCoerce(pvargFrom, VT_R8)); + IFFAILRET(doCoerce(pvargFrom, VT_CY)); + IFFAILRET(doCoerce(pvargFrom, VT_DATE)); + IFFAILRET(doCoerce(pvargFrom, VT_BSTR)); + IFFAILRET(doCoerce(pvargFrom, VT_DISPATCH)); + IFFAILRET(doCoerce(pvargFrom, VT_ERROR)); + IFFAILRET(doCoerce(pvargFrom, VT_BOOL)); + IFFAILRET(doCoerce(pvargFrom, VT_UNKNOWN)); + + return NOERROR; +} + +HRESULT +DefVariantTest(VARIANT_TEST_INFO FAR* pvti) +{ + int i; + VARIANTARG vargFrom; + VARIANTARG vargRefMem; + + + for(i = 0; i < pvti->nValues; ++i){ + VariantInit(&vargFrom); + + IfFailRet(VariantFromVariantTestInfo(pvti, i, &vargFrom, &vargRefMem)); + + IfFailRet(coerce(&vargFrom)); + + VariantClearAll(&vargFrom); + } + + return NOERROR; +} + + +#define CYFACTOR 10000 + +// NOTE: we define our own max/min values here, because these differ +// slightly than those supplied by limits.h for some compilers we use. +// specifically: C8 (and predecessors) define min short to be -32767, +// while we allow it to be one lower, -32768. + +#if VBA2 +#define MAX_UI1 0xFF +#define MIN_UI1 0x00 +#endif //VBA2 + +#define MAX_I2 0x7FFF +#define MIN_I2 0x8000 + +#define MAX_I4 0x7FFFFFFF +#define MIN_I4 0x80000000 + +#define MAX_R4 3.402823466e+38 +#define MIN_R4 (-3.402823466e+38) + +#if VBA2 +unsigned char g_bMax = MAX_UI1; +unsigned char g_bMin = MIN_UI1; +#endif //VBA2 + +short g_sMax = MAX_I2; +short g_sMin = MIN_I2; + +long g_lMax = MAX_I4; +long g_lMin = MIN_I4; + +CY g_cyMax = CY_(0x7FFFFFFF, 0xFFFFFFFF); +CY g_cyMin = CY_(0x80000000, 0x00000000); + +float g_fltMax = (float) MAX_R4; +float g_fltMin = (float) MIN_R4; + +void KillOpt(){} + +void +IncVar(VARIANT FAR* pvar) +{ + unsigned long ul; + float fltOrg, fltInc; + double dblOrg, dblInc; + +#if HC_MPW + float FAR* pfltTmp; + double FAR* pdblTmp; +#else + volatile float FAR* pfltTmp; + volatile double FAR* pdblTmp; +#endif + + pfltTmp = &V_R4(pvar); + pdblTmp = &V_R8(pvar); + + switch(V_VT(pvar)){ +#if VBA2 + case VT_UI1: + ++V_UI1(pvar); + break; +#endif //VBA2 + + case VT_I2: + ++V_I2(pvar); + break; + + case VT_I4: + ++V_I4(pvar); + break; + + case VT_R4: + fltInc = (float)1.0; + fltOrg = *pfltTmp; + while(1){ + *pfltTmp = *pfltTmp + fltInc; + KillOpt(); + if(*pfltTmp != fltOrg) + break; + fltInc *= (float)2.0; + } + break; + + case VT_R8: + dblInc = 1.0; + dblOrg = *pdblTmp; + while(1){ + *pdblTmp = *pdblTmp + dblInc; + KillOpt(); + if(*pdblTmp != dblOrg) + break; + dblInc *= 2.0; + } + break; + + case VT_CY: + ul = V_CY(pvar).Lo; + if((V_CY(pvar).Lo += CYFACTOR) <= ul){ + ++V_CY(pvar).Hi; + } + break; + } +} + +void +DecVar(VARIANT FAR* pvar) +{ + unsigned long ul; + float fltInc, fltOrg; + double dblInc, dblOrg; + +#if HC_MPW + float FAR* pfltTmp; + double FAR* pdblTmp; +#else + volatile float FAR* pfltTmp; + volatile double FAR* pdblTmp; +#endif + + pfltTmp = &V_R4(pvar); + pdblTmp = &V_R8(pvar); + + switch(V_VT(pvar)){ +#if VBA2 + case VT_UI1: + --V_UI1(pvar); + break; +#endif //VBA2 + case VT_I2: + --V_I2(pvar); + break; + + case VT_I4: + --V_I4(pvar); + break; + + case VT_R4: + fltOrg = *pfltTmp; + fltInc = (float)1.0; + while(1){ + *pfltTmp = *pfltTmp - fltInc; + KillOpt(); + if(*pfltTmp != fltOrg) + break; + fltInc *= (float)2.0; + } + break; + + case VT_R8: + dblOrg = *pdblTmp; + dblInc = 1.0; + while(1){ + *pdblTmp = *pdblTmp - dblInc; + KillOpt(); + if(*pdblTmp != dblOrg) + break; + dblInc *= 2.0; + } + break; + + case VT_CY: + ul = V_CY(pvar).Lo; + if((V_CY(pvar).Lo -= CYFACTOR) >= ul){ + --V_CY(pvar).Hi; + } + break; + } +} + +HRESULT +doOverflow(VARTYPE vt, VARIANT varMax, VARIANT varMin) +{ + int i; + HRESULT hr; + VARIANT var; + VARTYPE vtFrom; + +#define BACKOFF_ITERATIONS 3 + + vtFrom = V_VT(&varMax); + ASSERT(vtFrom == V_VT(&varMin)); + + + VariantInit(&var); + IfFailRet(VariantChangeType(&var, &varMax, 0, vt)); + + // back off the max value, + for(i = 0; i < BACKOFF_ITERATIONS; ++i) + DecVar(&var); + + for(i = 0; i <= BACKOFF_ITERATIONS*3; ++i){ + hr = doCoerce(&var, vtFrom); + if(hr != NOERROR){ + if(GetScode(hr) == DISP_E_OVERFLOW) + goto LDoneWithMax; + return hr; + } + IncVar(&var); + } + return RESULT(E_FAIL); // failed to detect overflow + +LDoneWithMax:; + + VariantInit(&var); + IfFailRet(VariantChangeType(&var, &varMin, 0, vt)); + + // back off the min value + for(i = 0; i < BACKOFF_ITERATIONS; ++i) + IncVar(&var); + + for(i = 0; i <= BACKOFF_ITERATIONS*3; ++i){ + hr = doCoerce(&var, vtFrom); + if(hr != NOERROR){ + if(GetScode(hr) == DISP_E_OVERFLOW) + goto LDoneWithMin; + return hr; + } + DecVar(&var); + } + return RESULT(E_FAIL); // failed to detect overflow + +LDoneWithMin:; + + return NOERROR; +} + +/*** +*PRIVATE HRESULT OverflowTests +*Purpose: +* Test various coersions to make sure they properly catch overflows. +* +* The heirarchy of ranges for each datatype is as follows, +* +* ui1 < i2 < i4 < cy < r4 < r8 +* +* which means that we need to check the following coersions for overflow, +* +* i2->ui1 +* i4->ui1, i4->i2 +* cy->ui1, cy->i2, cy->i4 +* r4->ui1, r4->i2, r4->i4, r4->cy +* r8->ui1, r8->i2, r8->i4, r8->cy, r8->r4 +* +*Entry: +* None +* +*Exit: +* return value = HRESULT +* +***********************************************************************/ +HRESULT +OverflowTests(VARIANT_TEST_INFO FAR* dummy) +{ +#if VBA2 + VARIANT varUI1Max, varUI1Min; +#endif //VBA2 + VARIANT varI2Max, varI2Min; + VARIANT varI4Max, varI4Min; + VARIANT varCyMax, varCyMin; + VARIANT varR4Max, varR4Min; + + UNUSED(dummy); + +#if VBA2 + V_VT(&varUI1Max) = VT_UI1; V_UI1(&varUI1Max) = g_bMax; + V_VT(&varUI1Min) = VT_UI1; V_UI1(&varUI1Min) = g_bMin; +#endif //VBA2 + + V_VT(&varI2Max) = VT_I2; V_I2(&varI2Max) = g_sMax; + V_VT(&varI2Min) = VT_I2; V_I2(&varI2Min) = g_sMin; + + V_VT(&varI4Max) = VT_I4; V_I4(&varI4Max) = g_lMax; + V_VT(&varI4Min) = VT_I4; V_I4(&varI4Min) = g_lMin; + + V_VT(&varCyMax) = VT_CY; V_CY(&varCyMax) = g_cyMax; + V_VT(&varCyMin) = VT_CY; V_CY(&varCyMin) = g_cyMin; + + V_VT(&varR4Max) = VT_R4; V_R4(&varR4Max) = g_fltMax; + V_VT(&varR4Min) = VT_R4; V_R4(&varR4Min) = g_fltMin; + +#if VBA2 + IfFailRet(doOverflow(VT_I2, varUI1Max, varUI1Min)); +#endif //VBA2 + +#if VBA2 + IfFailRet(doOverflow(VT_I4, varUI1Max, varUI1Min)); +#endif //VBA2 + IfFailRet(doOverflow(VT_I4, varI2Max, varI2Min)); + +#if VBA2 + IfFailRet(doOverflow(VT_CY, varUI1Max, varUI1Min)); +#endif //VBA2 + IfFailRet(doOverflow(VT_CY, varI2Max, varI2Min)); + IfFailRet(doOverflow(VT_CY, varI4Max, varI4Min)); + +#if VBA2 + IfFailRet(doOverflow(VT_R4, varUI1Max, varUI1Min)); +#endif //VBA2 + IfFailRet(doOverflow(VT_R4, varI2Max, varI2Min)); + IfFailRet(doOverflow(VT_R4, varI4Max, varI4Min)); + IfFailRet(doOverflow(VT_R4, varCyMax, varCyMin)); + +#if VBA2 + IfFailRet(doOverflow(VT_R8, varUI1Max, varUI1Min)); +#endif //VBA2 + IfFailRet(doOverflow(VT_R8, varI2Max, varI2Min)); + IfFailRet(doOverflow(VT_R8, varI4Max, varI4Min)); + IfFailRet(doOverflow(VT_R8, varCyMax, varCyMin)); + IfFailRet(doOverflow(VT_R8, varR4Max, varR4Min)); + + return NOERROR; +} + + +//--------------------------------------------------------------------- +// regression tests +//--------------------------------------------------------------------- + + +// regression test for raid:oob#1469 +// +// problem: Currency literal parsed wrong (BSTR -> CY) +// +HRESULT +VariantOB1469(VARIANT_TEST_INFO FAR* dummy) +{ + int i; + VARIANT var; + HRESULT hresult; +static OLECHAR FAR* str[] = { + OLESTR("92233700000"), + OLESTR("92233800000"), +}; + + UNUSED(dummy); + + for(i = 0; i < DIM(str); ++i){ + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(str[i]); + if(V_BSTR(&var) == NULL) + return RESULT(E_OUTOFMEMORY); + IfFailGo(VariantChangeType(&var, &var, 0, VT_CY), LError0); + VariantClear(&var); + } + + return NOERROR; + +LError0:; + VariantClear(&var); + + return hresult; +} + + + +// regression for raid:ob#2078 +// +// problem: double output off by 1 in last digit +// +HRESULT +VariantOB2078(VARIANT_TEST_INFO FAR* dummy) +{ + LCID lcid; + HRESULT hresult; + BSTR bstr1, bstr2; + double r1 = -1.797693134862315E+308, + r2 = 1.797693134862315E+308; + + UNUSED(dummy); + + bstr1 = bstr2 = NULL; + + lcid = GetUserDefaultLCID(); + + IfFailGo(VarBstrFromR8(r1, lcid, NULL, &bstr1), LError0); + IfFailGo(VarBstrFromR8(r2, lcid, NULL, &bstr2), LError0); + + if (STRCMP(STRING(bstr1), TSTR("-1.797693134862312E+308")) != 0){ + hresult = RESULT(E_FAIL); + goto LError0; + } + + if (STRCMP(STRING(bstr2), TSTR("1.797693134862312E+308")) != 0){ + hresult = RESULT(E_FAIL); + goto LError0; + } + + hresult = NOERROR; + +LError0:; + SysFreeString(bstr1); + SysFreeString(bstr2); + return hresult; +} + + + +// regression for raid:ob#2834 +// +// problem: not accepting YMD without year (accepted by VB3) +// +HRESULT +VariantOB2834(VARIANT_TEST_INFO FAR* dummy) +{ + DATE date; + BSTR bstr; + HRESULT hresult; + + UNUSED(dummy); + + IfFailRet(VarDateFromStr(OLESTR("8:07 AM"), + GetUserDefaultLCID(), 0, + &date)); + + bstr = NULL; + + hresult = VarBstrFromDate(date, GetUserDefaultLCID(), 0, &bstr); + + SysFreeString(bstr); + + return hresult; +} + + +// regression for raid:ob#3028 +// +// problem: Leading 0 is being ignored for the system (&prj) locale +// +HRESULT +VariantOB3028(VARIANT_TEST_INFO FAR* dummy) +{ + CY cy; + LCID lcid; + char szBuff[2]; + BSTR bstr1, bstr2; + HRESULT hresult; + + UNUSED(dummy); + + bstr1 = bstr2 = NULL; + + lcid = GetUserDefaultLCID(); + + IfFailGo(VarBstrFromR8(0.739, lcid, NULL, &bstr1), LError0); + DbPrintf("VarBstrFromR8(0.739) = \"%Fs\"\n", STRING(bstr1)); + + IfFailGo(VarCyFromR8(0.739, &cy), LError0); + IfFailGo(VarBstrFromCy(cy, lcid, NULL, &bstr2), LError0); + DbPrintf("VarBstrFromCy(0.739) = \"%Fs\"\n", STRING(bstr2)); + + GetLocaleInfoA(lcid, LOCALE_ILZERO, szBuff, SIZEOFCH(szBuff)); + if (szBuff[0] == '0') { + if (STRCMP(STRING(bstr1), TSTR(".739")) != 0 || + STRCMP(STRING(bstr2), TSTR(".739")) != 0){ + hresult = RESULT(E_FAIL); + goto LError0; + } + } else { + if (STRCMP(STRING(bstr1), TSTR("0.739")) != 0 || + STRCMP(STRING(bstr2), TSTR("0.739")) != 0){ + hresult = RESULT(E_FAIL); + goto LError0; + } + } + + hresult = NOERROR; + +LError0:; + SysFreeString(bstr1); + SysFreeString(bstr2); + return hresult; +} + + +// regression for raid:ob#3336 +// +// problem: Conversion routines does not remove thousands separators +// when coersing from STR to either R8 or CY. +// +HRESULT +VariantOB3336(VARIANT_TEST_INFO FAR* dummy) +{ + int i; + VARIANT var; + HRESULT hresult; + static OLECHAR FAR* str[] = { + OLESTR("12,456.78"), + OLESTR("1,2,3,4,5,6,,789.123"), + OLESTR(",1234,5678,9"), + OLESTR("123,456,789.124") +}; + + UNUSED(dummy); + + for(i = 0; i < DIM(str); ++i){ + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(str[i]); + if(V_BSTR(&var) == NULL) + return RESULT(E_OUTOFMEMORY); + IfFailGo(VariantChangeType(&var, &var, 0, VT_CY), LError0); + IfFailGo(VariantChangeType(&var, &var, 0, VT_R8), LError0); + VariantClear(&var); + } + + return NOERROR; + +LError0:; + VariantClear(&var); + + return hresult; +} + +// regression for raid:ob#3354 +// +// problem: Coersion to Date doesn't validate input value. +// +HRESULT +VariantOB3354(VARIANT_TEST_INFO FAR* dummy) +{ + DATE date; + + UNUSED(dummy); + if (VarDateFromR8(3000, &date) != NOERROR) return RESULT(E_FAIL); + if (VarDateFromR8(30000000, &date) == NOERROR) return RESULT(E_FAIL); + return NOERROR; +} + + +// regression for raid:ob#3603 +// +// problem: VarCyFromStr is hammering the input string (it is removing +// the negative sign in the following example in place). +// +HRESULT +VariantOB3603(VARIANT_TEST_INFO FAR* dummy) +{ + CY cy; + TCHAR strIn[32]; + HRESULT hresult; + + UNUSED(dummy); + STRCPY(strIn, TSTR("-1.0000000001")); + DbPrintf("strIn = \"%Fs\"\n", (char FAR*) strIn); + DbPrintf("strIn = \"%Fs\"\n", (char FAR*) strIn); + hresult = VarCyFromStr(WIDESTRING(strIn), 0, 0, &cy); + DbPrintf("VarCyFromStr(strIn, 0, 0, &cy) = %Fs\n", + DbSzOfScode(GetScode(hresult))); + DbPrintf("strIn = \"%Fs\"\n", (char FAR*) strIn); + return NOERROR; +} + + +// regression for raid:ob#3875 +// +// problem: not accepting YMD without year (accepted by VB3) +// +HRESULT +VariantOB3875(VARIANT_TEST_INFO FAR* dummy) +{ + DATE date; + + UNUSED(dummy); + IfFailRet(VarDateFromStr(OLESTR("93/4/30"), + GetUserDefaultLCID(), 0, + &date)); + IfFailRet(VarDateFromStr(OLESTR("4/30"), + GetUserDefaultLCID(), 0, + &date)); + return NOERROR; +} + + + +// regression for raid:ob#3876 +// +// problem: medium month with period (dec.) not recognized in date string +// +HRESULT +VariantOB3876(VARIANT_TEST_INFO FAR* dummy) +{ + DATE date; + + UNUSED(dummy); + IfFailRet(VarDateFromStr(OLESTR("12 dec 05 1:23 pm"), + GetUserDefaultLCID(), 0, + &date)); + IfFailRet(VarDateFromStr(OLESTR("12 dec. 05 1:23 pm"), + GetUserDefaultLCID(), 0, + &date)); + return NOERROR; +} + + +// regression test for raid:oleprog#10 +// +// problem: overflow not detected on coersion from VT_R8 to VT_R4. +// +HRESULT +VariantOleprog10(VARIANT_TEST_INFO FAR* dummy) +{ + SCODE scode; + HRESULT hresult; + VARIANT varFrom, varTo; + + UNUSED(dummy); + + VariantInit(&varTo); + + V_VT(&varFrom) = VT_R8; + V_R8(&varFrom) = DBL_MAX; + + hresult = VariantChangeType(&varTo, &varFrom, 0, VT_R4); + + scode = GetScode(hresult); + + if(scode != DISP_E_OVERFLOW) + return RESULT(E_UNEXPECTED); + + return NOERROR; +} + + +// regression test for raid:oleprog#11 +// +// problem: failed in place coersion of a variant destroys the +// contents of the variant. +// +HRESULT +VariantOleprog11(VARIANT_TEST_INFO FAR* dummy) +{ + SCODE scode; + VARIANT var; + HRESULT hresult; + + UNUSED(dummy); + + V_VT(&var) = VT_R8; + V_R8(&var) = DBL_MAX; + hresult = VariantChangeType(&var, &var, 0, VT_R4); + scode = GetScode(hresult); + + // make sure the overflow was caught correctly. + if(scode != DISP_E_OVERFLOW) + return RESULT(E_UNEXPECTED); + + // if the coersion failed, the contents should not be destroyed + // + if(V_VT(&var) != VT_R8 || V_R8(&var) != DBL_MAX) + return RESULT(E_UNEXPECTED); + + return NOERROR; +} + + +// regression test for raid:oleprog#12 +// +// problem: coersion of variants in place do not free strings. +// +HRESULT +VariantOleprog12(VARIANT_TEST_INFO FAR* dummy) +{ + int i; + VARIANT var; + HRESULT hresult; + +#if VBA2 +static VARTYPE rgvt[] = {VT_UI1, VT_I2, VT_I4, VT_R4, VT_R8, VT_CY}; +#else //VBA2 +static VARTYPE rgvt[] = {VT_I2, VT_I4, VT_R4, VT_R8, VT_CY}; +#endif //VBA2 + + + UNUSED(dummy); + + for(i = 0; i < DIM(rgvt); ++i){ + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(OLESTR("14")); + if(V_BSTR(&var) == NULL) + return RESULT(E_OUTOFMEMORY); + IfFailGo(VariantChangeType(&var, &var, 0, rgvt[i]), LError0); + VariantClear(&var); + } + + return NOERROR; + +LError0:; + VariantClear(&var); + + return hresult; +} + + +// retression test for raid:oleprog#27 +// +// problem: cant VariantCopyInd on a variant containing a ByRef array. +// +HRESULT +VariantOleprog27(VARIANT_TEST_INFO FAR* dummy) +{ + VARIANT var, varTo; + SAFEARRAY FAR* psa; + SARRAYDESC sadesc; + HRESULT hresult, hresultTmp; + + UNUSED(dummy); + + sadesc.cDims = 1; + sadesc.rgsabound[0].lLbound = 5; + sadesc.rgsabound[0].cElements = 5; + + IfFailRet(SafeArrayCreateIdentity(VT_BSTR, &sadesc, &psa)); + + V_VT(&var) = (VT_ARRAY|VT_BYREF|VT_BSTR); + V_ARRAYREF(&var) = &psa; + + VariantInit(&varTo); + IfFailGo(VariantCopyInd(&varTo, &var), LError0); + if(V_VT(&varTo) != (VT_ARRAY|VT_BSTR) +#if 0 +// add this back in when VariantCompare can handle arrays + || !VariantCompare(&varTo, &var) +#endif + ){ + hresult = RESULT(E_UNEXPECTED); + goto LError1; + } + + hresultTmp = VariantClear(&varTo); + ASSERT(hresultTmp == NOERROR); + + // now try the copy in-place + // + V_VT(&var) |= VT_BYREF; + IfFailGo(VariantCopyInd(&var, &var), LError0); + if(V_VT(&var) != (VT_ARRAY|VT_BSTR)){ + hresult = RESULT(E_UNEXPECTED); + goto LError0; + } + + hresultTmp = VariantClear(&var); + ASSERT(hresultTmp == NOERROR); + + hresultTmp = SafeArrayDestroy(psa); + ASSERT(hresultTmp == NOERROR); + + return NOERROR; + +LError1:; + VariantClear(&varTo); + +LError0:; + VariantClearAll(&var); + + return hresult; +} + + +// regression test for raid:oleprog#50 +// +// problem: in place variant coersion from VT_BYREF fail (all types) +// +HRESULT +VariantOleprog50(VARIANT_TEST_INFO FAR* dummy) +{ + short i2; + VARIANT var; + + UNUSED(dummy); + + i2 = 42; + V_I2REF(&var) = &i2; + V_VT(&var) = VT_BYREF | VT_I2; + return VariantChangeType(&var, &var, 0, VT_I2); +} + + +// regression test for raid:oleprog#84 +// +// problem: need to allow literal copying of ByRef variants. +// +HRESULT +VariantOleprog84(VARIANT_TEST_INFO FAR* dummy) +{ + short i2; + HRESULT hr, hrTmp; + VARIANT varSrc, varDst; + + UNUSED(dummy); + + i2 = 42; + V_I2REF(&varSrc) = &i2; + V_VT(&varSrc) = VT_BYREF | VT_I2; + VariantInit(&varDst); + hr = VariantCopy(&varDst, &varSrc); + hrTmp = VariantClear(&varDst); + ASSERT(hrTmp == NOERROR); + hrTmp = VariantClear(&varSrc); + ASSERT(hrTmp == NOERROR); + return hr; +} + + +// regression for unraided bug +// +// problem: VariantCopy/VariantCopyInd incorrectly report OutOfMemory +// when copying a VT_BSTR that is NULL. +// +HRESULT +VariantBug0(VARIANT_TEST_INFO FAR* dummy) +{ + BSTR bstr; + VARIANT varFrom, varTo; + HRESULT hresult, hresultTmp; + + UNUSED(dummy); + + V_VT(&varFrom) = VT_BSTR; + V_BSTR(&varFrom) = NULL; + + VariantInit(&varTo); + + IfFailRet(VariantCopy(&varTo, &varFrom)); + + hresultTmp = VariantClear(&varTo); + ASSERT(hresultTmp == NOERROR); + + bstr = NULL; + V_VT(&varFrom) = VT_BYREF | VT_BSTR; + V_BSTRREF(&varFrom) = &bstr; + + hresult = VariantCopyInd(&varTo, &varFrom); + + hresultTmp = VariantClear(&varTo); + ASSERT(hresultTmp == NOERROR); + + return hresult; +} + + +// regression test for raid:oleprog#82 +// +// problem: variant copy on a VT_BSTR containing an embedded null +// looses everything after the embedded null. +// +HRESULT +VariantOleprog82(VARIANT_TEST_INFO FAR* dummy) +{ + BSTR bstr; + HRESULT hresult; + VARIANT varFrom, varTo; + static OLECHAR sz_embedded_null[] = + OLESTR("where is \0 the rest of my string?"); + + + UNUSED(dummy); + + VariantInit(&varTo); + VariantInit(&varFrom); + + bstr = SysAllocStringLen(sz_embedded_null, sizeof(sz_embedded_null)); + + V_VT(&varFrom) = VT_BSTR; + V_BSTR(&varFrom) = bstr; + + VariantInit(&varTo); + + if((hresult = VariantCopy(&varTo, &varFrom)) != NOERROR) + goto LError0; + + if(MEMCMP(V_BSTR(&varTo), sz_embedded_null, sizeof(sz_embedded_null)) != 0){ + hresult = RESULT(E_UNEXPECTED); + goto LError1; + } + + + VariantClear(&varTo); + VariantClear(&varFrom); + + + bstr = SysAllocStringLen(sz_embedded_null, sizeof(sz_embedded_null)); + + V_VT(&varFrom) = VT_BYREF | VT_BSTR; + V_BSTRREF(&varFrom) = &bstr; + + VariantInit(&varTo); + + if((hresult = VariantCopyInd(&varTo, &varFrom)) != NOERROR) + goto LError0; + + if(MEMCMP(V_BSTRREF(&varTo), sz_embedded_null, sizeof(sz_embedded_null)) != 0){ + hresult = RESULT(E_UNEXPECTED); + goto LError1; + } + + hresult = NOERROR; + +LError1:; + VariantClear(&varTo); + +LError0:; + VariantClearAll(&varFrom); + + return hresult; +} + + +HRESULT +VariantOleprog94(VARIANT_TEST_INFO FAR* dummy) +{ + BSTR bstr; + VARIANT var; + HRESULT hresult; + + UNUSED(dummy); + + bstr = SysAllocString(OLESTR("hello world")); + V_VT(&var) = VT_BYREF | VT_BSTR; + V_BSTRREF(&var) = &bstr; + + hresult = doCoerce(&var, VT_BSTR); + + VariantClearAll(&var); + + return hresult; +} + + +// regression test for raid!oleprog#235 +// +// Problem: not correctly handling variants of VT_UNKNOWN or VT_DISPATCH +// that have a null IDispatch or IUnknown ptr. +// +HRESULT +VariantOleprog235(VARIANT_TEST_INFO FAR* dummy) +{ + HRESULT hresult; + VARIANT varSrc, varDst; + + UNUSED(dummy); + + V_VT(&varSrc) = VT_UNKNOWN; + V_UNKNOWN(&varSrc) = NULL; + VariantInit(&varDst); + IfFailRet(VariantCopy(&varDst, &varSrc)); + VariantClear(&varDst); + + V_VT(&varSrc) = VT_DISPATCH; + V_DISPATCH(&varSrc) = NULL; + VariantInit(&varDst); + IfFailRet(VariantCopy(&varDst, &varSrc)); + VariantClear(&varDst); + + // a null object cannot be converted to any fundamental type - + // because there is no way for us to extract its value property + + hresult = VariantChangeType(&varDst, &varSrc, 0, VT_I2); + if(hresult == NOERROR || GetScode(hresult) != DISP_E_TYPEMISMATCH) + return RESULT(E_FAIL); + + VariantClear(&varDst); + VariantClear(&varSrc); + return NOERROR; +} + + +// regression test for raid!oleprog#351 +// +// Problem: not correctly handling coersion of interface variants types +// of VT_UNKNOWN, VT_DISPATCH, or VT_DISPATCHW +// + + +class CBar : public IUnknown { +public: + STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppv); + STDMETHOD_(unsigned long, AddRef)(void); + STDMETHOD_(unsigned long, Release)(void); + CBar::CBar(){ + m_refs = 1; + } +private: + unsigned long m_refs; +}; +STDMETHODIMP +CBar::QueryInterface(REFIID riid, void FAR* FAR* ppv) +{ + if(!IsEqualIID(riid, IID_IUnknown)) + if(!IsEqualIID(riid, IID_IDispatch)) + return RESULT(E_NOINTERFACE); + + *ppv = this; + AddRef(); + return NOERROR; +} +STDMETHODIMP_(unsigned long) +CBar::AddRef() +{ + return ++m_refs; +} +STDMETHODIMP_(unsigned long) +CBar::Release() +{ + if(--m_refs == 0){ + delete this; + return 0; + } + return m_refs; +} + +HRESULT +VariantOleprog351(VARIANT_TEST_INFO FAR* dummy) +{ + HRESULT hresult; + VARIANT varSrc, varDst; + IUnknown FAR* punk; + + UNUSED(dummy); + + if((punk = (IUnknown FAR*)new FAR CBar()) == NULL) + return RESULT(E_OUTOFMEMORY); + + VariantInit(&varSrc); + VariantInit(&varDst); + V_VT(&varSrc) = VT_UNKNOWN; + V_UNKNOWN(&varSrc) = punk; + + // Test Non-Interface Coersion + VariantClear(&varDst); + hresult = VariantChangeType(&varDst, &varSrc, 0, VT_I2); + if(!(hresult == NOERROR || GetScode(hresult) == DISP_E_TYPEMISMATCH)) + return RESULT(E_FAIL); + + // Test IUnknown Coersion + VariantClear(&varDst); + hresult = VariantChangeType(&varDst, &varSrc, 0, VT_UNKNOWN); + if(!(hresult == NOERROR || GetScode(hresult) == DISP_E_TYPEMISMATCH)) + return RESULT(E_FAIL); + + // Test IDispatch Coersion + VariantClear(&varDst); + hresult = VariantChangeType(&varDst, &varSrc, 0, VT_DISPATCH); + if(!(hresult == NOERROR || GetScode(hresult) == DISP_E_TYPEMISMATCH)) + return RESULT(E_FAIL); + + VariantClear(&varDst); + VariantClear(&varSrc); + return NOERROR; +} + +class CFoo : public IUnknown { +public: + STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppv); + STDMETHOD_(unsigned long, AddRef)(void); + STDMETHOD_(unsigned long, Release)(void); + CFoo::CFoo(){ + m_refs = 0; + } +private: + unsigned long m_refs; +}; +STDMETHODIMP +CFoo::QueryInterface(REFIID riid, void FAR* FAR* ppv) +{ + if(IsEqualIID(riid, IID_IUnknown)){ + *ppv = this; + AddRef(); + return NOERROR; + } + return RESULT(E_NOINTERFACE); +} +STDMETHODIMP_(unsigned long) +CFoo::AddRef() +{ + return ++m_refs; +} +STDMETHODIMP_(unsigned long) +CFoo::Release() +{ + if(--m_refs == 0){ + delete this; + return 0; + } + return m_refs; +} + + +HRESULT +VariantBug1(VARIANT_TEST_INFO FAR* dummy) +{ + unsigned long refs; + VARIANT varDst, var; + HRESULT hresult; + IUnknown FAR* punk; + + UNUSED(dummy); + + if((punk = (IUnknown FAR*)new FAR CFoo()) == NULL) + return RESULT(E_OUTOFMEMORY); + punk->AddRef(); + + V_VT(&var) = VT_BYREF | VT_DISPATCH; + V_UNKNOWNREF(&var) = &punk; + VariantInit(&varDst); + hresult = VariantCopyInd(&varDst, &var); + ASSERT(hresult == NOERROR); + ASSERT(V_VT(&varDst) == VT_DISPATCH); + refs = punk->Release(); + ASSERT(refs == 1); + refs = V_DISPATCH(&varDst)->Release(); + ASSERT(refs == 0); + + return NOERROR; +} + diff --git a/private/oleauto/tests/disptest/cwbstr.cpp b/private/oleauto/tests/disptest/cwbstr.cpp new file mode 100644 index 000000000..443ff47a3 --- /dev/null +++ b/private/oleauto/tests/disptest/cwbstr.cpp @@ -0,0 +1,320 @@ +/*** +*cbstr.cpp +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* This file implements the CBstrSuite test object. +* +*Revision History: +* +* [00] 30-Oct-92 bradlo: Created. +* +*Implementation Notes: +* +*****************************************************************************/ + +#include "disptest.h" + +#include <limits.h> + +#include "tstsuite.h" + +ASSERTDATA + +#if OE_WIN32 && 0 + +struct TEST { + HRESULT (*pfnTest)(void); + char FAR* szName; +}; + + +HRESULT WBstrOleprog5(void); +HRESULT WBstrOleprog8(void); +HRESULT WBstrOleprog65(void); +HRESULT WBstrOleprog234(void); +HRESULT WBstrLimits(void); +HRESULT WBstrConvert(void); + +static TEST rgtest[] = { + { WBstrOleprog5, "raid!oleprog#5W" } + , { WBstrOleprog8, "raid!oleprog#8W" } + , { WBstrOleprog65, "raid!oleprog#65W" } + , { WBstrOleprog234, "raid!oleprog#234W" } + , { WBstrLimits, "WBstr limits" } + , { WBstrConvert, "WBstr conversion" } +}; + + +SUITE_CONSTRUCTION_IMPL(CWBstrSuite) + +SUITE_IUNKNOWN_IMPL(CWBstrSuite) + + +//--------------------------------------------------------------------- +// ITestSuite Methods +//--------------------------------------------------------------------- + +STDMETHODIMP +CWBstrSuite::GetNameOfSuite(BSTR FAR* pbstr) +{ + return ErrBstrAlloc("WBSTR API", pbstr); +} + +STDMETHODIMP +CWBstrSuite::GetNameOfLogfile(BSTR FAR* pbstr) +{ + return ErrBstrAlloc("wbstrapi.log", pbstr); +} + +STDMETHODIMP +CWBstrSuite::GetTestCount(unsigned int FAR* pcTests) +{ + *pcTests = DIM(rgtest); + return NOERROR; +} + +STDMETHODIMP +CWBstrSuite::GetNameOfTest(unsigned int iTest, BSTR FAR* pbstr) +{ + if(iTest >= DIM(rgtest)) + return RESULT(E_INVALIDARG); + + *pbstr = SysAllocString(rgtest[iTest].szName); + return NOERROR; +} + + +/*** +*HRESULT CWBstrSuite::DoTest(unsigned int) +*Purpose: +* Execute a single CWBstrSuite test. +* +*Entry: +* iTest = the index of the test to execute +* +*Exit: +* return value = HRESULT +* +***********************************************************************/ +STDMETHODIMP +CWBstrSuite::DoTest(unsigned int iTest) +{ + if(iTest >= DIM(rgtest)) + return RESULT(E_INVALIDARG); + + return rgtest[iTest].pfnTest(); +} + + + +//--------------------------------------------------------------------- +// WBSTR Test Suites +//--------------------------------------------------------------------- + + +// regression test for raid!oleprog:5 +// +HRESULT +WBstrOleprog5() +{ + unsigned int len; + WBSTR wbstr; +static WCHAR a_string[] = L"a string"; +static WCHAR another_string[] = L"another (longer) string"; + + wbstr = SysAllocStringW(a_string); + if(wbstr == NULL) + return RESULT(E_OUTOFMEMORY); + + len = SysStringLenW(wbstr); + if(len != (unsigned int) lstrlenW(a_string)) + return RESULT(E_FAIL); + + if(!SysReAllocStringW(&wbstr, another_string)) + return RESULT(E_OUTOFMEMORY); + + len = SysStringLenW(wbstr); + if(len != (unsigned int) lstrlenW(another_string)) + return RESULT(E_FAIL); + + SysFreeStringW(wbstr); + + return NOERROR; +} + +// regression test for raid!oleprog:8 +// +HRESULT +WBstrOleprog8() +{ + unsigned int len; + HRESULT hresult; + WBSTR wbstr1, wbstr2; +#define LARGE_BSTR_SIZE 128600 + + if((wbstr1 = SysAllocStringLenW(NULL, LARGE_BSTR_SIZE)) == NULL){ + hresult = RESULT(E_OUTOFMEMORY); + goto LError0; + } + + if((wbstr2 = SysAllocStringW(L"hello world")) == NULL){ + hresult = RESULT(E_OUTOFMEMORY); + goto LError1; + } + + if((len = SysStringLenW(wbstr1)) != LARGE_BSTR_SIZE){ + hresult = RESULT(E_FAIL); + goto LError2; + } + + hresult = NOERROR; + +LError2:; + SysFreeStringW(wbstr1); + +LError1:; + SysFreeStringW(wbstr2); + +LError0:; + return hresult; + +#undef LARGE_BSTR_SIZE +} + +// regression test for raid!oleprog:8 +// +// SysAllocString of a string containing an embedded '\0' stops +// copying at the '\0'; +// +HRESULT +WBstrOleprog65() +{ + WBSTR wbstr; + HRESULT hresult; +static WCHAR sz_embedded_null[] = L"a string \0 with an embedded null"; + + + wbstr = SysAllocStringLenW(sz_embedded_null, sizeof(sz_embedded_null)); + + hresult = (MEMCMP(wbstr, sz_embedded_null, sizeof(sz_embedded_null)) == 0) + ? NOERROR + : RESULT(E_UNEXPECTED); + + SysFreeStringW(wbstr); + + return hresult; +} + +// regression test for raid!oleprog:234 +// +// make sure we are properly handling Reallocing a bstr thats Null. +// +HRESULT +WBstrOleprog234() +{ + unsigned int len; + WBSTR wbstr; +static WCHAR szHooHa[] = L"HooHa"; + + wbstr = NULL; + if(!SysReAllocStringW(&wbstr, szHooHa)) + return RESULT(E_OUTOFMEMORY); + + len = SysStringLenW(wbstr); + if(len != (unsigned int) lstrlenW(szHooHa)) + return RESULT(E_FAIL); + + SysFreeStringW(wbstr); + + return NOERROR; +} + +HRESULT +WBstrLimits() +{ + unsigned long u; + WBSTR wbstr; + +static unsigned long s2M = 2097152; +static unsigned long INCREMENT = 262144; + + DbPrintf("SysAllocStringLen()\n"); + + DbPrintf("linear increasing...\n"); + for(u = 1; u < s2M; u+=INCREMENT){ + DbPrintf("%lu\n", u); + wbstr = SysAllocStringLenW(NULL, (unsigned int)u); + Yield(); + if(wbstr == NULL) + break; + SysFreeStringW(wbstr); + } + DbPrintf("max len = %lu\n", u-1); + + DbPrintf("linear decreasing...\n"); + for(u = s2M; u > 0; u-=INCREMENT){ + DbPrintf("%lu\n", u); + wbstr = SysAllocStringLenW(NULL, (unsigned int)u); + Yield(); + if(wbstr == NULL) + break; + SysFreeStringW(wbstr); + } + DbPrintf("max len = %lu\n", u); + + return NOERROR; +} + + +HRESULT +WBstrConvert() +{ + static char* rgStrVal[] = { + "This is line #1" + , "This is another line" + }; + + static WCHAR* rgWStrVal[] ={ + L"This is line #1" + , L"This is another line" + }; + BSTR bstr; + WBSTR wbstr; + unsigned long len; + unsigned int i; + + DbPrintf("SysStringAtoW test\n"); + for(i = 0; i < DIM(rgStrVal); i++) { + bstr = SysAllocString(rgStrVal[i]); + wbstr = SysStringAtoW(bstr, CP_ACP); + if (wbstr != NULL) { + len = SysStringLenW(wbstr); + if((len != (unsigned int) lstrlenW(rgWStrVal[i])) || + (lstrcmpW(wbstr, rgWStrVal[i]) != 0)) + return RESULT(E_FAIL); + SysFreeStringW(wbstr); + SysFreeString(bstr); + } + } + + DbPrintf("SysStringWtoA test\n"); + for(i = 0; i < DIM(rgWStrVal); i++) { + wbstr = SysAllocStringW(rgWStrVal[i]); + bstr = SysStringWtoA(wbstr, CP_ACP); + if (bstr != NULL) { + len = SysStringLen(bstr); + if((len != (unsigned int) lstrlen(rgStrVal[i])) || + (lstrcmp(bstr, rgStrVal[i]) != 0)) + return RESULT(E_FAIL); + SysFreeString(bstr); + SysFreeStringW(wbstr); + } + } + + return NOERROR; +} + +#endif diff --git a/private/oleauto/tests/disptest/disptest.cpp b/private/oleauto/tests/disptest/disptest.cpp new file mode 100644 index 000000000..f8cd8a163 --- /dev/null +++ b/private/oleauto/tests/disptest/disptest.cpp @@ -0,0 +1,316 @@ +/*** +*disptest.c - IDispatch test driver. +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* This module contains the entry point for the IDispatch test app. +* +* iid.cpp - allocation of the ITestSuite IID +* dtmisc.cpp - misc helpers and utilities +* cbstr.cpp - CBstrSuite +* cwbstr.cpp - CWBstrSuite (WIN32 Only) +* ctime.cpp - CTimeSuite +* cdatecnv.cpp = CDateCoersionSuite +* cvariant.cpp - CVariantSuite +* csarray.cpp - CSafeArraySuite +* cinvval.cpp - CInvokeByValSuite +* cinvref.cpp - CInvokeByRefSuite +* cinvmult.cpp - CInvokeMultipleSuite +* cinvsary.cpp - CInvokeSafeArraySuite +* cinvex.cpp - CInvokeExcepinfoSuite +* ccollect.cpp - CCollectionSuite +* cearly.cpp - CEarlySuite +* +* REVIEW: tests still needed for the following, +* heterogeneous variant arrays - csarray/cinvsary +* +*Revision History: +* +* [00] 23-Sep-92 bradlo: Added header. +* +*Implementation Notes: +* +*****************************************************************************/ + +#include "disptest.h" +#include "tstsuite.h" + +ASSERTDATA + +STDAPI_(void) PassFail(HRESULT, OLECHAR FAR*, HWND); +STDAPI DispTestAll(HWND, int, int); +STDAPI DispTestOne(HWND, int); + +BOOL InitApplication(HINSTANCE hinst); +BOOL InitInstance(HINSTANCE hist, int nCmdShow); + +extern "C" BOOL CALLBACK EXPORT +AboutDlgProc(HWND, unsigned, WORD, LONG); + +extern "C" LRESULT CALLBACK EXPORT +MainWndProc(HWND, UINT, WPARAM, LPARAM); + + +int g_fTrace = FALSE; +int g_fNamed = FALSE; +int g_fMultiThread = FALSE; +int g_fDetectLeaks = FALSE; + +HINSTANCE g_hinst; // current instance + +HWND g_hwnd = NULL; + +TCHAR g_szFrameWinClass[] = TSTR("DispTestWinClass"); + +#if OE_WIN32 +CRITICAL_SECTION g_csDbPrintf; +#endif // OE_WIN32 + +/*** +*int WinMain(HANDLE, HANDLE, LPSTR, int) +*Purpose: +* Windows recognizes this function by name as the initial entry +* point for the program +* +*Entry: +* hinst = instance handle of this instance +* hinstPrev = instance handle of previous running instance (if any) +* lpszCmdLine = command line passed to the program +* nCmdShow = how to show the main window +* +*Exit: +* return value = int, exit status of the program +* +***********************************************************************/ +extern "C" int PASCAL +WinMain( + HINSTANCE hinst, + HINSTANCE hinstPrev, + LPSTR lpCmdLine, + int nCmdShow) +{ + MSG msg; + + if(!hinstPrev) + if(!InitApplication(hinst)) + return FALSE; + +#if OE_WIN32 + if(strstr(lpCmdLine, "-detectleaks")) +#else + if(STRSTR(lpCmdLine, "-detectleaks")) +#endif + g_fDetectLeaks = TRUE; + + if(InitOle() != NOERROR) + return FALSE; + + if(!InitInstance(hinst, nCmdShow) || !InitAppData()) { + UninitOle(); + return FALSE; + } + +#if OE_WIN32 + InitializeCriticalSection(&g_csDbPrintf); +#endif // OE_WIN32 + +#if OE_WIN32 + if(strstr(lpCmdLine, "-all")) +#else + if(STRSTR(lpCmdLine, "-all")) +#endif + { DispTestAll(g_hwnd, FALSE, FALSE); PostQuitMessage(0); } + + while(GetMessage(&msg, NULL, NULL, NULL)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + ReleaseAppData(); + UninitOle(); + + return msg.wParam; /* Returns the value from PostQuitMessage */ +} + +BOOL +InitApplication(HINSTANCE hinst) +{ + WNDCLASS wc; + + wc.style = NULL; + wc.lpfnWndProc = MainWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hinst; + wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); + wc.lpszMenuName = TSTR("DispTestMenu"); + wc.lpszClassName = g_szFrameWinClass; + if(!RegisterClass(&wc)) + return FALSE; + + return TRUE; +} + +#ifdef WIN32 +#define szAppTitle TSTR("IDispatch Test App (32-bit)") +#else //WIN32 +#define szAppTitle TSTR("IDispatch Test App") +#endif //WIN32 + +BOOL +InitInstance(HINSTANCE hinst, int nCmdShow) +{ + HWND hwnd; + + g_hinst = hinst; + + /* Create a main window for this application instance. */ + + hwnd = CreateWindow( + g_szFrameWinClass, + szAppTitle, // title bar text + WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX, // window style + CW_USEDEFAULT, // horizontal position + CW_USEDEFAULT, // vertical position + 550, // width position + 100, // height position + NULL, // no parent + NULL, // use the window class menu + hinst, // this instance owns this window + NULL); // pointer not needed + + if(!hwnd) + return FALSE; + +#if OE_WIN16 + // Multithreading is not availible on WIN16. + // UNDONE: Grey this for WIN32s. + // + EnableMenuItem(GetMenu(hwnd), IDM_OPTIONS_MULTITHREAD, MF_DISABLED); +#endif // OE_WIN16 + + ShowWindow(hwnd, nCmdShow); + UpdateWindow(hwnd); + + g_hwnd = hwnd; + return TRUE; +} + + +/*** +*BOOL AboutDlgProc(HWND, unsigned, WORD, LONG) +*Purpose: +* The "about" dialog box procedure. +* +*Entry: +* hwndDlg = window handle for the dialog box +* message = the window message +* wparam = message data +* lparam = message data +* +*Exit: +* return value = BOOL. TRUE if processed message, FALSE if not +* +***********************************************************************/ +extern "C" BOOL CALLBACK EXPORT +AboutDlgProc(HWND hwndDlg, unsigned message, WORD wparam, LONG lparam) +{ + switch(message){ + case WM_INITDIALOG: /* message: initialize dialog box */ + return TRUE; + + case WM_COMMAND: + if(wparam == IDOK || wparam == IDCANCEL){ + EndDialog(hwndDlg, TRUE); + return TRUE; + } + break; + } + return FALSE; +} + + +extern "C" LRESULT CALLBACK EXPORT +MainWndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) +{ + BOOL fChk; + HMENU hmenu; +static DLGPROC pfnAboutDlgProc; + HRESULT hresult; + + switch(message){ + case WM_COMMAND: + switch(wparam){ + case IDM_OPTIONS_MULTITHREAD: + fChk = g_fMultiThread = (g_fMultiThread) ? FALSE : TRUE; + goto LCheckMark; + + case IDM_OPTIONS_TRACE: + fChk = g_fTrace = (g_fTrace) ? FALSE : TRUE; + goto LCheckMark; + + case IDM_OPTIONS_NAMED: + fChk = g_fNamed = (g_fNamed) ? FALSE : TRUE; + +LCheckMark:; + hmenu = GetMenu(hwnd); + CheckMenuItem(hmenu, wparam, fChk ? MF_CHECKED : MF_UNCHECKED); + return 0; + + case IDM_ALL: + hresult = DispTestAll(hwnd, TRUE, g_fMultiThread); + + // If S_FALSE is returned, we've already displayed an error, so + // don't do it again. + // + if (GetScode(hresult) != S_FALSE) { + PassFail(hresult, OLESTR("Test All"), hwnd); + } + + return 0; + + case IDM_SUITE_BSTR: +#if OE_WIN32 && 0 + case IDM_SUITE_WBSTR: +#endif + case IDM_SUITE_TIME: + case IDM_SUITE_DATECNV: + case IDM_SUITE_VARIANT: + case IDM_SUITE_SAFEARRAY: + case IDM_SUITE_NLS: + case IDM_SUITE_BIND: + case IDM_SUITE_INVOKE_BYVAL: + case IDM_SUITE_INVOKE_BYREF: + case IDM_SUITE_INVOKE_SAFEARRAY: + case IDM_SUITE_INVOKE_EXCEPINFO: + case IDM_SUITE_COLLECTION: +#if VBA2 + case IDM_SUITE_EARLY: +#endif + DispTestOne(hwnd, wparam); + return 0; + + case IDM_HELP_ABOUT: + pfnAboutDlgProc = + (DLGPROC)MakeProcInstance((DLGPROC)AboutDlgProc, g_hinst); + DialogBox(g_hinst, TSTR("AboutBox"), hwnd, pfnAboutDlgProc); + FreeProcInstance(pfnAboutDlgProc); + return 0; + } + break; + + case WM_CLOSE: + DestroyWindow(hwnd); + return 0; + + case WM_DESTROY: /* message: window being destroyed */ + PostQuitMessage(0); + return 0; + } + + return DefWindowProc(hwnd, message, wparam, lparam); +} diff --git a/private/oleauto/tests/disptest/disptest.h b/private/oleauto/tests/disptest/disptest.h new file mode 100644 index 000000000..6822aa2f5 --- /dev/null +++ b/private/oleauto/tests/disptest/disptest.h @@ -0,0 +1,63 @@ +/*** +*disptest.h +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* IDispatch test app definitions. +* +*Revision History: +* +* [00] 28-Sep-92 bradlo: Added this cool header. +* +*Implementation Notes: +* +*****************************************************************************/ + +#ifndef _DISPTEST_H_ +#define _DISPTEST_H_ + +#include "common.h" +#include "resource.h" +#include "testhelp.h" +#include "dispdbug.h" + +#ifdef _MAC +# include <stdio.h> +typedef FILE* HFILE; +# define HFILE_ERROR NULL +#endif + +// misc.cpp +// +struct APP_DATA { + HFILE m_hfLogfile; + + APP_DATA() { + m_hfLogfile = HFILE_ERROR; + } +}; + +#if OE_WIN32 +extern unsigned long g_itlsAppData; +#else // !OE_WIN32 +extern APP_DATA g_appdata; +#endif // !OE_WIN32 + +APP_DATA *Pappdata(); +BOOL InitAppData(); +VOID ReleaseAppData(); + +STDAPI InitOle(void); +STDAPI_(void) UninitOle(void); + +EXTERN_C void DbPrintf(char FAR*, ...); + +void PrintSuiteHeader(TCHAR FAR* szFmt, ...); +void PrintTestHeader(TCHAR FAR* szFmt, ...); +void PrintVarg(OLECHAR FAR* sz, VARIANTARG FAR* pvarg); +void PrintDate(DATE date); + +#endif + diff --git a/private/oleauto/tests/disptest/guid.c b/private/oleauto/tests/disptest/guid.c new file mode 100644 index 000000000..3cf489210 --- /dev/null +++ b/private/oleauto/tests/disptest/guid.c @@ -0,0 +1,56 @@ +/*** +*guid.c +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* This file allocates (via Ole macro mania) the ITestSuite IID. +* +*Revision History: +* +* [00] 31-Oct-92 bradlo: Created. +* +*****************************************************************************/ + +#ifdef _MAC +# ifdef _MSC_VER +# include <macos/types.h> +# include <macos/processe.h> +# include <macos/appleeve.h> +# define far +# define FAR far +# define near +# define NEAR near +# define PASCAL pascal +# define cdecl _cdecl +# define CDECL cdecl +#ifndef _PPCMAC +# define pascal _pascal +#endif +# else +# include <Types.h> +# include <Processes.h> +# include <AppleEvents.h> +# endif +#else +# include <windows.h> +#endif + +#ifndef WIN32 +#include <compobj.h> +#endif //!WIN32 + +// this redefines the DEFINE_GUID() macro to do allocation. +// +#include <initguid.h> + +#ifndef INITGUID +# define INITGUID +#endif + +// due to the previous header, including this causes our DEFINE_GUID defs +// in the following header(s) to actually allocate data. +// +#include "clsid.h" + diff --git a/private/oleauto/tests/disptest/macmain.cpp b/private/oleauto/tests/disptest/macmain.cpp new file mode 100644 index 000000000..9ee2a2f40 --- /dev/null +++ b/private/oleauto/tests/disptest/macmain.cpp @@ -0,0 +1,1447 @@ +/*** +*mcdsptst.cpp +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* UNDONE +* +* +*Revision History: +* +* [00] 28-Apr-93 bradlo: Created from TESample.c. +* +*Implementation Notes: +* +*****************************************************************************/ + +#include <stdio.h> +#include <string.h> +#include <stdarg.h> + +#include "disptest.h" +#include "macmain.h" +#include "resource.h" + +#if HC_MSC && !defined(_PPCMAC) +#include <swap.h> +#endif + +ASSERTDATA + +STDAPI +DispTestOne(void*, int); + +typedef struct { + WindowRecord docWindow; + TEHandle docTE; + ControlHandle docVScroll; + ControlHandle docHScroll; +#if 0 +// ProcPtr docClik; +#endif +} Doc; + + +SysEnvRec g_sysenv; +Boolean g_fInitOle = false; +Boolean g_fInBackground = false; +Boolean g_fLibrariesLoaded = false; + +short g_cNumDocs = 0; + + + +/* Define HIWRD and LOWRD macros for efficiency. */ +#define HIWRD(aLong) (((aLong) >> 16) & 0xFFFF) +#define LOWRD(aLong) ((aLong) & 0xFFFF) + +/* Define TOPLEFT and BOTRIGHT macros for convenience. Notice the implicit + dependency on the ordering of fields within a Rect */ +#define TOPLEFT(aRect) (*(Point*)&(aRect).top) +#define BOTRIGHT(aRect) (*(Point*)&(aRect).bottom) + + +void +Exit() +{ + if(g_fInitOle) + UninitOle(); +#ifndef _PPCMAC + if(g_fLibrariesLoaded) +#endif +#if 0 + CleanupLibraryManager(); +#else +#ifndef _PPCMAC + UninitOleManager(); // clean up applet +#endif +#endif + ExitToShell(); +} + +/* display fatal error alert, and exit */ +void +Fatal(char *msg) +{ +static const unsigned char pnil[2] = {0,0}; + unsigned char buf[128]; + + SetCursor(&qd.arrow); + + buf[0] = (unsigned char)strlen(msg); + memcpy(&buf[1], msg, buf[0]+1); + + ParamText(buf, pnil, pnil, pnil); + Alert(rUserAlert, nil); + Exit(); +} + +extern "C" int +main() +{ + + + + Init(); + long l = OleBuildVersion(); + DbPrintf("OleBuildVersion = %d.%d\n", (int)HIWRD(l), (int)LOWRD(l)); + +#ifdef _DEBUG + FnAssertOn(false); // TEMPORARY: to get around IMessageFilter assertions +#endif + EventLoop(); + return 0; +} + +/* Get events forever, and handle them by calling DoEvent. + Also call AdjustCursor each time through the loop. */ +void +EventLoop() +{ + Point mouse; + Boolean gotEvent; + EventRecord event; + RgnHandle cursorRgn; + + cursorRgn = NewRgn(); /* we'll pass WNE an empty region the 1st time thru */ + do{ + GetGlobalMouse(&mouse); + AdjustCursor(mouse, cursorRgn); + gotEvent = WaitNextEvent(everyEvent, &event, GetSleep(), cursorRgn); + if(gotEvent){ + /* make sure we have the right cursor before handling the event */ + AdjustCursor(event.where, cursorRgn); + DoEvent(&event); + }else{ + DoIdle(); /* perform idle tasks when it's not our event */ + } + + }while(true); +} + + +/* Do the right thing for an event. Determine what kind of event it is, + and call the appropriate routines. */ +void +DoEvent(EventRecord *pevent) +{ + char key; + short part; + WindowPtr window; + + switch(pevent->what){ + case nullEvent: + // we idle for null/mouse moved events ands for events which + // aren't ours (see EventLoop) + DoIdle(); + break; + + case mouseDown: + part = FindWindow(pevent->where, &window); + switch(part){ + case inMenuBar: /* process a mouse menu command (if any) */ + AdjustMenus(); /* bring 'em up-to-date */ + DoMenuCommand(MenuSelect(pevent->where)); + break; + + case inSysWindow: /* let the system handle the mouseDown */ + SystemClick(pevent, window); + break; + + case inContent: + if(window != FrontWindow()){ + SelectWindow(window); + }else{ + DoContentClick(window, pevent); + } + break; + + case inDrag: /* pass screenBits.bounds to get all gDevices */ + DragWindow(window, pevent->where, &qd.screenBits.bounds); + break; + + case inGoAway: + if(TrackGoAway(window, pevent->where)) + DoCloseWindow(window); /* we don't care if the user cancelled */ + break; + + case inGrow: + DoGrowWindow(window, pevent); + break; + + case inZoomIn: + case inZoomOut: + if(TrackBox(window, pevent->where, part)) + DoZoomWindow(window, part); + break; + } + break; + + case keyDown: + case autoKey: /* check for menukey equivalents */ + key = (char)(pevent->message & charCodeMask); + if(pevent->modifiers & cmdKey){/* Command key down */ + if(pevent->what == keyDown){ + AdjustMenus(); /* enable/disable/check menu items properly */ + DoMenuCommand(MenuKey(key)); + } + }else{ + DoKeyDown(pevent); + } + break; + + case activateEvt: + DoActivate( + (WindowPtr)pevent->message, + (Boolean)((pevent->modifiers & activeFlag) != 0)); + break; + + case updateEvt: + DoUpdate((WindowPtr)pevent->message); + break; + + case kOSEvent: + switch((pevent->message >> 24) & 0x0FF){ /* high byte of message */ + case kMouseMovedMessage: + DoIdle(); /* mouse-moved is also an idle event */ + break; + + case kSuspendResumeMessage: + /* suspend/resume is also an activate/deactivate */ + g_fInBackground = (pevent->message & kResumeMask) == 0; + DoActivate(FrontWindow(), (Boolean)!g_fInBackground); + break; + } + break; + + case kHighLevelEvent: + AEProcessAppleEvent(pevent); + break; + } +} + +/* Change the cursor's shape, depending on its position. This also + calculates the region where the current cursor resides (for + WaitNextEvent). When the mouse moves outside of this region, + an event is generated. If there is more to the event than just + the mouse moved, we get called before the event is processed to + make sure the cursor is the right one. In any (ahem) event, this + is called again before we fall back into WNE. */ +void +AdjustCursor(Point mouse, RgnHandle region) +{ + Rect iBeamRect; + WindowPtr window; + RgnHandle arrowRgn; + RgnHandle iBeamRgn; + + /* we only adjust the cursor when we are in front */ + window = FrontWindow(); + + if((!g_fInBackground) && (!IsDAWindow(window))){ + /* calculate regions for different cursor shapes */ + arrowRgn = NewRgn(); + iBeamRgn = NewRgn(); + + /* start arrowRgn wide open */ + SetRectRgn(arrowRgn, kExtremeNeg, kExtremeNeg, kExtremePos, kExtremePos); + + /* calculate iBeamRgn */ + if(IsAppWindow(window)){ + iBeamRect = (*((Doc*)window)->docTE)->viewRect; + SetPort(window); /* make a global version of the viewRect */ + LocalToGlobal(&TOPLEFT(iBeamRect)); + LocalToGlobal(&BOTRIGHT(iBeamRect)); + RectRgn(iBeamRgn, &iBeamRect); + /* we temporarily change the port's origin to "globalfy" the visRgn */ + SetOrigin( + (short)-window->portBits.bounds.left, + (short)-window->portBits.bounds.top); + SectRgn(iBeamRgn, window->visRgn, iBeamRgn); + SetOrigin((short)0, (short)0); + } + + /* subtract other regions from arrowRgn */ + DiffRgn(arrowRgn, iBeamRgn, arrowRgn); + + /* change the cursor and the region parameter */ + if(PtInRgn(mouse, iBeamRgn)){ + SetCursor(*GetCursor(iBeamCursor)); + CopyRgn(iBeamRgn, region); + }else{ + SetCursor(&qd.arrow); + CopyRgn(arrowRgn, region); + } + DisposeRgn(arrowRgn); + DisposeRgn(iBeamRgn); + } +} + +/* Get the global coordinates of the mouse. When you call OSEventAvail + it will return either a pending event or a null event. In either case, + the where field of the event record will contain the current position + of the mouse in global coordinates and the modifiers field will reflect + the current state of the modifiers. Another way to get the global + coordinates is to call GetMouse and LocalToGlobal, but that requires + being sure that thePort is set to a valid port. */ +void +GetGlobalMouse(Point *mouse) +{ + EventRecord event; + + /* we aren't interested in any events */ + OSEventAvail(kNoEvents, &event); + + /* just the mouse position */ + *mouse = event.where; +} + +/* Called when a mouseDown occurs in the grow box of an active window. + In order to eliminate any 'flicker', we want to invalidate only what + is necessary. Since ResizeWindow invalidates the whole portRect, we + save the old TE viewRect, intersect it with the new TE viewRect, and + remove the result from the update region. However, we must make sure + that any old update region that might have been around gets put back. */ +void +DoGrowWindow(WindowPtr window, EventRecord *event) +{ + Rect tempRect; + long growResult; + Doc* doc; + RgnHandle tempRgn; + + tempRect = qd.screenBits.bounds; /* set up limiting values */ + tempRect.left = kMinDocDim; + tempRect.top = kMinDocDim; + growResult = GrowWindow(window, event->where, &tempRect); + + /* see if it really changed size */ + if(growResult != 0){ + doc = (Doc*)window; + /* save old text box */ + tempRect = (*doc->docTE)->viewRect; + tempRgn = NewRgn(); + /* get localized update region */ + GetLocalUpdateRgn(window, tempRgn); + SizeWindow(window, (short)LOWRD(growResult), (short)HIWRD(growResult), (Boolean)true); + ResizeWindow(window); + + /* calculate & validate the region that hasn't changed so + it won't get redrawn */ + SectRect(&tempRect, &(*doc->docTE)->viewRect, &tempRect); + ValidRect(&tempRect); /* take it out of update */ + InvalRgn(tempRgn); /* put back any prior update */ + DisposeRgn(tempRgn); + } +} + +/* Called when a mouseClick occurs in the zoom box of an active window. + Everything has to get re-drawn here, so we don't mind that + ResizeWindow invalidates the whole portRect. */ +void DoZoomWindow(WindowPtr window, short part) +{ + EraseRect(&window->portRect); + ZoomWindow(window, part, (Boolean)(window == FrontWindow())); + ResizeWindow(window); +} + +/* Called when the window has been resized to fix up the controls and + content. */ +void ResizeWindow(WindowPtr window) +{ + AdjustScrollbars(window, true); + AdjustTE(window); + InvalRect(&window->portRect); +} + +/* Returns the update region in local coordinates */ +void GetLocalUpdateRgn(WindowPtr window, RgnHandle localRgn) +{ + /* save old update region */ + CopyRgn(((WindowPeek) window)->updateRgn, localRgn); + + OffsetRgn( + localRgn, + window->portBits.bounds.left, + window->portBits.bounds.top); +} + +void +DoUpdate(WindowPtr window) +{ + if(IsAppWindow(window)){ + /* this sets up the visRgn */ + BeginUpdate(window); + /* draw if updating needs to be done */ + if(!EmptyRgn(window->visRgn)) + DrawWindow(window); + EndUpdate(window); + } +} + +/* This is called when a window is activated or deactivated. + It calls TextEdit to deal with the selection. */ +void +DoActivate(WindowPtr window, Boolean becomingActive) +{ + Rect growRect; + Doc* doc; + RgnHandle tempRgn, clipRgn; + + if(IsAppWindow(window)){ + doc = (Doc*)window; + if(becomingActive){ + /* since we don't want TEActivate to draw a selection in an + area where we're going to erase and redraw, we'll clip + out the update region before calling it. */ + tempRgn = NewRgn(); + clipRgn = NewRgn(); + /* get localized update region */ + GetLocalUpdateRgn(window, tempRgn); + GetClip(clipRgn); + /* subtract updateRgn from clipRgn */ + DiffRgn(clipRgn, tempRgn, tempRgn); + SetClip(tempRgn); + TEActivate(doc->docTE); + /* restore the full-blown clipRgn */ + SetClip(clipRgn); + DisposeRgn(tempRgn); + DisposeRgn(clipRgn); + + /* the controls must be redrawn on activation: */ + (*doc->docVScroll)->contrlVis = kControlVisible; + (*doc->docHScroll)->contrlVis = kControlVisible; + InvalRect(&(*doc->docVScroll)->contrlRect); + InvalRect(&(*doc->docHScroll)->contrlRect); + /* the growbox needs to be redrawn on activation: */ + growRect = window->portRect; + /* adjust for the scrollbars */ + growRect.top = growRect.bottom - kScrollbarAdjust; + growRect.left = growRect.right - kScrollbarAdjust; + InvalRect(&growRect); + }else{ + TEDeactivate(doc->docTE); + /* the controls must be hidden on deactivation: */ + HideControl(doc->docVScroll); + HideControl(doc->docHScroll); + /* the growbox should be changed immediately on deactivation: */ + DrawGrowIcon(window); + } + } +} + +/* This is called when a mouseDown occurs in the content of a window. */ +void +DoContentClick(WindowPtr window, EventRecord *event) +{ + Rect teRect; + Point mouse; + Doc* doc; + short part, value; + Boolean shiftDown; + ControlHandle control; + + if(IsAppWindow(window)){ + SetPort(window); + mouse = event->where; /* get the click position */ + GlobalToLocal(&mouse); + doc = (Doc*)window; + /* see if we are in the viewRect. if so, we won't check the controls */ + GetTERect(window, &teRect); + if(PtInRect(mouse, &teRect)){ + /* see if we need to extend the selection - extend if Shift is down */ + shiftDown = (event->modifiers & shiftKey) != 0; + TEClick(mouse, shiftDown, doc->docTE); +#if 0 + PascalClikLoop(); +#endif + }else{ + part = FindControl(mouse, window, &control); + switch(part){ + case 0: /* do nothing for viewRect case */ + break; + case inThumb: + value = GetCtlValue(control); + part = TrackControl(control, mouse, nil); + if(part != 0){ + value -= GetCtlValue(control); + /* value now has CHANGE in value; if value changed, scroll */ + if(value != 0){ + if(control == doc->docVScroll){ + TEScroll( + (short)0, + (short)(value * (*doc->docTE)->lineHeight), + doc->docTE); + }else{ + TEScroll((short)value, (short)0, doc->docTE); + } + } + } + break; + + default: /* they clicked in an arrow, so track & scroll */ + if(control == doc->docVScroll) +#ifdef _PPCMAC + value = TrackControl(control, mouse, (ControlActionUPP)VActionProc); + else + value = TrackControl(control, mouse, (ControlActionUPP)HActionProc); +#else + value = TrackControl(control, mouse, (ProcPtr)VActionProc); + else + value = TrackControl(control, mouse, (ProcPtr)HActionProc); + break; +#endif + } + } + } +} + +/* This is called for any keyDown or autoKey events, except when the + Command key is held down. It looks at the frontmost window to decide what + to do with the key typed. */ +void +DoKeyDown(EventRecord *event) +{ + char key; + TEHandle te; + WindowPtr window; + + window = FrontWindow(); + if(IsAppWindow(window)){ + te = ((Doc*) window)->docTE; + key = (char)(event->message & charCodeMask); + /* we have a char. for our window; see if we are still below TextEditÕs + limit for the number of characters (but deletes are always rad) */ + if(key == kDelChar + || (*te)->teLength - ((*te)->selEnd - (*te)->selStart)+1 < kMaxTELength) + { + TEKey(key, te); + AdjustScrollbars(window, false); + AdjustTE(window); + } + } +} + +/* Common algorithm for pinning the value of a control. It returns + the actual amount the value of the control changed. Note the + pinning is done for the sake of returning the amount the control + value changed. */ +void +CommonAction(ControlHandle control, short *amount) +{ + short value, max; + + value = GetCtlValue(control); /* get current value */ + max = GetCtlMax(control); /* and maximum value */ + *amount = value - *amount; + if(*amount < 0) + *amount = 0; + else if(*amount > max) + *amount = max; + SetCtlValue(control, *amount); + *amount = value - *amount; /* calculate the real change */ +} + +/* Determines how much to change the value of the vertical scrollbar + by and how much to scroll the TE record. */ +extern "C" +PASCAL_(void) +VActionProc(ControlHandle control, short part) +{ + TEPtr te; + short amount; + WindowPtr window; + + if(part != 0){ /* if it was actually in the control */ + window = (*control)->contrlOwner; + te = *((Doc*) window)->docTE; + switch(part){ + case inUpButton: + case inDownButton: /* one line */ + amount = 1; + break; + case inPageUp: /* one page */ + case inPageDown: + amount = (te->viewRect.bottom - te->viewRect.top) / te->lineHeight; + break; + } + if((part == inDownButton) || (part == inPageDown)) + amount = -amount; /* reverse direction for a downer */ + CommonAction(control, &amount); + if(amount != 0){ + TEScroll((short)0, + (short)(amount * te->lineHeight), + ((Doc*)window)->docTE); + } + } +} + +/* Determines how much to change the value of the horizontal scrollbar + by and how much to scroll the TE record. */ +extern "C" +PASCAL_(void) +HActionProc(ControlHandle control, short part) +{ + TEPtr te; + short amount; + WindowPtr window; + + if(part != 0){ + window = (*control)->contrlOwner; + te = *((Doc*) window)->docTE; + switch(part){ + case inUpButton: + case inDownButton: /* a few pixels */ + amount = kButtonScroll; + break; + case inPageUp: /* a page */ + case inPageDown: + amount = te->viewRect.right - te->viewRect.left; + break; + } + if((part == inDownButton) || (part == inPageDown)) + amount = -amount; /* reverse direction */ + CommonAction(control, &amount); + if(amount != 0) + TEScroll(amount, 0, ((Doc*) window)->docTE); + } +} + +/* This is called whenever we get a null event et al. It takes care + of necessary periodic actions. For this program, it calls TEIdle. */ +void +DoIdle() +{ + WindowPtr window; + + window = FrontWindow(); + if(IsAppWindow(window)) + TEIdle(((Doc*)window)->docTE); +} + +/* Draw the contents of an application window. */ +void DrawWindow(WindowPtr window) +{ + SetPort(window); + EraseRect(&window->portRect); + DrawControls(window); + DrawGrowIcon(window); + TEUpdate(&window->portRect, ((Doc*)window)->docTE); +} + +/* Enable and disable menus based on the current state. */ + +void DoEnableItem(MenuHandle hmenu, short sItem) { + EnableItem(hmenu, sItem); +} + +void DoDisableItem(MenuHandle hmenu, short sItem) { + DisableItem(hmenu, sItem); +} + +/* Enable and disable menus based on the current state. */ +void +AdjustMenus() +{ + long offset; + TEHandle hte; + MenuHandle menu; + WindowPtr window; + Boolean undo; + Boolean paste; + Boolean cutCopyClear; + void (*pfnEnable)(MenuHandle, short); + +#if 0 + + File + New + Close + + Edit + Undo + Cut + Copy + Clear + Paste +#endif + + window = FrontWindow(); + + menu = GetMHandle(mFile); + + pfnEnable = ((g_cNumDocs < kMaxOpenDocs) ? DoEnableItem : DoDisableItem); + pfnEnable(menu, iNew); + + pfnEnable = ((window != nil) ? DoEnableItem : DoDisableItem); + pfnEnable(menu, iClose); + + menu = GetMHandle(mEdit); + undo = false; + paste = false; + cutCopyClear = false; + + if(IsDAWindow(window)){ + undo = true; /* all editing is enabled for DA windows */ + cutCopyClear = true; + paste = true; + }else if(IsAppWindow(window)){ + hte = ((Doc*) window)->docTE; + if((*hte)->selStart < (*hte)->selEnd){ + /* Cut, Copy, and Clear is enabled for app. windows with selections */ + cutCopyClear = true; + } + if(GetScrap(nil, 'TEXT', &offset) > 0){ + /* if there's any text in the clipboard, paste is enabled */ + paste = true; + } + } + + pfnEnable = (undo) ? DoEnableItem : DoDisableItem; + pfnEnable(menu, iUndo); + + pfnEnable = (cutCopyClear) ? DoEnableItem : DoDisableItem; + pfnEnable(menu, iCut); + pfnEnable(menu, iCopy); + pfnEnable(menu, iClear); + + pfnEnable = (paste) ? DoEnableItem : DoDisableItem; + pfnEnable(menu, iPaste); +} + + +/* This is called when an item is chosen from the menu bar (after calling + MenuSelect or MenuKey). It does the right thing for each command. */ +void +DoMenuCommand(long menuResult) +{ + TEHandle te; + Str255 daName; + OSErr saveErr; + Handle aHandle; + WindowPtr window; + long oldSize, newSize, total, contig; + short menuID, menuItem, itemHit, daRefNum; +static int rgIDMOfItem[] = { + -1 // <placeholder> + , IDM_SUITE_BSTR // iBstrAPI + , IDM_SUITE_TIME // iTimeAPI + , IDM_SUITE_DATECNV // iDateCnv + , IDM_SUITE_VARIANT // iVariantAPI + , IDM_SUITE_SAFEARRAY // iSafeArrayAPI + , IDM_SUITE_NLS // iNlsAPI + , IDM_SUITE_BIND // iBinding + , IDM_SUITE_INVOKE_BYVAL // iInvokeByVal + , IDM_SUITE_INVOKE_BYREF // iInvokeByRef + , IDM_SUITE_INVOKE_SAFEARRAY // iInvokeArray + , IDM_SUITE_INVOKE_EXCEPINFO // iInvokeExinfo + , IDM_SUITE_COLLECTION // iCollections +}; + + window = FrontWindow(); + + menuID = (short)HIWRD(menuResult); + menuItem = (short)LOWRD(menuResult); + + /* get menu item number and menu number */ + switch(menuID){ + case mApple: + switch(menuItem){ + case iAbout: /* bring up alert for About */ + itemHit = Alert(rAboutAlert, nil); + break; + default: /* all non-About items in this menu are DAs et al */ + /* type Str255 is an array in MPW 3 */ + GetMenuItemText(GetMHandle(mApple), menuItem, daName); + daRefNum = OpenDeskAcc(daName); + break; + } + break; + + case mFile: + switch(menuItem){ + case iNew: + DoNew(); + break; + case iClose: + DoCloseWindow(FrontWindow()); /* ignore the result */ + break; + case iQuit: + Terminate(); + break; + } + break; + + case mEdit: /* call SystemEdit for DA editing & MultiFinder */ + if(!SystemEdit((short)(menuItem-1))){ + te = ((Doc*)FrontWindow())->docTE; + switch(menuItem){ + case iCut: + if(ZeroScrap() == noErr){ + PurgeSpace(&total, &contig); + if((*te)->selEnd - (*te)->selStart + kTESlop > contig){ + AlertUser(eNoSpaceCut); + }else{ + TECut(te); + if(TEToScrap() != noErr){ + AlertUser(eNoCut); + ZeroScrap(); + } + } + } + break; + + case iCopy: + if(ZeroScrap() == noErr){ + TECopy(te); /* after copying, export the TE scrap */ + if(TEToScrap() != noErr){ + AlertUser(eNoCopy); + ZeroScrap(); + } + } + break; + + case iPaste: /* import the TE scrap before pasting */ + if(TEFromScrap() == noErr){ + if(TEGetScrapLen() + ((*te)->teLength - + ((*te)->selEnd - (*te)->selStart)) > kMaxTELength){ + AlertUser(eExceedPaste); + }else{ + aHandle = (Handle)TEGetText(te); + oldSize = GetHandleSize(aHandle); + newSize = oldSize + TEGetScrapLen() + kTESlop; + SetHandleSize(aHandle, newSize); + saveErr = MemError(); + SetHandleSize(aHandle, oldSize); + if(saveErr != noErr) + AlertUser(eNoSpacePaste); + else + TEPaste(te); + } + }else{ + AlertUser(eNoPaste); + } + break; + + case iClear: + TEDelete(te); + break; + } + AdjustScrollbars(window, false); + AdjustTE(window); + } + break; + + case mSuite: + switch(menuItem){ + case iBstrAPI: + case iTimeAPI: + case iDateCnv: + case iVariantAPI: + case iSafeArrayAPI: + case iNlsAPI: + case iBinding: + case iInvokeByVal: + case iInvokeByRef: + case iInvokeArray: + case iInvokeExinfo: + case iCollections: + DispTestOne(NULL, rgIDMOfItem[menuItem]); + break; + } + break; + + case mOptions: + switch(menuItem){ + case iClearAll: + te = ((Doc*)FrontWindow())->docTE; + TESetSelect(0, 32767, te); + TEDelete(te); + break; + case iDebugger: + Debugger(); + break; + } + break; + } + HiliteMenu(0); /* unhighlight what MenuSelect (or MenuKey) hilited */ +} + +/* Create a new document and window. */ +void +DoNew() +{ + Ptr storage; + Boolean good; + Doc* doc; + WindowPtr window; + Rect destRect, viewRect; + + storage = NewPtr(sizeof(Doc)); + if(storage != nil){ + window = GetNewWindow(rDocWindow, storage, (WindowPtr) -1); + if(window != nil){ + /* this will be decremented when we call DoCloseWindow */ + good = false; + g_cNumDocs += 1; + SetPort(window); + + short font; + GetFNum((const unsigned char*)"\006Monaco", &font); + TextFont(font); + TextSize(9); + + doc = (Doc*)window; + GetTERect(window, &viewRect); + destRect = viewRect; + destRect.right = destRect.left + kMaxDocWidth; + doc->docTE = TENew(&destRect, &viewRect); + + /* if TENew succeeded, we have a good document */ + good = doc->docTE != nil; + if(good){ + AdjustViewRect(doc->docTE); + TEAutoView(true, doc->docTE); + } + + if(good){ + doc->docVScroll = GetNewControl(rVScroll, window); + good = (doc->docVScroll != nil); + } + + if(good){ + doc->docHScroll = GetNewControl(rHScroll, window); + good = (doc->docHScroll != nil); + } + + if(good){ /* good? adjust & draw the controls, draw the window */ + /* false to AdjustScrollValues means musn't redraw; + technically, of course, the window is hidden so + it wouldn't matter whether we called ShowControl + or not. */ + AdjustScrollValues(window, false); + ShowWindow(window); + }else{ + /* otherwise regret we ever created it... */ + DoCloseWindow(window); + AlertUser(eNoWindow); + } + }else{ + /* get rid of the storage if it is never used */ + DisposPtr(storage); + } + } +} + + +/* Close a window. This handles desk accessory and application windows. */ +/* 1.01 - At this point, if there was a document associated with a + window, you could do any document saving processing if it is 'dirty'. + DoCloseWindow would return true if the window actually closed, i.e., + the user didn't cancel from a save dialog. This result is handy when + the user quits an application, but then cancels the save of a document + associated with a window. */ +Boolean +DoCloseWindow(WindowPtr window) +{ + TEHandle te; + + if(IsDAWindow(window)){ + CloseDeskAcc(((WindowPeek) window)->windowKind); + }else if(IsAppWindow(window)){ + te = ((Doc*)window)->docTE; + if(te != nil){ + /* dispose the TEHandle if we got far enough to make one */ + TEDispose(te); + } + CloseWindow(window); + DisposPtr((Ptr)window); + g_cNumDocs -= 1; + } + return true; +} + +/* Clean up the application and exit. We close all of the windows + so that they can update their documents, if any. */ +void +Terminate() +{ + Boolean closed; + WindowPtr aWindow; + + closed = true; + do{ + aWindow = FrontWindow(); /* get the current front window */ + if(aWindow != nil) + closed = DoCloseWindow(aWindow); /* close this window */ + } while (closed && (aWindow != nil)); + + if(closed) + Exit(); /* exit if no cancellation */ +} + +/* Return a rectangle that is inset from the portRect by the + size of the scrollbars and a little extra margin. */ +void +GetTERect(WindowPtr window, Rect *teRect) +{ + *teRect = window->portRect; + InsetRect(teRect, kTextMargin, kTextMargin);/* adjust for margin */ + teRect->bottom = teRect->bottom - 15; /* and for the scrollbars */ + teRect->right = teRect->right - 15; +} + +/* Update the TERec's view rect so that it is the greatest multiple + of the lineHeight that still fits in the old viewRect. */ +void +AdjustViewRect(TEHandle docTE) +{ + TEPtr te; + + te = *docTE; + te->viewRect.bottom = (((te->viewRect.bottom - te->viewRect.top) / te->lineHeight) * te->lineHeight) + te->viewRect.top; +} + +/* Scroll the TERec around to match up to the potentially updated + scrollbar values. This is really useful when the window has been + resized such that the scrollbars became inactive but the TERec + was already scrolled. */ +void +AdjustTE(WindowPtr window) +{ + TEPtr te; + + te = *((Doc*)window)->docTE; + + TEScroll( + (short)((te->viewRect.left - te->destRect.left) - + GetCtlValue(((Doc*)window)->docHScroll)), + (short)((te->viewRect.top - te->destRect.top) - + (GetCtlValue(((Doc*)window)->docVScroll) * te->lineHeight)), + ((Doc*)window)->docTE); +} + + +/* Calculate the new control maximum value and current value, whether + it is the horizontal or vertical scrollbar. The vertical max is + calculated by comparing the number of lines to the vertical size + of the viewRect. The horizontal max is calculated by comparing the + maximum document width to the width of the viewRect. The current + values are set by comparing the offset between the view and + destination rects. If necessary and we canRedraw, have the control + be re-drawn by calling ShowControl. */ +void +AdjustHV( + Boolean isVert, + ControlHandle control, + TEHandle docTE, + Boolean canRedraw) +{ + TEPtr te; + short value, lines, max, oldValue, oldMax; + + oldValue = GetCtlValue(control); + oldMax = GetCtlMax(control); + te = *docTE; /* point to TERec for convenience */ + + if(isVert){ + lines = te->nLines; + /* since nLines isn't right if the last character is a return, + check for that case */ + if(*(*te->hText + te->teLength - 1) == kCrChar) + lines += 1; + max = lines - ((te->viewRect.bottom - te->viewRect.top) / te->lineHeight); + }else{ + max = kMaxDocWidth - (te->viewRect.right - te->viewRect.left); + } + + if ( max < 0 ) max = 0; + SetCtlMax(control, max); + + /* Must deref. after SetCtlMax since, technically, it could + draw and therefore move memory. This is why we don't just + do it once at the beginning. */ + te = *docTE; + if(isVert) + value = (te->viewRect.top - te->destRect.top) / te->lineHeight; + else + value = te->viewRect.left - te->destRect.left; + + if(value < 0) + value = 0; + else if(value > max) + value = max; + + SetCtlValue(control, value); + /* now redraw the control if it needs to be and can be */ + if(canRedraw || (max != oldMax) || (value != oldValue)) + ShowControl(control); +} + +/* Simply call the common adjust routine for the vertical and + horizontal scrollbars. */ +void +AdjustScrollValues(WindowPtr window, Boolean canRedraw) +{ + Doc* doc; + + doc = (Doc*)window; + AdjustHV(true, doc->docVScroll, doc->docTE, canRedraw); + AdjustHV(false, doc->docHScroll, doc->docTE, canRedraw); +} + +/* Re-calculate the position and size of the viewRect and the + scrollbars. kScrollTweek compensates for off-by-one requirements + of the scrollbars to have borders coincide with the growbox. */ +void +AdjustScrollSizes(WindowPtr window) +{ + Rect teRect; + Doc* doc; + + doc = (Doc*) window; + GetTERect(window, &teRect); /* start with TERect */ + (*doc->docTE)->viewRect = teRect; + AdjustViewRect(doc->docTE); /* snap to nearest line */ + + MoveControl( + doc->docVScroll, + (short)(window->portRect.right - kScrollbarAdjust), + (short)-1); + SizeControl( + doc->docVScroll, + (short)kScrollbarWidth, + (short)((window->portRect.bottom - window->portRect.top) - + (kScrollbarAdjust - kScrollTweek))); + + MoveControl( + doc->docHScroll, + (short)-1, + (short)(window->portRect.bottom - kScrollbarAdjust)); + SizeControl( + doc->docHScroll, + (short)((window->portRect.right - window->portRect.left) - + (kScrollbarAdjust - kScrollTweek)), + (short)kScrollbarWidth); +} + +/* Turn off the controls by jamming a zero into their contrlVis + fields (HideControl erases them and we don't want that). If the + controls are to be resized as well, call the procedure to do that, + then call the procedure to adjust the maximum and current values. + Finally re-enable the controls by jamming a $FF in their contrlVis + fields. */ +void +AdjustScrollbars(WindowPtr window, Boolean needsResize) +{ + Doc* doc; + + doc = (Doc*)window; + + /* First, turn visibility of scrollbars off so we won't get + unwanted redrawing */ + (*doc->docVScroll)->contrlVis = kControlInvisible; /* turn them off */ + (*doc->docHScroll)->contrlVis = kControlInvisible; + if(needsResize) /* move & size as needed */ + AdjustScrollSizes(window); + + /* fool with max and current value */ + AdjustScrollValues(window, needsResize); + + /* Now, restore visibility in case we never had to ShowControl + during adjustment */ + (*doc->docVScroll)->contrlVis = kControlVisible; /* turn them on */ + (*doc->docHScroll)->contrlVis = kControlVisible; +} + +#if 0 +/* Gets called from our assembly language routine, AsmClikLoop, + which is in turn called by the TEClick toolbox routine. Saves + the windows clip region, sets it to the portRect, adjusts the + scrollbar values to match the TE scroll amount, then restores + the clip region. */ +PASCAL_(Boolean) +PascalClikLoop() +{ + WindowPtr window; + RgnHandle region; + + window = FrontWindow(); + + region = NewRgn(); + GetClip(region); /* save clip */ + ClipRect(&window->portRect); + AdjustScrollValues(window, true); /* pass true for canRedraw */ + SetClip(region); /* restore clip */ + DisposeRgn(region); + + return true; +} +#endif + +Boolean +IsAppWindow(WindowPtr window) +{ + return (window == nil) + ? false : (((WindowPeek)window)->windowKind == userKind); +} + +/* Check to see if a window belongs to a desk accessory. */ +Boolean IsDAWindow(WindowPtr window) +{ + /* DA windows have negative windowKinds */ + return (window == nil) + ? false : (((WindowPeek)window)->windowKind < 0); +} + +void +AlertUser(short error) +{ + short itemHit; + Str255 message, tmp; + + SetCursor(&qd.arrow); + GetIndString(message, kErrStrings, error); + tmp[0] = '\0'; + ParamText(message, tmp, tmp, tmp); + itemHit = Alert(rUserAlert, nil); +} + +PASCAL_(OSErr) +RemoteLowLevelEvt( + AppleEvent theAppEvt, + AppleEvent reply, + long HandlerRefCon) +{ + long cb; + OSErr err; + DescType descType; + EventRecord event; + + UNUSED(reply); + UNUSED(HandlerRefCon); + + err = AEGetKeyPtr( + &theAppEvt, + keyDirectObject, + typeWildCard, + &descType, + (Ptr)&event, + sizeof(event), + &cb); + + if(err != noErr){ + ASSERT(0); + return err; + } + + DoEvent(&event); + + return noErr; +} + +void +InitAE() +{ + OSErr err; + + err = AEInstallEventHandler( + 'OLE2', 'EVNT', (EventHandlerProcPtr)RemoteLowLevelEvt, 0, false); + ASSERT(err == noErr); +} + + +void +Init() +{ + short count; + Handle menuBar; + long total, contig; + EventRecord event; + + g_fInBackground = false; + +#if 0 + MoreMasters(); +#endif + MaxApplZone(); + + InitGraf((Ptr)&qd.thePort); + InitFonts(); + InitWindows(); + InitMenus(); + TEInit(); + InitDialogs(nil); + InitCursor(); + FlushEvents(everyEvent, 0); + InitCursor(); + + // REVIEW: move this above load of Ole? + SysEnvirons(kSysEnvironsVersion, &g_sysenv); + if (g_sysenv.machineType < 0 + || g_sysenv.systemVersion < 0x0600 + || g_sysenv.hasColorQD == false + || TrapExists(_WaitNextEvent) == false) + { + Fatal("System is too whimpy"); + } + + /* get MultiFinder started */ + for(count = 1; count <= 3; count++) + EventAvail(everyEvent, &event); + + /* make sure we have enough memory to run */ + if((long)GetApplLimit() - (long)ApplicZone() < kMinHeap) + Fatal("Not enough memory to run"); + PurgeSpace(&total, &contig); + if(total < kMinSpace) + Fatal("Not enough memory after purge"); + + menuBar = GetNewMBar(rMenuBar); /* read menus into menu bar */ + if(menuBar == nil) + Fatal("Unable to load menu bar"); + SetMenuBar(menuBar); + DisposHandle(menuBar); + AddResMenu(GetMHandle(mApple), 'DRVR'); /* add DA names to Apple menu */ + DrawMenuBar(); + + DoNew(); + +#ifdef _MSC_VER + DbPrintf("Wings Build\n"); +#else + DbPrintf("MPW Build\n"); +#endif + + DbPrintf("InitLibraryManager\n"); +#ifndef _PPCMAC + if (InitOleManager(0) != NOERROR) + Fatal("Unable to initialize Library Manager"); + g_fLibrariesLoaded = true; +#endif + + DbPrintf("Initializing Ole\n"); + if(InitOle() != NOERROR) + Fatal("Failed to initialize Ole"); + g_fInitOle = true; + + InitAE(); +} + +/* Calculate a sleep value for WaitNextEvent. This takes into + account the things that DoIdle does with idle time. */ +unsigned long +GetSleep() +{ + long sleep; + TEHandle te; + WindowPtr window; + + sleep = MAXLONG; /* default value for sleep */ + if(!g_fInBackground){ + window = FrontWindow(); /* and the front window is ours... */ + if(IsAppWindow(window)){ + /* and the selection is an insertion point... */ + te = ((Doc*)window)->docTE; + if((*te)->selStart == (*te)->selEnd){ + /* blink time for the insertion point */ + sleep = GetCaretTime(); + } + } + } + return sleep; +} + +/* Check the bits of a trap number to determine its type. If bit 11 + is set, its a Toolbox trap, otherwise its an OS trap. */ +TrapType +GetTrapType(short theTrap) +{ + return ((theTrap & 0x0800) == 0) ? OSTrap : ToolTrap; +} + +/* Find the size of the Toolbox trap table. This can be either 0x0200 + or 0x0400 bytes, depending on which Macintosh we are running on. We + determine the size by taking advantage of an anomaly of the smaller + trap table: any entries that fall beyond the end of the table are + mirrored back down into the lower part. For example, on a large table, + trap numbers A86E and AA6E correspond to different routines. However, + on a small table, they correspond to the same routine. By checking + the address of these routines, we can determine the size of the + table. */ +short +NumToolboxTraps() +{ + return + (NGetTrapAddress((short)0xA86E, ToolTrap) == + NGetTrapAddress((short)0xAA6E, ToolTrap)) ? 0x0200 : 0x0400; +} + +/* Check to see if a given trap is implemented */ +Boolean +TrapExists(short theTrap) +{ + TrapType theTrapType; + + theTrapType = GetTrapType(theTrap); + if((theTrapType == ToolTrap) + && ((theTrap & 0x07FF) >= NumToolboxTraps())) + return false; + return (NGetTrapAddress((short)_Unimplemented, ToolTrap) != + NGetTrapAddress(theTrap, theTrapType)); +} + + +STDAPI_(void) +OutputDebugString(const char *sz) +{ + long len; + TEHandle hTE; + WindowPtr window; + + len = strlen(sz); + + window = FrontWindow(); + if(window == nil) + return; + + hTE = ((Doc*)window)->docTE; + if(hTE == nil || *hTE == nil) + return; + + // if this insertion will cause us to overflow the TextEdit + // buffer, then delete enough from the beginning of the buffer + // to make room + + if(((long)(*hTE)->teLength + len) > 30000){ + TESetSelect(0, 15000, hTE); + TEDelete(hTE); + TESetSelect(30000, 30000, hTE); + } + + TEInsert(sz, len, hTE); + TESelView(hTE); +} + diff --git a/private/oleauto/tests/disptest/macmain.h b/private/oleauto/tests/disptest/macmain.h new file mode 100644 index 000000000..fc36822bc --- /dev/null +++ b/private/oleauto/tests/disptest/macmain.h @@ -0,0 +1,191 @@ + +#ifndef rez // { +void AlertUser(short error ); +void EventLoop(void ); +void DoEvent( EventRecord *event ); +void AdjustCursor(Point mouse, RgnHandle region ); +void GetGlobalMouse(Point *mouse ); +void DoGrowWindow(WindowPtr window, EventRecord *event ); +void DoZoomWindow(WindowPtr window, short part ); +void ResizeWindow(WindowPtr window ); +void GetLocalUpdateRgn(WindowPtr window, RgnHandle localRgn ); +void DoUpdate(WindowPtr window ); +void DoDeactivate(WindowPtr window ); +void DoActivate(WindowPtr window, Boolean becomingActive); +void DoContentClick(WindowPtr window, EventRecord *event ); +void DoKeyDown(EventRecord *event ); +void CommonAction(ControlHandle control, short *amount); +extern "C" PASCAL_(void) VActionProc(ControlHandle control, short part); +extern "C" PASCAL_(void) HActionProc(ControlHandle control, short part); +void DoIdle(void ); +void DrawWindow(WindowPtr window ); +void AdjustMenus(void ); +void DoMenuCommand(long menuResult ); +void DoNew(void ); +void Terminate(void ); +void Init(void ); +void BigBadError(short error ); +void GetTERect(WindowPtr window, Rect *teRect ); +void AdjustViewRect(TEHandle docTE ); +void AdjustTE(WindowPtr window ); +void AdjustHV(Boolean isVert, ControlHandle control, TEHandle docTE, Boolean canRedraw ); +void AdjustScrollValues(WindowPtr window, Boolean canRedraw ); +void AdjustScrollSizes(WindowPtr window ); +void AdjustScrollbars(WindowPtr window, Boolean needsResize ); +unsigned long GetSleep(void ); +Boolean DoCloseWindow(WindowPtr window ); +Boolean IsAppWindow(WindowPtr window ); +Boolean IsDAWindow(WindowPtr window ); +Boolean TrapExists(short tNumber); +PASCAL_(Boolean) PascalClikLoop(); +#endif // } + + +#define kPrefSize 3500 +#define kMinSize 2100 + +/* The following constants are used to identify menus and their items. + The menu IDs have an "m" prefix and the item numbers within each menu + have an "i" prefix. */ +#define mApple 128 /* Apple menu */ +#define iAbout 1 + +#define mFile 129 /* File menu */ +#define iNew 1 +#define iClose 4 +#define iQuit 12 + +#define mEdit 130 /* Edit menu */ +#define iUndo 1 +#define iCut 3 +#define iCopy 4 +#define iPaste 5 +#define iClear 6 + +#define mSuite 131 +#define iBstrAPI 1 +#define iTimeAPI 2 +#define iDateCnv 3 +#define iVariantAPI 4 +#define iSafeArrayAPI 5 +#define iNlsAPI 6 +#define iBinding 7 +#define iInvokeByVal 8 +#define iInvokeByRef 9 +#define iInvokeArray 10 +#define iInvokeExinfo 11 +#define iCollections 12 + +#define mOptions 132 +#define iClearAll 1 +#define iDebugger 2 + +#define kDITop 0x0050 +#define kDILeft 0x0070 + +/* kTextMargin is the number of pixels we leave blank at the edge + of the window. */ +#define kTextMargin 2 + +/* kMaxOpenDocs is used to determine whether a new document can be + opened or created. We keep track of the number of open documents, and + disable the menu items that create a new document when the maximum is + reached. If the number of documents falls below the maximum, the items + are enabled again. */ +#define kMaxOpenDocs 1 + +/* kMaxDocWidth is an arbitrary number used to specify the width of the + TERec's destination rectangle so that word wrap and horizontal scrolling + can be demonstrated. */ +#define kMaxDocWidth 576 + +/* kMinDocDim is used to limit the minimum dimension of a window when + GrowWindow is called. */ +#define kMinDocDim 64 + +/* kControlInvisible is used to 'turn off' controls (i.e., cause the + control not to be redrawn as a result of some Control Manager call + such as SetCtlValue) by being put into the contrlVis field of the + record. kControlVisible is used the same way to 'turn on' the control. */ +#define kControlInvisible 0 +#define kControlVisible 0xFF + +/* kScrollbarAdjust and kScrollbarWidth are used in calculating + values for control positioning and sizing. */ +#define kScrollbarWidth 16 +#define kScrollbarAdjust (kScrollbarWidth - 1) + +/* kScrollTweek compensates for off-by-one requirements of the + scrollbars to have borders coincide with the growbox. */ +#define kScrollTweek 2 + +/* kCrChar is used to match with a carriage return when calculating + the number of lines in the TextEdit record. kDelChar is used to + check for delete in keyDowns. */ +#define kCrChar 13 +#define kDelChar 8 + +/* kButtonScroll is how many pixels to scroll horizontally when the + button part of the horizontal scrollbar is pressed. */ +#define kButtonScroll 4 + +/* kMaxTELength is an arbitrary number used to limit the length of text + in the TERec so that various errors won't occur from too many characters + in the text. */ +#define kMaxTELength 32000 + +/* kSysEnvironsVersion is passed to SysEnvirons to tell it which version of the + SysEnvRec we understand. */ +#define kSysEnvironsVersion 1 + +/* kOSEvent is the event number of the suspend/resume and mouse-moved + events sent by MultiFinder. Once we determine that an event is an + OSEvent, we look at the high byte of the message sent to determine + which kind it is. To differentiate suspend and resume events we check + the resumeMask bit. */ +#define kOSEvent app4Evt /* event used by MultiFinder */ + +/* high byte of suspend/resume event message */ +#define kSuspendResumeMessage 1 + +/* bit of message field for resume vs. suspend */ +#define kResumeMask 1 + +/* high byte of mouse-moved event message */ +#define kMouseMovedMessage 0xFA + +#define kNoEvents 0 /* no events mask */ + + +#define kMinHeap (29 * 1024) + +#define kMinSpace (20 * 1024) + +/* kExtremeNeg and kExtremePos are used to set up wide open rectangles + and regions. */ +#define kExtremeNeg -32768 +#define kExtremePos (32767 - 1) /* required to address an old region bug */ + +/* kTESlop provides some extra security when pre-flighting edit commands. */ +#define kTESlop 1024 + +/* The following are indicies into STR# resources. */ +#define eWrongMachine 1 +#define eSmallSize 2 +#define eNoMemory 3 +#define eNoSpaceCut 4 +#define eNoCut 5 +#define eNoCopy 6 +#define eExceedPaste 7 +#define eNoSpacePaste 8 +#define eNoWindow 9 +#define eExceedChar 10 +#define eNoPaste 11 + +#define rMenuBar 128 /* application's menu bar */ +#define rAboutAlert 128 /* about alert */ +#define rUserAlert 129 /* user error alert */ +#define rDocWindow 128 /* application's window */ +#define rVScroll 128 /* vertical scrollbar control */ +#define rHScroll 129 /* horizontal scrollbar control */ +#define kErrStrings 128 /* error string list */ diff --git a/private/oleauto/tests/disptest/makefile b/private/oleauto/tests/disptest/makefile new file mode 100644 index 000000000..e9e562dfc --- /dev/null +++ b/private/oleauto/tests/disptest/makefile @@ -0,0 +1,552 @@ +############################################################################## +# +# (c) Copyright Microsoft Corp. 1992-1993 All Rights Reserved +# +# File: +# +# makefile - makefile for cdisptst.exe +# +# Purpose: +# +# Builds the OLE Automation test apps, cdisptst.exe. +# +# +# Usage: +# +# NMAKE ; build with defaults +# or: NMAKE option ; build with the given option(s) +# or: NMAKE clean ; erase all compiled files +# +# option: dev = [win16 | win32 | mac] ; dev=win16 is the default +# +# +# Notes: +# +# This makefile assumes that the PATH, INCLUDE and LIB environment +# variables are setup properly. +# +# +# Revision History: +# +# [00] 21-Sep-92 bradlo: Created +# [00] 1-Mar-93 tometeng: Update for Win32 build +# +############################################################################## + + +########################################################################## +# +# Default Settings +# + +!if !defined(OLEPROG) +!error OLEPROG environment variable not set +!endif + +TESTS = $(OLEPROG)\TESTS +!INCLUDE $(OLEPROG)\TESTS\OLEPROG.MAK + +APPS = cdisptst + + +########################################################################## +# +# Common Directories +# + +SRCDIR = $(TESTS)\DISPTEST +COMDIR = $(TESTS)\COMMON + + +########################################################################## +# +# Local WIN16 Settings +# +!if "$(TARG)" == "WIN16" + +OBJDIR = $(SRCDIR)\win16 + +!if [if not exist $(OBJDIR)\*.* mkdir $(OBJDIR)] != 0 +!endif + +GOAL = $(OBJDIR)\$(APPS).exe + +LCFLAGS = -Fo$(OBJDIR)\ -Fd$(OBJDIR)\cdsptst.pdb -AM -GA -GEs -I$(COMDIR) + +INCPATHS = $(INCPATHS);$(OLEPROG)\TESTS\COMMON + +CLIBS = \ + $(OLEPROG)\tools\win16\hdos\c800\lib\libw.lib \ + $(OLEPROG)\tools\win16\hdos\c800\lib\mlibcew.lib \ + $(OLEPROG)\tools\win16\hdos\c800\lib\shell.lib + +OLELIBS = \ + $(OLEPROG)\ole\win16\lib\ole2.lib \ + $(OLEPROG)\ole\win16\lib\compobj.lib \ + $(OLEPROG)\dwin16\ole2disp.lib \ + $(OLEPROG)\dwin16\ole2nls.lib + +OBJS = $(OBJDIR)\assert.obj \ + $(OBJDIR)\dispdbug.obj \ + $(OBJDIR)\dballoc.obj \ +# $(OBJDIR)\dispbind.obj \ + $(OBJDIR)\cunk.obj \ + $(OBJDIR)\cdisp.obj \ + $(OBJDIR)\testhelp.obj \ + $(OBJDIR)\util.obj \ + $(OBJDIR)\suite.obj \ + $(OBJDIR)\disptest.obj \ + $(OBJDIR)\disphelp.obj \ + $(OBJDIR)\crempoly.obj \ + $(OBJDIR)\cbstr.obj \ + $(OBJDIR)\cdatecnv.obj \ + $(OBJDIR)\ctime.obj \ + $(OBJDIR)\cnls.obj \ + $(OBJDIR)\cvariant.obj \ + $(OBJDIR)\cbind.obj \ + $(OBJDIR)\cinvsary.obj \ + $(OBJDIR)\cinvval.obj \ + $(OBJDIR)\cinvref.obj \ + $(OBJDIR)\cinvex.obj \ + $(OBJDIR)\csarray.obj \ + $(OBJDIR)\ccollect.obj \ + $(OBJDIR)\cearly.obj \ + $(OBJDIR)\misc.obj \ + $(OBJDIR)\guid.obj + +$(OBJDIR)\$(APPS).exe : \ + $(OBJS) \ + $(CLIBS) \ + $(OLELIBS) \ + $(OBJDIR)\$(APPS).res + $(LD) $(LFLAGS) $(LNOI) @<<$(OBJDIR)\cdisptst.lnk +$(OBJS: = +^ +) +$@, +$(OBJDIR)\$(APPS).map, +$(CLIBS) + +$(OLELIBS), +$(SRCDIR)\$(APPS).def +<<KEEP + rc -k -t $(OBJDIR)\$(APPS).res $@ + +$(OBJDIR)\$(APPS).res : \ + $(SRCDIR)\resource.h \ + $(COMDIR)\assert.dlg \ + $(SRCDIR)\$(APPS).rc + rc $(RCFLAGS) -r -fo$@ $(SRCDIR)\$(APPS).rc + +!endif + + +########################################################################## +# +# WIN32 Settings +# +!if "$(TARG)" == "WIN32" + +OBJDIR = $(SRCDIR)\win32 + +!if [if not exist $(OBJDIR)\*.* mkdir $(OBJDIR)] != 0 +!endif + +GOAL = $(OBJDIR)\$(APPS).exe + +LCFLAGS = -Fo$(OBJDIR)\ -I$(COMDIR) + +INCPATHS = $(INCPATHS);$(OLEPROG)\TESTS\COMMON + +LIBS = \ + libcmt.lib \ + kernel32.lib \ + user32.lib \ + gdi32.lib \ + ole32.lib \ + $(OLEPROG)\dwin32\oleaut32.lib \ + uuid.lib + + +OBJS = $(OBJDIR)\assert.obj \ + $(OBJDIR)\dispdbug.obj \ + $(OBJDIR)\dballoc.obj \ + $(OBJDIR)\nlshelp.obj \ +# $(OBJDIR)\dispbind.obj \ + $(OBJDIR)\cunk.obj \ + $(OBJDIR)\cdisp.obj \ + $(OBJDIR)\testhelp.obj \ + $(OBJDIR)\util.obj \ + $(OBJDIR)\suite.obj \ + $(OBJDIR)\disptest.obj \ + $(OBJDIR)\disphelp.obj \ + $(OBJDIR)\crempoly.obj \ + $(OBJDIR)\cbstr.obj \ + $(OBJDIR)\cdatecnv.obj \ + $(OBJDIR)\ctime.obj \ + $(OBJDIR)\cvariant.obj \ + $(OBJDIR)\cbind.obj \ + $(OBJDIR)\cinvsary.obj \ + $(OBJDIR)\cinvval.obj \ + $(OBJDIR)\cinvref.obj \ + $(OBJDIR)\cinvex.obj \ + $(OBJDIR)\csarray.obj \ + $(OBJDIR)\ccollect.obj \ + $(OBJDIR)\cearly.obj \ + $(OBJDIR)\misc.obj \ + $(OBJDIR)\cnls.obj \ + $(OBJDIR)\guid.obj + +$(OBJDIR)\$(APPS).exe : \ + $(OBJS) \ + $(SRCDIR)\$(APPS).def \ + $(OBJDIR)\$(APPS).res + cvtres -$(CPU) $(OBJDIR)\$(APPS).res -o $(OBJDIR)\$(APPS).rs + $(LD) @<< + -entry:WinMainCRTStartup + -out:$@ + -map:$*.map + -nodefaultlib + $(LFLAGS) + $(OBJS) + $(OBJDIR)\$(APPS).rs + $(LIBS) +<< + +$(OBJDIR)\$(APPS).res : $(SRCDIR)\$(APPS).rc $(SRCDIR)\resource.h + rc $(RCFLAGS) -r -fo$@ $(SRCDIR)\$(APPS).rc + +!endif + + +########################################################################## +# +# MAC Settings +# +!if "$(TARG)" == "MAC" + +OASRC = $(DISPDIR)\mac + +!if "$(TARGCPU)"=="PPC" +OBJDIR = $(SRCDIR)\macppc +!else +OBJDIR = $(SRCDIR)\mac +!endif + +!if [if not exist $(OBJDIR)\*.* mkdir $(OBJDIR)] != 0 +!endif + +MACLIBDIR = $(VBATOOLS)\win32\$(COMPILER)\LIB + +!if "$(TARGCPU)"=="PPC" +LCFLAGS = -Fd$(OBJDIR)\cdisptst.pdb -Fo$(OBJDIR)\ -D _SLM +!else +LCFLAGS = -AL -Gt1 -Fd$(OBJDIR)\cdisptst.pdb -Fo$(OBJDIR)\ -D _SLM +!endif + + +INCPATHS = $(INCPATHS);$(OLEPROG)\TESTS\COMMON;$(VBATOOLS)\win32\$(COMPILER)\INC\MRC + +LIBS = \ + $(MACLIBDIR)\interfac.lib \ +!if "$(TARGCPU)"=="PPC" + ole2auto.lib \ + ole2.lib \ + $(MACLIBDIR)\mprof.lib \ + $(MACLIBDIR)\libc.lib +!else + $(MACLIBDIR)\wlm.lib \ +!if ("$(SWAP)" == "1") + $(MACLIBDIR)\llibcs.lib \ + $(MACLIBDIR)\lsanes.lib \ + $(MACLIBDIR)\swap.lib +!else + $(MACLIBDIR)\llibc.lib \ + $(MACLIBDIR)\lsane.lib +!endif + +OLEOBJS = \ +!if ("$(SWAP)" == "1") + $(OLEDIR)\olelds.obj $(OLEDIR)\oalds.obj +!else + $(OLEDIR)\olendf.obj $(OLEDIR)\oandf.obj +!endif + +!endif # TARGCPU=PPC + + + +STATIC_OBJS = \ + $(OBJDIR)\assert.obj \ + $(OBJDIR)\dispdbug.obj \ + $(OBJDIR)\macmain.obj \ + $(OBJDIR)\suite.obj \ + $(OBJDIR)\dballoc.obj \ + $(OBJDIR)\cunk.obj \ + $(OBJDIR)\cdisp.obj \ + $(OBJDIR)\testhelp.obj \ + $(OBJDIR)\util.obj \ + $(OBJDIR)\cbstr.obj \ + $(OBJDIR)\cdatecnv.obj \ + $(OBJDIR)\ctime.obj \ + $(OBJDIR)\cnls.obj \ + $(OBJDIR)\cvariant.obj \ + $(OBJDIR)\csarray.obj \ + $(OBJDIR)\misc.obj \ + $(OBJDIR)\guid.obj \ + $(OBJDIR)\oleguids.obj + +DLL_OBJS = \ + $(OBJDIR)\disphelp.obj \ + $(OBJDIR)\crempoly.obj \ + $(OBJDIR)\cbind.obj \ + $(OBJDIR)\cinvsary.obj \ + $(OBJDIR)\cinvval.obj \ + $(OBJDIR)\ccollect.obj \ + $(OBJDIR)\cinvref.obj \ + $(OBJDIR)\cinvex.obj + +OBJS = \ + $(STATIC_OBJS) \ + $(DLL_OBJS) + + +$(OBJDIR)\$(APPS).exe : \ + $(OBJS) \ + $(OLEOBJS) \ + $(OBJDIR)\$(APPS).x + $(LD) @<< + $(OBJS) + $(OLEOBJS) + $(LIBS) +!if "$(TARGCPU)"=="PPC" + -machine:mppc +!else + -machine:m68k +!endif + -entry:mainCRTStartup + -debug:full + -debugtype:cv + -nopack + -nodefaultlib + -out:$@ + -map:$*.map +<<KEEP + cvpack $(OBJDIR)\$(APPS).exe + + +$(OBJDIR)\$(APPS).x : $(SRCDIR)\$(APPS).r +!if "$(TARGCPU)" == "PPC" + mrc -s$(VBATOOLS)\win32\ppc\lib -D_PPCMAC -o $(OBJDIR)\$(APPS).x $(SRCDIR)\$(APPS).r +!else + mrc -D_MAC -o $(OBJDIR)\$(APPS).x $(SRCDIR)\$(APPS).r +!endif + +!if "$(TARGCPU)" == "PPC" +GOAL = $(OBJDIR)\$(APPS).pef + +$(OBJDIR)\$(APPS) : $(OBJDIR)\$(APPS).exe $(OBJDIR)\$(APPS).x + copy $(OBJDIR)\$(APPS).x $(OBJDIR)\$(APPS) + makepef $(OBJDIR)\$(APPS).exe $(OBJDIR)\$(APPS).pef + +!else + +GOAL = $(OBJDIR)\$(APPS) + +$(OBJDIR)\$(APPS) : $(OBJDIR)\$(APPS).exe $(OBJDIR)\$(APPS).x + copy $(OBJDIR)\$(APPS).x $(OBJDIR)\$(APPS) + mrc -e $(OBJDIR)\$(APPS).exe -a -o $(OBJDIR)\$(APPS) + +!endif + +$(OBJDIR)\oleguids.obj : $(SRCDIR)\oleguids.c $(SRCDIR)\oleguids.h + $(CC) -c $(SRCDIR)\oleguids.c + +$(OBJDIR)\macmain.obj : $(SRCDIR)\macmain.h $(SRCDIR)\macmain.cpp + $(CCPP) -c $(SRCDIR)\macmain.cpp + +!endif + + +########################################################################## +# +# Default Goal +# + +all : setflags $(GOAL) + +setflags : + set CL=$(CFLAGS) $(LCFLAGS) + set LIB=$(LIBPATHS) + set PATH=$(BINPATHS) + set INCLUDE=$(INCPATHS) + + +########################################################################## +# +# Clean (erase) generated files +# +clean : + -erase $(OBJDIR)\*.obj + -erase $(OBJDIR)\*.lib + -erase $(OBJDIR)\*.dll + -erase $(OBJDIR)\*.exe + -erase $(OBJDIR)\*.map + -erase $(OBJDIR)\*.res + -erase $(OBJDIR)\*.rs + -erase $(OBJDIR)\*.lnk + -erase $(OBJDIR)\*.rpp + -erase $(OBJDIR)\*.x + + +########################################################################## +# +# Dependencies +# + +$(OBJDIR)\disptest.obj : \ + $(SRCDIR)\disptest.h \ + $(SRCDIR)\resource.h \ + $(SRCDIR)\disptest.cpp + $(CCPP) -c $(SRCDIR)\disptest.cpp + +$(OBJDIR)\suite.obj : \ + $(SRCDIR)\disptest.h \ + $(SRCDIR)\resource.h \ + $(SRCDIR)\suite.cpp + $(CCPP) -c $(SRCDIR)\suite.cpp + +$(OBJDIR)\misc.obj : \ + $(SRCDIR)\disptest.h \ + $(SRCDIR)\misc.cpp + $(CCPP) -c $(SRCDIR)\misc.cpp + +$(OBJDIR)\guid.obj : \ + $(SRCDIR)\tstsuite.h \ + $(SRCDIR)\clsid.h \ + $(SRCDIR)\guid.c + $(CCPP) -c $(SRCDIR)\guid.c + +$(OBJDIR)\cbstr.obj : \ + $(SRCDIR)\disptest.h \ + $(SRCDIR)\tstsuite.h \ + $(SRCDIR)\cbstr.cpp + $(CCPP) -c $(SRCDIR)\cbstr.cpp + +$(OBJDIR)\cwbstr.obj : \ + $(SRCDIR)\disptest.h \ + $(SRCDIR)\tstsuite.h \ + $(SRCDIR)\cwbstr.cpp + $(CCPP) -c $(SRCDIR)\cwbstr.cpp + +$(OBJDIR)\cdatecnv.obj : \ + $(SRCDIR)\disptest.h \ + $(SRCDIR)\tstsuite.h \ + $(SRCDIR)\cdatecnv.cpp + $(CCPP) -c $(SRCDIR)\cdatecnv.cpp + +$(OBJDIR)\ctime.obj : \ + $(SRCDIR)\disptest.h \ + $(SRCDIR)\tstsuite.h \ + $(SRCDIR)\ctime.cpp + $(CCPP) -c $(SRCDIR)\ctime.cpp + +$(OBJDIR)\cnls.obj : \ + $(SRCDIR)\disptest.h \ + $(SRCDIR)\tstsuite.h \ + $(SRCDIR)\cnls.cpp + $(CCPP) -c $(SRCDIR)\cnls.cpp + +$(OBJDIR)\cbind.obj : \ + $(SRCDIR)\disptest.h \ + $(SRCDIR)\tstsuite.h \ + $(SRCDIR)\cbind.cpp + $(CCPP) -c $(SRCDIR)\cbind.cpp + +$(OBJDIR)\cvariant.obj : \ + $(SRCDIR)\disptest.h \ + $(SRCDIR)\tstsuite.h \ + $(SRCDIR)\cvariant.cpp + $(CCPP) -c $(SRCDIR)\cvariant.cpp + +$(OBJDIR)\csarray.obj : \ + $(SRCDIR)\disptest.h \ + $(SRCDIR)\tstsuite.h \ + $(SRCDIR)\csarray.cpp + $(CCPP) -c $(SRCDIR)\csarray.cpp + +$(OBJDIR)\cinvval.obj : \ + $(SRCDIR)\disptest.h \ + $(SRCDIR)\tstsuite.h \ + $(SRCDIR)\cinvval.cpp + $(CCPP) -c $(SRCDIR)\cinvval.cpp + +$(OBJDIR)\cinvref.obj : \ + $(SRCDIR)\disptest.h \ + $(SRCDIR)\tstsuite.h \ + $(SRCDIR)\cinvref.cpp + $(CCPP) -c $(SRCDIR)\cinvref.cpp + +$(OBJDIR)\cinvsary.obj : \ + $(SRCDIR)\disptest.h \ + $(SRCDIR)\tstsuite.h \ + $(SRCDIR)\cinvsary.cpp + $(CCPP) -c $(SRCDIR)\cinvsary.cpp + +$(OBJDIR)\cinvex.obj : \ + $(SRCDIR)\disptest.h \ + $(SRCDIR)\tstsuite.h \ + $(SRCDIR)\cinvex.cpp + $(CCPP) -c $(SRCDIR)\cinvex.cpp + +$(OBJDIR)\ccollect.obj : \ + $(SRCDIR)\disptest.h \ + $(COMDIR)\crempoly.h \ + $(SRCDIR)\tstsuite.h \ + $(SRCDIR)\ccollect.cpp + $(CCPP) -c $(SRCDIR)\ccollect.cpp + +$(OBJDIR)\cearly.obj : \ + $(SRCDIR)\disptest.h \ + $(COMDIR)\dualtst.h \ + $(SRCDIR)\tstsuite.h \ + $(SRCDIR)\cearly.cpp + $(CCPP) -c $(SRCDIR)\cearly.cpp + +$(OBJDIR)\cunk.obj : $(COMDIR)\cunk.h $(COMDIR)\cunk.cpp + $(CCPP) -c $(COMDIR)\cunk.cpp + +$(OBJDIR)\cdisp.obj : $(COMDIR)\cdisp.h $(COMDIR)\cdisp.cpp + $(CCPP) -c $(COMDIR)\cdisp.cpp + +$(OBJDIR)\testhelp.obj : $(COMDIR)\testhelp.h $(COMDIR)\testhelp.cpp + $(CCPP) -c $(COMDIR)\testhelp.cpp + +$(OBJDIR)\util.obj : $(COMDIR)\common.h $(COMDIR)\util.cpp + $(CCPP) -c $(COMDIR)\util.cpp + +$(OBJDIR)\crempoly.obj : $(COMDIR)\crempoly.h $(COMDIR)\crempoly.cpp + $(CCPP) -c $(COMDIR)\crempoly.cpp + +$(OBJDIR)\disphelp.obj : $(COMDIR)\disphelp.h $(COMDIR)\disphelp.cpp + $(CCPP) -c $(COMDIR)\disphelp.cpp + +#$(OBJDIR)\dispbind.obj : $(COMDIR)\dispbind.cpp +# $(CCPP) -c $(COMDIR)\dispbind.cpp + +$(OBJDIR)\assert.obj : \ + $(COMDIR)\assrtdlg.h \ + $(COMDIR)\assert.cpp + $(CCPP) -c $(COMDIR)\assert.cpp + +$(OBJDIR)\nlshelp.obj : \ + $(COMDIR)\common.h \ + $(COMDIR)\nlshelp.cpp + $(CCPP) -c $(COMDIR)\nlshelp.cpp + +$(OBJDIR)\dispdbug.obj : \ + $(COMDIR)\common.h \ + $(COMDIR)\dispdbug.h \ + $(COMDIR)\dispdbug.cpp + $(CCPP) -c $(COMDIR)\dispdbug.cpp + +$(OBJDIR)\dballoc.obj : $(COMDIR)\dballoc.h $(COMDIR)\dballoc.cpp + $(CCPP) -c $(COMDIR)\dballoc.cpp diff --git a/private/oleauto/tests/disptest/makefile.mpw b/private/oleauto/tests/disptest/makefile.mpw new file mode 100644 index 000000000..ab3fb0a6e --- /dev/null +++ b/private/oleauto/tests/disptest/makefile.mpw @@ -0,0 +1,181 @@ +#*** +#makefile.mpw +# +# Copyright (C) 1992-93, Microsoft Corporation. All Rights Reserved. +# +#Purpose: +# Makefile for the Ole Automation Test App (Client), cdisptst +# +# +#Implementation Notes: +# +#****************************************************************************/ + +OleRoot = HD:Ole2: + +OleIncDir= {OleRoot}MPW:Interfaces:CIncludes: +OleLibDir= {OleRoot}MPW:Libraries:CLibraries: + +Common = hd:ole2auto:tests:common: +ObjDir = hd:ole2auto:build:cdisptst:d: +BinDir = hd:ole2auto:bin: + +defs = -d _MAC -d _DEBUG +incs = -i {CIncludes} -i {OleIncDir} -i {Common} + +cflags = -mf -w3 -z6 -model far -sym full -mbg full {defs} {incs} +cppflags = -mf -w3 -z6 -model far -sym full -mbg full {defs} {incs} + +pch = -load {ObjDir}disptest.h.dump + +AppleLibObjs = \ + "{Libraries}"Runtime.o \ + "{Libraries}"Interface.o \ + "{CLibraries}"CPluslib.o \ + "{CLibraries}"Math.o \ + "{CLibraries}"CSANELib.o \ + "{CLibraries}"StdCLib.o + +OleLibs = \ + {OleLibDir}LibraryManager.o \ + {OleLibDir}CompObjLib.cl.o \ + {OleLibDir}DefLib.cl.o \ + {OleLibDir}ole2nlsLib.cl.o \ + {OleLibDir}ole2dispLib.cl.o + +pchObjs = \ + {ObjDir}disptest.h.o + +commonObjs = \ + {ObjDir}assert.cpp.o \ + {ObjDir}cdisp.cpp.o \ + {ObjDir}crempoly.cpp.o \ + {ObjDir}cunk.cpp.o \ + {ObjDir}dballoc.cpp.o \ + {ObjDir}dispdbug.cpp.o \ + {ObjDir}disphelp.cpp.o \ + {ObjDir}testhelp.cpp.o \ + {ObjDir}util.cpp.o + +Objs = \ + {pchObjs} \ + {commonObjs} \ + {ObjDir}guid.c.o \ + {ObjDir}oleguids.c.o \ + {ObjDir}cbind.cpp.o \ + {ObjDir}cbstr.cpp.o \ + {ObjDir}ccollect.cpp.o \ + {ObjDir}cdatecnv.cpp.o \ + {ObjDir}cinvsary.cpp.o \ + {ObjDir}cinvval.cpp.o \ + {ObjDir}cinvref.cpp.o \ + {ObjDir}cinvex.cpp.o \ + {ObjDir}cnls.cpp.o \ + {ObjDir}csarray.cpp.o \ + {ObjDir}ctime.cpp.o \ + {ObjDir}cvariant.cpp.o \ + {ObjDir}macmain.cpp.o \ + {ObjDir}misc.cpp.o \ + {ObjDir}suite.cpp.o + + +all ^ {ObjDir}cdisptst + + +{ObjDir}cdisptst ^^ {Objs} {ObjDir}AppleLib.o {OleLibs} cdisptst.r resource.h + Link -model far -d -o {targ} -sym full {Objs} {ObjDir}AppleLib.o {OleLibs} + SetFile {targ} -t APPL -c 'CDSP' -a B + Rez -d _MAC -rd -append -o {targ} cdisptst.r + Duplicate -y {targ} {BinDir} + Duplicate -y {targ}.SYM {BinDir} + +{ObjDir}AppleLib.o ^ {AppleLibObjs} + Lib -o {ObjDir}AppleLib.o {AppleLibObjs} + + +## precompiled header + +{ObjDir}disptest.h.o ^ disptest.h + cplus disptest.h -o {targ} {cppflags} -dumpc {ObjDir}disptest.h.dump + + +{ObjDir}guid.c.o ^ guid.c + cplus guid.c -o {targ} {cppflags} + +{ObjDir}oleguids.c.o ^ oleguids.c oleguids.h + cplus oleguids.c -o {targ} {cppflags} + + +{ObjDir}assert.cpp.o ^ {Common}assert.cpp + cplus {Common}assert.cpp -o {targ} {cppflags} + +{ObjDir}crempoly.cpp.o ^ {Common}crempoly.cpp disptest.h + cplus {Common}crempoly.cpp -o {targ} {cppflags} + +{ObjDir}cunk.cpp.o ^ {Common}cunk.cpp {Common}cunk.h + cplus {Common}cunk.cpp -o {targ} {cppflags} + +{ObjDir}cdisp.cpp.o ^ {Common}cdisp.cpp {Common}cdisp.h + cplus {Common}cdisp.cpp -o {targ} {cppflags} + +{ObjDir}dballoc.cpp.o ^ {Common}dballoc.cpp {Common}dballoc.h + cplus {Common}dballoc.cpp -o {targ} {cppflags} + +{ObjDir}dispdbug.cpp.o ^ {Common}dispdbug.cpp disptest.h + cplus {Common}dispdbug.cpp -o {targ} {cppflags} + +{ObjDir}disphelp.cpp.o ^ {Common}disphelp.cpp disptest.h + cplus {Common}disphelp.cpp -o {targ} {cppflags} + +{ObjDir}testhelp.cpp.o ^ {Common}testhelp.cpp disptest.h + cplus {Common}testhelp.cpp -o {targ} {cppflags} + +{ObjDir}util.cpp.o ^ {Common}util.cpp disptest.h + cplus {Common}util.cpp -o {targ} {cppflags} + + +{ObjDir}cbind.cpp.o ^ cbind.cpp disptest.h + cplus cbind.cpp -o {targ} {pch} {cppflags} + +{ObjDir}cbstr.cpp.o ^ cbstr.cpp disptest.h + cplus cbstr.cpp -o {targ} {pch} {cppflags} + +{ObjDir}ccollect.cpp.o ^ ccollect.cpp disptest.h + cplus ccollect.cpp -o {targ} {pch} {cppflags} + +{ObjDir}cdatecnv.cpp.o ^ cdatecnv.cpp disptest.h + cplus cdatecnv.cpp -o {targ} {pch} {cppflags} + +{ObjDir}cinvsary.cpp.o ^ cinvsary.cpp disptest.h + cplus cinvsary.cpp -o {targ} {pch} {cppflags} + +{ObjDir}cinvval.cpp.o ^ cinvval.cpp disptest.h + cplus cinvval.cpp -o {targ} {pch} {cppflags} + +{ObjDir}cinvref.cpp.o ^ cinvref.cpp disptest.h + cplus cinvref.cpp -o {targ} {pch} {cppflags} + +{ObjDir}cinvex.cpp.o ^ cinvex.cpp disptest.h + cplus cinvex.cpp -o {targ} {pch} {cppflags} + +{ObjDir}cnls.cpp.o ^ cnls.cpp disptest.h + cplus cnls.cpp -o {targ} {pch} {cppflags} + +{ObjDir}csarray.cpp.o ^ csarray.cpp disptest.h + cplus csarray.cpp -o {targ} {pch} {cppflags} + +{ObjDir}ctime.cpp.o ^ ctime.cpp disptest.h + cplus ctime.cpp -o {targ} {pch} {cppflags} + +{ObjDir}cvariant.cpp.o ^ cvariant.cpp disptest.h + cplus cvariant.cpp -o {targ} {pch} {cppflags} + +{ObjDir}macmain.cpp.o ^ macmain.cpp disptest.h + cplus macmain.cpp -o {targ} {pch} {cppflags} + +{ObjDir}misc.cpp.o ^ misc.cpp disptest.h + cplus misc.cpp -o {targ} {pch} {cppflags} + +{ObjDir}suite.cpp.o ^ suite.cpp disptest.h + cplus suite.cpp -o {targ} {pch} {cppflags} + diff --git a/private/oleauto/tests/disptest/misc.cpp b/private/oleauto/tests/disptest/misc.cpp new file mode 100644 index 000000000..d5773d13a --- /dev/null +++ b/private/oleauto/tests/disptest/misc.cpp @@ -0,0 +1,271 @@ +/*** +*misc.cpp +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* Misc DispTest helpers and initialization functions. +* +*Revision History: +* +* [00] 02-Oct-92 bradlo: Created +* +*Implementation Notes: +* +*****************************************************************************/ + + +#include <stdio.h> +#include <string.h> +#include <stdarg.h> + +#include "disptest.h" +#include "dballoc.h" + +ASSERTDATA + +extern int g_fDetectLeaks; + +#if OE_WIN32 +extern CRITICAL_SECTION g_csDbPrintf; +#endif // OE_WIN32 + +int g_fLog = TRUE; + +OLECHAR FAR* g_szCPoly = OLESTR("spoly.cpoly"); +OLECHAR FAR* g_szCSArray = OLESTR("sdisptst.csarray"); +OLECHAR FAR* g_szCDispTst = OLESTR("sdisptst.cdisptst"); +OLECHAR FAR* g_szCExcepinfo = OLESTR("sdisptst.cexcepinfo"); +OLECHAR FAR* g_szCWExcepinfo = OLESTR("sdisptst.cwexcepinfo"); + +#if OE_WIN32 +unsigned long g_itlsAppData = ~(ULONG)0; +#else // !OE_WIN32 +APP_DATA g_appdata; +#endif // !OE_WIN32 + +APP_DATA *Pappdata() +{ +#if OE_WIN32 + return (APP_DATA *)TlsGetValue(g_itlsAppData); +#else // !OE_WIN32 + return &g_appdata; +#endif // !OE_WIN32 +} + + +BOOL InitAppData() +{ +#if OE_WIN32 + APP_DATA *pappdata; + + if (g_itlsAppData == ~(ULONG)0) { + if ((g_itlsAppData = TlsAlloc()) == ~(ULONG)0) { + return FALSE; + } + } + + ASSERT(TlsGetValue(g_itlsAppData) == NULL); + + pappdata = new APP_DATA; + + if (pappdata == NULL) { + return FALSE; + } + + TlsSetValue(g_itlsAppData, (LPVOID)pappdata); +#endif // OE_WIN32 + + return TRUE; +} + +VOID ReleaseAppData() +{ +#if OE_WIN32 + ASSERT(g_itlsAppData != ~(ULONG)0); + + delete Pappdata(); + TlsSetValue(g_itlsAppData, NULL); +#endif // OE_WIN32 +} + +STDAPI +InitOle() +{ + HRESULT hresult; + IMalloc FAR* pmalloc; + + pmalloc = NULL; + +#if OE_MAC + +#if 0 + OSErr oserr = LoadAllLibraries(); + if(oserr != noErr){ + hresult = ResultFromScode(E_FAIL); + goto LError0; + } +#endif + +#else + +#if !OE_WIN32 // latest OLE complains about our allocs not being + // properly aligned (it wants 8-byte alignment even + // on x86). New OLE debug allocator is pretty good + // now, so we'll just use theirs. + unsigned long options = DBALLOC_NONE; + + if(g_fDetectLeaks) + options |= DBALLOC_DETECTLEAKS; + + IfFailGo(CreateDbAlloc(options, NULL, &pmalloc), LError0); +#endif //!OE_WIN32 + +#endif + + hresult = OleInitialize(pmalloc); + +#if !OE_WIN32 +LError0:; +#endif // !OE_WIN32 + + if(pmalloc != NULL) + pmalloc->Release(); + + return hresult; +} + +STDAPI_(void) +UninitOle() +{ + OleUninitialize(); +} + +void +PrintSuiteHeader(TCHAR FAR* szFmt, ...) +{ + int i, len; + va_list args; + TCHAR rgch[256]; + + va_start(args, szFmt); +#if OE_MAC + vsprintf(rgch, szFmt, args); +#else + wvsprintf(rgch, szFmt, args); +#endif + + DbPrintf("\n\nSuite : "); + DbPrintf((char FAR*)rgch); + DbPrintf("\n"); + len = STRLEN(rgch) + 8; + for(i = 0; i < len+8; ++i) + rgch[i] = TSTR('-'); + rgch[i] = TSTR('\n'); + rgch[i+1] = TSTR('\0'); + DbPrintf((char FAR*) rgch); +} + +void +PrintTestHeader(TCHAR FAR* szFmt, ...) +{ + va_list args; + TCHAR rgch[256]; + + va_start(args, szFmt); +#if OE_MAC + vsprintf(rgch, szFmt, args); +#else + wvsprintf(rgch, szFmt, args); +#endif + DbPrintf("Test : "); + DbPrintf((char FAR*)rgch); + DbPrintf("\n"); +} + + +#if OE_MAC +STDAPI_(void) OutputDebugString(const OLECHAR*); +#endif + + +extern "C" void +DbPrintf(char FAR* szFmt, ...) +{ + int len; + va_list args; + char *pn, FAR* pf; + static char rgchFmtBuf[512]; + static char rgchOutputBuf[1024]; + +#if OE_WIN32 + EnterCriticalSection(&g_csDbPrintf); +#endif // OE_WIN32 + +#if HC_MPW + + // translate all instances of %Fs to %s + + for(pf=szFmt, pn=rgchFmtBuf; *pf != '\0';){ + + if(pf[0] == '%' && pf[1] == 'F' && pf[2] == 's'){ + pn[0] = '%'; + pn[1] = 's'; + pf += 3; + pn += 2; + }else{ + *pn++ = *pf++; + } + + } + *pn = '\0'; + + pn = rgchFmtBuf; + +#else + +# if OE_WIN16 + + // copy the 'far' format string to a near buffer so we can use + // the medium model vsprintf, which only supports near data pointers. + + pn = rgchFmtBuf, pf=szFmt; + while(*pf != '\0') + *pn++ = *pf++; + *pn = '\0'; + + pn = rgchFmtBuf; + +# else + + pn = szFmt; + +# endif + +#endif + + va_start(args, szFmt); + vsprintf(rgchOutputBuf, pn, args); + + len = strlen(rgchOutputBuf); + ASSERT(len < DIM(rgchOutputBuf)); +#if OE_WIN32 + OutputDebugStringA(rgchOutputBuf); +#else + OutputDebugString(rgchOutputBuf); +#endif + if(Pappdata()->m_hfLogfile != HFILE_ERROR){ +#if OE_MAC + fprintf(Pappdata()->m_hfLogfile, rgchOutputBuf); +#else + _lwrite(Pappdata()->m_hfLogfile, rgchOutputBuf, len); +#endif + } + +#if OE_WIN32 + LeaveCriticalSection(&g_csDbPrintf); +#endif // OE_WIN32 + +} + diff --git a/private/oleauto/tests/disptest/oleguids.c b/private/oleauto/tests/disptest/oleguids.c new file mode 100644 index 000000000..360169b83 --- /dev/null +++ b/private/oleauto/tests/disptest/oleguids.c @@ -0,0 +1,51 @@ +/*** +*oleguids.c +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* This file allocates (via Ole macro mania) the Ole GUIDS that are +* referenced by the OLEDISP dll. +* +*Revision History: +* +* [00] 21-Jan-93 bradlo: Created. +* +*****************************************************************************/ + +#ifdef _MAC +# ifdef _MSC_VER +# include <macos/types.h> +# include <macos/processe.h> +# include <macos/appleeve.h> +# define far +# define FAR far +# define near +# define NEAR near +# define pascal _pascal +# define PASCAL pascal +# define cdecl _cdecl +# define CDECL cdecl +# else +# include <Types.h> +# include <Processes.h> +# include <AppleEvents.h> +# endif +#endif +#include <compobj.h> + +// this redefines the Ole DEFINE_GUID() macro to do allocation. +// +#include <initguid.h> + +#ifndef INITGUID +# define INITGUID +#endif + +// due to the previous header, including this causes our DEFINE_GUID +// definitions in the following headers to actually allocate data. + +// instantiate the ole2 guids that we use +#include "oleguids.h" + diff --git a/private/oleauto/tests/disptest/oleguids.h b/private/oleauto/tests/disptest/oleguids.h new file mode 100644 index 000000000..446f7631b --- /dev/null +++ b/private/oleauto/tests/disptest/oleguids.h @@ -0,0 +1,37 @@ +/*** +*oleguids.h +* +* Copyright (C) 1993, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* This file is a subset of the Ole2 guid header: coguid.h. +* +* This file is used to instantiate the data for the Ole2 IIDs that +* are used in OLEDISP.DLL, rather than linking with the Ole2 implib, +* which causes us to pull in way more IID and CLSID definitions than +* we want. +* +* NOTE: the GUIDs below must be *exactly* the same as those assigned +* by the Ole group - If the Ole group ever changes their numbers, we +* must change accordingly. +* +*Revision History: +* +* [00] 03-Jun-93 bradlo: Created. +* +*Implementation Notes: +* +*****************************************************************************/ + + +DEFINE_GUID(GUID_NULL, 0L, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + +DEFINE_OLEGUID(IID_IUnknown, 0x00000000L, 0, 0); +DEFINE_OLEGUID(IID_IMalloc, 0x00000002L, 0, 0); + +#ifdef _MAC +DEFINE_OLEGUID(IID_IDispatch, 0x00020400L, 0, 0); +DEFINE_OLEGUID(IID_IEnumVARIANT,0x00020404L, 0, 0); +#endif + diff --git a/private/oleauto/tests/disptest/pch.cpp b/private/oleauto/tests/disptest/pch.cpp new file mode 100644 index 000000000..9a23250d4 --- /dev/null +++ b/private/oleauto/tests/disptest/pch.cpp @@ -0,0 +1,5 @@ +// this file is used to construct the precompiled header + +#include "disptest.h" +#include "tstsuite.h" + diff --git a/private/oleauto/tests/disptest/resource.h b/private/oleauto/tests/disptest/resource.h new file mode 100644 index 000000000..c3a0102a6 --- /dev/null +++ b/private/oleauto/tests/disptest/resource.h @@ -0,0 +1,41 @@ +#ifdef _MAC +# define MBARID_CDISPTST 128 +# define MENUID_APPLE 128 +# define ICONID_CDISPTST 228 +#endif + +#define IDM_ALL 200 + +#define IDM_SUITE 300 +#define IDM_SUITE_BSTR 301 +#define IDM_SUITE_TIME 302 +#define IDM_SUITE_DATECNV 303 +#define IDM_SUITE_VARIANT 304 +#define IDM_SUITE_SAFEARRAY 305 +#define IDM_SUITE_NLS 306 +#define IDM_SUITE_BIND 307 +#define IDM_SUITE_INVOKE_BYVAL 308 +#define IDM_SUITE_INVOKE_BYREF 309 +#define IDM_SUITE_INVOKE_MULTIPLE 310 +#define IDM_SUITE_INVOKE_SAFEARRAY 311 +#define IDM_SUITE_INVOKE_EXCEPINFO 312 +#define IDM_SUITE_COLLECTION 313 +#define IDM_SUITE_EARLY 314 + +#define IDM_OPTIONS 400 +#define IDM_OPTIONS_TRACE 401 +#define IDM_OPTIONS_NAMED 402 +#define IDM_OPTIONS_MULTITHREAD 403 + +#define IDM_HELP 500 +#define IDM_HELP_ABOUT 501 + + +#define IDD_SUITE_NAME 600 +#define IDD_SUITE_TESTNAME 601 +#define IDD_SUITE_PERCENT 603 +#define IDD_SUITE_GUAGE 604 + +#ifdef WIN32 +#define IDM_SUITE_WBSTR 314 +#endif diff --git a/private/oleauto/tests/disptest/src2mac.mak b/private/oleauto/tests/disptest/src2mac.mak new file mode 100644 index 000000000..7100cf7b1 --- /dev/null +++ b/private/oleauto/tests/disptest/src2mac.mak @@ -0,0 +1,228 @@ +#*** +#src2mac.mak +# +# Copyright (C) 1992-93, Microsoft Corporation. All Rights Reserved. +# Information Contained Herein Is Proprietary and Confidential. +# +#Purpose: +# UNDONE +# +# +#Revision History: +# +# [00] 15-Jun-93 bradlo: Created. +# +#Implementation Notes: +# +#****************************************************************************/ + +.SUFFIXES: .c .cpp .h + +all: setflags files + +# source directories +# +SRCCOMN = $(OLEPROG)\TESTS\COMMON +SRCCDSP = $(OLEPROG)\TESTS\DISPTEST + +# destination directories +# +MACCOMN = :hd:ole2auto:tests:common: +MACCDSP = :hd:ole2auto:tests:disptest: + +# timestamp directories +# +TMPCOMN = $(TMP)\common +TMPCDSP = $(TMP)\disptest + +CP2MAC=ec copy -l -t TEXT -c "MPS " + +setflags: + set path=%tools%\hnt\wings\bin;%oleprog%\bin + if not exist %TMP%\common mkdir %TMP%\common + if not exist %TMP%\disptest mkdir %TMP%\disptest + + +files : common cdisptst + +common : \ + $(TMPCOMN)\assrtdlg.h \ + $(TMPCOMN)\cdisp.h \ + $(TMPCOMN)\common.h \ + $(TMPCOMN)\crempoly.h \ + $(TMPCOMN)\cunk.h \ + $(TMPCOMN)\dballoc.h \ + $(TMPCOMN)\dispdbug.h \ + $(TMPCOMN)\disphelp.h \ + $(TMPCOMN)\testhelp.h \ + $(TMPCOMN)\assert.cpp \ + $(TMPCOMN)\cdisp.cpp \ + $(TMPCOMN)\crempoly.cpp \ + $(TMPCOMN)\cunk.cpp \ + $(TMPCOMN)\dispdbug.cpp \ + $(TMPCOMN)\dballoc.cpp \ + $(TMPCOMN)\disphelp.cpp \ + $(TMPCOMN)\testhelp.cpp \ + $(TMPCOMN)\util.cpp + +cdisptst : \ + $(TMPCDSP)\clsid.h \ + $(TMPCDSP)\disptest.h \ + $(TMPCDSP)\macmain.h \ + $(TMPCDSP)\oleguids.h \ + $(TMPCDSP)\resource.h \ + $(TMPCDSP)\tstsuite.h \ + $(TMPCDSP)\guid.c \ + $(TMPCDSP)\oleguids.c \ + $(TMPCDSP)\cbind.cpp \ + $(TMPCDSP)\cbstr.cpp \ + $(TMPCDSP)\ccollect.cpp \ + $(TMPCDSP)\cdatecnv.cpp \ + $(TMPCDSP)\cinvsary.cpp \ + $(TMPCDSP)\cinvval.cpp \ + $(TMPCDSP)\cinvref.cpp \ + $(TMPCDSP)\cinvex.cpp \ + $(TMPCDSP)\cnls.cpp \ + $(TMPCDSP)\csarray.cpp \ + $(TMPCDSP)\ctime.cpp \ + $(TMPCDSP)\cvariant.cpp \ + $(TMPCDSP)\macmain.cpp \ + $(TMPCDSP)\misc.cpp \ + $(TMPCDSP)\suite.cpp \ + $(TMPCDSP)\cdisptst.r \ + $(TMPCDSP)\makefile.tmp + + +#--------------------------------------------------------------------- +# default rules +#--------------------------------------------------------------------- + +##### tests\common + +{$(SRCCOMN)}.h{$(TMPCOMN)}.h: + $(CP2MAC) $< $(MACCOMN)$(@F) + echo $(@F) > $@ + +{$(SRCCOMN)}.c{$(TMPCOMN)}.c: + $(CP2MAC) $< $(MACCOMN)$(@F) + echo $(@F) > $@ + +{$(SRCCOMN)}.cpp{$(TMPCOMN)}.cpp: + $(CP2MAC) $< $(MACCOMN)$(@F) + echo $(@F) > $@ + + +##### tests\disptest + +{$(SRCCDSP)}.h{$(TMPCDSP)}.h: + $(CP2MAC) $< $(MACCDSP)$(@F) + echo $(@F) > $@ + +{$(SRCCDSP)}.c{$(TMPCDSP)}.c: + $(CP2MAC) $< $(MACCDSP)$(@F) + echo $(@F) > $@ + +{$(SRCCDSP)}.cpp{$(TMPCDSP)}.cpp: + $(CP2MAC) $< $(MACCDSP)$(@F) + echo $(@F) > $@ + + +#--------------------------------------------------------------------- +# common test sources +#--------------------------------------------------------------------- + +$(TMPCOMN)\assrtdlg.h : $(SRCCOMN)\assrtdlg.h + +$(TMPCOMN)\cdisp.h : $(SRCCOMN)\cdisp.h + +$(TMPCOMN)\common.h : $(SRCCOMN)\common.h + +$(TMPCOMN)\crempoly.h : $(SRCCOMN)\crempoly.h + +$(TMPCOMN)\cunk.h : $(SRCCOMN)\cunk.h + +$(TMPCOMN)\dballoc.h : $(SRCCOMN)\dballoc.h + +$(TMPCOMN)\dispdbug.h : $(SRCCOMN)\dispdbug.h + +$(TMPCOMN)\disphelp.h : $(SRCCOMN)\disphelp.h + +$(TMPCOMN)\testhelp.h : $(SRCCOMN)\testhelp.h + +$(TMPCOMN)\assert.cpp : $(SRCCOMN)\assert.cpp + +$(TMPCOMN)\cdisp.cpp : $(SRCCOMN)\cdisp.cpp + +$(TMPCOMN)\crempoly.cpp : $(SRCCOMN)\crempoly.cpp + +$(TMPCOMN)\cunk.cpp : $(SRCCOMN)\cunk.cpp + +$(TMPCOMN)\dispdbug.cpp : $(SRCCOMN)\dispdbug.cpp + +$(TMPCOMN)\dballoc.cpp : $(SRCCOMN)\dballoc.cpp + +$(TMPCOMN)\disphelp.cpp : $(SRCCOMN)\disphelp.cpp + +$(TMPCOMN)\testhelp.cpp : $(SRCCOMN)\testhelp.cpp + +$(TMPCOMN)\util.cpp : $(SRCCOMN)\util.cpp + + +#--------------------------------------------------------------------- +# cdisptst sources +#--------------------------------------------------------------------- + +$(TMPCDSP)\clsid.h : $(SRCCDSP)\clsid.h + +$(TMPCDSP)\disptest.h : $(SRCCDSP)\disptest.h + +$(TMPCDSP)\macmain.h : $(SRCCDSP)\macmain.h + +$(TMPCDSP)\oleguids.h : $(SRCCDSP)\oleguids.h + +$(TMPCDSP)\resource.h : $(SRCCDSP)\resource.h + +$(TMPCDSP)\tstsuite.h : $(SRCCDSP)\tstsuite.h + +$(TMPCDSP)\guid.c : $(SRCCDSP)\guid.c + +$(TMPCDSP)\oleguids.c : $(SRCCDSP)\oleguids.c + +$(TMPCDSP)\cbind.cpp : $(SRCCDSP)\cbind.cpp + +$(TMPCDSP)\cbstr.cpp : $(SRCCDSP)\cbstr.cpp + +$(TMPCDSP)\ccollect.cpp : $(SRCCDSP)\ccollect.cpp + +$(TMPCDSP)\cdatecnv.cpp : $(SRCCDSP)\cdatecnv.cpp + +$(TMPCDSP)\cinvsary.cpp : $(SRCCDSP)\cinvsary.cpp + +$(TMPCDSP)\cinvval.cpp : $(SRCCDSP)\cinvval.cpp + +$(TMPCDSP)\cinvref.cpp : $(SRCCDSP)\cinvref.cpp + +$(TMPCDSP)\cinvex.cpp : $(SRCCDSP)\cinvex.cpp + +$(TMPCDSP)\cnls.cpp : $(SRCCDSP)\cnls.cpp + +$(TMPCDSP)\csarray.cpp : $(SRCCDSP)\csarray.cpp + +$(TMPCDSP)\ctime.cpp : $(SRCCDSP)\ctime.cpp + +$(TMPCDSP)\cvariant.cpp : $(SRCCDSP)\cvariant.cpp + +$(TMPCDSP)\macmain.cpp : $(SRCCDSP)\macmain.cpp + +$(TMPCDSP)\misc.cpp : $(SRCCDSP)\misc.cpp + +$(TMPCDSP)\suite.cpp : $(SRCCDSP)\suite.cpp + +$(TMPCDSP)\cdisptst.r : $(SRCCDSP)\cdisptst.r + $(CP2MAC) $(SRCCDSP)\cdisptst.r $(MACCDSP)$(@F) + echo $(@F) > $@ + +$(TMPCDSP)\makefile.tmp : $(SRCCDSP)\makefile.mpw + mungemak $(SRCCDSP)\makefile.mpw > $(TMPCDSP)\makefile.tmp + $(CP2MAC) $(TMPCDSP)\makefile.tmp $(MACCDSP)makefile + diff --git a/private/oleauto/tests/disptest/suite.cpp b/private/oleauto/tests/disptest/suite.cpp new file mode 100644 index 000000000..d38eaedbb --- /dev/null +++ b/private/oleauto/tests/disptest/suite.cpp @@ -0,0 +1,590 @@ +/*** +*suite.cpp +* +* Copyright (C) 1992-93, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* This module contains the test suite drivers. +* +*Revision History: +* +* [00] 29-Apr-93 bradlo: Added header. +* +*Implementation Notes: +* +*****************************************************************************/ + +#include <stdio.h> + +#include "disptest.h" +#include "tstsuite.h" + +ASSERTDATA + + +#if OE_MAC +typedef void* HWND; +#endif + +#if !OE_MAC +extern HINSTANCE g_hinst; +#endif + +struct TEST_INFO { + HRESULT hresult; + HWND hwnd; + BSTR bstr; + + ITestSuite FAR * ptst; + + TEST_INFO () { + hresult = NOERROR; + hwnd = NULL; + bstr = NULL; + ptst = NULL; + } +}; + +extern int g_fLog; + +STDAPI_(void) +PassFail(HRESULT hresult, OLECHAR FAR* szCaption, HWND hwnd) +{ + SCODE sc; + TCHAR buf[80]; + + sc = GetScode(hresult); + // E_ABORT indicates the test was aborted by the user, so we do nothing. + if(sc == E_ABORT) + return; + SPRINTF(buf, + HC_MPW ? TSTR("%s : %s") : TSTR("%Fs : %Fs"), + (TCHAR FAR*)(FAILED(sc) ? TSTR("FAIL") : TSTR("PASS")), + DbSzOfScode(sc)); + + DbPrintf( + HC_MPW ? "DT : %s ==> %s\n" : "DT : %Fs ==> %Fs\n", + szCaption == NULL ? "" : (char FAR*) STRING(szCaption), (char FAR*)buf); + +#if OE_MAC + UNUSED(hwnd); +#else + MessageBox(hwnd, buf, STRING(szCaption), MB_OK); +#endif +} + +#if !OE_MAC /* { */ + +int g_nPercent = 0; +BOOL g_fCancel = FALSE; + +void PASCAL +PaintTheGuage(HWND hwndDlg) +{ + RECT rc; + HDC hdc; + int width; + HBRUSH hbrush; + HWND hwndGuage; + + hwndGuage = GetDlgItem(hwndDlg, IDD_SUITE_GUAGE); + + hdc = GetDC(hwndGuage); + + GetClientRect(hwndGuage, &rc); + + // draw the border + // + hbrush = CreateSolidBrush(RGB(255, 255, 255)); + hbrush = (HBRUSH)SelectObject(hdc, hbrush); + Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom); + DeleteObject(SelectObject(hdc, hbrush)); + + // leave room for the border + // + rc.left++, rc.top++, rc.right--, rc.bottom--; + + // compute the ammount of the guage rect to fill + // + width = ((rc.right - rc.left) * g_nPercent) / 100; + rc.right = rc.left + width; + + // fill the guage + // + hbrush = CreateSolidBrush(RGB(0, 0, 255)); // Blue brush + FillRect(hdc, &rc, hbrush); + DeleteObject(hbrush); + + ReleaseDC(hwndGuage, hdc); +} + + +extern "C" BOOL CALLBACK EXPORT +SuiteDlgProc(HWND hwndDlg, unsigned message, WORD wparam, LONG lparam) +{ + switch(message){ + case WM_INITDIALOG: + return TRUE; + + case WM_COMMAND: + if(wparam == IDCANCEL){ + g_fCancel = TRUE; + return TRUE; + } + break; + + case WM_PAINT: + PaintTheGuage(hwndDlg); + break; + } + + return FALSE; +} + + +void PASCAL +ProgressYield(HWND hwnd) +{ + MSG msg; + + // empty the message loop... + while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){ + if(!hwnd || !IsDialogMessage(hwnd, &msg)){ + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } +} + +#endif /* } */ + + +// Open a logfile for the given suite, in the directory that the +// test app lives. +// + +#if defined(WIN32) + #define GETMODULEFILENAME GetModuleFileNameA +#else + #define GETMODULEFILENAME GetModuleFileName +#endif + +HFILE +OpenLogFile(ITestSuite FAR* ptst) +{ + BSTR bstr; + HFILE hfile; + char szModuleName[512], FAR* p, FAR* q; + char buf[256]; + + bstr = NULL; + hfile = HFILE_ERROR; + +#if OE_WIN + int cb; + if((cb = GETMODULEFILENAME(g_hinst, szModuleName,sizeof(szModuleName)))==0) + goto LError0; /* couldn't get the module name */ +#endif + + // get the logfile name for this suite + if(ptst->GetNameOfLogfile(&bstr) != NOERROR) + goto LError0; + +#if OE_WIN + // backup to the first path separator (ie, backup over the .exe name) + for(p = &szModuleName[cb]; p > szModuleName; --p){ + if(*p == '\\'){ + ++p; + break; + } + } +#else + p = szModuleName; +#endif + + // tack the logfile name onto the end of the path +#if OE_WIN32 + for(q = ConvertStrWtoA(bstr, buf); *q != '\0';) +#else + for(q = bstr; *q != '\0';) +#endif + *p++ = *q++; + *p = '\0'; + +#if OE_WIN + OFSTRUCT of; + hfile = OpenFile(szModuleName, &of, OF_CREATE); +#else + hfile = fopen(szModuleName, "w"); +#endif + +LError0:; + SysFreeString(bstr); + + return hfile; +} + +/*** +*HRESULT DispTestDoSuite(ITestSuite*, HWND) +*Purpose: +* Execute all tests in the given suite. +* +*Entry: +* ptst = the ITestSuite* to execute tests from +* hwnd = HWND of the parent window +* +*Exit: +* return value = HRESULT +* +***********************************************************************/ +HRESULT +DispTestDoSuite(ITestSuite FAR* ptst, HWND hwnd) +{ + BSTR bstr; + HRESULT hresult; + unsigned int i, cTests; + +#if !OE_MAC + TCHAR buf[32]; + HWND hwndSuiteDlg; + +#if OE_WIN16 +static DLGPROC pfnSuiteDlgProc; +#endif // OE_WIN16 +#endif + +#if OE_MAC + UNUSED(hwnd); +#endif + +#if !OE_MAC + g_fCancel = FALSE; +#endif + + if(g_fLog){ + ASSERT(Pappdata()->m_hfLogfile == HFILE_ERROR); + if((Pappdata()->m_hfLogfile = OpenLogFile(ptst)) == HFILE_ERROR){ + hresult = RESULT(E_FAIL); + goto LError0; + } + } + + IfFailGo(ptst->GetNameOfSuite(&bstr), LError0); + IfFailGo(ptst->GetTestCount(&cTests), LError0); + PrintSuiteHeader(STRING(bstr)); + +#if OE_WIN + +#if OE_WIN16 + pfnSuiteDlgProc = + (DLGPROC)MakeProcInstance((DLGPROC)SuiteDlgProc, g_hinst); + + hwndSuiteDlg = CreateDialog(g_hinst, TSTR("SuiteDlg"), hwnd, pfnSuiteDlgProc); + +#else // !OE_WIN16 + hwndSuiteDlg = CreateDialog(g_hinst, TSTR("SuiteDlg"), hwnd, (DLGPROC)SuiteDlgProc); +#endif // !OE_WIN16 + + SetDlgItemText(hwndSuiteDlg, IDD_SUITE_NAME, STRING(bstr)); + ShowWindow(hwndSuiteDlg, SW_SHOW); +#endif + + SysFreeString(bstr); + + for(i = 0; i < cTests; ++i){ + IfFailGo(ptst->GetNameOfTest(i, &bstr), LError0); + PrintTestHeader(STRING(bstr)); +#if OE_WIN + SetDlgItemText(hwndSuiteDlg, IDD_SUITE_TESTNAME, STRING(bstr)); +#endif + SysFreeString(bstr); + +#if OE_WIN + g_nPercent = (i*100) / cTests; + SPRINTF(buf, TSTR("%d%%"), g_nPercent); + SetDlgItemText(hwndSuiteDlg, IDD_SUITE_PERCENT, buf); + PaintTheGuage(hwndSuiteDlg); +#endif + + // ** Execute the Test ** + // + IfFailGo(ptst->DoTest(i), LError0); + +#if OE_WIN + ProgressYield(hwndSuiteDlg); + if(g_fCancel == TRUE){ + hresult = RESULT(E_ABORT); + goto LError0; + } +#endif + } + +#if OE_WIN + g_nPercent = 100; + PaintTheGuage(hwndSuiteDlg); +#endif + + hresult = NOERROR; + +LError0:; +#if OE_WIN + if(hwndSuiteDlg) + DestroyWindow(hwndSuiteDlg); + +#if OE_WIN16 + FreeProcInstance(pfnSuiteDlgProc); +#endif // OE_WIN16 +#endif + + if(Pappdata()->m_hfLogfile != HFILE_ERROR){ +#if OE_MAC + fclose(Pappdata()->m_hfLogfile); +#else + _lclose(Pappdata()->m_hfLogfile); +#endif + Pappdata()->m_hfLogfile = HFILE_ERROR; + } + + return hresult; +} + +struct { + int idm; + ITestSuite FAR* (*create)(void); +} g_rgTestSuite[] = { +#if OE_MAC + { IDM_SUITE_BSTR, CBstrSuite::Create } + , { IDM_SUITE_TIME, CTimeSuite::Create } + , { IDM_SUITE_DATECNV, CDateCoersionSuite::Create } + , { IDM_SUITE_VARIANT, CVariantSuite::Create } + , { IDM_SUITE_SAFEARRAY, CSafeArraySuite::Create } + , { IDM_SUITE_NLS, CNlsSuite::Create } +// # if HC_MPW + , { IDM_SUITE_BIND, CBindSuite::Create } + , { IDM_SUITE_INVOKE_BYVAL, CInvokeByValSuite::Create } + , { IDM_SUITE_INVOKE_BYREF, CInvokeByRefSuite::Create } + , { IDM_SUITE_INVOKE_SAFEARRAY, CInvokeSafeArraySuite::Create } + , { IDM_SUITE_INVOKE_EXCEPINFO, CInvokeExcepinfoSuite::Create } + , { IDM_SUITE_COLLECTION, CCollectionSuite::Create } +// # endif +#else + { IDM_SUITE_BSTR, CBstrSuite::Create } + , { IDM_SUITE_TIME, CTimeSuite::Create } + , { IDM_SUITE_DATECNV, CDateCoersionSuite::Create } + , { IDM_SUITE_VARIANT, CVariantSuite::Create } + , { IDM_SUITE_SAFEARRAY, CSafeArraySuite::Create } + , { IDM_SUITE_NLS, CNlsSuite::Create } + , { IDM_SUITE_BIND, CBindSuite::Create } + , { IDM_SUITE_INVOKE_BYVAL, CInvokeByValSuite::Create } + , { IDM_SUITE_INVOKE_BYREF, CInvokeByRefSuite::Create } + , { IDM_SUITE_INVOKE_SAFEARRAY, CInvokeSafeArraySuite::Create } + , { IDM_SUITE_INVOKE_EXCEPINFO, CInvokeExcepinfoSuite::Create } + , { IDM_SUITE_COLLECTION, CCollectionSuite::Create } + , { IDM_SUITE_EARLY, CEarlySuite::Create } +#endif +}; + + +/*** +*PRIVATE ITestSuite *ITestSuiteFromIDM(int) +*Purpose: +* Create an ITestSuite* from the given message ID. +* +*Entry: +* idm = the message ID. +* +*Exit: +* return value = ITestSuite*, NULL if unable to create. +* +***********************************************************************/ +HRESULT +ITestSuiteFromIDM(int idm, ITestSuite FAR* FAR* pptst) +{ + int ix; + + for(ix = 0; ix < DIM(g_rgTestSuite); ++ix){ + if(g_rgTestSuite[ix].idm == idm){ + return((*pptst = g_rgTestSuite[ix].create()) != NULL + ? NOERROR : RESULT(E_OUTOFMEMORY)); + } + } + return RESULT(E_FAIL); // test suite not found +} + + +#if OE_WIN32 + +/*** +*DWORD ThreadDoSuite +*Purpose: +* Run a test inside it's own thread. +* +*Entry: +* Pointer to a TEST_INFO structure. +* +*Exit: +* returns 0. +* +***********************************************************************/ +DWORD ThreadDoSuite(LPDWORD lpdwParam) +{ + TEST_INFO FAR* ptinfo = (TEST_INFO FAR *)lpdwParam; + HRESULT hresult; + + hresult = OleInitialize(NULL); + ASSERT(SUCCEEDED(hresult)); + + if (InitAppData()) { + ptinfo->hresult = DispTestDoSuite(ptinfo->ptst, NULL); + ReleaseAppData(); + } + + OleUninitialize(); + + return 0; +} +#endif // OE_WIN32 + + +/*** +*HRESULT DispTestAll(HWND) +*Purpose: +* Execute All IDispatch tests in all suites. +* +*Entry: +* hwnd = window handle +* fShowDialog = TRUE if we should display a dialog on a failure. +* fMultiThread = TRUE if we should multithread the tests. +* +*Exit: +* return value = HRESULT +* +***********************************************************************/ +STDAPI +DispTestAll(HWND hwnd, int fShowDialog, int fMultiThread) +{ + int i; + HRESULT hresult = NOERROR; + + TEST_INFO rgtinfo[DIM(g_rgTestSuite)]; + +#if OE_WIN32 + HANDLE rghThread[DIM(g_rgTestSuite)]; + DWORD rgThreadId[DIM(g_rgTestSuite)]; + + HRESULT hRet; +#endif // OE_WIN32 + + // Set up all of the tests. + for(i = 0; i < DIM(g_rgTestSuite); ++i) { + rgtinfo[i].hwnd = hwnd; + rgtinfo[i].ptst = g_rgTestSuite[i].create(); + if(rgtinfo[i].ptst == NULL) { + hresult = RESULT(E_OUTOFMEMORY); + goto LError0; + } + + IfFailGo(rgtinfo[i].ptst->GetNameOfSuite(&rgtinfo[i].bstr), LError0); + } + + // Run the suites. + for(i = 0; i < DIM(g_rgTestSuite); ++i) { +#if OE_WIN32 + if (fMultiThread) { + rghThread[i] = CreateThread(NULL, + 0, + (LPTHREAD_START_ROUTINE)ThreadDoSuite, + &rgtinfo[i], + 0, + &rgThreadId[i]); + + if (rghThread[i] == NULL) { + hresult = ResultFromScode(E_OUTOFMEMORY); + break; + } + } + else +#endif // OE_WIN32 + { + rgtinfo[i].hresult = DispTestDoSuite(rgtinfo[i].ptst, hwnd); + + // E_ABORT means the test was aborted by the user. + // + if(GetScode(rgtinfo[i].hresult) == E_ABORT) { + hresult = ResultFromScode(E_ABORT); + goto LError0; + } + } + } + +#if OE_WIN32 + // Wait for all of the threads to finish. + if (fMultiThread) { + hRet = WaitForMultipleObjects(DIM(g_rgTestSuite), + rghThread, + TRUE, + INFINITE); + + ASSERT(SUCCEEDED(hRet)); + } +#endif // OE_WIN32 + + // Check the results. + for (i = 0; i < DIM(g_rgTestSuite) && fShowDialog; ++i) { + if (FAILED(rgtinfo[i].hresult)) { + PassFail(rgtinfo[i].hresult, rgtinfo[i].bstr, hwnd); + hresult = ResultFromScode(S_FALSE); + } + } + +LError0:; + for (i = 0; i < DIM(g_rgTestSuite) && rgtinfo[i].ptst; ++i) { + rgtinfo[i].ptst->Release(); + SysFreeString(rgtinfo[i].bstr); + } + + return hresult; +} + + +/*** +*PRIVATE HRESULT DispTestOne(int) +*Purpose: +* Execute the test suite associated with the given message ID. +* +*Entry: +* idm = the message id +* +*Exit: +* return value = HRESULT +* +***********************************************************************/ +STDAPI +DispTestOne(HWND hwnd, int idm) +{ + BSTR bstr; + HRESULT hresult; + ITestSuite FAR* ptst; + + ptst = NULL; + bstr = NULL; + + IfFailGo(ITestSuiteFromIDM(idm, &ptst), LError0); + + IfFailGo(ptst->GetNameOfSuite(&bstr), LError0); + + hresult = DispTestDoSuite(ptst, hwnd); + +LError0:; + PassFail(hresult, bstr, hwnd); + + if(bstr != NULL) + SysFreeString(bstr); + + if(ptst != NULL) + ptst->Release(); + + return hresult; +} + diff --git a/private/oleauto/tests/disptest/timer.c b/private/oleauto/tests/disptest/timer.c new file mode 100644 index 000000000..1b28ca802 --- /dev/null +++ b/private/oleauto/tests/disptest/timer.c @@ -0,0 +1,29 @@ +/*** +*timer.c - Timing functions. +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* +*Revision History: +* +* [00] 02-Oct-92 bradlo: Created. +* +*Implementation Notes: +* +*****************************************************************************/ + +#include <stdio.h> +#include <sys/timeb.h> + +double +GetTime() +{ + double secs; + struct _timeb t; + + _ftime(&t); + secs = t.time + (t.millitm/1000.0); + return secs; +} diff --git a/private/oleauto/tests/disptest/tstsuite.h b/private/oleauto/tests/disptest/tstsuite.h new file mode 100644 index 000000000..5fe433bd9 --- /dev/null +++ b/private/oleauto/tests/disptest/tstsuite.h @@ -0,0 +1,119 @@ +/*** +*tstsuite.h +* +* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. +* Information Contained Herein Is Proprietary and Confidential. +* +*Purpose: +* Definition of the ITestSuite interface. +* +*Revision History: +* +* [00] 30-Oct-92 bradlo: Created. +* +*Implementation Notes: +* +*****************************************************************************/ + +DEFINE_OLEGUID(IID_ITestSuite, 0x00020440, 0, 0); + +DECLARE_INTERFACE_(ITestSuite, IUnknown) +{ + + // IUnknown methods + // + STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppv) = 0; + STDMETHOD_(unsigned long, AddRef)(void) = 0; + STDMETHOD_(unsigned long, Release)(void) = 0; + + // Introduced methods + // + STDMETHOD(GetNameOfSuite)(BSTR FAR* pbstr) = 0; + STDMETHOD(GetNameOfLogfile)(BSTR FAR* pbstr) = 0; + STDMETHOD(GetTestCount)(unsigned int FAR* pcTests) = 0; + STDMETHOD(GetNameOfTest)(unsigned int iTest, BSTR FAR* pbstr) = 0; + STDMETHOD(DoTest)(unsigned int iTest) = 0; +}; + + +// Standard CTestSuite definition used by all TestSuite objects. +// +#define DEFINE_SUITE(CLASS) \ + class CLASS : public ITestSuite { \ + public: \ + static ITestSuite FAR* Create(void); \ + STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppv); \ + STDMETHOD_(unsigned long, AddRef)(void); \ + STDMETHOD_(unsigned long, Release)(void); \ + STDMETHOD(GetNameOfSuite)(BSTR FAR* pbstr); \ + STDMETHOD(GetNameOfLogfile)(BSTR FAR* pbstr); \ + STDMETHOD(GetTestCount)(unsigned int FAR* pcTests);\ + STDMETHOD(GetNameOfTest)(unsigned int iTest, BSTR FAR* pbstr); \ + STDMETHOD(DoTest)(unsigned int iTest); \ + private: \ + CLASS(); \ + ~CLASS(); \ + unsigned long m_refs; \ + } + +// Default creation an destruction routines +// used by all test suite objects. +// +#define SUITE_CONSTRUCTION_IMPL(CLASS) \ + CLASS::CLASS() \ + { m_refs = 0; } \ + CLASS::~CLASS() \ + { } \ + ITestSuite FAR* CLASS::Create() \ + { \ + CLASS FAR* pclass; \ + pclass = new FAR CLASS(); \ + if(pclass == NULL) \ + return NULL; \ + pclass->AddRef(); \ + return pclass; \ + } + + +// Default implementation of IUnknown used by +// all test suite objects. +// +#define SUITE_IUNKNOWN_IMPL(CLASS) \ + STDMETHODIMP CLASS::QueryInterface( \ + REFIID riid, void FAR* FAR* ppv) \ + { \ + if(!IsEqualIID(riid, IID_IUnknown)) \ + if(!IsEqualIID(riid, IID_ITestSuite)) \ + return RESULT(E_NOINTERFACE); \ + *ppv = this; \ + ++m_refs; \ + return NOERROR; \ + } \ + STDMETHODIMP_(unsigned long) CLASS::AddRef() \ + { return ++m_refs; } \ + STDMETHODIMP_(unsigned long) CLASS::Release() \ + { \ + if(--m_refs == 0){ \ + delete this; \ + return 0; \ + } \ + return m_refs; \ + } + + +DEFINE_SUITE(CBstrSuite); // cbstr.cpp +DEFINE_SUITE(CTimeSuite); // ctime.cpp +DEFINE_SUITE(CDateCoersionSuite); // cdatecnv.cpp +DEFINE_SUITE(CVariantSuite); // cvariant.cpp +DEFINE_SUITE(CSafeArraySuite); // csarray.cpp +DEFINE_SUITE(CNlsSuite); // cnls.cpp +DEFINE_SUITE(CBindSuite); // cbind.cpp +DEFINE_SUITE(CInvokeByValSuite); // cinvval.cpp +DEFINE_SUITE(CInvokeByRefSuite); // cinvref.cpp +DEFINE_SUITE(CInvokeMultipleSuite); // cinvmult.cpp +DEFINE_SUITE(CInvokeSafeArraySuite); // cinvsary.cpp +DEFINE_SUITE(CInvokeExcepinfoSuite); // cinvex.cpp +DEFINE_SUITE(CCollectionSuite); // ccollect.cpp +#if VBA2 +DEFINE_SUITE(CEarlySuite); // cearly.cpp +#endif |