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"
17 #include "wine/winestring.h"
23 #include "debugtools.h"
27 DEFAULT_DEBUG_CHANNEL(commdlg);
32 #define BUFFILEALLOC 512 * sizeof(WCHAR)
36 HWND hwnd; /* file dialog window handle */
37 BOOL hook; /* TRUE if the dialog is hooked */
38 UINT lbselchstring; /* registered message id */
39 UINT fileokstring; /* registered message id */
40 LPARAM lParam; /* save original lparam */
41 HANDLE16 hDlgTmpl16; /* handle for resource 16 */
42 HANDLE16 hResource16; /* handle for allocated resource 16 */
43 HANDLE16 hGlobal16; /* 16 bits mem block (resources) */
44 LPCVOID template; /* template for 32 bits resource */
45 BOOL open; /* TRUE if open dialog, FALSE if save dialog */
46 OPENFILENAMEW *ofnW; /* original structure or work struct */
47 OPENFILENAMEA *ofnA; /* original structure if 32bits ansi dialog */
48 OPENFILENAME16 *ofn16; /* original structure if 16 bits dialog */
52 #define LFSPRIVATE struct FSPRIVATE *
58 static const WCHAR FILE_star[] = {'*','.','*', 0};
59 static const WCHAR FILE_bslash[] = {'\\', 0};
60 static const WCHAR FILE_specc[] = {'%','c',':', 0};
62 static HICON16 hFolder = 0;
63 static HICON16 hFolder2 = 0;
64 static HICON16 hFloppy = 0;
65 static HICON16 hHDisk = 0;
66 static HICON16 hCDRom = 0;
67 static HICON16 hNet = 0;
68 static int fldrHeight = 0;
69 static int fldrWidth = 0;
71 #define OFN_PROP "FILEDLG_OFN"
73 static const char defaultfilter[]=" \0\0";
74 static char defaultopen[]="Open File";
75 static char defaultsave[]="Save as";
77 /***********************************************************************
79 * Windows 3.1 style OpenFileName/SaveFileName dialog
83 LRESULT WINAPI FileOpenDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
85 LRESULT WINAPI FileSaveDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
88 static LRESULT WINAPI FileOpenDlgProc(HWND hDlg, UINT msg,
89 WPARAM wParam, LPARAM lParam);
91 /***********************************************************************
92 * FileDlg_Init [internal]
94 static BOOL FileDlg_Init(void)
96 static BOOL initialized = 0;
97 CURSORICONINFO *fldrInfo;
100 if (!hFolder) hFolder = LoadIcon16(0, MAKEINTRESOURCE16(OIC_FOLDER));
101 if (!hFolder2) hFolder2 = LoadIcon16(0, MAKEINTRESOURCE16(OIC_FOLDER2));
102 if (!hFloppy) hFloppy = LoadIcon16(0, MAKEINTRESOURCE16(OIC_FLOPPY));
103 if (!hHDisk) hHDisk = LoadIcon16(0, MAKEINTRESOURCE16(OIC_HDISK));
104 if (!hCDRom) hCDRom = LoadIcon16(0, MAKEINTRESOURCE16(OIC_CDROM));
105 if (!hNet) hNet = LoadIcon16(0, MAKEINTRESOURCE16(OIC_NETWORK));
106 if (hFolder == 0 || hFolder2 == 0 || hFloppy == 0 ||
107 hHDisk == 0 || hCDRom == 0 || hNet == 0)
109 ERR("Error loading icons !\n");
112 fldrInfo = (CURSORICONINFO *) GlobalLock16( hFolder2 );
115 ERR("Error measuring icons !\n");
118 fldrHeight = fldrInfo -> nHeight;
119 fldrWidth = fldrInfo -> nWidth;
120 GlobalUnlock16( hFolder2 );
127 /***********************************************************************
128 * Get32BitsTemplate [internal]
130 * Get a template (or FALSE if failure) when 16 bits dialogs are used
131 * by a 32 bits application
134 BOOL Get32BitsTemplate(LFSPRIVATE lfs)
136 LPOPENFILENAMEW ofnW = lfs->ofnW;
139 if (ofnW->Flags & OFN_ENABLETEMPLATEHANDLE)
141 if (!(lfs->template = LockResource( ofnW->hInstance )))
143 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
147 else if (ofnW->Flags & OFN_ENABLETEMPLATE)
151 hResInfo = FindResourceA(lfs->ofnA->hInstance,
152 lfs->ofnA->lpTemplateName,
155 hResInfo = FindResourceW(ofnW->hInstance,
156 ofnW->lpTemplateName,
160 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
163 if (!(hDlgTmpl = LoadResource(ofnW->hInstance,
165 !(lfs->template = LockResource(hDlgTmpl)))
167 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
170 } else { /* get it from internal Wine resource */
172 if (!(hResInfo = FindResourceA(COMMDLG_hInstance32,
173 lfs->open? "OPEN_FILE":"SAVE_FILE", RT_DIALOGA)))
175 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
178 if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
179 !(lfs->template = LockResource( hDlgTmpl )))
181 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
189 /***********************************************************************
190 * Get16BitsTemplate [internal]
192 * Get a template (FALSE if failure) when 16 bits dialogs are used
193 * by a 16 bits application
196 BOOL Get16BitsTemplate(LFSPRIVATE lfs)
198 LPOPENFILENAME16 ofn16 = lfs->ofn16;
200 HGLOBAL16 hGlobal16 = 0;
202 if (ofn16->Flags & OFN_ENABLETEMPLATEHANDLE)
203 lfs->hDlgTmpl16 = ofn16->hInstance;
204 else if (ofn16->Flags & OFN_ENABLETEMPLATE)
207 if (!(hResInfo = FindResource16(ofn16->hInstance,
208 ofn16->lpTemplateName,
211 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
214 if (!(lfs->hDlgTmpl16 = LoadResource16( ofn16->hInstance, hResInfo )))
216 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
219 lfs->hResource16 = lfs->hDlgTmpl16;
222 { /* get resource from (32 bits) own Wine resource; convert it to 16 */
223 HANDLE hResInfo, hDlgTmpl32;
227 if (!(hResInfo = FindResourceA(COMMDLG_hInstance32,
228 lfs->open ? "OPEN_FILE":"SAVE_FILE", RT_DIALOGA)))
230 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
233 if (!(hDlgTmpl32 = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
234 !(template32 = LockResource( hDlgTmpl32 )))
236 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
239 size = SizeofResource(GetModuleHandleA("COMDLG32"), hResInfo);
240 hGlobal16 = GlobalAlloc16(0, size);
243 COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE);
244 ERR("alloc failure for %ld bytes\n", size);
247 template = GlobalLock16(hGlobal16);
250 COMDLG32_SetCommDlgExtendedError(CDERR_MEMLOCKFAILURE);
251 ERR("global lock failure for %x handle\n", hGlobal16);
252 GlobalFree16(hGlobal16);
255 ConvertDialog32To16((LPVOID)template32, size, (LPVOID)template);
256 lfs->hDlgTmpl16 = hGlobal16;
257 lfs->hGlobal16 = hGlobal16;
262 /***********************************************************************
263 * FILEDLG_StripEditControl [internal]
264 * Strip pathnames off the contents of the edit control.
266 static void FILEDLG_StripEditControl(HWND hwnd)
268 WCHAR temp[BUFFILE], *cp;
270 GetDlgItemTextW( hwnd, edt1, temp, sizeof(temp) );
271 cp = strrchrW(temp, '\\');
275 cp = strrchrW(temp, ':');
279 /* FIXME: shouldn't we do something with the result here? ;-) */
284 /***********************************************************************
285 * FILEDLG_CallWindowProc [internal]
287 * Call the appropriate hook
289 static BOOL FILEDLG_CallWindowProc(LFSPRIVATE lfs, UINT wMsg, WPARAM wParam,
294 return (BOOL16) CallWindowProc16(
295 (WNDPROC16)lfs->ofn16->lpfnHook, lfs->hwnd,
296 (UINT16)wMsg, (WPARAM16)wParam, lParam);
300 return (BOOL) CallWindowProcA(
301 (WNDPROC)lfs->ofnA->lpfnHook, lfs->hwnd,
302 wMsg, wParam, lParam);
307 return (BOOL) CallWindowProcW(
308 (WNDPROC)lfs->ofnW->lpfnHook, lfs->hwnd,
309 wMsg, wParam, lParam);
315 /***********************************************************************
316 * FILEDLG_ScanDir [internal]
318 static BOOL FILEDLG_ScanDir(HWND hWnd, LPWSTR newPath, BOOL bChgDir)
320 WCHAR buffer[BUFFILE];
324 if ( !SetCurrentDirectoryW( newPath ))
326 lstrcpynW(buffer, newPath, sizeof(buffer));
327 /* get the list of spec files */
328 GetDlgItemTextW(hWnd, edt1, buffer, sizeof(buffer));
330 if ((hdlg = GetDlgItem(hWnd, lst1)) != 0) {
331 WCHAR* scptr; /* ptr on semi-colon */
332 WCHAR* filter = buffer;
334 TRACE("Using filter %s\n", debugstr_w(filter));
335 SendMessageW(hdlg, LB_RESETCONTENT, 0, 0);
337 scptr = strchrW(filter, ';');
338 if (scptr) *scptr = 0;
339 while (*filter == ' ') filter++;
340 TRACE("Using file spec %s\n", debugstr_w(filter));
341 if (SendMessageW(hdlg, LB_DIR, 0, (LPARAM)filter) == LB_ERR)
343 if (scptr) *scptr = ';';
344 filter = (scptr) ? (scptr + 1) : 0;
347 /* list of directories */
348 strcpyW(buffer, FILE_star);
349 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, TRUE)) {
591 if (!FILEDLG_ScanDir(hWnd, tmpstr, TRUE))
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);
671 /***********************************************************************
672 * FILEDLG_DirListDblClick [internal]
674 static LRESULT FILEDLG_DirListDblClick(HWND hWnd, LFSPRIVATE lfs)
678 WCHAR tmpstr[BUFFILE];
680 /* get the raw string (with brackets) */
681 lRet = SendDlgItemMessageW(hWnd, lst2, LB_GETCURSEL, 0, 0);
682 if (lRet == LB_ERR) return TRUE;
683 pstr = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC);
684 SendDlgItemMessageW(hWnd, lst2, LB_GETTEXT, lRet,
686 strcpyW( tmpstr, pstr );
687 HeapFree(GetProcessHeap(), 0, pstr);
688 /* get the selected directory in tmpstr */
689 if (tmpstr[0] == '[')
691 tmpstr[lstrlenW(tmpstr) - 1] = 0;
692 strcpyW(tmpstr,tmpstr+1);
694 strcatW(tmpstr, FILE_bslash);
696 /* directory *has* to be changed before notifying the hook */
697 SetCurrentDirectoryW( tmpstr );
701 if (FILEDLG_CallWindowProc(lfs, lfs->lbselchstring, lst2,
702 MAKELONG(lRet,CD_LBSELCHANGE)))
706 lRet = SendDlgItemMessageW(hWnd, cmb1, CB_GETCURSEL, 0, 0);
709 pstr = (LPWSTR)SendDlgItemMessageW(hWnd, cmb1, CB_GETITEMDATA, lRet, 0);
710 TRACE("Selected filter : %s\n", debugstr_w(pstr));
711 SetDlgItemTextW( hWnd, edt1, pstr );
713 FILEDLG_ScanDir(hWnd, tmpstr, FALSE);
717 /***********************************************************************
718 * FILEDLG_WMCommand [internal]
720 BOOL in_update=FALSE;
722 static LRESULT FILEDLG_WMCommand(HWND hWnd, LPARAM lParam, UINT notification,
723 UINT control, LFSPRIVATE lfs )
727 LPOPENFILENAMEW ofnW = lfs->ofnW;
728 WCHAR tmpstr[BUFFILE], tmpstr2[BUFFILE];
733 case lst1: /* file list */
734 FILEDLG_StripEditControl(hWnd);
735 if (notification == LBN_DBLCLK)
738 lRet = SendDlgItemMessageW(hWnd, lst1, LB_GETCURSEL16, 0, 0);
739 if (lRet == LB_ERR) return TRUE;
740 if ((pstr = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC)))
742 SendDlgItemMessageW(hWnd, lst1, LB_GETTEXT, lRet,
744 SetDlgItemTextW( hWnd, edt1, pstr );
745 HeapFree(GetProcessHeap(), 0, pstr);
748 FILEDLG_CallWindowProc(lfs, lfs->lbselchstring, control,
749 MAKELONG(lRet,CD_LBSELCHANGE));
750 /* FIXME: for OFN_ALLOWMULTISELECT we need CD_LBSELSUB, CD_SELADD, CD_LBSELNOITEMS */
753 case lst2: /* directory list */
754 FILEDLG_StripEditControl(hWnd);
755 if (notification == LBN_DBLCLK)
757 return FILEDLG_DirListDblClick(hWnd, lfs);
761 case cmb1: /* file type drop list */
762 if (notification == CBN_SELCHANGE)
774 case cmb2: /* disk drop list */
775 FILEDLG_StripEditControl(hWnd);
776 lRet = SendDlgItemMessageW(hWnd, cmb2, CB_GETCURSEL, 0, 0L);
777 if (lRet == LB_ERR) return 0;
778 pstr = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC);
779 SendDlgItemMessageW(hWnd, cmb2, CB_GETLBTEXT, lRet,
781 wsprintfW(tmpstr, FILE_specc, pstr[2]);
782 HeapFree(GetProcessHeap(), 0, pstr);
783 if (notification != CBN_SELCHANGE) return TRUE;
785 /* on entry tmpstr points to the new path to scan */
787 lRet = SendDlgItemMessageW(hWnd, cmb1, CB_GETCURSEL, 0, 0);
790 pstr = (LPWSTR)SendDlgItemMessageW(hWnd, cmb1, CB_GETITEMDATA, lRet, 0);
791 TRACE("Selected filter : %s\n", debugstr_w(pstr));
792 SetDlgItemTextW( hWnd, edt1, pstr );
793 FILEDLG_ScanDir(hWnd, tmpstr, TRUE);
799 ofn2 = *ofnW; /* for later restoring */
800 /* get current file name */
801 GetDlgItemTextW( hWnd, edt1, tmpstr, sizeof(tmpstr) );
802 pstr = strrchrW(tmpstr, '\\');
804 pstr = strrchrW(tmpstr, ':');
806 if (strchrW(tmpstr,'*') != NULL || strchrW(tmpstr,'?') != NULL)
808 /* edit control contains wildcards */
811 lstrcpynW(tmpstr2, pstr+1, BUFFILE);
816 strcpyW(tmpstr2, tmpstr);
820 TRACE("tmpstr=%s, tmpstr2=%s\n", debugstr_w(tmpstr), debugstr_w(tmpstr2));
821 SetDlgItemTextW( hWnd, edt1, tmpstr2 );
822 FILEDLG_ScanDir(hWnd, tmpstr, TRUE);
825 /* no wildcards, we might have a directory or a filename */
826 /* try appending a wildcard and reading the directory */
827 pstr2 = tmpstr + lstrlenW(tmpstr);
828 if (pstr == NULL || *(pstr+1) != 0)
829 strcatW(tmpstr, FILE_bslash);
830 lRet = SendDlgItemMessageW(hWnd, cmb1, CB_GETCURSEL, 0, 0);
831 if (lRet == LB_ERR) return TRUE;
832 ofnW->nFilterIndex = lRet + 1;
833 TRACE("ofn->nFilterIndex=%ld\n", ofnW->nFilterIndex);
835 FILEDLG_GetFileType(ofnW->lpstrCustomFilter,
836 (LPWSTR) ofnW->lpstrFilter,
837 lRet), sizeof(tmpstr2));
838 SetDlgItemTextW( hWnd, edt1, tmpstr2 );
842 /* if ScanDir succeeds, we have changed the directory */
843 if (FILEDLG_ScanDir(hWnd, tmpstr, TRUE))
846 /* if not, this must be a filename */
847 *pstr2 = 0; /* remove the wildcard added before */
851 /* strip off the pathname */
853 SetDlgItemTextW( hWnd, edt1, pstr + 1 );
854 lstrcpynW(tmpstr2, pstr+1, sizeof(tmpstr2) );
855 /* Should we MessageBox() if this fails? */
856 if (!FILEDLG_ScanDir(hWnd, tmpstr, TRUE)) return TRUE;
857 strcpyW(tmpstr, tmpstr2);
859 else SetDlgItemTextW( hWnd, edt1, tmpstr );
860 FILEDLG_UpdateResult(lfs, tmpstr, tmpstr2);
864 FILEDLG_CallWindowProc(lfs, lfs->lbselchstring, control,
865 MAKELONG(lRet,CD_LBSELCHANGE));
869 FILEDLG_UpdateFileTitle(lfs);
872 lRet = (BOOL)FILEDLG_CallWindowProc(lfs, lfs->fileokstring,
876 *ofnW = ofn2; /* restore old state */
880 if ((ofnW->Flags & OFN_ALLOWMULTISELECT) && (ofnW->Flags & OFN_EXPLORER)) {
881 if (ofnW->lpstrFile) {
882 LPWSTR str = (LPWSTR)ofnW->lpstrFile;
883 LPWSTR ptr = strrchrW(str, '\\');
884 str[lstrlenW(str) + 1] = '\0';
888 EndDialog(hWnd, TRUE);
891 EndDialog(hWnd, FALSE);
893 case IDABORT: /* can be sent by the hook procedure */
894 EndDialog(hWnd, TRUE);
901 /***********************************************************************
902 * FILEDLG_MapDrawItemStruct [internal]
903 * map a 16 bits drawitem struct to 32
905 void FILEDLG_MapDrawItemStruct(LPDRAWITEMSTRUCT16 lpdis16, LPDRAWITEMSTRUCT lpdis)
907 lpdis->CtlType = lpdis16->CtlType;
908 lpdis->CtlID = lpdis16->CtlID;
909 lpdis->itemID = lpdis16->itemID;
910 lpdis->itemAction = lpdis16->itemAction;
911 lpdis->itemState = lpdis16->itemState;
912 lpdis->hwndItem = lpdis16->hwndItem;
913 lpdis->hDC = lpdis16->hDC;
914 lpdis->rcItem.right = lpdis16->rcItem.right;
915 lpdis->rcItem.left = lpdis16->rcItem.left;
916 lpdis->rcItem.top = lpdis16->rcItem.top;
917 lpdis->rcItem.bottom = lpdis16->rcItem.bottom;
918 lpdis->itemData = lpdis16->itemData;
921 /************************************************************************
922 * FILEDLG_MapStringPairsToW [internal]
923 * map string pairs to Unicode
925 LPWSTR FILEDLG_MapStringPairsToW(LPCSTR strA, UINT size)
936 if (n < size) n = size;
938 x = y = HeapAlloc(GetProcessHeap(),0, n * sizeof(WCHAR));
950 /************************************************************************
951 * FILEDLG_DupToW [internal]
952 * duplicates an Ansi string to unicode, with a buffer size
954 LPWSTR FILEDLG_DupToW(LPCSTR str, UINT size)
957 if (str && (size > 0))
959 strW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
960 lstrcpynAtoW(strW, str, size);
968 /************************************************************************
969 * FILEDLG_MapOfnStructA [internal]
970 * map a 32 bits Ansi structure to an Unicode one
972 void FILEDLG_MapOfnStructA(LPOPENFILENAMEA ofnA, LPOPENFILENAMEW ofnW, BOOL open)
976 ofnW->lStructSize = sizeof(OPENFILENAMEW);
977 ofnW->hwndOwner = ofnA->hwndOwner;
978 ofnW->hInstance = ofnA->hInstance;
979 if (ofnA->lpstrFilter)
980 ofnW->lpstrFilter = FILEDLG_MapStringPairsToW(ofnA->lpstrFilter, 0);
982 ofnW->lpstrFilter = FILEDLG_MapStringPairsToW(defaultfilter, 0);
984 if ((ofnA->lpstrCustomFilter) && (*(ofnA->lpstrCustomFilter)))
985 ofnW->lpstrCustomFilter = FILEDLG_MapStringPairsToW(ofnA->lpstrCustomFilter, ofnA->nMaxCustFilter);
986 ofnW->nMaxCustFilter = ofnA->nMaxCustFilter;
987 ofnW->nFilterIndex = ofnA->nFilterIndex;
988 ofnW->lpstrFile = FILEDLG_DupToW(ofnA->lpstrFile, ofnA->nMaxFile);
989 ofnW->nMaxFile = ofnA->nMaxFile;
990 ofnW->lpstrFileTitle = FILEDLG_DupToW(ofnA->lpstrFileTitle, ofnA->nMaxFileTitle);
991 ofnW->nMaxFileTitle = ofnA->nMaxFileTitle;
992 if (ofnA->lpstrInitialDir)
993 ofnW->lpstrInitialDir = HEAP_strdupAtoW(GetProcessHeap(),0,ofnA->lpstrInitialDir);
994 if (ofnA->lpstrTitle)
995 str = ofnA->lpstrTitle;
997 /* Allocates default title (FIXME : get it from resource) */
998 str = open ? defaultopen:defaultsave;
999 ofnW->lpstrTitle = HEAP_strdupAtoW(GetProcessHeap(),0, str);
1000 ofnW->Flags = ofnA->Flags;
1001 ofnW->nFileOffset = ofnA->nFileOffset;
1002 ofnW->nFileExtension = ofnA->nFileExtension;
1003 ofnW->lpstrDefExt = FILEDLG_DupToW(ofnA->lpstrDefExt, 3);
1004 if ((ofnA->Flags & OFN_ENABLETEMPLATE) && (ofnA->lpTemplateName))
1006 if (HIWORD(ofnA->lpTemplateName))
1007 ofnW->lpTemplateName = HEAP_strdupAtoW(GetProcessHeap(), 0, ofnA->lpTemplateName);
1008 else /* numbered resource */
1009 ofnW->lpTemplateName = (LPWSTR) ofnA->lpTemplateName;
1014 /************************************************************************
1015 * FILEDLG_MapOfnStruct16 [internal]
1016 * map a 16 bits structure to an Unicode one
1018 void FILEDLG_MapOfnStruct16(LPOPENFILENAME16 ofn16, LPOPENFILENAMEW ofnW, BOOL open)
1021 /* first convert to linear pointers */
1022 memset(&ofnA, 0, sizeof(OPENFILENAMEA));
1023 ofnA.lStructSize = sizeof(OPENFILENAMEA);
1024 ofnA.hwndOwner = ofn16->hwndOwner;
1025 ofnA.hInstance = ofn16->hInstance;
1026 if (ofn16->lpstrFilter)
1027 ofnA.lpstrFilter = PTR_SEG_TO_LIN(ofn16->lpstrFilter);
1028 if (ofn16->lpstrCustomFilter)
1029 ofnA.lpstrCustomFilter = PTR_SEG_TO_LIN(ofn16->lpstrCustomFilter);
1030 ofnA.nMaxCustFilter = ofn16->nMaxCustFilter;
1031 ofnA.nFilterIndex = ofn16->nFilterIndex;
1032 ofnA.lpstrFile = PTR_SEG_TO_LIN(ofn16->lpstrFile);
1033 ofnA.nMaxFile = ofn16->nMaxFile;
1034 ofnA.lpstrFileTitle = PTR_SEG_TO_LIN(ofn16->lpstrFileTitle);
1035 ofnA.nMaxFileTitle = ofn16->nMaxFileTitle;
1036 ofnA.lpstrInitialDir = PTR_SEG_TO_LIN(ofn16->lpstrInitialDir);
1037 ofnA.lpstrTitle = PTR_SEG_TO_LIN(ofn16->lpstrTitle);
1038 ofnA.Flags = ofn16->Flags;
1039 ofnA.nFileOffset = ofn16->nFileOffset;
1040 ofnA.nFileExtension = ofn16->nFileExtension;
1041 ofnA.lpstrDefExt = PTR_SEG_TO_LIN(ofn16->lpstrDefExt);
1042 if (HIWORD(ofn16->lpTemplateName))
1043 ofnA.lpTemplateName = PTR_SEG_TO_LIN(ofn16->lpTemplateName);
1045 ofnA.lpTemplateName = (LPSTR) ofn16->lpTemplateName; /* ressource number */
1046 /* now calls the 32 bits Ansi to Unicode version to complete the job */
1047 FILEDLG_MapOfnStructA(&ofnA, ofnW, open);
1051 /************************************************************************
1052 * FILEDLG_DestroyPrivate [internal]
1053 * destroys the private object
1055 void FILEDLG_DestroyPrivate(LFSPRIVATE lfs)
1060 /* free resources for a 16 bits dialog */
1061 if (lfs->hResource16) FreeResource16(lfs->hResource16);
1064 GlobalUnlock16(lfs->hGlobal16);
1065 GlobalFree16(lfs->hGlobal16);
1067 /* if ofnW has been allocated, have to free everything in it */
1068 if (lfs->ofn16 || lfs->ofnA)
1070 LPOPENFILENAMEW ofnW = lfs->ofnW;
1071 if (ofnW->lpstrFilter) HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpstrFilter);
1072 if (ofnW->lpstrCustomFilter) HeapFree(GetProcessHeap(), 0, ofnW->lpstrCustomFilter);
1073 if (ofnW->lpstrFile) HeapFree(GetProcessHeap(), 0, ofnW->lpstrFile);
1074 if (ofnW->lpstrFileTitle) HeapFree(GetProcessHeap(), 0, ofnW->lpstrFileTitle);
1075 if (ofnW->lpstrInitialDir) HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpstrInitialDir);
1076 if (ofnW->lpstrTitle) HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpstrTitle);
1077 if ((ofnW->lpTemplateName) && (HIWORD(ofnW->lpTemplateName)))
1078 HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpTemplateName);
1079 HeapFree(GetProcessHeap(), 0, ofnW);
1081 TRACE("destroying private allocation %p\n", lfs);
1082 HeapFree(GetProcessHeap(), 0, lfs);
1083 RemovePropA(hwnd, OFN_PROP);
1086 /************************************************************************
1087 * FILEDLG_AllocPrivate [internal]
1088 * allocate a private object to hold 32 bits Unicode
1089 * structure that will be used throughtout the calls, while
1090 * keeping available the original structures and a few variables
1091 * On entry : type = dialog procedure type (16,32A,32W)
1092 * dlgType = dialog type (open or save)
1094 LFSPRIVATE FILEDLG_AllocPrivate(LPARAM lParam, int type, UINT dlgType)
1096 LFSPRIVATE lfs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct FSPRIVATE));
1098 TRACE("alloc private buf %p\n", lfs);
1099 if (!lfs) return NULL;
1101 lfs->lParam = lParam;
1102 if (dlgType == OPEN_DIALOG)
1106 lfs->lbselchstring = RegisterWindowMessageA(LBSELCHSTRING);
1107 lfs->fileokstring = RegisterWindowMessageA(FILEOKSTRING);
1111 lfs->ofn16 = (LPOPENFILENAME16) PTR_SEG_TO_LIN(lParam);
1112 if (lfs->ofn16->Flags & OFN_ENABLEHOOK)
1113 if (lfs->ofn16->lpfnHook)
1119 lfs->ofnA = (LPOPENFILENAMEA) lParam;
1120 if (lfs->ofnA->Flags & OFN_ENABLEHOOK)
1121 if (lfs->ofnA->lpfnHook)
1126 lfs->ofnW = (LPOPENFILENAMEW) lParam;
1127 if (lfs->ofnW->Flags & OFN_ENABLEHOOK)
1128 if (lfs->ofnW->lpfnHook)
1134 { /* this structure is needed internally, so create it */
1135 lfs->ofnW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(OPENFILENAMEW));
1139 FILEDLG_MapOfnStruct16(lfs->ofn16, lfs->ofnW, lfs->open);
1141 FILEDLG_MapOfnStructA(lfs->ofnA, lfs->ofnW, lfs->open);
1148 if (!Get16BitsTemplate(lfs)) ret = NULL;
1151 if (!Get32BitsTemplate(lfs)) ret = NULL;
1152 if (!ret) FILEDLG_DestroyPrivate(lfs);
1157 /***********************************************************************
1158 * GetFileName31A [internal]
1160 * Creates a win31 style dialog box for the user to select a file to open/save.
1162 BOOL WINAPI GetFileName31A(
1163 LPOPENFILENAMEA lpofn, /* addess of structure with data*/
1164 UINT dlgType /* type dialogue : open/save */
1171 if (!lpofn || !FileDlg_Init()) return FALSE;
1173 lfs = FILEDLG_AllocPrivate((LPARAM) lpofn, LFS32A, dlgType);
1176 hInst = GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );
1177 bRet = DialogBoxIndirectParamA( hInst, lfs->template, lpofn->hwndOwner,
1178 (DLGPROC) FileOpenDlgProc, (DWORD) lfs);
1179 FILEDLG_DestroyPrivate(lfs);
1182 TRACE("return lpstrFile='%s' !\n", lpofn->lpstrFile);
1187 /***********************************************************************
1188 * GetFileName31W [internal]
1190 * Creates a win31 style dialog box for the user to select a file to open/save
1192 BOOL WINAPI GetFileName31W(
1193 LPOPENFILENAMEW lpofn, /* addess of structure with data*/
1194 UINT dlgType /* type dialogue : open/save */
1201 if (!lpofn || !FileDlg_Init()) return FALSE;
1203 lfs = FILEDLG_AllocPrivate((LPARAM) lpofn, LFS32W, dlgType);
1206 hInst = GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );
1207 bRet = DialogBoxIndirectParamW( hInst, lfs->template, lpofn->hwndOwner,
1208 (DLGPROC) FileOpenDlgProc, (DWORD) lfs);
1209 FILEDLG_DestroyPrivate(lfs);
1212 TRACE("return lpstrFile='%s' !\n", debugstr_w(lpofn->lpstrFile));
1217 /* ------------------ Dialog procedures ---------------------- */
1219 /***********************************************************************
1220 * FileOpenDlgProc16 (COMMDLG.6)
1222 LRESULT WINAPI FileOpenDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1225 LFSPRIVATE lfs = (LFSPRIVATE)GetPropA(hWnd,OFN_PROP);
1228 TRACE("msg=%x wparam=%x lParam=%lx\n", wMsg, wParam, lParam);
1229 if ((wMsg != WM_INITDIALOG) && lfs && lfs->hook)
1231 LRESULT lRet = (BOOL16)FILEDLG_CallWindowProc(lfs, wMsg, wParam, lParam);
1233 return lRet; /* else continue message processing */
1238 return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
1240 case WM_MEASUREITEM:
1241 return FILEDLG_WMMeasureItem16(hWnd, wParam, lParam);
1244 FILEDLG_MapDrawItemStruct((LPDRAWITEMSTRUCT16)PTR_SEG_TO_LIN(lParam), &dis);
1245 return FILEDLG_WMDrawItem(hWnd, wParam, lParam, FALSE, &dis);
1248 return FILEDLG_WMCommand(hWnd, lParam, HIWORD(lParam),wParam, lfs);
1251 SetBkColor((HDC16)wParam, 0x00C0C0C0);
1252 switch (HIWORD(lParam))
1255 SetTextColor((HDC16)wParam, 0x00000000);
1257 case CTLCOLOR_STATIC:
1258 SetTextColor((HDC16)wParam, 0x00000000);
1267 /***********************************************************************
1268 * FileSaveDlgProc16 (COMMDLG.7)
1270 LRESULT WINAPI FileSaveDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1273 LFSPRIVATE lfs = (LFSPRIVATE)GetPropA(hWnd,OFN_PROP);
1276 TRACE("msg=%x wparam=%x lParam=%lx\n", wMsg, wParam, lParam);
1277 if ((wMsg != WM_INITDIALOG) && lfs && lfs->hook)
1280 lRet = (BOOL16)FILEDLG_CallWindowProc(lfs, wMsg, wParam, lParam);
1282 return lRet; /* else continue message processing */
1286 return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
1288 case WM_MEASUREITEM:
1289 return FILEDLG_WMMeasureItem16(hWnd, wParam, lParam);
1292 FILEDLG_MapDrawItemStruct((LPDRAWITEMSTRUCT16)PTR_SEG_TO_LIN(lParam), &dis);
1293 return FILEDLG_WMDrawItem(hWnd, wParam, lParam, TRUE, &dis);
1296 return FILEDLG_WMCommand(hWnd, lParam, HIWORD(lParam), wParam, lfs);
1301 SetBkColor((HDC16)wParam, 0x00C0C0C0);
1302 switch (HIWORD(lParam))
1305 SetTextColor((HDC16)wParam, 0x00000000);
1307 case CTLCOLOR_STATIC:
1308 SetTextColor((HDC16)wParam, 0x00000000);
1317 /***********************************************************************
1318 * FileOpenDlgProc [internal]
1319 * Used for open and save, in fact.
1321 static LRESULT WINAPI FileOpenDlgProc(HWND hWnd, UINT wMsg,
1322 WPARAM wParam, LPARAM lParam)
1324 LFSPRIVATE lfs = (LFSPRIVATE)GetPropA(hWnd,OFN_PROP);
1326 TRACE("msg=%x wparam=%x lParam=%lx\n", wMsg, wParam, lParam);
1327 if ((wMsg != WM_INITDIALOG) && lfs && lfs->hook)
1330 lRet = (BOOL)FILEDLG_CallWindowProc(lfs, wMsg, wParam, lParam);
1332 return lRet; /* else continue message processing */
1337 return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
1339 case WM_MEASUREITEM:
1340 return FILEDLG_WMMeasureItem(hWnd, wParam, lParam);
1343 return FILEDLG_WMDrawItem(hWnd, wParam, lParam, !lfs->open, (DRAWITEMSTRUCT *)lParam);
1346 return FILEDLG_WMCommand(hWnd, lParam, HIWORD(wParam), LOWORD(wParam), lfs);
1349 SetBkColor((HDC16)wParam, 0x00C0C0C0);
1350 switch (HIWORD(lParam))
1353 SetTextColor((HDC16)wParam, 0x00000000);
1355 case CTLCOLOR_STATIC:
1356 SetTextColor((HDC16)wParam, 0x00000000);
1365 /* ------------------ APIs ---------------------- */
1367 /***********************************************************************
1368 * GetOpenFileName16 (COMMDLG.1)
1370 * Creates a dialog box for the user to select a file to open.
1373 * TRUE on success: user selected a valid file
1374 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1377 * unknown, there are some FIXME's left.
1379 BOOL16 WINAPI GetOpenFileName16(
1380 SEGPTR ofn /* addess of structure with data*/
1385 LPOPENFILENAME16 lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(ofn);
1389 if (!lpofn || !FileDlg_Init()) return FALSE;
1391 lfs = FILEDLG_AllocPrivate((LPARAM) ofn, LFS16, OPEN_DIALOG);
1394 hInst = GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );
1395 ptr = GetProcAddress16(GetModuleHandle16("COMMDLG"), (SEGPTR) 6);
1396 bRet = DialogBoxIndirectParam16( hInst, lfs->hDlgTmpl16, lpofn->hwndOwner,
1397 (DLGPROC16) ptr, (DWORD) lfs);
1398 FILEDLG_DestroyPrivate(lfs);
1401 TRACE("return lpstrFile='%s' !\n",
1402 (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
1406 /***********************************************************************
1407 * GetSaveFileName16 (COMMDLG.2)
1409 * Creates a dialog box for the user to select a file to save.
1412 * TRUE on success: user enters a valid file
1413 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1416 * unknown. There are some FIXME's left.
1418 BOOL16 WINAPI GetSaveFileName16(
1419 SEGPTR ofn /* addess of structure with data*/
1424 LPOPENFILENAME16 lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(ofn);
1428 if (!lpofn || !FileDlg_Init()) return FALSE;
1430 lfs = FILEDLG_AllocPrivate((LPARAM) ofn, LFS16, SAVE_DIALOG);
1433 hInst = GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );
1434 ptr = GetProcAddress16(GetModuleHandle16("COMMDLG"), (SEGPTR) 7);
1435 bRet = DialogBoxIndirectParam16( hInst, lfs->hDlgTmpl16, lpofn->hwndOwner,
1436 (DLGPROC16) ptr, (DWORD) lfs);
1437 FILEDLG_DestroyPrivate(lfs);
1440 TRACE("return lpstrFile='%s' !\n",
1441 (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
1445 /***********************************************************************
1446 * GetOpenFileNameA (COMDLG32.10)
1448 * Creates a dialog box for the user to select a file to open.
1451 * TRUE on success: user enters a valid file
1452 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1455 BOOL WINAPI GetOpenFileNameA(
1456 LPOPENFILENAMEA ofn) /* address of init structure */
1460 /* some flags don't allow to match the TWEAK_WineLook */
1461 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
1463 newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
1467 /* no special flags set, we can match the TWEAK_WineLook */
1468 newlook = (TWEAK_WineLook>WIN31_LOOK) ? TRUE : FALSE;
1473 return GetFileDialog95A(ofn, OPEN_DIALOG);
1477 return GetFileName31A(ofn, OPEN_DIALOG);
1481 /***********************************************************************
1482 * GetOpenFileNameW (COMDLG32.11)
1484 * Creates a dialog box for the user to select a file to open.
1487 * TRUE on success: user enters a valid file
1488 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1491 BOOL WINAPI GetOpenFileNameW(
1492 LPOPENFILENAMEW ofn) /* address of init structure */
1496 /* some flags don't allow to match the TWEAK_WineLook */
1497 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
1499 newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
1503 /* no special flags set, we can match the TWEAK_WineLook */
1504 newlook = (TWEAK_WineLook>WIN31_LOOK) ? TRUE : FALSE;
1509 return GetFileDialog95W(ofn, OPEN_DIALOG);
1513 return GetFileName31W(ofn, OPEN_DIALOG);
1517 /***********************************************************************
1518 * GetSaveFileNameA (COMDLG32.12)
1520 * Creates a dialog box for the user to select a file to save.
1523 * TRUE on success: user enters a valid file
1524 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1527 BOOL WINAPI GetSaveFileNameA(
1528 LPOPENFILENAMEA ofn) /* address of init structure */
1532 /* some flags don't allow to match the TWEAK_WineLook */
1533 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
1535 newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
1539 /* no special flags set, we can match the TWEAK_WineLook */
1540 newlook = (TWEAK_WineLook>WIN31_LOOK) ? TRUE : FALSE;
1545 return GetFileDialog95A(ofn, SAVE_DIALOG);
1549 return GetFileName31A(ofn, SAVE_DIALOG);
1553 /***********************************************************************
1554 * GetSaveFileNameW (COMDLG32.13)
1556 * Creates a dialog box for the user to select a file to save.
1559 * TRUE on success: user enters a valid file
1560 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1563 BOOL WINAPI GetSaveFileNameW(
1564 LPOPENFILENAMEW ofn) /* address of init structure */
1568 /* some flags don't allow to match the TWEAK_WineLook */
1569 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
1571 newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
1575 /* no special flags set, we can match the TWEAK_WineLook */
1576 newlook = (TWEAK_WineLook>WIN31_LOOK) ? TRUE : FALSE;
1581 return GetFileDialog95W(ofn, SAVE_DIALOG);
1585 return GetFileName31W(ofn, SAVE_DIALOG);