📄 mtlcom.h
字号:
{
MTLVERIFY(::VariantClear(this) == NOERROR);
}
operator LPVARIANT()
{
return this;
}
operator LPCVARIANT() const
{
return this;
}
DWORD GetDim()
{
return ::SafeArrayGetDim(parray);
}
DWORD GetElemSize()
{
return ::SafeArrayGetElemsize(parray);
}
// Operations
void Attach(VARIANT& varSrc)
{
ATLASSERT(varSrc.vt & VT_ARRAY);
// Free up previous safe array if necessary
Clear();
// give control of data to CComSafeArray
::memcpy(this, &varSrc, sizeof(varSrc));
varSrc.vt = VT_EMPTY;
}
VARIANT Detach()
{
VARIANT varResult = *this;
vt = VT_EMPTY;
return varResult;
}
// Assignment operators
CComSafeArray& operator=(const CComSafeArray& saSrc)
{
ATLASSERT(saSrc.vt & VT_ARRAY);
MtlCheckError(::VariantCopy(this, (LPVARIANT)&saSrc));
return *this;
}
CComSafeArray& operator=(const VARIANT& varSrc)
{
ATLASSERT(varSrc.vt & VT_ARRAY);
MtlCheckError(::VariantCopy(this, (LPVARIANT)&varSrc));
return *this;
}
CComSafeArray& operator=(LPCVARIANT pSrc)
{
ATLASSERT(pSrc->vt & VT_ARRAY);
MtlCheckError(::VariantCopy(this, (LPVARIANT)pSrc));
return *this;
}
CComSafeArray& operator=(const CComVariant& varSrc)
{
ATLASSERT(varSrc.vt & VT_ARRAY);
MtlCheckError(::VariantCopy(this, (LPVARIANT)&varSrc));
return *this;
}
// Comparison operators
bool operator==(const SAFEARRAY& saSrc) const
{
return _MtlCompareSafeArrays(parray, (LPSAFEARRAY)&saSrc);
}
bool operator==(LPCSAFEARRAY pSrc) const
{
return _MtlCompareSafeArrays(parray, (LPSAFEARRAY)pSrc);
}
bool operator==(const CComSafeArray& saSrc) const
{
if (vt != saSrc.vt)
return false;
return _MtlCompareSafeArrays(parray, saSrc.parray);
}
bool operator==(const VARIANT& varSrc) const
{
if (vt != varSrc.vt)
return false;
return _MtlCompareSafeArrays(parray, varSrc.parray);
}
bool operator==(LPCVARIANT pSrc) const
{
if (vt != pSrc->vt)
return false;
return _MtlCompareSafeArrays(parray, pSrc->parray);
}
bool operator==(const CComVariant& varSrc) const
{
if (vt != varSrc.vt)
return false;
return _MtlCompareSafeArrays(parray, varSrc.parray);
}
void CreateOneDim(VARTYPE vtSrc, DWORD dwElements,
const void* pvSrcData = NULL, long nLBound = 0)
{
ATLASSERT(dwElements > 0);
// Setup the bounds and create the array
SAFEARRAYBOUND rgsabound;
rgsabound.cElements = dwElements;
rgsabound.lLbound = nLBound;
Create(vtSrc, 1, &rgsabound);
// Copy over the data if neccessary
if (pvSrcData != NULL)
{
void* pvDestData;
AccessData(&pvDestData);
memcpy(pvDestData, pvSrcData, GetElemSize() * dwElements);
UnaccessData();
}
}
DWORD GetOneDimSize()
{
ATLASSERT(GetDim() == 1);
long nUBound, nLBound;
GetUBound(1, &nUBound);
GetLBound(1, &nLBound);
return nUBound + 1 - nLBound;
}
void ResizeOneDim(DWORD dwElements)
{
ATLASSERT(GetDim() == 1);
SAFEARRAYBOUND rgsabound;
rgsabound.cElements = dwElements;
rgsabound.lLbound = 0;
Redim(&rgsabound);
}
void Create(VARTYPE vtSrc, DWORD dwDims, DWORD* rgElements)
{
ATLASSERT(rgElements != NULL);
// Allocate and fill proxy array of bounds (with lower bound of zero)
SAFEARRAYBOUND* rgsaBounds = new SAFEARRAYBOUND[dwDims];
for (DWORD dwIndex = 0; dwIndex < dwDims; dwIndex++)
{
// Assume lower bound is 0 and fill in element count
rgsaBounds[dwIndex].lLbound = 0;
rgsaBounds[dwIndex].cElements = rgElements[dwIndex];
}
Create(vtSrc, dwDims, rgsaBounds);
delete[] rgsaBounds;
}
void Create(VARTYPE vtSrc, DWORD dwDims, SAFEARRAYBOUND* rgsabound)
{
ATLASSERT(dwDims > 0);
ATLASSERT(rgsabound != NULL);
// Validate the VARTYPE for SafeArrayCreate call
ATLASSERT(!(vtSrc & VT_ARRAY));
ATLASSERT(!(vtSrc & VT_BYREF));
ATLASSERT(!(vtSrc & VT_VECTOR));
ATLASSERT(vtSrc != VT_EMPTY);
ATLASSERT(vtSrc != VT_NULL);
// Free up old safe array if necessary
Clear();
ATLTRY(parray = ::SafeArrayCreate(vtSrc, dwDims, rgsabound));
if (parray == NULL)
{
ATLTRACE2(atlTraceDBProvider, 0, "CComSafeArray::Create Error : OOM\n");
return;
}
vt = unsigned short(vtSrc | VT_ARRAY);
m_dwDims = dwDims;
m_dwElementSize = GetElemSize();
}
void AccessData(void** ppvData)
{
MtlCheckError(::SafeArrayAccessData(parray, ppvData));
}
void UnaccessData()
{
MtlCheckError(::SafeArrayUnaccessData(parray));
}
void AllocData()
{
MtlCheckError(::SafeArrayAllocData(parray));
}
void AllocDescriptor(DWORD dwDims)
{
MtlCheckError(::SafeArrayAllocDescriptor(dwDims, &parray));
}
void Copy(LPSAFEARRAY* ppsa)
{
MtlCheckError(::SafeArrayCopy(parray, ppsa));
}
void GetLBound(DWORD dwDim, long* pLbound)
{
MtlCheckError(::SafeArrayGetLBound(parray, dwDim, pLbound));
}
void GetUBound(DWORD dwDim, long* pUbound)
{
MtlCheckError(::SafeArrayGetUBound(parray, dwDim, pUbound));
}
void GetElement(long* rgIndices, void* pvData)
{
MtlCheckError(::SafeArrayGetElement(parray, rgIndices, pvData));
}
void PtrOfIndex(long* rgIndices, void** ppvData)
{
MtlCheckError(::SafeArrayPtrOfIndex(parray, rgIndices, ppvData));
}
void PutElement(long* rgIndices, void* pvData)
{
MtlCheckError(::SafeArrayPutElement(parray, rgIndices, pvData));
}
void Redim(SAFEARRAYBOUND* psaboundNew)
{
MtlCheckError(::SafeArrayRedim(parray, psaboundNew));
}
void Lock()
{
MtlCheckError(::SafeArrayLock(parray));
}
void Unlock()
{
MtlCheckError(::SafeArrayUnlock(parray));
}
void Destroy()
{
MtlCheckError(::SafeArrayDestroy(parray));
}
void DestroyData()
{
MtlCheckError(::SafeArrayDestroyData(parray));
}
void DestroyDescriptor()
{
MtlCheckError(::SafeArrayDestroyDescriptor(parray));
}
};
/////////////////////////////////////////////////////////////////////////////
// Helper for iter to CComSafeArray
inline void _MtlCreateOneDimArray(VARIANT& varSrc, DWORD dwSize)
{
UINT nDim;
// Clear VARIANT and re-create SafeArray if necessary
if (varSrc.vt != (VT_UI1 | VT_ARRAY) ||
(nDim = ::SafeArrayGetDim(varSrc.parray)) != 1)
{
MTLVERIFY(::VariantClear(&varSrc) == NOERROR);
varSrc.vt = VT_UI1 | VT_ARRAY;
SAFEARRAYBOUND bound;
bound.cElements = dwSize;
bound.lLbound = 0;
ATLTRY(varSrc.parray = ::SafeArrayCreate(VT_UI1, 1, &bound));
if (varSrc.parray == NULL)
ATLTRACE2(atlTraceDBProvider, 0, "MtlCheckError Error : OOM\n");
}
else
{
// Must redimension array if necessary
long lLower, lUpper;
MtlCheckError(::SafeArrayGetLBound(varSrc.parray, 1, &lLower));
MtlCheckError(::SafeArrayGetUBound(varSrc.parray, 1, &lUpper));
// Upper bound should always be greater than lower bound
long lSize = lUpper - lLower;
if (lSize < 0)
{
ATLASSERT(FALSE);
lSize = 0;
}
if ((DWORD)lSize != dwSize)
{
SAFEARRAYBOUND bound;
bound.cElements = dwSize;
bound.lLbound = lLower;
MtlCheckError(::SafeArrayRedim(varSrc.parray, &bound));
}
}
}
inline void _MtlCopyBinaryData(SAFEARRAY* parray, const void* pvSrc, DWORD dwSize)
{
// Access the data, copy it and unaccess it.
void* pDest;
MtlCheckError(::SafeArrayAccessData(parray, &pDest));
::memcpy(pDest, pvSrc, dwSize);
MtlCheckError(::SafeArrayUnaccessData(parray));
}
inline void MtlInitVariantFromArray(CComVariant& v, CSimpleArray<BYTE>& arrSrc)
{
int nSize = arrSrc.GetSize();
// Set the correct type and make sure SafeArray can hold data
_MtlCreateOneDimArray(v, (DWORD)nSize);
// Copy the data into the SafeArray
_MtlCopyBinaryData(v.parray, arrSrc.GetData(), (DWORD)nSize);
}
inline void MtlInitVariantFromItemIDList(CComVariant& v, LPCITEMIDLIST pidl)
{
if (pidl != NULL)
{
// walk through entries in the list and accumulate their size
UINT cbTotal = 0;
SAFEARRAY *psa = NULL;
LPCITEMIDLIST pidlWalker = pidl;
while (pidlWalker->mkid.cb)
{
cbTotal += pidlWalker->mkid.cb;
pidlWalker = (LPCITEMIDLIST)
(((LPBYTE)pidlWalker) + pidlWalker->mkid.cb);
}
// add the base structure size
cbTotal += sizeof(ITEMIDLIST);
// get a safe array for them
psa = ::SafeArrayCreateVector(VT_UI1, 0, cbTotal);
// copy it and set members
if (psa != NULL)
{
::memcpy(psa->pvData, (LPBYTE) pidl, cbTotal);
v.vt = VT_ARRAY | VT_UI1;
v.parray = psa;
}
}
}
////////////////////////////////////////////////////////////////////////////
} // namespace MTL
#endif // __MTLCOM_H__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -