changeset 134:fa7d7d66b9ed

Accessible
author Frank Benoit <benoit@tionex.de>
date Wed, 13 Feb 2008 03:22:44 +0100
parents ce00a993e4c3
children 242e33c0e383
files dwt/accessibility/Accessible.d dwt/internal/ole/win32/COM.d
diffstat 2 files changed, 410 insertions(+), 447 deletions(-) [+]
line wrap: on
line diff
--- a/dwt/accessibility/Accessible.d	Wed Feb 13 01:37:19 2008 +0100
+++ b/dwt/accessibility/Accessible.d	Wed Feb 13 03:22:44 2008 +0100
@@ -12,98 +12,16 @@
  *******************************************************************************/
 module dwt.accessibility.Accessible;
 
-import dwt.widgets.Control;
-//PORTING_TYPE
-import dwt.accessibility.Accessible;
-import dwt.accessibility.AccessibleControlListener;
-import dwt.accessibility.AccessibleListener;
-import dwt.accessibility.AccessibleTextListener;
-import dwt.widgets.Control;
-class  Accessible {
-    public static Accessible internal_new_Accessible(Control control) {
-        return new Accessible;
-    }
-//     int AddRef();
-//     int Release();
-//     int QueryInterface(int, int);
-//     void checkWidget();
-//     void setFocus(int);
-    void internal_dispose_Accessible(){
-    }
-    int internal_WM_GETOBJECT(int, int){
-        assert(false);
-        return 0;
-    }
-//     bool isValidThread();
-//     int Next(int, int, int);
-//     int Skip(int);
-    void addAccessibleListener(AccessibleListener){
-    }
-    void addAccessibleControlListener(AccessibleControlListener){
-    }
-//     void addAccessibleTextListener(AccessibleTextListener);
-//     void removeAccessibleListener(AccessibleListener);
-//     void removeAccessibleControlListener(AccessibleControlListener);
-//     void removeAccessibleTextListener(AccessibleTextListener);
-//     int childIDToOs(int);
-//     void textCaretMoved(int);
-//     void textChanged(int, int, int);
-//     void textSelectionChanged();
-//     int accDoDefaultAction(int);
-//     int accHitTest(int, int, int);
-//     int accLocation(int, int, int, int, int);
-//     int osToChildID(int);
-//     int accNavigate(int, int, int);
-//     int accSelect(int, int);
-//     int get_accChild(int, int);
-//     int get_accChildCount(int);
-//     int get_accDefaultAction(int, int);
-//     int get_accDescription(int, int);
-//     int get_accFocus(int);
-//     int get_accHelp(int, int);
-//     int get_accHelpTopic(int, int, int);
-//     int get_accKeyboardShortcut(int, int);
-//     int get_accName(int, int);
-//     int get_accParent(int);
-//     int get_accRole(int, int);
-//     int osToRole(int);
-//     int roleToOs(int);
-//     int get_accSelection(int);
-//     int get_accState(int, int);
-//     int osToState(int);
-//     int stateToOs(int);
-//     int get_accValue(int, int);
-//     int put_accName(int, int);
-//     int put_accValue(int, int);
-//     int Clone(int);
-//     Control getControl();
-//     void selectionChanged();
-//     int Reset();
-    //int refCount;
-    //int enumIndex;
-    //COMObject objIAccessible;
-    //COMObject objIEnumVARIANT;
-    //IAccessible iaccessible;
-    //Vector accessibleListeners;
-    //Vector accessibleControlListeners;
-    //Vector textListeners;
-    //Object[] variants;
-    //Control control;
-}
-
-
-/++
 import dwt.DWT;
 import dwt.DWTException;
 import dwt.internal.ole.win32.COM;
-import dwt.internal.ole.win32.COMObject;
-import dwt.internal.ole.win32.GUID;
-import dwt.internal.ole.win32.IAccessible;
-import dwt.internal.ole.win32.IEnumVARIANT;
-import dwt.internal.ole.win32.VARIANT;
+import dwt.internal.ole.win32.OAIDL;
+import dwt.internal.ole.win32.ifs;
+import dwt.internal.ole.win32.extras;
 import dwt.internal.win32.OS;
-import dwt.internal.win32.TVITEM;
+import dwt.internal.DWTEventListener;
 import dwt.ole.win32.OLE;
+import dwt.ole.win32.Variant;
 import dwt.widgets.Control;
 import dwt.widgets.Table;
 import dwt.widgets.TableItem;
@@ -111,6 +29,17 @@
 import dwt.widgets.TreeItem;
 import dwt.widgets.Widget;
 
+import dwt.accessibility.ACC;
+import dwt.accessibility.AccessibleControlListener;
+import dwt.accessibility.AccessibleListener;
+import dwt.accessibility.AccessibleTextListener;
+import dwt.accessibility.AccessibleControlEvent;
+import dwt.accessibility.AccessibleEvent;
+
+import dwt.dwthelper.utils;
+import tango.core.Array;
+import tango.core.Thread;
+
 /**
  * Instances of this class provide a bridge between application
  * code and assistive technology clients. Many platforms provide
@@ -134,59 +63,32 @@
  */
 public class Accessible {
     int refCount = 0, enumIndex = 0;
-    COMObject objIAccessible, objIEnumVARIANT;
+    _IAccessibleImpl objIAccessible;
+    _IEnumVARIANTImpl objIEnumVARIANT;
     IAccessible iaccessible;
-    Vector accessibleListeners = new Vector();
-    Vector accessibleControlListeners = new Vector();
-    Vector textListeners = new Vector ();
+    DWTEventListener[] accessibleListeners;
+    DWTEventListener[] accessibleControlListeners;
+    DWTEventListener[] textListeners;
     Object[] variants;
     Control control;
 
-    Accessible(Control control) {
+    this(Control control) {
         this.control = control;
         int /*long*/[] ppvObject = new int /*long*/[1];
         /* CreateStdAccessibleObject([in] hwnd, [in] idObject, [in] riidInterface, [out] ppvObject).
          * AddRef has already been called on ppvObject by the callee and must be released by the caller.
          */
-        int result = (int)/*64*/COM.CreateStdAccessibleObject(control.handle, COM.OBJID_CLIENT, COM.IIDIAccessible, ppvObject);
+        HRESULT result = COM.CreateStdAccessibleObject(control.handle, COM.OBJID_CLIENT, &COM.IIDIAccessible, cast(void**)&iaccessible);
         /* The object needs to be checked, because if the CreateStdAccessibleObject()
          * symbol is not found, the return value is S_OK.
          */
-        if (ppvObject[0] is 0) return;
+        if (iaccessible is null) return;
         if (result !is COM.S_OK) OLE.error(OLE.ERROR_CANNOT_CREATE_OBJECT, result);
-        iaccessible = new IAccessible(ppvObject[0]);
 
-        objIAccessible = new COMObject(new int[] {2,0,0,1,3,5,8,1,1,2,2,2,2,2,2,2,3,2,1,1,2,2,5,3,3,1,2,2}) {
-            public int /*long*/ method0(int /*long*/[] args) {return QueryInterface(args[0], args[1]);}
-            public int /*long*/ method1(int /*long*/[] args) {return AddRef();}
-            public int /*long*/ method2(int /*long*/[] args) {return Release();}
-            // method3 GetTypeInfoCount - not implemented
-            // method4 GetTypeInfo - not implemented
-            // method5 GetIDsOfNames - not implemented
-            // method6 Invoke - not implemented
-            public int /*long*/ method7(int /*long*/[] args) {return get_accParent(args[0]);}
-            public int /*long*/ method8(int /*long*/[] args) {return get_accChildCount(args[0]);}
-            public int /*long*/ method9(int /*long*/[] args) {return get_accChild(args[0], args[1]);}
-            public int /*long*/ method10(int /*long*/[] args) {return get_accName(args[0], args[1]);}
-            public int /*long*/ method11(int /*long*/[] args) {return get_accValue(args[0], args[1]);}
-            public int /*long*/ method12(int /*long*/[] args) {return get_accDescription(args[0], args[1]);}
-            public int /*long*/ method13(int /*long*/[] args) {return get_accRole(args[0], args[1]);}
-            public int /*long*/ method14(int /*long*/[] args) {return get_accState(args[0], args[1]);}
-            public int /*long*/ method15(int /*long*/[] args) {return get_accHelp(args[0], args[1]);}
-            public int /*long*/ method16(int /*long*/[] args) {return get_accHelpTopic(args[0], args[1], args[2]);}
-            public int /*long*/ method17(int /*long*/[] args) {return get_accKeyboardShortcut(args[0], args[1]);}
-            public int /*long*/ method18(int /*long*/[] args) {return get_accFocus(args[0]);}
-            public int /*long*/ method19(int /*long*/[] args) {return get_accSelection(args[0]);}
-            public int /*long*/ method20(int /*long*/[] args) {return get_accDefaultAction(args[0], args[1]);}
-            public int /*long*/ method21(int /*long*/[] args) {return accSelect((int)/*64*/args[0], args[1]);}
-            public int /*long*/ method22(int /*long*/[] args) {return accLocation(args[0], args[1], args[2], args[3], args[4]);}
-            public int /*long*/ method23(int /*long*/[] args) {return accNavigate((int)/*64*/args[0], args[1], args[2]);}
-            public int /*long*/ method24(int /*long*/[] args) {return accHitTest((int)/*64*/args[0], (int)/*64*/args[1], args[2]);}
-            public int /*long*/ method25(int /*long*/[] args) {return accDoDefaultAction(args[0]);}
-            public int /*long*/ method26(int /*long*/[] args) {return put_accName(args[0], args[1]);}
-            public int /*long*/ method27(int /*long*/[] args) {return put_accValue(args[0], args[1]);}
-        };
+        objIAccessible = new _IAccessibleImpl(this);
 
+//PORTING_FIXME: i don't understand this...
+/+
         int /*long*/ ppVtable = objIAccessible.ppVtable;
         int /*long*/[] pVtable = new int /*long*/[1];
         COM.MoveMemory(pVtable, ppVtable, OS.PTR_SIZEOF);
@@ -209,16 +111,9 @@
         funcs[26] = COM.put_accName_CALLBACK(funcs[26]);
         funcs[27] = COM.put_accValue_CALLBACK(funcs[27]);
         COM.MoveMemory(pVtable[0], funcs, OS.PTR_SIZEOF * funcs.length);
++/
 
-        objIEnumVARIANT = new COMObject(new int[] {2,0,0,3,1,0,1}) {
-            public int /*long*/ method0(int /*long*/[] args) {return QueryInterface(args[0], args[1]);}
-            public int /*long*/ method1(int /*long*/[] args) {return AddRef();}
-            public int /*long*/ method2(int /*long*/[] args) {return Release();}
-            public int /*long*/ method3(int /*long*/[] args) {return Next((int)args[0], args[1], args[2]);}
-            public int /*long*/ method4(int /*long*/[] args) {return Skip((int)args[0]);}
-            public int /*long*/ method5(int /*long*/[] args) {return Reset();}
-            public int /*long*/ method6(int /*long*/[] args) {return Clone(args[0]);}
-        };
+        objIEnumVARIANT = new _IEnumVARIANTImpl(this) ;
         AddRef();
     }
 
@@ -262,8 +157,8 @@
      */
     public void addAccessibleListener(AccessibleListener listener) {
         checkWidget();
-        if (listener is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
-        accessibleListeners.addElement(listener);
+        if (listener is null) DWT.error(__FILE__, __LINE__, DWT.ERROR_NULL_ARGUMENT);
+        accessibleListeners ~= listener;
     }
 
     /**
@@ -289,8 +184,8 @@
      */
     public void addAccessibleControlListener(AccessibleControlListener listener) {
         checkWidget();
-        if (listener is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
-        accessibleControlListeners.addElement(listener);
+        if (listener is null) DWT.error(__FILE__, __LINE__, DWT.ERROR_NULL_ARGUMENT);
+        accessibleControlListeners ~= listener;
     }
 
     /**
@@ -319,7 +214,7 @@
     public void addAccessibleTextListener (AccessibleTextListener listener) {
         checkWidget ();
         if (listener is null) DWT.error (DWT.ERROR_NULL_ARGUMENT);
-        textListeners.addElement (listener);
+        textListeners ~= listener;
     }
 
     /**
@@ -362,12 +257,12 @@
      */
     public int /*long*/ internal_WM_GETOBJECT (int /*long*/ wParam, int /*long*/ lParam) {
         if (objIAccessible is null) return 0;
-        if ((int)/*64*/lParam is COM.OBJID_CLIENT) {
+        if (cast(int)/*64*/lParam is COM.OBJID_CLIENT) {
             /* LresultFromObject([in] riid, [in] wParam, [in] pAcc)
              * The argument pAcc is owned by the caller so reference count does not
              * need to be incremented.
              */
-            return COM.LresultFromObject(COM.IIDIAccessible, wParam, objIAccessible.getAddress());
+            return COM.LresultFromObject(&COM.IIDIAccessible, wParam, cast(IAccessible)objIAccessible);
         }
         return 0;
     }
@@ -393,8 +288,8 @@
      */
     public void removeAccessibleListener(AccessibleListener listener) {
         checkWidget();
-        if (listener is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
-        accessibleListeners.removeElement(listener);
+        if (listener is null) DWT.error(__FILE__, __LINE__, DWT.ERROR_NULL_ARGUMENT);
+        accessibleListeners.remove(listener);
     }
 
     /**
@@ -418,8 +313,8 @@
      */
     public void removeAccessibleControlListener(AccessibleControlListener listener) {
         checkWidget();
-        if (listener is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
-        accessibleControlListeners.removeElement(listener);
+        if (listener is null) DWT.error(__FILE__, __LINE__, DWT.ERROR_NULL_ARGUMENT);
+        accessibleControlListeners.remove(listener);
     }
 
     /**
@@ -446,7 +341,7 @@
     public void removeAccessibleTextListener (AccessibleTextListener listener) {
         checkWidget ();
         if (listener is null) DWT.error (DWT.ERROR_NULL_ARGUMENT);
-        textListeners.removeElement (listener);
+        textListeners.remove (listener);
     }
 
     /**
@@ -543,63 +438,54 @@
      * Ownership of ppvObject transfers from callee to caller so reference count on ppvObject
      * must be incremented before returning.  Caller is responsible for releasing ppvObject.
      */
-    int QueryInterface(int /*long*/ iid, int /*long*/ ppvObject) {
+    HRESULT QueryInterface(REFIID riid, void** ppvObject) {
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
-        GUID guid = new GUID();
-        COM.MoveMemory(guid, iid, GUID.sizeof);
 
-        if (COM.IsEqualGUID(guid, COM.IIDIUnknown)) {
-            COM.MoveMemory(ppvObject, new int /*long*/[] { objIAccessible.getAddress()}, OS.PTR_SIZEOF);
+        if (COM.IsEqualGUID(riid, &COM.IIDIUnknown)) {
+            *ppvObject = cast(void*)cast(IUnknown)  objIAccessible;
             AddRef();
             return COM.S_OK;
         }
 
-        if (COM.IsEqualGUID(guid, COM.IIDIDispatch)) {
-            COM.MoveMemory(ppvObject, new int /*long*/[] { objIAccessible.getAddress()}, OS.PTR_SIZEOF);
+        if (COM.IsEqualGUID(riid, &COM.IIDIDispatch)) {
+            *ppvObject = cast(void*)cast(IDispatch) objIAccessible;
             AddRef();
             return COM.S_OK;
         }
 
-        if (COM.IsEqualGUID(guid, COM.IIDIAccessible)) {
-            COM.MoveMemory(ppvObject, new int /*long*/[] { objIAccessible.getAddress()}, OS.PTR_SIZEOF);
+        if (COM.IsEqualGUID(riid, &COM.IIDIAccessible)) {
+            *ppvObject = cast(void*)cast(IAccessible) objIAccessible;
             AddRef();
             return COM.S_OK;
         }
 
-        if (COM.IsEqualGUID(guid, COM.IIDIEnumVARIANT)) {
-            COM.MoveMemory(ppvObject, new int /*long*/[] { objIEnumVARIANT.getAddress()}, OS.PTR_SIZEOF);
+        if (COM.IsEqualGUID(riid, &COM.IIDIEnumVARIANT)) {
+            *ppvObject = cast(void*)cast(IEnumVARIANT) objIEnumVARIANT;
             AddRef();
             enumIndex = 0;
             return COM.S_OK;
         }
 
-        int /*long*/[] ppv = new int /*long*/[1];
-        int result = iaccessible.QueryInterface(guid, ppv);
-        COM.MoveMemory(ppvObject, ppv, OS.PTR_SIZEOF);
+        HRESULT result = iaccessible.QueryInterface(riid, ppvObject);
         return result;
     }
 
-    int AddRef() {
+    ULONG AddRef() {
         refCount++;
         return refCount;
     }
 
-    int Release() {
+    ULONG Release() {
         refCount--;
 
         if (refCount is 0) {
-            if (objIAccessible !is null)
-                objIAccessible.dispose();
             objIAccessible = null;
-
-            if (objIEnumVARIANT !is null)
-                objIEnumVARIANT.dispose();
             objIEnumVARIANT = null;
         }
         return refCount;
     }
 
-    int accDoDefaultAction(int /*long*/ variant) {
+    HRESULT accDoDefaultAction(VARIANT variant) {
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
         // Currently, we don't let the application override this. Forward to the proxy.
         int code = iaccessible.accDoDefaultAction(variant);
@@ -607,9 +493,9 @@
         return code;
     }
 
-    int accHitTest(int xLeft, int yTop, int /*long*/ pvarChild) {
+    HRESULT accHitTest(LONG xLeft, LONG yTop, VARIANT* pvarChild) {
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
-        if (accessibleControlListeners.size() is 0) {
+        if (accessibleControlListeners.length is 0) {
             return iaccessible.accHitTest(xLeft, yTop, pvarChild);
         }
 
@@ -617,57 +503,57 @@
         event.childID = ACC.CHILDID_NONE;
         event.x = xLeft;
         event.y = yTop;
-        for (int i = 0; i < accessibleControlListeners.size(); i++) {
-            AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
+        for (int i = 0; i < accessibleControlListeners.length; i++) {
+            AccessibleControlListener listener = cast(AccessibleControlListener) accessibleControlListeners[i];
             listener.getChildAtPoint(event);
         }
         int childID = event.childID;
         if (childID is ACC.CHILDID_NONE) {
             return iaccessible.accHitTest(xLeft, yTop, pvarChild);
         }
-        COM.MoveMemory(pvarChild, new short[] { COM.VT_I4 }, 2);
-        COM.MoveMemory(pvarChild + 8, new int[] { childIDToOs(childID) }, 4);
+        pvarChild.vt = COM.VT_I4;
+        pvarChild.lVal = childIDToOs(childID);
         return COM.S_OK;
     }
 
-    int accLocation(int /*long*/ pxLeft, int /*long*/ pyTop, int /*long*/ pcxWidth, int /*long*/ pcyHeight, int /*long*/ variant) {
+    HRESULT accLocation(LONG* pxLeft, LONG* pyTop, LONG* pcxWidth, LONG* pcyHeight, VARIANT variant) {
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
-        VARIANT v = new VARIANT();
-        COM.MoveMemory(v, variant, VARIANT.sizeof);
+        VARIANT* v = &variant;
+        //COM.MoveMemory(v, variant, VARIANT.sizeof);
         if ((v.vt & 0xFFFF) !is COM.VT_I4) return COM.E_INVALIDARG;
 
         /* Get the default location from the OS. */
         int osLeft = 0, osTop = 0, osWidth = 0, osHeight = 0;
         int code = iaccessible.accLocation(pxLeft, pyTop, pcxWidth, pcyHeight, variant);
         if (code is COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
-        if (accessibleControlListeners.size() is 0) return code;
+        if (accessibleControlListeners.length is 0) return code;
         if (code is COM.S_OK) {
-            int[] pLeft = new int[1], pTop = new int[1], pWidth = new int[1], pHeight = new int[1];
-            COM.MoveMemory(pLeft, pxLeft, 4);
-            COM.MoveMemory(pTop, pyTop, 4);
-            COM.MoveMemory(pWidth, pcxWidth, 4);
-            COM.MoveMemory(pHeight, pcyHeight, 4);
+            int[1] pLeft, pTop, pWidth, pHeight;
+            COM.MoveMemory(pLeft.ptr, pxLeft, 4);
+            COM.MoveMemory(pTop.ptr, pyTop, 4);
+            COM.MoveMemory(pWidth.ptr, pcxWidth, 4);
+            COM.MoveMemory(pHeight.ptr, pcyHeight, 4);
             osLeft = pLeft[0]; osTop = pTop[0]; osWidth = pWidth[0]; osHeight = pHeight[0];
         }
 
         AccessibleControlEvent event = new AccessibleControlEvent(this);
-        event.childID = osToChildID((int)/*64*/v.lVal);
+        event.childID = osToChildID(cast(int)/*64*/v.lVal);
         event.x = osLeft;
         event.y = osTop;
         event.width = osWidth;
         event.height = osHeight;
-        for (int i = 0; i < accessibleControlListeners.size(); i++) {
-            AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
+        for (int i = 0; i < accessibleControlListeners.length; i++) {
+            AccessibleControlListener listener = cast(AccessibleControlListener) accessibleControlListeners[i];
             listener.getLocation(event);
         }
-        OS.MoveMemory(pxLeft, new int[] { event.x }, 4);
-        OS.MoveMemory(pyTop, new int[] { event.y }, 4);
-        OS.MoveMemory(pcxWidth, new int[] { event.width }, 4);
-        OS.MoveMemory(pcyHeight, new int[] { event.height }, 4);
+        OS.MoveMemory(pxLeft, &event.x, 4);
+        OS.MoveMemory(pyTop, &event.y, 4);
+        OS.MoveMemory(pcxWidth, &event.width, 4);
+        OS.MoveMemory(pcyHeight, &event.height, 4);
         return COM.S_OK;
     }
 
-    int accNavigate(int navDir, int /*long*/ variant, int /*long*/ pvarEndUpAt) {
+    HRESULT accNavigate(LONG navDir, VARIANT variant, VARIANT* pvarEndUpAt) {
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
         // Currently, we don't let the application override this. Forward to the proxy.
         int code = iaccessible.accNavigate(navDir, variant, pvarEndUpAt);
@@ -675,7 +561,7 @@
         return code;
     }
 
-    int accSelect(int flagsSelect, int /*long*/ variant) {
+    HRESULT accSelect(LONG flagsSelect, VARIANT variant) {
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
         // Currently, we don't let the application override this. Forward to the proxy.
         int code = iaccessible.accSelect(flagsSelect, variant);
@@ -687,118 +573,107 @@
      * Ownership of ppdispChild transfers from callee to caller so reference count on ppdispChild
      * must be incremented before returning.  The caller is responsible for releasing ppdispChild.
      */
-    int get_accChild(int /*long*/ variant, int /*long*/ ppdispChild) {
+    HRESULT get_accChild(VARIANT variant, LPDISPATCH* ppdispChild) {
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
-        VARIANT v = new VARIANT();
-        COM.MoveMemory(v, variant, VARIANT.sizeof);
+        VARIANT* v = &variant;
+        //COM.MoveMemory(v, variant, VARIANT.sizeof);
         if ((v.vt & 0xFFFF) !is COM.VT_I4) return COM.E_INVALIDARG;
-        if (accessibleControlListeners.size() is 0) {
+        if (accessibleControlListeners.length is 0) {
             int code = iaccessible.get_accChild(variant, ppdispChild);
             if (code is COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
             return code;
         }
 
         AccessibleControlEvent event = new AccessibleControlEvent(this);
-        event.childID = osToChildID((int)/*64*/v.lVal);
-        for (int i = 0; i < accessibleControlListeners.size(); i++) {
-            AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
+        event.childID = osToChildID(cast(int)/*64*/v.lVal);
+        for (int i = 0; i < accessibleControlListeners.length; i++) {
+            AccessibleControlListener listener = cast(AccessibleControlListener) accessibleControlListeners[i];
             listener.getChild(event);
         }
         Accessible accessible = event.accessible;
         if (accessible !is null) {
             accessible.AddRef();
-            COM.MoveMemory(ppdispChild, new int /*long*/[] { accessible.objIAccessible.getAddress() }, OS.PTR_SIZEOF);
+            *ppdispChild = accessible.objIAccessible;
             return COM.S_OK;
         }
         return COM.S_FALSE;
     }
 
-    int get_accChildCount(int /*long*/ pcountChildren) {
+    HRESULT get_accChildCount(LONG* pcountChildren) {
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
 
         /* Get the default child count from the OS. */
         int osChildCount = 0;
         int code = iaccessible.get_accChildCount(pcountChildren);
-        if (accessibleControlListeners.size() is 0) return code;
+        if (accessibleControlListeners.length is 0) return code;
         if (code is COM.S_OK) {
-            int[] pChildCount = new int[1];
-            COM.MoveMemory(pChildCount, pcountChildren, 4);
+            int[1] pChildCount;
+            COM.MoveMemory(pChildCount.ptr, pcountChildren, 4);
             osChildCount = pChildCount[0];
         }
 
         AccessibleControlEvent event = new AccessibleControlEvent(this);
         event.childID = ACC.CHILDID_SELF;
         event.detail = osChildCount;
-        for (int i = 0; i < accessibleControlListeners.size(); i++) {
-            AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
+        for (int i = 0; i < accessibleControlListeners.length; i++) {
+            AccessibleControlListener listener = cast(AccessibleControlListener) accessibleControlListeners[i];
             listener.getChildCount(event);
         }
 
-        COM.MoveMemory(pcountChildren, new int[] { event.detail }, 4);
+        *pcountChildren = event.detail;
         return COM.S_OK;
     }
 
-    int get_accDefaultAction(int /*long*/ variant, int /*long*/ pszDefaultAction) {
+    HRESULT get_accDefaultAction(VARIANT variant, BSTR* pszDefaultAction) {
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
-        VARIANT v = new VARIANT();
-        COM.MoveMemory(v, variant, VARIANT.sizeof);
+        VARIANT* v = &variant;
+        //COM.MoveMemory(v, variant, VARIANT.sizeof);
         if ((v.vt & 0xFFFF) !is COM.VT_I4) return COM.E_INVALIDARG;
 
         /* Get the default defaultAction from the OS. */
-        String osDefaultAction = null;
+        char[] osDefaultAction = null;
         int code = iaccessible.get_accDefaultAction(variant, pszDefaultAction);
         if (code is COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
-        if (accessibleControlListeners.size() is 0) return code;
+        if (accessibleControlListeners.length is 0) return code;
         if (code is COM.S_OK) {
-            int /*long*/[] pDefaultAction = new int /*long*/[1];
-            COM.MoveMemory(pDefaultAction, pszDefaultAction, OS.PTR_SIZEOF);
-            int size = COM.SysStringByteLen(pDefaultAction[0]);
-            if (size > 0) {
-                char[] buffer = new char[(size + 1) /2];
-                COM.MoveMemory(buffer, pDefaultAction[0], size);
-                osDefaultAction = new String(buffer);
-            }
+            osDefaultAction = BSTRToStr( *pszDefaultAction, true );
         }
 
         AccessibleControlEvent event = new AccessibleControlEvent(this);
-        event.childID = osToChildID((int)/*64*/v.lVal);
+        event.childID = osToChildID(cast(int)/*64*/v.lVal);
         event.result = osDefaultAction;
-        for (int i = 0; i < accessibleControlListeners.size(); i++) {
-            AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
+        for (int i = 0; i < accessibleControlListeners.length; i++) {
+            AccessibleControlListener listener = cast(AccessibleControlListener) accessibleControlListeners[i];
             listener.getDefaultAction(event);
         }
         if (event.result is null) return code;
-        char[] data = (event.result + "\0").toCharArray();
-        int /*long*/ ptr = COM.SysAllocString(data);
-        COM.MoveMemory(pszDefaultAction, new int /*long*/[] { ptr }, OS.PTR_SIZEOF);
+        auto ptr = COM.SysAllocString(StrToWCHARz(event.result));
+        *pszDefaultAction = ptr;
         return COM.S_OK;
     }
 
-    int get_accDescription(int /*long*/ variant, int /*long*/ pszDescription) {
+    HRESULT get_accDescription(VARIANT variant, BSTR* pszDescription) {
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
-        VARIANT v = new VARIANT();
-        COM.MoveMemory(v, variant, VARIANT.sizeof);
+        VARIANT* v = &variant;
+        //COM.MoveMemory(v, variant, VARIANT.sizeof);
         if ((v.vt & 0xFFFF) !is COM.VT_I4) return COM.E_INVALIDARG;
 
         /* Get the default description from the OS. */
-        String osDescription = null;
+        char[] osDescription = null;
         int code = iaccessible.get_accDescription(variant, pszDescription);
         if (code is COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
         // TEMPORARY CODE - process tree even if there are no apps listening
-        if (accessibleListeners.size() is 0 && !(control instanceof Tree)) return code;
+        if (accessibleListeners.length is 0 && !( null is cast(Tree)control )) return code;
         if (code is COM.S_OK) {
-            int /*long*/[] pDescription = new int /*long*/[1];
-            COM.MoveMemory(pDescription, pszDescription, OS.PTR_SIZEOF);
-            int size = COM.SysStringByteLen(pDescription[0]);
+            int size = COM.SysStringByteLen(*pszDescription);
             if (size > 0) {
-                char[] buffer = new char[(size + 1) /2];
-                COM.MoveMemory(buffer, pDescription[0], size);
-                osDescription = new String(buffer);
+                size = (size + 1) /2;
+                osDescription = WCHARzToStr(*pszDescription, size);
             }
         }
 
         AccessibleEvent event = new AccessibleEvent(this);
-        event.childID = osToChildID((int)/*64*/v.lVal);
+        event.childID = osToChildID(cast(int)/*64*/v.lVal);
         event.result = osDescription;
 
         // TEMPORARY CODE
@@ -806,11 +681,11 @@
          * so we need to create the description using the tree column
          * header text and tree item text. */
         if (v.lVal !is COM.CHILDID_SELF) {
-            if (control instanceof Tree) {
-                Tree tree = (Tree) control;
+            if (auto tree = cast(Tree)control ) {
                 int columnCount = tree.getColumnCount ();
                 if (columnCount > 1) {
-                    int /*long*/ hwnd = control.handle, hItem = 0;
+                    HWND hwnd = control.handle;
+                    int hItem;
                     if (OS.COMCTL32_MAJOR >= 6) {
                         hItem = OS.SendMessage (hwnd, OS.TVM_MAPACCIDTOHTREEITEM, v.lVal, 0);
                     } else {
@@ -818,24 +693,22 @@
                     }
                     Widget widget = tree.getDisplay ().findWidget (hwnd, hItem);
                     event.result = "";
-                    if (widget !is null && widget instanceof TreeItem) {
-                        TreeItem item = (TreeItem) widget;
+                    if (widget !is null ) if( auto item = cast(TreeItem) widget ) {
                         for (int i = 1; i < columnCount; i++) {
-                            event.result += tree.getColumn(i).getText() + ": " + item.getText(i);
-                            if (i + 1 < columnCount) event.result += ", ";
+                            event.result ~= tree.getColumn(i).getText() ~ ": " ~ item.getText(i);
+                            if (i + 1 < columnCount) event.result ~= ", ";
                         }
                     }
                 }
             }
         }
-        for (int i = 0; i < accessibleListeners.size(); i++) {
-            AccessibleListener listener = (AccessibleListener) accessibleListeners.elementAt(i);
+        for (int i = 0; i < accessibleListeners.length; i++) {
+            AccessibleListener listener = cast(AccessibleListener) accessibleListeners[i];
             listener.getDescription(event);
         }
         if (event.result is null) return code;
-        char[] data = (event.result + "\0").toCharArray();
-        int /*long*/ ptr = COM.SysAllocString(data);
-        COM.MoveMemory(pszDescription, new int /*long*/[] { ptr }, OS.PTR_SIZEOF);
+        auto ptr = COM.SysAllocString(StrToWCHARz(event.result));
+        *pszDescription = ptr;
         return COM.S_OK;
     }
 
@@ -843,89 +716,82 @@
      * Ownership of pvarChild transfers from callee to caller so reference count on pvarChild
      * must be incremented before returning.  The caller is responsible for releasing pvarChild.
      */
-    int get_accFocus(int /*long*/ pvarChild) {
+    HRESULT get_accFocus(VARIANT* pvarChild) {
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
 
         /* Get the default focus child from the OS. */
         int osChild = ACC.CHILDID_NONE;
         int code = iaccessible.get_accFocus(pvarChild);
-        if (accessibleControlListeners.size() is 0) return code;
+        if (accessibleControlListeners.length is 0) return code;
         if (code is COM.S_OK) {
-            short[] pvt = new short[1];
-            COM.MoveMemory(pvt, pvarChild, 2);
+            short[1] pvt;
+            COM.MoveMemory(pvt.ptr, pvarChild, 2);
             if (pvt[0] is COM.VT_I4) {
-                int[] pChild = new int[1];
-                COM.MoveMemory(pChild, pvarChild + 8, 4);
+                int[1] pChild;
+                COM.MoveMemory(pChild.ptr, pvarChild + 8, 4);
                 osChild = osToChildID(pChild[0]);
             }
         }
 
         AccessibleControlEvent event = new AccessibleControlEvent(this);
         event.childID = osChild;
-        for (int i = 0; i < accessibleControlListeners.size(); i++) {
-            AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
+        for (int i = 0; i < accessibleControlListeners.length; i++) {
+            AccessibleControlListener listener = cast(AccessibleControlListener) accessibleControlListeners[i];
             listener.getFocus(event);
         }
         Accessible accessible = event.accessible;
         if (accessible !is null) {
             accessible.AddRef();
-            COM.MoveMemory(pvarChild, new short[] { COM.VT_DISPATCH }, 2);
-            COM.MoveMemory(pvarChild + 8, new int /*long*/[] { accessible.objIAccessible.getAddress() }, OS.PTR_SIZEOF);
+            pvarChild.vt = COM.VT_DISPATCH;
+            pvarChild.byRef = cast(void*)cast(IDispatch)accessible.objIAccessible;
             return COM.S_OK;
         }
         int childID = event.childID;
         if (childID is ACC.CHILDID_NONE) {
-            COM.MoveMemory(pvarChild, new short[] { COM.VT_EMPTY }, 2);
+            pvarChild.vt = COM.VT_EMPTY;
             return COM.S_FALSE;
         }
         if (childID is ACC.CHILDID_SELF) {
             AddRef();
-            COM.MoveMemory(pvarChild, new short[] { COM.VT_DISPATCH }, 2);
-            COM.MoveMemory(pvarChild + 8, new int /*long*/[] { objIAccessible.getAddress() }, OS.PTR_SIZEOF);
+            pvarChild.vt = COM.VT_DISPATCH;
+            pvarChild.byRef = cast(void*)cast(IDispatch)objIAccessible;
             return COM.S_OK;
         }
-        COM.MoveMemory(pvarChild, new short[] { COM.VT_I4 }, 2);
-        COM.MoveMemory(pvarChild + 8, new int[] { childIDToOs(childID) }, 4);
+        pvarChild.vt = COM.VT_I4;
+        pvarChild.lVal = childIDToOs(childID);
         return COM.S_OK;
     }
 
-    int get_accHelp(int /*long*/ variant, int /*long*/ pszHelp) {
+    HRESULT get_accHelp(VARIANT variant, BSTR* pszHelp) {
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
-        VARIANT v = new VARIANT();
-        COM.MoveMemory(v, variant, VARIANT.sizeof);
+        VARIANT* v = &variant;
+        //COM.MoveMemory(v, variant, VARIANT.sizeof);
         if ((v.vt & 0xFFFF) !is COM.VT_I4) return COM.E_INVALIDARG;
 
         /* Get the default help string from the OS. */
-        String osHelp = null;
+        char[] osHelp = null;
         int code = iaccessible.get_accHelp(variant, pszHelp);
         if (code is COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
-        if (accessibleListeners.size() is 0) return code;
+        if (accessibleListeners.length is 0) return code;
         if (code is COM.S_OK) {
-            int /*long*/[] pHelp = new int /*long*/[1];
-            COM.MoveMemory(pHelp, pszHelp, OS.PTR_SIZEOF);
-            int size = COM.SysStringByteLen(pHelp[0]);
-            if (size > 0) {
-                char[] buffer = new char[(size + 1) /2];
-                COM.MoveMemory(buffer, pHelp[0], size);
-                osHelp = new String(buffer);
-            }
+            // the original SysString is clearuped and bstr set to null
+            osHelp = BSTRToStr(*pszHelp, true);
         }
 
         AccessibleEvent event = new AccessibleEvent(this);
-        event.childID = osToChildID((int)/*64*/v.lVal);
+        event.childID = osToChildID(cast(int)/*64*/v.lVal);
         event.result = osHelp;
-        for (int i = 0; i < accessibleListeners.size(); i++) {
-            AccessibleListener listener = (AccessibleListener) accessibleListeners.elementAt(i);
+        for (int i = 0; i < accessibleListeners.length; i++) {
+            AccessibleListener listener = cast(AccessibleListener) accessibleListeners[i];
             listener.getHelp(event);
         }
         if (event.result is null) return code;
-        char[] data = (event.result + "\0").toCharArray();
-        int /*long*/ ptr = COM.SysAllocString(data);
-        COM.MoveMemory(pszHelp, new int /*long*/[] { ptr }, OS.PTR_SIZEOF);
+        auto ptr = COM.SysAllocString(StrToWCHARz(event.result));
+        *pszHelp = ptr;
         return COM.S_OK;
     }
 
-    int get_accHelpTopic(int /*long*/ pszHelpFile, int /*long*/ variant, int /*long*/ pidTopic) {
+    HRESULT get_accHelpTopic(BSTR* pszHelpFile, VARIANT variant, LONG* pidTopic) {
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
         // Currently, we don't let the application override this. Forward to the proxy.
         int code = iaccessible.get_accHelpTopic(pszHelpFile, variant, pidTopic);
@@ -933,75 +799,61 @@
         return code;
     }
 
-    int get_accKeyboardShortcut(int /*long*/ variant, int /*long*/ pszKeyboardShortcut) {
+    HRESULT get_accKeyboardShortcut(VARIANT variant, BSTR* pszKeyboardShortcut) {
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
-        VARIANT v = new VARIANT();
-        COM.MoveMemory(v, variant, VARIANT.sizeof);
+        VARIANT* v = &variant;
+        //COM.MoveMemory(v, variant, VARIANT.sizeof);
         if ((v.vt & 0xFFFF) !is COM.VT_I4) return COM.E_INVALIDARG;
 
         /* Get the default keyboard shortcut from the OS. */
-        String osKeyboardShortcut = null;
+        char[] osKeyboardShortcut = null;
         int code = iaccessible.get_accKeyboardShortcut(variant, pszKeyboardShortcut);
         if (code is COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
-        if (accessibleListeners.size() is 0) return code;
+        if (accessibleListeners.length is 0) return code;
         if (code is COM.S_OK) {
-            int /*long*/[] pKeyboardShortcut = new int /*long*/[1];
-            COM.MoveMemory(pKeyboardShortcut, pszKeyboardShortcut, OS.PTR_SIZEOF);
-            int size = COM.SysStringByteLen(pKeyboardShortcut[0]);
-            if (size > 0) {
-                char[] buffer = new char[(size + 1) /2];
-                COM.MoveMemory(buffer, pKeyboardShortcut[0], size);
-                osKeyboardShortcut = new String(buffer);
-            }
+            // the original SysString is clearuped and bstr set to null
+            osKeyboardShortcut = BSTRToStr(*pszKeyboardShortcut, true);
         }
 
         AccessibleEvent event = new AccessibleEvent(this);
-        event.childID = osToChildID((int)/*64*/v.lVal);
+        event.childID = osToChildID(cast(int)/*64*/v.lVal);
         event.result = osKeyboardShortcut;
-        for (int i = 0; i < accessibleListeners.size(); i++) {
-            AccessibleListener listener = (AccessibleListener) accessibleListeners.elementAt(i);
+        for (int i = 0; i < accessibleListeners.length; i++) {
+            AccessibleListener listener = cast(AccessibleListener) accessibleListeners[i];
             listener.getKeyboardShortcut(event);
         }
         if (event.result is null) return code;
-        char[] data = (event.result + "\0").toCharArray();
-        int /*long*/ ptr = COM.SysAllocString(data);
-        COM.MoveMemory(pszKeyboardShortcut, new int /*long*/[] { ptr }, OS.PTR_SIZEOF);
+        auto ptr = COM.SysAllocString(StrToWCHARz(event.result));
+        *pszKeyboardShortcut = ptr;
         return COM.S_OK;
     }
 
-    int get_accName(int /*long*/ variant, int /*long*/ pszName) {
+    HRESULT get_accName(VARIANT variant, BSTR* pszName) {
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
-        VARIANT v = new VARIANT();
-        COM.MoveMemory(v, variant, VARIANT.sizeof);
+        VARIANT* v = &variant;
+        //COM.MoveMemory(v, variant, VARIANT.sizeof);
         if ((v.vt & 0xFFFF) !is COM.VT_I4) return COM.E_INVALIDARG;
 
         /* Get the default name from the OS. */
-        String osName = null;
+        char[] osName = null;
         int code = iaccessible.get_accName(variant, pszName);
         if (code is COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
-        if (accessibleListeners.size() is 0) return code;
+        if (accessibleListeners.length is 0) return code;
         if (code is COM.S_OK) {
-            int /*long*/[] pName = new int /*long*/[1];
-            COM.MoveMemory(pName, pszName, OS.PTR_SIZEOF);
-            int size = COM.SysStringByteLen(pName[0]);
-            if (size > 0) {
-                char[] buffer = new char[(size + 1) /2];
-                COM.MoveMemory(buffer, pName[0], size);
-                osName = new String(buffer);
-            }
+            // the original SysString is clearuped and bstr set to null
+            osName = BSTRToStr(*pszName, true);
         }
 
         AccessibleEvent event = new AccessibleEvent(this);
-        event.childID = osToChildID((int)/*64*/v.lVal);
+        event.childID = osToChildID(cast(int)/*64*/v.lVal);
         event.result = osName;
-        for (int i = 0; i < accessibleListeners.size(); i++) {
-            AccessibleListener listener = (AccessibleListener) accessibleListeners.elementAt(i);
+        for (int i = 0; i < accessibleListeners.length; i++) {
+            AccessibleListener listener = cast(AccessibleListener) accessibleListeners[i];
             listener.getName(event);
         }
         if (event.result is null) return code;
-        char[] data = (event.result + "\0").toCharArray();
-        int /*long*/ ptr = COM.SysAllocString(data);
-        COM.MoveMemory(pszName, new int /*long*/[] { ptr }, OS.PTR_SIZEOF);
+        auto ptr = COM.SysAllocString(StrToWCHARz(event.result));
+        *pszName = ptr;
         return COM.S_OK;
     }
 
@@ -1009,16 +861,16 @@
      * Ownership of ppdispParent transfers from callee to caller so reference count on ppdispParent
      * must be incremented before returning.  The caller is responsible for releasing ppdispParent.
      */
-    int get_accParent(int /*long*/ ppdispParent) {
+    HRESULT get_accParent(LPDISPATCH* ppdispParent) {
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
         // Currently, we don't let the application override this. Forward to the proxy.
         return iaccessible.get_accParent(ppdispParent);
     }
 
-    int get_accRole(int /*long*/ variant, int /*long*/ pvarRole) {
+    HRESULT get_accRole(VARIANT variant, VARIANT* pvarRole) {
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
-        VARIANT v = new VARIANT();
-        COM.MoveMemory(v, variant, VARIANT.sizeof);
+        VARIANT* v = &variant;
+        //COM.MoveMemory(v, variant, VARIANT.sizeof);
         if ((v.vt & 0xFFFF) !is COM.VT_I4) return COM.E_INVALIDARG;
 
         /* Get the default role from the OS. */
@@ -1026,35 +878,35 @@
         int code = iaccessible.get_accRole(variant, pvarRole);
         if (code is COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
         // TEMPORARY CODE - process tree and table even if there are no apps listening
-        if (accessibleControlListeners.size() is 0 && !(control instanceof Tree || control instanceof Table)) return code;
+        if (accessibleControlListeners.length is 0 && !( null !is cast(Tree)control || null !is cast(Table)control )) return code;
         if (code is COM.S_OK) {
-            short[] pvt = new short[1];
-            COM.MoveMemory(pvt, pvarRole, 2);
+            short[1] pvt;
+            COM.MoveMemory(pvt.ptr, pvarRole, 2);
             if (pvt[0] is COM.VT_I4) {
-                int[] pRole = new int[1];
-                COM.MoveMemory(pRole, pvarRole + 8, 4);
+                int[1] pRole;
+                COM.MoveMemory(pRole.ptr, pvarRole + 8, 4);
                 osRole = pRole[0];
             }
         }
 
         AccessibleControlEvent event = new AccessibleControlEvent(this);
-        event.childID = osToChildID((int)/*64*/v.lVal);
+        event.childID = osToChildID(cast(int)/*64*/v.lVal);
         event.detail = osToRole(osRole);
         // TEMPORARY CODE
         /* Currently our checkbox table and tree are emulated using state mask
          * images, so we need to specify 'checkbox' role for the items. */
         if (v.lVal !is COM.CHILDID_SELF) {
-            if (control instanceof Tree || control instanceof Table) {
+            if ( null !is cast(Tree)control || null !is cast(Table)control ) {
                 if ((control.getStyle() & DWT.CHECK) !is 0) event.detail = ACC.ROLE_CHECKBUTTON;
             }
         }
-        for (int i = 0; i < accessibleControlListeners.size(); i++) {
-            AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
+        for (int i = 0; i < accessibleControlListeners.length; i++) {
+            AccessibleControlListener listener = cast(AccessibleControlListener) accessibleControlListeners[i];
             listener.getRole(event);
         }
         int role = roleToOs(event.detail);
-        COM.MoveMemory(pvarRole, new short[] { COM.VT_I4 }, 2);
-        COM.MoveMemory(pvarRole + 8, new int[] { role }, 4);
+        pvarRole.vt = COM.VT_I4;
+        pvarRole.lVal = role;
         return COM.S_OK;
     }
 
@@ -1062,19 +914,19 @@
      * Ownership of pvarChildren transfers from callee to caller so reference count on pvarChildren
      * must be incremented before returning.  The caller is responsible for releasing pvarChildren.
      */
-    int get_accSelection(int /*long*/ pvarChildren) {
+    HRESULT get_accSelection(VARIANT* pvarChildren) {
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
 
         /* Get the default selection from the OS. */
         int osChild = ACC.CHILDID_NONE;
         int code = iaccessible.get_accSelection(pvarChildren);
-        if (accessibleControlListeners.size() is 0) return code;
+        if (accessibleControlListeners.length is 0) return code;
         if (code is COM.S_OK) {
-            short[] pvt = new short[1];
-            COM.MoveMemory(pvt, pvarChildren, 2);
+            short[1] pvt;
+            COM.MoveMemory(pvt.ptr, pvarChildren, 2);
             if (pvt[0] is COM.VT_I4) {
-                int[] pChild = new int[1];
-                COM.MoveMemory(pChild, pvarChildren + 8, 4);
+                int[1] pChild;
+                COM.MoveMemory(pChild.ptr, pvarChildren + 8, 4);
                 osChild = osToChildID(pChild[0]);
             } else if (pvt[0] is COM.VT_UNKNOWN) {
                 osChild = ACC.CHILDID_MULTIPLE;
@@ -1084,43 +936,43 @@
 
         AccessibleControlEvent event = new AccessibleControlEvent(this);
         event.childID = osChild;
-        for (int i = 0; i < accessibleControlListeners.size(); i++) {
-            AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
+        for (int i = 0; i < accessibleControlListeners.length; i++) {
+            AccessibleControlListener listener = cast(AccessibleControlListener) accessibleControlListeners[i];
             listener.getSelection(event);
         }
         Accessible accessible = event.accessible;
         if (accessible !is null) {
             accessible.AddRef();
-            COM.MoveMemory(pvarChildren, new short[] { COM.VT_DISPATCH }, 2);
-            COM.MoveMemory(pvarChildren + 8, new int /*long*/[] { accessible.objIAccessible.getAddress() }, OS.PTR_SIZEOF);
+            pvarChildren.vt = COM.VT_DISPATCH;
+            pvarChildren.byRef = cast(void*)cast(IDispatch)accessible.objIAccessible;
             return COM.S_OK;
         }
         int childID = event.childID;
         if (childID is ACC.CHILDID_NONE) {
-            COM.MoveMemory(pvarChildren, new short[] { COM.VT_EMPTY }, 2);
+            pvarChildren.vt = COM.VT_EMPTY;
             return COM.S_FALSE;
         }
         if (childID is ACC.CHILDID_MULTIPLE) {
             AddRef();
-            COM.MoveMemory(pvarChildren, new short[] { COM.VT_UNKNOWN }, 2);
-            COM.MoveMemory(pvarChildren + 8, new int /*long*/[] { objIAccessible.getAddress() }, OS.PTR_SIZEOF);
+            pvarChildren.vt = COM.VT_UNKNOWN;
+            pvarChildren.byRef = cast(void*)cast(IUnknown)objIAccessible;
             return COM.S_OK;
         }
         if (childID is ACC.CHILDID_SELF) {
             AddRef();
-            COM.MoveMemory(pvarChildren, new short[] { COM.VT_DISPATCH }, 2);
-            COM.MoveMemory(pvarChildren + 8, new int /*long*/[] { objIAccessible.getAddress() }, OS.PTR_SIZEOF);
+            pvarChildren.vt = COM.VT_DISPATCH;
+            pvarChildren.byRef = cast(void*)cast(IDispatch)objIAccessible;
             return COM.S_OK;
         }
-        COM.MoveMemory(pvarChildren, new short[] { COM.VT_I4 }, 2);
-        COM.MoveMemory(pvarChildren + 8, new int[] { childIDToOs(childID) }, 4);
+        pvarChildren.vt = COM.VT_I4;
+        pvarChildren.lVal = childIDToOs(childID);
         return COM.S_OK;
     }
 
-    int get_accState(int /*long*/ variant, int /*long*/ pvarState) {
+    HRESULT get_accState(VARIANT variant, VARIANT* pvarState) {
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
-        VARIANT v = new VARIANT();
-        COM.MoveMemory(v, variant, VARIANT.sizeof);
+        VARIANT* v = &variant;
+        //COM.MoveMemory(v, variant, VARIANT.sizeof);
         if ((v.vt & 0xFFFF) !is COM.VT_I4) return COM.E_INVALIDARG;
 
         /* Get the default state from the OS. */
@@ -1128,92 +980,87 @@
         int code = iaccessible.get_accState(variant, pvarState);
         if (code is COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
         // TEMPORARY CODE - process tree and table even if there are no apps listening
-        if (accessibleControlListeners.size() is 0 && !(control instanceof Tree || control instanceof Table)) return code;
+        if (accessibleControlListeners.length is 0 && !( null !is cast(Tree)control || null !is cast(Table)control )) return code;
         if (code is COM.S_OK) {
-            short[] pvt = new short[1];
-            COM.MoveMemory(pvt, pvarState, 2);
+            short[1] pvt;
+            COM.MoveMemory(pvt.ptr, pvarState, 2);
             if (pvt[0] is COM.VT_I4) {
-                int[] pState = new int[1];
-                COM.MoveMemory(pState, pvarState + 8, 4);
+                int[1] pState;
+                COM.MoveMemory(pState.ptr, pvarState + 8, 4);
                 osState = pState[0];
             }
         }
 
         AccessibleControlEvent event = new AccessibleControlEvent(this);
-        event.childID = osToChildID((int)/*64*/v.lVal);
+        event.childID = osToChildID(cast(int)/*64*/v.lVal);
         event.detail = osToState(osState);
         // TEMPORARY CODE
         /* Currently our checkbox table and tree are emulated using state mask
          * images, so we need to determine if the item state is 'checked'. */
         if (v.lVal !is COM.CHILDID_SELF) {
-            if (control instanceof Tree && (control.getStyle() & DWT.CHECK) !is 0) {
-                int /*long*/ hwnd = control.handle;
-                TVITEM tvItem = new TVITEM ();
+            if (null !is cast(Tree)control && (control.getStyle() & DWT.CHECK) !is 0) {
+                auto hwnd = control.handle;
+                TVITEM tvItem;
                 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE;
                 tvItem.stateMask = OS.TVIS_STATEIMAGEMASK;
                 if (OS.COMCTL32_MAJOR >= 6) {
-                    tvItem.hItem = OS.SendMessage (hwnd, OS.TVM_MAPACCIDTOHTREEITEM, v.lVal, 0);
+                    tvItem.hItem = cast(HANDLE) OS.SendMessage (hwnd, OS.TVM_MAPACCIDTOHTREEITEM, v.lVal, 0);
                 } else {
-                    tvItem.hItem = v.lVal;
+                    tvItem.hItem = cast(HANDLE) v.lVal;
                 }
-                int /*long*/ result = OS.SendMessage (hwnd, OS.TVM_GETITEM, 0, tvItem);
+                auto result = OS.SendMessage (hwnd, OS.TVM_GETITEM, 0, &tvItem);
                 bool checked = (result !is 0) && (((tvItem.state >> 12) & 1) is 0);
                 if (checked) event.detail |= ACC.STATE_CHECKED;
-            } else if (control instanceof Table && (control.getStyle() & DWT.CHECK) !is 0) {
-                Table table = (Table) control;
+            } else if (null !is cast(Table)control && (control.getStyle() & DWT.CHECK) !is 0) {
+                Table table = cast(Table) control;
                 TableItem item = table.getItem(event.childID);
                 if (item !is null) {
                     if (item.getChecked()) event.detail |= ACC.STATE_CHECKED;
                 }
             }
         }
-        for (int i = 0; i < accessibleControlListeners.size(); i++) {
-            AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
+        for (int i = 0; i < accessibleControlListeners.length; i++) {
+            AccessibleControlListener listener = cast(AccessibleControlListener) accessibleControlListeners[i];
             listener.getState(event);
         }
         int state = stateToOs(event.detail);
-        COM.MoveMemory(pvarState, new short[] { COM.VT_I4 }, 2);
-        COM.MoveMemory(pvarState + 8, new int[] { state }, 4);
+        pvarState.vt = COM.VT_I4;
+        pvarState.lVal = state;
         return COM.S_OK;
     }
 
-    int get_accValue(int /*long*/ variant, int /*long*/ pszValue) {
+    HRESULT get_accValue(VARIANT variant, BSTR* pszValue) {
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
-        VARIANT v = new VARIANT();
-        COM.MoveMemory(v, variant, VARIANT.sizeof);
+        VARIANT* v = &variant;
+        //COM.MoveMemory(v, variant, VARIANT.sizeof);
         if ((v.vt & 0xFFFF) !is COM.VT_I4) return COM.E_INVALIDARG;
 
         /* Get the default value string from the OS. */
-        String osValue = null;
+        char[] osValue = null;
         int code = iaccessible.get_accValue(variant, pszValue);
         if (code is COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
-        if (accessibleControlListeners.size() is 0) return code;
+        if (accessibleControlListeners.length is 0) return code;
         if (code is COM.S_OK) {
-            int /*long*/[] pValue = new int /*long*/[1];
-            COM.MoveMemory(pValue, pszValue, OS.PTR_SIZEOF);
-            int size = COM.SysStringByteLen(pValue[0]);
+            int size = COM.SysStringByteLen(*pszValue);
             if (size > 0) {
-                char[] buffer = new char[(size + 1) /2];
-                COM.MoveMemory(buffer, pValue[0], size);
-                osValue = new String(buffer);
+                osValue = WCHARsToStr((*pszValue)[ 0 .. size ]);
             }
         }
 
         AccessibleControlEvent event = new AccessibleControlEvent(this);
-        event.childID = osToChildID((int)/*64*/v.lVal);
+        event.childID = osToChildID(cast(int)/*64*/v.lVal);
         event.result = osValue;
-        for (int i = 0; i < accessibleControlListeners.size(); i++) {
-            AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
+        for (int i = 0; i < accessibleControlListeners.length; i++) {
+            AccessibleControlListener listener = cast(AccessibleControlListener) accessibleControlListeners[i];
             listener.getValue(event);
         }
         if (event.result is null) return code;
-        char[] data = (event.result + "\0").toCharArray();
-        int /*long*/ ptr = COM.SysAllocString(data);
-        COM.MoveMemory(pszValue, new int /*long*/[] { ptr }, OS.PTR_SIZEOF);
+        auto ptr = COM.SysAllocString(StrToWCHARz(event.result));
+        *pszValue = ptr;
         return COM.S_OK;
     }
 
-    int put_accName(int /*long*/ variant, int /*long*/ szName) {
+    HRESULT put_accName(VARIANT variant, BSTR* szName) {
         // MSAA: this method is no longer supported
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
         // We don't implement this. Forward to the proxy.
@@ -1222,7 +1069,7 @@
         return code;
     }
 
-    int put_accValue(int /*long*/ variant, int /*long*/ szValue) {
+    HRESULT put_accValue(VARIANT variant, BSTR* szValue) {
         // MSAA: this method is typically only used for edit controls
         if (iaccessible is null) return COM.CO_E_OBJNOTCONNECTED;
         // We don't implement this. Forward to the proxy.
@@ -1243,29 +1090,28 @@
      * Ownership of rgvar transfers from callee to caller so reference count on rgvar
      * must be incremented before returning.  The caller is responsible for releasing rgvar.
      */
-    int Next(int celt, int /*long*/ rgvar, int /*long*/ pceltFetched) {
+    HRESULT Next(ULONG celt, VARIANT *rgvar, ULONG *pceltFetched) {
         /* If there are no listeners, query the proxy for
          * its IEnumVariant, and get the Next items from it.
          */
-        if (accessibleControlListeners.size() is 0) {
-            int /*long*/[] ppvObject = new int /*long*/[1];
-            int code = iaccessible.QueryInterface(COM.IIDIEnumVARIANT, ppvObject);
+        if (accessibleControlListeners.length is 0) {
+            IEnumVARIANT ienumvariant;
+            int code = iaccessible.QueryInterface(&COM.IIDIEnumVARIANT, cast(void**)&ienumvariant);
             if (code !is COM.S_OK) return code;
-            IEnumVARIANT ienumvariant = new IEnumVARIANT(ppvObject[0]);
-            int[] celtFetched = new int[1];
-            code = ienumvariant.Next(celt, rgvar, celtFetched);
+            uint[1] celtFetched;
+            code = ienumvariant.Next(celt, rgvar, celtFetched.ptr);
             ienumvariant.Release();
-            COM.MoveMemory(pceltFetched, celtFetched, 4);
+            COM.MoveMemory(pceltFetched, celtFetched.ptr, 4);
             return code;
         }
 
-        if (rgvar is 0) return COM.E_INVALIDARG;
-        if (pceltFetched is 0 && celt !is 1) return COM.E_INVALIDARG;
+        if (rgvar is null) return COM.E_INVALIDARG;
+        if (pceltFetched is null && celt !is 1) return COM.E_INVALIDARG;
         if (enumIndex is 0) {
             AccessibleControlEvent event = new AccessibleControlEvent(this);
             event.childID = ACC.CHILDID_SELF;
-            for (int i = 0; i < accessibleControlListeners.size(); i++) {
-                AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
+            for (int i = 0; i < accessibleControlListeners.length; i++) {
+                AccessibleControlListener listener = cast(AccessibleControlListener) accessibleControlListeners[i];
                 listener.getChildren(event);
             }
             variants = event.children;
@@ -1278,8 +1124,8 @@
                 nextItems = new Object[endIndex - enumIndex + 1];
                 for (int i = 0; i < nextItems.length; i++) {
                     Object child = variants[enumIndex];
-                    if (child instanceof Integer) {
-                        nextItems[i] = new Integer(childIDToOs(((Integer)child).intValue()));
+                    if (auto val = cast(ValueWrapperInt)child ) {
+                        nextItems[i] = new ValueWrapperInt(childIDToOs(val.value));
                     } else {
                         nextItems[i] = child;
                     }
@@ -1290,37 +1136,38 @@
         if (nextItems !is null) {
             for (int i = 0; i < nextItems.length; i++) {
                 Object nextItem = nextItems[i];
-                if (nextItem instanceof Integer) {
-                    int item = ((Integer) nextItem).intValue();
-                    COM.MoveMemory(rgvar + i * 16, new short[] { COM.VT_I4 }, 2);
-                    COM.MoveMemory(rgvar + i * 16 + 8, new int[] { item }, 4);
+                if (auto val = cast(ValueWrapperInt)nextItem ) {
+                    int item = val.value;
+                    rgvar[i].vt = COM.VT_I4;
+                    rgvar[i].byRef = cast(void*)item;
                 } else {
-                    Accessible accessible = (Accessible) nextItem;
+                    Accessible accessible = cast(Accessible) nextItem;
                     accessible.AddRef();
-                    COM.MoveMemory(rgvar + i * 16, new short[] { COM.VT_DISPATCH }, 2);
-                    COM.MoveMemory(rgvar + i * 16 + 8, new int /*long*/[] { accessible.objIAccessible.getAddress() }, OS.PTR_SIZEOF);
+                    rgvar[i].vt = COM.VT_DISPATCH;
+                    rgvar[i].byRef = cast(void*)accessible.objIAccessible;
                 }
             }
-            if (pceltFetched !is 0)
-                COM.MoveMemory(pceltFetched, new int[] {nextItems.length}, 4);
+            if (pceltFetched !is null)
+                *pceltFetched = nextItems.length;
             if (nextItems.length is celt) return COM.S_OK;
         } else {
-            if (pceltFetched !is 0)
-                COM.MoveMemory(pceltFetched, new int[] {0}, 4);
+            if (pceltFetched !is null){
+                int zero = 0;
+                *pceltFetched = 0;
+            }
         }
         return COM.S_FALSE;
     }
 
     /* Skip over the specified number of elements in the enumeration sequence. */
-    int Skip(int celt) {
+    HRESULT Skip(ULONG celt)  {
         /* If there are no listeners, query the proxy
          * for its IEnumVariant, and tell it to Skip.
          */
-        if (accessibleControlListeners.size() is 0) {
-            int /*long*/[] ppvObject = new int /*long*/[1];
-            int code = iaccessible.QueryInterface(COM.IIDIEnumVARIANT, ppvObject);
+        if (accessibleControlListeners.length is 0) {
+            IEnumVARIANT ienumvariant;
+            int code = iaccessible.QueryInterface(&COM.IIDIEnumVARIANT, cast(void**)&ienumvariant);
             if (code !is COM.S_OK) return code;
-            IEnumVARIANT ienumvariant = new IEnumVARIANT(ppvObject[0]);
             code = ienumvariant.Skip(celt);
             ienumvariant.Release();
             return code;
@@ -1336,15 +1183,14 @@
     }
 
     /* Reset the enumeration sequence to the beginning. */
-    int Reset() {
+    HRESULT Reset() {
         /* If there are no listeners, query the proxy
          * for its IEnumVariant, and tell it to Reset.
          */
-        if (accessibleControlListeners.size() is 0) {
-            int /*long*/[] ppvObject = new int /*long*/[1];
-            int code = (int)/*64*/iaccessible.QueryInterface(COM.IIDIEnumVARIANT, ppvObject);
+        if (accessibleControlListeners.length is 0) {
+            IEnumVARIANT ienumvariant;
+            int code = cast(int)/*64*/iaccessible.QueryInterface(&COM.IIDIEnumVARIANT, cast(void**)&ienumvariant);
             if (code !is COM.S_OK) return code;
-            IEnumVARIANT ienumvariant = new IEnumVARIANT(ppvObject[0]);
             code = ienumvariant.Reset();
             ienumvariant.Release();
             return code;
@@ -1358,24 +1204,23 @@
      * Ownership of ppEnum transfers from callee to caller so reference count on ppEnum
      * must be incremented before returning.  The caller is responsible for releasing ppEnum.
      */
-    int Clone(int /*long*/ ppEnum) {
+    int Clone(IEnumVARIANT* ppEnum) {
         /* If there are no listeners, query the proxy for
          * its IEnumVariant, and get the Clone from it.
          */
-        if (accessibleControlListeners.size() is 0) {
-            int /*long*/[] ppvObject = new int /*long*/[1];
-            int code = iaccessible.QueryInterface(COM.IIDIEnumVARIANT, ppvObject);
+        if (accessibleControlListeners.length is 0) {
+            IEnumVARIANT ienumvariant;
+            int code = iaccessible.QueryInterface(&COM.IIDIEnumVARIANT, cast(void**)&ienumvariant);
             if (code !is COM.S_OK) return code;
-            IEnumVARIANT ienumvariant = new IEnumVARIANT(ppvObject[0]);
-            int[] pEnum = new int[1];
-            code = ienumvariant.Clone(pEnum);
+            IEnumVARIANT[1] pEnum;
+            code = ienumvariant.Clone(pEnum.ptr);
             ienumvariant.Release();
-            COM.MoveMemory(ppEnum, pEnum, 4);
+            COM.MoveMemory(ppEnum, pEnum.ptr, 4);
             return code;
         }
 
-        if (ppEnum is 0) return COM.E_INVALIDARG;
-        COM.MoveMemory(ppEnum, new int /*long*/[] { objIEnumVARIANT.getAddress()}, OS.PTR_SIZEOF);
+        if (ppEnum is null) return COM.E_INVALIDARG;
+        *ppEnum = objIEnumVARIANT;
         AddRef();
         return COM.S_OK;
     }
@@ -1389,9 +1234,9 @@
         * For backward compatibility, we still take a handle childID for tree
         * items on XP. All other childIDs are 1-based indices.
         */
-        if (!(control instanceof Tree)) return childID + 1;
+        if (!(cast(Tree)control )) return childID + 1;
         if (OS.COMCTL32_MAJOR < 6) return childID;
-        return (int)/*64*/OS.SendMessage (control.handle, OS.TVM_MAPHTREEITEMTOACCID, childID, 0);
+        return cast(int)/*64*/OS.SendMessage (control.handle, OS.TVM_MAPHTREEITEMTOACCID, childID, 0);
     }
 
     int osToChildID(int osChildID) {
@@ -1403,9 +1248,9 @@
         * For backward compatibility, we still take a handle childID for tree
         * items on XP. All other childIDs are 1-based indices.
         */
-        if (!(control instanceof Tree)) return osChildID - 1;
+        if (!(cast(Tree)control )) return osChildID - 1;
         if (OS.COMCTL32_MAJOR < 6) return osChildID;
-        return (int)/*64*/OS.SendMessage (control.handle, OS.TVM_MAPACCIDTOHTREEITEM, osChildID, 0);
+        return cast(int)/*64*/OS.SendMessage (control.handle, OS.TVM_MAPACCIDTOHTREEITEM, osChildID, 0);
     }
 
     int stateToOs(int state) {
@@ -1481,6 +1326,7 @@
             case ACC.ROLE_PROGRESSBAR: return COM.ROLE_SYSTEM_PROGRESSBAR;
             case ACC.ROLE_SLIDER: return COM.ROLE_SYSTEM_SLIDER;
             case ACC.ROLE_LINK: return COM.ROLE_SYSTEM_LINK;
+            default:
         }
         return COM.ROLE_SYSTEM_CLIENT;
     }
@@ -1516,6 +1362,7 @@
             case COM.ROLE_SYSTEM_PROGRESSBAR: return ACC.ROLE_PROGRESSBAR;
             case COM.ROLE_SYSTEM_SLIDER: return ACC.ROLE_SLIDER;
             case COM.ROLE_SYSTEM_LINK: return ACC.ROLE_LINK;
+            default:
         }
         return ACC.ROLE_CLIENT_AREA;
     }
@@ -1527,8 +1374,99 @@
     }
 
     /* isValidThread was copied from Widget, and rewritten to work in this package */
-    bool isValidThread () {
-        return control.getDisplay ().getThread () is Thread.currentThread ();
+    WINBOOL isValidThread () {
+        return control.getDisplay ().getThread () is Thread.getThis ();
     }
 }
-++/
\ No newline at end of file
+
+class _IAccessibleImpl : IAccessible {
+
+    Accessible  parent;
+    this(Accessible p) { parent = p; }
+extern (Windows):
+    // interface of IUnknown
+    HRESULT QueryInterface(REFIID riid, void ** ppvObject) { return parent.QueryInterface(riid, ppvObject); }
+    ULONG AddRef()  { return parent.AddRef(); }
+    ULONG Release() { return parent.Release(); }
+
+    // interface of IDispatch
+    HRESULT GetTypeInfoCount(UINT * pctinfo) { return COM.E_NOTIMPL; }
+    HRESULT GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo * ppTInfo) { return COM.E_NOTIMPL; }
+    HRESULT GetIDsOfNames(REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId) { return COM.E_NOTIMPL; }
+    HRESULT Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS* pDispParams,VARIANT* pVarResult,EXCEPINFO* pExcepInfo,UINT* puArgErr) { return COM.E_NOTIMPL; }
+
+    // interface of IAccessible
+    HRESULT get_accParent(LPDISPATCH * ppdispParent) { return parent.get_accParent(ppdispParent); }
+    HRESULT get_accChildCount(LONG* pcountChildren) { return parent.get_accChildCount(pcountChildren); }
+    HRESULT get_accChild(VARIANT varChildID, LPDISPATCH* ppdispChild) {
+        return parent.get_accChild(varChildID, ppdispChild);
+    }
+    HRESULT get_accName(VARIANT varID, BSTR* pszName) {
+        return parent.get_accName(varID, pszName);
+    }
+    HRESULT get_accValue(VARIANT varID, BSTR* pszValue) {
+        return parent.get_accValue(varID, pszValue);
+    }
+    HRESULT get_accDescription(VARIANT varID,BSTR* pszDescription) {
+        return parent.get_accDescription(varID, pszDescription);
+    }
+    HRESULT get_accRole(VARIANT varID, VARIANT* pvarRole) {
+        return parent.get_accRole(varID, pvarRole);
+    }
+    HRESULT get_accState(VARIANT varID, VARIANT* pvarState) {
+        return parent.get_accState(varID, pvarState);
+    }
+    HRESULT get_accHelp(VARIANT varID, BSTR* pszHelp) {
+        return parent.get_accHelp(varID, pszHelp);
+    }
+    HRESULT get_accHelpTopic(BSTR* pszHelpFile, VARIANT varChild, LONG* pidTopic) {
+        return parent.get_accHelpTopic(pszHelpFile, varChild, pidTopic);
+    }
+    HRESULT get_accKeyboardShortcut(VARIANT varID, BSTR* pszKeyboardShortcut) {
+        return parent.get_accKeyboardShortcut(varID, pszKeyboardShortcut);
+    }
+    HRESULT get_accFocus(VARIANT* pvarID) { return parent.get_accFocus(pvarID); }
+    HRESULT get_accSelection(VARIANT* pvarChildren) { return parent.get_accSelection(pvarChildren); }
+    HRESULT get_accDefaultAction(VARIANT varID,BSTR* pszDefaultAction) {
+        return parent.get_accDefaultAction(varID, pszDefaultAction);
+    }
+    HRESULT accSelect(LONG flagsSelect, VARIANT varID) {
+        return parent.accSelect(flagsSelect, varID);
+    }
+    HRESULT accLocation(LONG* pxLeft, LONG* pyTop, LONG* pcxWidth, LONG* pcyHeight, VARIANT varID) {
+        return parent.accLocation(pxLeft, pyTop, pcxWidth, pcyHeight, varID);
+    }
+    HRESULT accNavigate(LONG navDir, VARIANT varStart, VARIANT* pvarEnd) {
+        return parent.accNavigate(navDir, varStart, pvarEnd);
+    }
+    HRESULT accHitTest(LONG xLeft,  LONG yTop, VARIANT* pvarID) {
+        return parent.accHitTest(xLeft, yTop, pvarID);
+    }
+    HRESULT accDoDefaultAction(VARIANT varID) {
+        return parent.accDoDefaultAction(varID);
+    }
+    HRESULT put_accName(VARIANT varID, BSTR* szName) {
+        return parent.put_accName(varID, szName);
+    }
+    HRESULT put_accValue(VARIANT varID, BSTR* szValue) {
+        return parent.put_accValue(varID, szValue);
+    }
+}
+
+class _IEnumVARIANTImpl : IEnumVARIANT {
+
+    Accessible  parent;
+    this(Accessible a) { parent = a; }
+extern (Windows):
+    // interface of IUnknown
+    HRESULT QueryInterface(REFIID riid, void ** ppvObject) { return parent.QueryInterface(riid, ppvObject); }
+    ULONG AddRef()  { return parent.AddRef(); }
+    ULONG Release() { return parent.Release(); }
+
+    // interface of IEnumVARIANT
+    HRESULT Next(ULONG celt, VARIANT *rgvar, ULONG *pceltFetched) { return parent.Next(celt, rgvar, pceltFetched); }
+    HRESULT Skip(ULONG celt) { return parent.Skip(celt); }
+    HRESULT Reset() { return parent.Reset(); }
+    HRESULT Clone(LPENUMVARIANT * ppenum) { return COM.E_NOTIMPL;}
+}
+
--- a/dwt/internal/ole/win32/COM.d	Wed Feb 13 01:37:19 2008 +0100
+++ b/dwt/internal/ole/win32/COM.d	Wed Feb 13 03:22:44 2008 +0100
@@ -844,3 +844,28 @@
 /* End ACCESSIBILITY */
 
 }
+
+/**
+ * <Shawn> difference between WCHARzToStr(pwstr, -1) :
+ * BSTRToStr() internally call WCHARzToStr(pwstr, length) with length set,
+ * instead to determine the null ended, this mean BSTRToStr() can get string
+ * which has embedded null characters.
+ */
+// BSTR is aliased to wchar*
+// Note : Free the "bstr" memory if freeTheString is true, default false
+char[] BSTRToStr( /*BSTR*/ inout wchar* bstr, bool freeTheString = false){
+    if(bstr is null) return null;
+    int size = (SysStringByteLen(bstr) + 1)/wchar.sizeof;
+    char[] result = WCHARzToStr(bstr, size);
+    if(freeTheString) {
+        // free the string and set ptr to null
+        SysFreeString(bstr);
+        bstr = null;
+    }
+    return result;
+}
+
+
+
+
+