⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 olevar.cpp

📁 c语言编程软件vc6.0中文绿色版_vc6.0官方下载
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.

#include "stdafx.h"
#include <afxtempl.h>
#include <math.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// helpers

void AFXAPI AfxCheckError(SCODE sc)
{
	if (FAILED(sc))
	{
		if (sc == E_OUTOFMEMORY)
			AfxThrowMemoryException();
		else
			AfxThrowOleException(sc);
	}
}

AFX_STATIC BOOL AFXAPI _AfxCompareSafeArrays(SAFEARRAY* parray1, SAFEARRAY* parray2)
{
	BOOL bCompare = FALSE;

	// If one is NULL they must both be NULL to compare
	if (parray1 == NULL || parray2 == NULL)
	{
		return parray1 == parray2;
	}

	// Dimension must match and if 0, then arrays compare
	DWORD dwDim1 = ::SafeArrayGetDim(parray1);
	DWORD dwDim2 = ::SafeArrayGetDim(parray2);
	if (dwDim1 != dwDim2)
		return FALSE;
	else if (dwDim1 == 0)
		return TRUE;

	// Element size must match
	DWORD dwSize1 = ::SafeArrayGetElemsize(parray1);
	DWORD dwSize2 = ::SafeArrayGetElemsize(parray2);
	if (dwSize1 != dwSize2)
		return FALSE;

	long* pLBound1 = NULL;
	long* pLBound2 = NULL;
	long* pUBound1 = NULL;
	long* pUBound2 = NULL;

	void* pData1 = NULL;
	void* pData2 = NULL;

	TRY
	{
		// Bounds must match
		pLBound1 = new long[dwDim1];
		pLBound2 = new long[dwDim2];
		pUBound1 = new long[dwDim1];
		pUBound2 = new long[dwDim2];

		size_t nTotalElements = 1;

		// Get and compare bounds
		for (DWORD dwIndex = 0; dwIndex < dwDim1; dwIndex++)
		{
			AfxCheckError(::SafeArrayGetLBound(
				parray1, dwIndex+1, &pLBound1[dwIndex]));
			AfxCheckError(::SafeArrayGetLBound(
				parray2, dwIndex+1, &pLBound2[dwIndex]));
			AfxCheckError(::SafeArrayGetUBound(
				parray1, dwIndex+1, &pUBound1[dwIndex]));
			AfxCheckError(::SafeArrayGetUBound(
				parray2, dwIndex+1, &pUBound2[dwIndex]));

			// Check the magnitude of each bound
			if (pUBound1[dwIndex] - pLBound1[dwIndex] !=
				pUBound2[dwIndex] - pLBound2[dwIndex])
			{
				delete[] pLBound1;
				delete[] pLBound2;
				delete[] pUBound1;
				delete[] pUBound2;

				return FALSE;
			}

			// Increment the element count
			nTotalElements *= pUBound1[dwIndex] - pLBound1[dwIndex] + 1;
		}

		// Access the data
		AfxCheckError(::SafeArrayAccessData(parray1, &pData1));
		AfxCheckError(::SafeArrayAccessData(parray2, &pData2));

		// Calculate the number of bytes of data and compare
		size_t nSize = nTotalElements * dwSize1;
		int nOffset = memcmp(pData1, pData2, nSize);
		bCompare = nOffset == 0;

		// Release the array locks
		AfxCheckError(::SafeArrayUnaccessData(parray1));
		AfxCheckError(::SafeArrayUnaccessData(parray2));
	}
	CATCH_ALL(e)
	{
		// Clean up bounds arrays
		delete[] pLBound1;
		delete[] pLBound2;
		delete[] pUBound1;
		delete[] pUBound2;

		// Release the array locks
		if (pData1 != NULL)
			AfxCheckError(::SafeArrayUnaccessData(parray1));
		if (pData2 != NULL)
			AfxCheckError(::SafeArrayUnaccessData(parray2));

		THROW_LAST();
	}
	END_CATCH_ALL

	// Clean up bounds arrays
	delete[] pLBound1;
	delete[] pLBound2;
	delete[] pUBound1;
	delete[] pUBound2;

	return bCompare;
}

AFX_STATIC void AFXAPI _AfxCreateOneDimArray(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)
	{
		VERIFY(::VariantClear(&varSrc) == NOERROR);
		varSrc.vt = VT_UI1 | VT_ARRAY;

		SAFEARRAYBOUND bound;
		bound.cElements = dwSize;
		bound.lLbound = 0;
		varSrc.parray = ::SafeArrayCreate(VT_UI1, 1, &bound);
		if (varSrc.parray == NULL)
			AfxThrowMemoryException();
	}
	else
	{
		// Must redimension array if necessary
		long lLower, lUpper;
		AfxCheckError(::SafeArrayGetLBound(varSrc.parray, 1, &lLower));
		AfxCheckError(::SafeArrayGetUBound(varSrc.parray, 1, &lUpper));

		// Upper bound should always be greater than lower bound
		long lSize = lUpper - lLower;
		if (lSize < 0)
		{
			ASSERT(FALSE);
			lSize = 0;

		}

		if ((DWORD)lSize != dwSize)
		{
			SAFEARRAYBOUND bound;
			bound.cElements = dwSize;
			bound.lLbound = lLower;
			AfxCheckError(::SafeArrayRedim(varSrc.parray, &bound));
		}
	}
}

