//---------------------------------------------------------------------------
// Excel Multivalue Formula Add-In
// Copyright (C) <2005> <Herbert Danler>
// Contact: danler@users.sourceforge.net
// Project Home Page: http://excelmvf.sourceforge.net/
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any
// later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//---------------------------------------------------------------------------
/***********************************************************************
* Module: TComHelper.cpp
* Author: Herbert Danler
* Modified: Dienstag, 15. Juni 2004 10:59:42
* Purpose: Implementation of the class TComHelper
* Comment: Helper class for COM-Automation
***********************************************************************/
#include "stdafx.h"
#include "TCOMException.h"
#include "TComHelper.h"
////////////////////////////////////////////////////////////////////////
// Name: TComHelper::AutoWrap(int autoType, VARIANT* pvResult, IDispatch* pDisp, LPOLESTR ptName, int cArgs...)
// Purpose: Implementation of TComHelper::AutoWrap()
// Comment: function for access (calling functions, changing properties etc.) of COM Objects via their IDispatch-Interface.
// This function ist taken from the Microsoft Knowledge base article 211686
// Attention:
// when multiple parameters are passed, they must be passed in reverse order!!
// Parameters:
// - autoType
// - pvResult
// - pDisp
// - ptName
// - cArgs
// Return: HRESULT
////////////////////////////////////////////////////////////////////////
HRESULT TComHelper::AutoWrap(int autoType, VARIANT* pvResult, IDispatch* pDisp, LPOLESTR ptName, int cArgs...)
{
// Begin variable-argument list...
va_list marker;
va_start(marker, cArgs);
if(!pDisp) {
throw TCOMException(0,"No Dispatch interface pointer passed to AutoWrap()","AutoWrap()");
//MessageBox(NULL, "NULL IDispatch passed to AutoWrap()", "Error", 0x10010);
//_exit(0);
}
// Variables used...
DISPPARAMS dp = { NULL, NULL, 0, 0 };
DISPID dispidNamed = DISPID_PROPERTYPUT;
DISPID dispID;
HRESULT hr;
char buf[200];
char szName[200];
// Convert down to ANSI
WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);
// Get DISPID for name passed...
hr = pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID);
if(FAILED(hr)) {
sprintf(buf, "IDispatch::GetIDsOfNames(\"%s\") failed w/err 0x%08lx", szName, hr);
throw TCOMException(hr,buf,"AutoWrap()");
//MessageBox(NULL, buf, "AutoWrap()", 0x10010);
//_exit(0);
//return hr;
}
// Allocate memory for arguments...
VARIANT *pArgs = new VARIANT[cArgs+1];
// Extract arguments...
for(int i=0; i<cArgs; i++) {
pArgs[i] = va_arg(marker, VARIANT);
}
// Build DISPPARAMS
dp.cArgs = cArgs;
dp.rgvarg = pArgs;
// Handle special-case for property-puts!
if(autoType & DISPATCH_PROPERTYPUT) {
dp.cNamedArgs = 1;
dp.rgdispidNamedArgs = &dispidNamed;
}
// Make the call!
hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, autoType, &dp, pvResult, NULL, NULL);
if(FAILED(hr)) {
va_end(marker);
if (pArgs) delete [] pArgs;
sprintf(buf, "IDispatch::Invoke(\"%s\"=%08lx) failed w/err 0x%08lx", szName, dispID, hr);
throw TCOMException(hr,buf,"AutoWrap()");
//MessageBox(NULL, buf, "AutoWrap()", 0x10010);
//_exit(0);
//return hr;
}
// End variable-argument section...
va_end(marker);
delete [] pArgs;
return hr;
}