changeset 84:00a333240696

FileDialog, sync dwthelper with dwt-linux, some TCHAR issues
author Frank Benoit <benoit@tionex.de>
date Wed, 06 Feb 2008 18:46:23 +0100
parents b1f026458bc5
children a155324d7a44
files dwt/DWT.d dwt/dwthelper/ByteArrayInputStream.d dwt/dwthelper/InputStream.d dwt/dwthelper/ResourceBundle.d dwt/dwthelper/System.d dwt/dwthelper/utils.d dwt/graphics/Device.d dwt/graphics/FontData.d dwt/internal/win32/OS.d dwt/widgets/FileDialog.d dwt/widgets/Tracker.d tango_sys_win32/Types.d
diffstat 12 files changed, 300 insertions(+), 138 deletions(-) [+]
line wrap: on
line diff
--- a/dwt/DWT.d	Wed Feb 06 16:04:41 2008 +0100
+++ b/dwt/DWT.d	Wed Feb 06 18:46:23 2008 +0100
@@ -24,6 +24,7 @@
 version(build){
     pragma(link, "advapi32");
     pragma(link, "comctl32");
+    pragma(link, "comdlg32");
     pragma(link, "gdi32");
     pragma(link, "kernel32");
     pragma(link, "shell32");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/dwthelper/ByteArrayInputStream.d	Wed Feb 06 18:46:23 2008 +0100
@@ -0,0 +1,70 @@
+/* language convertion www.dsource.org/project/tioport */
+module dwt.dwthelper.ByteArrayInputStream;
+
+import dwt.dwthelper.InputStream;
+
+public class ByteArrayInputStream : dwt.dwthelper.InputStream.InputStream {
+
+    alias dwt.dwthelper.InputStream.InputStream.read read;
+    alias dwt.dwthelper.InputStream.InputStream.skip skip;
+    alias dwt.dwthelper.InputStream.InputStream.available available;
+    alias dwt.dwthelper.InputStream.InputStream.close close;
+    alias dwt.dwthelper.InputStream.InputStream.mark mark;
+    alias dwt.dwthelper.InputStream.InputStream.reset reset;
+    alias dwt.dwthelper.InputStream.InputStream.markSupported markSupported;
+
+    protected byte[] buf;
+    protected int pos;
+    protected int fld_mark = 0;
+    //protected int count;
+    public this ( byte[] aBuf ){
+        this.buf = aBuf;
+    }
+
+    public this ( byte[] aBuf, int offset, int length_ESCAPE ){
+        this.buf = aBuf[ offset .. offset+length_ESCAPE ];
+    }
+
+    public synchronized int read(){
+        if( pos >= this.buf.length ){
+            return -1;
+        }
+        int result = this.buf[pos];
+        pos++;
+        return result & 0xFF;
+    }
+
+    public synchronized int read( byte[] b, int off, int len ){
+        return super.read( b, off, len );
+    }
+
+    public synchronized long skip( long n ){
+        pos += n;
+        return 0L;
+    }
+
+    public synchronized int available(){
+        if( pos >= this.buf.length ){
+            return 0;
+        }
+        return this.buf.length - pos;
+    }
+
+    public bool markSupported(){
+        return false;
+    }
+
+    public void mark( int readAheadLimit ){
+    }
+
+    public synchronized void reset(){
+        pos = 0;
+    }
+
+    public void close(){
+    }
+
+
+}
+
+
--- a/dwt/dwthelper/InputStream.d	Wed Feb 06 16:04:41 2008 +0100
+++ b/dwt/dwthelper/InputStream.d	Wed Feb 06 18:46:23 2008 +0100
@@ -18,7 +18,7 @@
         foreach( uint idx, inout byte val; b ){
             int c = read();
             if( c == -1 ){
-                return idx;
+                return ( idx == 0 ) ? -1 : idx;
             }
             b[ idx] = cast(byte)( c & 0xFF );
         }
--- a/dwt/dwthelper/ResourceBundle.d	Wed Feb 06 16:04:41 2008 +0100
+++ b/dwt/dwthelper/ResourceBundle.d	Wed Feb 06 18:46:23 2008 +0100
@@ -1,21 +1,119 @@
-/**
+/**
  * Authors: Frank Benoit <keinfarbton@googlemail.com>
  */
 module dwt.dwthelper.ResourceBundle;
 
+import tango.text.Util;
+import tango.io.Stdout;
+
+
 class ResourceBundle {
 
-    public this( char[] name ){
+    char[][ char[] ] map;
+
+    public this( char[] data ){
+        char[] line;
+        int dataIndex;
+
+        //tango.io.Stdout.Stdout.formatln( "properties put ..." );
+        void readLine(){
+            line.length = 0;
+            char i = data[ dataIndex++ ];
+            while( dataIndex < data.length && i !is '\n' && i !is '\r' ){
+                line ~= i;
+                i = data[ dataIndex++ ];
+            }
+        }
+
+        //tango.io.Stdout.Stdout.formatln( "properties put {}", __LINE__ );
+        bool linecontinue = false;
+        bool iskeypart = true;
+        char[] key;
+        char[] value;
+nextline:
+        while( dataIndex < data.length ){
+            //tango.io.Stdout.Stdout.formatln( "properties put {} startline", __LINE__ );
+            readLine();
+            line = tango.text.Util.trim( line );
+            if( line.length is 0 ){
+                //tango.io.Stdout.Stdout.formatln( "properties put {} was 0 length", __LINE__ );
+                continue;
+            }
+            if( line[0] == '#' ){
+                //tango.io.Stdout.Stdout.formatln( "properties put {} was comment", __LINE__ );
+                continue;
+            }
+            int pos = 0;
+            bool esc = false;
+            if( !linecontinue ){
+                iskeypart = true;
+                key = null;
+                value = null;
+            }
+            else{
+                linecontinue = false;
+            }
+            while( pos < line.length ){
+                char c = line[pos];
+                if( esc ){
+                    esc = false;
+                    switch( c ){
+                    case 't': c = '\t'; break;
+                    case 'n': c = '\n'; break;
+                    case '\\': c = '\\'; break;
+                    default:  c = '?'; break;
+                    }
+                }
+                else{
+                    if( c == '\\' ){
+                        if( pos == line.length -1 ){
+                            linecontinue = true;
+                            goto nextline;
+                        }
+                        esc = true;
+                        pos++;
+                        continue;
+                    }
+                    else if( iskeypart && c == '=' ){
+                        pos++;
+                        iskeypart = false;
+                        continue;
+                    }
+                }
+                pos++;
+                if( iskeypart ){
+                    key ~= c;
+                }
+                else{
+                    value ~= c;
+                }
+            }
+            if( iskeypart ){
+                tango.io.Stdout.Stdout.formatln( "dwt.dwthelper.ResourceBundle ctor cannot find '='." );
+                continue;
+            }
+            key = tango.text.Util.trim( key );
+            value = tango.text.Util.trim(value);
+            //tango.io.Stdout.Stdout.formatln( "properties put {}=>{}", key, value );
+
+            map[ key.dup ] = value.dup;
+            //tango.io.Stdout.Stdout.formatln( "properties put {}", __LINE__ );
+        }
     }
 
     public char[] getString( char[] key ){
+        if( auto v = key in map ){
+            return (*v).dup;
+        }
         return key;
     }
 
     public static ResourceBundle getBundle( char[] name ){
-        return new ResourceBundle( name );
+        return new ResourceBundle( null );
     }
-
+    public static ResourceBundle getBundleFromData( char[] data ){
+        return new ResourceBundle( data );
+    }
 }
 
 
--- a/dwt/dwthelper/System.d	Wed Feb 06 16:04:41 2008 +0100
+++ b/dwt/dwthelper/System.d	Wed Feb 06 18:46:23 2008 +0100
@@ -4,6 +4,7 @@
 module dwt.dwthelper.System;
 
 import tango.core.Exception;
+import tango.time.Clock;
 import tango.stdc.stdlib : exit;
 
 template SimpleType(T) {
@@ -121,8 +122,7 @@
     alias SimpleType!(void*[]).arraycopy arraycopy;
 
     static long currentTimeMillis(){
-        //PORTING_FIXMe
-        return 0;
+        return Clock.now().ticks() / 10000;
     }
 
     static void exit( int code ){
--- a/dwt/dwthelper/utils.d	Wed Feb 06 16:04:41 2008 +0100
+++ b/dwt/dwthelper/utils.d	Wed Feb 06 18:46:23 2008 +0100
@@ -88,6 +88,10 @@
     return res;
 }
 
+public char[] replace( char[] str, char from, char to ){
+    return tango.text.Util.replace( str.dup, from, to );
+}
+
 public char[] substring( char[] str, int start ){
     return str[ start .. $ ].dup;
 }
--- a/dwt/graphics/Device.d	Wed Feb 06 16:04:41 2008 +0100
+++ b/dwt/graphics/Device.d	Wed Feb 06 18:46:23 2008 +0100
@@ -511,7 +511,7 @@
              * once. The fix is to call EnumFontFamilies, which works as expected.
              */
             cbdata.scalable = scalable;
-            if (OS.IsUnicode) {
+            static if (OS.IsUnicode) {
                 OS.EnumFontFamiliesW (hDC, (cast(LOGFONTW*)lf).lfFaceName.ptr, &EnumFontFamFunc, cast(int)&cbdata);
             } else {
                 OS.EnumFontFamiliesA (hDC, (cast(LOGFONTA*)lf).lfFaceName.ptr, &EnumFontFamFunc, cast(int)&cbdata);
--- a/dwt/graphics/FontData.d	Wed Feb 06 16:04:41 2008 +0100
+++ b/dwt/graphics/FontData.d	Wed Feb 06 18:46:23 2008 +0100
@@ -323,10 +323,7 @@
     return false;
 }
 
-//PORTING_FIXME: tango has this callback defined always with char*, needs fix
-extern (Windows) static
-//int EnumLocalesProc(TCHAR* lpLocaleString) {
-int EnumLocalesProc(char* lpLocaleString) {
+extern (Windows) static int EnumLocalesProc(TCHAR* lpLocaleString) {
 
     /* Get the locale ID */
     int length_ = 8;
--- a/dwt/internal/win32/OS.d	Wed Feb 06 16:04:41 2008 +0100
+++ b/dwt/internal/win32/OS.d	Wed Feb 06 18:46:23 2008 +0100
@@ -230,7 +230,7 @@
                 pActCtx.cbSize = ACTCTX.sizeof;
                 pActCtx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_SET_PROCESS_DEFAULT;
                 pActCtx.lpSource = pszText;
-                pActCtx.lpResourceName = cast(char*)MANIFEST_RESOURCE_ID;
+                pActCtx.lpResourceName = cast(TCHAR*)MANIFEST_RESOURCE_ID;
                 HANDLE hActCtx = OS.CreateActCtx (&pActCtx);
                 if (pszText !is null) OS.HeapFree (hHeap, 0, pszText);
                 uint lpCookie;
--- a/dwt/widgets/FileDialog.d	Wed Feb 06 16:04:41 2008 +0100
+++ b/dwt/widgets/FileDialog.d	Wed Feb 06 18:46:23 2008 +0100
@@ -12,27 +12,15 @@
  *******************************************************************************/
 module dwt.widgets.FileDialog;
 
+
+import dwt.DWT;
+import dwt.DWTException;
+import dwt.internal.win32.OS;
 import dwt.widgets.Dialog;
 import dwt.widgets.Shell;
-
-class FileDialog : Dialog {
-    public this (Shell parent) {
-        this (parent, 0);
-    }
-    public this (Shell parent, int style) {
-        super (parent, style);
-    }
+import dwt.widgets.Display;
 
-}
-
-/++
-import dwt.DWT;
-import dwt.DWTException;
-import dwt.internal.Callback;
-import dwt.internal.win32.OFNOTIFY;
-import dwt.internal.win32.OPENFILENAME;
-import dwt.internal.win32.OS;
-import dwt.internal.win32.TCHAR;
+import dwt.dwthelper.utils;
 
 /**
  * Instances of this class allow the user to navigate
@@ -50,12 +38,12 @@
  * within the DWT implementation.
  * </p>
  */
-public class FileDialog extends Dialog {
-    String [] filterNames = new String [0];
-    String [] filterExtensions = new String [0];
-    String [] fileNames = new String [0];
-    String filterPath = "", fileName = "";
-    static final String FILTER = "*.*";
+public class FileDialog : Dialog {
+    char[] [] filterNames;
+    char[] [] filterExtensions;
+    char[] [] fileNames;
+    char[] filterPath = "", fileName = "";
+    static final char[] FILTER = "*.*";
     static int BUFFER_SIZE = 1024 * 32;
     static bool USE_HOOK;
 
@@ -72,7 +60,7 @@
  *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
  * </ul>
  */
-public FileDialog (Shell parent) {
+public this (Shell parent) {
     this (parent, DWT.PRIMARY_MODAL);
 }
 
@@ -100,7 +88,7 @@
  *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
  * </ul>
  */
-public FileDialog (Shell parent, int style) {
+public this (Shell parent, int style) {
     super (parent, style);
     checkSubclass ();
 }
@@ -112,7 +100,7 @@
  *
  * @return the relative path of the file
  */
-public String getFileName () {
+public char[] getFileName () {
     return fileName;
 }
 
@@ -122,7 +110,7 @@
  *
  * @return the relative paths of the files
  */
-public String [] getFileNames () {
+public char[] [] getFileNames () {
     return fileNames;
 }
 
@@ -132,7 +120,7 @@
  *
  * @return the file extensions filter
  */
-public String [] getFilterExtensions () {
+public char[] [] getFilterExtensions () {
     return filterExtensions;
 }
 
@@ -142,7 +130,7 @@
  *
  * @return the list of filter names
  */
-public String [] getFilterNames () {
+public char[] [] getFilterNames () {
     return filterNames;
 }
 
@@ -155,29 +143,29 @@
  *
  * @see #setFilterExtensions
  */
-public String getFilterPath () {
+public char[] getFilterPath () {
     return filterPath;
 }
 
-int OFNHookProc (int hdlg, int uiMsg, int wParam, int lParam) {
+private static extern(Windows) uint OFNHookProc (HWND hdlg, uint uiMsg, uint wParam, int lParam) {
     switch (uiMsg) {
         case OS.WM_NOTIFY:
-            OFNOTIFY ofn = new OFNOTIFY ();
-            OS.MoveMemory (ofn, lParam, OFNOTIFY.sizeof);
-            if (ofn.code is OS.CDN_SELCHANGE) {
-                int lResult = OS.SendMessage (ofn.hwndFrom, OS.CDM_GETSPEC, 0, 0);
+            OFNOTIFY* ofn = cast(OFNOTIFY*)lParam;
+            //OS.MoveMemory (ofn, lParam, OFNOTIFY.sizeof);
+            if (ofn.hdr.code is OS.CDN_SELCHANGE) {
+                int lResult = OS.SendMessage (ofn.hdr.hwndFrom, OS.CDM_GETSPEC, 0, 0);
                 if (lResult > 0) {
                     lResult += OS.MAX_PATH;
-                    OPENFILENAME lpofn = new OPENFILENAME ();
-                    OS.MoveMemory (lpofn, ofn.lpOFN, OPENFILENAME.sizeof);
+                    OPENFILENAME* lpofn = ofn.lpOFN;
+                    //OS.MoveMemory (lpofn, ofn.lpOFN, OPENFILENAME.sizeof);
                     if (lpofn.nMaxFile < lResult) {
-                        int hHeap = OS.GetProcessHeap ();
-                        int lpstrFile = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, lResult * TCHAR.sizeof);
-                        if (lpstrFile !is 0) {
-                            if (lpofn.lpstrFile !is 0) OS.HeapFree (hHeap, 0, lpofn.lpstrFile);
+                        auto hHeap = OS.GetProcessHeap ();
+                        auto lpstrFile = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, lResult * TCHAR.sizeof);
+                        if (lpstrFile !is null) {
+                            if (lpofn.lpstrFile !is null) OS.HeapFree (hHeap, 0, lpofn.lpstrFile);
                             lpofn.lpstrFile = lpstrFile;
                             lpofn.nMaxFile = lResult;
-                            OS.MoveMemory (ofn.lpOFN, lpofn, OPENFILENAME.sizeof);
+                            //OS.MoveMemory (ofn.lpOFN, lpofn, OPENFILENAME.sizeof);
                         }
                     }
               }
@@ -200,43 +188,43 @@
  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the dialog</li>
  * </ul>
  */
-public String open () {
-    int hHeap = OS.GetProcessHeap ();
+public char[] open () {
+    auto hHeap = OS.GetProcessHeap ();
 
     /* Get the owner HWND for the dialog */
-    int hwndOwner = 0;
+    HWND hwndOwner;
     if (parent !is null) hwndOwner = parent.handle;
 
     /* Convert the title and copy it into lpstrTitle */
     if (title is null) title = "";
     /* Use the character encoding for the default locale */
-    TCHAR buffer3 = new TCHAR (0, title, true);
-    int byteCount3 = buffer3.length () * TCHAR.sizeof;
-    int lpstrTitle = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount3);
-    OS.MoveMemory (lpstrTitle, buffer3, byteCount3);
+    TCHAR[] buffer3 = StrToTCHARs (0, title, true);
+    int byteCount3 = buffer3.length * TCHAR.sizeof;
+    auto lpstrTitle = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount3);
+    OS.MoveMemory (lpstrTitle, buffer3.ptr, byteCount3);
 
     /* Compute filters and copy into lpstrFilter */
-    String strFilter = "";
-    if (filterNames is null) filterNames = new String [0];
-    if (filterExtensions is null) filterExtensions = new String [0];
+    char[] strFilter = "";
+    if (filterNames is null) filterNames = null;
+    if (filterExtensions is null) filterExtensions = null;
     for (int i=0; i<filterExtensions.length; i++) {
-        String filterName = filterExtensions [i];
+        char[] filterName = filterExtensions [i];
         if (i < filterNames.length) filterName = filterNames [i];
-        strFilter = strFilter + filterName + '\0' + filterExtensions [i] + '\0';
+        strFilter = strFilter ~ filterName ~ '\0' ~ filterExtensions [i] ~ '\0';
     }
     if (filterExtensions.length is 0) {
-        strFilter = strFilter + FILTER + '\0' + FILTER + '\0';
+        strFilter = strFilter ~ FILTER ~ '\0' ~ FILTER ~ '\0';
     }
     /* Use the character encoding for the default locale */
-    TCHAR buffer4 = new TCHAR (0, strFilter, true);
-    int byteCount4 = buffer4.length () * TCHAR.sizeof;
-    int lpstrFilter = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount4);
-    OS.MoveMemory (lpstrFilter, buffer4, byteCount4);
+    TCHAR[] buffer4 = StrToTCHARs (0, strFilter, true);
+    int byteCount4 = buffer4.length * TCHAR.sizeof;
+    auto lpstrFilter = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount4);
+    OS.MoveMemory (lpstrFilter, buffer4.ptr, byteCount4);
 
     /* Convert the fileName and filterName to C strings */
     if (fileName is null) fileName = "";
     /* Use the character encoding for the default locale */
-    TCHAR name = new TCHAR (0, fileName, true);
+    TCHAR[] name = StrToTCHARs (0, fileName, true);
 
     /*
     * Copy the name into lpstrFile and ensure that the
@@ -245,9 +233,9 @@
     int nMaxFile = OS.MAX_PATH;
     if ((style & DWT.MULTI) !is 0) nMaxFile = Math.max (nMaxFile, BUFFER_SIZE);
     int byteCount = nMaxFile * TCHAR.sizeof;
-    int lpstrFile = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
-    int byteCountFile = Math.min (name.length () * TCHAR.sizeof, byteCount - TCHAR.sizeof);
-    OS.MoveMemory (lpstrFile, name, byteCountFile);
+    auto lpstrFile = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
+    int byteCountFile = Math.min (name.length * TCHAR.sizeof, byteCount - TCHAR.sizeof);
+    OS.MoveMemory (lpstrFile, name.ptr, byteCountFile);
 
     /*
     * Copy the path into lpstrInitialDir and ensure that
@@ -255,34 +243,35 @@
     */
     if (filterPath is null) filterPath = "";
     /* Use the character encoding for the default locale */
-    TCHAR path = new TCHAR (0, filterPath.replace ('/', '\\'), true);
+    TCHAR[] path = StrToTCHARs (0, filterPath.replace ('/', '\\'), true);
     int byteCount5 = OS.MAX_PATH * TCHAR.sizeof;
-    int lpstrInitialDir = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount5);
-    int byteCountDir = Math.min (path.length () * TCHAR.sizeof, byteCount5 - TCHAR.sizeof);
-    OS.MoveMemory (lpstrInitialDir, path, byteCountDir);
+    auto lpstrInitialDir = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount5);
+    int byteCountDir = Math.min (path.length * TCHAR.sizeof, byteCount5 - TCHAR.sizeof);
+    OS.MoveMemory (lpstrInitialDir, path.ptr, byteCountDir);
 
     /* Create the file dialog struct */
-    OPENFILENAME struct = new OPENFILENAME ();
-    struct.lStructSize = OPENFILENAME.sizeof;
-    struct.Flags = OS.OFN_HIDEREADONLY | OS.OFN_NOCHANGEDIR;
-    Callback callback = null;
+    OPENFILENAME struct_;
+    struct_.lStructSize = OPENFILENAME.sizeof;
+    struct_.Flags = OS.OFN_HIDEREADONLY | OS.OFN_NOCHANGEDIR;
+    //Callback callback = null;
     if ((style & DWT.MULTI) !is 0) {
-        struct.Flags |= OS.OFN_ALLOWMULTISELECT | OS.OFN_EXPLORER;
+        struct_.Flags |= OS.OFN_ALLOWMULTISELECT | OS.OFN_EXPLORER;
         if (!OS.IsWinCE && USE_HOOK) {
-            callback = new Callback (this, "OFNHookProc", 4); //$NON-NLS-1$
-            int lpfnHook = callback.getAddress ();
-            if (lpfnHook is 0) DWT.error (DWT.ERROR_NO_MORE_CALLBACKS);
-            struct.lpfnHook = lpfnHook;
-            struct.Flags |= OS.OFN_ENABLEHOOK;
+            //callback = new Callback (this, "OFNHookProc", 4); //$NON-NLS-1$
+            //int lpfnHook = callback.getAddress ();
+            //if (lpfnHook is 0) DWT.error (DWT.ERROR_NO_MORE_CALLBACKS);
+            struct_.lCustData = cast(uint) cast(void*) this;
+            struct_.lpfnHook = &OFNHookProc;
+            struct_.Flags |= OS.OFN_ENABLEHOOK;
         }
     }
-    struct.hwndOwner = hwndOwner;
-    struct.lpstrTitle = lpstrTitle;
-    struct.lpstrFile = lpstrFile;
-    struct.nMaxFile = nMaxFile;
-    struct.lpstrInitialDir = lpstrInitialDir;
-    struct.lpstrFilter = lpstrFilter;
-    struct.nFilterIndex = 0;
+    struct_.hwndOwner = hwndOwner;
+    struct_.lpstrTitle = lpstrTitle;
+    struct_.lpstrFile = lpstrFile;
+    struct_.nMaxFile = nMaxFile;
+    struct_.lpstrInitialDir = lpstrInitialDir;
+    struct_.lpstrFilter = lpstrFilter;
+    struct_.nFilterIndex = 0;
 
     /*
     * Set the default extension to an empty string.  If the
@@ -290,11 +279,11 @@
     * empty, Windows uses the current value of the filter
     * extension at the time that the dialog is closed.
     */
-    int lpstrDefExt = 0;
+    TCHAR* lpstrDefExt;
     bool save = (style & DWT.SAVE) !is 0;
     if (save) {
-        lpstrDefExt = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, TCHAR.sizeof);
-        struct.lpstrDefExt = lpstrDefExt;
+        lpstrDefExt = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, TCHAR.sizeof);
+        struct_.lpstrDefExt = lpstrDefExt;
     }
 
     /* Make the parent shell be temporary modal */
@@ -323,11 +312,11 @@
     * Open the dialog.  If the open fails due to an invalid
     * file name, use an empty file name and open it again.
     */
-    bool success = (save) ? OS.GetSaveFileName (struct) : OS.GetOpenFileName (struct);
+    bool success = cast(bool)( (save) ? OS.GetSaveFileName (&struct_) : OS.GetOpenFileName (&struct_));
     switch (OS.CommDlgExtendedError ()) {
         case OS.FNERR_INVALIDFILENAME:
-            OS.MoveMemory (lpstrFile, new TCHAR (0, "", true), TCHAR.sizeof);
-            success = (save) ? OS.GetSaveFileName (struct) : OS.GetOpenFileName (struct);
+            OS.MoveMemory (lpstrFile, StrToTCHARz ( "" ), TCHAR.sizeof);
+            success = cast(bool)((save) ? OS.GetSaveFileName (&struct_) : OS.GetOpenFileName (&struct_));
             break;
         case OS.FNERR_BUFFERTOOSMALL:
             USE_HOOK = true;
@@ -342,18 +331,18 @@
     }
 
     /* Dispose the callback and reassign the buffer */
-    if (callback !is null) callback.dispose ();
-    lpstrFile = struct.lpstrFile;
+    //if (callback !is null) callback.dispose ();
+    lpstrFile = struct_.lpstrFile;
 
     /* Set the new path, file name and filter */
-    fileNames = new String [0];
-    String fullPath = null;
+    fileNames = new char[] [0];
+    char[] fullPath = null;
     if (success) {
 
         /* Use the character encoding for the default locale */
-        TCHAR buffer = new TCHAR (0, struct.nMaxFile);
-        int byteCount1 = buffer.length () * TCHAR.sizeof;
-        OS.MoveMemory (buffer, lpstrFile, byteCount1);
+        TCHAR[] buffer = NewTCHARs (0, struct_.nMaxFile);
+        int byteCount1 = buffer.length * TCHAR.sizeof;
+        OS.MoveMemory (buffer.ptr, lpstrFile, byteCount1);
 
         /*
         * Bug in WinCE.  For some reason, nFileOffset and nFileExtension
@@ -364,11 +353,11 @@
         *
         * Note: WinCE does not support multi-select file dialogs.
         */
-        int nFileOffset = struct.nFileOffset;
+        int nFileOffset = struct_.nFileOffset;
         if (OS.IsWinCE && nFileOffset is 0) {
             int index = 0;
-            while (index < buffer.length ()) {
-                int ch = buffer.tcharAt (index);
+            while (index < buffer.length ) {
+                int ch = buffer[index];
                 if (ch is 0) break;
                 if (ch is '\\') nFileOffset = index + 1;
                 index++;
@@ -377,42 +366,42 @@
         if (nFileOffset > 0) {
 
             /* Use the character encoding for the default locale */
-            TCHAR prefix = new TCHAR (0, nFileOffset - 1);
-            int byteCount2 = prefix.length () * TCHAR.sizeof;
-            OS.MoveMemory (prefix, lpstrFile, byteCount2);
-            filterPath = prefix.toString (0, prefix.length ());
+            TCHAR[] prefix = NewTCHARs (0, nFileOffset - 1);
+            int byteCount2 = prefix.length * TCHAR.sizeof;
+            OS.MoveMemory (prefix.ptr, lpstrFile, byteCount2);
+            filterPath = TCHARsToStr( prefix );
 
             /*
             * Get each file from the buffer.  Files are delimited
             * by a NULL character with 2 NULL characters at the end.
             */
             int count = 0;
-            fileNames = new String [(style & DWT.MULTI) !is 0 ? 4 : 1];
+            fileNames = new char[][]( (style & DWT.MULTI) !is 0 ? 4 : 1 );
             int start = nFileOffset;
             do {
                 int end = start;
-                while (end < buffer.length () && buffer.tcharAt (end) !is 0) end++;
-                String string = buffer.toString (start, end - start);
+                while (end < buffer.length && buffer[end] !is 0) end++;
+                char[] string = TCHARsToStr( buffer[ start .. end - start ] );
                 start = end;
                 if (count is fileNames.length) {
-                    String [] newFileNames = new String [fileNames.length + 4];
+                    char[] [] newFileNames = new char[][]( fileNames.length + 4 );
                     System.arraycopy (fileNames, 0, newFileNames, 0, fileNames.length);
                     fileNames = newFileNames;
                 }
                 fileNames [count++] = string;
                 if ((style & DWT.MULTI) is 0) break;
                 start++;
-            } while (start < buffer.length () && buffer.tcharAt (start) !is 0);
+            } while (start < buffer.length && buffer[start] !is 0);
 
             if (fileNames.length > 0) fileName = fileNames  [0];
-            String separator = "";
-            int length = filterPath.length ();
-            if (length > 0 && filterPath.charAt (length - 1) !is '\\') {
+            char[] separator = "";
+            int length_ = filterPath.length;
+            if (length_ > 0 && filterPath[length_ - 1] !is '\\') {
                 separator = "\\";
             }
-            fullPath = filterPath + separator + fileName;
+            fullPath = filterPath ~ separator ~ fileName;
             if (count < fileNames.length) {
-                String [] newFileNames = new String [count];
+                char[] [] newFileNames = new char[][]( count );
                 System.arraycopy (fileNames, 0, newFileNames, 0, count);
                 fileNames = newFileNames;
             }
@@ -424,7 +413,7 @@
     OS.HeapFree (hHeap, 0, lpstrFilter);
     OS.HeapFree (hHeap, 0, lpstrInitialDir);
     OS.HeapFree (hHeap, 0, lpstrTitle);
-    if (lpstrDefExt !is 0) OS.HeapFree (hHeap, 0, lpstrDefExt);
+    if (lpstrDefExt !is null) OS.HeapFree (hHeap, 0, lpstrDefExt);
 
     /*
     * This code is intentionally commented.  On some
@@ -446,7 +435,7 @@
  *
  * @param string the file name
  */
-public void setFileName (String string) {
+public void setFileName (char[] string) {
     fileName = string;
 }
 
@@ -465,7 +454,7 @@
  * @see #setFilterNames to specify the user-friendly
  * names corresponding to the extensions
  */
-public void setFilterExtensions (String [] extensions) {
+public void setFilterExtensions (char[] [] extensions) {
     filterExtensions = extensions;
 }
 
@@ -483,7 +472,7 @@
  *
  * @see #setFilterExtensions
  */
-public void setFilterNames (String [] names) {
+public void setFilterNames (char[] [] names) {
     filterNames = names;
 }
 
@@ -504,9 +493,9 @@
  *
  * @see #setFilterExtensions
  */
-public void setFilterPath (String string) {
+public void setFilterPath (char[] string) {
     filterPath = string;
 }
 
 }
-++/
+
--- a/dwt/widgets/Tracker.d	Wed Feb 06 16:04:41 2008 +0100
+++ b/dwt/widgets/Tracker.d	Wed Feb 06 18:46:23 2008 +0100
@@ -498,7 +498,7 @@
         int height = OS.GetSystemMetrics (OS.SM_CYSCREEN);
         hwndTransparent = OS.CreateWindowEx (
             isVista ? OS.WS_EX_LAYERED | OS.WS_EX_NOACTIVATE : OS.WS_EX_TRANSPARENT,
-            display.windowClass_,
+            display.windowClass_.ptr,
             null,
             OS.WS_POPUP,
             0, 0,
--- a/tango_sys_win32/Types.d	Wed Feb 06 16:04:41 2008 +0100
+++ b/tango_sys_win32/Types.d	Wed Feb 06 18:46:23 2008 +0100
@@ -97,7 +97,7 @@
 alias PCHAR LPCH;
 alias COLORREF* LPCOLORREF;
 alias PCHAR LPCSTR;
-alias PCHAR LPCTSTR;
+alias TCHAR* LPCTSTR;
 alias wchar* LPCWCH;
 alias wchar* LPCWSTR;
 alias DWORD* LPDWORD;
@@ -106,7 +106,7 @@
 alias int* LPLONG;
 alias PCHAR LPSTR;
 alias PCHAR LPTCH;
-alias PCHAR LPTSTR;
+alias TCHAR* LPTSTR;
 alias int LRESULT;
 alias POINTER LPVOID;
 alias POINTER LPCVOID;
@@ -150,7 +150,10 @@
 alias SC_HANDLE* LPSC_HANDLE;
 alias DWORD SERVICE_STATUS_HANDLE;
 alias ubyte TBYTE;
-alias char TCHAR;
+
+// version dependent
+alias wchar TCHAR;
+
 alias ubyte BCHAR;
 alias ubyte UCHAR;
 alias wchar WCHAR;