AFX_STATIC void AFXAPI _AfxCopyBinaryData(SAFEARRAY* parray, const void* pvSrc, DWORD dwSize)
{
	// Access the data, copy it and unaccess it.
	void* pDest;
	AfxCheckError(::SafeArrayAccessData(parray, &pDest));
	memcpy(pDest, pvSrc, dwSize);
	AfxCheckError(::SafeArrayUnaccessData(parray));
}

/////////////////////////////////////////////////////////////////////////////
// COleVariant class

COleVariant::COleVariant(const VARIANT& varSrc)
{
	AfxVariantInit(this);
	AfxCheckError(::VariantCopy(this, (LPVARIANT)&varSrc));
}

COleVariant::COleVariant(LPCVARIANT pSrc)
{
	AfxVariantInit(this);
	AfxCheckError(::VariantCopy(this, (LPVARIANT)pSrc));
}

COleVariant::COleVariant(const COleVariant& varSrc)
{
	AfxVariantInit(this);
	AfxCheckError(::VariantCopy(this, (LPVARIANT)&varSrc));
}

COleVariant::COleVariant(LPCTSTR lpszSrc, VARTYPE vtSrc)
{
	USES_CONVERSION;
	ASSERT(vtSrc == VT_BSTR || vtSrc == VT_BSTRT);
	UNUSED(vtSrc);

	vt = VT_BSTR;
	bstrVal = NULL;

	if (lpszSrc != NULL)
	{
#ifndef _UNICODE
		if (vtSrc == VT_BSTRT)
		{
			int nLen = lstrlen(lpszSrc);
			bstrVal = ::SysAllocStringByteLen(lpszSrc, nLen);
		}
		else
#endif
		{
			bstrVal = ::SysAllocString(T2COLE(lpszSrc));
		}

		if (bstrVal == NULL)
			AfxThrowMemoryException();
	}
}



void COleVariant::SetString(LPCTSTR lpszSrc, VARTYPE vtSrc)
{
	USES_CONVERSION;
	ASSERT(vtSrc == VT_BSTR || vtSrc == VT_BSTRT);
	UNUSED(vtSrc);

	// Free up previous VARIANT
	Clear();

	vt = VT_BSTR;
	bstrVal = NULL;

	if (lpszSrc != NULL)
	{
#ifndef _UNICODE
		if (vtSrc == VT_BSTRT)
		{
			int nLen = lstrlen(lpszSrc);
			bstrVal = ::SysAllocStringByteLen(lpszSrc, nLen);
		}
		else
#endif
		{
			bstrVal = ::SysAllocString(T2COLE(lpszSrc));
		}

		if (bstrVal == NULL)
			AfxThrowMemoryException();
	}
}

COleVariant::COleVariant(short nSrc, VARTYPE vtSrc)
{
	ASSERT(vtSrc == VT_I2 || vtSrc == VT_BOOL);

	if (vtSrc == VT_BOOL)
	{
		vt = VT_BOOL;
		if (!nSrc)
			V_BOOL(this) = AFX_OLE_FALSE;
		else
			V_BOOL(this) = AFX_OLE_TRUE;
	}
	else
	{
		vt = VT_I2;
		iVal = nSrc;
	}
}

COleVariant::COleVariant(long lSrc, VARTYPE vtSrc)
{
	ASSERT(vtSrc == VT_I4 || vtSrc == VT_ERROR || vtSrc == VT_BOOL);

	if (vtSrc == VT_ERROR)
	{
		vt = VT_ERROR;
		scode = lSrc;
	}
	else if (vtSrc == VT_BOOL)
	{
		vt = VT_BOOL;
		if (!lSrc)
			V_BOOL(this) = AFX_OLE_FALSE;
		else
			V_BOOL(this) = AFX_OLE_TRUE;
	}
	else
	{
		vt = VT_I4;
		lVal = lSrc;
	}
}

// Operations
void COleVariant::_ClearCompat()
{
	Clear();
}

void COleVariant::ChangeType(VARTYPE vartype, LPVARIANT pSrc)
{
	// If pSrc is NULL, convert type in place
	if (pSrc == NULL)
		pSrc = this;
	if (pSrc != this || vartype != vt)
		AfxCheckError(::VariantChangeType(this, pSrc, 0, vartype));
}

void COleVariant::Attach(VARIANT& varSrc)
{
	// Free up previous VARIANT
	Clear();

	// give control of data to COleVariant
	memcpy(this, &varSrc, sizeof(varSrc));
	varSrc.vt = VT_EMPTY;
}

VARIANT COleVariant::Detach()
{
	VARIANT varResult = *this;
	vt = VT_EMPTY;
	return varResult;
}

