📄 autoobj.cpp
字号:
WCHAR wszTmp[256];
// char szTmp[256];
HRESULT hr;
// first get the createerrorinfo object.
//
hr = CreateErrorInfo(&pCreateErrorInfo);
if (FAILED(hr)) return hrExcep;
// MAKE_WIDEPTR_FROMANSI(wszHelpFile, HELPFILEOFOBJECT(m_ObjectType));
// set up some default information on it.
//
pCreateErrorInfo->SetGUID((REFIID)INTERFACEOFOBJECT(m_ObjectType));
// pCreateErrorInfo->SetHelpFile(wszHelpFile);
pCreateErrorInfo->SetHelpContext(dwHelpContextID);
// load in the actual error string value. max of 256.
//
LoadString(GetResourceHandle(), idException, wszTmp, 256);
// MultiByteToWideChar(CP_ACP, 0, szTmp, -1, wszTmp, 256);
pCreateErrorInfo->SetDescription(wszTmp);
// load in the source
//
// MultiByteToWideChar(CP_ACP, 0, NAMEOFOBJECT(m_ObjectType), -1, szTmp, 256);
pCreateErrorInfo->SetSource(wszTmp);
// now set the Error info up with the system
//
hr = pCreateErrorInfo->QueryInterface(IID_IErrorInfo, (void **)&pErrorInfo);
CLEANUP_ON_FAILURE(hr);
SetErrorInfo(0, pErrorInfo);
pErrorInfo->Release();
CleanUp:
pCreateErrorInfo->Release();
return hrExcep;
}
//=--------------------------------------------------------------------------=
// CAutomationObject::InterfaceSupportsErrorInfo
//=--------------------------------------------------------------------------=
// indicates whether or not the given interface supports rich error information
//
// Parameters:
// REFIID - [in] the interface we want the answer for.
//
// Output:
// HRESULT - S_OK = Yes, S_FALSE = No.
//
// Notes:
//
HRESULT CAutomationObject::InterfaceSupportsErrorInfo
(
REFIID riid
)
{
// see if it's the interface for the type of object that we are.
//
if (riid == (REFIID)INTERFACEOFOBJECT(m_ObjectType))
return S_OK;
return S_FALSE;
}
//=--------------------------------------------------------------------------=
// CAutomationObject::GetResourceHandle [helper]
//=--------------------------------------------------------------------------=
// virtual routine to get the resource handle. virtual, so that inheriting
// objects, such as COleControl can use theirs instead, which goes and gets
// the Host's version ...
//
// Output:
// HINSTANCE
//
// Notes:
//
HINSTANCE CAutomationObject::GetResourceHandle
(
void
)
{
return NULL;
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// //
// CAutomationObjectWEvents //
// //
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//=--------------------------------------------------------------------------=
// CAutomationObjectWEvents::CAutomationObjectWEvents
//=--------------------------------------------------------------------------=
// constructor
//
// Parameters:
//
// IUnknown * - [in] controlling Unknown
// int - [in] the object type that we are
// void * - [in] the VTable of of the object we really are.
//
// Notes:
//
CAutomationObjectWEvents::CAutomationObjectWEvents
(
IUnknown *pUnkOuter,
int ObjType,
void *pVTable
)
: CAutomationObject(pUnkOuter, ObjType, pVTable),
m_cpEvents(SINK_TYPE_EVENT),
m_cpPropNotify(SINK_TYPE_PROPNOTIFY)
{
// not much to do yet.
}
//=--------------------------------------------------------------------------=
// CAutomationObjectWEvents::~CAutomationObjectWEvents
//=--------------------------------------------------------------------------=
// virtual destructor
//
// Notes:
//
CAutomationObjectWEvents::~CAutomationObjectWEvents()
{
// homey don't play that
}
//=--------------------------------------------------------------------------=
// CAutomationObjectWEvents::InternalQueryInterface
//=--------------------------------------------------------------------------=
// our internal query interface routine. we only add IConnectionPtContainer
// on top of CAutomationObject
//
// Parameters:
// REFIID - [in] interface they want
// void ** - [out] where they want to put the resulting object ptr.
//
// Output:
// HRESULT - S_OK, E_NOINTERFACE
//
// Notes:
//
HRESULT CAutomationObjectWEvents::InternalQueryInterface
(
REFIID riid,
void **ppvObjOut
)
{
// we only add one interface
//
if (DO_GUIDS_MATCH(riid, IID_IConnectionPointContainer)) {
*ppvObjOut = (IConnectionPointContainer *)this;
((IUnknown *)(*ppvObjOut))->AddRef();
return S_OK;
}
// just get our parent class to process it from here on out.
//
return CAutomationObject::InternalQueryInterface(riid, ppvObjOut);
}
//=--------------------------------------------------------------------------=
// CAutomationObjectWEvents::FindConnectionPoint [IConnectionPointContainer]
//=--------------------------------------------------------------------------=
// given an IID, find a connection point sink for it.
//
// Parameters:
// REFIID - [in] interfaces they want
// IConnectionPoint ** - [out] where the cp should go
//
// Output:
// HRESULT
//
// Notes:
//
STDMETHODIMP CAutomationObjectWEvents::FindConnectionPoint
(
REFIID riid,
IConnectionPoint **ppConnectionPoint
)
{
CHECK_POINTER(ppConnectionPoint);
// we support the event interface, and IDispatch for it, and we also
// support IPropertyNotifySink.
//
if (DO_GUIDS_MATCH(riid, EVENTIIDOFOBJECT(m_ObjectType)) || DO_GUIDS_MATCH(riid, IID_IDispatch))
*ppConnectionPoint = &m_cpEvents;
else if (DO_GUIDS_MATCH(riid, IID_IPropertyNotifySink))
*ppConnectionPoint = &m_cpPropNotify;
else
return E_NOINTERFACE;
// generic post-processing.
//
(*ppConnectionPoint)->AddRef();
return S_OK;
}
//=--------------------------------------------------------------------------=
// CAutomationObjectWEvents::EnumConnectionPoints [IConnectionPointContainer]
//=--------------------------------------------------------------------------=
// creates an enumerator for connection points.
//
// Parameters:
// IEnumConnectionPoints ** - [out]
//
// Output:
// HRESULT
//
// Notes:
//
STDMETHODIMP CAutomationObjectWEvents::EnumConnectionPoints
(
IEnumConnectionPoints **ppEnumConnectionPoints
)
{
IConnectionPoint **rgConnectionPoints;
CHECK_POINTER(ppEnumConnectionPoints);
// HeapAlloc an array of connection points [since our standard enum
// assumes this and HeapFree's it later ]
//
rgConnectionPoints = (IConnectionPoint **)HeapAlloc(g_hHeap, 0, sizeof(IConnectionPoint *) * 2);
RETURN_ON_NULLALLOC(rgConnectionPoints);
// we support the event interface for this dude as well as IPropertyNotifySink
//
rgConnectionPoints[0] = &m_cpEvents;
rgConnectionPoints[1] = &m_cpPropNotify;
*ppEnumConnectionPoints = (IEnumConnectionPoints *)(IEnumGeneric *) new CStandardEnum(IID_IEnumConnectionPoints,
2, sizeof(IConnectionPoint *), (void *)rgConnectionPoints,
CopyAndAddRefObject);
if (!*ppEnumConnectionPoints) {
HeapFree(g_hHeap, 0, rgConnectionPoints);
return E_OUTOFMEMORY;
}
return S_OK;
}
//=--------------------------------------------------------------------------=
// CAutomationObjectWEvents::CConnectionPoint::m_pObject
//=--------------------------------------------------------------------------=
// returns a pointer to the control in which we are nested.
//
// Output:
// CAutomationObjectWEvents *
//
// Notes:
//
inline CAutomationObjectWEvents *CAutomationObjectWEvents::CConnectionPoint::m_pObject
(
void
)
{
return (CAutomationObjectWEvents *)((BYTE *)this - ((m_bType == SINK_TYPE_EVENT)
? offsetof(CAutomationObjectWEvents, m_cpEvents)
: offsetof(CAutomationObjectWEvents, m_cpPropNotify)));
}
//=--------------------------------------------------------------------------=
// CAutomationObjectWEvents::CConnectionPoint::QueryInterface
//=--------------------------------------------------------------------------=
// standard qi
//
// Parameters:
// REFIID - [in] interface they want
// void ** - [out] where they want to put the resulting object ptr.
//
// Output:
// HRESULT - S_OK, E_NOINTERFACE
//
// Notes:
//
STDMETHODIMP CAutomationObjectWEvents::CConnectionPoint::QueryInterface
(
REFIID riid,
void **ppvObjOut
)
{
if (DO_GUIDS_MATCH(riid, IID_IConnectionPoint) || DO_GUIDS_MATCH(riid, IID_IUnknown)) {
*ppvObjOut = (IConnectionPoint *)this;
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
//=--------------------------------------------------------------------------=
// CAutomationObjectWEvents::CConnectionPoint::AddRef
//=--------------------------------------------------------------------------=
//
// Output:
// ULONG - the new reference count
//
// Notes:
//
ULONG CAutomationObjectWEvents::CConnectionPoint::AddRef
(
void
)
{
return m_pObject()->ExternalAddRef();
}
//=--------------------------------------------------------------------------=
// CAutomationObjectWEvents::CConnectionPoint::Release
//=--------------------------------------------------------------------------=
//
// Output:
// ULONG - remaining refs
//
// Notes:
//
ULONG CAutomationObjectWEvents::CConnectionPoint::Release
(
void
)
{
return m_pObject()->ExternalRelease();
}
//=--------------------------------------------------------------------------=
// CAutomationObjectWEvents::CConnectionPoint::GetConnectionInterface
//=--------------------------------------------------------------------------=
// returns the interface we support connections on.
//
// Parameters:
// IID * - [out] interface we support.
//
// Output:
// HRESULT
//
// Notes:
//
STDMETHODIMP CAutomationObjectWEvents::CConnectionPoint::GetConnectionInterface
(
IID *piid
)
{
if (m_bType == SINK_TYPE_EVENT)
*piid = EVENTIIDOFOBJECT(m_pObject()->m_ObjectType);
else
*piid = IID_IPropertyNotifySink;
return S_OK;
}
//=--------------------------------------------------------------------------=
// CAutomationObjectWEvents::CConnectionPoint::GetConnectionPointContainer
//=--------------------------------------------------------------------------=
// returns the connection point container
//
// Parameters:
// IConnectionPointContainer **ppCPC
//
// Output:
// HRESULT
//
// Notes:
//
STDMETHODIMP CAutomationObjectWEvents::CConnectionPoint::GetConnectionPointContainer
(
IConnectionPointContainer **ppCPC
)
{
return m_pObject()->ExternalQueryInterface(IID_IConnectionPointContainer, (void **)ppCPC);
}
//=--------------------------------------------------------------------------=
// CAutomationObjectWEvents::CConnectiontPoint::Advise
//=--------------------------------------------------------------------------=
// someboyd wants to be advised when something happens.
//
// Parameters:
// IUnknown * - [in] guy who wants to be advised.
// DWORD * - [out] cookie
//
// Output:
// HRESULT
//
// Notes:
//
STDMETHODIMP CAutomationObjectWEvents::CConnectionPoint::Advise
(
IUnknown *pUnk,
DWORD *pdwCookie
)
{
HRESULT hr;
void *pv;
CHECK_POINTER(pdwCookie);
// first, make sure everybody's got what they thinks they got
//
if (m_bType == SINK_TYPE_EVENT) {
// CONSIDER: 12.95 -- this theoretically is broken -- if they do a find
// connection point on IDispatch, and they just happened to also support
// the Event IID, we'd advise on that. this is not awesome, but will
// prove entirely acceptable short term.
//
hr = pUnk->QueryInterface(EVENTIIDOFOBJECT(m_pObject()->m_ObjectType), &pv);
if (FAILED(hr))
hr = pUnk->QueryInterface(IID_IDispatch, &pv);
}
else
hr = pUnk->QueryInterface(IID_IPropertyNotifySink, &pv);
RETURN_ON_FAILURE(hr);
// finally, add the sink. it's now been cast to the correct type and has
// been AddRef'd.
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -