/*******************************************************************************
 * Copyright (c) 2000, 2012 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.ole.win32;


import org.eclipse.swt.*;
import org.eclipse.swt.internal.ole.win32.*;
import org.eclipse.swt.internal.win32.*;

/**
 * OleAutomation provides a generic mechanism for accessing functionality that is 
 * specific to a particular ActiveX Control or OLE Document.
 *
 * <p>The OLE Document or ActiveX Control must support the IDispatch interface in order to provide
 * OleAutomation support. The additional functionality provided by the OLE Object is specified in 
 * its IDL file.  The additional methods can either be to get property values (<code>getProperty</code>), 
 * to set property values (<code>setProperty</code>) or to invoke a method (<code>invoke</code> or
 * <code>invokeNoReply</code>).  Arguments are passed around in the form of <code>Variant</code> 
 * objects.
 *
 * <p>Here is a sample IDL fragment:
 *
 * <pre>
 *	interface IMyControl : IDispatch
 *	{
 *		[propget, id(0)] HRESULT maxFileCount([retval, out] int *c);
 *		[propput, id(0)] HRESULT maxFileCount([in] int c);
 *		[id(1)]	HRESULT AddFile([in] BSTR fileName);
 *	};
 * </pre>
 *
 * <p>An example of how to interact with this extended functionality is shown below:
 *
 * <code><pre>
 *	OleAutomation automation = new OleAutomation(myControlSite);
 *
 *	// Look up the ID of the maxFileCount parameter
 *	int[] rgdispid = automation.getIDsOfNames(new String[]{"maxFileCount"});
 *	int maxFileCountID = rgdispid[0];
 *
 *	// Set the property maxFileCount to 100:
 *	if (automation.setProperty(maxFileCountID, new Variant(100))) {
 *		System.out.println("Max File Count was successfully set.");
 *	}
 *
 *	// Get the new value of the maxFileCount parameter:
 *	Variant pVarResult = automation.getProperty(maxFileCountID);
 *	if (pVarResult != null) {
 *		System.out.println("Max File Count is "+pVarResult.getInt());
 *	}
 *
 *	// Invoke the AddFile method
 *	// Look up the IDs of the AddFile method and its parameter
 *	rgdispid = automation.getIDsOfNames(new String[]{"AddFile", "fileName"}); 
 *	int dispIdMember = rgdispid[0];
 *	int[] rgdispidNamedArgs = new int[] {rgdispid[1]};
 *
 *	// Convert arguments to Variant objects
 *	Variant[] rgvarg = new Variant[1];
 *	String fileName = "C:\\testfile";
 * 	rgvarg[0] = new Variant(fileName);
 *
 *	// Call the method
 *	Variant pVarResult = automation.invoke(dispIdMember, rgvarg, rgdispidNamedArgs);
 *
 *	// Check the return value
 * 	if (pVarResult == null || pVarResult.getInt() != OLE.S_OK){
 * 		System.out.println("Failed to add file "+fileName);
 *	}
 *
 *	automation.dispose();
 *
 * </pre></code>
 * 
 * @see <a href="http://www.eclipse.org/swt/snippets/#ole">OLE and ActiveX snippets</a>
 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Examples: OLEExample, OleWebBrowser</a>
 */
public final class OleAutomation {
	private IUnknown objIUnknown;
	private IDispatch objIDispatch;
	private String exceptionDescription;
	private ITypeInfo objITypeInfo;
	
OleAutomation(IDispatch idispatch) {
	if (idispatch == null) OLE.error(OLE.ERROR_INVALID_INTERFACE_ADDRESS);
	objIDispatch = idispatch;
	objIDispatch.AddRef();
	
	long /*int*/[] ppv = new long /*int*/[1];
	/* GetTypeInfo([in] iTInfo, [in] lcid, [out] ppTInfo) 
	 * AddRef has already been called on ppTInfo by the callee and must be released by the caller. 
	 */
	int result = objIDispatch.GetTypeInfo(0, COM.LOCALE_USER_DEFAULT, ppv);
	if (result == OLE.S_OK) {
		objITypeInfo = new ITypeInfo(ppv[0]);
	}
}
/**
 * Creates an OleAutomation object for the specified client.
 *
 * @param clientSite the site for the OLE Document or ActiveX Control whose additional functionality 
 *        you need to access
 *
 * @exception IllegalArgumentException <ul>
 *		<li>ERROR_INVALID_INTERFACE_ADDRESS when called with an invalid client site
 *	</ul>
 */
public OleAutomation(OleClientSite clientSite) {
	if (clientSite == null) OLE.error(OLE.ERROR_INVALID_INTERFACE_ADDRESS);
	objIDispatch = clientSite.getAutomationObject();

	long /*int*/[] ppv = new long /*int*/[1];
	/* GetTypeInfo([in] iTInfo, [in] lcid, [out] ppTInfo) 
	 * AddRef has already been called on ppTInfo by the callee and must be released by the caller. 
	 */
	int result = objIDispatch.GetTypeInfo(0, COM.LOCALE_USER_DEFAULT, ppv);
	if (result == OLE.S_OK) {
		objITypeInfo = new ITypeInfo(ppv[0]);
	}
}
/**
 * Creates an OleAutomation object for the specified <code>progID</code>.
 *
 * @param progId the unique program identifier of an OLE Document application; 
 *               the value of the ProgID key or the value of the VersionIndependentProgID key specified
 *               in the registry for the desired OLE Document (for example, the VersionIndependentProgID
 *               for Word is Word.Document)
 *               
 * @exception SWTException
 * <ul><li>ERROR_INVALID_CLASSID when the progId does not map to a registered CLSID
 *     <li>ERROR_CANNOT_CREATE_OBJECT when failed to create OLE Object
 *     <li>ERROR_INTERFACE_NOT_FOUND when the OLE object specified does not implement IDispatch
 * </ul>
 * 
 * @since 3.6
 */
public OleAutomation(String progId) {
	try {
		OS.OleInitialize(0);
		GUID appClsid = getClassID(progId);
		if (appClsid == null) {
			OS.OleUninitialize();
			OLE.error(OLE.ERROR_INVALID_CLASSID);
		}
		int flags = COM.CLSCTX_INPROC_SERVER;
		if (progId.startsWith("Excel")) flags |= COM.CLSCTX_LOCAL_SERVER; //$NON-NLS-1$
		long /*int*/[] ppvObject = new long /*int*/[1];
		int result = COM.CoCreateInstance(appClsid, 0, flags, COM.IIDIUnknown, ppvObject); 
		if (result != COM.S_OK) {
			OS.OleUninitialize();
			OLE.error(OLE.ERROR_CANNOT_CREATE_OBJECT, result);
		}
		objIUnknown = new IUnknown(ppvObject[0]);
		
		ppvObject[0] = 0;
		result = objIUnknown.QueryInterface(COM.IIDIDispatch, ppvObject); 
		if (result != COM.S_OK) OLE.error(OLE.ERROR_INTERFACE_NOT_FOUND);
		objIDispatch = new IDispatch(ppvObject[0]);

		ppvObject[0] = 0;
		result = objIDispatch.GetTypeInfo(0, COM.LOCALE_USER_DEFAULT, ppvObject);
		if (result == OLE.S_OK) {
			objITypeInfo = new ITypeInfo(ppvObject[0]);
		}
	} catch (SWTException e) {
		dispose();
		throw e;
	}
}
/**
 * Disposes the automation object.
 * <p>
 * This method releases the IDispatch interface on the OLE Document or ActiveX Control.
 * Do not use the OleAutomation object after it has been disposed.
 */
public void dispose() {

	if (objIDispatch != null){
		objIDispatch.Release();
	}
	objIDispatch = null;
	
	if (objITypeInfo != null){
		objITypeInfo.Release();
	}
	objITypeInfo = null;
	
	if (objIUnknown != null){
		objIUnknown.Release();
		OS.OleUninitialize();
	}
	objIUnknown = null;
}
long /*int*/ getAddress() {	
	return objIDispatch.getAddress();
}
GUID getClassID(String clientName) {
	// create a GUID struct to hold the result
	GUID guid = new GUID();

	// create a null terminated array of char
	char[] buffer = null;
	if (clientName != null) {
		int count = clientName.length();
		buffer = new char[count + 1];
		clientName.getChars(0, count, buffer, 0);
	}
	if (COM.CLSIDFromProgID(buffer, guid) != COM.S_OK){
		int result = COM.CLSIDFromString(buffer, guid);
		if (result != COM.S_OK) return null;
	}
	return guid;
}
/**
 * Returns the fully qualified name of the Help file for the given member ID.
 * 
 * @param dispId the member ID whose Help file is being retrieved.
 * @return a string representing the fully qualified name of a Help 
 * file or null.
 */
public String getHelpFile(int dispId) {
	if (objITypeInfo == null) return null;
	String[] file = new String[1];
	int rc = objITypeInfo.GetDocumentation(dispId, null, null, null, file );
	if (rc == OLE.S_OK) return file[0];
	return null;	
}
/**
 * Returns the documentation string for the given member ID.
 * 
 * @param dispId the member ID in which the documentation is being retrieved.
 * @return the documentation string if it exists; otherwise return null.
 */
public String getDocumentation(int dispId) {
	if (objITypeInfo == null) return null;
	String[] doc = new String[1];
	int rc = objITypeInfo.GetDocumentation(dispId, null, doc, null, null );
	if (rc == OLE.S_OK) return doc[0];
	return null;
}
/**
 * Returns the property description of a variable at the given index.
 * 
 * @param index the index of a variable whose property is being retrieved.
 * @return an OlePropertyDescription for a variable at the given index.
 */
public OlePropertyDescription getPropertyDescription(int index) {
	if (objITypeInfo == null) return null;
	long /*int*/[] ppVarDesc = new long /*int*/[1];
	int rc = objITypeInfo.GetVarDesc(index, ppVarDesc);
	if (rc != OLE.S_OK) return null;
	VARDESC vardesc = new VARDESC();
	COM.MoveMemory(vardesc, ppVarDesc[0], VARDESC.sizeof);
	
	OlePropertyDescription data = new OlePropertyDescription();
	data.id = vardesc.memid;
	data.name = getName(vardesc.memid);
	data.type = vardesc.elemdescVar_tdesc_vt;
	if (data.type == OLE.VT_PTR) {
		short[] vt = new short[1];
		COM.MoveMemory(vt, vardesc.elemdescVar_tdesc_union + OS.PTR_SIZEOF, 2);
		data.type = vt[0];
	}
	data.flags = vardesc.wVarFlags;
	data.kind = vardesc.varkind;
	data.description = getDocumentation(vardesc.memid);
	data.helpFile = getHelpFile(vardesc.memid);
	
	objITypeInfo.ReleaseVarDesc(ppVarDesc[0]);
	return data;
}
/**
 * Returns the description of a function at the given index.
 * 
 * @param index the index of a function whose property is being retrieved.
 * @return an OleFunctionDescription for a function at the given index.
 */
public OleFunctionDescription getFunctionDescription(int index) {
	if (objITypeInfo == null) return null;
	long /*int*/[] ppFuncDesc = new long /*int*/[1];
	int rc = objITypeInfo.GetFuncDesc(index, ppFuncDesc);
	if (rc != OLE.S_OK) return null;
	FUNCDESC funcdesc = new FUNCDESC();
	COM.MoveMemory(funcdesc, ppFuncDesc[0], FUNCDESC.sizeof);
	
	OleFunctionDescription data = new OleFunctionDescription();
	
	data.id = funcdesc.memid;
	data.optionalArgCount = funcdesc.cParamsOpt;
	data.invokeKind = funcdesc.invkind;
	data.funcKind = funcdesc.funckind;
	data.flags = funcdesc.wFuncFlags;
	data.callingConvention = funcdesc.callconv;
	data.documentation = getDocumentation(funcdesc.memid);
	data.helpFile = getHelpFile(funcdesc.memid);
	
	String[] names = getNames(funcdesc.memid, funcdesc.cParams + 1);
	if (names.length > 0) {
		data.name = names[0];
	}
	data.args = new OleParameterDescription[funcdesc.cParams];
	for (int i = 0; i < data.args.length; i++) {
		data.args[i] = new OleParameterDescription();
		if (names.length > i + 1) {
			data.args[i].name = names[i + 1];
		}
		//TODO 0- use structures
		short[] vt = new short[1];	
		COM.MoveMemory(vt, funcdesc.lprgelemdescParam + i * COM.ELEMDESC_sizeof() + OS.PTR_SIZEOF, 2);				
		if (vt[0] == OLE.VT_PTR) {
			long /*int*/ [] pTypedesc = new long /*int*/ [1];
			COM.MoveMemory(pTypedesc, funcdesc.lprgelemdescParam + i * COM.ELEMDESC_sizeof(), OS.PTR_SIZEOF);
			short[] vt2 = new short[1];
			COM.MoveMemory(vt2, pTypedesc[0] + OS.PTR_SIZEOF, 2);
			vt[0] = (short)(vt2[0] | COM.VT_BYREF);
		}
		data.args[i].type = vt[0];
		short[] wParamFlags = new short[1];
		COM.MoveMemory(wParamFlags, funcdesc.lprgelemdescParam + i * COM.ELEMDESC_sizeof() + COM.TYPEDESC_sizeof () + OS.PTR_SIZEOF, 2);
		data.args[i].flags = wParamFlags[0];	
	}
	
	data.returnType = funcdesc.elemdescFunc_tdesc_vt;
	if (data.returnType == OLE.VT_PTR) {
		short[] vt = new short[1];
		COM.MoveMemory(vt, funcdesc.elemdescFunc_tdesc_union + OS.PTR_SIZEOF, 2);
		data.returnType = vt[0];
	}

	objITypeInfo.ReleaseFuncDesc(ppFuncDesc[0]);
	return data;
}
/**
 * Returns the type info of the current object referenced by the automation.
 * The type info contains information about the object such as the function descriptions,
 * the member descriptions and attributes of the type.
 * 
 * @return the type info of the receiver
 */
public TYPEATTR getTypeInfoAttributes() {
	if (objITypeInfo == null) return null;
	long /*int*/ [] ppTypeAttr = new long /*int*/ [1];
	int rc = objITypeInfo.GetTypeAttr(ppTypeAttr);
	if (rc != OLE.S_OK) return null;
	TYPEATTR typeattr = new TYPEATTR();
	COM.MoveMemory(typeattr, ppTypeAttr[0], TYPEATTR.sizeof);
	objITypeInfo.ReleaseTypeAttr(ppTypeAttr[0]);
	return typeattr;
}
/**
 * Returns the name of the given member ID.
 * 
 * @param dispId the member ID in which the name is being retrieved.
 * @return the name if it exists; otherwise return null.
 */
public String getName(int dispId) {
	if (objITypeInfo == null) return null;
	String[] name = new String[1];
	int rc = objITypeInfo.GetDocumentation(dispId, name, null, null, null );
	if (rc == OLE.S_OK) return name[0];
	return null;
}
/**
 * Returns the name of a function and parameter names for the specified function ID.
 * 
 * @param dispId the function ID in which the name and parameters are being retrieved.
 * @param maxSize the maximum number of names to retrieve.
 * @return an array of name containing the function name and the parameter names
 */
public String[] getNames(int dispId, int maxSize) {
	if (objITypeInfo == null) return new String[0];
	String[] names = new String[maxSize];
	int[] count = new int[1];
	int rc = objITypeInfo.GetNames(dispId, names, maxSize, count);
	if (rc == OLE.S_OK) {
		String[] newNames = new String[count[0]];
		System.arraycopy(names, 0, newNames, 0, count[0]);
		return newNames;
	}
	return new String[0];
}
/**
 * Returns the positive integer values (IDs) that are associated with the specified names by the
 * IDispatch implementor.  If you are trying to get the names of the parameters in a method, the first 
 * String in the names array must be the name of the method followed by the names of the parameters.
 *
 * @param names an array of names for which you require the identifiers
 *
 * @return positive integer values that are associated with the specified names in the same
 *         order as the names where provided; or null if the names are unknown
 */
public int[] getIDsOfNames(String[] names) {

	int[] rgdispid = new int[names.length];
	int result = objIDispatch.GetIDsOfNames(new GUID(), names, names.length, COM.LOCALE_USER_DEFAULT, rgdispid);
	if (result != COM.S_OK) return null;
	
	return rgdispid;
}
/**
 * Returns a description of the last error encountered.
 *
 * @return a description of the last error encountered
 */
public String getLastError() {
	
	return exceptionDescription;

}
/**
 * Returns the value of the property specified by the dispIdMember.
 *
 * @param dispIdMember the ID of the property as specified by the IDL of the ActiveX Control; the
 *        value for the ID can be obtained using OleAutomation.getIDsOfNames
 *
 * @return the value of the property specified by the dispIdMember or null
 */
public Variant getProperty(int dispIdMember) {
	Variant pVarResult = new Variant();
	int result = invoke(dispIdMember, COM.DISPATCH_PROPERTYGET, null, null, pVarResult);
	return (result == OLE.S_OK) ? pVarResult : null;
}
/**
 * Returns the value of the property specified by the dispIdMember.
 *
 * @param dispIdMember the ID of the property as specified by the IDL of the ActiveX Control; the
 *        value for the ID can be obtained using OleAutomation.getIDsOfNames
 *
 * @param rgvarg an array of arguments for the method.  All arguments are considered to be
 *        read only unless the Variant is a By Reference Variant type.
 * 
 * @return the value of the property specified by the dispIdMember or null
 * 
 * @since 2.0
 */
public Variant getProperty(int dispIdMember, Variant[] rgvarg) {
	Variant pVarResult = new Variant();
	int result = invoke(dispIdMember, COM.DISPATCH_PROPERTYGET, rgvarg, null, pVarResult);
	return (result == OLE.S_OK) ? pVarResult : null;
	
}
/**
 * Returns the value of the property specified by the dispIdMember.
 *
 * @param dispIdMember the ID of the property as specified by the IDL of the ActiveX Control; the
 *        value for the ID can be obtained using OleAutomation.getIDsOfNames
 *
 * @param rgvarg an array of arguments for the method.  All arguments are considered to be
 *        read only unless the Variant is a By Reference Variant type.
 * 
 * @param rgdispidNamedArgs an array of identifiers for the arguments specified in rgvarg; the
 *        parameter IDs must be in the same order as their corresponding values;
 *        all arguments must have an identifier - identifiers can be obtained using 
 *        OleAutomation.getIDsOfNames
 * 
 * @return the value of the property specified by the dispIdMember or null
 * 
 * @since 2.0
 */
public Variant getProperty(int dispIdMember, Variant[] rgvarg, int[] rgdispidNamedArgs) {
	Variant pVarResult = new Variant();
	int result = invoke(dispIdMember, COM.DISPATCH_PROPERTYGET, rgvarg, rgdispidNamedArgs, pVarResult);
	return (result == OLE.S_OK) ? pVarResult : null;
}
public boolean equals(Object object) {
	if (object == this) return true;
	if (object instanceof OleAutomation) {
		if (objIDispatch == null) return false;
		OleAutomation oleAutomation = ((OleAutomation) object); 
		if (oleAutomation.objIDispatch == null) return false;
		long /*int*/ address1 = objIDispatch.getAddress();
		long /*int*/ address2 = oleAutomation.objIDispatch.getAddress();
		return address1 == address2;
	}
	return false;
}
/** 
 * Invokes a method on the OLE Object; the method has no parameters.
 *
 * @param dispIdMember the ID of the method as specified by the IDL of the ActiveX Control; the
 *        value for the ID can be obtained using OleAutomation.getIDsOfNames
 *
 * @return the result of the method or null if the method failed to give result information
 */
public Variant invoke(int dispIdMember) {
	Variant pVarResult = new Variant();
	int result = invoke(dispIdMember, COM.DISPATCH_METHOD, null, null, pVarResult);
	return (result == COM.S_OK) ? pVarResult : null;
}
/** 
 * Invokes a method on the OLE Object; the method has no optional parameters.
 *
 * @param dispIdMember the ID of the method as specified by the IDL of the ActiveX Control; the
 *        value for the ID can be obtained using OleAutomation.getIDsOfNames
 *
 * @param rgvarg an array of arguments for the method.  All arguments are considered to be
 *        read only unless the Variant is a By Reference Variant type.
 *
 * @return the result of the method or null if the method failed to give result information
 */
public Variant invoke(int dispIdMember, Variant[] rgvarg) {
	Variant pVarResult = new Variant();
	int result = invoke(dispIdMember, COM.DISPATCH_METHOD, rgvarg, null, pVarResult);
	return (result == COM.S_OK) ? pVarResult : null;
}
/** 
 * Invokes a method on the OLE Object; the method has optional parameters.  It is not
 * necessary to specify all the optional parameters, only include the parameters for which
 * you are providing values.
 *
 * @param dispIdMember the ID of the method as specified by the IDL of the ActiveX Control; the
 *        value for the ID can be obtained using OleAutomation.getIDsOfNames
 *
 * @param rgvarg an array of arguments for the method.  All arguments are considered to be
 *        read only unless the Variant is a By Reference Variant type.
 *
 * @param rgdispidNamedArgs an array of identifiers for the arguments specified in rgvarg; the
 *        parameter IDs must be in the same order as their corresponding values;
 *        all arguments must have an identifier - identifiers can be obtained using 
 *        OleAutomation.getIDsOfNames
 *
 * @return the result of the method or null if the method failed to give result information
 */
public Variant invoke(int dispIdMember, Variant[] rgvarg, int[] rgdispidNamedArgs) {
	Variant pVarResult = new Variant();
	int result = invoke(dispIdMember, COM.DISPATCH_METHOD, rgvarg, rgdispidNamedArgs, pVarResult);
	return (result == COM.S_OK) ? pVarResult : null;
}
private int invoke(int dispIdMember, int wFlags, Variant[] rgvarg, int[] rgdispidNamedArgs, Variant pVarResult) {

	// get the IDispatch interface for the control
	if (objIDispatch == null) return COM.E_FAIL;
	
	// create a DISPPARAMS structure for the input parameters
	DISPPARAMS pDispParams = new DISPPARAMS();
	// store arguments in rgvarg
	if (rgvarg != null && rgvarg.length > 0) {
		pDispParams.cArgs = rgvarg.length;
		pDispParams.rgvarg = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, VARIANT.sizeof * rgvarg.length);
		int offset = 0;
		for (int i = rgvarg.length - 1; i >= 0 ; i--) {
			rgvarg[i].getData(pDispParams.rgvarg + offset);
			offset += VARIANT.sizeof;
		}
	}

