📄 olevar.cpp
字号:
if (vt != VT_DATE)
{
Clear();
vt = VT_DATE;
}
date = dateSrc.m_dt;
return *this;
}
const COleVariant& COleVariant::operator=(const CByteArray& arrSrc)
{
int nSize = arrSrc.GetSize();
// Set the correct type and make sure SafeArray can hold data
_AfxCreateOneDimArray(*this, (DWORD)nSize);
// Copy the data into the SafeArray
_AfxCopyBinaryData(parray, arrSrc.GetData(), (DWORD)nSize);
return *this;
}
const COleVariant& COleVariant::operator=(const CLongBinary& lbSrc)
{
// Set the correct type and make sure SafeArray can hold data
_AfxCreateOneDimArray(*this, lbSrc.m_dwDataLength);
// Copy the data into the SafeArray
BYTE* pData = (BYTE*)::GlobalLock(lbSrc.m_hData);
_AfxCopyBinaryData(parray, pData, lbSrc.m_dwDataLength);
::GlobalUnlock(lbSrc.m_hData);
return *this;
}
void AFXAPI AfxVariantInit(LPVARIANT pVar)
{
memset(pVar, 0, sizeof(*pVar));
}
/////////////////////////////////////////////////////////////////////////////
// Diagnostics
#ifdef _DEBUG
CDumpContext& AFXAPI operator <<(CDumpContext& dc, COleVariant varSrc)
{
LPCVARIANT pSrc = (LPCVARIANT)varSrc;
dc << "\nCOleVariant Object:";
dc << "\n\t vt = " << pSrc->vt;
// No support for VT_BYREF & VT_ARRAY
if (pSrc->vt & VT_BYREF || pSrc->vt & VT_ARRAY)
return dc;
switch (pSrc->vt)
{
case VT_BOOL:
return dc << "\n\t VT_BOOL = " << V_BOOL(pSrc);
case VT_UI1:
return dc << "\n\t bVal = " << pSrc->bVal;
case VT_I2:
return dc << "\n\t iVal = " << pSrc->iVal;
case VT_I4:
return dc << "\n\t lVal = " << pSrc->lVal;
case VT_CY:
{
COleVariant var(varSrc);
var.ChangeType(VT_BSTR);
return dc << "\n\t cyVal = " << var.bstrVal;
}
case VT_R4:
return dc << "\n\t fltVal = " << pSrc->fltVal;
case VT_R8:
return dc << "\n\t dblVal = " << pSrc->dblVal;
case VT_DATE:
{
COleVariant var(varSrc);
var.ChangeType(VT_BSTR);
return dc << "\n\t date = " << var.bstrVal;
}
case VT_BSTR:
return dc << "\n\t bstrVal = " << pSrc->bstrVal;
case VT_ERROR:
return dc << "\n\t scode = " << pSrc->scode;
case VT_DISPATCH:
case VT_UNKNOWN:
return dc << "\n\t punkVal = " << pSrc->punkVal;
case VT_EMPTY:
case VT_NULL:
return dc;
default:
ASSERT(FALSE);
return dc;
}
}
#endif // _DEBUG
CArchive& AFXAPI operator<<(CArchive& ar, COleVariant varSrc)
{
LPCVARIANT pSrc = (LPCVARIANT)varSrc;
ar << pSrc->vt;
// No support for VT_BYREF & VT_ARRAY
if (pSrc->vt & VT_BYREF || pSrc->vt & VT_ARRAY)
return ar;
switch (pSrc->vt)
{
case VT_BOOL:
return ar << (WORD)V_BOOL(pSrc);
case VT_UI1:
return ar << pSrc->bVal;
case VT_I2:
return ar << (WORD)pSrc->iVal;
case VT_I4:
return ar << pSrc->lVal;
case VT_CY:
ar << pSrc->cyVal.Lo;
return ar << pSrc->cyVal.Hi;
case VT_R4:
return ar << pSrc->fltVal;
case VT_R8:
return ar << pSrc->dblVal;
case VT_DATE:
return ar << pSrc->date;
case VT_BSTR:
{
DWORD nLen = SysStringByteLen(pSrc->bstrVal);
ar << nLen;
if (nLen > 0)
ar.Write(pSrc->bstrVal, nLen * sizeof(BYTE));
return ar;
}
case VT_ERROR:
return ar << pSrc->scode;
case VT_DISPATCH:
case VT_UNKNOWN:
{
LPPERSISTSTREAM pPersistStream;
CArchiveStream stm(&ar);
// QI for IPersistStream or IPeristStreamInit
SCODE sc = pSrc->punkVal->QueryInterface(
IID_IPersistStream, (void**)&pPersistStream);
#ifndef _AFX_NO_OCC_SUPPORT
if (FAILED(sc))
sc = pSrc->punkVal->QueryInterface(
IID_IPersistStreamInit, (void**)&pPersistStream);
#endif
AfxCheckError(sc);
TRY
{
// Get and archive the CLSID (GUID)
CLSID clsid;
AfxCheckError(pPersistStream->GetClassID(&clsid));
ar << clsid.Data1;
ar << clsid.Data2;
ar << clsid.Data3;
ar.Write(&clsid.Data4[0], sizeof clsid.Data4);
// Always assume object is dirty
AfxCheckError(pPersistStream->Save(&stm, TRUE));
}
CATCH_ALL(e)
{
pPersistStream->Release();
THROW_LAST();
}
END_CATCH_ALL
pPersistStream->Release();
}
return ar;
case VT_EMPTY:
case VT_NULL:
// do nothing
return ar;
default:
ASSERT(FALSE);
return ar;
}
}
CArchive& AFXAPI operator>>(CArchive& ar, COleVariant& varSrc)
{
LPVARIANT pSrc = &varSrc;
// Free up current data if necessary
if (pSrc->vt != VT_EMPTY)
VariantClear(pSrc);
ar >> pSrc->vt;
// No support for VT_BYREF & VT_ARRAY
if (pSrc->vt & VT_BYREF || pSrc->vt & VT_ARRAY)
return ar;
switch (pSrc->vt)
{
case VT_BOOL:
return ar >> (WORD&)V_BOOL(pSrc);
case VT_UI1:
return ar >> pSrc->bVal;
case VT_I2:
return ar >> (WORD&)pSrc->iVal;
case VT_I4:
return ar >> pSrc->lVal;
case VT_CY:
ar >> pSrc->cyVal.Lo;
return ar >> pSrc->cyVal.Hi;
case VT_R4:
return ar >> pSrc->fltVal;
case VT_R8:
return ar >> pSrc->dblVal;
case VT_DATE:
return ar >> pSrc->date;
case VT_BSTR:
{
DWORD nLen;
ar >> nLen;
if (nLen > 0)
{
pSrc->bstrVal = SysAllocStringByteLen(NULL, nLen);
if (pSrc->bstrVal == NULL)
AfxThrowMemoryException();
ar.Read(pSrc->bstrVal, nLen * sizeof(BYTE));
}
else
pSrc->bstrVal = NULL;
return ar;
}
break;
case VT_ERROR:
return ar >> pSrc->scode;
case VT_DISPATCH:
case VT_UNKNOWN:
{
LPPERSISTSTREAM pPersistStream = NULL;
CArchiveStream stm(&ar);
// Retrieve the CLSID (GUID) and create an instance
CLSID clsid;
ar >> clsid.Data1;
ar >> clsid.Data2;
ar >> clsid.Data3;
ar.Read(&clsid.Data4[0], sizeof clsid.Data4);
// Create the object
SCODE sc = CoCreateInstance(clsid, NULL, CLSCTX_ALL | CLSCTX_REMOTE_SERVER,
pSrc->vt == VT_UNKNOWN ? IID_IUnknown : IID_IDispatch,
(void**)&pSrc->punkVal);
if (sc == E_INVALIDARG)
{
// may not support CLSCTX_REMOTE_SERVER, so try without
sc = CoCreateInstance(clsid, NULL,
CLSCTX_ALL & ~CLSCTX_REMOTE_SERVER,
pSrc->vt == VT_UNKNOWN ? IID_IUnknown : IID_IDispatch,
(void**)&pSrc->punkVal);
}
AfxCheckError(sc);
TRY
{
// QI for IPersistStream or IPeristStreamInit
sc = pSrc->punkVal->QueryInterface(
IID_IPersistStream, (void**)&pPersistStream);
#ifndef _AFX_NO_OCC_SUPPORT
if (FAILED(sc))
sc = pSrc->punkVal->QueryInterface(
IID_IPersistStreamInit, (void**)&pPersistStream);
#endif
AfxCheckError(sc);
// Always assumes object is dirty
AfxCheckError(pPersistStream->Load(&stm));
}
CATCH_ALL(e)
{
// Clean up
if (pPersistStream != NULL)
pPersistStream->Release();
pSrc->punkVal->Release();
THROW_LAST();
}
END_CATCH_ALL
pPersistStream->Release();
}
return ar;
case VT_EMPTY:
case VT_NULL:
// do nothing
return ar;
default:
ASSERT(FALSE);
return ar;
}
}
/////////////////////////////////////////////////////////////////////////////
// COleVariant Helpers
#if _MSC_VER >= 1100
template <> void AFXAPI ConstructElements<COleVariant> (COleVariant* pElements, int nCount)
#else
void AFXAPI ConstructElements(COleVariant* pElements, int nCount)
#endif
{
ASSERT(nCount == 0 ||
AfxIsValidAddress(pElements, nCount * sizeof(COleVariant)));
for (; nCount--; ++pElements)
new(pElements) COleVariant;
}
#if _MSC_VER >= 1100
template <> void AFXAPI DestructElements<COleVariant> (COleVariant* pElements, int nCount)
#else
void AFXAPI DestructElements(COleVariant* pElements, int nCount)
#endif
{
ASSERT(nCount == 0 ||
AfxIsValidAddress(pElements, nCount * sizeof(COleVariant)));
for (; nCount--; ++pElements)
pElements->~COleVariant();
}
#if _MSC_VER >= 1100
template <> void AFXAPI CopyElements<COleVariant> (COleVariant* pDest, const COleVariant* pSrc, int nCount)
#else
void AFXAPI CopyElements(COleVariant* pDest, const COleVariant* pSrc, int nCount)
#endif
{
ASSERT(nCount == 0 ||
AfxIsValidAddress(pDest, nCount * sizeof(COleVariant)));
ASSERT(nCount == 0 ||
AfxIsValidAddress(pSrc, nCount * sizeof(COleVariant)));
for (; nCount--; ++pDest, ++pSrc)
*pDest = *pSrc;
}
#if _MSC_VER >= 1100
template <> void AFXAPI SerializeElements<COleVariant> (CArchive& ar, COleVariant* pElements, int nCount)
#else
void AFXAPI SerializeElements(CArchive& ar, COleVariant* pElements, int nCount)
#endif
{
ASSERT(nCount == 0 ||
AfxIsValidAddress(pElements, nCount * sizeof(COleVariant)));
if (ar.IsStoring())
{
for (; nCount--; ++pElements)
ar << *pElements;
}
else
{
for (; nCount--; ++pElements)
ar >> *pElements;
}
}
#ifdef _DEBUG
#if _MSC_VER >= 1100
template <> void AFXAPI DumpElements<COleVariant> (CDumpContext& dc, const COleVariant* pElements, int nCount)
#else
void AFXAPI DumpElements(CDumpContext& dc, const COleVariant* pElements, int nCount)
#endif
{
for (; nCount--; ++pElements)
dc << *pElements;
}
#endif // _DEBUG
#if _MSC_VER >= 1100
template<> UINT AFXAPI HashKey<const struct tagVARIANT&> (const struct tagVARIANT& var)
#else
UINT AFXAPI HashKey(const struct tagVARIANT& var)
#endif
{
switch (var.vt)
{
case VT_EMPTY:
case VT_NULL:
return 0;
case VT_I2:
#if _MSC_VER >= 1100
return HashKey<DWORD>((DWORD)var.iVal);
#else
return HashKey((DWORD)var.iVal);
#endif
case VT_I4:
#if _MSC_VER >= 1100
return HashKey<DWORD>((DWORD)var.lVal);
#else
return HashKey((DWORD)var.lVal);
#endif
case VT_R4:
return (UINT)(var.fltVal / 16);
case VT_R8:
case VT_CY:
return (UINT)(var.dblVal / 16);
case VT_BOOL:
#if _MSC_VER >= 1100
return HashKey<DWORD>((DWORD)V_BOOL(&var));
#else
return HashKey((DWORD)V_BOOL(&var));
#endif
case VT_ERROR:
#if _MSC_VER >= 1100
return HashKey<DWORD>((DWORD)var.scode);
#else
return HashKey((DWORD)var.scode);
#endif
case VT_DATE:
return (UINT)(var.date / 16);
case VT_BSTR:
#if _MSC_VER >= 1100
return HashKey<LPCOLESTR>(var.bstrVal);
#else
return HashKey((LPCOLESTR)var.bstrVal);
#endif
case VT_DISPATCH:
case VT_UNKNOWN:
#if _MSC_VER >= 1100
return HashKey<DWORD>((DWORD)var.punkVal);
#else
return HashKey((DWORD)var.punkVal);
#endif
default:
// No support for VT_BYREF, VT_ARRAY, VT_VARIANT, VT_DECIMAL, & VT_UI1
ASSERT(FALSE);
// Fall through
}
return 0;
}
/////////////////////////////////////////////////////////////////////////////
// COleCurrency class helpers
// Return the highest order bit composing dwTarget in wBit
#define HI_BIT(dwTarget, wBit) \
do \
{ \
if (dwTarget != 0) \
for (wBit = 32; (dwTarget & (0x00000001 << (wBit-1))) == 0; wBit--);\
else \
wBit = 0; \
} while (0)
// Left shift an (assumed unsigned) currency by wBits
#define LSHIFT_UCUR(cur, wBits) \
do \
{ \
for (WORD wTempBits = wBits; wTempBits > 0; wTempBits--) \
{ \
cur.m_cur.Hi = ((DWORD)cur.m_cur.Hi << 1); \
cur.m_cur.Hi |= (cur.m_cur.Lo & 0x80000000) >> 31; \
cur.m_cur.Lo = cur.m_cur.Lo << 1; \
} \
} while (0)
// Right shift an (assumed unsigned) currency by wBits
#define RSHIFT_UCUR(cur, wBits) \
do \
{ \
for (WORD wTempBits = wBits; wTempBits > 0; wTempBits--) \
{ \
cur.m_cur.Lo = cur.m_cur.Lo >> 1; \
cur.m_cur.Lo |= (cur.m_cur.Hi & 0x00000001) << 31; \
cur.m_cur.Hi = ((DWORD)cur.m_cur.Hi >> 1); \
} \
} while (0)
/////////////////////////////////////////////////////////////////////////////
// COleCurrency class (internally currency is 8-byte int scaled by 10,000)
COleCurrency::COleCurrency(long nUnits, long nFractionalUnits)
{
SetCurrency(nUnits, nFractionalUnits);
SetStatus(valid);
}
const COleCurrency& COleCurrency::operator=(CURRENCY cySrc)
{
m_cur = cySrc;
SetStatus(valid);
return *this;
}
const COleCurrency& COleCurrency::operator=(const COleCurrency& curSrc)
{
m_cur = curSrc.m_cur;
m_status = curSrc.m_status;
return *this;
}
const COleCurrency& COleCurrency::operator=(const VARIANT& varSrc)
{
if (varSrc.vt != VT_CY)
{
TRY
{
COleVariant varTemp(varSrc);
varTemp.ChangeType(VT_CY);
m_cur = varTemp.cyVal;
SetStatus(valid);
}
// Catch COleException from ChangeType, but not CMemoryException
CATCH(COleException, e)
{
// Not able to convert VARIANT to CURRENCY
m_cur.Hi = 0;
m_cur.Lo = 0;
SetStatus(invalid);
DELETE_EXCEPTION(e);
}
END_CATCH
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -