示例#1
0
BOOL CXLAutomation::ExlInvoke(IDispatch *pdisp, LPOLESTR szMember, VARIANTARG * pvargReturn,
			WORD wInvokeAction, WORD wFlags)
{
	HRESULT hr;
	DISPPARAMS dispparams;
	unsigned int uiArgErr;
	EXCEPINFO excep;
	
	// Get the IDs for the member and its arguments.  GetIDsOfNames expects the
	// member name as the first name, followed by argument names (if any).
	m_alpszArgNames[0] = szMember;
	hr = pdisp->GetIDsOfNames( IID_NULL, m_alpszArgNames,
								1 + m_iNamedArgCount, LOCALE_SYSTEM_DEFAULT, m_aDispIds);
	if (FAILED(hr)) 
	{
		if (!(wFlags & DISP_NOSHOWEXCEPTIONS))
			ShowException(szMember, hr, NULL, 0);
		return FALSE;
	}
	
	if (pvargReturn != NULL)
		ClearVariant(pvargReturn);
	
	// if doing a property put(ref), we need to adjust the first argument to have a
	// named arg of DISPID_PROPERTYPUT.
	if (wInvokeAction & (DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF)) 
	{
		m_iNamedArgCount = 1;
		m_aDispIds[1] = DISPID_PROPERTYPUT;
		pvargReturn = NULL;
	}
	
	dispparams.rgdispidNamedArgs = m_aDispIds + 1;
	dispparams.rgvarg = m_aVargs;
	dispparams.cArgs = m_iArgCount;
	dispparams.cNamedArgs = m_iNamedArgCount;
	
	excep.pfnDeferredFillIn = NULL;
	
	hr = pdisp->Invoke(m_aDispIds[0], IID_NULL, LOCALE_SYSTEM_DEFAULT,
								wInvokeAction, &dispparams, pvargReturn, &excep, &uiArgErr);
	
	if (wFlags & DISP_FREEARGS)
		ClearAllArgs();
	
	if (FAILED(hr)) 
	{
		// display the exception information if appropriate:
		if (!(wFlags & DISP_NOSHOWEXCEPTIONS))
			ShowException(szMember, hr, &excep, uiArgErr);
	
		// free exception structure information
		SysFreeString(excep.bstrSource);
		SysFreeString(excep.bstrDescription);
		SysFreeString(excep.bstrHelpFile);
	
		return FALSE;
	}
	return TRUE;
}
示例#2
0
void CXLAutomation::AddArgumentCommon(LPOLESTR lpszArgName, WORD wFlags, VARTYPE vt)
{
	ClearVariant(&m_aVargs[m_iArgCount]);
	
	m_aVargs[m_iArgCount].vt = vt;
	m_awFlags[m_iArgCount] = wFlags;
	
	if (lpszArgName != NULL) 
	{
		m_alpszArgNames[m_iNamedArgCount + 1] = lpszArgName;
		m_iNamedArgCount++;
	}
}	
示例#3
0
void AddArgumentCommon(LPOLESTR lpszArgName, WORD wFlags, VARTYPE vt)
{
    ClearVariant(&g_aVargs[g_iArgCount]);

    g_aVargs[g_iArgCount].vt = vt;
    g_awFlags[g_iArgCount] = wFlags;

    if (lpszArgName != NULL) 
    {
        g_alpszArgNames[g_iNamedArgCount + 1] = lpszArgName;
        g_iNamedArgCount++;
    }
}    
示例#4
0
/*
 *  Constructs an 1-dimensional array containing variant strings.  The strings
 *  are copied from an incoming array of C-Strings.
 */
BOOL CXLAutomation::AddArgumentCStringArray(LPOLESTR lpszArgName, WORD wFlags, LPOLESTR *paszStrings, int iCount)
{
	SAFEARRAY *psa;
	SAFEARRAYBOUND saBound;
	VARIANTARG *pvargBase;
	VARIANTARG *pvarg;
	int i, j;
	
	saBound.lLbound = 0;
	saBound.cElements = iCount;
	
	psa = SafeArrayCreate(VT_VARIANT, 1, &saBound);
	if (psa == NULL)
		return FALSE;
	
	SafeArrayAccessData(psa, (void**) &pvargBase);
	
	pvarg = pvargBase;
	for (i = 0; i < iCount; i++) 
	{
		// copy each string in the list of strings
		ClearVariant(pvarg);
		pvarg->vt = VT_BSTR;
		if ((pvarg->bstrVal = SysAllocString(*paszStrings++)) == NULL) 
		{
			// memory failure:  back out and free strings alloc'ed up to
			// now, and then the array itself.
			pvarg = pvargBase;
			for (j = 0; j < i; j++) 
			{
				SysFreeString(pvarg->bstrVal);
				pvarg++;
			}
			SafeArrayDestroy(psa);
			return FALSE;
		}
		pvarg++;
	}
	
	SafeArrayUnaccessData(psa);

	// With all memory allocated, setup this argument
	AddArgumentCommon(lpszArgName, wFlags, VT_VARIANT | VT_ARRAY);
	m_aVargs[m_iArgCount++].parray = psa;
	return TRUE;

}
示例#5
0
/*
 *  ClearAllArgs
 *
 *  Clears the existing contents of the arg array in preparation for
 *  a new invocation.  Frees argument memory if so marked.
 */
void CXLAutomation::ClearAllArgs()
{
	int i;
	
	for (i = 0; i < m_iArgCount; i++) 
	{
		if (m_awFlags[i] & DISPARG_NOFREEVARIANT)
			// free the variant's contents based on type
			ClearVariant(&m_aVargs[i]);
		else
			ReleaseVariant(&m_aVargs[i]);
	}

	m_iArgCount = 0;
	m_iNamedArgCount = 0;

}
示例#6
0
void ClearAllArgs()
{
    int i;




    for (i = 0; i < g_iArgCount; i++) 
    {
        if (g_awFlags[i] & DISPARG_NOFREEVARIANT)
            // free the variant's contents based on type
            ClearVariant(&g_aVargs[i]);
        else
            ReleaseVariant(&g_aVargs[i]);
    }

    g_iArgCount = 0;
    g_iNamedArgCount = 0;
}
示例#7
0
/*
 *  ReleaseVariant
 *
 *  Clears a particular variant structure and releases any external objects
 *  or memory contained in the variant.  Supports the data types listed above.
 */
int CXLAutomation::ReleaseVariant(VARIANTARG *pvarg)
{
	VARTYPE vt;
	VARIANTARG *pvargArray;
	long lLBound, lUBound, l;
	
	vt = pvarg->vt & 0xfff;		// mask off flags
	
	// check if an array.  If so, free its contents, then the array itself.
	if (V_ISARRAY(pvarg)) 
	{
		// variant arrays are all this routine currently knows about.  Since a
		// variant can contain anything (even other arrays), call ourselves
		// recursively.
		if (vt == VT_VARIANT) 
		{
			SafeArrayGetLBound(pvarg->parray, 1, &lLBound);
			SafeArrayGetUBound(pvarg->parray, 1, &lUBound);
			
			if (lUBound > lLBound) 
			{
				lUBound -= lLBound;
				
				SafeArrayAccessData(pvarg->parray, (void**)&pvargArray);
				
				for (l = 0; l < lUBound; l++) 
				{
					ReleaseVariant(pvargArray);
					pvargArray++;
				}
				
				SafeArrayUnaccessData(pvarg->parray);
			}
		}
		else 
		{
			return 1; //  non-variant type

			// MessageBox(NULL, _T("ReleaseVariant: Array contains non-variant type"), "Failed", MB_OK | MB_ICONSTOP);
		}
		
		// Free the array itself.
		SafeArrayDestroy(pvarg->parray);
	}
	else 
	{
		switch (vt) 
		{
			case VT_DISPATCH:
				//(*(pvarg->pdispVal->lpVtbl->Release))(pvarg->pdispVal);
				pvarg->pdispVal->Release();
				break;
				
			case VT_BSTR:
				SysFreeString(pvarg->bstrVal);
				break;
				
			case VT_I2:
			case VT_BOOL:
			case VT_R8:
			case VT_ERROR:		// to avoid erroring on an error return from Excel
				// no work for these types
				break;
				
			default:

				return 2; //unknonw type
				// MessageBox(NULL, _T("ReleaseVariant: Unknown type"), "Failed", MB_OK | MB_ICONSTOP);
				break;
		}
	}
	
	ClearVariant(pvarg);
	return 0;

}
示例#8
0
void ReleaseVariant(VARIANTARG *pvarg)
{
    VARTYPE vt;
    VARIANTARG HUGEP *pvargArray;
    long lLBound, lUBound, l;

    vt = pvarg->vt & 0xfff;        // mask off flags

    // check if an array.  If so, free its contents, 
    // then the array itself.
    if (V_ISARRAY(pvarg)) 
    {
        // variant arrays are all this routine currently knows about.
        // Since a variant can contain anything (even other arrays), 
        // call ourselves recursively.
        if (vt == VT_VARIANT) 
        {
            SafeArrayGetLBound(pvarg->parray, 1, &lLBound);
            SafeArrayGetUBound(pvarg->parray, 1, &lUBound);

            if (lUBound > lLBound) 
            {
                lUBound -= lLBound;

                SafeArrayAccessData(pvarg->parray,(void **) &pvargArray);




                for (l = 0; l < lUBound; l++) 
                {
                    ReleaseVariant(pvargArray);
                    pvargArray++;
                }

                SafeArrayUnaccessData(pvarg->parray);
            }
        }
        else 
        {
            MessageBox(g_hwndApp, "ReleaseVariant: Array contains non-variant type", g_szAppTitle, MB_OK | MB_ICONSTOP);
        }

        // Free the array itself.
        SafeArrayDestroy(pvarg->parray);
    }
    else 
    {
        switch (vt) 
        {
            case VT_DISPATCH:
				//14/12/2004
				//!!!all comments had to be added
                (/***/(pvarg->pdispVal/*->lpVtbl*/->Release))(/*pvarg->pdispVal*/);
                break;

            case VT_BSTR:
                SysFreeString(pvarg->bstrVal);
                break;

            case VT_I2:
            case VT_BOOL:
            case VT_R8:
            case VT_ERROR:        // to avoid erroring on an error return 
                                // from Excel
                // no work for these types
                break;

            default:
                MessageBox(g_hwndApp, "ReleaseVariant: Unknown type",g_szAppTitle, MB_OK | MB_ICONSTOP);
                break;
        }
    }

    ClearVariant(pvarg);
}