	// if arguments have ids, store the ids in rgdispidNamedArgs
	if (rgdispidNamedArgs != null && rgdispidNamedArgs.length > 0) {
		pDispParams.cNamedArgs = rgdispidNamedArgs.length;
		pDispParams.rgdispidNamedArgs = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, 4 * rgdispidNamedArgs.length);
		int offset = 0;
		for (int i = rgdispidNamedArgs.length; i > 0; i--) {
			COM.MoveMemory(pDispParams.rgdispidNamedArgs + offset, new int[] {rgdispidNamedArgs[i-1]}, 4);
			offset += 4;
		}
	}

	// invoke the method
	EXCEPINFO excepInfo = new EXCEPINFO();
	int[] pArgErr = new int[1];
	long /*int*/ pVarResultAddress = 0;
	if (pVarResult != null)	pVarResultAddress = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, VARIANT.sizeof);
	int result = objIDispatch.Invoke(dispIdMember, new GUID(), COM.LOCALE_USER_DEFAULT, wFlags, pDispParams, pVarResultAddress, excepInfo, pArgErr);

	if (pVarResultAddress != 0){
		pVarResult.setData(pVarResultAddress);
		COM.VariantClear(pVarResultAddress);
		OS.GlobalFree(pVarResultAddress);
	}
	
	// free the Dispparams resources
	if (pDispParams.rgdispidNamedArgs != 0){
		OS.GlobalFree(pDispParams.rgdispidNamedArgs);
	}
	if (pDispParams.rgvarg != 0) {
		int offset = 0;
		for (int i = 0, length = rgvarg.length; i < length; i++){
			COM.VariantClear(pDispParams.rgvarg + offset);
			offset += VARIANT.sizeof;
		}
		OS.GlobalFree(pDispParams.rgvarg);
	}

	// save error string and cleanup EXCEPINFO
	manageExcepinfo(result, excepInfo);
		
	return result;
}
/** 
 * Invokes a method on the OLE Object; the method has no parameters.  In the early days of OLE, 
 * the IDispatch interface was not well defined and some applications (mainly Word) did not support 
 * a return value.  For these applications, call this method instead of calling
 * <code>public void invoke(int dispIdMember)</code>.
 *
 * @param dispIdMember the ID of the method as specified by the IDL of the ActiveX Control; the
 *        value for the ID can be obtained using OleAutomation.getIDsOfNames
 *
 * @exception org.eclipse.swt.SWTException <ul>
 *		<li>ERROR_ACTION_NOT_PERFORMED when method invocation fails
 *	</ul>
 */
