home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Troubleshooting Netware Systems
/
CSTRIAL0196.BIN
/
attach
/
msj
/
v10n04
/
olecont.exe
/
CNTLITEM.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-01
|
28KB
|
952 lines
///////////////////////////////////////////////////////////////////////////
// CNTLITEM.CPP -- Implementation for the CControlItem class
#include "stdafx.h"
#include "cntlinfo.h"
#include "cntlitem.h"
#include "contdoc.h"
#include "resource.h"
/////////////////////////////////////////////////////////////////////////////
// Definitions
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
///////////////////////////////////////////////////////////////////////////
// struct BINDINFO
BINDINFO::~BINDINFO()
{
delete [] m_lpParamProps;
}
///////////////////////////////////////////////////////////////////////////
// class CControlItem
IMPLEMENT_SERIAL(CControlItem, COleClientItem, 0)
#define new DEBUG_NEW
///////////////////////////////////////////////////////////////////////////
// Constructors & Destructors
CControlItem::CControlItem(CContainerDoc* pContainerDoc)
: COleClientItem(pContainerDoc)
{
m_pConnPt = NULL;
m_pEventInfo = NULL;
m_pCtlDispatch = NULL;
// Setup Last Params Structure
m_LastParams.cArgs = m_LastParams.cNamedArgs = 0;
m_LastParams.rgvarg = NULL;
m_LastParams.rgdispidNamedArgs = NULL;
// Binding members
m_pConnPtrBind = NULL;
m_dwBindConnection = 0;
m_nBinds = 0;
m_pBindInfo = NULL;
}
CControlItem::~CControlItem()
{
if (m_pConnPtrBind != NULL)
{
m_pConnPtrBind->Release();
m_pConnPtrBind = NULL;
}
if (m_pBindInfo != NULL)
{
delete m_pBindInfo;
m_pBindInfo = NULL;
}
if (m_pCtlDispatch != NULL)
{
m_pCtlDispatch->Release();
m_pCtlDispatch = NULL;
}
if (m_LastParams.cArgs > 0)
CleanUpParams();
}
///////////////////////////////////////////////////////////////////////////
// Operations
/////////////////////////////////////////////////////////////////////////////
// CControlItem diagnostics
#ifdef _DEBUG
void CControlItem::AssertValid() const
{
COleClientItem::AssertValid();
}
void CControlItem::Dump(CDumpContext& dc) const
{
COleClientItem::Dump(dc);
}
#endif
/////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// Attributes
/////////////////////////////////////////////////////////////////////////////
// CControlItem interface map
BEGIN_INTERFACE_MAP(CControlItem, COleClientItem)
INTERFACE_PART(CControlItem, IID_IDispatch, AmbientProps)
INTERFACE_PART(CControlItem, IID_IPropertyNotifySink, PropertyNotifySink)
END_INTERFACE_MAP()
LPUNKNOWN CControlItem::GetInterfaceHook(const void FAR* iid)
{
//
// If requested IID is same as the one we looked up in the registry
// (see InitControlInfo), return pointer to our event handler code.
//
if (*(IID FAR*)iid == m_iidEvents)
return &m_xEventHandler;
return NULL;
}
///////////////////////////////////////////////////////////////////////////
// Overrides
BOOL CControlItem::FinishCreate(HRESULT hr)
{
BOOL bSuper = COleClientItem::FinishCreate(hr);
if (bSuper)
{
m_pView = ((CFrameWnd *)(AfxGetApp()->m_pMainWnd))->GetActiveView();
// Note we don't explicitly handle freezing events here, if we wished to,
// we would grab the OLE object and inform it that its events are frozen.
InitControlInfo();
InitBindInfo();
// Wire the control to our event handler
LPCONNECTIONPOINTCONTAINER lpContainer;
if (SUCCEEDED(m_lpObject->QueryInterface(
IID_IConnectionPointContainer,
(LPVOID FAR*)&lpContainer)))
{
ASSERT(lpContainer != NULL);
if (SUCCEEDED(lpContainer->FindConnectionPoint(m_iidEvents, &m_pConnPt)))
{
ASSERT(m_pConnPt != NULL);
m_pConnPt->Advise(&m_xEventHandler, &m_dwEventConnection);
}
if (SUCCEEDED(lpContainer->FindConnectionPoint(IID_IPropertyNotifySink, &m_pConnPtrBind)))
{
ASSERT(m_pConnPtrBind != NULL);
if (m_pConnPtrBind != NULL)
{
m_pConnPtrBind->Advise(&m_xPropertyNotifySink, &m_dwBindConnection);
}
}
lpContainer->Release();
}
}
return bSuper;
}
void CControlItem::Release(OLECLOSE dwCloseOption)
{
UINT nSt = GetItemState ();
if ((nSt == activeUIState) || (nSt == activeState) || (nSt == openState))
Close (OLECLOSE_NOSAVE);
if (m_pConnPt != NULL)
{
m_pConnPt->Unadvise(m_dwEventConnection);
m_pConnPt->Release();
}
if (m_pConnPtrBind != NULL)
{
m_pConnPtrBind->Unadvise(m_dwBindConnection);
m_pConnPtrBind->Release();
m_pConnPtrBind = NULL;
}
FreeControlInfo();
COleClientItem::Release(dwCloseOption);
}
///////////////////////////////////////////////////////////////////////////
// Implementation
LPUNKNOWN CControlItem::GetCtlInterface(IID iidRequested)
{
LPUNKNOWN lpUnknown = NULL;
if (m_lpObject != NULL)
{
IID iidUnknown = IID_IUnknown;
if (IsEqualIID(iidRequested, iidUnknown))
{
lpUnknown = m_lpObject;
lpUnknown->AddRef();
}
else
{
if (FAILED (m_lpObject->QueryInterface(iidRequested,
(LPVOID *) &lpUnknown)))
{
lpUnknown = NULL;
}
}
}
return lpUnknown;
}
void CControlItem::InitEventInfo(LPTYPEINFO lpTypeInfo)
{
LPTYPEATTR lpType = NULL;
LPFUNCDESC lpFuncDesc = NULL;
if (lpTypeInfo != NULL && SUCCEEDED(lpTypeInfo->GetTypeAttr(&lpType)))
{
m_iidEvents = lpType->guid;
m_nEvents = lpType->cFuncs;
if (m_nEvents > 0)
{
TRY
{
m_pEventInfo = new EVENTINFO[m_nEvents];
USHORT nCount;
//
// Enumerate events, getting their member id's and names
//
for (nCount = 0; nCount < m_nEvents; nCount++)
{
m_pEventInfo[nCount].memid = -1;
m_pEventInfo[nCount].cParams = 0;
m_pEventInfo[nCount].pbstr = NULL;
if (SUCCEEDED(lpTypeInfo->GetFuncDesc(nCount, &lpFuncDesc)))
{
m_pEventInfo[nCount].memid = lpFuncDesc->memid;
m_pEventInfo[nCount].cParams = lpFuncDesc->cParams;
m_pEventInfo[nCount].pbstr = new BSTR[lpFuncDesc->cParams+1];
UINT cNames;
lpTypeInfo->GetNames(lpFuncDesc->memid, m_pEventInfo[nCount].pbstr,
lpFuncDesc->cParams+1, &cNames);
ASSERT((unsigned)lpFuncDesc->cParams+1 == cNames);
lpTypeInfo->ReleaseFuncDesc(lpFuncDesc);
lpFuncDesc = NULL;
}
}
}
CATCH(CMemoryException, e)
{
if (lpType != NULL)
lpTypeInfo->ReleaseTypeAttr(lpType);
if (lpFuncDesc != NULL)
lpTypeInfo->ReleaseFuncDesc(lpFuncDesc);
lpType = NULL;
lpFuncDesc = NULL;
}
END_CATCH
}
lpTypeInfo->ReleaseTypeAttr(lpType);
lpType = NULL;
}
}
void CControlItem::InitBindInfo()
{
LPTYPEINFO lpTypeInfo = NULL;
LPTYPEATTR lpType = NULL;
LPVARDESC lpVarDesc = NULL;
TRY
{
m_pBindInfo = new BINDINFO;
ASSERT(m_pBindInfo != NULL);
m_pCtlDispatch = (LPDISPATCH) GetCtlInterface(IID_IDispatch);
if (m_pCtlDispatch != NULL)
{
UINT nTypeCount = 0;
if ((SUCCEEDED(m_pCtlDispatch->GetTypeInfoCount(&nTypeCount))) && (nTypeCount == 1))
{
if (SUCCEEDED(m_pCtlDispatch->GetTypeInfo(0, GetUserDefaultLCID(), &lpTypeInfo)))
{
if (SUCCEEDED(lpTypeInfo->GetTypeAttr(&lpType)))
{
if ((m_pBindInfo->m_nParamCount = lpType->cVars) != 0)
{
m_pBindInfo->m_lpParamProps = new PARAMPROPINFO [m_pBindInfo->m_nParamCount];
ASSERT(m_pBindInfo->m_lpParamProps != NULL);
UINT nDesc = 0;
UINT nParam = 0;
while (nParam < m_pBindInfo->m_nParamCount)
{
lpTypeInfo->GetVarDesc(nDesc++, &lpVarDesc);
ASSERT(lpVarDesc != NULL);
if (lpVarDesc->varkind == VAR_DISPATCH)
{
LPPARAMPROPINFO lpParam = &m_pBindInfo->m_lpParamProps[nParam];
lpParam->id = lpVarDesc->memid;
BSTR bstr = NULL;
UINT nNameCount;
lpTypeInfo->GetNames(lpParam->id, &bstr, 1, &nNameCount);
ASSERT (nNameCount == 1);
if (nNameCount > 0)
{
char sz[80];
wcstombs(sz,
(const unsigned short*) bstr, 80);
lpParam->strName = sz;
}
::SysFreeString(bstr);
bstr = NULL;
nParam++;
}
else
{
m_pBindInfo->m_nParamCount--;
}
lpTypeInfo->ReleaseVarDesc(lpVarDesc);
lpVarDesc = NULL;
}
}
lpTypeInfo->ReleaseTypeAttr(lpType);
lpType = NULL;
}
lpTypeInfo->Release();
lpTypeInfo = NULL;
}
m_pCtlDispatch->Release();
m_pCtlDispatch = NULL;
}
else
{
TRACE(_T("Controls primary IDispatch could not be found!\n"));
AfxThrowMemoryException(); // force cleanup
}
}
}
CATCH(CMemoryException, e)
{
if (m_pCtlDispatch != NULL)
{
m_pCtlDispatch->Release();
m_pCtlDispatch = NULL;
}
if (lpTypeInfo != NULL)
{
if (lpType != NULL)
lpTypeInfo->ReleaseTypeAttr(lpType);
if (lpVarDesc != NULL)
lpTypeInfo->ReleaseVarDesc(lpVarDesc);
lpTypeInfo->Release();
}
lpTypeInfo = NULL;
lpType = NULL;
lpVarDesc = NULL;
}
END_CATCH
}
void CControlItem::InitControlInfo()
{
//
// Use the control's class info to obtain information about
// its events, etc.
//
ASSERT_VALID(this);
ASSERT(m_lpObject != NULL);
LPPROVIDECLASSINFO lpProvide = NULL;
if (SUCCEEDED(m_lpObject->QueryInterface(
IID_IProvideClassInfo,
(LPVOID FAR*)&lpProvide)))
{
ASSERT(lpProvide != NULL);
LPTYPEINFO lpClassInfo = NULL;
if (SUCCEEDED(lpProvide->GetClassInfo(&lpClassInfo)))
{
ASSERT(lpClassInfo != NULL);
LPTYPEATTR lpType;
if (SUCCEEDED(lpClassInfo->GetTypeAttr(&lpType)))
{
ASSERT(lpType != NULL);
ASSERT(lpType->typekind == TKIND_COCLASS);
UINT nCount;
int iFlags;
HREFTYPE hRefType;
//
// Search for typeinfo of the default events interface.
//
for (nCount = 0; nCount < lpType->cImplTypes; nCount++)
{
if (SUCCEEDED(lpClassInfo->GetImplTypeFlags(nCount, &iFlags)) &&
((iFlags & IMPLTYPE_MASK) == IMPLTYPE_DEFAULTSOURCE))
{
LPTYPEINFO lpTypeInfo = NULL;
if (SUCCEEDED(lpClassInfo->GetRefTypeOfImplType(nCount, &hRefType)) &&
SUCCEEDED(lpClassInfo->GetRefTypeInfo(hRefType, &lpTypeInfo)))
{
//
// Found it! Use it to initialize event table.
//
ASSERT(lpTypeInfo != NULL);
InitEventInfo(lpTypeInfo);
lpTypeInfo->Release();
lpTypeInfo = NULL;
}
break;
}
}
lpClassInfo->ReleaseTypeAttr(lpType);
lpType = NULL;
}
lpClassInfo->Release();
lpClassInfo = NULL;
}
lpProvide->Release();
}
}
void CControlItem::FreeControlInfo(void)
{
if (m_pEventInfo != NULL)
{
USHORT i;
for (i = 0; i < m_nEvents; i++)
if (m_pEventInfo[i].pbstr != NULL)
{
SHORT j;
for (j = 0; j < m_pEventInfo[i].cParams+1; j++)
::SysFreeString(m_pEventInfo[i].pbstr[j]);
delete [] m_pEventInfo[i].pbstr;
}
delete [] m_pEventInfo;
m_pEventInfo = NULL;
}
}
PARAMPROPINFO* CControlItem::GetParamPropInfo(DISPID id)
{
USHORT i;
for (i = 0; i < m_pBindInfo->m_nParamCount; i++)
if (id == m_pBindInfo->m_lpParamProps[i].id)
return &(m_pBindInfo->m_lpParamProps[i]);
return NULL;
}
EVENTINFO* CControlItem::GetEventInfo(MEMBERID memid)
{
USHORT i;
for (i = 0; i < m_nEvents; i++)
if (memid == m_pEventInfo[i].memid)
return &m_pEventInfo[i];
return NULL;
}
void CControlItem::CleanUpParams()
{
ASSERT_VALID(this);
DISPPARAMS FAR* lpDispparams = &m_LastParams;
if (lpDispparams->rgvarg != NULL)
{
for (UINT i=0; i<lpDispparams->cArgs; i++)
{
switch(lpDispparams->rgvarg[i].vt)
{
case VT_BSTR:
::SysFreeString(lpDispparams->rgvarg[i].bstrVal);
break;
case VT_DISPATCH:
lpDispparams->rgvarg[i].pdispVal->Release();
break;
case VT_UNKNOWN:
lpDispparams->rgvarg[i].punkVal->Release();
break;
default:
break;
}
}
delete lpDispparams->rgvarg;
}
lpDispparams->rgvarg = NULL;
if (lpDispparams->rgdispidNamedArgs != NULL)
delete lpDispparams->rgdispidNamedArgs;
lpDispparams->rgdispidNamedArgs = NULL;
}
void CControlItem::CopyParams(DISPPARAMS FAR* lpDispparams)
{
UINT i;
if (lpDispparams == NULL)
return; // can't copy bogus params
if (m_LastParams.cArgs > 0)
CleanUpParams();
// Change state information about incoming
m_LastParams.cArgs = lpDispparams->cArgs;
if (lpDispparams->cArgs == 0)
m_LastParams.rgvarg = NULL;
else
m_LastParams.rgvarg = new VARIANTARG[lpDispparams->cArgs];
m_LastParams.cNamedArgs = lpDispparams->cNamedArgs;
if(lpDispparams->cNamedArgs == 0)
m_LastParams.rgdispidNamedArgs = NULL;
else
{
m_LastParams.rgdispidNamedArgs = new DISPID[lpDispparams->cNamedArgs];
for(i = 0; i < m_LastParams.cNamedArgs; ++i)
m_LastParams.rgdispidNamedArgs[i] = lpDispparams->rgdispidNamedArgs[i];
}
for (i = 0; i < m_LastParams.cArgs; i++)
{
// Copy Parameter type
m_LastParams.rgvarg[i].vt = lpDispparams->rgvarg[i].vt;
switch(lpDispparams->rgvarg[i].vt)
{
case VT_I2:
m_LastParams.rgvarg[i].iVal = lpDispparams->rgvarg[i].iVal;
break;
case VT_I4:
m_LastParams.rgvarg[i].lVal = lpDispparams->rgvarg[i].lVal;
break;
case VT_R4:
m_LastParams.rgvarg[i].fltVal = lpDispparams->rgvarg[i].fltVal;
break;
case VT_R8:
m_LastParams.rgvarg[i].dblVal = lpDispparams->rgvarg[i].dblVal;
break;
case VT_BOOL:
m_LastParams.rgvarg[i].bool = lpDispparams->rgvarg[i].bool;
break;
case VT_ERROR:
m_LastParams.rgvarg[i].scode = lpDispparams->rgvarg[i].scode;
break;
case VT_CY:
m_LastParams.rgvarg[i].cyVal = lpDispparams->rgvarg[i].cyVal;
break;
case VT_DATE:
m_LastParams.rgvarg[i].date = lpDispparams->rgvarg[i].date;
break;
case VT_BSTR:
m_LastParams.rgvarg[i].bstrVal = ::SysAllocString(lpDispparams->rgvarg[i].bstrVal);
break;
case VT_UNKNOWN:
m_LastParams.rgvarg[i].punkVal = lpDispparams->rgvarg[i].punkVal;
break;
case VT_DISPATCH:
m_LastParams.rgvarg[i].pdispVal = lpDispparams->rgvarg[i].pdispVal;
break;
case (VT_I2 | VT_BYREF):
m_LastParams.rgvarg[i].piVal = lpDispparams->rgvarg[i].piVal;
break;
case (VT_I4 | VT_BYREF):
m_LastParams.rgvarg[i].plVal = lpDispparams->rgvarg[i].plVal;
break;
case (VT_R4 | VT_BYREF):
m_LastParams.rgvarg[i].pfltVal = lpDispparams->rgvarg[i].pfltVal;
break;
case (VT_R8 | VT_BYREF):
m_LastParams.rgvarg[i].pdblVal = lpDispparams->rgvarg[i].pdblVal;
break;
case (VT_BOOL | VT_BYREF):
m_LastParams.rgvarg[i].pbool = lpDispparams->rgvarg[i].pbool;
break;
case (VT_ERROR | VT_BYREF):
m_LastParams.rgvarg[i].pscode = lpDispparams->rgvarg[i].pscode;
break;
case (VT_CY | VT_BYREF):
m_LastParams.rgvarg[i].pcyVal = lpDispparams->rgvarg[i].pcyVal;
break;
case (VT_DATE | VT_BYREF):
m_LastParams.rgvarg[i].pdate = lpDispparams->rgvarg[i].pdate;
break;
case (VT_BSTR | VT_BYREF):
m_LastParams.rgvarg[i].pbstrVal = lpDispparams->rgvarg[i].pbstrVal;
break;
case (VT_VARIANT | VT_BYREF):
m_LastParams.rgvarg[i].pvarVal = lpDispparams->rgvarg[i].pvarVal;
break;
case (VT_UNKNOWN | VT_BYREF):
m_LastParams.rgvarg[i].ppunkVal = lpDispparams->rgvarg[i].ppunkVal;
break;
case (VT_DISPATCH | VT_BYREF):
m_LastParams.rgvarg[i].ppdispVal = lpDispparams->rgvarg[i].ppdispVal;
break;
default:
break;
}
}
}
/////////////////////////////////////////////////////////////////////////////
// Callbacks
void CControlItem::OnEvent(DISPID dispID, DISPPARAMS FAR* lpDispparams)
{
// Just set the dispid and dispparams pointers to the latest information
m_EventID = dispID;
CopyParams(lpDispparams);
// find the event
EVENTINFO* pEvent = GetEventInfo(m_EventID);
if (pEvent == NULL)
{
TRACE1("Unknown event ID: %u\n", m_EventID);
return;
}
CString strMsg;
char sz[80];
unsigned nParameter;
wcstombs(sz,
(const unsigned short*) pEvent->pbstr[0], ELEMENTS(sz));
strMsg.Format(_T("%s("), sz);
for (nParameter = 1; nParameter <= m_LastParams.cArgs;
nParameter++)
{
wcstombs(sz, (const unsigned short*)
pEvent->pbstr[nParameter], ELEMENTS(sz));
if (nParameter > 1)
strMsg += _T(", ");
strMsg += sz;
strMsg += _T("= ");
}
strMsg += _T(")");
TRACE(strMsg);
TRACE(_T("\n"));
m_pView->MessageBox(strMsg, _T("CControlItem::OnEvent"), MB_OK);
}
HRESULT CControlItem::OnPropertyNotification(DISPID dispID, UINT idsOccurence)
{
CString strMsg;
PARAMPROPINFO* pInfo = GetParamPropInfo(dispID);
if (pInfo == NULL)
{
strMsg.Format(_T("%s: Unknown DISPID = %d"),
(idsOccurence == IDS_BOUNDPROP_REQEDIT) ? _T("Edit Request") : _T("Change Notify"),
dispID);
}
else
{
strMsg.Format(_T("%s: %s"),
(idsOccurence == IDS_BOUNDPROP_REQEDIT) ? _T("Edit Request") : _T("Change Notify"),
pInfo->strName);
}
TRACE(strMsg);
TRACE(_T("\n"));
m_pView->MessageBox(strMsg,
_T("CControlItem::OnPropertyNotifcation()"), MB_OK);
return NOERROR;
}
/////////////////////////////////////////////////////////////////////////////
// CControlItem::XEventHandler
STDMETHODIMP_(ULONG) CControlItem::XEventHandler::AddRef()
{
METHOD_PROLOGUE(CControlItem, EventHandler)
return (ULONG)pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG) CControlItem::XEventHandler::Release()
{
METHOD_PROLOGUE(CControlItem, EventHandler)
return (ULONG)pThis->ExternalRelease();
}
STDMETHODIMP CControlItem::XEventHandler::QueryInterface(
REFIID iid, LPVOID far* ppvObj)
{
METHOD_PROLOGUE(CControlItem, EventHandler)
return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
}
STDMETHODIMP CControlItem::XEventHandler::GetTypeInfoCount(unsigned int FAR* pctinfo)
{
METHOD_PROLOGUE(CControlItem, EventHandler)
ASSERT_VALID(pThis);
*pctinfo = 0;
return NOERROR;
}
STDMETHODIMP CControlItem::XEventHandler::GetTypeInfo(unsigned int itinfo,
LCID lcid, ITypeInfo FAR* FAR* pptinfo)
{
METHOD_PROLOGUE(CControlItem, EventHandler)
ASSERT_VALID(pThis);
return ResultFromScode(E_NOTIMPL);
}
STDMETHODIMP CControlItem::XEventHandler::GetIDsOfNames(REFIID riid,
LPTSTR FAR* rgszNames, unsigned int cNames, LCID lcid,
DISPID FAR* rgdispid)
{
METHOD_PROLOGUE(CControlItem, EventHandler)
ASSERT_VALID(pThis);
return ResultFromScode(E_NOTIMPL);
}
STDMETHODIMP CControlItem::XEventHandler::Invoke(DISPID dispidMember,
REFIID riid, LCID lcid, unsigned short wFlags, DISPPARAMS FAR* lpDispparams,
VARIANT FAR* pvarResult, EXCEPINFO FAR* pexcepinfo,
unsigned int FAR* puArgErr)
{
METHOD_PROLOGUE(CControlItem, EventHandler)
ASSERT_VALID(pThis);
pThis->OnEvent(dispidMember, lpDispparams); // Call the event handler, who also cleans up.
return NOERROR;
}
/////////////////////////////////////////////////////////////////////////////
// CControlItem::XPropertyNotifySink
STDMETHODIMP_(ULONG) CControlItem::XPropertyNotifySink::AddRef()
{
METHOD_PROLOGUE(CControlItem, PropertyNotifySink)
return (ULONG)pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG) CControlItem::XPropertyNotifySink::Release()
{
METHOD_PROLOGUE(CControlItem, PropertyNotifySink)
return (ULONG)pThis->ExternalRelease();
}
STDMETHODIMP CControlItem::XPropertyNotifySink::QueryInterface(
REFIID iid, LPVOID far* ppvObj)
{
METHOD_PROLOGUE(CControlItem, PropertyNotifySink)
return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
}
STDMETHODIMP CControlItem::XPropertyNotifySink::OnChanged(
DISPID dispid)
{
METHOD_PROLOGUE(CControlItem, PropertyNotifySink)
return (pThis->OnPropertyNotification(dispid, IDS_BOUNDPROP_CHANGED));
}
STDMETHODIMP CControlItem::XPropertyNotifySink::OnRequestEdit(
DISPID dispid)
{
METHOD_PROLOGUE(CControlItem, PropertyNotifySink)
return (pThis->OnPropertyNotification(dispid, IDS_BOUNDPROP_REQEDIT));
}
/////////////////////////////////////////////////////////////////////////////
// CControlItem::XAmbientProps
STDMETHODIMP_(ULONG) CControlItem::XAmbientProps::AddRef()
{
METHOD_PROLOGUE(CControlItem, AmbientProps)
return (ULONG)pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG) CControlItem::XAmbientProps::Release()
{
METHOD_PROLOGUE(CControlItem, AmbientProps)
return (ULONG)pThis->ExternalRelease();
}
STDMETHODIMP CControlItem::XAmbientProps::QueryInterface(
REFIID iid, LPVOID far* ppvObj)
{
METHOD_PROLOGUE(CControlItem, AmbientProps)
return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
}
STDMETHODIMP CControlItem::XAmbientProps::GetTypeInfoCount(unsigned int FAR* pctinfo)
{
METHOD_PROLOGUE(CControlItem, AmbientProps)
ASSERT_VALID(pThis);
*pctinfo = 0;
return NOERROR;
}
STDMETHODIMP CControlItem::XAmbientProps::GetTypeInfo(unsigned int itinfo,
LCID lcid, ITypeInfo FAR* FAR* pptinfo)
{
METHOD_PROLOGUE(CControlItem, AmbientProps)
ASSERT_VALID(pThis);
return ResultFromScode(E_NOTIMPL);
}
STDMETHODIMP CControlItem::XAmbientProps::GetIDsOfNames(REFIID riid,
LPTSTR FAR* rgszNames, unsigned int cNames, LCID lcid,
DISPID FAR* rgdispid)
{
METHOD_PROLOGUE(CControlItem, AmbientProps)
ASSERT_VALID(pThis);
UINT nIdx = 0;
CContainerDoc* pDoc = (CContainerDoc*)pThis->m_pDocument;
while (nIdx < cNames)
{
LPAPROP lpAprop = pDoc->FindAprop(rgszNames[nIdx]);
if (lpAprop)
{
rgdispid[nIdx] = lpAprop->dispid;
}
else
{
rgdispid[nIdx] = DISPID_UNKNOWN;
}
nIdx++;
}
return NOERROR;
}
STDMETHODIMP CControlItem::XAmbientProps::Invoke(DISPID dispidMember, REFIID riid,
LCID lcid, unsigned short wFlags, DISPPARAMS FAR* lpDispparams,
VARIANT FAR* pvarResult, EXCEPINFO FAR* pexcepinfo, unsigned int FAR* puArgErr)
{
METHOD_PROLOGUE(CControlItem, AmbientProps)
ASSERT_VALID(pThis);
HRESULT hr = ResultFromScode (DISP_E_MEMBERNOTFOUND);
CContainerDoc* pDoc = (CContainerDoc*)pThis->m_pDocument;
LPAPROP lpAprop = pDoc->FindAprop(dispidMember);
if (lpAprop)
{
TFVarCopy(pvarResult, &lpAprop->varValue);
hr = NOERROR;
}
return (hr);
}