460 lines
9.6 KiB
C++
460 lines
9.6 KiB
C++
/***
|
|
*cdualtst.cpp
|
|
*
|
|
* Copyright (C) 1994, Microsoft Corporation. All Rights Reserved.
|
|
* Information Contained Herein Is Proprietary and Confidential.
|
|
*
|
|
*Purpose:
|
|
* Implementation of the CDualTst, dual-interface test object.
|
|
*
|
|
*
|
|
*Revision History:
|
|
*
|
|
* [00] 27-Jun-94 Bradlo: Created.
|
|
*
|
|
*Implementation Notes:
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include "sdisptst.h"
|
|
#include "dispdbug.h"
|
|
#include "cdualtst.h"
|
|
|
|
ASSERTDATA
|
|
|
|
CDualTst::CDualTst()
|
|
{
|
|
m_cRefs = 0;
|
|
m_ptinfo = NULL;
|
|
|
|
m_ui1 = 0;
|
|
m_i2 = 0;
|
|
m_i4 = 0;
|
|
m_r4 = 0.0;
|
|
m_r8 = 0.0;
|
|
MEMSET(&m_cy, 0, sizeof(CY));
|
|
m_date = 0.0;
|
|
m_bstr = NULL;
|
|
m_pdisp = NULL;
|
|
VariantInit(&m_var);
|
|
}
|
|
|
|
CDualTst::~CDualTst()
|
|
{
|
|
if(m_ptinfo != NULL)
|
|
m_ptinfo->Release();
|
|
SysFreeString(m_bstr);
|
|
if(m_pdisp != NULL)
|
|
m_pdisp->Release();
|
|
VariantClear(&m_var);
|
|
}
|
|
|
|
HRESULT
|
|
CDualTst::Create(IUnknown FAR* punkOuter, IUnknown FAR* FAR* ppunk)
|
|
{
|
|
HRESULT hresult;
|
|
CDualTst FAR* pdual;
|
|
ITypeLib FAR* ptlib;
|
|
ITypeInfo FAR* ptinfo;
|
|
|
|
ptlib = NULL;
|
|
ptinfo = NULL;
|
|
*ppunk = NULL;
|
|
|
|
if(punkOuter != NULL)
|
|
return RESULT(CLASS_E_NOAGGREGATION);
|
|
|
|
if((pdual = new CDualTst()) == NULL)
|
|
return RESULT(E_OUTOFMEMORY);
|
|
pdual->AddRef();
|
|
|
|
// load & register the type library and the interfaces within the typelib
|
|
hresult = LoadTypeLib(OLESTR("sdisptst.exe"), &ptlib);
|
|
if(HRESULT_FAILED(hresult)){
|
|
// Work around the fact that LoadTypeLib may not leave
|
|
// ptlib == NULL if it fails...
|
|
ptlib = NULL;
|
|
goto Error;
|
|
}
|
|
|
|
IfFailGo(ptlib->GetTypeInfoOfGuid(IID_IDualTst, &ptinfo), Error);
|
|
|
|
pdual->m_ptinfo = ptinfo;
|
|
ptinfo = NULL;
|
|
|
|
*ppunk = (IUnknown FAR*)pdual;
|
|
pdual = NULL;
|
|
|
|
IncObjectCount(); // incriment count of global objects
|
|
|
|
hresult = NOERROR;
|
|
// FALLTHROUGH...
|
|
|
|
Error:;
|
|
if(ptinfo != NULL)
|
|
ptinfo->Release();
|
|
if(ptlib != NULL)
|
|
ptlib->Release();
|
|
if(pdual != NULL)
|
|
delete pdual;
|
|
return hresult;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CDualTst::QueryInterface(REFIID riid, void FAR* FAR* ppv)
|
|
{
|
|
if (riid == IID_IUnknown
|
|
|| riid == IID_IDispatch
|
|
|| riid == IID_IDualTst)
|
|
{
|
|
*ppv = this;
|
|
AddRef();
|
|
return NOERROR;
|
|
}
|
|
*ppv = NULL;
|
|
return RESULT(E_NOINTERFACE);
|
|
}
|
|
|
|
STDMETHODIMP_(unsigned long)
|
|
CDualTst::AddRef(void)
|
|
{
|
|
return ++m_cRefs;
|
|
}
|
|
|
|
STDMETHODIMP_(unsigned long)
|
|
CDualTst::Release(void)
|
|
{
|
|
if(--m_cRefs == 0){
|
|
DecObjectCount(); // decriment global count of objects
|
|
delete this;
|
|
return 0;
|
|
}
|
|
return m_cRefs;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CDualTst::GetTypeInfoCount(unsigned int FAR* pctinfo)
|
|
{
|
|
*pctinfo = 1;
|
|
return NOERROR;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CDualTst::GetTypeInfo(unsigned int itinfo,
|
|
LCID lcid,
|
|
ITypeInfo FAR* FAR* pptinfo)
|
|
{
|
|
ASSERT(m_ptinfo != NULL);
|
|
if(itinfo != 0)
|
|
return RESULT(TYPE_E_ELEMENTNOTFOUND);
|
|
m_ptinfo->AddRef();
|
|
*pptinfo = m_ptinfo;
|
|
return NOERROR;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CDualTst::GetIDsOfNames(REFIID riid,
|
|
OLECHAR FAR* FAR* rgszNames,
|
|
unsigned int cNames,
|
|
LCID lcid,
|
|
DISPID FAR* rgdispid)
|
|
{
|
|
ASSERT(m_ptinfo != NULL);
|
|
return m_ptinfo->GetIDsOfNames(rgszNames, cNames, rgdispid);
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CDualTst::Invoke(DISPID dispidMember,
|
|
REFIID riid,
|
|
LCID lcid,
|
|
unsigned short wFlags,
|
|
DISPPARAMS FAR* pdispparams,
|
|
VARIANT FAR* pvarResult,
|
|
EXCEPINFO FAR* pexcepinfo,
|
|
unsigned int FAR* puArgErr)
|
|
{
|
|
ASSERT(m_ptinfo != NULL);
|
|
return m_ptinfo->Invoke(this,
|
|
dispidMember,
|
|
wFlags,
|
|
pdispparams,
|
|
pvarResult,
|
|
pexcepinfo,
|
|
puArgErr);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::get_ui1(unsigned char FAR* pui1)
|
|
{
|
|
DoPrintf("CDualTst::get_ui1(*ret = %d)\n", (unsigned int)m_ui1);
|
|
*pui1 = m_ui1;
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::put_ui1(unsigned char ui1)
|
|
{
|
|
DoPrintf("CDualTst::put_ui1(%d)\n", (unsigned int)ui1);
|
|
m_ui1 = ui1;
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::get_i2(short FAR* pi2)
|
|
{
|
|
DoPrintf("CDualTst::get_i2(*ret = %d)\n", (int)m_i2);
|
|
*pi2 = m_i2;
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::put_i2(short i2)
|
|
{
|
|
DoPrintf("CDualTst::put_i2(%d)\n", (int)i2);
|
|
m_i2 = i2;
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::get_i4(long FAR* pi4)
|
|
{
|
|
DoPrintf("CDualTst::get_i4(*ret = %ld)\n", m_i4);
|
|
*pi4 = m_i4;
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::put_i4(long i4)
|
|
{
|
|
DoPrintf("CDualTst::put_i4(%d)\n", i4);
|
|
m_i4 = i4;
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::get_r4(float FAR* pr4)
|
|
{
|
|
DoPrintf("CDualTst::get_r4(*ret = %#f)\n", m_r4);
|
|
*pr4 = m_r4;
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::put_r4(float r4)
|
|
{
|
|
DoPrintf("CDualTst::put_r4(%#f)\n", r4);
|
|
m_r4 = r4;
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::get_r8(double FAR* pr8)
|
|
{
|
|
DoPrintf("CDualTst::get_r8(*ret = %#f)\n", m_r8);
|
|
*pr8 = m_r8;
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::put_r8(double r8)
|
|
{
|
|
DoPrintf("CDualTst::put_r8(%#f)\n", r8);
|
|
m_r8 = r8;
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::get_cy(CY FAR* pcy)
|
|
{
|
|
DoPrintf("CDualTst::get_cy(*ret = {hi=%ld,lo=%ld})\n", m_cy.Hi, m_cy.Lo);
|
|
MEMCPY(pcy, &m_cy, sizeof(CY));
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::put_cy(CY cy)
|
|
{
|
|
DoPrintf("CDualTst::put_cy({hi=%ld,lo=%ld})\n", cy.Hi, cy.Lo);
|
|
MEMCPY(&m_cy, &cy, sizeof(CY));
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::get_date(DATE FAR* pdate)
|
|
{
|
|
DoPrintf("CDualTst::get_date(*ret = %#f)\n", m_date);
|
|
*pdate = m_date;
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::put_date(DATE date)
|
|
{
|
|
DoPrintf("CDualTst::put_date(%#f)\n", date);
|
|
m_date = date;
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::get_bstr(BSTR FAR* pbstr)
|
|
{
|
|
DoPrintf("CDualTst::get_bstr(*ret = %Fs)\n", m_bstr);
|
|
// REVIEW: the following drops embedded nulls...
|
|
*pbstr = (m_bstr == NULL) ? NULL : SysAllocString(m_bstr);
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::put_bstr(BSTR bstr)
|
|
{
|
|
DoPrintf("CDualTst::put_bstr(%Fs)\n", bstr);
|
|
SysFreeString(m_bstr);
|
|
// REVIEW: the following drops embedded nulls...
|
|
m_bstr = (bstr == NULL) ? NULL : SysAllocString(bstr);
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::get_disp(IDispatch FAR* FAR* ppdisp)
|
|
{
|
|
DoPrintf("CDualTst::get_disp(*ret = ...)\n");
|
|
if(m_pdisp != NULL)
|
|
m_pdisp->AddRef();
|
|
*ppdisp = m_pdisp;
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::put_disp(IDispatch FAR* pdisp)
|
|
{
|
|
DoPrintf("CDualTst::put_disp(...)\n");
|
|
// UNDONE: need to implement 'Let' of object valued property
|
|
return RESULT(E_NOTIMPL);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::putref_disp(IDispatch FAR* pdisp)
|
|
{
|
|
DoPrintf("CDualTst::putref_disp(...)\n");
|
|
if(m_pdisp != NULL)
|
|
m_pdisp->Release();
|
|
if(pdisp != NULL)
|
|
pdisp->AddRef();
|
|
m_pdisp = pdisp;
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::get_var(VARIANT FAR* pvar)
|
|
{
|
|
DoPrintf("CDualTst::get_var(*ret.vt = %d)\n", m_var.vt);
|
|
return VariantCopy(pvar, &m_var);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::put_var(VARIANT var)
|
|
{
|
|
DoPrintf("CDualTst::put_var(var.vt = %d)\n", var.vt);
|
|
// UNDONE: the following isn't quite the correct implementation
|
|
// UNDONE: for 'Let' of a variant valued property...
|
|
return VariantCopy(&m_var, &var);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::putref_var(VARIANT var)
|
|
{
|
|
DoPrintf("CDualTst::putref_var(var.vt = %d)\n", var.vt);
|
|
return VariantCopy(&m_var, &var);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::m0(unsigned char ui1,
|
|
short i2,
|
|
long i4,
|
|
float r4,
|
|
double r8,
|
|
CY cy,
|
|
DATE date,
|
|
BSTR bstr,
|
|
IDispatch FAR* pdisp,
|
|
VARIANT var)
|
|
{
|
|
IfFailRet(put_ui1(ui1));
|
|
IfFailRet(put_i2(i2));
|
|
IfFailRet(put_i4(i4));
|
|
IfFailRet(put_r4(r4));
|
|
IfFailRet(put_r8(r8));
|
|
IfFailRet(put_cy(cy));
|
|
IfFailRet(put_date(date));
|
|
IfFailRet(put_bstr(bstr));
|
|
IfFailRet(putref_disp(pdisp));
|
|
IfFailRet(putref_var(var));
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::m1(unsigned char FAR* pui1,
|
|
short FAR* pi2,
|
|
long FAR* pi4,
|
|
float FAR* pr4,
|
|
double FAR* pr8,
|
|
CY FAR* pcy,
|
|
DATE FAR* pdate,
|
|
BSTR FAR* pbstr,
|
|
IDispatch FAR* FAR* ppdisp,
|
|
VARIANT FAR* pvar)
|
|
{
|
|
IfFailRet(put_ui1(*pui1));
|
|
IfFailRet(put_i2(*pi2));
|
|
IfFailRet(put_i4(*pi4));
|
|
IfFailRet(put_r4(*pr4));
|
|
IfFailRet(put_r8(*pr8));
|
|
IfFailRet(put_cy(*pcy));
|
|
IfFailRet(put_date(*pdate));
|
|
IfFailRet(put_bstr(*pbstr));
|
|
IfFailRet(putref_disp(*ppdisp));
|
|
IfFailRet(putref_var(*pvar));
|
|
|
|
*pui1 = 41;
|
|
*pi2 = 42;
|
|
*pi4 = 43;
|
|
*pr4 = 4.2;
|
|
*pr8 = 4.3;
|
|
pcy->Hi = 4; pcy->Lo = 2;
|
|
*pdate = 4.2;
|
|
*ppdisp = this;
|
|
VariantClear(pvar);
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CDualTst::raise(long error,
|
|
BSTR bstrSource,
|
|
BSTR bstrDescription,
|
|
long dwHelpContest,
|
|
BSTR bstrHelpFile)
|
|
{
|
|
IErrorInfo FAR* perrinfo;
|
|
ICreateErrorInfo FAR* pcerrinfo;
|
|
|
|
perrinfo = NULL;
|
|
pcerrinfo = NULL;
|
|
|
|
IfFailRet(CreateErrorInfo(&pcerrinfo));
|
|
pcerrinfo->SetSource(bstrSource);
|
|
pcerrinfo->SetDescription(bstrDescription);
|
|
pcerrinfo->SetHelpContext(dwHelpContest);
|
|
pcerrinfo->SetHelpFile(bstrHelpFile);
|
|
|
|
if(pcerrinfo->QueryInterface(IID_IErrorInfo, (void FAR* FAR*)&perrinfo) == NOERROR){
|
|
SetErrorInfo(0L, perrinfo);
|
|
}
|
|
|
|
if(perrinfo != NULL)
|
|
perrinfo->Release();
|
|
if(pcerrinfo != NULL)
|
|
pcerrinfo->Release();
|
|
return RESULT((SCODE)error);
|
|
}
|