public void invokeNoReply(int dispIdMember) {
	int result = invoke(dispIdMember, COM.DISPATCH_METHOD, null, null, null);
	if (result != COM.S_OK)
		OLE.error(OLE.ERROR_ACTION_NOT_PERFORMED, result);
}
/** 
 * Invokes a method on the OLE Object; the method has no optional parameters.  In the early days of OLE, 
 * the IDispatch interface was not well defined and some applications (mainly Word) did not support 
 * a return value.  For these applications, call this method instead of calling
 * <code>public void invoke(int dispIdMember, Variant[] rgvarg)</code>.
 *
 * @param dispIdMember the ID of the method as specified by the IDL of the ActiveX Control; the
 *        value for the ID can be obtained using OleAutomation.getIDsOfNames
 *
 * @param rgvarg an array of arguments for the method.  All arguments are considered to be
 *        read only unless the Variant is a By Reference Variant type.
 *
 * @exception org.eclipse.swt.SWTException <ul>
 *		<li>ERROR_ACTION_NOT_PERFORMED when method invocation fails
 *	</ul>
 */
public void invokeNoReply(int dispIdMember, Variant[] rgvarg) {
	int result = invoke(dispIdMember, COM.DISPATCH_METHOD, rgvarg, null, null);
	if (result != COM.S_OK)
		OLE.error(OLE.ERROR_ACTION_NOT_PERFORMED, result);
}
/** 
 * Invokes a method on the OLE Object; the method has optional parameters.  It is not
 * necessary to specify all the optional parameters, only include the parameters for which
 * you are providing values.  In the early days of OLE, the IDispatch interface was not well 
 * defined and some applications (mainly Word) did not support a return value.  For these 
 * applications, call this method instead of calling
 * <code>public void invoke(int dispIdMember, Variant[] rgvarg, int[] rgdispidNamedArgs)</code>.
 *
 * @param dispIdMember the ID of the method as specified by the IDL of the ActiveX Control; the
 *        value for the ID can be obtained using OleAutomation.getIDsOfNames
 *
 * @param rgvarg an array of arguments for the method.  All arguments are considered to be
 *        read only unless the Variant is a By Reference Variant type.
 *
 * @param rgdispidNamedArgs an array of identifiers for the arguments specified in rgvarg; the
 *        parameter IDs must be in the same order as their corresponding values;
 *        all arguments must have an identifier - identifiers can be obtained using 
 *        OleAutomation.getIDsOfNames
 *
 * @exception org.eclipse.swt.SWTException <ul>
 *		<li>ERROR_ACTION_NOT_PERFORMED when method invocation fails
 *	</ul>
 */
public void invokeNoReply(int dispIdMember, Variant[] rgvarg, int[] rgdispidNamedArgs) {
	int result = invoke(dispIdMember, COM.DISPATCH_METHOD, rgvarg, rgdispidNamedArgs, null);
	if (result != COM.S_OK)
		OLE.error(OLE.ERROR_ACTION_NOT_PERFORMED, result);
}
private void manageExcepinfo(int hResult, EXCEPINFO excepInfo) {

	if (hResult == COM.S_OK){
		exceptionDescription = "No Error"; //$NON-NLS-1$
		return;
	}

	// extract exception info
	if (hResult == COM.DISP_E_EXCEPTION) {
		if (excepInfo.bstrDescription != 0){
			int size = COM.SysStringByteLen(excepInfo.bstrDescription);
			char[] buffer = new char[(size + 1) /2];
			COM.MoveMemory(buffer, excepInfo.bstrDescription, size);
			exceptionDescription = new String(buffer);
		} else {
			exceptionDescription = "OLE Automation Error Exception "; //$NON-NLS-1$
			if (excepInfo.wCode != 0){
				exceptionDescription += "code = "+excepInfo.wCode; //$NON-NLS-1$
			} else if (excepInfo.scode != 0){
				exceptionDescription += "code = "+excepInfo.scode; //$NON-NLS-1$
			}
		}
	} else {
		exceptionDescription = "OLE Automation Error HResult : " + hResult; //$NON-NLS-1$
	}

	// cleanup EXCEPINFO struct
	if (excepInfo.bstrDescription != 0)
		COM.SysFreeString(excepInfo.bstrDescription);
	if (excepInfo.bstrHelpFile != 0)
		COM.SysFreeString(excepInfo.bstrHelpFile);
	if (excepInfo.bstrSource != 0)
		COM.SysFreeString(excepInfo.bstrSource);
}
/**
 * Sets the property specified by the dispIdMember to a new value.
 *
 * @param dispIdMember the ID of the property as specified by the IDL of the ActiveX Control; the
 *                     value for the ID can be obtained using OleAutomation.getIDsOfNames
 * @param rgvarg the new value of the property
 *
 * @return true if the operation was successful
 */
public boolean setProperty(int dispIdMember, Variant rgvarg) {
	Variant[] rgvarg2 = new Variant[] {rgvarg};
	int[] rgdispidNamedArgs = new int[] {COM.DISPID_PROPERTYPUT};
	int dwFlags = COM.DISPATCH_PROPERTYPUT;
	if ((rgvarg.getType() & COM.VT_BYREF) == COM.VT_BYREF)
		dwFlags = COM.DISPATCH_PROPERTYPUTREF;
	Variant pVarResult = new Variant();
	int result = invoke(dispIdMember, dwFlags, rgvarg2, rgdispidNamedArgs, pVarResult);
	return (result == COM.S_OK);
}
/**
 * Sets the property specified by the dispIdMember to a new value.
 *
 * @param dispIdMember the ID of the property as specified by the IDL of the ActiveX Control; the
 *                     value for the ID can be obtained using OleAutomation.getIDsOfNames
 * @param rgvarg an array of arguments for the method.  All arguments are considered to be
 *                     read only unless the Variant is a By Reference Variant type.
 *
 * @return true if the operation was successful
 *
 * @since 2.0
 */
public boolean setProperty(int dispIdMember, Variant[] rgvarg) {
	int[] rgdispidNamedArgs = new int[] {COM.DISPID_PROPERTYPUT};
	int dwFlags = COM.DISPATCH_PROPERTYPUT;
	for (int i = 0; i < rgvarg.length; i++) {
		if ((rgvarg[i].getType() & COM.VT_BYREF) == COM.VT_BYREF)
		dwFlags = COM.DISPATCH_PROPERTYPUTREF;
	}
	Variant pVarResult = new Variant();
	int result = invoke(dispIdMember, dwFlags, rgvarg, rgdispidNamedArgs, pVarResult);
	return (result == COM.S_OK);
}
}
