/******************************************************************************* * Copyright (c) 2000, 2003 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package com.impart.ole.outlook; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTError; import org.eclipse.swt.internal.ole.win32.COM; import org.eclipse.swt.internal.ole.win32.IDispatch; import org.eclipse.swt.internal.ole.win32.IUnknown; import org.eclipse.swt.internal.win32.OS; import org.eclipse.swt.ole.win32.OLE; /** * * A Variant is a generic OLE mechanism for passing data of different types via a common interface. * *
It is used within the OleAutomation object for getting a property, setting a property or invoking * a method on an OLE Control or OLE Document. * */ public final class VariantEx { // A variant always takes up 16 bytes, no matter what you // store in it. Objects, strings, and arrays are not physically // stored in the Variant; in these cases, four bytes of the // Variant are used to hold either an object reference, or a // pointer to the string or array. The actual data are stored elsewhere. public static final int sizeof = 16; private short type; // OLE.VT_* type private boolean booleanData; private float floatData; private int intData; private short shortData; private String stringData; private int byRefPtr; private IDispatch dispatchData; private IUnknown unknownData; private double doubleData; /** * Create an empty Variant object with type VT_EMPTY. * * @since 2.0 */ public VariantEx(){ type = COM.VT_EMPTY; } /** * Create a Variant object which represents a Java float as a VT_R4. * * @param val the Java float value that this Variant represents * */ public VariantEx(float val) { type = COM.VT_R4; floatData = val; } public VariantEx(double val) { type = COM.VT_R8; doubleData = val; } /** * Create a Variant object which represents a Java int as a VT_I4. * * @param val the Java int value that this Variant represents * */ public VariantEx(int val) { type = COM.VT_I4; intData = val; } /** * Create a Variant object which contains a reference to the data being transferred. * *
When creating a VT_BYREF Variant, you must give the full Variant type * including VT_BYREF such as * *
short byRefType = OLE.VT_BSTR | OLE.VT_BYREF
.
*
* @param ptr a pointer to the data being transferred.
* @param byRefType the type of the data being transferred such as OLE.VT_BSTR | OLE.VT_BYREF
*
*/
public VariantEx(int ptr, short byRefType) {
type = byRefType;
byRefPtr = ptr;
}
/**
* Create a Variant object which represents an IDispatch interface as a VT_Dispatch.
*
* @param automation the OleAutomation object that this Variant represents
*
*/
public VariantEx(OleAutomationEx automation) {
type = COM.VT_DISPATCH;
dispatchData = new IDispatch(automation.getAddress());
}
/**
* Create a Variant object which represents an IDispatch interface as a VT_Dispatch.
* The caller is expected to have appropriately invoked unknown.AddRef() before creating * this Variant. * * @since 2.0 * * @param idispatch the IDispatch object that this Variant represents * */ public VariantEx(IDispatch idispatch) { type = COM.VT_DISPATCH; dispatchData = idispatch; } /** * Create a Variant object which represents an IUnknown interface as a VT_UNKNOWN. * *
The caller is expected to have appropriately invoked unknown.AddRef() before creating * this Variant. * * @param unknown the IUnknown object that this Variant represents * */ public VariantEx(IUnknown unknown) { type = COM.VT_UNKNOWN; unknownData = unknown; } /** * Create a Variant object which represents a Java String as a VT_BSTR. * * @param string the Java String value that this Variant represents * */ public VariantEx(String string) { type = COM.VT_BSTR; stringData = string; } /** * Create a Variant object which represents a Java short as a VT_I2. * * @param val the Java short value that this Variant represents * */ public VariantEx(short val) { type = COM.VT_I2; shortData = val; } /** * Create a Variant object which represents a Java boolean as a VT_BOOL. * * @param val the Java boolean value that this Variant represents * */ public VariantEx(boolean val) { type = COM.VT_BOOL; booleanData = val; } /** * Calling dispose will release resources associated with this Variant. * If the resource is an IDispatch or IUnknown interface, Release will be called. * If the resource is a ByRef pointer, nothing is released. * * @since 2.1 */ public void dispose() { if ((type & COM.VT_BYREF) == COM.VT_BYREF) { return; } switch (type) { case COM.VT_EMPTY : case COM.VT_BOOL : case COM.VT_R4 : case COM.VT_I4 : case COM.VT_I2 : case COM.VT_BSTR : break; case COM.VT_DISPATCH : dispatchData.Release(); break; case COM.VT_UNKNOWN : unknownData.Release(); break; } } /** * Returns the OleAutomation object represented by this Variant. * *
If this Variant does not contain an OleAutomation object, an attempt is made to * coerce the Variant type into an OleAutomation object. If this fails, an error is * thrown. Note that OleAutomation objects must be disposed when no longer * needed. * * @return the OleAutomation object represented by this Variant * * @exception SWTError * ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into an OleAutomation object */ public OleAutomationEx getAutomation() { if (type == COM.VT_EMPTY) { OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); } if (type == COM.VT_DISPATCH) { return new OleAutomationEx(dispatchData); } // try to coerce the value to the desired type int oldPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof); int newPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof); try { getData(oldPtr); int result = COM.VariantChangeType(newPtr, oldPtr, (short) 0, COM.VT_DISPATCH); if (result != COM.S_OK) OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); VariantEx autoVar = new VariantEx(); autoVar.setData(newPtr); return autoVar.getAutomation(); } finally { COM.VariantClear(oldPtr); OS.GlobalFree(oldPtr); COM.VariantClear(newPtr); // Note: This must absolutely be done AFTER the // OleAutomationEx object is created as Variant Clear // will result in a Release being performed on the // Dispatch object OS.GlobalFree(newPtr); } } /** * Returns the IDispatch object represented by this Variant. * *
If this Variant does not contain an IDispatch object, an attempt is made to * coerce the Variant type into an IDIspatch object. If this fails, an error is * thrown. * * @since 2.0 * * @return the IDispatch object represented by this Variant * * @exception SWTError * ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into an IDispatch object */ public IDispatch getDispatch() { if (type == COM.VT_EMPTY) { OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); } if (type == COM.VT_DISPATCH) { return dispatchData; } // try to coerce the value to the desired type int oldPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof); int newPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof); try { getData(oldPtr); int result = COM.VariantChangeType(newPtr, oldPtr, (short) 0, COM.VT_DISPATCH); if (result != COM.S_OK) OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); VariantEx autoVar = new VariantEx(); autoVar.setData(newPtr); return autoVar.getDispatch(); } finally { COM.VariantClear(oldPtr); OS.GlobalFree(oldPtr); COM.VariantClear(newPtr); // Note: This must absolutely be done AFTER the // OleAutomationEx object is created as Variant Clear // will result in a Release being performed on the // Dispatch object OS.GlobalFree(newPtr); } } /** * Returns the Java boolean represented by this Variant. * *
If this Variant does not contain a Java boolean, an attempt is made to * coerce the Variant type into a Java boolean. If this fails, an error is thrown. * * @return the Java boolean represented by this Variant * * @exception SWTError *
If this Variant does not contain a reference to data, zero is returned. * * @return a pointer to the referenced data represented by this Variant or 0 * */ public int getByRef() { if (type == COM.VT_EMPTY) { OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); } if ((type & COM.VT_BYREF)== COM.VT_BYREF) { return byRefPtr; } return 0; } void getData(int pData){ if (pData == 0) OLE.error(OLE.ERROR_OUT_OF_MEMORY); COM.VariantInit(pData); if ((type & COM.VT_BYREF) == COM.VT_BYREF) { COM.MoveMemory(pData, new short[] {type}, 2); COM.MoveMemory(pData + 8, new int[]{byRefPtr}, 4); return; } switch (type) { case COM.VT_EMPTY : break; case COM.VT_BOOL : COM.MoveMemory(pData, new short[] {type}, 2); COM.MoveMemory(pData + 8, new int[]{(booleanData) ? COM.VARIANT_TRUE : COM.VARIANT_FALSE}, 2); break; case COM.VT_DATE : COM.MoveMemory(pData, new short[] {type}, 2); COM.MoveMemory(pData + 8, new double[]{doubleData}, 8); break; case COM.VT_R8 : COM.MoveMemory(pData, new short[] {type}, 2); COM.MoveMemory(pData + 8, new double[]{doubleData}, 8); break; case COM.VT_R4 : COM.MoveMemory(pData, new short[] {type}, 2); COM.MoveMemory(pData + 8, new float[]{floatData}, 4); break; case COM.VT_I4 : COM.MoveMemory(pData, new short[] {type}, 2); COM.MoveMemory(pData + 8, new int[]{intData}, 4); break; case COM.VT_DISPATCH : dispatchData.AddRef(); COM.MoveMemory(pData, new short[] {type}, 2); COM.MoveMemory(pData + 8, new int[]{dispatchData.getAddress()}, 4); break; case COM.VT_UNKNOWN : unknownData.AddRef(); COM.MoveMemory(pData, new short[] {type}, 2); COM.MoveMemory(pData + 8, new int[]{unknownData.getAddress()}, 4); break; case COM.VT_I2 : COM.MoveMemory(pData, new short[] {type}, 2); COM.MoveMemory(pData + 8, new short[]{shortData}, 2); break; case COM.VT_BSTR : COM.MoveMemory(pData, new short[] {type}, 2); char[] data = (stringData+"\0").toCharArray(); int ptr = COM.SysAllocString(data); COM.MoveMemory(pData + 8, new int[] {ptr}, 4); break; default : OLE.error(SWT.ERROR_NOT_IMPLEMENTED); } } /** * Returns the Java float represented by this Variant. * *
If this Variant does not contain a Java float, an attempt is made to * coerce the Variant type into a Java float. If this fails, an error is thrown. * * @return the Java float represented by this Variant * * @exception SWTError *
If this Variant does not contain a Java int, an attempt is made to * coerce the Variant type into a Java int. If this fails, an error is thrown. * * @return the Java int represented by this Variant * * @exception SWTError *
If this Variant does not contain a Java short, an attempt is made to * coerce the Variant type into a Java short. If this fails, an error is thrown. * * @return the Java short represented by this Variant * * @exception SWTError *
If this Variant does not contain a Java String, an attempt is made to * coerce the Variant type into a Java String. If this fails, an error is thrown. * * @return the Java String represented by this Variant * * @exception SWTError *
If this Variant does not contain an IUnknown object, an attempt is made to * coerce the Variant type into an IUnknown object. If this fails, an error is * thrown. * * @return the IUnknown object represented by this Variant * * @exception SWTError *