📄 smartif.h
字号:
if (SUCCEEDED(hr))
{
IMoniker *pmk = 0;
ULONG cch = 0;
hr = MkParseDisplayName(pbc, pszDisplayName, &cch, &pmk);
if (SUCCEEDED(hr))
{
hr = pmk->BindToObject(pbc, 0, GetIID(), (void**)&m_pif);
if (FAILED(hr))
m_pif = 0;
pmk->Release();
}
pbc->Release();
}
return hr;
}
// operations
const IID& GetIID(void) const
{
return *piid;
}
void * * AsPPVArg(void)
{
SafeRelease();
return (void * FAR*)&m_pif;
}
// note: no If * operator is allowed, as it makes it very
// easy to break the protocol of COM. Instead, these
// four operations require the user to be explicit
If * GetAddRefedInterface(void) const
{
if (m_pif)
m_pif->AddRef();
return m_pif;
}
If * GetNonAddRefedInterface(void) const
{
return m_pif;
}
If **GetReleasedInterfaceReference(void)
{
SafeRelease();
return &m_pif;
}
If **GetNonReleasedInterfaceReference(void)
{
return &m_pif;
}
BOOL operator ! (void) const
{
return m_pif == 0;
}
BOOL IsOK(void) const
{
return m_pif != 0;
}
// instead of operator bool, we return a fake ptr type to allow if (pFoo) usage
// but to disallow if (pFoo == pBar) which is probably wrong
class PseudoBool {};
operator PseudoBool * (void) const
{
return (PseudoBool *)m_pif;
}
// the arrow operator returns a pointer with AddRef and Release disabled
class NoAddRefOrRelease : public If {
private:
STDMETHOD_(ULONG, AddRef)(THIS) PURE;
STDMETHOD_(ULONG, Release)(THIS) PURE;
};
NoAddRefOrRelease *operator ->(void)
{
assert(m_pif);
return (NoAddRefOrRelease *)m_pif;
}
};
#if _MSC_VER>1020
template <>
#endif
class SmartInterface<IUnknown, &IID_IUnknown>
{
If *m_pif;
typedef IUnknown If;
typedef SmartInterface<If, &IID_IUnknown> 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);
}
// heterogeneous raw constructor (see homo version)
// heterogeneous smart constructor (AddRef's instead of QI)
SmartInterface(const SmartToken& rhs)
: m_pif(0)
{
if (m_pif = rhs.m_pif)
m_pif->AddRef();
}
// 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 (see homo version)
// 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;
}
// heterogeneous raw assignment (see homo version)
// heterogeneous smart assignment
SameSmartType& operator = (const SmartToken& rhs)
{
Attach(rhs);
return *this;
}
// 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 Instantiate(REFCLSID rclsid,
DWORD dwClsCtx = CLSCTX_ALL,
IUnknown *pUnkOuter = 0)
{
Detach();
return CoCreateInstance(rclsid, pUnkOuter, dwClsCtx,
GetIID(), AsPPVArg());
}
HRESULT Instantiate(LPCOLESTR szProgID,
DWORD dwClsCtx = CLSCTX_ALL,
IUnknown *pUnkOuter = 0)
{
CLSID clsid;
HRESULT result = CLSIDFromProgID(szProgID, &clsid);
if (SUCCEEDED(result))
result = Instantiate(clsid, dwClsCtx, pUnkOuter);
return result;
}
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);
if (SUCCEEDED(hr))
{
IMoniker *pmk = 0;
ULONG cch = 0;
hr = MkParseDisplayName(pbc, pszDisplayName, &cch, &pmk);
if (SUCCEEDED(hr))
{
hr = pmk->BindToObject(pbc, 0, GetIID(), (void**)&m_pif);
if (FAILED(hr))
m_pif = 0;
pmk->Release();
}
pbc->Release();
}
return hr;
}
// operations
const IID& GetIID(void) const
{
return IID_IUnknown;
}
void * * AsPPVArg(void)
{
SafeRelease();
return (void * FAR*)&m_pif;
}
// note: no If * operator is allowed, as it makes it very
// easy to break the protocol of COM. Instead, these
// four operations require the user to be explicit
If * GetAddRefedInterface(void) const
{
if (m_pif)
m_pif->AddRef();
return m_pif;
}
If * GetNonAddRefedInterface(void) const
{
return m_pif;
}
If **GetReleasedInterfaceReference(void)
{
SafeRelease();
return &m_pif;
}
If **GetNonReleasedInterfaceReference(void)
{
return &m_pif;
}
BOOL operator ! (void) const
{
return m_pif == 0;
}
BOOL IsOK(void) const
{
return m_pif != 0;
}
// instead of operator bool, we return a fake ptr type to allow if (pFoo) usage
// but to disallow if (pFoo == pBar) which is probably wrong
class PseudoBool {};
operator PseudoBool * (void) const
{
return (PseudoBool *)m_pif;
}
// the arrow operator returns a pointer with AddRef and Release disabled
class NoAddRefOrRelease : public If {
private:
STDMETHOD_(ULONG, AddRef)(THIS) PURE;
STDMETHOD_(ULONG, Release)(THIS) PURE;
};
NoAddRefOrRelease *operator ->(void)
{
assert(m_pif);
return (NoAddRefOrRelease *)m_pif;
}
};
#define SI(InterfaceName) \
SmartInterface<InterfaceName, &IID_##InterfaceName>
#define DECLARE_SMART_INTERFACE(InterfaceName) \
typedef SI(I##InterfaceName) Smart##InterfaceName
#define IID_PPV(sif) ((sif).GetIID()), ((sif).AsPPVArg())
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -