Exemple #1
0
//-------------------------------------------------------------------
void cpp_xloper::operator=(VARIANT *pv)
{
   Free();

   if(vt_to_xloper(m_Op, pv, false) && m_Op.xltype == xltypeStr)
      m_DLLtoFree = true;
}
Exemple #2
0
//-------------------------------------------------------------------
// The Variant constructor.  Takes type from the VARTYPE.
//-------------------------------------------------------------------
cpp_xloper::cpp_xloper(VARIANT *pv)
{
   Clear();

   if(vt_to_xloper(m_Op, pv, true) && (m_Op.xltype == xltypeStr || m_Op.xltype == xltypeMulti))
      m_DLLtoFree = true;
}
Exemple #3
0
//-------------------------------------------------------------------
// Converts the passed-in array Variant to an xltypeMulti xloper.
//-------------------------------------------------------------------
bool array_vt_to_xloper(xloper &op, const VARIANT *pv)
{
	if(!pv || !pv->parray)
		return false;

	int ndims = pv->parray->cDims;

	if(ndims == 0 || ndims > 2)
		return false;

	int dims[2] = {1,1};
	
	long ubound[2], lbound[2];

	for(int d = 0; d < ndims; d++)
	{
// Dimension argument counts from 1, so need to pass d + 1
		if(FAILED(SafeArrayGetUBound(pv->parray, d + 1, ubound + d))
		|| FAILED(SafeArrayGetLBound(pv->parray, d + 1, lbound + d)))
			return false;

		dims[d] = (short)(ubound[d] - lbound[d] + 1);
	}

	op.val.array.lparray = (xloper *)malloc(dims[0] * dims[1] * XLOPER_SIZE);

	if(!op.val.array.lparray)
		return false;

	op.val.array.rows = dims[0];
	op.val.array.columns = dims[1];
	op.xltype = xltypeMulti;

	xloper *p_op = op.val.array.lparray;

// Use this union structure to retrieve elements of the SafeArray
	union
	{
		VARIANT var;
		short I2;
		double R8;
		ULONG ulVal;
		CY cyVal;
		bool boolVal;
		BSTR bstrVal;
	}
		temp_union;

	xloper temp_op;
	VARTYPE vt_type = pv->vt & ~VT_ARRAY;
	long element_index[2];

	void *vp;
	SafeArrayAccessData(pv->parray, &vp);
	SafeArrayUnaccessData(pv->parray);

	for(WORD r = 0; r < dims[0]; r++)
	{
		for(WORD c = 0; c < dims[1];)
		{
			element_index[0] = r + lbound[0];
			element_index[1] = c++ + lbound[1];

			if(FAILED(SafeArrayGetElement(pv->parray, element_index, &temp_union)))
			{
				temp_op.xltype = xltypeNil;
			}
			else
			{
				switch(vt_type)
				{
				case VT_I2:
					temp_op.xltype = xltypeInt;
					temp_op.val.w = temp_union.I2;
					break;

				case VT_R8:
					temp_op.xltype = xltypeNum;
					temp_op.val.num = temp_union.R8;
					break;

				case VT_BOOL:
					temp_op.xltype = xltypeBool;
					temp_op.val.xbool = temp_union.boolVal;
					break;

				case VT_VARIANT:
// Don't allow Variant to contain an array Variant to prevent recursion
					if(vt_to_xloper(temp_op, &temp_union.var, false))
						break;

				case VT_ERROR:
					temp_op.xltype = xltypeErr;
					temp_op.val.err = (unsigned short)(temp_union.ulVal - VT_XL_ERR_OFFSET);
					break;

				case VT_CY:
					temp_op.xltype = xltypeNum;
					temp_op.val.num = (double)(temp_union.cyVal.int64 / 1e4);
					break;

				case VT_BSTR:
					op.xltype = xltypeStr;
					op.val.str = vt_bstr_to_xlstring(temp_union.bstrVal);
					break;

				default:
					temp_op.xltype = xltypeNil;
				}
			}
			*p_op++ = temp_op;
		}
	}
	return true;
}