2 * COMMDLG - File Dialogs
4 * Copyright 1994 Martin Ayotte
5 * Copyright 1996 Albrecht Kleine
14 #include "wine/winbase16.h"
15 #include "wine/winuser16.h"
16 #include "wine/unicode.h"
24 #include "debugtools.h"
29 DEFAULT_DEBUG_CHANNEL(commdlg);
34 #define BUFFILEALLOC 512 * sizeof(WCHAR)
38 HWND hwnd; /* file dialog window handle */
39 BOOL hook; /* TRUE if the dialog is hooked */
40 UINT lbselchstring; /* registered message id */
41 UINT fileokstring; /* registered message id */
42 LPARAM lParam; /* save original lparam */
43 HANDLE16 hDlgTmpl16; /* handle for resource 16 */
44 HANDLE16 hResource16; /* handle for allocated resource 16 */
45 HANDLE16 hGlobal16; /* 16 bits mem block (resources) */
46 LPCVOID template; /* template for 32 bits resource */
47 BOOL open; /* TRUE if open dialog, FALSE if save dialog */
48 OPENFILENAMEW *ofnW; /* original structure or work struct */
49 OPENFILENAMEA *ofnA; /* original structure if 32bits ansi dialog */
50 OPENFILENAME16 *ofn16; /* original structure if 16 bits dialog */
54 #define LFSPRIVATE struct FSPRIVATE *
60 static const WCHAR FILE_star[] = {'*','.','*', 0};
61 static const WCHAR FILE_bslash[] = {'\\', 0};
62 static const WCHAR FILE_specc[] = {'%','c',':', 0};
64 static HICON16 hFolder = 0;
65 static HICON16 hFolder2 = 0;
66 static HICON16 hFloppy = 0;
67 static HICON16 hHDisk = 0;
68 static HICON16 hCDRom = 0;
69 static HICON16 hNet = 0;
70 static int fldrHeight = 0;
71 static int fldrWidth = 0;
73 #define OFN_PROP "FILEDLG_OFN"
75 static const char defaultfilter[]=" \0\0";
76 static char defaultopen[]="Open File";
77 static char defaultsave[]="Save as";
79 /***********************************************************************
81 * Windows 3.1 style OpenFileName/SaveFileName dialog
85 LRESULT WINAPI FileOpenDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
87 LRESULT WINAPI FileSaveDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
90 static LRESULT WINAPI FileOpenDlgProc(HWND hDlg, UINT msg,
91 WPARAM wParam, LPARAM lParam);
93 /***********************************************************************
94 * FileDlg_Init [internal]
96 static BOOL FileDlg_Init(void)
98 static BOOL initialized = 0;
99 CURSORICONINFO *fldrInfo;
102 if (!hFolder) hFolder = LoadIcon16(0, MAKEINTRESOURCE16(OIC_FOLDER));
103 if (!hFolder2) hFolder2 = LoadIcon16(0, MAKEINTRESOURCE16(OIC_FOLDER2));
104 if (!hFloppy) hFloppy = LoadIcon16(0, MAKEINTRESOURCE16(OIC_FLOPPY));
105 if (!hHDisk) hHDisk = LoadIcon16(0, MAKEINTRESOURCE16(OIC_HDISK));
106 if (!hCDRom) hCDRom = LoadIcon16(0, MAKEINTRESOURCE16(OIC_CDROM));
107 if (!hNet) hNet = LoadIcon16(0, MAKEINTRESOURCE16(OIC_NETWORK));
108 if (hFolder == 0 || hFolder2 == 0 || hFloppy == 0 ||
109 hHDisk == 0 || hCDRom == 0 || hNet == 0)
111 ERR("Error loading icons !\n");
114 fldrInfo = (CURSORICONINFO *) GlobalLock16( hFolder2 );
117 ERR("Error measuring icons !\n");
120 fldrHeight = fldrInfo -> nHeight;
121 fldrWidth = fldrInfo -> nWidth;
122 GlobalUnlock16( hFolder2 );
129 /***********************************************************************
130 * Get32BitsTemplate [internal]
132 * Get a template (or FALSE if failure) when 16 bits dialogs are used
133 * by a 32 bits application
136 BOOL Get32BitsTemplate(LFSPRIVATE lfs)
138 LPOPENFILENAMEW ofnW = lfs->ofnW;
141 if (ofnW->Flags & OFN_ENABLETEMPLATEHANDLE)
143 if (!(lfs->template = LockResource( ofnW->hInstance )))
145 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
149 else if (ofnW->Flags & OFN_ENABLETEMPLATE)
153 hResInfo = FindResourceA(lfs->ofnA->hInstance,
154 lfs->ofnA->lpTemplateName,
157 hResInfo = FindResourceW(ofnW->hInstance,
158 ofnW->lpTemplateName,
162 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
165 if (!(hDlgTmpl = LoadResource(ofnW->hInstance,
167 !(lfs->template = LockResource(hDlgTmpl)))
169 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
172 } else { /* get it from internal Wine resource */
174 if (!(hResInfo = FindResourceA(COMMDLG_hInstance32,
175 lfs->open? "OPEN_FILE":"SAVE_FILE", RT_DIALOGA)))
177 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
180 if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
181 !(lfs->template = LockResource( hDlgTmpl )))
183 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
191 /***********************************************************************
192 * Get16BitsTemplate [internal]
194 * Get a template (FALSE if failure) when 16 bits dialogs are used
195 * by a 16 bits application
198 BOOL Get16BitsTemplate(LFSPRIVATE lfs)
200 LPOPENFILENAME16 ofn16 = lfs->ofn16;
202 HGLOBAL16 hGlobal16 = 0;
204 if (ofn16->Flags & OFN_ENABLETEMPLATEHANDLE)
205 lfs->hDlgTmpl16 = ofn16->hInstance;
206 else if (ofn16->Flags & OFN_ENABLETEMPLATE)
209 if (!(hResInfo = FindResource16(ofn16->hInstance,
210 ofn16->lpTemplateName,
213 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
216 if (!(lfs->hDlgTmpl16 = LoadResource16( ofn16->hInstance, hResInfo )))
218 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
221 lfs->hResource16 = lfs->hDlgTmpl16;
224 { /* get resource from (32 bits) own Wine resource; convert it to 16 */
225 HANDLE hResInfo, hDlgTmpl32;
229 if (!(hResInfo = FindResourceA(COMMDLG_hInstance32,
230 lfs->open ? "OPEN_FILE":"SAVE_FILE", RT_DIALOGA)))
232 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
235 if (!(hDlgTmpl32 = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
236 !(template32 = LockResource( hDlgTmpl32 )))
238 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
241 size = SizeofResource(GetModuleHandleA("COMDLG32"), hResInfo);
242 hGlobal16 = GlobalAlloc16(0, size);
245 COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE);
246 ERR("alloc failure for %ld bytes\n", size);
249 template = GlobalLock16(hGlobal16);
252 COMDLG32_SetCommDlgExtendedError(CDERR_MEMLOCKFAILURE);
253 ERR("global lock failure for %x handle\n", hGlobal16);
254 GlobalFree16(hGlobal16);
257 ConvertDialog32To16((LPVOID)template32, size, (LPVOID)template);
258 lfs->hDlgTmpl16 = hGlobal16;
259 lfs->hGlobal16 = hGlobal16;
264 /***********************************************************************
265 * FILEDLG_StripEditControl [internal]
266 * Strip pathnames off the contents of the edit control.
268 static void FILEDLG_StripEditControl(HWND hwnd)
270 WCHAR temp[BUFFILE], *cp;
272 GetDlgItemTextW( hwnd, edt1, temp, sizeof(temp) );
273 cp = strrchrW(temp, '\\');
277 cp = strrchrW(temp, ':');
281 /* FIXME: shouldn't we do something with the result here? ;-) */
286 /***********************************************************************
287 * FILEDLG_CallWindowProc [internal]
289 * Call the appropriate hook
291 static BOOL FILEDLG_CallWindowProc(LFSPRIVATE lfs, UINT wMsg, WPARAM wParam,
296 return (BOOL) CallWindowProc16(
297 (WNDPROC16)lfs->ofn16->lpfnHook, lfs->hwnd,
298 (UINT16)wMsg, (WPARAM16)wParam, lParam);
302 return (BOOL) CallWindowProcA(
303 (WNDPROC)lfs->ofnA->lpfnHook, lfs->hwnd,
304 wMsg, wParam, lParam);
309 return (BOOL) CallWindowProcW(
310 (WNDPROC)lfs->ofnW->lpfnHook, lfs->hwnd,
311 wMsg, wParam, lParam);
317 /***********************************************************************
318 * FILEDLG_ScanDir [internal]
320 static BOOL FILEDLG_ScanDir(HWND hWnd, LPWSTR newPath)
322 WCHAR buffer[BUFFILE];
325 lstrcpynW(buffer, newPath, sizeof(buffer));
327 if ( !SetCurrentDirectoryW( newPath ))
329 /* get the list of spec files */
330 GetDlgItemTextW(hWnd, edt1, buffer, sizeof(buffer));
332 if ((hdlg = GetDlgItem(hWnd, lst1)) != 0) {
333 WCHAR* scptr; /* ptr on semi-colon */
334 WCHAR* filter = buffer;
336 TRACE("Using filter %s\n", debugstr_w(filter));
337 SendMessageW(hdlg, LB_RESETCONTENT, 0, 0);
339 scptr = strchrW(filter, ';');
340 if (scptr) *scptr = 0;
341 TRACE("Using file spec %s\n", debugstr_w(filter));
342 if (SendMessageW(hdlg, LB_DIR, 0, (LPARAM)filter) == LB_ERR)
344 if (scptr) *scptr = ';';
345 filter = (scptr) ? (scptr + 1) : 0;
348 /* list of directories */
349 strcpyW(buffer, FILE_star);
350 return DlgDirListW(hWnd, buffer, lst2, stc1, DDL_EXCLUSIVE | DDL_DIRECTORY);
353 /***********************************************************************
354 * FILEDLG_GetFileType [internal]
357 static LPWSTR FILEDLG_GetFileType(LPWSTR cfptr, LPWSTR fptr, WORD index)
362 for ( ;(n = lstrlenW(cfptr)) != 0; i++)
367 cfptr += lstrlenW(cfptr) + 1;
370 for ( ;(n = lstrlenW(fptr)) != 0; i++)
375 fptr += lstrlenW(fptr) + 1;
377 return (LPWSTR) FILE_star; /* FIXME */
380 /***********************************************************************
381 * FILEDLG_WMDrawItem [internal]
383 static LONG FILEDLG_WMDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam,
384 int savedlg, LPDRAWITEMSTRUCT lpdis)
388 COLORREF oldText = 0, oldBk = 0;
390 if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst1)
392 if (!(str = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC))) return FALSE;
393 SendMessageW(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID,
396 if ((lpdis->itemState & ODS_SELECTED) && !savedlg)
398 oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
399 oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
402 SetTextColor(lpdis->hDC,GetSysColor(COLOR_GRAYTEXT) );
404 ExtTextOutW(lpdis->hDC, lpdis->rcItem.left + 1,
405 lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
406 &(lpdis->rcItem), str, lstrlenW(str), NULL);
408 if (lpdis->itemState & ODS_SELECTED)
409 DrawFocusRect( lpdis->hDC, &(lpdis->rcItem) );
411 if ((lpdis->itemState & ODS_SELECTED) && !savedlg)
413 SetBkColor( lpdis->hDC, oldBk );
414 SetTextColor( lpdis->hDC, oldText );
416 HeapFree(GetProcessHeap(), 0, str);
420 if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst2)
422 if (!(str = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC)))
424 SendMessageW(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID,
427 if (lpdis->itemState & ODS_SELECTED)
429 oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
430 oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
432 ExtTextOutW(lpdis->hDC, lpdis->rcItem.left + fldrWidth,
433 lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
434 &(lpdis->rcItem), str, lstrlenW(str), NULL);
436 if (lpdis->itemState & ODS_SELECTED)
437 DrawFocusRect( lpdis->hDC, &(lpdis->rcItem) );
439 if (lpdis->itemState & ODS_SELECTED)
441 SetBkColor( lpdis->hDC, oldBk );
442 SetTextColor( lpdis->hDC, oldText );
444 DrawIcon(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hFolder);
445 HeapFree(GetProcessHeap(), 0, str);
448 if (lpdis->CtlType == ODT_COMBOBOX && lpdis->CtlID == cmb2)
450 if (!(str = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC)))
452 SendMessageW(lpdis->hwndItem, CB_GETLBTEXT, lpdis->itemID,
454 switch(DRIVE_GetType( str[2] - 'a' ))
456 case TYPE_FLOPPY: hIcon = hFloppy; break;
457 case TYPE_CDROM: hIcon = hCDRom; break;
458 case TYPE_NETWORK: hIcon = hNet; break;
460 default: hIcon = hHDisk; break;
462 if (lpdis->itemState & ODS_SELECTED)
464 oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
465 oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
467 ExtTextOutW(lpdis->hDC, lpdis->rcItem.left + fldrWidth,
468 lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
469 &(lpdis->rcItem), str, lstrlenW(str), NULL);
471 if (lpdis->itemState & ODS_SELECTED)
473 SetBkColor( lpdis->hDC, oldBk );
474 SetTextColor( lpdis->hDC, oldText );
476 DrawIcon(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hIcon);
477 HeapFree(GetProcessHeap(), 0, str);
483 /***********************************************************************
484 * FILEDLG_WMMeasureItem [internal]
486 static LONG FILEDLG_WMMeasureItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
488 LPMEASUREITEMSTRUCT lpmeasure;
490 lpmeasure = (LPMEASUREITEMSTRUCT)lParam;
491 lpmeasure->itemHeight = fldrHeight;
495 /***********************************************************************
496 * FILEDLG_WMMeasureItem16 [internal]
498 static LONG FILEDLG_WMMeasureItem16(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam)
500 LPMEASUREITEMSTRUCT16 lpmeasure;
502 lpmeasure = (LPMEASUREITEMSTRUCT16)PTR_SEG_TO_LIN(lParam);
503 lpmeasure->itemHeight = fldrHeight;
507 /***********************************************************************
508 * FILEDLG_WMInitDialog [internal]
511 static LONG FILEDLG_WMInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam)
514 WCHAR tmpstr[BUFFILE];
515 LPWSTR pstr, old_pstr;
517 LFSPRIVATE lfs = (LFSPRIVATE) lParam;
519 if (!lfs) return FALSE;
520 SetPropA(hWnd, OFN_PROP, (HANDLE)lfs);
524 TRACE("flags=%lx initialdir=%s\n", ofn->Flags, debugstr_w(ofn->lpstrInitialDir));
526 SetWindowTextW( hWnd, ofn->lpstrTitle );
527 /* read custom filter information */
528 if (ofn->lpstrCustomFilter)
530 pstr = ofn->lpstrCustomFilter;
532 TRACE("lpstrCustomFilter = %p\n", pstr);
536 i = SendDlgItemMessageW(hWnd, cmb1, CB_ADDSTRING, 0,
537 (LPARAM)(ofn->lpstrCustomFilter) + n );
538 n += lstrlenW(pstr) + 1;
539 pstr += lstrlenW(pstr) + 1;
540 TRACE("add str='%s' "
541 "associated to '%s'\n", debugstr_w(old_pstr), debugstr_w(pstr));
542 SendDlgItemMessageW(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr);
543 n += lstrlenW(pstr) + 1;
544 pstr += lstrlenW(pstr) + 1;
547 /* read filter information */
548 if (ofn->lpstrFilter) {
549 pstr = (LPWSTR) ofn->lpstrFilter;
553 i = SendDlgItemMessageW(hWnd, cmb1, CB_ADDSTRING, 0,
554 (LPARAM)(ofn->lpstrFilter + n) );
555 n += lstrlenW(pstr) + 1;
556 pstr += lstrlenW(pstr) + 1;
557 TRACE("add str='%s' "
558 "associated to '%s'\n", debugstr_w(old_pstr), debugstr_w(pstr));
559 SendDlgItemMessageW(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr);
560 n += lstrlenW(pstr) + 1;
561 pstr += lstrlenW(pstr) + 1;
564 /* set default filter */
565 if (ofn->nFilterIndex == 0 && ofn->lpstrCustomFilter == NULL)
566 ofn->nFilterIndex = 1;
567 SendDlgItemMessageW(hWnd, cmb1, CB_SETCURSEL, ofn->nFilterIndex - 1, 0);
568 lstrcpynW(tmpstr, FILEDLG_GetFileType(ofn->lpstrCustomFilter,
569 (LPWSTR)ofn->lpstrFilter, ofn->nFilterIndex - 1),BUFFILE);
570 TRACE("nFilterIndex = %ld, SetText of edt1 to '%s'\n",
571 ofn->nFilterIndex, debugstr_w(tmpstr));
572 SetDlgItemTextW( hWnd, edt1, tmpstr );
575 DlgDirListComboBoxW(hWnd, tmpstr, cmb2, 0, DDL_DRIVES | DDL_EXCLUSIVE);
576 /* read initial directory */
577 if (ofn->lpstrInitialDir != NULL)
580 lstrcpynW(tmpstr, ofn->lpstrInitialDir, 511);
581 len = lstrlenW(tmpstr);
582 if (len > 0 && tmpstr[len-1] != '\\' && tmpstr[len-1] != ':') {
589 if (!FILEDLG_ScanDir(hWnd, tmpstr)) {
591 if (!FILEDLG_ScanDir(hWnd, tmpstr))
592 WARN("Couldn't read initial directory %s!\n", debugstr_w(tmpstr));
594 /* select current drive in combo 2, omit missing drives */
595 for(i = 0, n = -1; i <= DRIVE_GetCurrentDrive(); i++)
596 if (DRIVE_IsValid(i)) n++;
597 SendDlgItemMessageW(hWnd, cmb2, CB_SETCURSEL, n, 0);
598 if (!(ofn->Flags & OFN_SHOWHELP))
599 ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
600 if (ofn->Flags & OFN_HIDEREADONLY)
601 ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
603 return (BOOL) FILEDLG_CallWindowProc(lfs, WM_INITDIALOG, wParam, lfs->lParam);
607 /***********************************************************************
608 * FILEDLG_UpdateResult [internal]
609 * update the displayed file name (with path)
611 void FILEDLG_UpdateResult(LFSPRIVATE lfs, WCHAR *tmpstr, WCHAR *tmpstr2)
614 LPOPENFILENAMEW ofnW = lfs->ofnW;
616 GetCurrentDirectoryW(BUFFILE, tmpstr2);
617 lenstr2 = lstrlenW(tmpstr2);
619 tmpstr2[lenstr2++]='\\';
620 lstrcpynW(tmpstr2+lenstr2, tmpstr, BUFFILE-lenstr2);
622 lstrcpynW(ofnW->lpstrFile, tmpstr2, ofnW->nMaxFile);
623 ofnW->nFileOffset = strrchrW(tmpstr2,'\\') - tmpstr2 +1;
624 ofnW->nFileExtension = 0;
625 while(tmpstr2[ofnW->nFileExtension] != '.' && tmpstr2[ofnW->nFileExtension] != '\0')
626 ofnW->nFileExtension++;
627 if (tmpstr2[ofnW->nFileExtension] == '\0')
628 ofnW->nFileExtension = 0;
630 ofnW->nFileExtension++;
631 /* update the real client structures if any */
634 lstrcpynWtoA(PTR_SEG_TO_LIN(lfs->ofn16->lpstrFile), ofnW->lpstrFile, ofnW->nMaxFile);
635 lfs->ofn16->nFileOffset = ofnW->nFileOffset;
636 lfs->ofn16->nFileExtension = ofnW->nFileExtension;
640 lstrcpynWtoA(lfs->ofnA->lpstrFile, ofnW->lpstrFile, ofnW->nMaxFile);
641 lfs->ofnA->nFileOffset = ofnW->nFileOffset;
642 lfs->ofnA->nFileExtension = ofnW->nFileExtension;
647 /***********************************************************************
648 * FILEDLG_UpdateFileTitle [internal]
649 * update the displayed file name (without path)
651 void FILEDLG_UpdateFileTitle(LFSPRIVATE lfs)
654 LPOPENFILENAMEW ofnW = lfs->ofnW;
655 if (ofnW->lpstrFileTitle != NULL)
657 lRet = SendDlgItemMessageW(lfs->hwnd, lst1, LB_GETCURSEL, 0, 0);
658 SendDlgItemMessageW(lfs->hwnd, lst1, LB_GETTEXT, lRet,
659 (LPARAM)ofnW->lpstrFileTitle );
661 lstrcpynWtoA(PTR_SEG_TO_LIN(lfs->ofn16->lpstrFileTitle),ofnW->lpstrFileTitle,
662 ofnW->nMaxFileTitle);
664 lstrcpynWtoA(lfs->ofnA->lpstrFileTitle,ofnW->lpstrFileTitle,
665 ofnW->nMaxFileTitle);
669 /***********************************************************************
670 * FILEDLG_WMCommand [internal]
672 BOOL in_update=FALSE;
674 static LRESULT FILEDLG_WMCommand(HWND hWnd, LPARAM lParam, UINT notification,
675 UINT control, LFSPRIVATE lfs )
679 LPOPENFILENAMEW ofnW = lfs->ofnW;
680 WCHAR tmpstr[BUFFILE], tmpstr2[BUFFILE];
685 case lst1: /* file list */
686 FILEDLG_StripEditControl(hWnd);
687 if (notification == LBN_DBLCLK)
690 lRet = SendDlgItemMessageW(hWnd, lst1, LB_GETCURSEL16, 0, 0);
691 if (lRet == LB_ERR) return TRUE;
692 if ((pstr = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC)))
694 SendDlgItemMessageW(hWnd, lst1, LB_GETTEXT, lRet,
696 SetDlgItemTextW( hWnd, edt1, pstr );
697 HeapFree(GetProcessHeap(), 0, pstr);
700 FILEDLG_CallWindowProc(lfs, lfs->lbselchstring, control,
701 MAKELONG(lRet,CD_LBSELCHANGE));
702 /* FIXME: for OFN_ALLOWMULTISELECT we need CD_LBSELSUB, CD_SELADD, CD_LBSELNOITEMS */
705 case lst2: /* directory list */
706 FILEDLG_StripEditControl(hWnd);
707 if (notification == LBN_DBLCLK)
709 /* get the raw string (with brackets) */
710 lRet = SendDlgItemMessageW(hWnd, lst2, LB_GETCURSEL, 0, 0);
711 if (lRet == LB_ERR) return TRUE;
712 pstr = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC);
713 SendDlgItemMessageW(hWnd, lst2, LB_GETTEXT, lRet,
715 strcpyW( tmpstr, pstr );
716 HeapFree(GetProcessHeap(), 0, pstr);
717 /* get the selected directory in tmpstr */
718 if (tmpstr[0] == '[')
720 tmpstr[lstrlenW(tmpstr) - 1] = 0;
721 strcpyW(tmpstr,tmpstr+1);
723 strcatW(tmpstr, FILE_bslash);
724 /* directory *has* to be changed before notifying the hook */
725 SetCurrentDirectoryW( tmpstr );
729 if (FILEDLG_CallWindowProc(lfs, lfs->lbselchstring, control,
730 MAKELONG(lRet,CD_LBSELCHANGE)))
737 case cmb1: /* file type drop list */
738 if (notification == CBN_SELCHANGE)
750 case cmb2: /* disk drop list */
751 FILEDLG_StripEditControl(hWnd);
752 lRet = SendDlgItemMessageW(hWnd, cmb2, CB_GETCURSEL, 0, 0L);
753 if (lRet == LB_ERR) return 0;
754 pstr = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC);
755 SendDlgItemMessageW(hWnd, cmb2, CB_GETLBTEXT, lRet,
757 wsprintfW(tmpstr, FILE_specc, pstr[2]);
758 HeapFree(GetProcessHeap(), 0, pstr);
759 if (notification != CBN_SELCHANGE) return TRUE;
761 /* on entry tmpstr points to the new path to scan */
763 lRet = SendDlgItemMessageW(hWnd, cmb1, CB_GETCURSEL, 0, 0);
766 pstr = (LPWSTR)SendDlgItemMessageW(hWnd, cmb1, CB_GETITEMDATA, lRet, 0);
767 TRACE("Selected filter : %s\n", debugstr_w(pstr));
768 SetDlgItemTextW( hWnd, edt1, pstr );
769 FILEDLG_ScanDir(hWnd, tmpstr);
775 ofn2 = *ofnW; /* for later restoring */
776 /* get current file name */
777 GetDlgItemTextW( hWnd, edt1, tmpstr, sizeof(tmpstr) );
778 pstr = strrchrW(tmpstr, '\\');
780 pstr = strrchrW(tmpstr, ':');
782 if (strchrW(tmpstr,'*') != NULL || strchrW(tmpstr,'?') != NULL)
784 /* edit control contains wildcards */
787 lstrcpynW(tmpstr2, pstr+1, BUFFILE);
792 strcpyW(tmpstr2, tmpstr);
796 TRACE("tmpstr=%s, tmpstr2=%s\n", debugstr_w(tmpstr), debugstr_w(tmpstr2));
797 SetDlgItemTextW( hWnd, edt1, tmpstr2 );
798 FILEDLG_ScanDir(hWnd, tmpstr);
801 /* no wildcards, we might have a directory or a filename */
802 /* try appending a wildcard and reading the directory */
803 pstr2 = tmpstr + lstrlenW(tmpstr);
804 if (pstr == NULL || *(pstr+1) != 0)
805 strcatW(tmpstr, FILE_bslash);
806 lRet = SendDlgItemMessageW(hWnd, cmb1, CB_GETCURSEL, 0, 0);
807 if (lRet == LB_ERR) return TRUE;
808 ofnW->nFilterIndex = lRet + 1;
809 TRACE("ofn->nFilterIndex=%ld\n", ofnW->nFilterIndex);
811 FILEDLG_GetFileType(ofnW->lpstrCustomFilter,
812 (LPWSTR) ofnW->lpstrFilter,
813 lRet), sizeof(tmpstr2));
814 SetDlgItemTextW( hWnd, edt1, tmpstr2 );
818 /* if ScanDir succeeds, we have changed the directory */
819 if (FILEDLG_ScanDir(hWnd, tmpstr))
822 /* if not, this must be a filename */
823 *pstr2 = 0; /* remove the wildcard added before */
827 /* strip off the pathname */
829 SetDlgItemTextW( hWnd, edt1, pstr + 1 );
830 lstrcpynW(tmpstr2, pstr+1, sizeof(tmpstr2) );
831 /* Should we MessageBox() if this fails? */
832 if (!FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
833 strcpyW(tmpstr, tmpstr2);
835 else SetDlgItemTextW( hWnd, edt1, tmpstr );
836 FILEDLG_UpdateResult(lfs, tmpstr, tmpstr2);
840 FILEDLG_CallWindowProc(lfs, lfs->lbselchstring, control,
841 MAKELONG(lRet,CD_LBSELCHANGE));
845 FILEDLG_UpdateFileTitle(lfs);
848 lRet = (BOOL)FILEDLG_CallWindowProc(lfs, lfs->fileokstring,
852 *ofnW = ofn2; /* restore old state */
856 if ((ofnW->Flags & OFN_ALLOWMULTISELECT) && (ofnW->Flags & OFN_EXPLORER)) {
857 if (ofnW->lpstrFile) {
858 LPWSTR str = (LPWSTR)ofnW->lpstrFile;
859 LPWSTR ptr = strrchrW(str, '\\');
860 str[lstrlenW(str) + 1] = '\0';
864 EndDialog(hWnd, TRUE);
867 EndDialog(hWnd, FALSE);
869 case IDABORT: /* can be sent by the hook procedure */
870 EndDialog(hWnd, TRUE);
877 /***********************************************************************
878 * FILEDLG_MapDrawItemStruct [internal]
879 * map a 16 bits drawitem struct to 32
881 void FILEDLG_MapDrawItemStruct(LPDRAWITEMSTRUCT16 lpdis16, LPDRAWITEMSTRUCT lpdis)
883 lpdis->CtlType = lpdis16->CtlType;
884 lpdis->CtlID = lpdis16->CtlID;
885 lpdis->itemID = lpdis16->itemID;
886 lpdis->itemAction = lpdis16->itemAction;
887 lpdis->itemState = lpdis16->itemState;
888 lpdis->hwndItem = lpdis16->hwndItem;
889 lpdis->hDC = lpdis16->hDC;
890 lpdis->rcItem.right = lpdis16->rcItem.right;
891 lpdis->rcItem.left = lpdis16->rcItem.left;
892 lpdis->rcItem.top = lpdis16->rcItem.top;
893 lpdis->rcItem.bottom = lpdis16->rcItem.bottom;
894 lpdis->itemData = lpdis16->itemData;
897 /************************************************************************
898 * FILEDLG_MapStringPairsToW [internal]
899 * map string pairs to Unicode
901 LPWSTR FILEDLG_MapStringPairsToW(LPCSTR strA, UINT size)
912 if (n < size) n = size;
914 x = y = HeapAlloc(GetProcessHeap(),0, n * sizeof(WCHAR));
926 /************************************************************************
927 * FILEDLG_DupToW [internal]
928 * duplicates an Ansi string to unicode, with a buffer size
930 LPWSTR FILEDLG_DupToW(LPCSTR str, UINT size)
933 if (str && (size > 0))
935 strW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
936 lstrcpynAtoW(strW, str, size);
944 /************************************************************************
945 * FILEDLG_MapOfnStructA [internal]
946 * map a 32 bits Ansi structure to an Unicode one
948 void FILEDLG_MapOfnStructA(LPOPENFILENAMEA ofnA, LPOPENFILENAMEW ofnW, BOOL open)
952 ofnW->lStructSize = sizeof(OPENFILENAMEW);
953 ofnW->hwndOwner = ofnA->hwndOwner;
954 ofnW->hInstance = ofnA->hInstance;
955 if (ofnA->lpstrFilter)
956 ofnW->lpstrFilter = FILEDLG_MapStringPairsToW(ofnA->lpstrFilter, 0);
958 ofnW->lpstrFilter = FILEDLG_MapStringPairsToW(defaultfilter, 0);
960 if ((ofnA->lpstrCustomFilter) && (*(ofnA->lpstrCustomFilter)))
961 ofnW->lpstrCustomFilter = FILEDLG_MapStringPairsToW(ofnA->lpstrCustomFilter, ofnA->nMaxCustFilter);
962 ofnW->nMaxCustFilter = ofnA->nMaxCustFilter;
963 ofnW->nFilterIndex = ofnA->nFilterIndex;
964 ofnW->lpstrFile = FILEDLG_DupToW(ofnA->lpstrFile, ofnA->nMaxFile);
965 ofnW->nMaxFile = ofnA->nMaxFile;
966 ofnW->lpstrFileTitle = FILEDLG_DupToW(ofnA->lpstrFileTitle, ofnA->nMaxFileTitle);
967 ofnW->nMaxFileTitle = ofnA->nMaxFileTitle;
968 if (ofnA->lpstrInitialDir)
969 ofnW->lpstrInitialDir = HEAP_strdupAtoW(GetProcessHeap(),0,ofnA->lpstrInitialDir);
970 if (ofnA->lpstrTitle)
971 str = ofnA->lpstrTitle;
973 /* Allocates default title (FIXME : get it from resource) */
974 str = open ? defaultopen:defaultsave;
975 ofnW->lpstrTitle = HEAP_strdupAtoW(GetProcessHeap(),0, str);
976 ofnW->Flags = ofnA->Flags;
977 ofnW->nFileOffset = ofnA->nFileOffset;
978 ofnW->nFileExtension = ofnA->nFileExtension;
979 ofnW->lpstrDefExt = FILEDLG_DupToW(ofnA->lpstrDefExt, 3);
980 if ((ofnA->Flags & OFN_ENABLETEMPLATE) && (ofnA->lpTemplateName))
982 if (HIWORD(ofnA->lpTemplateName))
983 ofnW->lpTemplateName = HEAP_strdupAtoW(GetProcessHeap(), 0, ofnA->lpTemplateName);
984 else /* numbered resource */
985 ofnW->lpTemplateName = (LPWSTR) ofnA->lpTemplateName;
990 /************************************************************************
991 * FILEDLG_MapOfnStruct16 [internal]
992 * map a 16 bits structure to an Unicode one
994 void FILEDLG_MapOfnStruct16(LPOPENFILENAME16 ofn16, LPOPENFILENAMEW ofnW, BOOL open)
997 /* first convert to linear pointers */
998 memset(&ofnA, 0, sizeof(OPENFILENAMEA));
999 ofnA.lStructSize = sizeof(OPENFILENAMEA);
1000 ofnA.hwndOwner = ofn16->hwndOwner;
1001 ofnA.hInstance = ofn16->hInstance;
1002 if (ofn16->lpstrFilter)
1003 ofnA.lpstrFilter = PTR_SEG_TO_LIN(ofn16->lpstrFilter);
1004 if (ofn16->lpstrCustomFilter)
1005 ofnA.lpstrCustomFilter = PTR_SEG_TO_LIN(ofn16->lpstrCustomFilter);
1006 ofnA.nMaxCustFilter = ofn16->nMaxCustFilter;
1007 ofnA.nFilterIndex = ofn16->nFilterIndex;
1008 ofnA.lpstrFile = PTR_SEG_TO_LIN(ofn16->lpstrFile);
1009 ofnA.nMaxFile = ofn16->nMaxFile;
1010 ofnA.lpstrFileTitle = PTR_SEG_TO_LIN(ofn16->lpstrFileTitle);
1011 ofnA.nMaxFileTitle = ofn16->nMaxFileTitle;
1012 ofnA.lpstrInitialDir = PTR_SEG_TO_LIN(ofn16->lpstrInitialDir);
1013 ofnA.lpstrTitle = PTR_SEG_TO_LIN(ofn16->lpstrTitle);
1014 ofnA.Flags = ofn16->Flags;
1015 ofnA.nFileOffset = ofn16->nFileOffset;
1016 ofnA.nFileExtension = ofn16->nFileExtension;
1017 ofnA.lpstrDefExt = PTR_SEG_TO_LIN(ofn16->lpstrDefExt);
1018 if (HIWORD(ofn16->lpTemplateName))
1019 ofnA.lpTemplateName = PTR_SEG_TO_LIN(ofn16->lpTemplateName);
1021 ofnA.lpTemplateName = (LPSTR) ofn16->lpTemplateName; /* ressource number */
1022 /* now calls the 32 bits Ansi to Unicode version to complete the job */
1023 FILEDLG_MapOfnStructA(&ofnA, ofnW, open);
1027 /************************************************************************
1028 * FILEDLG_DestroyPrivate [internal]
1029 * destroys the private object
1031 void FILEDLG_DestroyPrivate(LFSPRIVATE lfs)
1036 /* free resources for a 16 bits dialog */
1037 if (lfs->hResource16) FreeResource16(lfs->hResource16);
1040 GlobalUnlock16(lfs->hGlobal16);
1041 GlobalFree16(lfs->hGlobal16);
1043 /* if ofnW has been allocated, have to free everything in it */
1044 if (lfs->ofn16 || lfs->ofnA)
1046 LPOPENFILENAMEW ofnW = lfs->ofnW;
1047 if (ofnW->lpstrFilter) HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpstrFilter);
1048 if (ofnW->lpstrCustomFilter) HeapFree(GetProcessHeap(), 0, ofnW->lpstrCustomFilter);
1049 if (ofnW->lpstrFile) HeapFree(GetProcessHeap(), 0, ofnW->lpstrFile);
1050 if (ofnW->lpstrFileTitle) HeapFree(GetProcessHeap(), 0, ofnW->lpstrFileTitle);
1051 if (ofnW->lpstrInitialDir) HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpstrInitialDir);
1052 if (ofnW->lpstrTitle) HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpstrTitle);
1053 if ((ofnW->lpTemplateName) && (HIWORD(ofnW->lpTemplateName)))
1054 HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpTemplateName);
1055 HeapFree(GetProcessHeap(), 0, ofnW);
1057 TRACE("destroying private allocation %p\n", lfs);
1058 HeapFree(GetProcessHeap(), 0, lfs);
1059 RemovePropA(hwnd, OFN_PROP);
1062 /************************************************************************
1063 * FILEDLG_AllocPrivate [internal]
1064 * allocate a private object to hold 32 bits Unicode
1065 * structure that will be used throughtout the calls, while
1066 * keeping available the original structures and a few variables
1067 * On entry : type = dialog procedure type (16,32A,32W)
1068 * dlgType = dialog type (open or save)
1070 LFSPRIVATE FILEDLG_AllocPrivate(LPARAM lParam, int type, UINT dlgType)
1072 LFSPRIVATE lfs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct FSPRIVATE));
1074 TRACE("alloc private buf %p\n", lfs);
1075 if (!lfs) return NULL;
1077 lfs->lParam = lParam;
1078 if (dlgType == OPEN_DIALOG)
1082 lfs->lbselchstring = RegisterWindowMessageA(LBSELCHSTRING);
1083 lfs->fileokstring = RegisterWindowMessageA(FILEOKSTRING);
1087 lfs->ofn16 = (LPOPENFILENAME16) PTR_SEG_TO_LIN(lParam);
1088 if (lfs->ofn16->Flags & OFN_ENABLEHOOK)
1089 if (lfs->ofn16->lpfnHook)
1095 lfs->ofnA = (LPOPENFILENAMEA) lParam;
1096 if (lfs->ofnA->Flags & OFN_ENABLEHOOK)
1097 if (lfs->ofnA->lpfnHook)
1102 lfs->ofnW = (LPOPENFILENAMEW) lParam;
1103 if (lfs->ofnW->Flags & OFN_ENABLEHOOK)
1104 if (lfs->ofnW->lpfnHook)
1110 { /* this structure is needed internally, so create it */
1111 lfs->ofnW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(OPENFILENAMEW));
1115 FILEDLG_MapOfnStruct16(lfs->ofn16, lfs->ofnW, lfs->open);
1117 FILEDLG_MapOfnStructA(lfs->ofnA, lfs->ofnW, lfs->open);
1124 if (!Get16BitsTemplate(lfs)) ret = NULL;
1127 if (!Get32BitsTemplate(lfs)) ret = NULL;
1128 if (!ret) FILEDLG_DestroyPrivate(lfs);
1133 /***********************************************************************
1134 * GetFileName31A [internal]
1136 * Creates a win31 style dialog box for the user to select a file to open/save.
1138 BOOL WINAPI GetFileName31A(
1139 LPOPENFILENAMEA lpofn, /* addess of structure with data*/
1140 UINT dlgType /* type dialogue : open/save */
1147 if (!lpofn || !FileDlg_Init()) return FALSE;
1149 lfs = FILEDLG_AllocPrivate((LPARAM) lpofn, LFS32A, dlgType);
1152 hInst = GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );
1153 bRet = DialogBoxIndirectParamA( hInst, lfs->template, lpofn->hwndOwner,
1154 (DLGPROC) FileOpenDlgProc, (DWORD) lfs);
1155 FILEDLG_DestroyPrivate(lfs);
1158 TRACE("return lpstrFile='%s' !\n", lpofn->lpstrFile);
1163 /***********************************************************************
1164 * GetFileName31W [internal]
1166 * Creates a win31 style dialog box for the user to select a file to open/save
1168 BOOL WINAPI GetFileName31W(
1169 LPOPENFILENAMEW lpofn, /* addess of structure with data*/
1170 UINT dlgType /* type dialogue : open/save */
1177 if (!lpofn || !FileDlg_Init()) return FALSE;
1179 lfs = FILEDLG_AllocPrivate((LPARAM) lpofn, LFS32W, dlgType);
1182 hInst = GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );
1183 bRet = DialogBoxIndirectParamW( hInst, lfs->template, lpofn->hwndOwner,
1184 (DLGPROC) FileOpenDlgProc, (DWORD) lfs);
1185 FILEDLG_DestroyPrivate(lfs);
1188 TRACE("return lpstrFile='%s' !\n", debugstr_w(lpofn->lpstrFile));
1193 /* ------------------ Dialog procedures ---------------------- */
1195 /***********************************************************************
1196 * FileOpenDlgProc16 (COMMDLG.6)
1198 LRESULT WINAPI FileOpenDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1201 LFSPRIVATE lfs = (LFSPRIVATE)GetPropA(hWnd,OFN_PROP);
1204 TRACE("msg=%x wparam=%x lParam=%lx\n", wMsg, wParam, lParam);
1205 if ((wMsg != WM_INITDIALOG) && lfs && lfs->hook)
1207 LRESULT lRet = (BOOL16)FILEDLG_CallWindowProc(lfs, wMsg, wParam, lParam);
1209 return lRet; /* else continue message processing */
1214 return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
1216 case WM_MEASUREITEM:
1217 return FILEDLG_WMMeasureItem16(hWnd, wParam, lParam);
1220 FILEDLG_MapDrawItemStruct((LPDRAWITEMSTRUCT16)PTR_SEG_TO_LIN(lParam), &dis);
1221 return FILEDLG_WMDrawItem(hWnd, wParam, lParam, FALSE, &dis);
1224 return FILEDLG_WMCommand(hWnd, lParam, HIWORD(lParam),wParam, lfs);
1227 SetBkColor((HDC16)wParam, 0x00C0C0C0);
1228 switch (HIWORD(lParam))
1231 SetTextColor((HDC16)wParam, 0x00000000);
1233 case CTLCOLOR_STATIC:
1234 SetTextColor((HDC16)wParam, 0x00000000);
1243 /***********************************************************************
1244 * FileSaveDlgProc16 (COMMDLG.7)
1246 LRESULT WINAPI FileSaveDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1249 LFSPRIVATE lfs = (LFSPRIVATE)GetPropA(hWnd,OFN_PROP);
1252 TRACE("msg=%x wparam=%x lParam=%lx\n", wMsg, wParam, lParam);
1253 if ((wMsg != WM_INITDIALOG) && lfs && lfs->hook)
1256 lRet = (BOOL16)FILEDLG_CallWindowProc(lfs, wMsg, wParam, lParam);
1258 return lRet; /* else continue message processing */
1262 return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
1264 case WM_MEASUREITEM:
1265 return FILEDLG_WMMeasureItem16(hWnd, wParam, lParam);
1268 FILEDLG_MapDrawItemStruct((LPDRAWITEMSTRUCT16)PTR_SEG_TO_LIN(lParam), &dis);
1269 return FILEDLG_WMDrawItem(hWnd, wParam, lParam, TRUE, &dis);
1272 return FILEDLG_WMCommand(hWnd, lParam, HIWORD(lParam), wParam, lfs);
1277 SetBkColor((HDC16)wParam, 0x00C0C0C0);
1278 switch (HIWORD(lParam))
1281 SetTextColor((HDC16)wParam, 0x00000000);
1283 case CTLCOLOR_STATIC:
1284 SetTextColor((HDC16)wParam, 0x00000000);
1293 /***********************************************************************
1294 * FileOpenDlgProc [internal]
1295 * Used for open and save, in fact.
1297 static LRESULT WINAPI FileOpenDlgProc(HWND hWnd, UINT wMsg,
1298 WPARAM wParam, LPARAM lParam)
1300 LFSPRIVATE lfs = (LFSPRIVATE)GetPropA(hWnd,OFN_PROP);
1302 TRACE("msg=%x wparam=%x lParam=%lx\n", wMsg, wParam, lParam);
1303 if ((wMsg != WM_INITDIALOG) && lfs && lfs->hook)
1306 lRet = (BOOL)FILEDLG_CallWindowProc(lfs, wMsg, wParam, lParam);
1308 return lRet; /* else continue message processing */
1313 return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
1315 case WM_MEASUREITEM:
1316 return FILEDLG_WMMeasureItem(hWnd, wParam, lParam);
1319 return FILEDLG_WMDrawItem(hWnd, wParam, lParam, !lfs->open, (DRAWITEMSTRUCT *)lParam);
1322 return FILEDLG_WMCommand(hWnd, lParam, HIWORD(wParam), LOWORD(wParam), lfs);
1325 SetBkColor((HDC16)wParam, 0x00C0C0C0);
1326 switch (HIWORD(lParam))
1329 SetTextColor((HDC16)wParam, 0x00000000);
1331 case CTLCOLOR_STATIC:
1332 SetTextColor((HDC16)wParam, 0x00000000);
1341 /* ------------------ APIs ---------------------- */
1343 /***********************************************************************
1344 * GetOpenFileName16 (COMMDLG.1)
1346 * Creates a dialog box for the user to select a file to open.
1349 * TRUE on success: user selected a valid file
1350 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1353 * unknown, there are some FIXME's left.
1355 BOOL16 WINAPI GetOpenFileName16(
1356 SEGPTR ofn /* addess of structure with data*/
1361 LPOPENFILENAME16 lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(ofn);
1365 if (!lpofn || !FileDlg_Init()) return FALSE;
1367 lfs = FILEDLG_AllocPrivate((LPARAM) ofn, LFS16, OPEN_DIALOG);
1370 hInst = GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );
1371 ptr = GetProcAddress16(GetModuleHandle16("COMMDLG"), (SEGPTR) 6);
1372 bRet = DialogBoxIndirectParam16( hInst, lfs->hDlgTmpl16, lpofn->hwndOwner,
1373 (DLGPROC16) ptr, (DWORD) lfs);
1374 FILEDLG_DestroyPrivate(lfs);
1377 TRACE("return lpstrFile='%s' !\n",
1378 (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
1382 /***********************************************************************
1383 * GetSaveFileName16 (COMMDLG.2)
1385 * Creates a dialog box for the user to select a file to save.
1388 * TRUE on success: user enters a valid file
1389 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1392 * unknown. There are some FIXME's left.
1394 BOOL16 WINAPI GetSaveFileName16(
1395 SEGPTR ofn /* addess of structure with data*/
1400 LPOPENFILENAME16 lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(ofn);
1404 if (!lpofn || !FileDlg_Init()) return FALSE;
1406 lfs = FILEDLG_AllocPrivate((LPARAM) ofn, LFS16, SAVE_DIALOG);
1409 hInst = GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );
1410 ptr = GetProcAddress16(GetModuleHandle16("COMMDLG"), (SEGPTR) 7);
1411 bRet = DialogBoxIndirectParam16( hInst, lfs->hDlgTmpl16, lpofn->hwndOwner,
1412 (DLGPROC16) ptr, (DWORD) lfs);
1413 FILEDLG_DestroyPrivate(lfs);
1416 TRACE("return lpstrFile='%s' !\n",
1417 (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
1421 /***********************************************************************
1422 * GetOpenFileNameA (COMDLG32.10)
1424 * Creates a dialog box for the user to select a file to open.
1427 * TRUE on success: user enters a valid file
1428 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1431 BOOL WINAPI GetOpenFileNameA(
1432 LPOPENFILENAMEA ofn) /* address of init structure */
1436 /* some flags don't allow to match the TWEAK_WineLook */
1437 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
1439 newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
1443 /* no special flags set, we can match the TWEAK_WineLook */
1444 newlook = (TWEAK_WineLook>WIN31_LOOK) ? TRUE : FALSE;
1449 return GetFileDialog95A(ofn, OPEN_DIALOG);
1453 return GetFileName31A(ofn, OPEN_DIALOG);
1457 /***********************************************************************
1458 * GetOpenFileNameW (COMDLG32.11)
1460 * Creates a dialog box for the user to select a file to open.
1463 * TRUE on success: user enters a valid file
1464 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1467 BOOL WINAPI GetOpenFileNameW(
1468 LPOPENFILENAMEW ofn) /* address of init structure */
1472 /* some flags don't allow to match the TWEAK_WineLook */
1473 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
1475 newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
1479 /* no special flags set, we can match the TWEAK_WineLook */
1480 newlook = (TWEAK_WineLook>WIN31_LOOK) ? TRUE : FALSE;
1485 return GetFileDialog95W(ofn, OPEN_DIALOG);
1489 return GetFileName31W(ofn, OPEN_DIALOG);
1493 /***********************************************************************
1494 * GetSaveFileNameA (COMDLG32.12)
1496 * Creates a dialog box for the user to select a file to save.
1499 * TRUE on success: user enters a valid file
1500 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1503 BOOL WINAPI GetSaveFileNameA(
1504 LPOPENFILENAMEA ofn) /* address of init structure */
1508 /* some flags don't allow to match the TWEAK_WineLook */
1509 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
1511 newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
1515 /* no special flags set, we can match the TWEAK_WineLook */
1516 newlook = (TWEAK_WineLook>WIN31_LOOK) ? TRUE : FALSE;
1521 return GetFileDialog95A(ofn, SAVE_DIALOG);
1525 return GetFileName31A(ofn, SAVE_DIALOG);
1529 /***********************************************************************
1530 * GetSaveFileNameW (COMDLG32.13)
1532 * Creates a dialog box for the user to select a file to save.
1535 * TRUE on success: user enters a valid file
1536 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1539 BOOL WINAPI GetSaveFileNameW(
1540 LPOPENFILENAMEW ofn) /* address of init structure */
1544 /* some flags don't allow to match the TWEAK_WineLook */
1545 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
1547 newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
1551 /* no special flags set, we can match the TWEAK_WineLook */
1552 newlook = (TWEAK_WineLook>WIN31_LOOK) ? TRUE : FALSE;
1557 return GetFileDialog95W(ofn, SAVE_DIALOG);
1561 return GetFileName31W(ofn, SAVE_DIALOG);