You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
496 lines
12 KiB
496 lines
12 KiB
//*************************************************************
|
|
//
|
|
// Copyright (c) Microsoft Corporation 1999 - 2000
|
|
// All rights reserved
|
|
//
|
|
// variant.hxx
|
|
//
|
|
//*************************************************************
|
|
|
|
#include "rsop.hxx"
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CVariant::CVariant
|
|
//
|
|
// Purpose: Constructor for CVariant class. Initializes the
|
|
// storage of the variant data.
|
|
//
|
|
// Params: none
|
|
//
|
|
// Return value: none
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
CVariant::CVariant() :
|
|
_iCurrentArrayIndex(0),
|
|
_cMaxArrayElements(0)
|
|
{
|
|
VariantInit(&_var);
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CVariant::~CVariant
|
|
//
|
|
// Purpose: Denstructor for CVariant class. Frees any data
|
|
// allocated to store variant data.
|
|
//
|
|
// Params: none
|
|
//
|
|
// Return value: none
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
CVariant::~CVariant()
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = VariantClear(&_var);
|
|
|
|
ASSERT(SUCCEEDED(hr));
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CVariant::SetStringValue
|
|
//
|
|
// Purpose: Sets the type of the variant to VT_BSTR and creates
|
|
// a bstr to store the string.
|
|
//
|
|
// Params: wszValue -- this unicode string is the value to
|
|
// which we want to set this variant
|
|
//
|
|
// Return value: returns S_OK if successful, other
|
|
// error code if not
|
|
//
|
|
// Notes: The variant should not be set to a value after
|
|
// this is called -- otherwise, you may lose reference
|
|
// to allocated memory -- the value is meant to be set
|
|
// only once.
|
|
//
|
|
//------------------------------------------------------------
|
|
HRESULT CVariant::SetStringValue(WCHAR* wszValue)
|
|
{
|
|
XBStr xString;
|
|
|
|
ASSERT(VT_EMPTY == _var.vt);
|
|
|
|
xString = wszValue;
|
|
|
|
if (!xString)
|
|
{
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
_var.vt = VT_BSTR;
|
|
_var.bstrVal = xString.Acquire();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CVariant::SetLongValue
|
|
//
|
|
// Purpose: Sets the type of the variant to VT_I4 and creates
|
|
// a bstr to store the string.
|
|
//
|
|
// Params: lValue -- this LONG value is the value to
|
|
// which we want to set this variant
|
|
//
|
|
// Return value: returns S_OK if successful, other
|
|
// error code if not
|
|
//
|
|
// Notes: The variant should not be set to a value after
|
|
// this is called -- otherwise, you may lose reference
|
|
// to allocated memory -- the value is meant to be set
|
|
// only once.
|
|
//
|
|
//------------------------------------------------------------
|
|
HRESULT CVariant::SetLongValue(LONG lValue)
|
|
{
|
|
ASSERT(VT_EMPTY == _var.vt);
|
|
|
|
_var.vt = VT_I4;
|
|
_var.lVal = lValue;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CVariant::SetBoolValue
|
|
//
|
|
// Purpose: Sets the type of the variant to VT_BOOL and stores the value
|
|
//
|
|
// Params: bValue -- this boolean value is the value to
|
|
// which we want to set this variant
|
|
//
|
|
// Return value: returns S_OK if successful, other
|
|
// error code if not
|
|
//
|
|
// Notes: The variant should not be set to a value after
|
|
// this is called -- otherwise, you may lose reference
|
|
// to allocated memory -- the value is meant to be set
|
|
// only once.
|
|
//
|
|
//------------------------------------------------------------
|
|
HRESULT CVariant::SetBoolValue(BOOL bValue)
|
|
{
|
|
ASSERT(VT_EMPTY == _var.vt);
|
|
|
|
_var.vt = VT_BOOL;
|
|
_var.boolVal = bValue ? VARIANT_TRUE : VARIANT_FALSE;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CVariant::SetNextLongArrayElement
|
|
//
|
|
// Purpose: Adds an element in an array of strings to a
|
|
// specified string
|
|
//
|
|
// Params: Value -- the value to which to add as an element
|
|
// cMaxElements (optional) -- the maximum number
|
|
// of elements in this array -- must be specified
|
|
// the first time this method is called on this object
|
|
//
|
|
// Return value: returns S_OK if successful, other
|
|
// error code if not
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
HRESULT CVariant::SetNextLongArrayElement(
|
|
LONG Value,
|
|
DWORD cMaxElements)
|
|
{
|
|
HRESULT hr;
|
|
|
|
//
|
|
// Add the long to the correct index
|
|
// in the array
|
|
//
|
|
hr = SetNextArrayElement(
|
|
VT_I4,
|
|
cMaxElements,
|
|
&Value);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CVariant::SetNextStringArrayElement
|
|
//
|
|
// Purpose: Adds an element to an array of strings
|
|
//
|
|
// Params: wszValue -- the value to which to add as an element
|
|
// cMaxElements (optional) -- the maximum number
|
|
// of elements in this array -- must be specified
|
|
// the first time this method is called on this object
|
|
//
|
|
// Return value: returns S_OK if successful, other
|
|
// error code if not
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
HRESULT CVariant::SetNextStringArrayElement(
|
|
WCHAR* wszValue,
|
|
DWORD cMaxElements)
|
|
{
|
|
HRESULT hr;
|
|
XBStr xString;
|
|
|
|
//
|
|
// Create a bstr from the supplied unicode string
|
|
//
|
|
xString = wszValue;
|
|
|
|
if (!xString)
|
|
{
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
//
|
|
// Now add the unicode string to the correct index
|
|
// in the array
|
|
//
|
|
hr = SetNextArrayElement(
|
|
VT_BSTR,
|
|
cMaxElements,
|
|
xString);
|
|
|
|
//
|
|
// If we've succeeded in setting the element, it now
|
|
// owns the reference, so we release our reference
|
|
//
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
(void) xString.Acquire();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CVariant::SetNextByteArrayElement
|
|
//
|
|
// Purpose: Adds an element in an array of bytes to a byte array
|
|
//
|
|
// Params: byteValue -- the value to which to add as an element
|
|
// cMaxElements (optional) -- the maximum number
|
|
// of elements in this array -- must be specified
|
|
// the first time this method is called on this object
|
|
//
|
|
// Return value: returns S_OK if successful, other
|
|
// error code if not
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
HRESULT CVariant::SetNextByteArrayElement(
|
|
BYTE byteValue,
|
|
DWORD cMaxElements)
|
|
{
|
|
HRESULT hr;
|
|
|
|
//
|
|
// Add the long to the correct index
|
|
// in the array
|
|
//
|
|
hr = SetNextArrayElement(
|
|
VT_UI1,
|
|
cMaxElements,
|
|
&byteValue);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CVariant::IsStringValue
|
|
//
|
|
// Purpose: Determines whether this variant represents a string
|
|
//
|
|
// Params:
|
|
//
|
|
// Return value: returns TRUE if this is a string, FALSE if not
|
|
//
|
|
//------------------------------------------------------------
|
|
BOOL CVariant::IsStringValue()
|
|
{
|
|
return VT_BSTR == _var.vt;
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CVariant::IsLongValue
|
|
//
|
|
// Purpose: Determines whether this variant represents a long
|
|
//
|
|
// Params:
|
|
//
|
|
// Return value: returns TRUE if this is a long, FALSE if not
|
|
//
|
|
//------------------------------------------------------------
|
|
BOOL CVariant::IsLongValue()
|
|
{
|
|
return VT_I4 == _var.vt;
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CVariant::operator VARIANT*()
|
|
//
|
|
// Purpose: Casts this object into a VARIANT structure pointer
|
|
//
|
|
// Params:
|
|
//
|
|
// Return value: returns a pointer to a VARIANT structure
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
CVariant::operator VARIANT*()
|
|
{
|
|
return &_var;
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CVariant::SetNextArrayElement
|
|
//
|
|
// Purpose: Adds an element to an array of objects of arbitrary
|
|
// type
|
|
//
|
|
// Params: wszValue -- the value to which to set the element
|
|
// cMaxElements (optional) -- the maximum number
|
|
// of elements in this array -- must be specified
|
|
// the first time this method is called on this object
|
|
//
|
|
// Return value: returns S_OK if successful, other
|
|
// error code if not
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
HRESULT CVariant::SetNextArrayElement(
|
|
VARTYPE varType,
|
|
DWORD cMaxElements,
|
|
LPVOID pvData)
|
|
{
|
|
HRESULT hr;
|
|
|
|
//
|
|
// If this array contains no elements, return the hr
|
|
// that lets the caller know that this array is full
|
|
//
|
|
if ( 0 == cMaxElements )
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
//
|
|
// The first time this method is called on this object,
|
|
// we should allocate space for the array
|
|
//
|
|
if ( !_iCurrentArrayIndex )
|
|
{
|
|
ASSERT( cMaxElements );
|
|
ASSERT( VT_EMPTY == _var.vt );
|
|
|
|
//
|
|
// Allocate space for the array with elements
|
|
// of the caller specifed type and number
|
|
//
|
|
hr = InitializeArray(
|
|
varType,
|
|
cMaxElements);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
_cMaxArrayElements = cMaxElements;
|
|
}
|
|
|
|
ASSERT( ((DWORD) _iCurrentArrayIndex) < _cMaxArrayElements );
|
|
|
|
//
|
|
// Now add the polymorphic object's IUnknown
|
|
// into the array
|
|
//
|
|
hr = SafeArrayPutElement(
|
|
_var.parray,
|
|
&_iCurrentArrayIndex,
|
|
pvData);
|
|
|
|
//
|
|
// If we've filled up the array, return S_FALSE to
|
|
// signal that no more elements can be added
|
|
//
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//
|
|
// Increment our cursor into the array to the
|
|
// next element
|
|
//
|
|
_iCurrentArrayIndex++;
|
|
|
|
//
|
|
// Check our current index -- if it's the same
|
|
// as our maximum, we're full
|
|
//
|
|
if ( ((DWORD) _iCurrentArrayIndex) == _cMaxArrayElements)
|
|
{
|
|
hr = S_FALSE;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CVariant::InitializeArray
|
|
//
|
|
// Purpose: Private method that allocates space for an array
|
|
// of a specified size and element type
|
|
//
|
|
// Params: varType -- type of elements that will be in the array
|
|
// cMaxElements -- the size, in elements, of the array
|
|
//
|
|
// Return value: returns ERROR_SUCCESS if successful, other
|
|
// win32 error code if not
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
HRESULT CVariant::InitializeArray(
|
|
VARTYPE varType,
|
|
DWORD cMaxElements)
|
|
{
|
|
SAFEARRAY* pSafeArray;
|
|
SAFEARRAYBOUND arrayBound;
|
|
|
|
//
|
|
// Set the bounds of the array to be zero-based
|
|
//
|
|
arrayBound.lLbound = 0;
|
|
arrayBound.cElements = cMaxElements;
|
|
|
|
//
|
|
// Allocate the array
|
|
//
|
|
pSafeArray = SafeArrayCreate(
|
|
varType,
|
|
1, // 1 dimension
|
|
&arrayBound);
|
|
|
|
if (!pSafeArray)
|
|
{
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
//
|
|
// Set our state to refer to the allocated memory
|
|
// with the specified type
|
|
//
|
|
_var.vt = VT_ARRAY | varType;
|
|
_var.parray = pSafeArray;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|