// Literal comparison. Types and values must match.
BOOL COleVariant::operator==(const VARIANT& var) const
{
	if (&var == this)
		return TRUE;

	// Variants not equal if types don't match
	if (var.vt != vt)
		return FALSE;

	// Check type specific values
	switch (vt)
	{
	case VT_EMPTY:
	case VT_NULL:
		return TRUE;

	case VT_BOOL:
		return V_BOOL(&var) == V_BOOL(this);

	case VT_UI1:
		return var.bVal == bVal;

	case VT_I2:
		return var.iVal == iVal;

	case VT_I4:
		return var.lVal == lVal;

	case VT_CY:
		return (var.cyVal.Hi == cyVal.Hi && var.cyVal.Lo == cyVal.Lo);

	case VT_R4:
		return var.fltVal == fltVal;

	case VT_R8:
		return var.dblVal == dblVal;

	case VT_DATE:
		return var.date == date;

	case VT_BSTR:
		return SysStringByteLen(var.bstrVal) == SysStringByteLen(bstrVal) &&
			memcmp(var.bstrVal, bstrVal, SysStringByteLen(bstrVal)) == 0;

	case VT_ERROR:
		return var.scode == scode;

	case VT_DISPATCH:
	case VT_UNKNOWN:
		return var.punkVal == punkVal;

	default:
		if (vt & VT_ARRAY && !(vt & VT_BYREF))
			return _AfxCompareSafeArrays(var.parray, parray);
		else
			ASSERT(FALSE);  // VT_BYREF not supported
		// fall through
	}

	return FALSE;
}

const COleVariant& COleVariant::operator=(const VARIANT& varSrc)
{
	AfxCheckError(::VariantCopy(this, (LPVARIANT)&varSrc));
	return *this;
}

const COleVariant& COleVariant::operator=(LPCVARIANT pSrc)
{
	AfxCheckError(::VariantCopy(this, (LPVARIANT)pSrc));
	return *this;
}

const COleVariant& COleVariant::operator=(const COleVariant& varSrc)
{
	AfxCheckError(::VariantCopy(this, (LPVARIANT)&varSrc));
	return *this;
}

const COleVariant& COleVariant::operator=(const LPCTSTR lpszSrc)
{
	USES_CONVERSION;
	// Free up previous VARIANT
	Clear();

	vt = VT_BSTR;
	if (lpszSrc == NULL)
		bstrVal = NULL;
	else
	{
		bstrVal = ::SysAllocString(T2COLE(lpszSrc));
		if (bstrVal == NULL)
			AfxThrowMemoryException();
	}
	return *this;
}

const COleVariant& COleVariant::operator=(const CString& strSrc)
{
	USES_CONVERSION;
	// Free up previous VARIANT
	Clear();

	vt = VT_BSTR;
	bstrVal = ::SysAllocString(T2COLE(strSrc));
	if (bstrVal == NULL)
		AfxThrowMemoryException();

	return *this;
}

const COleVariant& COleVariant::operator=(BYTE nSrc)
{
	// Free up previous VARIANT if necessary
	if (vt != VT_UI1)
	{
		Clear();
		vt = VT_UI1;
	}

	bVal = nSrc;
	return *this;
}

const COleVariant& COleVariant::operator=(short nSrc)
{
	if (vt == VT_I2)
		iVal = nSrc;
	else if (vt == VT_BOOL)
	{
		if (!nSrc)
			V_BOOL(this) = AFX_OLE_FALSE;
		else
			V_BOOL(this) = AFX_OLE_TRUE;
	}
	else
	{
		// Free up previous VARIANT
		Clear();
		vt = VT_I2;
		iVal = nSrc;
	}

	return *this;
}

const COleVariant& COleVariant::operator=(long lSrc)
{
	if (vt == VT_I4)
		lVal = lSrc;
	else if (vt == VT_ERROR)
		scode = lSrc;
	else if (vt == VT_BOOL)
	{
		if (!lSrc)
			V_BOOL(this) = AFX_OLE_FALSE;
		else
			V_BOOL(this) = AFX_OLE_TRUE;
	}
	else
	{
		// Free up previous VARIANT
		Clear();
		vt = VT_I4;
		lVal = lSrc;
	}

	return *this;
}

const COleVariant& COleVariant::operator=(const COleCurrency& curSrc)
{
	// Free up previous VARIANT if necessary
	if (vt != VT_CY)
	{
		Clear();
		vt = VT_CY;
	}

	cyVal = curSrc.m_cur;
	return *this;
}

const COleVariant& COleVariant::operator=(float fltSrc)
{
	// Free up previous VARIANT if necessary
	if (vt != VT_R4)
	{
		Clear();
		vt = VT_R4;
	}

	fltVal = fltSrc;
	return *this;
}

const COleVariant& COleVariant::operator=(double dblSrc)
{
	// Free up previous VARIANT if necessary
	if (vt != VT_R8)
	{
		Clear();
		vt = VT_R8;
	}

	dblVal = dblSrc;
	return *this;
}

const COleVariant& COleVariant::operator=(const COleDateTime& dateSrc)
{
	// Free up previous VARIANT if necessary

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -