📄 smartif.h
字号:
/////////////////////////////////////////////////
//
// Smart Interface Class
//
// Copyright 1994-1997, Don Box
//
// There is one class in this file:
//
// SmartInterface<T, PIID> : the smart interface pointer
//
// There is one function in this file:
//
// IsSameObject(x, y) : identity test that supports SmartInterface
//
// There are three macros in this file:
//
// SI(IInterfaceType) : expands to SmartInterface<IInterfaceType, &IID_IInterfaceType>
// DECLARE_SMART_INTERFACE(InterfaceType) : expands to typedef SI(I##InterfaceType) Smart##InterfaceType
// IID_PPV(sp) : expands to sp.GetIID(), sp.GetAsPPV()
//
// There is one conditional compilation symbol:
// _NO_SILENT_QI : if this symbol is defined, then heterogeneous assignment/construction is disallowed
//
// Usage:
/*
DECLARE_SMART_INTERFACE(PersistStorage)
IPersistStorage *LoadFromStorage(IStorage *pstg)
{
CLSID clsid;
ReadClassStg(pstg, &clsid);
SmartInterface<IUnknown, &IID_IUnknown> punk1;
SI(IUnknown) punk2;
SmartPersistStorage pPersistStg1, pPersistStg2;
// use the IID_PPV macro to get the last two args in QI form
CoCreateInstance(clsid, 0, CLSCTX_ALL, IID_PPV(punk1));
// I1 <- I1 assignment simply addrefs
punk2 = punk1;
// I2 <- I1 assignment silently QI's
pPersistStg1 = punk1;
// I2 <- I2 simply addref's
pPersistStg2 = pPersistStg2;
// I1 <- I2 simply addref's (down cast)
punk2 = pPersistStg2;
// overloaded arrow allows all members EXCEPT for AddRef/Release
pPersistStg2->Load(pstg);
// must explictitly specify usage, since
// dtors will release all outstanding references
// (silent typecast operator allowed too many errors)
CoLockObjectExternal(punk1.GetNonAddRefedInterface(), TRUE, TRUE);
return pPersistStg1.GetAddRefedInterface();
}
*/
//
//
#ifndef _SMARTIF_H
#define _SMARTIF_H
#include <assert.h>
struct SmartToken { IUnknown *m_pif; SmartToken(IUnknown* p) : m_pif(p) {} };
// this routine should really be moved to a real extern
inline BOOL IsSameObject(IUnknown *pUnk1, IUnknown *pUnk2)
{
assert(pUnk1 && pUnk2);
BOOL bResult = TRUE;
if (pUnk1 != pUnk2)
{
HRESULT hr;
IUnknown *p1 = 0, *p2 = 0;
hr = pUnk1->QueryInterface(IID_IUnknown, (void**)&p1);
if (SUCCEEDED(hr)) p1->Release(); else p1 = 0;
hr = pUnk2->QueryInterface(IID_IUnknown, (void**)&p2);
if (SUCCEEDED(hr)) p2->Release(); else p2 = 0;
bResult = (p1 == p2); // values do not change after release
}
return bResult;
}
inline BOOL IsSameObject(IUnknown *pUnk1, const SmartToken& pUnk2)
{
return IsSameObject(pUnk1, pUnk2.m_pif);
}
inline BOOL IsSameObject(const SmartToken& pUnk1, IUnknown *pUnk2)
{
return IsSameObject(pUnk1.m_pif, pUnk2);
}
inline BOOL IsSameObject(const SmartToken& pUnk1, const SmartToken& pUnk2)
{
return IsSameObject(pUnk1.m_pif, pUnk2.m_pif);
}
template <class If, const IID *piid>
class SmartInterface
{
If *m_pif;
typedef SmartInterface<If, piid> SameSmartType;
void SafeRelease(void)
{
if (m_pif)
m_pif->Release();
}
public:
// constructors/destructors ///////////////////////////
// default constructor
SmartInterface(void)
: m_pif(0)
{
}
// homogeneous raw constructor
SmartInterface(If *rhs)
{
if (m_pif = rhs)
m_pif->AddRef();
}
// homogeneous smart constructor
SmartInterface(const SameSmartType& rhs)
{
if (m_pif = rhs.m_pif)
m_pif->AddRef();
}
operator SmartToken (void) const
{
return SmartToken(m_pif);
}
#if !defined(_NO_SILENT_QI)
// heterogeneous raw constructor
SmartInterface(IUnknown * rhs)
: m_pif(0)
{
if (rhs)
rhs->QueryInterface(GetIID(), (void **)&m_pif);
}
// heterogeneous smart constructor
SmartInterface(const SmartToken& rhs)
: m_pif(0)
{
if (rhs.m_pif)
rhs.m_pif->QueryInterface(GetIID(), (void **)&m_pif);
}
#endif
// destructor
~SmartInterface(void)
{
SafeRelease();
}
// Attach/Detach operations
// homogeneous raw attachment
void Attach(If * rhs)
{
if (rhs != m_pif)
{
SafeRelease();
if (m_pif = rhs)
m_pif->AddRef();
}
}
// homogeneous smart attachment
void Attach(const SameSmartType& rhs)
{
Attach(rhs.m_pif);
}
// heterogeneous raw attachment
void Attach(IUnknown * rhs)
{
SafeRelease();
if (rhs)
rhs->QueryInterface(GetIID(), (void **)&m_pif);
else
m_pif = 0;
}
// heterogeneous smart attachment
void Attach(const SmartToken& rhs)
{
Attach(rhs.m_pif);
}
void Detach(void)
{
SafeRelease();
m_pif = 0;
}
// assignment operators ////////////////////////
// homogeneous raw assignment
SameSmartType& operator = (If *rhs)
{
Attach(rhs);
return *this;
}
// homogeneous smart assignment
SameSmartType& operator = (const SameSmartType& rhs)
{
Attach(rhs);
return *this;
}
#if !defined(_NO_SILENT_QI)
// heterogeneous raw assignment
SameSmartType& operator = (IUnknown * rhs)
{
Attach(rhs);
return *this;
}
// heterogeneous smart assignment
SameSmartType& operator = (const SmartToken& rhs)
{
Attach(rhs);
return *this;
}
#endif
// equivalence operators (note - no identity tests performed here!)
BOOL operator == (If * rhs)
{
return m_pif == rhs;
}
BOOL operator == (const SameSmartType& rhs)
{
return m_pif == rhs.m_pif;
}
BOOL operator != (If *rhs)
{
return m_pif != rhs;
}
BOOL operator != (const SameSmartType& rhs)
{
return m_pif != rhs.m_pif;
}
// CoCreateInstance wrappers
HRESULT CreateInstance(REFCLSID rclsid,
DWORD dwClsCtx = CLSCTX_ALL,
IUnknown *pUnkOuter = 0)
{
Detach();
return CoCreateInstance(rclsid, pUnkOuter, dwClsCtx,
GetIID(), AsPPVArg());
}
HRESULT CreateInstance(LPCOLESTR szProgID,
DWORD dwClsCtx = CLSCTX_ALL,
IUnknown *pUnkOuter = 0)
{
CLSID clsid;
HRESULT result = CLSIDFromProgID(szProgID, &clsid);
if (SUCCEEDED(result))
result = CreateInstance(clsid, dwClsCtx, pUnkOuter);
return result;
}
HRESULT GetClassObject(REFCLSID rclsid,
DWORD dwClsCtx = CLSCTX_ALL)
{
Detach();
return CoGetClassObject(rclsid, dwClsCtx, 0,
GetIID(), AsPPVArg());
}
HRESULT GetClassObject(LPCOLESTR szProgID,
DWORD dwClsCtx = CLSCTX_ALL)
{
CLSID clsid;
HRESULT result = CLSIDFromProgID(szProgID, &clsid);
if (SUCCEEDED(result))
result = GetClassObject(clsid, dwClsCtx);
return result;
}
#ifdef _WIN32_DCOM
HRESULT CreateInstance(REFCLSID rclsid, DWORD dwClsCtx,
const OLECHAR *pwszHostName,
COAUTHINFO *pai = 0)
{
Detach();
COSERVERINFO csi = { 0, pwszHostName, pai, 0 };
MULTI_QI mqi = { piid, 0, 0 };
HRESULT hr = CoCreateInstanceEx(rclsid, 0, dwClsCtx,
&csi, 1, &mqi);
if (SUCCEEDED(hr))
*(IUnknown**)&m_pif = mqi.pItf;
return hr;
}
HRESULT CreateInstance(LPCOLESTR szProgID, DWORD dwClsCtx,
const OLECHAR *pwszHostName,
COAUTHINFO *pai = 0)
{
CLSID clsid;
HRESULT result = CLSIDFromProgID(szProgID, &clsid);
if (SUCCEEDED(result))
result = CreateInstance(clsid, dwClsCtx, pwszHostName, pai);
return result;
}
HRESULT GetClassObject(REFCLSID rclsid,
DWORD dwClsCtx,
const OLECHAR *pwszHostName,
COAUTHINFO *pai = 0)
{
Detach();
COSERVERINFO csi = { 0, pwszHostName, pai, 0 };
return CoGetClassObject(rclsid, dwClsCtx, &csi,
GetIID(), AsPPVArg());
}
HRESULT GetClassObject(LPCOLESTR szProgID,
DWORD dwClsCtx,
const OLECHAR *pwszHostName,
COAUTHINFO *pai = 0)
{
CLSID clsid;
HRESULT result = CLSIDFromProgID(szProgID, &clsid);
if (SUCCEEDED(result))
result = GetClassObject(clsid, dwClsCtx, pwszHostName, pai);
return result;
}
#endif
HRESULT BindToObject(IMoniker *pmk, IBindCtx *pbc = 0, IMoniker *pmkToLeft = 0)
{
Detach();
HRESULT hr = S_OK;
if (pbc)
pbc->AddRef();
else
hr = CreateBindCtx(0, &pbc);
if (SUCCEEDED(hr))
{
hr = pmk->BindToObject(pbc, pmkToLeft, GetIID(), (void**)&m_pif);
if (FAILED(hr))
m_pif = 0;
pbc->Release();
}
return hr;
}
HRESULT BindToObject(LPCOLESTR pszDisplayName)
{
Detach();
IBindCtx *pbc = 0;
HRESULT hr = CreateBindCtx(0, &pbc);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -