diff org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/ole/win32/Variant.d @ 0:6dd524f61e62

add dwt win and basic java stuff
author Frank Benoit <benoit@tionex.de>
date Mon, 02 Mar 2009 14:44:16 +0100
parents
children 6bf2837c50fe
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/ole/win32/Variant.d	Mon Mar 02 14:44:16 2009 +0100
@@ -0,0 +1,1053 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module org.eclipse.swt.ole.win32.Variant;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.internal.ole.win32.extras;
+import org.eclipse.swt.internal.ole.win32.COM;
+import org.eclipse.swt.internal.ole.win32.COMTYPES;
+import org.eclipse.swt.internal.ole.win32.OAIDL;
+import org.eclipse.swt.internal.win32.OS;
+
+import org.eclipse.swt.ole.win32.OleAutomation;
+import org.eclipse.swt.ole.win32.OLE;
+
+import tango.util.Convert;
+import tango.text.convert.Format;
+import java.lang.all;
+
+/**
+ *
+ * A Variant is a generic OLE mechanism for passing data of different types via a common interface.
+ *
+ * <p>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 Variant {
+    /**
+    * The size in bytes of a native VARIANT struct.
+    */
+    /**
+     * 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 bool booleanData;
+    private byte    byteData;
+    private short   shortData;
+    private wchar   charData;
+    private int     intData;
+    private long    longData;
+    private float   floatData;
+    private double  doubleData;
+    private String  stringData;
+    private void*   byRefPtr;
+    private IDispatch dispatchData;
+    private IUnknown unknownData;
+
+/**
+ * Invokes platform specific functionality to copy a variant
+ * into operating system memory.
+ * <p>
+ * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
+ * API for <code>Variant</code>. It is marked public only so that it
+ * can be shared within the packages provided by SWT. It is not
+ * available on all platforms, and should never be called from
+ * application code.
+ * </p>
+ *
+ * @param pVarDest destination pointer to a variant
+ * @param varSrc source <code>Variant</code>
+ *
+ * @since 3.3
+ */
+public static void win32_copy (VARIANT* pVarDest, Variant varSrc) {
+    varSrc.getData (pVarDest);
+}
+
+/**
+ * Invokes platform specific functionality to wrap a variant
+ * that was allocated in operating system memory.
+ * <p>
+ * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
+ * API for <code>Variant</code>. It is marked public only so that it
+ * can be shared within the packages provided by SWT. It is not
+ * available on all platforms, and should never be called from
+ * application code.
+ * </p>
+ *
+ * @param pVariant pointer to a variant
+ *
+ * @return a new <code>Variant</code>
+ *
+ * @since 3.3
+ */
+public static Variant win32_new (VARIANT* pVariant) {
+    Variant variant = new Variant ();
+    variant.setData (pVariant);
+    return variant;
+}
+
+/**
+ * Create an empty Variant object with type VT_EMPTY.
+ *
+ * @since 2.0
+ */
+public this(){
+    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 this(float val) {
+    type = COM.VT_R4;
+    floatData = val;
+
+}
+/**
+ * Create a Variant object which represents a Java double as a VT_R8.
+ *
+ * @param val the Java double value that this Variant represents
+ *
+ * @since 3.2
+ */
+public this(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 this(int val) {
+    type = COM.VT_I4;
+    intData = val;
+}
+public this(uint val) {
+    type = COM.VT_I4;
+    intData = val;
+}
+/**
+ * Create a Variant object which contains a reference to the data being transferred.
+ *
+ * <p>When creating a VT_BYREF Variant, you must give the full Variant type
+ * including VT_BYREF such as
+ *
+ * <pre><code>short byRefType = OLE.VT_BSTR | OLE.VT_BYREF</code></pre>.
+ *
+ * @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 this(void* ptr, ushort 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 this(OleAutomation automation) {
+    type = COM.VT_DISPATCH;
+    dispatchData = automation.getAddress();
+}
+/**
+ * Create a Variant object which represents an IDispatch interface as a VT_Dispatch.
+ * <p>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 this(IDispatch idispatch) {
+    type = COM.VT_DISPATCH;
+    dispatchData = idispatch;
+}
+/**
+ * Create a Variant object which represents an IUnknown interface as a VT_UNKNOWN.
+ *
+ * <p>The caller is expected to have appropriately invoked unknown.AddRef() before creating
+ * this Variant.
+ *
+ * @param unknown the IUnknown object that this Variant represents
+ *
+ */
+public this(IUnknown unknown) {
+    type = COM.VT_UNKNOWN;
+    unknownData = unknown;
+}
+/**
+ * Create a Variant object which represents a Java long as a VT_I8.
+ *
+ * @param val the Java long value that this Variant represents
+ *
+ * @since 3.2
+ */
+ public this(long val) {
+    type = COM.VT_I8;
+    longData = val;
+}
+/**
+ * Create a Variant object which represents a Java String as a VT_BSTR.
+ *
+ * @param string the Java String value that this Variant represents
+ *
+ */
+public this(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 this(short val) {
+    type = COM.VT_I2;
+    shortData = val;
+}
+/**
+ * Create a Variant object which represents a Java bool as a VT_BOOL.
+ *
+ * @param val the Java bool value that this Variant represents
+ *
+ */
+public this(bool 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) is COM.VT_BYREF) {
+        return;
+    }
+
+    switch (type) {
+        case COM.VT_DISPATCH :
+            dispatchData.Release();
+            break;
+        case COM.VT_UNKNOWN :
+            unknownData.Release();
+            break;
+        default:
+    }
+
+}
+/**
+ * Returns the OleAutomation object represented by this Variant.
+ *
+ * <p>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 SWTException <ul>
+ *     <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into an OleAutomation object</li>
+ * </ul>
+ */
+public OleAutomation getAutomation() {
+    if (type is COM.VT_EMPTY) {
+        OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
+    }
+    if (type is COM.VT_DISPATCH) {
+        return new OleAutomation(dispatchData);
+    }
+    // try to coerce the value to the desired type
+    VARIANT oldPtr, newPtr;
+    try {
+        getData(&oldPtr);
+        HRESULT result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_DISPATCH);
+        if (result !is COM.S_OK)
+            OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
+        Variant autoVar = new Variant();
+        autoVar.setData(&newPtr);
+        return autoVar.getAutomation();
+    } finally {
+        COM.VariantClear(&oldPtr);
+        COM.VariantClear(&newPtr); // Note: This must absolutely be done AFTER the
+                                  // OleAutomation object is created as Variant Clear
+                                  // will result in a Release being performed on the
+                                  // Dispatch object
+    }
+}
+/**
+ * Returns the IDispatch object represented by this Variant.
+ *
+ * <p>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 SWTException <ul>
+ *     <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into an IDispatch object</li>
+ * </ul>
+ */
+public IDispatch getDispatch() {
+    if (type is COM.VT_EMPTY) {
+        OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
+    }
+
+    if (type is COM.VT_DISPATCH) {
+        return dispatchData;
+    }
+    // try to coerce the value to the desired type
+    VARIANT oldPtr, newPtr;
+    try {
+        getData(&oldPtr);
+        HRESULT result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_DISPATCH);
+        if (result !is COM.S_OK)
+            OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
+        Variant autoVar = new Variant();
+        autoVar.setData(&newPtr);
+        return autoVar.getDispatch();
+    } finally {
+        COM.VariantClear(&oldPtr);
+        COM.VariantClear(&newPtr); // Note: This must absolutely be done AFTER the
+                                  // OleAutomation object is created as Variant Clear
+                                  // will result in a Release being performed on the
+                                  // Dispatch object
+    }
+}
+/**
+ * Returns the Java bool represented by this Variant.
+ *
+ * <p>If this Variant does not contain a Java bool, an attempt is made to
+ * coerce the Variant type into a Java bool.  If this fails, an error is thrown.
+ *
+ * @return the Java bool represented by this Variant
+ *
+ * @exception SWTException <ul>
+ *     <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a bool</li>
+ * </ul>
+ *
+ */
+public bool getBoolean() {
+    if (type is COM.VT_EMPTY) {
+        OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
+    }
+    if (type is COM.VT_BOOL) {
+        return booleanData;
+    }
+    // try to coerce the value to the desired type
+    VARIANT oldPtr, newPtr;
+    try {
+        getData(&oldPtr);
+        HRESULT result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_BOOL);
+        if (result !is COM.S_OK)
+            OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
+        Variant boolVar = new Variant();
+        boolVar.setData(&newPtr);
+        return boolVar.getBoolean();
+    } finally {
+        COM.VariantClear(&oldPtr);
+        COM.VariantClear(&newPtr);
+    }
+}
+/**
+ * Returns a pointer to the referenced data represented by this Variant.
+ *
+ * <p>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 void* getByRef() {
+    if (type is COM.VT_EMPTY) {
+        OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
+    }
+    if ((type & COM.VT_BYREF)is COM.VT_BYREF) {
+        return byRefPtr;
+    }
+
+    return null;
+}
+/**
+ * Returns the Java byte represented by this Variant.
+ *
+ * <p>If this Variant does not contain a Java byte, an attempt is made to
+ * coerce the Variant type into a Java byte.  If this fails, an error is thrown.
+ *
+ * @return the Java byte represented by this Variant
+ *
+ * @exception SWTException <ul>
+ *     <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a byte</li>
+ * </ul>
+ *
+ * @since 3.3
+ */
+public byte getByte() {
+    if (type is COM.VT_EMPTY) {
+        OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
+    }
+    if (type is COM.VT_I1) {
+        return byteData;
+    }
+
+    // try to coerce the value to the desired type
+    VARIANT oldPtr, newPtr;
+    try {
+        getData(&oldPtr);
+        int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_I1);
+        if (result !is COM.S_OK)
+            OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
+        Variant byteVar = new Variant();
+        byteVar.setData(&newPtr);
+        return byteVar.getByte();
+    } finally {
+        COM.VariantClear(&oldPtr);
+        COM.VariantClear(&newPtr);
+    }
+}
+/**
+ * Returns the Java char represented by this Variant.
+ *
+ * <p>If this Variant does not contain a Java char, an attempt is made to
+ * coerce the Variant type into a Java char.  If this fails, an error is thrown.
+ *
+ * @return the Java char represented by this Variant
+ *
+ * @exception SWTException <ul>
+ *     <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a char</li>
+ * </ul>
+ *
+ * @since 3.3
+ */
+public wchar getChar() {
+    if (type is COM.VT_EMPTY) {
+        OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
+    }
+    if (type is COM.VT_UI2) {
+        return charData;
+    }
+
+    // try to coerce the value to the desired type
+    VARIANT oldPtr, newPtr;
+    try {
+        getData(&oldPtr);
+        int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_UI2);
+        if (result !is COM.S_OK)
+            OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
+        Variant charVar = new Variant();
+        charVar.setData(&newPtr);
+        return charVar.getChar();
+    } finally {
+        COM.VariantClear(&oldPtr);
+        COM.VariantClear(&newPtr);
+    }
+}
+void getData(VARIANT* pData){
+    if (pData is null) OLE.error(OLE.ERROR_OUT_OF_MEMORY);
+
+    COM.VariantInit(pData);
+
+    // set type
+    pData.vt = type;
+    if ((type & COM.VT_BYREF) is COM.VT_BYREF) {
+        COM.MoveMemory((cast(void*)pData), &type, 2);
+        COM.MoveMemory((cast(void*)pData) + 8, &byRefPtr, 4);
+        return;
+    }
+
+    switch (type) {
+        case COM.VT_EMPTY :
+        case COM.VT_NULL :
+            COM.MoveMemory((cast(void*)pData), &type, 2);
+            break;
+        case COM.VT_BOOL :
+            COM.MoveMemory((cast(void*)pData), &type, 2);
+            auto v = booleanData ? COM.VARIANT_TRUE : COM.VARIANT_FALSE;
+            COM.MoveMemory((cast(void*)pData) + 8, &v, 2);
+            break;
+        case COM.VT_I1 :
+            COM.MoveMemory((cast(void*)pData), &type, 2);
+            COM.MoveMemory((cast(void*)pData) + 8, &byteData, 1);
+            break;
+        case COM.VT_I2 :
+            COM.MoveMemory((cast(void*)pData), &type, 2);
+            COM.MoveMemory((cast(void*)pData) + 8, &shortData, 2);
+            break;
+        case COM.VT_UI2 :
+            COM.MoveMemory((cast(void*)pData), &type, 2);
+            COM.MoveMemory((cast(void*)pData) + 8, &charData, 2);
+            break;
+        case COM.VT_I4 :
+            COM.MoveMemory((cast(void*)pData), &type, 2);
+            COM.MoveMemory((cast(void*)pData) + 8, &intData, 4);
+            break;
+        case COM.VT_I8 :
+            COM.MoveMemory((cast(void*)pData), &type, 2);
+            COM.MoveMemory((cast(void*)pData) + 8, &longData, 8);
+            break;
+        case COM.VT_R4 :
+            COM.MoveMemory((cast(void*)pData), &type, 2);
+            COM.MoveMemory((cast(void*)pData) + 8, &floatData, 4);
+            break;
+        case COM.VT_R8 :
+            COM.MoveMemory((cast(void*)pData), &type, 2);
+            COM.MoveMemory((cast(void*)pData) + 8, &doubleData, 8);
+            break;
+        case COM.VT_DISPATCH :
+            dispatchData.AddRef();
+            COM.MoveMemory((cast(void*)pData), &type, 2);
+            auto v = cast(void*)dispatchData;
+            COM.MoveMemory((cast(void*)pData) + 8, &v, 4);
+            break;
+        case COM.VT_UNKNOWN :
+            unknownData.AddRef();
+            COM.MoveMemory((cast(void*)pData), &type, 2);
+            auto v = cast(void*)dispatchData;
+            COM.MoveMemory((cast(void*)pData) + 8, &v, 4);
+            break;
+        case COM.VT_BSTR :
+            COM.MoveMemory((cast(void*)pData), &type, 2);
+            wchar[] data = StrToWCHARs(stringData);
+            auto ptr = COM.SysAllocString(data.ptr);
+            COM.MoveMemory((cast(void*)pData) + 8, &ptr, 4);
+            break;
+
+        default :
+            OLE.error(SWT.ERROR_NOT_IMPLEMENTED);
+    }
+}
+/**
+ * Returns the Java double represented by this Variant.
+ *
+ * <p>If this Variant does not contain a Java double, an attempt is made to
+ * coerce the Variant type into a Java double.  If this fails, an error is thrown.
+ *
+ * @return the Java double represented by this Variant
+ *
+ * @exception SWTException <ul>
+ *     <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a double</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public double getDouble() {
+    if (type is COM.VT_EMPTY) {
+        OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
+    }
+    if (type is COM.VT_R8) {
+        return doubleData;
+    }
+
+    // try to coerce the value to the desired type
+    VARIANT oldPtr, newPtr;
+    try {
+        getData(&oldPtr);
+        int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_R8);
+        if (result !is COM.S_OK)
+            OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
+        Variant doubleVar = new Variant();
+        doubleVar.setData(&newPtr);
+        return doubleVar.getDouble();
+    } finally {
+        COM.VariantClear(&oldPtr);
+        COM.VariantClear(&newPtr);
+    }
+}
+
+/**
+ * Returns the Java float represented by this Variant.
+ *
+ * <p>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 SWTException <ul>
+ *     <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a float</li>
+ * </ul>
+ */
+public float getFloat() {
+    if (type is COM.VT_EMPTY) {
+        OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
+    }
+    if (type is COM.VT_R4) {
+        return floatData;
+    }
+
+    // try to coerce the value to the desired type
+    VARIANT oldPtr, newPtr;
+    try {
+        getData(&oldPtr);
+        int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_R4);
+        if (result !is COM.S_OK)
+            OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
+        Variant floatVar = new Variant();
+        floatVar.setData(&newPtr);
+        return floatVar.getFloat();
+    } finally {
+        COM.VariantClear(&oldPtr);
+        COM.VariantClear(&newPtr);
+    }
+
+}
+/**
+ * Returns the Java int represented by this Variant.
+ *
+ * <p>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 SWTException <ul>
+ *     <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a int</li>
+ * </ul>
+ */
+public int getInt() {
+    if (type is COM.VT_EMPTY) {
+        OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
+    }
+    if (type is COM.VT_I4) {
+        return intData;
+    }
+
+    // try to coerce the value to the desired type
+    VARIANT oldPtr, newPtr;
+    try {
+        getData(&oldPtr);
+        int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_I4);
+        if (result !is COM.S_OK)
+            OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
+        Variant intVar = new Variant();
+        intVar.setData(&newPtr);
+        return intVar.getInt();
+    } finally {
+        COM.VariantClear(&oldPtr);
+        COM.VariantClear(&newPtr);
+    }
+}
+/**
+ * Returns the Java long represented by this Variant.
+ *
+ * <p>If this Variant does not contain a Java long, an attempt is made to
+ * coerce the Variant type into a Java long.  If this fails, an error is thrown.
+ *
+ * @return the Java long represented by this Variant
+ *
+ * @exception SWTException <ul>
+ *     <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a long</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public long getLong() {
+    if (type is COM.VT_EMPTY) {
+        OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
+    }
+    if (type is COM.VT_I8) {
+        return longData;
+    }
+
+    // try to coerce the value to the desired type
+    VARIANT oldPtr, newPtr;
+    try {
+        getData(&oldPtr);
+        int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_I8);
+        if (result !is COM.S_OK)
+            OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
+        Variant longVar = new Variant();
+        longVar.setData(&newPtr);
+        return longVar.getLong();
+    } finally {
+        COM.VariantClear(&oldPtr);
+        COM.VariantClear(&newPtr);
+    }
+}
+/**
+ * Returns the Java short represented by this Variant.
+ *
+ * <p>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 SWTException <ul>
+ *     <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a short</li>
+ * </ul>
+ */
+public short getShort() {
+    if (type is COM.VT_EMPTY) {
+        OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
+    }
+    if (type is COM.VT_I2) {
+        return shortData;
+    }
+
+    // try to coerce the value to the desired type
+    VARIANT oldPtr, newPtr;
+    try {
+        getData(&oldPtr);
+        int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_I2);
+        if (result !is COM.S_OK)
+            OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
+        Variant shortVar = new Variant();
+        shortVar.setData(&newPtr);
+        return shortVar.getShort();
+    } finally {
+        COM.VariantClear(&oldPtr);
+        COM.VariantClear(&newPtr);
+    }
+
+}
+/**
+ * Returns the Java String represented by this Variant.
+ *
+ * <p>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 SWTException <ul>
+ *     <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a String</li>
+ * </ul>
+ */
+public String getString() {
+    if (type is COM.VT_EMPTY) {
+        OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
+    }
+    if (type is COM.VT_BSTR) {
+        return stringData;
+    }
+
+    // try to coerce the value to the desired type
+    VARIANT oldPtr, newPtr;
+    try {
+        getData(&oldPtr);
+        int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_BSTR);
+        if (result !is COM.S_OK)
+            OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
+
+        Variant stringVar = new Variant();
+        stringVar.setData(&newPtr);
+        return stringVar.getString();
+
+    } finally {
+        COM.VariantClear(&oldPtr);
+        COM.VariantClear(&newPtr);
+    }
+}
+/**
+ * Returns the type of the variant type.  This will be an OLE.VT_* value or
+ * a bitwise combination of OLE.VT_* values as in the case of
+ * OLE.VT_BSTR | OLE.VT_BYREF.
+ *
+ * @return the type of the variant data
+ *
+ * @since 2.0
+ */
+public short getType() {
+    return type;
+}
+/**
+ * Returns the IUnknown object represented by this Variant.
+ *
+ * <p>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 SWTException <ul>
+ *     <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into
+ *          an IUnknown object</li>
+ * </ul>
+ */
+public IUnknown getUnknown() {
+    if (type is COM.VT_EMPTY) {
+        OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
+    }
+    if (type is COM.VT_UNKNOWN) {
+        return unknownData;
+    }
+
+    // try to coerce the value to the desired type
+    VARIANT oldPtr, newPtr;
+    try {
+        getData(&oldPtr);
+        int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_UNKNOWN);
+        if (result !is COM.S_OK)
+            OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
+        Variant unknownVar = new Variant();
+        unknownVar.setData(&newPtr);
+        return unknownVar.getUnknown();
+    } finally {
+        COM.VariantClear(&oldPtr);
+        COM.VariantClear(&newPtr); // Note: This must absolutely be done AFTER the
+                                  // IUnknown object is created as Variant Clear
+                                  // will result in a Release being performed on the
+                                  // Dispatch object
+    }
+}
+/**
+ * Update the by reference value of this variant with a new bool value.
+ *
+ * @param val the new bool value
+ *
+ * @exception SWTException <ul>
+ *     <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant is not
+ *          a (VT_BYREF | VT_BOOL) object</li>
+ * </ul>
+ *
+ * @since 2.1
+ */
+public void setByRef(bool val) {
+    if ((type & COM.VT_BYREF) is 0 || (type & COM.VT_BOOL) is 0) {
+        OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE);
+    }
+    auto v = val ? COM.VARIANT_TRUE : COM.VARIANT_FALSE;
+    COM.MoveMemory(byRefPtr, &v, 2);
+}
+/**
+ * Update the by reference value of this variant with a new float value.
+ *
+ * @param val the new float value
+ *
+ * @exception SWTException <ul>
+ *     <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant is not
+ *          a (VT_BYREF | VT_R4) object</li>
+ * </ul>
+ *
+ * @since 2.1
+ */
+public void setByRef(float val) {
+    if ((type & COM.VT_BYREF) is 0 || (type & COM.VT_R4) is 0) {
+        OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE);
+    }
+    COM.MoveMemory(byRefPtr, &val, 4);
+}
+/**
+ * Update the by reference value of this variant with a new integer value.
+ *
+ * @param val the new integer value
+ *
+ * @exception SWTException <ul>
+ *     <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant is not a (VT_BYREF | VT_I4) object</li>
+ * </ul>
+ *
+ * @since 2.1
+ */
+public void setByRef(int val) {
+    if ((type & COM.VT_BYREF) is 0 || (type & COM.VT_I4) is 0) {
+        OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE);
+    }
+    COM.MoveMemory(byRefPtr, &val, 4);
+}
+/**
+ * Update the by reference value of this variant with a new short value.
+ *
+ * @param val the new short value
+ *
+ * @exception SWTException <ul>
+ *     <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant is not a (VT_BYREF | VT_I2) object
+ * </ul>
+ *
+ * @since 2.1
+ */
+public void setByRef(short val) {
+    if ((type & COM.VT_BYREF) is 0 || (type & COM.VT_I2) is 0) {
+        OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE);
+    }
+    COM.MoveMemory(byRefPtr, &val, 2);
+}
+
+void setData(VARIANT* pData){
+    if (pData is null) OLE.error(OLE.ERROR_INVALID_ARGUMENT);
+
+    short[1] dataType ;
+    COM.MoveMemory(dataType.ptr, (cast(void*)pData), 2);
+    type = dataType[0];
+
+    if ((type & COM.VT_BYREF) is COM.VT_BYREF) {
+        void*[1] newByRefPtr;
+        OS.MoveMemory(newByRefPtr.ptr, (cast(void*)pData) + 8, 4);
+        byRefPtr = newByRefPtr[0];
+        return;
+    }
+
+    switch (type) {
+        case COM.VT_EMPTY :
+        case COM.VT_NULL :
+            break;
+        case COM.VT_BOOL :
+            short[1] newBooleanData;
+            COM.MoveMemory(newBooleanData.ptr, (cast(void*)pData) + 8, 2);
+            booleanData = (newBooleanData[0] !is COM.VARIANT_FALSE);
+            break;
+        case COM.VT_I1 :
+            byte[1] newByteData;
+            COM.MoveMemory(newByteData.ptr, (cast(void*)pData) + 8, 1);
+            byteData = newByteData[0];
+            break;
+        case COM.VT_I2 :
+            short[1] newShortData;
+            COM.MoveMemory(newShortData.ptr, (cast(void*)pData) + 8, 2);
+            shortData = newShortData[0];
+            break;
+        case COM.VT_UI2 :
+            wchar[1] newCharData;
+            COM.MoveMemory(newCharData.ptr, (cast(void*)pData) + 8, 2);
+            charData = newCharData[0];
+            break;
+        case COM.VT_I4 :
+            int[1] newIntData;
+            OS.MoveMemory(newIntData.ptr, (cast(void*)pData) + 8, 4);
+            intData = newIntData[0];
+            break;
+        case COM.VT_I8 :
+            long[1] newLongData;
+            OS.MoveMemory(newLongData.ptr, (cast(void*)pData) + 8, 8);
+            longData = newLongData[0];
+            break;
+        case COM.VT_R4 :
+            float[1] newFloatData;
+            COM.MoveMemory(newFloatData.ptr, (cast(void*)pData) + 8, 4);
+            floatData = newFloatData[0];
+            break;
+        case COM.VT_R8 :
+            double[1] newDoubleData;
+            COM.MoveMemory(newDoubleData.ptr, (cast(void*)pData) + 8, 8);
+            doubleData = newDoubleData[0];
+            break;
+        case COM.VT_DISPATCH : {
+            IDispatch[1] ppvObject;
+            OS.MoveMemory(ppvObject.ptr, (cast(void*)pData) + 8, 4);
+            if (ppvObject[0] is null) {
+                type = COM.VT_EMPTY;
+                break;
+            }
+            dispatchData = ppvObject[0];
+            dispatchData.AddRef();
+            break;
+        }
+        case COM.VT_UNKNOWN : {
+            IUnknown[1] ppvObject;
+            OS.MoveMemory(ppvObject.ptr, (cast(void*)pData) + 8, 4);
+            if (ppvObject[0] is null) {
+                type = COM.VT_EMPTY;
+                break;
+            }
+            unknownData = ppvObject[0];
+            unknownData.AddRef();
+            break;
+        }
+        case COM.VT_BSTR :
+            // get the address of the memory in which the string resides
+            wchar*[1] hMem;
+            OS.MoveMemory(hMem.ptr, (cast(void*)pData) + 8, 4);
+            if (hMem[0] is null) {
+                type = COM.VT_EMPTY;
+                break;
+            }
+            // Get the size of the string from the OS - the size is expressed in number
+            // of bytes - each unicode character is 2 bytes.
+            int size = COM.SysStringByteLen(hMem[0]);
+            if (size > 0){
+                // get the unicode character array from the global memory and create a String
+                wchar[] buffer = new wchar[(size + 1) /2]; // add one to avoid rounding errors
+                COM.MoveMemory(buffer.ptr, hMem[0], size);
+                stringData = WCHARsToStr( buffer );
+            } else {
+                stringData = ""; //$NON-NLS-1$
+            }
+            break;
+
+        default :
+            // try coercing it into one of the known forms
+            auto newPData = cast(VARIANT*) OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, VARIANT.sizeof);
+            if (COM.VariantChangeType(newPData, pData, 0, COM.VT_R4) is COM.S_OK) {
+                setData(newPData);
+            } else if (COM.VariantChangeType(newPData, pData, 0, COM.VT_I4) is COM.S_OK) {
+                setData(newPData);
+            } else if (COM.VariantChangeType(newPData, pData, 0, COM.VT_BSTR) is COM.S_OK) {
+                setData(newPData);
+            }
+            COM.VariantClear(newPData);
+            OS.GlobalFree(newPData);
+            break;
+    }
+}
+
+/**
+ * Returns a string containing a concise, human-readable
+ * description of the receiver.
+ *
+ * @return a string representation of the Variant
+ */
+public String toString () {
+    switch (type) {
+        case COM.VT_BOOL :
+            return "VT_BOOL{"~to!(String)(booleanData)~"}";
+        case COM.VT_I1 :
+            return "VT_I1{"~to!(String)(byteData)~"}";
+        case COM.VT_I2 :
+            return "VT_I2{"~to!(String)(shortData)~"}";
+        case COM.VT_UI2 :
+            return "VT_UI2{"~ dcharToString(charData) ~"}";
+        case COM.VT_I4 :
+            return "VT_I4{"~to!(String)(intData)~"}";
+        case COM.VT_I8 :
+            return "VT_I8{"~to!(String)(longData)~"}";
+        case COM.VT_R4 :
+            return "VT_R4{"~to!(String)(floatData)~"}";
+        case COM.VT_R8 :
+            return "VT_R8{"~to!(String)(doubleData)~"}";
+        case COM.VT_BSTR :
+            return "VT_BSTR{"~stringData~"}";
+        case COM.VT_DISPATCH :
+            return Format("VT_DISPATCH{{0x{:X}}", cast(void*) (dispatchData is null ? null : dispatchData));
+        case COM.VT_UNKNOWN :
+            return Format("VT_UNKNOWN{{0x{:X}}", cast(void*) (unknownData is null ? null : unknownData));
+        case COM.VT_EMPTY :
+            return "VT_EMPTY";
+        case COM.VT_NULL :
+            return "VT_NULL";
+        default:
+     }
+    if ((type & COM.VT_BYREF) !is 0) {
+        return Format("VT_BYREF|{}{{{}}",(type & ~COM.VT_BYREF), byRefPtr );
+    }
+    return "Unsupported Type "~to!(String)(type);
+}
+}