#include "stdafx.h"
#include <comutil.h>
#include "SgxVariant.h"
CSgxVariant::CSgxVariant(void)
{
}
CSgxVariant::CSgxVariant(VARTYPE vtNew, ULONG nCount, void* pData)
{
Redim(nCount, vtNew);
int nElementSize = GetElementSizeFromVt(vtNew);
if(nElementSize >= 0 && pData != NULL)
SetData(pData, nCount, nElementSize);
}
CSgxVariant::CSgxVariant(VARIANT v) : _variant_t(v) {}
CSgxVariant::~CSgxVariant(void)
{
}
VARTYPE CSgxVariant::GetDataType()
{
VARTYPE vta;
if (IsArray())
{
SAFEARRAY** ppArr = GetSafeArrayPtrPtr();
if (*ppArr == NULL) //空数组
return VT_ERROR;
HRESULT hr = SafeArrayGetVartype(*ppArr, &vta);
if (FAILED(hr))
{
ASSERT(FALSE);
return VT_ERROR;
}
return vta;
}
else
{
return vt;
}
}
int CSgxVariant::GetArrayType()
{
//支持四种形式, 1 传值模式的数组,vt : VT_ARRAY parray保存
// 2 引用形式的数组,vt: VT_ARRAY | VT_BYREFT pparray保存
// 3 引用传递VARIANT,vt:VT_BYREF | VT_VARIANT , pvarVal->vt: VT_ARRAY pvarVal->parray 或 4 pvalVal->pparray保存
if(vt & VT_ARRAY )
{
if(vt & VT_BYREF)
return VARIANT_ARRAY_TYPE_PP;
else
return VARIANT_ARRAY_TYPE_P;
}
else if(vt & VT_BYREF && vt & VT_VARIANT && pvarVal->vt & VT_ARRAY )
{
if(pvarVal->vt & VT_BYREF)
return VARIANT_ARRAY_TYPE_V_PP;
else
return VARIANT_ARRAY_TYPE_V_P;
}
return 0;
}
VARTYPE CSgxVariant::GetArrayVT()
{
if(vt & VT_ARRAY )
{
return vt;
}
else if(vt & VT_BYREF && vt & VT_VARIANT && pvarVal->vt & VT_ARRAY )
{
return pvarVal->vt;
}
return 0;
}
BOOL CSgxVariant::IsArray()
{
return GetArrayType() > 0;
}
SAFEARRAY** CSgxVariant::GetSafeArrayPtrPtr()
{
int nType = GetArrayType();
ASSERT(nType > 0);
switch (nType)
{
case VARIANT_ARRAY_TYPE_P:
return &parray;
break;
case VARIANT_ARRAY_TYPE_PP:
return pparray;
break;
case VARIANT_ARRAY_TYPE_V_P:
return &pvarVal->parray;
break;
case VARIANT_ARRAY_TYPE_V_PP:
return pvarVal->pparray;
break;
}
return NULL;
}
void* CSgxVariant::GetArrayData()
{
SAFEARRAY** ppArr = GetSafeArrayPtrPtr();
if(ppArr == NULL)
return NULL;
else
return (*ppArr)->pvData;
}
long CSgxVariant::GetDimensions()
{
SAFEARRAY** ppArr = GetSafeArrayPtrPtr();
if(ppArr == NULL)
return -1;
return (*ppArr)->cDims;
}
long CSgxVariant::GetSize()
{
SAFEARRAY** ppArr = GetSafeArrayPtrPtr();
if(ppArr == NULL)
return -1;
ASSERT((*ppArr)->cDims == 1);
return (*ppArr)->rgsabound[0].cElements;
}
long CSgxVariant::GetSize(long nDim)
{
SAFEARRAY** ppArr = GetSafeArrayPtrPtr();
if(ppArr == NULL)
return -1;
long Lbound, Ubound;
SafeArrayGetLBound(*ppArr, nDim + 1, &Lbound);//nDim base 1
SafeArrayGetUBound(*ppArr, nDim + 1, &Ubound);//nDim base 1
return Ubound - Lbound + 1;
//return (*ppArr)->rgsabound[nDim].cElements;
}
BOOL CSgxVariant::Redim(long n1, VARTYPE vtNew)
{
ASSERT(n1 >=0);
SAFEARRAYBOUND MyBound[1];
MyBound[0].cElements = n1;
MyBound[0].lLbound = 0;
if(!(vt & VT_ARRAY) || GetDataType() != vtNew)
{
VariantInit(this);
vt = VT_ARRAY | vtNew;
this->parray=SafeArrayCreateVector(vtNew, 0, n1);
if (parray == NULL)
return FALSE;
}
else
{
SAFEARRAY** ppArr = GetSafeArrayPtrPtr();
HRESULT hr = SafeArrayRedim(*ppArr, MyBound);
if (FAILED(hr))
return FALSE;
}
if (vtNew == VT_BSTR)
_InitBStrArray();
return TRUE;
}
BOOL CSgxVariant::Redim(long n1, long n2, VARTYPE vtNew)
{
ASSERT(n1 >=0 && n2 >=0);
SAFEARRAYBOUND MyBound[2];
MyBound[0].cElements = n1;
MyBound[0].lLbound = 0;
MyBound[1].cElements = n2;
MyBound[1].lLbound = 0;
if (!(vt & VT_ARRAY) || GetDataType() != vtNew)
{
VariantInit(this);
vt = VT_ARRAY | vtNew;
this->parray=SafeArrayCreate(vtNew, 2, MyBound);
if (parray == NULL)
return FALSE;
}
else
{
SAFEARRAY** ppArr = GetSafeArrayPtrPtr();
if (*ppArr != NULL)
SafeArrayDestroy(*ppArr);
*ppArr = SafeArrayCreate(vtNew, 2, MyBound);
if (*ppArr == NULL)
return FALSE;
//return SafeArrayRedim(*ppArr, MyBound) == S_OK;
}
return TRUE;
}
BOOL CSgxVariant::Redim(long n1, long n2, long n3, VARTYPE vtNew)
{
ASSERT(n1 >=0 && n2 >=0 && n3 >= 0);
SAFEARRAYBOUND MyBound[3];
MyBound[0].cElements = n1;
MyBound[0].lLbound = 0;
MyBound[1].cElements = n2;
MyBound[1].lLbound = 0;
MyBound[2].cElements = n3;
MyBound[2].lLbound = 0;
if (!(vt & VT_ARRAY) || GetDataType() != vtNew)
{
VariantInit(this);
vt = VT_ARRAY | vtNew;
this->parray=SafeArrayCreate(vtNew, 3, MyBound);
if (parray == NULL)
return FALSE;
}
else
{
SAFEARRAY** ppArr = GetSafeArrayPtrPtr();
if (*ppArr != NULL)
SafeArrayDestroy(*ppArr);
*ppArr = SafeArrayCreate(vtNew, 3, MyBound);
if (*ppArr == NULL)
return FALSE;
//return SafeArrayRedim(*ppArr, MyBound) == S_OK;
}
return TRUE;
}
BOOL CSgxVariant::Redim(long n1, long n2, long n3, long n4, VARTYPE vtNew)
{
ASSERT(n1 >= 0 && n2 >= 0 && n3 >= 0 && n4 >= 0);
SAFEARRAYBOUND MyBound[4];
MyBound[0].cElements = n1;
MyBound[0].lLbound = 0;
MyBound[1].cElements = n2;
MyBound[1].lLbound = 0;
MyBound[2].cElements = n3;
MyBound[2].lLbound = 0;
MyBound[3].cElements = n4;
MyBound[3].lLbound = 0;
if (!(vt & VT_ARRAY) || GetDataType() != vtNew)
{
VariantInit(this);
vt = VT_ARRAY | vtNew;
this->parray=SafeArrayCreate(vtNew, 3, MyBound);
if (parray == NULL)
return FALSE;
}
else
{
SAFEARRAY** ppArr = GetSafeArrayPtrPtr();
if (*ppArr != NULL)
SafeArrayDestroy(*ppArr);
*ppArr = SafeArrayCreate(vtNew, 4, MyBound);
if (*ppArr == NULL)
return FALSE;
//return SafeArrayRedim(*ppArr, MyBound) == S_OK;
}
return TRUE;
}
BOOL CSgxVariant::RedimPreserve(long nNewCount)
{
ASSERT(nNewCount >= 0);
SAFEARRAY** ppArr = GetSafeArrayPtrPtr();
if(ppArr == NULL)
return FALSE;
int nElementSize = GetElementSizeFromVt(vt);
if(nElementSize <= 0)
return FALSE;
//保留原始数据
BYTE* pNewData=NULL, *pOldData=(BYTE*)(*ppArr)->pvData;
try{
pNewData= new BYTE[nNewCount * nElementSize];
}
catch(...)
{
return FALSE;
}
int nCopyCount;
if(nNewCount < GetSize())//缩小数组
nCopyCount=nNewCount;
else //增大数组
{
nCopyCount=GetSize();
ZeroMemory(pNewData + nCopyCount*nElementSize,(nNewCount-GetSize())* nElementSize);
}
memcpy(pNewData, pOldData, nElementSize*nCopyCount);
//重新设置大小
SAFEARRAYBOUND BoundNew[1];
BoundNew[0].cElements = nNewCount;
BoundNew[0].lLbound = 0;
SafeArrayRedim(*ppArr,BoundNew);
//赋值
//ULONG i;
//long ix[1];
//BYTE* p = pNewData;
//for(i=0; i<nNewCount; ++i)
//{
// ix[0]=i;
// SafeArrayPutElement(parray, ix, (void *)p);
// p += nElementSize;
//}
BOOL bRet = SetData((void*)pNewData, nNewCount, nElementSize);
//清理
delete [] pNewData;
return bRet;
}
BOOL CSgxVariant::SetData(void* pData, long nCount, int nElemenstSize)
{
long nOldCount=GetSize();
ASSERT(!(nOldCount < 1 || nCount > nOldCount || nElemenstSize <= 0));
if(nOldCount < 1 || nCount > nOldCount || nElemenstSize <= 0)
return FALSE;
if(pData == NULL || nCount == 0)
return TRUE;
SAFEARRAY** ppArr = GetSafeArrayPtrPtr();
if(ppArr == NULL)
return FALSE;
ASSERT((*ppArr)->cbElements == nElemenstSize);
BYTE* p = (BYTE*)pData;
long ix[1];
//指定的数据个数不够
if(!::AfxIsValidAddress(p, nElemenstSize * nCount, TRUE))
return FALSE;
for(long i = 0; i < nCount; i++)
{
ix[0]=i;
SafeArrayPutElement(*ppArr, ix, (void *)p);
p += nElemenstSize;
}
return TRUE;
}
//static functions
long CSgxVariant::_GetSize(VARIANT& v)
{
CSgxVariant sv;
sv.Attach(v);
long nSize = sv.GetSize();
v = sv.Detach();
return nSize;
}
BOOL CSgxVariant::EqualVt(VARTYPE vt1, VARTYPE vt2)
{
NormalizeVt(vt1);
Normaliz
没有合适的资源?快使用搜索试试~ 我知道了~
SegeX SgxVariant:VC封装支持多维数组的变体类型(VRIANT 、SafeArray)(免费免积分)
共2个文件
h:1个
cpp:1个
需积分: 6 2 下载量 16 浏览量
2022-12-30
16:58:03
上传
评论
收藏 6KB RAR 举报
温馨提示
SegeX组件之一:CSgxVariant。VRIANT变体类型是Com技术中的一种标准数据类型,Vb中的变体也是这种类型,在针对Com编程过程中,比如AutoCAD、Surfer、Excel、Word中使用自动化Automation(OLE)功能时,经常遇到VARIANT数组的情况,在VC中使用VARIANT数组很繁琐,特别是多维数组。CSgxVariant封装了VARIANT,具备以下主要功能:1)使用方便,最多4维数组的支持;2)使用VARIANT数组类似于CArray、vector,也类似与Vb中的动态数组;3)支持CArray、vector与VARIANT的转换(1~4维)。代码适用于VC2012及以上的Windows程序。 使用方法见代码中的CSgxVariant::Test()函数。
资源推荐
资源详情
资源评论
收起资源包目录
SgxVariant.rar (2个子文件)
SgxVariant.h 15KB
SgxVariant.cpp 24KB
共 2 条
- 1
资源评论
哆啦刘小洋
- 粉丝: 359
- 资源: 5
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功