comdlg32 16/32 split (1)

Steven Edwards steven_ed4153 at yahoo.com
Sat Oct 11 18:14:12 CDT 2003


Hello,
There are two patches in this set. The next one should come tommrow if
the Lord is with me and the planets align right. That will be the end
of the comdlg32 win16/32 mess. You can commit this now and it wont
break anything (I Think). After this patch we are down to 2 WINE16
functions being imported when we compile with --disable-win16. I know
the headers/includes in this dll are now a real mess and I plan on
cleaning it up as part of the PSDK/w32api port once the Win16/32 mess
is over and done with.

Directions: Apply the patch and remove filedlg.c or rename filedlg95.c
to filedlg.c to keep with the current naming system and remove
filedlg.h from CVS. I didnt submit a new Makefile.in because I didnt
know if you wanted to rename it or not.

Thanks
Steven

Changlog: 
- Split Win16/32 File Dialogs.
- Remove support for Win16 style'd Win32 dialogs


__________________________________
Do you Yahoo!?
The New Yahoo! Shopping - with improved product search
http://shopping.yahoo.com
-------------- next part --------------
Index: commdlg/filedlg16.c
===================================================================
RCS file: /home/wine/wine/dlls/commdlg/filedlg16.c,v
retrieving revision 1.4
diff -u -r1.4 filedlg16.c
--- commdlg/filedlg16.c	5 Sep 2003 23:08:42 -0000	1.4
+++ commdlg/filedlg16.c	11 Oct 2003 23:00:47 -0000
@@ -25,14 +25,18 @@
 #include <string.h>
 #include "windef.h"
 #include "winbase.h"
-#include "wingdi.h"
 #include "winnls.h"
+#include "wingdi.h"
+#include "winuser.h"
 #include "wine/winbase16.h"
 #include "wine/winuser16.h"
 #include "wine/unicode.h"
+#include "wine/debug.h"
+#include "cderr.h"
+#include "winreg.h"
+#include "winternl.h"
 #include "winuser.h"
 #include "commdlg.h"
-#include "wine/debug.h"
 #include "cderr.h"
 #include "winreg.h"
 #include "winternl.h"
@@ -40,7 +44,1097 @@
 WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
 
 #include "cdlg.h"
