windows-nt/Source/XPSP1/NT/shell/inc/cowsite.h
2020-09-26 16:20:57 +08:00

97 lines
2.1 KiB
C++

#ifndef _COWSITE_H_
#define _COWSITE_H_
class CObjectWithSite : public IObjectWithSite
{
public:
CObjectWithSite() {_punkSite = NULL;};
virtual ~CObjectWithSite() {ATOMICRELEASE(_punkSite);}
//*** IUnknown ****
// (client must provide!)
//*** IObjectWithSite ***
STDMETHOD(SetSite)(IUnknown *punkSite);
STDMETHOD(GetSite)(REFIID riid, void **ppvSite);
protected:
IUnknown* _punkSite;
};
//
// use this when you dont have a good Destroy site chain event - ZekeL - 20-DEC-2000
// if you need to call SetSite(NULL) on your children, and
// would prefer to do this cleanup in your destructor.
// your object should be implemented like this
//
/******
class CMyObject : public IMyInterface
{
private:
CSafeServiceSite *_psss;
IKid _pkid;
CMyObject()
{
_psss = new CSafeServiceSite();
if (_psss)
_psss->SetProviderWeakRef(this);
}
~CMyObject()
{
if (_psss)
{
_psss->SetProviderWeakRef(NULL);
_psss->Release();
}
if (_pkid)
{
IUnknown_SetSite(_pkid, _psss);
_pkid->Release();
}
}
public:
// IMyInterface
HRESULT Init()
{
CoCreate(CLSID_Kid, &_pkid);
IUnknown_SetSite(_pkid, _psss);
}
// NOTE - there is no Uninit()
// so it's hard to know when to release _pkid
// and you dont want to _pkid->SetSite(NULL)
// unless you are sure you are done
};
******/
class CSafeServiceSite : public IServiceProvider
{
public:
CSafeServiceSite() : _cRef(1), _psp(NULL) {}
// IUnknown
STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
// IServiceProvider
STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void **ppvObj);
// our personal weak ref
HRESULT SetProviderWeakRef(IServiceProvider *psp);
private: // methods
~CSafeServiceSite()
{ ASSERT(_psp == NULL); }
private: // members
LONG _cRef;
IServiceProvider *_psp;
};
#endif