Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

160 lines
5.7 KiB

#ifndef __CNCTNPT_H__
#define __CNCTNPT_H__
//
// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
//
// This class is shared between DLLs, and DLLs that use it have already
// shipped as part of IE4 (specifically, shell32). This means that
// any changes you make must be done EXTREMELY CAREFULLY and TESTED
// FOR INTEROPERABILITY WITH IE4! For one thing, you have to make sure
// that none of your changes alter the vtbl used by IE4's shell32.
//
// If you change CIE4ConnectionPoint, you must build SHDOC401 and
// test it on IE4!
//
// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
//
//
// First, the class as it was defined in IE4. All virtual functions
// must be be listed in exactly the same order as they were in IE4.
// Fortunately, no cross-component users mucked with the member
// variables.
//
// Change any of these at your own risk.
//
class CIE4ConnectionPoint : public IConnectionPoint {
public:
// IUnknown methods
//
virtual STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj) PURE;
virtual STDMETHODIMP_(ULONG) AddRef(void) PURE;
virtual STDMETHODIMP_(ULONG) Release(void) PURE;
// IConnectionPoint methods
//
virtual STDMETHODIMP GetConnectionInterface(IID FAR* pIID) PURE;
virtual STDMETHODIMP GetConnectionPointContainer(IConnectionPointContainer FAR* FAR* ppCPC) PURE;
virtual STDMETHODIMP Advise(LPUNKNOWN pUnkSink, DWORD FAR* pdwCookie) PURE;
virtual STDMETHODIMP Unadvise(DWORD dwCookie) PURE;
virtual STDMETHODIMP EnumConnections(LPENUMCONNECTIONS FAR* ppEnum) PURE;
// This is how you actually fire the events
// Those called by shell32 are virtual
// (Renamed to DoInvokeIE4)
virtual HRESULT DoInvokeIE4(LPBOOL pf, LPVOID *ppv, DISPID dispid, DISPPARAMS *pdispparams) PURE;
// This helper function does work that callers of DoInvoke often need done
virtual HRESULT DoInvokePIDLIE4(DISPID dispid, LPCITEMIDLIST pidl, BOOL fCanCancel) PURE;
};
//
// CConnectionPoint is an implementation of a conection point.
// To get the rest of the implementation, you also have to include
// lib\cnctnpt.cpp in your project.
//
// Embed an instance of CConnectionPoint in an object that needs to
// implement a connectionpoint and call SetOwner to initialize it.
//
// Fire events to anyone connected to this connectionpoint via DoInvoke
// or DoOnChanged. External clients should use the shlwapi functions
// like IConnectionPoint_Invoke or IConnectionPoint_OnChanged.
//
class CConnectionPoint : public CIE4ConnectionPoint {
friend class CConnectionPointEnum;
public:
// IUnknown methods
//
virtual STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj);
virtual STDMETHODIMP_(ULONG) AddRef(void)
{ return m_punk->AddRef(); }
virtual STDMETHODIMP_(ULONG) Release(void)
{ return m_punk->Release(); }
// IConnectionPoint methods
//
virtual STDMETHODIMP GetConnectionInterface(IID * pIID);
virtual STDMETHODIMP GetConnectionPointContainer(IConnectionPointContainer ** ppCPC);
virtual STDMETHODIMP Advise(LPUNKNOWN pUnkSink, DWORD * pdwCookie);
virtual STDMETHODIMP Unadvise(DWORD dwCookie);
virtual STDMETHODIMP EnumConnections(LPENUMCONNECTIONS * ppEnum);
// CIE4ConnectionPoint methods - called by IE4's shell32
virtual HRESULT DoInvokeIE4(LPBOOL pf, LPVOID *ppv, DISPID dispid, DISPPARAMS *pdispparams);
// DoInvokePidlIE4 is strange in that shell32 linked to it but never
// actually called it. This makes the implementation particularly simple.
virtual HRESULT DoInvokePIDLIE4(DISPID dispid, LPCITEMIDLIST pidl, BOOL fCanCancel)
{ return E_NOTIMPL; }
public:
// Additional helper methods
// Performs a basic DISPID Invoke on the object
inline HRESULT InvokeDispid(DISPID dispid) {
return IConnectionPoint_SimpleInvoke(this, dispid, NULL);
}
// Performs an OnChanged on the object
inline HRESULT OnChanged(DISPID dispid) {
return IConnectionPoint_OnChanged(this, dispid);
}
// A couple functions to setup and destroy this subclass object
~CConnectionPoint(); // not virtual: nobody inherits from this class
//
// The containing object must call SetOwner to initialize the
// connection point.
//
// punk - The IUnknown of the object this ConnectionPoint is
// embedded in; it will be treated as the connection
// point container.
//
// piid - The IID that the sinks are expected to support.
// If you call DoInvoke, then it must be derived from
// IID_IDispatch. If you call DoOnChanged, then it must
// be exactly &IID_IPropertyNotifySink.
//
void SetOwner(IUnknown* punk, const IID* piid)
{
// Validate the special requirement on the piid parameter.
if (*piid == IID_IPropertyNotifySink)
{
ASSERT(piid == &IID_IPropertyNotifySink);
}
// don't AddRef -- we're a member variable of the object punk points to
m_punk = punk;
m_piid = piid;
}
// The underline version is inline
BOOL _HasSinks() { return (BOOL)m_cSinks; }
// We are empty if there are no sinks
BOOL IsEmpty() { return !_HasSinks(); }
HRESULT UnadviseAll(void);
// A lot of people need to convert a CConnectionPoint into an
// IConnectionPoint. We used to be multiply inherited, hence the
// need for this member, but that's gone now.
IConnectionPoint *CastToIConnectionPoint()
{ return SAFECAST(this, IConnectionPoint*); }
private:
IUnknown **m_rgSinks;
int m_cSinks;
int m_cSinksAlloc;
IUnknown *m_punk; // IUnknown of object containing us
const IID *m_piid; // IID of this connection point
};
#endif