-#include "filedlg.h"
+
+#define BUFFILE 512
+#define BUFFILEALLOC 512 * sizeof(WCHAR)
+
+struct FSPRIVATE
+{
+    HWND hwnd; /* file dialog window handle */
+    BOOL hook; /* TRUE if the dialog is hooked */
+    UINT lbselchstring; /* registered message id */
+    UINT fileokstring; /* registered message id */
+    LPARAM lParam; /* save original lparam */
+    HANDLE16 hDlgTmpl16; /* handle for resource 16 */
+    HANDLE16 hResource16; /* handle for allocated resource 16 */
+    HANDLE16 hGlobal16; /* 16 bits mem block (resources) */
+    LPCVOID template; /* template for 32 bits resource */
+    BOOL open; /* TRUE if open dialog, FALSE if save dialog */
+    OPENFILENAMEW *ofnW; /* original structure or work struct */
+    OPENFILENAMEA *ofnA; /* original structure if 32bits ansi dialog */
+    OPENFILENAME16 *ofn16; /* original structure if 16 bits dialog */
+};
+
+#define LFSPRIVATE struct FSPRIVATE *
+#define LFS16 1
+#define LFS32A 2
+#define LFS32W 3
+#define OFN_PROP "FILEDLG_OFN"
+
+static const WCHAR FILE_star[] = {'*','.','*', 0};
+static const WCHAR FILE_bslash[] = {'\\', 0};
+static const WCHAR FILE_specc[] = {'%','c',':', 0};
+static const int fldrHeight = 16;
+static const int fldrWidth = 20;
+
+static HICON hFolder = 0;
+static HICON hFolder2 = 0;
+static HICON hFloppy = 0;
+static HICON hHDisk = 0;
+static HICON hCDRom = 0;
+static HICON hNet = 0;
+static char defaultopen[]="Open File";
+static char defaultsave[]="Save as";
+
+/***********************************************************************
+ * 				FileDlg_Init			[internal]
+ */
+static BOOL FileDlg_Init(void)
+{
+    static BOOL initialized = 0;
+
+    if (!initialized) {
+        HINSTANCE inst = GetModuleHandleA( "comdlg32.dll" );
+        if (!inst)
+        {
+            ERR( "cannot get comdlg32.dll instance\n" );
+            return FALSE;
+        }
+        hFolder  = LoadImageA( inst, "FOLDER", IMAGE_ICON, 16, 16, LR_SHARED );
+        hFolder2 = LoadImageA( inst, "FOLDER2", IMAGE_ICON, 16, 16, LR_SHARED );
+        hFloppy  = LoadImageA( inst, "FLOPPY", IMAGE_ICON, 16, 16, LR_SHARED );
+        hHDisk   = LoadImageA( inst, "HDISK", IMAGE_ICON, 16, 16, LR_SHARED );
+        hCDRom   = LoadImageA( inst, "CDROM", IMAGE_ICON, 16, 16, LR_SHARED );
+        hNet     = LoadImageA( inst, "NETWORK", IMAGE_ICON, 16, 16, LR_SHARED );
+	if (hFolder == 0 || hFolder2 == 0 || hFloppy == 0 ||
+	    hHDisk == 0 || hCDRom == 0 || hNet == 0)
+	{
+	    ERR("Error loading icons !\n");
+	    return FALSE;
+	}
+	initialized = TRUE;
+    }
+    return TRUE;
+}
+
+/***********************************************************************
+ *           Get32BitsTemplate                                  [internal]
+ *
+ * Get a template (or FALSE if failure) when 16 bits dialogs are used
+ * by a 32 bits application
+ *
+ */
+BOOL Get32BitsTemplate(LFSPRIVATE lfs)
+{
+    LPOPENFILENAMEW ofnW = lfs->ofnW;
+    HANDLE hDlgTmpl;
+
+    if (ofnW->Flags & OFN_ENABLETEMPLATEHANDLE)
+    {
+	if (!(lfs->template = LockResource( ofnW->hInstance )))
+	{
+	    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
+	    return FALSE;
+	}
+    }
+    else if (ofnW->Flags & OFN_ENABLETEMPLATE)
+    {
+	HRSRC hResInfo;
+        if (lfs->ofnA)
+	    hResInfo = FindResourceA(lfs->ofnA->hInstance,
+				 lfs->ofnA->lpTemplateName,
+                                 (LPSTR)RT_DIALOG);
+        else
+	    hResInfo = FindResourceW(ofnW->hInstance,
+				 ofnW->lpTemplateName,
+                                 (LPWSTR)RT_DIALOG);
+        if (!hResInfo)
+	{
+	    COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
+	    return FALSE;
+	}
+	if (!(hDlgTmpl = LoadResource(ofnW->hInstance,
+				hResInfo)) ||
+		    !(lfs->template = LockResource(hDlgTmpl)))
+	{
+	    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
+	    return FALSE;
+	}
+    } else { /* get it from internal Wine resource */
+	HRSRC hResInfo;
+	if (!(hResInfo = FindResourceA(COMDLG32_hInstance,
+             lfs->open? "OPEN_FILE":"SAVE_FILE", (LPSTR)RT_DIALOG)))
+	{
+	    COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
+	    return FALSE;
+        }
+        if (!(hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo )) ||
+                !(lfs->template = LockResource( hDlgTmpl )))
+        {
+            COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+/***********************************************************************
+ *           Get16BitsTemplate                                [internal]
+ *
+ * Get a template (FALSE if failure) when 16 bits dialogs are used
+ * by a 16 bits application
+ *
+ */
+BOOL Get16BitsTemplate(LFSPRIVATE lfs)
+{
+    LPOPENFILENAME16 ofn16 = lfs->ofn16;
+    LPCVOID template;
+    HGLOBAL16 hGlobal16 = 0;
+
+    if (ofn16->Flags & OFN_ENABLETEMPLATEHANDLE)
+        lfs->hDlgTmpl16 = ofn16->hInstance;
+    else if (ofn16->Flags & OFN_ENABLETEMPLATE)
+    {
+	HANDLE16 hResInfo;
+	if (!(hResInfo = FindResource16(ofn16->hInstance,
+					MapSL(ofn16->lpTemplateName),
+                                        (LPSTR)RT_DIALOG)))
+	{
+	    COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
+	    return FALSE;
+	}
+	if (!(lfs->hDlgTmpl16 = LoadResource16( ofn16->hInstance, hResInfo )))
+	{
+	    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
+	    return FALSE;
+	}
+        lfs->hResource16 = lfs->hDlgTmpl16;
+    }
+    else
+    { /* get resource from (32 bits) own Wine resource; convert it to 16 */
+	HRSRC hResInfo;
+	HGLOBAL hDlgTmpl32;
+        LPCVOID template32;
+        DWORD size;
+
+	if (!(hResInfo = FindResourceA(COMDLG32_hInstance,
+               lfs->open ? "OPEN_FILE":"SAVE_FILE", (LPSTR)RT_DIALOG)))
+	{
+	    COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
+	    return FALSE;
+	}
+	if (!(hDlgTmpl32 = LoadResource(COMDLG32_hInstance, hResInfo )) ||
+	    !(template32 = LockResource( hDlgTmpl32 )))
+	{
+	    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
+	    return FALSE;
+	}
+        size = SizeofResource(GetModuleHandleA("COMDLG32"), hResInfo);
+        hGlobal16 = GlobalAlloc16(0, size);
+        if (!hGlobal16)
+        {
+            COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE);
+            ERR("alloc failure for %ld bytes\n", size);
+            return FALSE;
+        }
+        template = GlobalLock16(hGlobal16);
+        if (!template)
+        {
+            COMDLG32_SetCommDlgExtendedError(CDERR_MEMLOCKFAILURE);
+            ERR("global lock failure for %x handle\n", hGlobal16);
+            GlobalFree16(hGlobal16);
+            return FALSE;
+        }
+        ConvertDialog32To16((LPVOID)template32, size, (LPVOID)template);
+        lfs->hDlgTmpl16 = hGlobal16;
+        lfs->hGlobal16 = hGlobal16;
+    }
+    return TRUE;
+}
+
+/***********************************************************************
+ *                              FILEDLG_StripEditControl        [internal]
+ * Strip pathnames off the contents of the edit control.
+ */
+static void FILEDLG_StripEditControl(HWND hwnd)
+{
+    WCHAR temp[BUFFILE], *cp;
+
+    GetDlgItemTextW( hwnd, edt1, temp, sizeof(temp)/sizeof(WCHAR));
+    cp = strrchrW(temp, '\\');
+    if (cp != NULL) {
+	strcpyW(temp, cp+1);
+    }
+    cp = strrchrW(temp, ':');
+    if (cp != NULL) {
+	strcpyW(temp, cp+1);
+    }
+    /* FIXME: shouldn't we do something with the result here? ;-) */
+}
+
+/***********************************************************************
+ *                              FILEDLG_CallWindowProc          [internal]
+ *
+ *      Call the appropriate hook
+ */
+static BOOL FILEDLG_CallWindowProc(LFSPRIVATE lfs, UINT wMsg, WPARAM wParam,
+                                   LPARAM lParam)
+{
+    if (lfs->ofnA)
+    {
+        return (BOOL) CallWindowProcA(
+          (WNDPROC)lfs->ofnA->lpfnHook, lfs->hwnd,
+          wMsg, wParam, lParam);
+    }
+
+    if (lfs->ofnW)
+    {
+        return (BOOL) CallWindowProcW(
+          (WNDPROC)lfs->ofnW->lpfnHook, lfs->hwnd,
+          wMsg, wParam, lParam);
+    }
+    return FALSE;
+}
+
+/***********************************************************************
+ * 				FILEDLG_ScanDir                 [internal]
+ */
+static BOOL FILEDLG_ScanDir(HWND hWnd, LPWSTR newPath)
+{
+    WCHAR		buffer[BUFFILE];
+    HWND 		hdlg, hdlgDir;
+    LRESULT             lRet = TRUE;
+    HCURSOR             hCursorWait, oldCursor;
+
+    TRACE("Trying to change to %s\n", debugstr_w(newPath));
+    if  ( !SetCurrentDirectoryW( newPath ))
+        return FALSE;
+    lstrcpynW(buffer, newPath, sizeof(buffer)/sizeof(WCHAR));
+
+    /* get the list of spec files */
+    GetDlgItemTextW(hWnd, edt1, buffer, sizeof(buffer)/sizeof(WCHAR));
+
+    hCursorWait = LoadCursorA(0, (LPSTR)IDC_WAIT);
+    oldCursor = SetCursor(hCursorWait);
+
+    /* list of files */
+    if ((hdlg = GetDlgItem(hWnd, lst1)) != 0) {
+        WCHAR*	scptr; /* ptr on semi-colon */
+	WCHAR*	filter = buffer;
+
+	TRACE("Using filter %s\n", debugstr_w(filter));
+	SendMessageW(hdlg, LB_RESETCONTENT, 0, 0);
+	while (filter) {
+	    scptr = strchrW(filter, ';');
+	    if (scptr)	*scptr = 0;
+            while (*filter == ' ') filter++;
+	    TRACE("Using file spec %s\n", debugstr_w(filter));
+	    if (SendMessageW(hdlg, LB_DIR, 0, (LPARAM)filter) == LB_ERR)
+	        return FALSE;
+	    if (scptr) *scptr = ';';
+	        filter = (scptr) ? (scptr + 1) : 0;
+	 }
+    }
+
+    /* list of directories */
+    strcpyW(buffer, FILE_star);
+
+    if ((hdlgDir = GetDlgItem(hWnd, lst2)) != 0) {
+        lRet = DlgDirListW(hWnd, buffer, lst2, stc1, DDL_EXCLUSIVE | DDL_DIRECTORY);
+    }
+    SetCursor(oldCursor);
+    return lRet;
+}
+
+/***********************************************************************
+ * 				FILEDLG_GetFileType		[internal]
+ */
+
+static LPWSTR FILEDLG_GetFileType(LPWSTR cfptr, LPWSTR fptr, WORD index)
+{
+  int n, i;
+  i = 0;
+  if (cfptr)
+    for ( ;(n = lstrlenW(cfptr)) != 0; i++)
+      {
+	cfptr += n + 1;
+	if (i == index)
+	  return cfptr;
+	cfptr += lstrlenW(cfptr) + 1;
+      }
+  if (fptr)
+    for ( ;(n = lstrlenW(fptr)) != 0; i++)
+      {
+	fptr += n + 1;
+	if (i == index)
+	  return fptr;
+	fptr += lstrlenW(fptr) + 1;
+    }
+  return (LPWSTR) FILE_star; /* FIXME */
+}
+
+/***********************************************************************
+ *                              FILEDLG_WMDrawItem              [internal]
+ */
+static LONG FILEDLG_WMDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam,
+       int savedlg, LPDRAWITEMSTRUCT lpdis)
+{
+    WCHAR *str;
+    HICON hIcon;
+    COLORREF oldText = 0, oldBk = 0;
+
+    if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst1)
+    {
+        if (!(str = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC))) return FALSE;
+	SendMessageW(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID,
+                      (LPARAM)str);
+
+	if ((lpdis->itemState & ODS_SELECTED) && !savedlg)
+	{
+	    oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
+	    oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
+	}
+	if (savedlg)
+	    SetTextColor(lpdis->hDC,GetSysColor(COLOR_GRAYTEXT) );
+
+	ExtTextOutW(lpdis->hDC, lpdis->rcItem.left + 1,
+                  lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
+                  &(lpdis->rcItem), str, lstrlenW(str), NULL);
+
+	if (lpdis->itemState & ODS_SELECTED)
+	    DrawFocusRect( lpdis->hDC, &(lpdis->rcItem) );
+
+	if ((lpdis->itemState & ODS_SELECTED) && !savedlg)
+	{
+	    SetBkColor( lpdis->hDC, oldBk );
+	    SetTextColor( lpdis->hDC, oldText );
+	}
+        HeapFree(GetProcessHeap(), 0, str);
+	return TRUE;
+    }
+
+    if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst2)
+    {
+        if (!(str = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC)))
+            return FALSE;
+	SendMessageW(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID,
+                      (LPARAM)str);
+
+	if (lpdis->itemState & ODS_SELECTED)
+	{
+	    oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
+	    oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
+	}
+	ExtTextOutW(lpdis->hDC, lpdis->rcItem.left + fldrWidth,
+                  lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
+                  &(lpdis->rcItem), str, lstrlenW(str), NULL);
+
+	if (lpdis->itemState & ODS_SELECTED)
+	    DrawFocusRect( lpdis->hDC, &(lpdis->rcItem) );
+
+	if (lpdis->itemState & ODS_SELECTED)
+	{
+	    SetBkColor( lpdis->hDC, oldBk );
+	    SetTextColor( lpdis->hDC, oldText );
+	}
+	DrawIcon(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hFolder);
+        HeapFree(GetProcessHeap(), 0, str);
+	return TRUE;
+    }
+    if (lpdis->CtlType == ODT_COMBOBOX && lpdis->CtlID == cmb2)
+    {
+        char root[] = "a:";
+        if (!(str = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC)))
+            return FALSE;
+	SendMessageW(lpdis->hwndItem, CB_GETLBTEXT, lpdis->itemID,
+                      (LPARAM)str);
+        root[0] += str[2] - 'a';
+        switch(GetDriveTypeA(root))
+        {
+        case DRIVE_REMOVABLE: hIcon = hFloppy; break;
+        case DRIVE_CDROM:     hIcon = hCDRom; break;
+        case DRIVE_REMOTE:    hIcon = hNet; break;
+        case DRIVE_FIXED:
+        default:           hIcon = hHDisk; break;
+        }
+	if (lpdis->itemState & ODS_SELECTED)
+	{
+	    oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
+	    oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
+	}
+	ExtTextOutW(lpdis->hDC, lpdis->rcItem.left + fldrWidth,
+                  lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
+                  &(lpdis->rcItem), str, lstrlenW(str), NULL);
+
+	if (lpdis->itemState & ODS_SELECTED)
+	{
+	    SetBkColor( lpdis->hDC, oldBk );
+	    SetTextColor( lpdis->hDC, oldText );
+	}
+	DrawIcon(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hIcon);
+        HeapFree(GetProcessHeap(), 0, str);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/***********************************************************************
+ *                              FILEDLG_UpdateResult            [internal]
+ *      update the displayed file name (with path)
+ */
+void FILEDLG_UpdateResult(LFSPRIVATE lfs, WCHAR *tmpstr)
+{
+    int lenstr2;
+    LPOPENFILENAMEW ofnW = lfs->ofnW;
+    WCHAR tmpstr2[BUFFILE];
+    WCHAR *bs;
+
+    TRACE("%s\n", debugstr_w(tmpstr));
+    if(ofnW->Flags & OFN_NOVALIDATE)
+        tmpstr2[0] = '\0';
+    else
+        GetCurrentDirectoryW(BUFFILE, tmpstr2);
+    lenstr2 = strlenW(tmpstr2);
+    if (lenstr2 > 3)
+        tmpstr2[lenstr2++]='\\';
+    lstrcpynW(tmpstr2+lenstr2, tmpstr, BUFFILE-lenstr2);
+    if (ofnW->lpstrFile)
+        lstrcpynW(ofnW->lpstrFile, tmpstr2, ofnW->nMaxFile);
+    if((bs = strrchrW(tmpstr2, '\\')) != NULL)
+        ofnW->nFileOffset = bs - tmpstr2 +1;
+    else
+        ofnW->nFileOffset = 0;
+    ofnW->nFileExtension = 0;
+    while(tmpstr2[ofnW->nFileExtension] != '.' && tmpstr2[ofnW->nFileExtension] != '\0')
+        ofnW->nFileExtension++;
+    if (tmpstr2[ofnW->nFileExtension] == '\0')
+        ofnW->nFileExtension = 0;
+    else
+        ofnW->nFileExtension++;
+    /* update the real client structures if any */
+    if (lfs->ofn16)
+    { /* we have to convert to short (8.3) path */
+	char tmp[1024]; /* MAX_PATHNAME_LEN */
+	LPOPENFILENAME16 ofn16 = lfs->ofn16;
+        char *dest = MapSL(ofn16->lpstrFile);
+        char *bs16;
+        if (!WideCharToMultiByte( CP_ACP, 0, ofnW->lpstrFile, -1,
+                                  tmp, sizeof(tmp), NULL, NULL ))
+            tmp[sizeof(tmp)-1] = 0;
+	GetShortPathNameA(tmp, dest, ofn16->nMaxFile);
+
+	/* the same procedure as every year... */
+        if((bs16 = strrchr(dest, '\\')) != NULL)
+            ofn16->nFileOffset = bs16 - dest +1;
+        else
+            ofn16->nFileOffset = 0;
+        ofn16->nFileExtension = 0;
+        while(dest[ofn16->nFileExtension] != '.' && dest[ofn16->nFileExtension] != '\0')
+            ofn16->nFileExtension++;
+        if (dest[ofn16->nFileExtension] == '\0')
+            ofn16->nFileExtension = 0;
+        else
+            ofn16->nFileExtension++;
+    }
+    if (lfs->ofnA)
+    {
+        if (ofnW->nMaxFile &&
+            !WideCharToMultiByte( CP_ACP, 0, ofnW->lpstrFile, -1,
+                                  lfs->ofnA->lpstrFile, ofnW->nMaxFile, NULL, NULL ))
+            lfs->ofnA->lpstrFile[ofnW->nMaxFile-1] = 0;
+        lfs->ofnA->nFileOffset = ofnW->nFileOffset;
+        lfs->ofnA->nFileExtension = ofnW->nFileExtension;
+    }
+}
+
+/***********************************************************************
+ *                              FILEDLG_UpdateFileTitle         [internal]
+ *      update the displayed file name (without path)
+ */
+void FILEDLG_UpdateFileTitle(LFSPRIVATE lfs)
+{
+  LONG lRet;
+  LPOPENFILENAMEW ofnW = lfs->ofnW;
+  if (ofnW->lpstrFileTitle != NULL)
+  {
+    lRet = SendDlgItemMessageW(lfs->hwnd, lst1, LB_GETCURSEL, 0, 0);
+    SendDlgItemMessageW(lfs->hwnd, lst1, LB_GETTEXT, lRet,
+                             (LPARAM)ofnW->lpstrFileTitle );
+    if (lfs->ofn16)
+    {
+        char *dest = MapSL(lfs->ofn16->lpstrFileTitle);
+        if (!WideCharToMultiByte( CP_ACP, 0, ofnW->lpstrFileTitle, -1,
+                                  dest, ofnW->nMaxFileTitle, NULL, NULL ))
+            dest[ofnW->nMaxFileTitle-1] = 0;
+    }
+    if (lfs->ofnA)
+    {
+        if (!WideCharToMultiByte( CP_ACP, 0, ofnW->lpstrFileTitle, -1,
+                                  lfs->ofnA->lpstrFileTitle, ofnW->nMaxFileTitle, NULL, NULL ))
+            lfs->ofnA->lpstrFileTitle[ofnW->nMaxFileTitle-1] = 0;
+    }
+  }
+}
+
+/***********************************************************************
+ *                              FILEDLG_DirListDblClick         [internal]
+ */
+static LRESULT FILEDLG_DirListDblClick( LFSPRIVATE lfs )
+{
+  LONG lRet;
+  HWND hWnd = lfs->hwnd;
+  LPWSTR pstr;
+  WCHAR tmpstr[BUFFILE];
+
+  /* get the raw string (with brackets) */
+  lRet = SendDlgItemMessageW(hWnd, lst2, LB_GETCURSEL, 0, 0);
+  if (lRet == LB_ERR) return TRUE;
+  pstr = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC);
+  SendDlgItemMessageW(hWnd, lst2, LB_GETTEXT, lRet,
+		     (LPARAM)pstr);
+  strcpyW( tmpstr, pstr );
+  HeapFree(GetProcessHeap(), 0, pstr);
+  /* get the selected directory in tmpstr */
+  if (tmpstr[0] == '[')
+    {
+      tmpstr[lstrlenW(tmpstr) - 1] = 0;
+      strcpyW(tmpstr,tmpstr+1);
+    }
+  strcatW(tmpstr, FILE_bslash);
+
+  FILEDLG_ScanDir(hWnd, tmpstr);
+  /* notify the app */
+  if (lfs->hook)
+    {
+      if (FILEDLG_CallWindowProc(lfs, lfs->lbselchstring, lst2,
+              MAKELONG(lRet,CD_LBSELCHANGE)))
+        return TRUE;
+    }
+  return TRUE;
+}
+
+/***********************************************************************
+ *                              FILEDLG_FileListSelect         [internal]
+ *    called when a new item is picked in the file list
+ */
+static LRESULT FILEDLG_FileListSelect( LFSPRIVATE lfs )
+{
+    LONG lRet;
+    HWND hWnd = lfs->hwnd;
+    LPWSTR pstr;
+
+    lRet = SendDlgItemMessageW(hWnd, lst1, LB_GETCURSEL16, 0, 0);
+    if (lRet == LB_ERR)
+        return TRUE;
+
+    /* set the edit control to the choosen file */
+    if ((pstr = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC)))
+    {
+        SendDlgItemMessageW(hWnd, lst1, LB_GETTEXT, lRet,
+                       (LPARAM)pstr);
+        SetDlgItemTextW( hWnd, edt1, pstr );
+        HeapFree(GetProcessHeap(), 0, pstr);
+    }
+    if (lfs->hook)
+    {
+        FILEDLG_CallWindowProc(lfs, lfs->lbselchstring, lst1,
+                           MAKELONG(lRet,CD_LBSELCHANGE));
+    }
+    /* FIXME: for OFN_ALLOWMULTISELECT we need CD_LBSELSUB, CD_SELADD,
+           CD_LBSELNOITEMS */
+    return TRUE;
+}
+
+/***********************************************************************
+ *                              FILEDLG_TestPath      [internal]
+ *      before accepting the file name, test if it includes wild cards
+ *      tries to scan the directory and returns TRUE if no error.
+ */
+static LRESULT FILEDLG_TestPath( LFSPRIVATE lfs, LPWSTR path )
+{
+    HWND hWnd = lfs->hwnd;
+    LPWSTR pBeginFileName, pstr2;
+    WCHAR tmpstr2[BUFFILE];
+
+    pBeginFileName = strrchrW(path, '\\');
+    if (pBeginFileName == NULL)
+	pBeginFileName = strrchrW(path, ':');
+
+    if (strchrW(path,'*') != NULL || strchrW(path,'?') != NULL)
+    {
+        /* edit control contains wildcards */
+        if (pBeginFileName != NULL)
+        {
+	    lstrcpynW(tmpstr2, pBeginFileName + 1, BUFFILE);
+	    *(pBeginFileName + 1) = 0;
+	}
+	else
+	{
+	    strcpyW(tmpstr2, path);
+            if(!(lfs->ofnW->Flags & OFN_NOVALIDATE))
+                *path = 0;
+        }
+
+        TRACE("path=%s, tmpstr2=%s\n", debugstr_w(path), debugstr_w(tmpstr2));
+        SetDlgItemTextW( hWnd, edt1, tmpstr2 );
+        FILEDLG_ScanDir(hWnd, path);
+        return (lfs->ofnW->Flags & OFN_NOVALIDATE) ? TRUE : FALSE;
+    }
+
+    /* no wildcards, we might have a directory or a filename */
+    /* try appending a wildcard and reading the directory */
+
+    pstr2 = path + lstrlenW(path);
+    if (pBeginFileName == NULL || *(pBeginFileName + 1) != 0)
+        strcatW(path, FILE_bslash);
+
+    /* if ScanDir succeeds, we have changed the directory */
+    if (FILEDLG_ScanDir(hWnd, path))
+        return TRUE;
+
+    /* if not, this must be a filename */
+
+    *pstr2 = 0; /* remove the wildcard added before */
+
+    if (pBeginFileName != NULL)
+    {
+        /* strip off the pathname */
+        *pBeginFileName = 0;
+        SetDlgItemTextW( hWnd, edt1, pBeginFileName + 1 );
+
+        lstrcpynW(tmpstr2, pBeginFileName + 1, sizeof(tmpstr2)/sizeof(WCHAR) );
+        /* Should we MessageBox() if this fails? */
+        if (!FILEDLG_ScanDir(hWnd, path))
+        {
+            return FALSE;
+        }
+        strcpyW(path, tmpstr2);
+    }
+    else
+        SetDlgItemTextW( hWnd, edt1, path );
+    return TRUE;
+}
+
+/***********************************************************************
+ *                              FILEDLG_Validate               [internal]
+ *   called on: click Ok button, Enter in edit, DoubleClick in file list
+ */
+static LRESULT FILEDLG_Validate( LFSPRIVATE lfs, LPWSTR path, UINT control, INT itemIndex,
+                                 BOOL internalUse )
+{
+    LONG lRet;
+    HWND hWnd = lfs->hwnd;
+    OPENFILENAMEW ofnsav;
+    LPOPENFILENAMEW ofnW = lfs->ofnW;
+    WCHAR filename[BUFFILE];
+
+    ofnsav = *ofnW; /* for later restoring */
+
+    /* get current file name */
+    if (path)
+        lstrcpynW(filename, path, sizeof(filename)/sizeof(WCHAR));
+    else
+        GetDlgItemTextW( hWnd, edt1, filename, sizeof(filename)/sizeof(WCHAR));
+
+    TRACE("got filename = %s\n", debugstr_w(filename));
+    /* if we did not click in file list to get there */
+    if (control != lst1)
+    {
+        if (!FILEDLG_TestPath( lfs, filename) )
+           return FALSE;
+    }
+    FILEDLG_UpdateResult(lfs, filename);
+
+    if (internalUse)
+    { /* called internally after a change in a combo */
+        if (lfs->hook)
+        {
+             FILEDLG_CallWindowProc(lfs, lfs->lbselchstring, control,
+                             MAKELONG(itemIndex,CD_LBSELCHANGE));
+        }
+        return TRUE;
+    }
+
+    FILEDLG_UpdateFileTitle(lfs);
+    if (lfs->hook)
+    {
+        lRet = (BOOL)FILEDLG_CallWindowProc(lfs, lfs->fileokstring,
+                  0, lfs->lParam );
+        if (lRet)
+        {
+            *ofnW = ofnsav; /* restore old state */
+            return FALSE;
+        }
+    }
+    if ((ofnW->Flags & OFN_ALLOWMULTISELECT) && (ofnW->Flags & OFN_EXPLORER))
+    {
+        if (ofnW->lpstrFile)
+        {
+            LPWSTR str = (LPWSTR)ofnW->lpstrFile;
+            LPWSTR ptr = strrchrW(str, '\\');
+	    str[lstrlenW(str) + 1] = '\0';
+	    *ptr = 0;
+        }
+    }
+    return TRUE;
+}
+
+/***********************************************************************
+ *                              FILEDLG_DiskChange             [internal]
+ *    called when a new item is picked in the disk selection combo
+ */
+static LRESULT FILEDLG_DiskChange( LFSPRIVATE lfs )
+{
+    LONG lRet;
+    HWND hWnd = lfs->hwnd;
+    LPWSTR pstr;
+    WCHAR diskname[BUFFILE];
+
+    FILEDLG_StripEditControl(hWnd);
+    lRet = SendDlgItemMessageW(hWnd, cmb2, CB_GETCURSEL, 0, 0L);
+    if (lRet == LB_ERR)
+        return 0;
+    pstr = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC);
+    SendDlgItemMessageW(hWnd, cmb2, CB_GETLBTEXT, lRet,
+                         (LPARAM)pstr);
+    wsprintfW(diskname, FILE_specc, pstr[2]);
+    HeapFree(GetProcessHeap(), 0, pstr);
+
+    return FILEDLG_Validate( lfs, diskname, cmb2, lRet, TRUE );
+}
+
+/***********************************************************************
+ *                              FILEDLG_FileTypeChange         [internal]
+ *    called when a new item is picked in the file type combo
+ */
+static LRESULT FILEDLG_FileTypeChange( LFSPRIVATE lfs )
+{
+    LONG lRet;
+    WCHAR diskname[BUFFILE];
+    LPWSTR pstr;
+
+    diskname[0] = 0;
+
+    lRet = SendDlgItemMessageW(lfs->hwnd, cmb1, CB_GETCURSEL, 0, 0);
+    if (lRet == LB_ERR)
+        return TRUE;
+    pstr = (LPWSTR)SendDlgItemMessageW(lfs->hwnd, cmb1, CB_GETITEMDATA, lRet, 0);
+    TRACE("Selected filter : %s\n", debugstr_w(pstr));
+    SetDlgItemTextW( lfs->hwnd, edt1, pstr );
+
+    return FILEDLG_Validate( lfs, NULL, cmb1, lRet, TRUE );
+}
+
+/***********************************************************************
+ *                              FILEDLG_WMCommand               [internal]
+ */
+static LRESULT FILEDLG_WMCommand(HWND hWnd, LPARAM lParam, UINT notification,
+       UINT control, LFSPRIVATE lfs )
+{
+    switch (control)
+    {
+        case lst1: /* file list */
+        FILEDLG_StripEditControl(hWnd);
+        if (notification == LBN_DBLCLK)
+        {
+            if (FILEDLG_Validate( lfs, NULL, control, 0, FALSE ))
+                EndDialog(hWnd, TRUE);
+            return TRUE;
+        }
+        else if (notification == LBN_SELCHANGE)
+            return FILEDLG_FileListSelect( lfs );
+        break;
+
+        case lst2: /* directory list */
+        FILEDLG_StripEditControl(hWnd);
+        if (notification == LBN_DBLCLK)
+            return FILEDLG_DirListDblClick( lfs );
+        break;
+
+        case cmb1: /* file type drop list */
+        if (notification == CBN_SELCHANGE)
+            return FILEDLG_FileTypeChange( lfs );
+        break;
+
+        case chx1:
+        break;
+
+        case pshHelp:
+        break;
+
+        case cmb2: /* disk dropdown combo */
+        if (notification == CBN_SELCHANGE)
+            return FILEDLG_DiskChange( lfs );
+        break;
+
+        case IDOK:
+        TRACE("OK pressed\n");
+        if (FILEDLG_Validate( lfs, NULL, control, 0, FALSE ))
+            EndDialog(hWnd, TRUE);
+        return TRUE;
+
+        case IDCANCEL:
+        EndDialog(hWnd, FALSE);
+        return TRUE;
+
+        case IDABORT: /* can be sent by the hook procedure */
+        EndDialog(hWnd, TRUE);
+        return TRUE;
+    }
+    return FALSE;
+}
+
+/***********************************************************************
+ *                              FILEDLG_MapDrawItemStruct       [internal]
+ *      map a 16 bits drawitem struct to 32
+ */
+static void FILEDLG_MapDrawItemStruct(LPDRAWITEMSTRUCT16 lpdis16, LPDRAWITEMSTRUCT lpdis)
+{
+    lpdis->CtlType = lpdis16->CtlType;
+    lpdis->CtlID = lpdis16->CtlID;
+    lpdis->itemID = lpdis16->itemID;
+    lpdis->itemAction = lpdis16->itemAction;
+    lpdis->itemState = lpdis16->itemState;
+    lpdis->hwndItem = HWND_32(lpdis16->hwndItem);
+    lpdis->hDC = HDC_32(lpdis16->hDC);
+    lpdis->rcItem.right = lpdis16->rcItem.right;
+    lpdis->rcItem.left = lpdis16->rcItem.left;
+    lpdis->rcItem.top = lpdis16->rcItem.top;
+    lpdis->rcItem.bottom = lpdis16->rcItem.bottom;
+    lpdis->itemData = lpdis16->itemData;
+}
+
+/************************************************************************
+ *                              FILEDLG_MapStringPairsToW       [internal]
+ *      map string pairs to Unicode
+ */
+static LPWSTR FILEDLG_MapStringPairsToW(LPCSTR strA, UINT size)
+{
+    LPCSTR s;
+    LPWSTR x;
+    int n, len;
+
+    s = strA;
+    while (*s)
+        s = s+strlen(s)+1;
+    s++;
+    n = s + 1 - strA; /* Don't forget the other \0 */
+    if (n < size) n = size;
+
+    len = MultiByteToWideChar( CP_ACP, 0, strA, n, NULL, 0 );
+    x = HeapAlloc(GetProcessHeap(),0, len * sizeof(WCHAR));
+    MultiByteToWideChar( CP_ACP, 0, strA, n, x, len );
+    return x;
+}
+
+
+/************************************************************************
+ *                              FILEDLG_DupToW                  [internal]
+ *      duplicates an Ansi string to unicode, with a buffer size
+ */
+LPWSTR FILEDLG_DupToW(LPCSTR str, DWORD size)
+{
+    LPWSTR strW = NULL;
+    if (str && (size > 0))
+    {
+        strW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
+        if (strW) MultiByteToWideChar( CP_ACP, 0, str, -1, strW, size );
+    }
+    return strW;
+}
+
+
+/************************************************************************
+ *                              FILEDLG_MapOfnStructA          [internal]
+ *      map a 32 bits Ansi structure to an Unicode one
+ */
+void FILEDLG_MapOfnStructA(LPOPENFILENAMEA ofnA, LPOPENFILENAMEW ofnW, BOOL open)
+{
+    LPCSTR str;
+    UNICODE_STRING usBuffer;
+
+    ofnW->lStructSize = sizeof(OPENFILENAMEW);
+    ofnW->hwndOwner = ofnA->hwndOwner;
+    ofnW->hInstance = ofnA->hInstance;
+    if (ofnA->lpstrFilter)
+        ofnW->lpstrFilter = FILEDLG_MapStringPairsToW(ofnA->lpstrFilter, 0);
+
+    if ((ofnA->lpstrCustomFilter) && (*(ofnA->lpstrCustomFilter)))
+        ofnW->lpstrCustomFilter = FILEDLG_MapStringPairsToW(ofnA->lpstrCustomFilter, ofnA->nMaxCustFilter);
+    ofnW->nMaxCustFilter = ofnA->nMaxCustFilter;
+    ofnW->nFilterIndex = ofnA->nFilterIndex;
+    ofnW->nMaxFile = ofnA->nMaxFile;
+    ofnW->lpstrFile = FILEDLG_DupToW(ofnA->lpstrFile, ofnW->nMaxFile);
+    ofnW->nMaxFileTitle = ofnA->nMaxFileTitle;
+    ofnW->lpstrFileTitle = FILEDLG_DupToW(ofnA->lpstrFileTitle, ofnW->nMaxFileTitle);
+    if (ofnA->lpstrInitialDir)
+    {
+        RtlCreateUnicodeStringFromAsciiz (&usBuffer,ofnA->lpstrInitialDir);
+        ofnW->lpstrInitialDir = usBuffer.Buffer;
+    }
+    if (ofnA->lpstrTitle)
+        str = ofnA->lpstrTitle;
+    else
+        /* Allocates default title (FIXME : get it from resource) */
+        str = open ? defaultopen:defaultsave;
+    RtlCreateUnicodeStringFromAsciiz (&usBuffer,ofnA->lpstrTitle);
+    ofnW->lpstrTitle = usBuffer.Buffer;
+    ofnW->Flags = ofnA->Flags;
+    ofnW->nFileOffset = ofnA->nFileOffset;
+    ofnW->nFileExtension = ofnA->nFileExtension;
+    ofnW->lpstrDefExt = FILEDLG_DupToW(ofnA->lpstrDefExt, 3);
+    if ((ofnA->Flags & OFN_ENABLETEMPLATE) && (ofnA->lpTemplateName))
+    {
+        if (HIWORD(ofnA->lpTemplateName))
+        {
+            RtlCreateUnicodeStringFromAsciiz (&usBuffer,ofnA->lpTemplateName);
+            ofnW->lpTemplateName = usBuffer.Buffer;
+        }
+        else /* numbered resource */
+            ofnW->lpTemplateName = (LPWSTR) ofnA->lpTemplateName;
+    }
+}
+
+/************************************************************************
+ *                              FILEDLG_MapOfnStruct16          [internal]
+ *      map a 16 bits structure to an Unicode one
+ */
+void FILEDLG_MapOfnStruct16(LPOPENFILENAME16 ofn16, LPOPENFILENAMEW ofnW, BOOL open)
+{
+    OPENFILENAMEA ofnA;
+    /* first convert to linear pointers */
+    memset(&ofnA, 0, sizeof(OPENFILENAMEA));
+    ofnA.lStructSize = sizeof(OPENFILENAMEA);
+    ofnA.hwndOwner = HWND_32(ofn16->hwndOwner);
+    ofnA.hInstance = HINSTANCE_32(ofn16->hInstance);
+    if (ofn16->lpstrFilter)
+        ofnA.lpstrFilter = MapSL(ofn16->lpstrFilter);
+    if (ofn16->lpstrCustomFilter)
+        ofnA.lpstrCustomFilter = MapSL(ofn16->lpstrCustomFilter);
+    ofnA.nMaxCustFilter = ofn16->nMaxCustFilter;
+    ofnA.nFilterIndex = ofn16->nFilterIndex;
+    ofnA.lpstrFile = MapSL(ofn16->lpstrFile);
+    ofnA.nMaxFile = ofn16->nMaxFile;
+    ofnA.lpstrFileTitle = MapSL(ofn16->lpstrFileTitle);
+    ofnA.nMaxFileTitle = ofn16->nMaxFileTitle;
+    ofnA.lpstrInitialDir = MapSL(ofn16->lpstrInitialDir);
+    ofnA.lpstrTitle = MapSL(ofn16->lpstrTitle);
+    ofnA.Flags = ofn16->Flags;
+    ofnA.nFileOffset = ofn16->nFileOffset;
+    ofnA.nFileExtension = ofn16->nFileExtension;
+    ofnA.lpstrDefExt = MapSL(ofn16->lpstrDefExt);
+    if (HIWORD(ofn16->lpTemplateName))
+        ofnA.lpTemplateName = MapSL(ofn16->lpTemplateName);
+    else
+        ofnA.lpTemplateName = (LPSTR) ofn16->lpTemplateName; /* ressource number */
+    /* now calls the 32 bits Ansi to Unicode version to complete the job */
+    FILEDLG_MapOfnStructA(&ofnA, ofnW, open);
+}
+
+/************************************************************************
+ *                              FILEDLG_DestroyPrivate            [internal]
+ *      destroys the private object
+ */
+static void FILEDLG_DestroyPrivate(LFSPRIVATE lfs)
+{
+    HWND hwnd;
+    if (!lfs) return;
+    hwnd = lfs->hwnd;
+    /* free resources for a 16 bits dialog */
+    if (lfs->hResource16) FreeResource16(lfs->hResource16);
+    if (lfs->hGlobal16)
+    {
+        GlobalUnlock16(lfs->hGlobal16);
+        GlobalFree16(lfs->hGlobal16);
+    }
+    /* if ofnW has been allocated, have to free everything in it */
+    if (lfs->ofn16 || lfs->ofnA)
+    {
+       LPOPENFILENAMEW ofnW = lfs->ofnW;
+       if (ofnW->lpstrFilter) HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpstrFilter);
+       if (ofnW->lpstrCustomFilter) HeapFree(GetProcessHeap(), 0, ofnW->lpstrCustomFilter);
+       if (ofnW->lpstrFile) HeapFree(GetProcessHeap(), 0, ofnW->lpstrFile);
+       if (ofnW->lpstrFileTitle) HeapFree(GetProcessHeap(), 0, ofnW->lpstrFileTitle);
+       if (ofnW->lpstrInitialDir) HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpstrInitialDir);
+       if (ofnW->lpstrTitle) HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpstrTitle);
+       if ((ofnW->lpTemplateName) && (HIWORD(ofnW->lpTemplateName)))
+           HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpTemplateName);
+       HeapFree(GetProcessHeap(), 0, ofnW);
+    }
+    TRACE("destroying private allocation %p\n", lfs);
+    HeapFree(GetProcessHeap(), 0, lfs);
+    RemovePropA(hwnd, OFN_PROP);
+}
+
+/************************************************************************
+ *                              FILEDLG_AllocPrivate            [internal]
+ *      allocate a private object to hold 32 bits Unicode
+ *      structure that will be used throughtout the calls, while
+ *      keeping available the original structures and a few variables
+ *      On entry : type = dialog procedure type (16,32A,32W)
+ *                 dlgType = dialog type (open or save)
+ */
+static LFSPRIVATE FILEDLG_AllocPrivate(LPARAM lParam, int type, UINT dlgType)
+{
+    LFSPRIVATE lfs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct FSPRIVATE));
+    LFSPRIVATE ret;
+    TRACE("alloc private buf %p\n", lfs);
+    if (!lfs) return NULL;
+    lfs->hook = FALSE;
+    lfs->lParam = lParam;
+    if (dlgType == OPEN_DIALOG)
+        lfs->open = TRUE;
+    else
+        lfs->open = FALSE;
+    lfs->lbselchstring = RegisterWindowMessageA(LBSELCHSTRINGA);
+    lfs->fileokstring = RegisterWindowMessageA(FILEOKSTRINGA);
+    switch(type)
+    {
+        case LFS16:
+        lfs->ofn16 = MapSL(lParam);
+        if (lfs->ofn16->Flags & OFN_ENABLEHOOK)
+            if (lfs->ofn16->lpfnHook)
+                lfs->hook = TRUE;
+
+        break;
+
+        case LFS32A:
+        lfs->ofnA = (LPOPENFILENAMEA) lParam;
+        if (lfs->ofnA->Flags & OFN_ENABLEHOOK)
+            if (lfs->ofnA->lpfnHook)
+                lfs->hook = TRUE;
+        break;
+
+        case LFS32W:
+        lfs->ofnW = (LPOPENFILENAMEW) lParam;
+        if (lfs->ofnW->Flags & OFN_ENABLEHOOK)
+            if (lfs->ofnW->lpfnHook)
+                lfs->hook = TRUE;
+        break;
+    }
+    ret = lfs;
+    if (!lfs->ofnW)
+    { /* this structure is needed internally, so create it */
+        lfs->ofnW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(OPENFILENAMEW));
+        if (lfs->ofnW)
+        {
+            if (lfs->ofn16)
+                FILEDLG_MapOfnStruct16(lfs->ofn16, lfs->ofnW, lfs->open);
+            if (lfs->ofnA)
+                FILEDLG_MapOfnStructA(lfs->ofnA, lfs->ofnW, lfs->open);
+        }
+        else
+            ret = NULL;
+    }
+    if (lfs->ofn16)
+    {
+        if (!Get16BitsTemplate(lfs)) ret = NULL;
+    }
+    else
+        if (!Get32BitsTemplate(lfs)) ret = NULL;
+    if (!ret) FILEDLG_DestroyPrivate(lfs);
+    return ret;
+}
 
 /***********************************************************************
  *                              FILEDLG_CallWindowProc16          [internal]
Index: commdlg/filedlg95.c
===================================================================
RCS file: /home/wine/wine/dlls/commdlg/filedlg95.c,v
retrieving revision 1.103
diff -u -r1.103 filedlg95.c
--- commdlg/filedlg95.c	10 Sep 2003 03:56:48 -0000	1.103
+++ commdlg/filedlg95.c	11 Oct 2003 23:00:51 -0000
@@ -3176,3 +3176,69 @@
         HeapFree(GetProcessHeap(),0,mem);
     }
 }
+
+/* ------------------ APIs ---------------------- */
+
+/***********************************************************************
+ *            GetOpenFileNameA  (COMDLG32.@)
+ *
+ * Creates a dialog box for the user to select a file to open.
+ *
+ * RETURNS
+ *    TRUE on success: user enters a valid file
+ *    FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
+ *
+ */
+BOOL WINAPI GetOpenFileNameA(
+	LPOPENFILENAMEA ofn) /* [in/out] address of init structure */
+{
+        return GetFileDialog95A(ofn, OPEN_DIALOG);
+}
+
+/***********************************************************************
+ *            GetOpenFileNameW (COMDLG32.@)
+ *
+ * Creates a dialog box for the user to select a file to open.
+ *
+ * RETURNS
+ *    TRUE on success: user enters a valid file
+ *    FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
+ *
+ */
+BOOL WINAPI GetOpenFileNameW(
+	LPOPENFILENAMEW ofn) /* [in/out] address of init structure */
+{
+        return GetFileDialog95W(ofn, OPEN_DIALOG);
+}
+
+/***********************************************************************
+ *            GetSaveFileNameA  (COMDLG32.@)
+ *
+ * Creates a dialog box for the user to select a file to save.
+ *
+ * RETURNS
+ *    TRUE on success: user enters a valid file
+ *    FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
+ *
+ */
+BOOL WINAPI GetSaveFileNameA(
+	LPOPENFILENAMEA ofn) /* [in/out] address of init structure */
+{
+        return GetFileDialog95A(ofn, SAVE_DIALOG);
+}
+
+/***********************************************************************
+ *            GetSaveFileNameW  (COMDLG32.@)
+ *
+ * Creates a dialog box for the user to select a file to save.
+ *
+ * RETURNS
+ *    TRUE on success: user enters a valid file
+ *    FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
+ *
+ */
+BOOL WINAPI GetSaveFileNameW(
+	LPOPENFILENAMEW ofn) /* [in/out] address of init structure */
+{
+	return GetFileDialog95W(ofn, SAVE_DIALOG);
+}


More information about the wine-patches mailing list