📄 utilcls.h
字号:
return V_I4(&v);
}
operator unsigned long() const
{
TVariantT v(*this);
v.ChangeType(VT_UI4);
return V_UI4(&v);
}
operator float() const
{
TVariantT v(*this);
v.ChangeType(VT_R4);
return V_R4(&v);
}
operator double() const
{
TVariantT v(*this);
v.ChangeType(VT_R8);
return V_R8(&v);
}
#if defined(DSTRING_H)
operator AnsiString() const
{
TVariantT v(*this);
v.ChangeType(VT_BSTR);
WideString temp(V_BSTR(&v));
AnsiString retval(temp);
return retval;
}
#endif
#if defined(SYSCURR_H)
operator Currency() const
{
TVariantT v(*this);
v.ChangeType(VT_CY);
Currency retval;
retval.Val = V_CY(&v).int64;
return retval;
}
#endif
#if defined(SYSTDATE_H)
operator TDateTime() const
{
TVariantT v(*this);
v.ChangeType(VT_DATE);
TDateTime retval(V_DATE(&v));
return retval;
}
#endif
#if defined(WSTRING_H)
operator WideString() const
{
TVariantT v(*this);
v.ChangeType(VT_BSTR);
return WideString(::SysAllocString(V_BSTR(&v)));
}
#endif
operator CURRENCY() const
{
TVariantT v(*this);
v.ChangeType(VT_CY);
return V_CY(&v);
}
// NOTE: Caller must free SysString
operator wchar_t*() const
{
TVariantT v(*this);
v.ChangeType(VT_BSTR);
return ::SysAllocString(V_BSTR(&v));
}
operator IUnknown*();
operator IDispatch*();
// by ref conversion operators
/* operator char*(); */ // Dangerous - easily used as string instead of VT_I1|VT_BYREF
operator signed char*()
{
if (vt == (VT_I1|VT_BYREF))
return (signed char*)V_I1REF(this);
else if (vt == VT_I1)
return (signed char*)&(V_I1(this));
}
operator unsigned char*()
{
if (vt == (VT_UI1 | VT_BYREF))
return V_UI1REF(this);
else if (vt == VT_UI1)
return &(V_UI1(this));
}
operator short*()
{
if (vt == (VT_I2|VT_BYREF))
return V_I2REF(this);
else if (vt == VT_I2)
return &(V_I2(this));
return NULL;
}
operator unsigned short*()
{
if (vt == (VT_UI2|VT_BYREF))
return V_UI2REF(this);
else if (vt == VT_UI2)
return &(V_UI2(this));
return NULL;
}
operator int*()
{
if (vt == (VT_I4|VT_BYREF))
return (int*)V_I4REF(this);
else if (vt == VT_I4)
return (int*)&(V_I4(this));
return NULL;
}
operator unsigned int*()
{
if (vt == (VT_UI4|VT_BYREF))
return (unsigned int*)V_UI4REF(this);
else if (vt == VT_UI4)
return (unsigned int*)&(V_UI4(this));
return NULL;
}
operator float*()
{
if (vt == (VT_R4|VT_BYREF))
return V_R4REF(this);
else if (vt == VT_R4)
return &(V_R4(this));
return NULL;
}
operator double*()
{
if (vt == (VT_R8|VT_BYREF))
return V_R8REF(this);
else if (vt == VT_R8)
return &(V_R8(this));
return NULL;
}
operator wchar_t**()
{
if (vt == (VT_BSTR|VT_BYREF))
return V_BSTRREF(this);
else if (vt == VT_BSTR)
return &(V_BSTR(this));
return NULL;
}
operator VARIANT*()
{
return reinterpret_cast<VARIANT*>(GetBaseVariant());
}
// NOTE: Caller must destroy SAFEARRAY*
operator SAFEARRAY*()
{
SAFEARRAY *pSAOut = 0;
if (vt & VT_ARRAY)
{
if (vt & VT_BYREF)
::SafeArrayCopy(*V_ARRAYREF(this), &pSAOut);
else
::SafeArrayCopy(V_ARRAY(this), &pSAOut);
}
return pSAOut;
}
/*operator CURRENCY*() const;*/
/*operator SAFEARRAY**() const;*/
#if defined(SYSCURR_H)
operator Currency*()
{
if (vt==(VT_CY|VT_BYREF))
return reinterpret_cast<Currency*>(pcyVal);
else if (vt==VT_CY)
return reinterpret_cast<Currency*>(&cyVal);
return NULL;
}
#endif
#if defined(SYSTDATE_H)
operator TDateTime*()
{
if (vt==(VT_DATE|VT_BYREF))
return reinterpret_cast<TDateTime*>(pdate);
else if (vt==VT_DATE)
return reinterpret_cast<TDateTime*>(&date);
return NULL;
}
#endif
// Generic == operator (NOTE: Relies on conversion operator for TYPE)
//
template <class TYPE>
bool operator == (TYPE rhs)
{
TVariant tmp(*this);
return TYPE(tmp) == rhs;
}
};
// Returns 'base-most' VARIANT pointed to by a TVariantT instance
// (i.e. skip cases where VARIANT points to other VARIANT - VT_VARIANT)
//
template <class T>
TVariantT<T>* TVariantT<T>::GetBaseVariant()
{
TVariantT *pVar = this;
// NOTE: Technically there could only be one level of indirection for VT_VARIANT
// Additionally, VT_VARIANT should always be used in combination with VT_BYREF
// However, it does not hurt to catch multiple indirection or check a simple
// VT_VARIANT VARTYPE. Never know what's being packed and sent down out there
//
while (((pVar->vt == VT_VARIANT) || (pVar->vt == (VT_VARIANT|VT_BYREF))) && (V_VARIANTREF(pVar)))
pVar = reinterpret_cast<TVariantT*>(V_VARIANTREF(pVar));
return pVar;
}
// Extracts an IUnknown* from the TVariantT instance.
// NOTE: Caller must 'Release' interface.
//
template <class T>
TVariantT<T>::operator IUnknown*()
{
// Handle easy case right away
//
if (vt==VT_NULL || vt==VT_EMPTY)
return 0;
IDispatch* disp;
IUnknown* punk = 0;
TVariantT* pVar = GetBaseVariant();
// Get Data out of Variant
//
switch(pVar->vt)
{
case VT_UNKNOWN:
case VT_UNKNOWN|VT_BYREF:
punk = (vt==VT_UNKNOWN ? V_UNKNOWN(pVar) : (*(V_UNKNOWNREF(pVar))));
punk->AddRef();
return punk;
case VT_DISPATCH:
case VT_DISPATCH|VT_BYREF:
disp = (vt==VT_DISPATCH ? V_DISPATCH(pVar) : (*(V_DISPATCHREF(pVar))));
if (disp)
disp->QueryInterface(IID_IUnknown, (LPVOID*)&punk);
return punk;
// Hopefully, we'll never get here, but as last resort
//
default:
TVariantT v(*this);
v.ChangeType(VT_UNKNOWN);
V_UNKNOWN(&v)->AddRef();
return V_UNKNOWN(&v);
}
}
// Extracts an IDispatch* from the TVariantT instance.
// NOTE: Caller must 'Release' interface.
//
template <class T>
TVariantT<T>::operator IDispatch*()
{
// Handle easy case right away
//
if (vt==VT_NULL || vt==VT_EMPTY)
return 0;
IUnknown* punk;
IDispatch* disp= 0;
TVariantT* pVar= GetBaseVariant();
// Get data out of Variant
//
switch(pVar->vt)
{
case VT_DISPATCH:
case VT_DISPATCH|VT_BYREF:
disp = (vt==VT_DISPATCH ? V_DISPATCH(pVar) : (*(V_DISPATCHREF(pVar))));
if (disp)
disp->AddRef();
return disp;
case VT_UNKNOWN:
case VT_UNKNOWN|VT_BYREF:
punk = (vt==VT_UNKNOWN ? V_UNKNOWN(pVar) : (*(V_UNKNOWNREF(pVar))));
punk->QueryInterface(IID_IDispatch, (LPVOID*)&disp);
return disp;
default:
TVariantT v(*pVar);
v.ChangeType(VT_DISPATCH);
V_DISPATCH(&v)->AddRef();
return V_DISPATCH(&v);
}
}
// Default VARIANT wrapper used by TAutoArgs
//
typedef TVariantT<VARIANT> TVariant;
typedef TVariantT<VARIANT> VARIANTOBJ;
// Generic COM Interface wrapper
// Performs proper AddRef/Release when object is copied, assigned to and deleted
//
template <class T, const IID *piid = &GUID_NULL>
class TComInterface
{
public:
TComInterface() : intf(0)
{}
// NOTE: The default behaviour of the constructor is to not AddRef the interface
// pointer parameter. This is appropriate if the interface was obtained
// has already been addRef'ed - as when retrieving a Font property.
//
TComInterface(T* p, bool addRef = false)
{
if (((intf = p) != 0) && addRef)
intf->AddRef();
}
#if 0
TComInterface(int /*ToAllowNull*/) : intf(0)
{
/* OLECHECK(ToAllowNull == 0); */
}
#endif
TComInterface(IUnknown* p) : intf(0)
{
*this = p;
}
TComInterface(IDispatch* p) : intf(0)
{
*this = p;
}
TComInterface(TVariant var) : intf(0)
{
*this = var;
}
TComInterface(const TComInterface<T, piid>& src)
{
if ((intf = src.intf) != 0)
intf->AddRef();
}
template <class ANOTHERINTF, const IID* ANOTHERIID>
TComInterface(const TComInterface<ANOTHERINTF, ANOTHERIID>& src) : intf(0)
{
_ASSERTE_(/* Need have valid IID to invoke this */GetIID() != GUID_NULL);
if (src)
{
OLECHECK(src->QueryInterface(GetIID(), (LPVOID*)(&intf)));
}
}
~TComInterface()
{
Reset();
}
operator T* () const
{
return intf;
}
T& operator*()
{
_ASSERTE_(intf!=0 /* Don't allow *() of smart interface with NULL pointer interface */);
return *intf;
}
// NOTE: You must explicitly Reset() any held interface pointers before invoking
// the &operator (presumably to store another interface in the object)
// (Should we do the Release() automatically and eliminate the _ASSERTE_ check??)
//
T** operator & ()
{
_ASSERTE_(intf==0 /* Don't allow &() of smart interface with NULL pointer interface */);
return &intf;
}
T* operator->() const
{
_ASSERTE_(intf != 0 /* Don't allow ->() of smart interface with NULL pointer interface */);
return intf;
}
T* operator->()
{
_ASSERTE_(intf != 0 /*Don't allow ->() of smart interface with NULL pointer interface */);
return intf;
}
void Reset(T* p = 0)
{
if (intf)
intf->Release();
intf=p;
}
void Bind(T* p, bool addRef = false)
{
if (p && addRef)
p->AddRef();
Reset(p);
}
void Unbind()
{
Reset(0);
}
void AddRef()
{
(*this)->AddRef();
}
void Release()
{
(*this)->Release();
intf = 0;
}
// NOTE: This assignment operator does *NOT* addRef the interface pointer being
// assigned to this object.
//
TComInterface<T, piid>& operator=(T* p)
{
Bind(p);
return *this;
}
#if 0
TComInterface<T, piid>& operator=(int /*ToAllowNullAssignment*/)
{
/* OLECHECK(ToAllowNullAssignment == 0); */
Reset();
}
#endif
const IID& GetIID() const
{
return *piid;
}
TComInterface<T, piid>& operator=(IUnknown* p)
{
_ASSERTE_(/* Need have valid IID to invoke this */GetIID() != GUID_NULL);
Reset();
if (p)
{
OLECHECK(p->QueryInterface(GetIID(), (LPVOID*)(&intf)));
}
return *this;
}
TComInterface<T, piid>& operator=(IDispatch* p)
{
_ASSERTE_(/* Need have valid IID to invoke this */GetIID() != GUID_NULL);
Reset();
if (p)
{
OLECHECK(p->QueryInterface(GetIID(), (LPVOID*)(&intf)));
}
return *this;
}
TComInterface<T, piid>& operator=(TVariant var)
{
_ASSERTE_(/* Need have valid IID to invoke this */GetIID() != GUID_NULL);
IUnknown* punk = var;
if (punk)
{
Reset();
OLECHECK(punk->QueryInterface(GetIID(), (LPVOID*)(&intf)));
}
return *this;
}
template <class ANOTHERINTF, const IID* ANOTHERIID>
TComInterface<T, piid>& operator=(const TComInterface<ANOTHERINTF, ANOTHERIID>& src)
{
_ASSERTE_(/* Need have valid IID to invoke this */GetIID() != GUID_NULL);
Reset();
if (src)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -