source: trunk/src/comdlg32/filedlg.c@ 5462

Last change on this file since 5462 was 5462, checked in by sandervl, 24 years ago

update

File size: 54.6 KB
Line 
1/*
2 * COMMDLG - File Dialogs
3 *
4 * Copyright 1994 Martin Ayotte
5 * Copyright 1996 Albrecht Kleine
6 */
7#include <ctype.h>
8#include <stdlib.h>
9#include <stdio.h>
10#include <string.h>
11#include "windef.h"
12#include "winnls.h"
13#include "winbase.h"
14#include "wingdi.h"
15#include "wine/winbase16.h"
16#include "wine/winuser16.h"
17#include "wine/unicode.h"
18#include "heap.h"
19#include "commdlg.h"
20#include "debugtools.h"
21#include "cderr.h"
22
23#ifdef __WIN32OS2__
24#include <win\cursoricon.h>
25#include <heapstring.h>
26
27#define GlobalFree16 GlobalFree
28#define GlobalLock16 GlobalLock
29#define GlobalUnlock16 GlobalUnlock
30#define GlobalAlloc16 GlobalAlloc
31#define FreeResource16 FreeResource
32#define LoadResource16 LoadResourceA
33#define FindResource16 FindResourceA
34#define MapSL(a) a
35#define CallWindowProc16 CallWindowProcA
36
37#endif
38
39DEFAULT_DEBUG_CHANNEL(commdlg);
40
41#include "cdlg.h"
42
43#define BUFFILE 512
44#define BUFFILEALLOC 512 * sizeof(WCHAR)
45
46struct FSPRIVATE
47{
48 HWND hwnd; /* file dialog window handle */
49 BOOL hook; /* TRUE if the dialog is hooked */
50 UINT lbselchstring; /* registered message id */
51 UINT fileokstring; /* registered message id */
52 LPARAM lParam; /* save original lparam */
53#ifdef __WIN32OS2__
54 HANDLE hDlgTmpl16; /* handle for resource 16 */
55 HANDLE hResource16; /* handle for allocated resource 16 */
56 HANDLE hGlobal16; /* 16 bits mem block (resources) */
57#else
58 HANDLE16 hDlgTmpl16; /* handle for resource 16 */
59 HANDLE16 hResource16; /* handle for allocated resource 16 */
60 HANDLE16 hGlobal16; /* 16 bits mem block (resources) */
61#endif
62 LPCVOID template; /* template for 32 bits resource */
63 BOOL open; /* TRUE if open dialog, FALSE if save dialog */
64 OPENFILENAMEW *ofnW; /* original structure or work struct */
65 OPENFILENAMEA *ofnA; /* original structure if 32bits ansi dialog */
66#ifndef __WIN32OS2__
67 OPENFILENAME16 *ofn16; /* original structure if 16 bits dialog */
68#endif
69};
70
71
72#define LFSPRIVATE struct FSPRIVATE *
73
74#define LFS16 1
75#define LFS32A 2
76#define LFS32W 3
77
78static const WCHAR FILE_star[] = {'*','.','*', 0};
79static const WCHAR FILE_bslash[] = {'\\', 0};
80static const WCHAR FILE_specc[] = {'%','c',':', 0};
81
82#ifdef __WIN32OS2__
83static HICON hFolder = 0;
84static HICON hFolder2 = 0;
85static HICON hFloppy = 0;
86static HICON hHDisk = 0;
87static HICON hCDRom = 0;
88static HICON hNet = 0;
89#else
90static HICON16 hFolder = 0;
91static HICON16 hFolder2 = 0;
92static HICON16 hFloppy = 0;
93static HICON16 hHDisk = 0;
94static HICON16 hCDRom = 0;
95static HICON16 hNet = 0;
96#endif
97static int fldrHeight = 0;
98static int fldrWidth = 0;
99
100#define OFN_PROP "FILEDLG_OFN"
101
102static const char defaultfilter[]=" \0\0";
103static char defaultopen[]="Open File";
104static char defaultsave[]="Save as";
105
106/***********************************************************************
107 *
108 * Windows 3.1 style OpenFileName/SaveFileName dialog
109 *
110 */
111
112LRESULT WINAPI FileOpenDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
113 LPARAM lParam);
114LRESULT WINAPI FileSaveDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
115 LPARAM lParam);
116
117static LRESULT WINAPI FileOpenDlgProc(HWND hDlg, UINT msg,
118 WPARAM wParam, LPARAM lParam);
119
120/***********************************************************************
121 * FileDlg_Init [internal]
122 */
123static BOOL FileDlg_Init(void)
124{
125 static BOOL initialized = 0;
126 CURSORICONINFO *fldrInfo;
127
128 if (!initialized) {
129#ifdef __WIN32OS2__
130 if (!hFolder) hFolder = LoadImageA(0, MAKEINTRESOURCEA(OIC_FOLDER), IMAGE_ICON, 16, 16, LR_SHARED);
131 if (!hFolder2) hFolder2 = LoadImageA(0, MAKEINTRESOURCEA(OIC_FOLDER2), IMAGE_ICON, 16, 16, LR_SHARED);
132 if (!hFloppy) hFloppy = LoadImageA(0, MAKEINTRESOURCEA(OIC_FLOPPY), IMAGE_ICON, 16, 16, LR_SHARED);
133 if (!hHDisk) hHDisk = LoadImageA(0, MAKEINTRESOURCEA(OIC_HDISK), IMAGE_ICON, 16, 16, LR_SHARED);
134 if (!hCDRom) hCDRom = LoadImageA(0, MAKEINTRESOURCEA(OIC_CDROM), IMAGE_ICON, 16, 16, LR_SHARED);
135 if (!hNet) hNet = LoadImageA(0, MAKEINTRESOURCEA(OIC_NETWORK), IMAGE_ICON, 16, 16, LR_SHARED);
136#else
137 if (!hFolder) hFolder = LoadIconA(0, MAKEINTRESOURCEA(OIC_FOLDER));
138 if (!hFolder2) hFolder2 = LoadIconA(0, MAKEINTRESOURCEA(OIC_FOLDER2));
139 if (!hFloppy) hFloppy = LoadIconA(0, MAKEINTRESOURCEA(OIC_FLOPPY));
140 if (!hHDisk) hHDisk = LoadIconA(0, MAKEINTRESOURCEA(OIC_HDISK));
141 if (!hCDRom) hCDRom = LoadIconA(0, MAKEINTRESOURCEA(OIC_CDROM));
142 if (!hNet) hNet = LoadIconA(0, MAKEINTRESOURCEA(OIC_NETWORK));
143#endif
144 if (hFolder == 0 || hFolder2 == 0 || hFloppy == 0 ||
145 hHDisk == 0 || hCDRom == 0 || hNet == 0)
146 {
147 ERR("Error loading icons !\n");
148 return FALSE;
149 }
150 fldrInfo = (CURSORICONINFO *) GlobalLock16( hFolder2 );
151 if (!fldrInfo)
152 {
153 ERR("Error measuring icons !\n");
154 return FALSE;
155 }
156 fldrHeight = fldrInfo -> nHeight;
157 fldrWidth = fldrInfo -> nWidth;
158 GlobalUnlock16( hFolder2 );
159 initialized = TRUE;
160 }
161 return TRUE;
162}
163
164
165/***********************************************************************
166 * Get32BitsTemplate [internal]
167 *
168 * Get a template (or FALSE if failure) when 16 bits dialogs are used
169 * by a 32 bits application
170 *
171 */
172BOOL Get32BitsTemplate(LFSPRIVATE lfs)
173{
174 LPOPENFILENAMEW ofnW = lfs->ofnW;
175 HANDLE hDlgTmpl;
176
177 if (ofnW->Flags & OFN_ENABLETEMPLATEHANDLE)
178 {
179 if (!(lfs->template = LockResource( ofnW->hInstance )))
180 {
181 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
182 return FALSE;
183 }
184 }
185 else if (ofnW->Flags & OFN_ENABLETEMPLATE)
186 {
187 HANDLE hResInfo;
188 if (lfs->ofnA)
189 hResInfo = FindResourceA(lfs->ofnA->hInstance,
190 lfs->ofnA->lpTemplateName,
191 RT_DIALOGA);
192 else
193 hResInfo = FindResourceW(ofnW->hInstance,
194 ofnW->lpTemplateName,
195 RT_DIALOGW);
196 if (!hResInfo)
197 {
198 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
199 return FALSE;
200 }
201 if (!(hDlgTmpl = LoadResource(ofnW->hInstance,
202 hResInfo)) ||
203 !(lfs->template = LockResource(hDlgTmpl)))
204 {
205 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
206 return FALSE;
207 }
208 } else { /* get it from internal Wine resource */
209 HANDLE hResInfo;
210 if (!(hResInfo = FindResourceA(COMMDLG_hInstance32,
211 lfs->open? "OPEN_FILE":"SAVE_FILE", RT_DIALOGA)))
212 {
213 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
214 return FALSE;
215 }
216 if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
217 !(lfs->template = LockResource( hDlgTmpl )))
218 {
219 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
220 return FALSE;
221 }
222 }
223 return TRUE;
224}
225
226#ifndef __WIN32OS2__
227/***********************************************************************
228 * Get16BitsTemplate [internal]
229 *
230 * Get a template (FALSE if failure) when 16 bits dialogs are used
231 * by a 16 bits application
232 *
233 */
234BOOL Get16BitsTemplate(LFSPRIVATE lfs)
235{
236 LPOPENFILENAME16 ofn16 = lfs->ofn16;
237 LPCVOID template;
238 HGLOBAL16 hGlobal16 = 0;
239
240 if (ofn16->Flags & OFN_ENABLETEMPLATEHANDLE)
241 lfs->hDlgTmpl16 = ofn16->hInstance;
242 else if (ofn16->Flags & OFN_ENABLETEMPLATE)
243 {
244 HANDLE16 hResInfo;
245 if (!(hResInfo = FindResource16(ofn16->hInstance,
246 MapSL(ofn16->lpTemplateName),
247 RT_DIALOGA)))
248 {
249 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
250 return FALSE;
251 }
252 if (!(lfs->hDlgTmpl16 = LoadResource16( ofn16->hInstance, hResInfo )))
253 {
254 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
255 return FALSE;
256 }
257 lfs->hResource16 = lfs->hDlgTmpl16;
258 }
259 else
260 { /* get resource from (32 bits) own Wine resource; convert it to 16 */
261 HANDLE hResInfo, hDlgTmpl32;
262 LPCVOID template32;
263 DWORD size;
264
265 if (!(hResInfo = FindResourceA(COMMDLG_hInstance32,
266 lfs->open ? "OPEN_FILE":"SAVE_FILE", RT_DIALOGA)))
267 {
268 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
269 return FALSE;
270 }
271 if (!(hDlgTmpl32 = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
272 !(template32 = LockResource( hDlgTmpl32 )))
273 {
274 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
275 return FALSE;
276 }
277 size = SizeofResource(GetModuleHandleA("COMDLG32"), hResInfo);
278 hGlobal16 = GlobalAlloc16(0, size);
279 if (!hGlobal16)
280 {
281 COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE);
282 ERR("alloc failure for %ld bytes\n", size);
283 return FALSE;
284 }
285 template = GlobalLock16(hGlobal16);
286 if (!template)
287 {
288 COMDLG32_SetCommDlgExtendedError(CDERR_MEMLOCKFAILURE);
289 ERR("global lock failure for %x handle\n", hGlobal16);
290 GlobalFree16(hGlobal16);
291 return FALSE;
292 }
293 ConvertDialog32To16((LPVOID)template32, size, (LPVOID)template);
294 lfs->hDlgTmpl16 = hGlobal16;
295 lfs->hGlobal16 = hGlobal16;
296 }
297 return TRUE;
298}
299#endif
300
301/***********************************************************************
302 * FILEDLG_StripEditControl [internal]
303 * Strip pathnames off the contents of the edit control.
304 */
305static void FILEDLG_StripEditControl(HWND hwnd)
306{
307 WCHAR temp[BUFFILE], *cp;
308
309 GetDlgItemTextW( hwnd, edt1, temp, sizeof(temp)/sizeof(WCHAR));
310 cp = strrchrW(temp, '\\');
311 if (cp != NULL) {
312 strcpyW(temp, cp+1);
313 }
314 cp = strrchrW(temp, ':');
315 if (cp != NULL) {
316 strcpyW(temp, cp+1);
317 }
318 /* FIXME: shouldn't we do something with the result here? ;-) */
319}
320
321
322
323/***********************************************************************
324 * FILEDLG_CallWindowProc [internal]
325 *
326 * Call the appropriate hook
327 */
328static BOOL FILEDLG_CallWindowProc(LFSPRIVATE lfs, UINT wMsg, WPARAM wParam,
329 LPARAM lParam)
330{
331#ifndef __WIN32OS2__
332 if (lfs->ofn16)
333 {
334 return (BOOL16) CallWindowProc16(
335 (WNDPROC16)lfs->ofn16->lpfnHook, lfs->hwnd,
336 (UINT16)wMsg, (WPARAM16)wParam, lParam);
337 }
338#endif
339 if (lfs->ofnA)
340 {
341 return (BOOL) CallWindowProcA(
342 (WNDPROC)lfs->ofnA->lpfnHook, lfs->hwnd,
343 wMsg, wParam, lParam);
344 }
345
346 if (lfs->ofnW)
347 {
348 return (BOOL) CallWindowProcW(
349 (WNDPROC)lfs->ofnW->lpfnHook, lfs->hwnd,
350 wMsg, wParam, lParam);
351 }
352 return FALSE;
353}
354
355
356/***********************************************************************
357 * FILEDLG_ScanDir [internal]
358 */
359static BOOL FILEDLG_ScanDir(HWND hWnd, LPWSTR newPath)
360{
361 WCHAR buffer[BUFFILE];
362 HWND hdlg, hdlgDir;
363 LRESULT lRet = TRUE;
364 HCURSOR hCursorWait, oldCursor;
365
366 if ( !SetCurrentDirectoryW( newPath ))
367 return FALSE;
368 lstrcpynW(buffer, newPath, sizeof(buffer)/sizeof(WCHAR));
369
370 /* get the list of spec files */
371 GetDlgItemTextW(hWnd, edt1, buffer, sizeof(buffer)/sizeof(WCHAR));
372
373 hCursorWait = LoadCursorA(0, IDC_WAITA);
374 oldCursor = SetCursor(hCursorWait);
375
376 /* list of files */
377 if ((hdlg = GetDlgItem(hWnd, lst1)) != 0) {
378 WCHAR* scptr; /* ptr on semi-colon */
379 WCHAR* filter = buffer;
380
381 TRACE("Using filter %s\n", debugstr_w(filter));
382 SendMessageW(hdlg, LB_RESETCONTENT, 0, 0);
383 while (filter) {
384 scptr = strchrW(filter, ';');
385 if (scptr) *scptr = 0;
386 while (*filter == ' ') filter++;
387 TRACE("Using file spec %s\n", debugstr_w(filter));
388 if (SendMessageW(hdlg, LB_DIR, 0, (LPARAM)filter) == LB_ERR)
389 return FALSE;
390 if (scptr) *scptr = ';';
391 filter = (scptr) ? (scptr + 1) : 0;
392 }
393 }
394
395 /* list of directories */
396 strcpyW(buffer, FILE_star);
397
398 if ((hdlgDir = GetDlgItem(hWnd, lst2)) != 0) {
399 lRet = DlgDirListW(hWnd, buffer, lst2, stc1, DDL_EXCLUSIVE | DDL_DIRECTORY);
400 }
401 SetCursor(oldCursor);
402 return lRet;
403}
404
405
406/***********************************************************************
407 * FILEDLG_GetFileType [internal]
408 */
409
410static LPWSTR FILEDLG_GetFileType(LPWSTR cfptr, LPWSTR fptr, WORD index)
411{
412 int n, i;
413 i = 0;
414 if (cfptr)
415 for ( ;(n = lstrlenW(cfptr)) != 0; i++)
416 {
417 cfptr += n + 1;
418 if (i == index)
419 return cfptr;
420 cfptr += lstrlenW(cfptr) + 1;
421 }
422 if (fptr)
423 for ( ;(n = lstrlenW(fptr)) != 0; i++)
424 {
425 fptr += n + 1;
426 if (i == index)
427 return fptr;
428 fptr += lstrlenW(fptr) + 1;
429 }
430 return (LPWSTR) FILE_star; /* FIXME */
431}
432
433/***********************************************************************
434 * FILEDLG_WMDrawItem [internal]
435 */
436static LONG FILEDLG_WMDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam,
437 int savedlg, LPDRAWITEMSTRUCT lpdis)
438{
439 WCHAR *str;
440 HICON hIcon;
441 COLORREF oldText = 0, oldBk = 0;
442
443 if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst1)
444 {
445 if (!(str = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC))) return FALSE;
446 SendMessageW(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID,
447 (LPARAM)str);
448
449 if ((lpdis->itemState & ODS_SELECTED) && !savedlg)
450 {
451 oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
452 oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
453 }
454 if (savedlg)
455 SetTextColor(lpdis->hDC,GetSysColor(COLOR_GRAYTEXT) );
456
457 ExtTextOutW(lpdis->hDC, lpdis->rcItem.left + 1,
458 lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
459 &(lpdis->rcItem), str, lstrlenW(str), NULL);
460
461 if (lpdis->itemState & ODS_SELECTED)
462 DrawFocusRect( lpdis->hDC, &(lpdis->rcItem) );
463
464 if ((lpdis->itemState & ODS_SELECTED) && !savedlg)
465 {
466 SetBkColor( lpdis->hDC, oldBk );
467 SetTextColor( lpdis->hDC, oldText );
468 }
469 HeapFree(GetProcessHeap(), 0, str);
470 return TRUE;
471 }
472
473 if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst2)
474 {
475 if (!(str = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC)))
476 return FALSE;
477 SendMessageW(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID,
478 (LPARAM)str);
479
480 if (lpdis->itemState & ODS_SELECTED)
481 {
482 oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
483 oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
484 }
485 ExtTextOutW(lpdis->hDC, lpdis->rcItem.left + fldrWidth,
486 lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
487 &(lpdis->rcItem), str, lstrlenW(str), NULL);
488
489 if (lpdis->itemState & ODS_SELECTED)
490 DrawFocusRect( lpdis->hDC, &(lpdis->rcItem) );
491
492 if (lpdis->itemState & ODS_SELECTED)
493 {
494 SetBkColor( lpdis->hDC, oldBk );
495 SetTextColor( lpdis->hDC, oldText );
496 }
497 DrawIcon(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hFolder);
498 HeapFree(GetProcessHeap(), 0, str);
499 return TRUE;
500 }
501 if (lpdis->CtlType == ODT_COMBOBOX && lpdis->CtlID == cmb2)
502 {
503 char root[] = "a:";
504 if (!(str = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC)))
505 return FALSE;
506 SendMessageW(lpdis->hwndItem, CB_GETLBTEXT, lpdis->itemID,
507 (LPARAM)str);
508 root[0] += str[2] - 'a';
509 switch(GetDriveTypeA(root))
510 {
511 case DRIVE_REMOVABLE: hIcon = hFloppy; break;
512 case DRIVE_CDROM: hIcon = hCDRom; break;
513 case DRIVE_REMOTE: hIcon = hNet; break;
514 case DRIVE_FIXED:
515 default: hIcon = hHDisk; break;
516 }
517 if (lpdis->itemState & ODS_SELECTED)
518 {
519 oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
520 oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
521 }
522 ExtTextOutW(lpdis->hDC, lpdis->rcItem.left + fldrWidth,
523 lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
524 &(lpdis->rcItem), str, lstrlenW(str), NULL);
525
526 if (lpdis->itemState & ODS_SELECTED)
527 {
528 SetBkColor( lpdis->hDC, oldBk );
529 SetTextColor( lpdis->hDC, oldText );
530 }
531 DrawIcon(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hIcon);
532 HeapFree(GetProcessHeap(), 0, str);
533 return TRUE;
534 }
535 return FALSE;
536}
537
538/***********************************************************************
539 * FILEDLG_WMMeasureItem [internal]
540 */
541static LONG FILEDLG_WMMeasureItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
542{
543 LPMEASUREITEMSTRUCT lpmeasure;
544
545 lpmeasure = (LPMEASUREITEMSTRUCT)lParam;
546 lpmeasure->itemHeight = fldrHeight;
547 return TRUE;
548}
549/***********************************************************************
550 * FILEDLG_WMMeasureItem16 [internal]
551 */
552#ifdef __WIN32OS2__
553static LONG FILEDLG_WMMeasureItem16(HWND hWnd, WPARAM wParam, LPARAM lParam)
554{
555 LPMEASUREITEMSTRUCT lpmeasure;
556
557 lpmeasure = (LPMEASUREITEMSTRUCT)lParam;
558 lpmeasure->itemHeight = fldrHeight;
559 return TRUE;
560}
561#else
562static LONG FILEDLG_WMMeasureItem16(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam)
563{
564 LPMEASUREITEMSTRUCT16 lpmeasure;
565
566 lpmeasure = MapSL(lParam);
567 lpmeasure->itemHeight = fldrHeight;
568 return TRUE;
569}
570#endif
571
572/***********************************************************************
573 * FILEDLG_WMInitDialog [internal]
574 */
575
576static LONG FILEDLG_WMInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam)
577{
578 int i, n;
579 WCHAR tmpstr[BUFFILE];
580 LPWSTR pstr, old_pstr;
581 LPOPENFILENAMEW ofn;
582 LFSPRIVATE lfs = (LFSPRIVATE) lParam;
583
584 if (!lfs) return FALSE;
585 SetPropA(hWnd, OFN_PROP, (HANDLE)lfs);
586 lfs->hwnd = hWnd;
587 ofn = lfs->ofnW;
588
589 TRACE("flags=%lx initialdir=%s\n", ofn->Flags, debugstr_w(ofn->lpstrInitialDir));
590
591 SetWindowTextW( hWnd, ofn->lpstrTitle );
592 /* read custom filter information */
593 if (ofn->lpstrCustomFilter)
594 {
595 pstr = ofn->lpstrCustomFilter;
596 n = 0;
597 TRACE("lpstrCustomFilter = %p\n", pstr);
598 while(*pstr)
599 {
600 old_pstr = pstr;
601 i = SendDlgItemMessageW(hWnd, cmb1, CB_ADDSTRING, 0,
602 (LPARAM)(ofn->lpstrCustomFilter) + n );
603 n += lstrlenW(pstr) + 1;
604 pstr += lstrlenW(pstr) + 1;
605 TRACE("add str='%s' "
606 "associated to '%s'\n", debugstr_w(old_pstr), debugstr_w(pstr));
607 SendDlgItemMessageW(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr);
608 n += lstrlenW(pstr) + 1;
609 pstr += lstrlenW(pstr) + 1;
610 }
611 }
612 /* read filter information */
613 if (ofn->lpstrFilter) {
614 pstr = (LPWSTR) ofn->lpstrFilter;
615 n = 0;
616 while(*pstr) {
617 old_pstr = pstr;
618 i = SendDlgItemMessageW(hWnd, cmb1, CB_ADDSTRING, 0,
619 (LPARAM)(ofn->lpstrFilter + n) );
620 n += lstrlenW(pstr) + 1;
621 pstr += lstrlenW(pstr) + 1;
622 TRACE("add str='%s' "
623 "associated to '%s'\n", debugstr_w(old_pstr), debugstr_w(pstr));
624 SendDlgItemMessageW(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr);
625 n += lstrlenW(pstr) + 1;
626 pstr += lstrlenW(pstr) + 1;
627 }
628 }
629 /* set default filter */
630 if (ofn->nFilterIndex == 0 && ofn->lpstrCustomFilter == NULL)
631 ofn->nFilterIndex = 1;
632 SendDlgItemMessageW(hWnd, cmb1, CB_SETCURSEL, ofn->nFilterIndex - 1, 0);
633 lstrcpynW(tmpstr, FILEDLG_GetFileType(ofn->lpstrCustomFilter,
634 (LPWSTR)ofn->lpstrFilter, ofn->nFilterIndex - 1),BUFFILE);
635 TRACE("nFilterIndex = %ld, SetText of edt1 to '%s'\n",
636 ofn->nFilterIndex, debugstr_w(tmpstr));
637 SetDlgItemTextW( hWnd, edt1, tmpstr );
638 /* get drive list */
639 *tmpstr = 0;
640 DlgDirListComboBoxW(hWnd, tmpstr, cmb2, 0, DDL_DRIVES | DDL_EXCLUSIVE);
641 /* read initial directory */
642 if (ofn->lpstrInitialDir != NULL)
643 {
644 int len;
645 lstrcpynW(tmpstr, ofn->lpstrInitialDir, 511);
646 len = lstrlenW(tmpstr);
647 if (len > 0 && tmpstr[len-1] != '\\' && tmpstr[len-1] != ':') {
648 tmpstr[len]='\\';
649 tmpstr[len+1]='\0';
650 }
651 }
652 else
653#ifdef __WIN32OS2__
654 GetCurrentDirectoryW(BUFFILE, tmpstr);
655#else
656 *tmpstr = 0;
657#endif
658
659 if (!FILEDLG_ScanDir(hWnd, tmpstr)) {
660 *tmpstr = 0;
661 if (!FILEDLG_ScanDir(hWnd, tmpstr))
662 WARN("Couldn't read initial directory %s!\n", debugstr_w(tmpstr));
663 }
664 /* select current drive in combo 2, omit missing drives */
665 {
666 char dir[MAX_PATH];
667#ifdef __WIN32OS2__
668 DWORD drives;
669#endif
670 char str[4] = "a:\\";
671 GetCurrentDirectoryA( sizeof(dir), dir );
672
673#ifdef __WIN32OS2__
674 drives = GetLogicalDrives();
675
676 //Don't use GetDriveType here. Calling it for a floppy drive causes
677 //the drive to become active for a brief moment
678 for(i = 0, n = -1; i < 26; i++)
679 {
680 str[0] = 'a' + i;
681 if(drives & (1 << i)) n++;
682
683 if (toupper(str[0]) == toupper(dir[0])) break;
684 }
685#else
686 for(i = 0, n = -1; i < 26; i++)
687 {
688 str[0] = 'a' + i;
689#ifdef __WIN32OS2__
690 //bugfix
691 if (GetDriveTypeA(str) > DRIVE_NO_ROOT_DIR) n++;
692#else
693 if (GetDriveTypeA(str) <= DRIVE_NO_ROOT_DIR) n++;
694#endif
695 if (toupper(str[0]) == toupper(dir[0])) break;
696 }
697#endif
698 }
699 SendDlgItemMessageW(hWnd, cmb2, CB_SETCURSEL, n, 0);
700 if (!(ofn->Flags & OFN_SHOWHELP))
701 ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
702 if (ofn->Flags & OFN_HIDEREADONLY)
703 ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
704 if (lfs->hook)
705 return (BOOL) FILEDLG_CallWindowProc(lfs, WM_INITDIALOG, wParam, lfs->lParam);
706 return TRUE;
707}
708
709/***********************************************************************
710 * FILEDLG_UpdateResult [internal]
711 * update the displayed file name (with path)
712 */
713void FILEDLG_UpdateResult(LFSPRIVATE lfs, WCHAR *tmpstr)
714{
715 int lenstr2;
716 LPOPENFILENAMEW ofnW = lfs->ofnW;
717 WCHAR tmpstr2[BUFFILE];
718
719 GetCurrentDirectoryW(BUFFILE, tmpstr2);
720 lenstr2 = strlenW(tmpstr2);
721 if (lenstr2 > 3)
722 tmpstr2[lenstr2++]='\\';
723 lstrcpynW(tmpstr2+lenstr2, tmpstr, BUFFILE-lenstr2);
724 if (ofnW->lpstrFile)
725 lstrcpynW(ofnW->lpstrFile, tmpstr2, ofnW->nMaxFile);
726 ofnW->nFileOffset = strrchrW(tmpstr2,'\\') - tmpstr2 +1;
727 ofnW->nFileExtension = 0;
728 while(tmpstr2[ofnW->nFileExtension] != '.' && tmpstr2[ofnW->nFileExtension] != '\0')
729 ofnW->nFileExtension++;
730 if (tmpstr2[ofnW->nFileExtension] == '\0')
731 ofnW->nFileExtension = 0;
732 else
733 ofnW->nFileExtension++;
734 /* update the real client structures if any */
735#ifndef __WIN32OS2__
736 if (lfs->ofn16)
737 { /* we have to convert to short (8.3) path */
738 char tmp[1024]; /* MAX_PATHNAME_LEN */
739 LPOPENFILENAME16 ofn16 = lfs->ofn16;
740 char *dest = MapSL(ofn16->lpstrFile);
741 if (!WideCharToMultiByte( CP_ACP, 0, ofnW->lpstrFile, -1,
742 tmp, ofnW->nMaxFile, NULL, NULL ))
743 tmp[ofnW->nMaxFile-1] = 0;
744 GetShortPathNameA(tmp, dest, ofn16->nMaxFile);
745
746 /* the same procedure as every year... */
747 ofn16->nFileOffset = strrchr(dest,'\\') - dest +1;
748 ofn16->nFileExtension = 0;
749 while(dest[ofn16->nFileExtension] != '.' && dest[ofn16->nFileExtension] != '\0')
750 ofn16->nFileExtension++;
751 if (dest[ofn16->nFileExtension] == '\0')
752 ofn16->nFileExtension = 0;
753 else
754 ofn16->nFileExtension++;
755 }
756#endif
757 if (lfs->ofnA)
758 {
759 if (!WideCharToMultiByte( CP_ACP, 0, ofnW->lpstrFile, -1,
760 lfs->ofnA->lpstrFile, ofnW->nMaxFile, NULL, NULL ))
761 lfs->ofnA->lpstrFile[ofnW->nMaxFile-1] = 0;
762 lfs->ofnA->nFileOffset = ofnW->nFileOffset;
763 lfs->ofnA->nFileExtension = ofnW->nFileExtension;
764 }
765}
766
767
768/***********************************************************************
769 * FILEDLG_UpdateFileTitle [internal]
770 * update the displayed file name (without path)
771 */
772void FILEDLG_UpdateFileTitle(LFSPRIVATE lfs)
773{
774 LONG lRet;
775 LPOPENFILENAMEW ofnW = lfs->ofnW;
776 if (ofnW->lpstrFileTitle != NULL)
777 {
778 lRet = SendDlgItemMessageW(lfs->hwnd, lst1, LB_GETCURSEL, 0, 0);
779 SendDlgItemMessageW(lfs->hwnd, lst1, LB_GETTEXT, lRet,
780 (LPARAM)ofnW->lpstrFileTitle );
781#ifndef __WIN32OS2__
782 if (lfs->ofn16)
783 {
784 char *dest = MapSL(lfs->ofn16->lpstrFileTitle);
785 if (!WideCharToMultiByte( CP_ACP, 0, ofnW->lpstrFileTitle, -1,
786 dest, ofnW->nMaxFileTitle, NULL, NULL ))
787 dest[ofnW->nMaxFileTitle-1] = 0;
788 }
789#endif
790 if (lfs->ofnA)
791 {
792 if (!WideCharToMultiByte( CP_ACP, 0, ofnW->lpstrFileTitle, -1,
793 lfs->ofnA->lpstrFileTitle, ofnW->nMaxFileTitle, NULL, NULL ))
794 lfs->ofnA->lpstrFileTitle[ofnW->nMaxFileTitle-1] = 0;
795 }
796 }
797}
798
799
800
801/***********************************************************************
802 * FILEDLG_DirListDblClick [internal]
803 */
804static LRESULT FILEDLG_DirListDblClick( LFSPRIVATE lfs )
805{
806 LONG lRet;
807 HWND hWnd = lfs->hwnd;
808 LPWSTR pstr;
809 WCHAR tmpstr[BUFFILE];
810
811 /* get the raw string (with brackets) */
812 lRet = SendDlgItemMessageW(hWnd, lst2, LB_GETCURSEL, 0, 0);
813 if (lRet == LB_ERR) return TRUE;
814 pstr = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC);
815 SendDlgItemMessageW(hWnd, lst2, LB_GETTEXT, lRet,
816 (LPARAM)pstr);
817 strcpyW( tmpstr, pstr );
818 HeapFree(GetProcessHeap(), 0, pstr);
819 /* get the selected directory in tmpstr */
820 if (tmpstr[0] == '[')
821 {
822 tmpstr[lstrlenW(tmpstr) - 1] = 0;
823 strcpyW(tmpstr,tmpstr+1);
824 }
825 strcatW(tmpstr, FILE_bslash);
826
827 FILEDLG_ScanDir(hWnd, tmpstr);
828 /* notify the app */
829 if (lfs->hook)
830 {
831 if (FILEDLG_CallWindowProc(lfs, lfs->lbselchstring, lst2,
832 MAKELONG(lRet,CD_LBSELCHANGE)))
833 return TRUE;
834 }
835 return TRUE;
836}
837
838
839/***********************************************************************
840 * FILEDLG_FileListSelect [internal]
841 * called when a new item is picked in the file list
842 */
843static LRESULT FILEDLG_FileListSelect( LFSPRIVATE lfs )
844{
845 LONG lRet;
846 HWND hWnd = lfs->hwnd;
847 LPWSTR pstr;
848
849#ifdef __WIN32OS2__
850 lRet = SendDlgItemMessageW(hWnd, lst1, LB_GETCURSEL, 0, 0);
851#else
852 lRet = SendDlgItemMessageW(hWnd, lst1, LB_GETCURSEL16, 0, 0);
853#endif
854 if (lRet == LB_ERR)
855 return TRUE;
856
857 /* set the edit control to the choosen file */
858 if ((pstr = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC)))
859 {
860 SendDlgItemMessageW(hWnd, lst1, LB_GETTEXT, lRet,
861 (LPARAM)pstr);
862 SetDlgItemTextW( hWnd, edt1, pstr );
863 HeapFree(GetProcessHeap(), 0, pstr);
864 }
865 if (lfs->hook)
866 {
867 FILEDLG_CallWindowProc(lfs, lfs->lbselchstring, lst1,
868 MAKELONG(lRet,CD_LBSELCHANGE));
869 }
870 /* FIXME: for OFN_ALLOWMULTISELECT we need CD_LBSELSUB, CD_SELADD,
871 CD_LBSELNOITEMS */
872 return TRUE;
873}
874
875/***********************************************************************
876 * FILEDLG_TestPath [internal]
877 * before accepting the file name, test if it includes wild cards
878 * tries to scan the directory and returns TRUE if no error.
879 */
880static LRESULT FILEDLG_TestPath( LFSPRIVATE lfs, LPWSTR path )
881{
882 HWND hWnd = lfs->hwnd;
883 LPWSTR pBeginFileName, pstr2;
884 WCHAR tmpstr2[BUFFILE];
885
886 pBeginFileName = strrchrW(path, '\\');
887 if (pBeginFileName == NULL)
888 pBeginFileName = strrchrW(path, ':');
889
890 if (strchrW(path,'*') != NULL || strchrW(path,'?') != NULL)
891 {
892 /* edit control contains wildcards */
893 if (pBeginFileName != NULL)
894 {
895 lstrcpynW(tmpstr2, pBeginFileName + 1, BUFFILE);
896 *(pBeginFileName + 1) = 0;
897 }
898 else
899 {
900 strcpyW(tmpstr2, path);
901 *path = 0;
902 }
903
904 TRACE("path=%s, tmpstr2=%s\n", debugstr_w(path), debugstr_w(tmpstr2));
905 SetDlgItemTextW( hWnd, edt1, tmpstr2 );
906 FILEDLG_ScanDir(hWnd, path);
907 return FALSE;
908 }
909
910 /* no wildcards, we might have a directory or a filename */
911 /* try appending a wildcard and reading the directory */
912
913 pstr2 = path + lstrlenW(path);
914 if (pBeginFileName == NULL || *(pBeginFileName + 1) != 0)
915 strcatW(path, FILE_bslash);
916
917 /* if ScanDir succeeds, we have changed the directory */
918 if (FILEDLG_ScanDir(hWnd, path))
919 return TRUE;
920
921 /* if not, this must be a filename */
922
923 *pstr2 = 0; /* remove the wildcard added before */
924
925 if (pBeginFileName != NULL)
926 {
927 /* strip off the pathname */
928 *pBeginFileName = 0;
929 SetDlgItemTextW( hWnd, edt1, pBeginFileName + 1 );
930
931 lstrcpynW(tmpstr2, pBeginFileName + 1, sizeof(tmpstr2)/sizeof(WCHAR) );
932 /* Should we MessageBox() if this fails? */
933 if (!FILEDLG_ScanDir(hWnd, path))
934 {
935 return FALSE;
936 }
937 strcpyW(path, tmpstr2);
938 }
939 else
940 SetDlgItemTextW( hWnd, edt1, path );
941 return TRUE;
942}
943
944/***********************************************************************
945 * FILEDLG_Validate [internal]
946 * called on: click Ok button, Enter in edit, DoubleClick in file list
947 */
948static LRESULT FILEDLG_Validate( LFSPRIVATE lfs, LPWSTR path, UINT control, INT itemIndex,
949 BOOL internalUse )
950{
951 LONG lRet;
952 HWND hWnd = lfs->hwnd;
953 OPENFILENAMEW ofnsav;
954 LPOPENFILENAMEW ofnW = lfs->ofnW;
955 WCHAR filename[BUFFILE];
956
957 ofnsav = *ofnW; /* for later restoring */
958
959 /* get current file name */
960 if (path)
961 lstrcpynW(filename, path, sizeof(filename)/sizeof(WCHAR));
962 else
963 GetDlgItemTextW( hWnd, edt1, filename, sizeof(filename)/sizeof(WCHAR));
964
965 /* if we did not click in file list to get there */
966 if (control != lst1)
967 {
968 if (!FILEDLG_TestPath( lfs, filename) )
969 return FALSE;
970 }
971 FILEDLG_UpdateResult(lfs, filename);
972
973 if (internalUse)
974 { /* called internally after a change in a combo */
975 if (lfs->hook)
976 {
977 FILEDLG_CallWindowProc(lfs, lfs->lbselchstring, control,
978 MAKELONG(itemIndex,CD_LBSELCHANGE));
979 }
980 return TRUE;
981 }
982
983 FILEDLG_UpdateFileTitle(lfs);
984 if (lfs->hook)
985 {
986 lRet = (BOOL)FILEDLG_CallWindowProc(lfs, lfs->fileokstring,
987 0, lfs->lParam );
988 if (lRet)
989 {
990 *ofnW = ofnsav; /* restore old state */
991 return FALSE;
992 }
993 }
994 if ((ofnW->Flags & OFN_ALLOWMULTISELECT) && (ofnW->Flags & OFN_EXPLORER))
995 {
996 if (ofnW->lpstrFile)
997 {
998 LPWSTR str = (LPWSTR)ofnW->lpstrFile;
999 LPWSTR ptr = strrchrW(str, '\\');
1000 str[lstrlenW(str) + 1] = '\0';
1001 *ptr = 0;
1002 }
1003 }
1004 return TRUE;
1005}
1006
1007/***********************************************************************
1008 * FILEDLG_DiskChange [internal]
1009 * called when a new item is picked in the disk selection combo
1010 */
1011static LRESULT FILEDLG_DiskChange( LFSPRIVATE lfs )
1012{
1013 LONG lRet;
1014 HWND hWnd = lfs->hwnd;
1015 LPWSTR pstr;
1016 WCHAR diskname[BUFFILE];
1017
1018 FILEDLG_StripEditControl(hWnd);
1019 lRet = SendDlgItemMessageW(hWnd, cmb2, CB_GETCURSEL, 0, 0L);
1020 if (lRet == LB_ERR)
1021 return 0;
1022 pstr = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC);
1023 SendDlgItemMessageW(hWnd, cmb2, CB_GETLBTEXT, lRet,
1024 (LPARAM)pstr);
1025 wsprintfW(diskname, FILE_specc, pstr[2]);
1026 HeapFree(GetProcessHeap(), 0, pstr);
1027
1028 return FILEDLG_Validate( lfs, diskname, cmb2, lRet, TRUE );
1029}
1030
1031
1032/***********************************************************************
1033 * FILEDLG_FileTypeChange [internal]
1034 * called when a new item is picked in the file type combo
1035 */
1036static LRESULT FILEDLG_FileTypeChange( LFSPRIVATE lfs )
1037{
1038 LONG lRet;
1039 WCHAR diskname[BUFFILE];
1040 LPWSTR pstr;
1041
1042 diskname[0] = 0;
1043
1044 lRet = SendDlgItemMessageW(lfs->hwnd, cmb1, CB_GETCURSEL, 0, 0);
1045 if (lRet == LB_ERR)
1046 return TRUE;
1047 pstr = (LPWSTR)SendDlgItemMessageW(lfs->hwnd, cmb1, CB_GETITEMDATA, lRet, 0);
1048 TRACE("Selected filter : %s\n", debugstr_w(pstr));
1049 SetDlgItemTextW( lfs->hwnd, edt1, pstr );
1050
1051 return FILEDLG_Validate( lfs, NULL, cmb1, lRet, TRUE );
1052}
1053
1054/***********************************************************************
1055 * FILEDLG_WMCommand [internal]
1056 */
1057static LRESULT FILEDLG_WMCommand(HWND hWnd, LPARAM lParam, UINT notification,
1058 UINT control, LFSPRIVATE lfs )
1059{
1060 switch (control)
1061 {
1062 case lst1: /* file list */
1063 FILEDLG_StripEditControl(hWnd);
1064 if (notification == LBN_DBLCLK)
1065 {
1066 if (FILEDLG_Validate( lfs, NULL, control, 0, FALSE ))
1067 EndDialog(hWnd, TRUE);
1068 return TRUE;
1069 }
1070 else if (notification == LBN_SELCHANGE)
1071 return FILEDLG_FileListSelect( lfs );
1072 break;
1073
1074 case lst2: /* directory list */
1075 FILEDLG_StripEditControl(hWnd);
1076 if (notification == LBN_DBLCLK)
1077 return FILEDLG_DirListDblClick( lfs );
1078 break;
1079
1080 case cmb1: /* file type drop list */
1081 if (notification == CBN_SELCHANGE)
1082 return FILEDLG_FileTypeChange( lfs );
1083 break;
1084
1085 case chx1:
1086 break;
1087
1088 case pshHelp:
1089 break;
1090
1091 case cmb2: /* disk dropdown combo */
1092 if (notification == CBN_SELCHANGE)
1093 return FILEDLG_DiskChange( lfs );
1094 break;
1095
1096 case IDOK:
1097 if (FILEDLG_Validate( lfs, NULL, control, 0, FALSE ))
1098 EndDialog(hWnd, TRUE);
1099 return TRUE;
1100
1101 case IDCANCEL:
1102 EndDialog(hWnd, FALSE);
1103 return TRUE;
1104
1105 case IDABORT: /* can be sent by the hook procedure */
1106 EndDialog(hWnd, TRUE);
1107 return TRUE;
1108 }
1109 return FALSE;
1110}
1111
1112#ifndef __WIN32OS2__
1113/***********************************************************************
1114 * FILEDLG_MapDrawItemStruct [internal]
1115 * map a 16 bits drawitem struct to 32
1116 */
1117void FILEDLG_MapDrawItemStruct(LPDRAWITEMSTRUCT16 lpdis16, LPDRAWITEMSTRUCT lpdis)
1118{
1119 lpdis->CtlType = lpdis16->CtlType;
1120 lpdis->CtlID = lpdis16->CtlID;
1121 lpdis->itemID = lpdis16->itemID;
1122 lpdis->itemAction = lpdis16->itemAction;
1123 lpdis->itemState = lpdis16->itemState;
1124 lpdis->hwndItem = lpdis16->hwndItem;
1125 lpdis->hDC = lpdis16->hDC;
1126 lpdis->rcItem.right = lpdis16->rcItem.right;
1127 lpdis->rcItem.left = lpdis16->rcItem.left;
1128 lpdis->rcItem.top = lpdis16->rcItem.top;
1129 lpdis->rcItem.bottom = lpdis16->rcItem.bottom;
1130 lpdis->itemData = lpdis16->itemData;
1131}
1132#endif
1133
1134/************************************************************************
1135 * FILEDLG_MapStringPairsToW [internal]
1136 * map string pairs to Unicode
1137 */
1138LPWSTR FILEDLG_MapStringPairsToW(LPCSTR strA, UINT size)
1139{
1140 LPCSTR s;
1141 LPWSTR x;
1142 int n, len;
1143
1144 s = strA;
1145 while (*s)
1146 s = s+strlen(s)+1;
1147 s++;
1148 n = s - strA;
1149 if (n < size) n = size;
1150
1151 len = MultiByteToWideChar( CP_ACP, 0, strA, n, NULL, 0 );
1152 x = HeapAlloc(GetProcessHeap(),0, len * sizeof(WCHAR));
1153 MultiByteToWideChar( CP_ACP, 0, strA, n, x, len );
1154 return x;
1155}
1156
1157
1158/************************************************************************
1159 * FILEDLG_DupToW [internal]
1160 * duplicates an Ansi string to unicode, with a buffer size
1161 */
1162LPWSTR FILEDLG_DupToW(LPCSTR str, DWORD size)
1163{
1164 LPWSTR strW = NULL;
1165 if (str && (size > 0))
1166 {
1167 strW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
1168 if (strW) MultiByteToWideChar( CP_ACP, 0, str, -1, strW, size );
1169 }
1170 return strW;
1171}
1172
1173
1174/************************************************************************
1175 * FILEDLG_MapOfnStructA [internal]
1176 * map a 32 bits Ansi structure to an Unicode one
1177 */
1178void FILEDLG_MapOfnStructA(LPOPENFILENAMEA ofnA, LPOPENFILENAMEW ofnW, BOOL open)
1179{
1180 LPCSTR str;
1181
1182 ofnW->lStructSize = sizeof(OPENFILENAMEW);
1183 ofnW->hwndOwner = ofnA->hwndOwner;
1184 ofnW->hInstance = ofnA->hInstance;
1185 if (ofnA->lpstrFilter)
1186 ofnW->lpstrFilter = FILEDLG_MapStringPairsToW(ofnA->lpstrFilter, 0);
1187 else
1188#ifdef __WIN32OS2__
1189 ofnW->lpstrFilter = NULL;
1190#else
1191 ofnW->lpstrFilter = FILEDLG_MapStringPairsToW(defaultfilter, 0);
1192#endif
1193
1194 if ((ofnA->lpstrCustomFilter) && (*(ofnA->lpstrCustomFilter)))
1195 ofnW->lpstrCustomFilter = FILEDLG_MapStringPairsToW(ofnA->lpstrCustomFilter, ofnA->nMaxCustFilter);
1196 ofnW->nMaxCustFilter = ofnA->nMaxCustFilter;
1197 ofnW->nFilterIndex = ofnA->nFilterIndex;
1198 ofnW->nMaxFile = ofnA->nMaxFile;
1199 ofnW->lpstrFile = FILEDLG_DupToW(ofnA->lpstrFile, ofnW->nMaxFile);
1200 ofnW->nMaxFileTitle = ofnA->nMaxFileTitle;
1201 ofnW->lpstrFileTitle = FILEDLG_DupToW(ofnA->lpstrFileTitle, ofnW->nMaxFileTitle);
1202 if (ofnA->lpstrInitialDir)
1203 ofnW->lpstrInitialDir = HEAP_strdupAtoW(GetProcessHeap(),0,ofnA->lpstrInitialDir);
1204 if (ofnA->lpstrTitle)
1205 str = ofnA->lpstrTitle;
1206 else
1207 /* Allocates default title (FIXME : get it from resource) */
1208 str = open ? defaultopen:defaultsave;
1209 ofnW->lpstrTitle = HEAP_strdupAtoW(GetProcessHeap(),0, str);
1210 ofnW->Flags = ofnA->Flags;
1211 ofnW->nFileOffset = ofnA->nFileOffset;
1212 ofnW->nFileExtension = ofnA->nFileExtension;
1213 ofnW->lpstrDefExt = FILEDLG_DupToW(ofnA->lpstrDefExt, 3);
1214 if ((ofnA->Flags & OFN_ENABLETEMPLATE) && (ofnA->lpTemplateName))
1215 {
1216 if (HIWORD(ofnA->lpTemplateName))
1217 ofnW->lpTemplateName = HEAP_strdupAtoW(GetProcessHeap(), 0, ofnA->lpTemplateName);
1218 else /* numbered resource */
1219 ofnW->lpTemplateName = (LPWSTR) ofnA->lpTemplateName;
1220 }
1221}
1222
1223#ifndef __WIN32OS2__
1224/************************************************************************
1225 * FILEDLG_MapOfnStruct16 [internal]
1226 * map a 16 bits structure to an Unicode one
1227 */
1228void FILEDLG_MapOfnStruct16(LPOPENFILENAME16 ofn16, LPOPENFILENAMEW ofnW, BOOL open)
1229{
1230 OPENFILENAMEA ofnA;
1231 /* first convert to linear pointers */
1232 memset(&ofnA, 0, sizeof(OPENFILENAMEA));
1233 ofnA.lStructSize = sizeof(OPENFILENAMEA);
1234 ofnA.hwndOwner = ofn16->hwndOwner;
1235 ofnA.hInstance = ofn16->hInstance;
1236 if (ofn16->lpstrFilter)
1237 ofnA.lpstrFilter = MapSL(ofn16->lpstrFilter);
1238 if (ofn16->lpstrCustomFilter)
1239 ofnA.lpstrCustomFilter = MapSL(ofn16->lpstrCustomFilter);
1240 ofnA.nMaxCustFilter = ofn16->nMaxCustFilter;
1241 ofnA.nFilterIndex = ofn16->nFilterIndex;
1242 ofnA.lpstrFile = MapSL(ofn16->lpstrFile);
1243 ofnA.nMaxFile = ofn16->nMaxFile;
1244 ofnA.lpstrFileTitle = MapSL(ofn16->lpstrFileTitle);
1245 ofnA.nMaxFileTitle = ofn16->nMaxFileTitle;
1246 ofnA.lpstrInitialDir = MapSL(ofn16->lpstrInitialDir);
1247 ofnA.lpstrTitle = MapSL(ofn16->lpstrTitle);
1248 ofnA.Flags = ofn16->Flags;
1249 ofnA.nFileOffset = ofn16->nFileOffset;
1250 ofnA.nFileExtension = ofn16->nFileExtension;
1251 ofnA.lpstrDefExt = MapSL(ofn16->lpstrDefExt);
1252 if (HIWORD(ofn16->lpTemplateName))
1253 ofnA.lpTemplateName = MapSL(ofn16->lpTemplateName);
1254 else
1255 ofnA.lpTemplateName = (LPSTR) ofn16->lpTemplateName; /* ressource number */
1256 /* now calls the 32 bits Ansi to Unicode version to complete the job */
1257 FILEDLG_MapOfnStructA(&ofnA, ofnW, open);
1258}
1259#endif
1260
1261/************************************************************************
1262 * FILEDLG_DestroyPrivate [internal]
1263 * destroys the private object
1264 */
1265void FILEDLG_DestroyPrivate(LFSPRIVATE lfs)
1266{
1267 HWND hwnd;
1268 if (!lfs) return;
1269 hwnd = lfs->hwnd;
1270 /* free resources for a 16 bits dialog */
1271 if (lfs->hResource16) FreeResource16(lfs->hResource16);
1272 if (lfs->hGlobal16)
1273 {
1274 GlobalUnlock16(lfs->hGlobal16);
1275 GlobalFree16(lfs->hGlobal16);
1276 }
1277 /* if ofnW has been allocated, have to free everything in it */
1278#ifndef __WIN32OS2__
1279 if (lfs->ofn16 || lfs->ofnA)
1280#else
1281 if (lfs->ofnA)
1282#endif
1283 {
1284 LPOPENFILENAMEW ofnW = lfs->ofnW;
1285 if (ofnW->lpstrFilter) HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpstrFilter);
1286 if (ofnW->lpstrCustomFilter) HeapFree(GetProcessHeap(), 0, ofnW->lpstrCustomFilter);
1287 if (ofnW->lpstrFile) HeapFree(GetProcessHeap(), 0, ofnW->lpstrFile);
1288 if (ofnW->lpstrFileTitle) HeapFree(GetProcessHeap(), 0, ofnW->lpstrFileTitle);
1289 if (ofnW->lpstrInitialDir) HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpstrInitialDir);
1290 if (ofnW->lpstrTitle) HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpstrTitle);
1291 if ((ofnW->lpTemplateName) && (HIWORD(ofnW->lpTemplateName)))
1292 HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpTemplateName);
1293 HeapFree(GetProcessHeap(), 0, ofnW);
1294 }
1295 TRACE("destroying private allocation %p\n", lfs);
1296 HeapFree(GetProcessHeap(), 0, lfs);
1297 RemovePropA(hwnd, OFN_PROP);
1298}
1299
1300/************************************************************************
1301 * FILEDLG_AllocPrivate [internal]
1302 * allocate a private object to hold 32 bits Unicode
1303 * structure that will be used throughtout the calls, while
1304 * keeping available the original structures and a few variables
1305 * On entry : type = dialog procedure type (16,32A,32W)
1306 * dlgType = dialog type (open or save)
1307 */
1308LFSPRIVATE FILEDLG_AllocPrivate(LPARAM lParam, int type, UINT dlgType)
1309{
1310 LFSPRIVATE lfs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct FSPRIVATE));
1311 LFSPRIVATE ret;
1312 TRACE("alloc private buf %p\n", lfs);
1313 if (!lfs) return NULL;
1314 lfs->hook = FALSE;
1315 lfs->lParam = lParam;
1316 if (dlgType == OPEN_DIALOG)
1317 lfs->open = TRUE;
1318 else
1319 lfs->open = FALSE;
1320 lfs->lbselchstring = RegisterWindowMessageA(LBSELCHSTRING);
1321 lfs->fileokstring = RegisterWindowMessageA(FILEOKSTRING);
1322 switch(type)
1323 {
1324#ifndef __WIN32OS2__
1325 case LFS16:
1326 lfs->ofn16 = MapSL(lParam);
1327 if (lfs->ofn16->Flags & OFN_ENABLEHOOK)
1328 if (lfs->ofn16->lpfnHook)
1329 lfs->hook = TRUE;
1330
1331 break;
1332#endif
1333 case LFS32A:
1334 lfs->ofnA = (LPOPENFILENAMEA) lParam;
1335 if (lfs->ofnA->Flags & OFN_ENABLEHOOK)
1336 if (lfs->ofnA->lpfnHook)
1337 lfs->hook = TRUE;
1338 break;
1339
1340 case LFS32W:
1341 lfs->ofnW = (LPOPENFILENAMEW) lParam;
1342 if (lfs->ofnW->Flags & OFN_ENABLEHOOK)
1343 if (lfs->ofnW->lpfnHook)
1344 lfs->hook = TRUE;
1345 break;
1346 }
1347 ret = lfs;
1348 if (!lfs->ofnW)
1349 { /* this structure is needed internally, so create it */
1350 lfs->ofnW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(OPENFILENAMEW));
1351 if (lfs->ofnW)
1352 {
1353#ifndef __WIN32OS2__
1354 if (lfs->ofn16)
1355 FILEDLG_MapOfnStruct16(lfs->ofn16, lfs->ofnW, lfs->open);
1356#endif
1357 if (lfs->ofnA)
1358 FILEDLG_MapOfnStructA(lfs->ofnA, lfs->ofnW, lfs->open);
1359 }
1360 else
1361 ret = NULL;
1362 }
1363#ifndef __WIN32OS2__
1364 if (lfs->ofn16)
1365 {
1366 if (!Get16BitsTemplate(lfs)) ret = NULL;
1367 }
1368 else
1369#endif
1370 if (!Get32BitsTemplate(lfs)) ret = NULL;
1371 if (!ret) FILEDLG_DestroyPrivate(lfs);
1372 return ret;
1373}
1374
1375
1376/***********************************************************************
1377 * GetFileName31A [internal]
1378 *
1379 * Creates a win31 style dialog box for the user to select a file to open/save.
1380 */
1381BOOL WINAPI GetFileName31A(
1382 LPOPENFILENAMEA lpofn, /* addess of structure with data*/
1383 UINT dlgType /* type dialogue : open/save */
1384 )
1385{
1386 HINSTANCE hInst;
1387 BOOL bRet = FALSE;
1388 LFSPRIVATE lfs;
1389
1390 if (!lpofn || !FileDlg_Init()) return FALSE;
1391
1392 lfs = FILEDLG_AllocPrivate((LPARAM) lpofn, LFS32A, dlgType);
1393 if (lfs)
1394 {
1395 hInst = GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );
1396 bRet = DialogBoxIndirectParamA( hInst, lfs->template, lpofn->hwndOwner,
1397 (DLGPROC) FileOpenDlgProc, (DWORD) lfs);
1398 FILEDLG_DestroyPrivate(lfs);
1399 }
1400
1401 TRACE("return lpstrFile='%s' !\n", lpofn->lpstrFile);
1402 return bRet;
1403}
1404
1405
1406/***********************************************************************
1407 * GetFileName31W [internal]
1408 *
1409 * Creates a win31 style dialog box for the user to select a file to open/save
1410 */
1411BOOL WINAPI GetFileName31W(
1412 LPOPENFILENAMEW lpofn, /* addess of structure with data*/
1413 UINT dlgType /* type dialogue : open/save */
1414 )
1415{
1416 HINSTANCE hInst;
1417 BOOL bRet = FALSE;
1418 LFSPRIVATE lfs;
1419
1420 if (!lpofn || !FileDlg_Init()) return FALSE;
1421
1422 lfs = FILEDLG_AllocPrivate((LPARAM) lpofn, LFS32W, dlgType);
1423 if (lfs)
1424 {
1425 hInst = GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );
1426 bRet = DialogBoxIndirectParamW( hInst, lfs->template, lpofn->hwndOwner,
1427 (DLGPROC) FileOpenDlgProc, (DWORD) lfs);
1428 FILEDLG_DestroyPrivate(lfs);
1429 }
1430
1431 TRACE("return lpstrFile='%s' !\n", debugstr_w(lpofn->lpstrFile));
1432 return bRet;
1433}
1434
1435
1436/* ------------------ Dialog procedures ---------------------- */
1437
1438#ifndef __WIN32OS2__
1439/***********************************************************************
1440 * FileOpenDlgProc16 (COMMDLG.6)
1441 */
1442LRESULT WINAPI FileOpenDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1443 LPARAM lParam)
1444{
1445 LFSPRIVATE lfs = (LFSPRIVATE)GetPropA(hWnd,OFN_PROP);
1446 DRAWITEMSTRUCT dis;
1447
1448 TRACE("msg=%x wparam=%x lParam=%lx\n", wMsg, wParam, lParam);
1449 if ((wMsg != WM_INITDIALOG) && lfs && lfs->hook)
1450 {
1451 LRESULT lRet = (BOOL16)FILEDLG_CallWindowProc(lfs, wMsg, wParam, lParam);
1452 if (lRet)
1453 return lRet; /* else continue message processing */
1454 }
1455 switch (wMsg)
1456 {
1457 case WM_INITDIALOG:
1458 return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
1459
1460 case WM_MEASUREITEM:
1461 return FILEDLG_WMMeasureItem16(hWnd, wParam, lParam);
1462
1463 case WM_DRAWITEM:
1464 FILEDLG_MapDrawItemStruct(MapSL(lParam), &dis);
1465 return FILEDLG_WMDrawItem(hWnd, wParam, lParam, FALSE, &dis);
1466
1467 case WM_COMMAND:
1468 return FILEDLG_WMCommand(hWnd, lParam, HIWORD(lParam),wParam, lfs);
1469#if 0
1470 case WM_CTLCOLOR:
1471 SetBkColor((HDC16)wParam, 0x00C0C0C0);
1472 switch (HIWORD(lParam))
1473 {
1474 case CTLCOLOR_BTN:
1475 SetTextColor((HDC16)wParam, 0x00000000);
1476 return hGRAYBrush;
1477 case CTLCOLOR_STATIC:
1478 SetTextColor((HDC16)wParam, 0x00000000);
1479 return hGRAYBrush;
1480 }
1481 break;
1482#endif
1483 }
1484 return FALSE;
1485}
1486
1487/***********************************************************************
1488 * FileSaveDlgProc16 (COMMDLG.7)
1489 */
1490LRESULT WINAPI FileSaveDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1491 LPARAM lParam)
1492{
1493 LFSPRIVATE lfs = (LFSPRIVATE)GetPropA(hWnd,OFN_PROP);
1494 DRAWITEMSTRUCT dis;
1495
1496 TRACE("msg=%x wparam=%x lParam=%lx\n", wMsg, wParam, lParam);
1497 if ((wMsg != WM_INITDIALOG) && lfs && lfs->hook)
1498 {
1499 LRESULT lRet;
1500 lRet = (BOOL16)FILEDLG_CallWindowProc(lfs, wMsg, wParam, lParam);
1501 if (lRet)
1502 return lRet; /* else continue message processing */
1503 }
1504 switch (wMsg) {
1505 case WM_INITDIALOG:
1506 return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
1507
1508 case WM_MEASUREITEM:
1509 return FILEDLG_WMMeasureItem16(hWnd, wParam, lParam);
1510
1511 case WM_DRAWITEM:
1512 FILEDLG_MapDrawItemStruct(MapSL(lParam), &dis);
1513 return FILEDLG_WMDrawItem(hWnd, wParam, lParam, TRUE, &dis);
1514
1515 case WM_COMMAND:
1516 return FILEDLG_WMCommand(hWnd, lParam, HIWORD(lParam), wParam, lfs);
1517 }
1518
1519 /*
1520 case WM_CTLCOLOR:
1521 SetBkColor((HDC16)wParam, 0x00C0C0C0);
1522 switch (HIWORD(lParam))
1523 {
1524 case CTLCOLOR_BTN:
1525 SetTextColor((HDC16)wParam, 0x00000000);
1526 return hGRAYBrush;
1527 case CTLCOLOR_STATIC:
1528 SetTextColor((HDC16)wParam, 0x00000000);
1529 return hGRAYBrush;
1530 }
1531 return FALSE;
1532
1533 */
1534 return FALSE;
1535}
1536#endif //__WIN32OS2__
1537
1538/***********************************************************************
1539 * FileOpenDlgProc [internal]
1540 * Used for open and save, in fact.
1541 */
1542static LRESULT WINAPI FileOpenDlgProc(HWND hWnd, UINT wMsg,
1543 WPARAM wParam, LPARAM lParam)
1544{
1545 LFSPRIVATE lfs = (LFSPRIVATE)GetPropA(hWnd,OFN_PROP);
1546
1547 TRACE("msg=%x wparam=%x lParam=%lx\n", wMsg, wParam, lParam);
1548 if ((wMsg != WM_INITDIALOG) && lfs && lfs->hook)
1549 {
1550 LRESULT lRet;
1551 lRet = (BOOL)FILEDLG_CallWindowProc(lfs, wMsg, wParam, lParam);
1552 if (lRet)
1553 return lRet; /* else continue message processing */
1554 }
1555 switch (wMsg)
1556 {
1557 case WM_INITDIALOG:
1558 return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
1559
1560 case WM_MEASUREITEM:
1561 return FILEDLG_WMMeasureItem(hWnd, wParam, lParam);
1562
1563 case WM_DRAWITEM:
1564 return FILEDLG_WMDrawItem(hWnd, wParam, lParam, !lfs->open, (DRAWITEMSTRUCT *)lParam);
1565
1566 case WM_COMMAND:
1567 return FILEDLG_WMCommand(hWnd, lParam, HIWORD(wParam), LOWORD(wParam), lfs);
1568#if 0
1569 case WM_CTLCOLOR:
1570 SetBkColor((HDC16)wParam, 0x00C0C0C0);
1571 switch (HIWORD(lParam))
1572 {
1573 case CTLCOLOR_BTN:
1574 SetTextColor((HDC16)wParam, 0x00000000);
1575 return hGRAYBrush;
1576 case CTLCOLOR_STATIC:
1577 SetTextColor((HDC16)wParam, 0x00000000);
1578 return hGRAYBrush;
1579 }
1580 break;
1581#endif
1582 }
1583 return FALSE;
1584}
1585
1586/* ------------------ APIs ---------------------- */
1587#ifndef __WIN32OS2__
1588/***********************************************************************
1589 * GetOpenFileName16 (COMMDLG.1)
1590 *
1591 * Creates a dialog box for the user to select a file to open.
1592 *
1593 * RETURNS
1594 * TRUE on success: user selected a valid file
1595 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1596 *
1597 * BUGS
1598 * unknown, there are some FIXME's left.
1599 */
1600BOOL16 WINAPI GetOpenFileName16(
1601 SEGPTR ofn /* [in/out] address of structure with data*/
1602 )
1603{
1604 HINSTANCE hInst;
1605 BOOL bRet = FALSE;
1606 LPOPENFILENAME16 lpofn = MapSL(ofn);
1607 LFSPRIVATE lfs;
1608 FARPROC16 ptr;
1609
1610 if (!lpofn || !FileDlg_Init()) return FALSE;
1611
1612 lfs = FILEDLG_AllocPrivate((LPARAM) ofn, LFS16, OPEN_DIALOG);
1613 if (lfs)
1614 {
1615 hInst = GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );
1616 ptr = GetProcAddress16(GetModuleHandle16("COMMDLG"), (LPCSTR) 6);
1617 bRet = DialogBoxIndirectParam16( hInst, lfs->hDlgTmpl16, lpofn->hwndOwner,
1618 (DLGPROC16) ptr, (DWORD) lfs);
1619 FILEDLG_DestroyPrivate(lfs);
1620 }
1621
1622 TRACE("return lpstrFile='%s' !\n", (char *)MapSL(lpofn->lpstrFile));
1623 return bRet;
1624}
1625
1626/***********************************************************************
1627 * GetSaveFileName16 (COMMDLG.2)
1628 *
1629 * Creates a dialog box for the user to select a file to save.
1630 *
1631 * RETURNS
1632 * TRUE on success: user enters a valid file
1633 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1634 *
1635 * BUGS
1636 * unknown. There are some FIXME's left.
1637 */
1638BOOL16 WINAPI GetSaveFileName16(
1639 SEGPTR ofn /* [in/out] addess of structure with data*/
1640 )
1641{
1642 HINSTANCE hInst;
1643 BOOL bRet = FALSE;
1644 LPOPENFILENAME16 lpofn = MapSL(ofn);
1645 LFSPRIVATE lfs;
1646 FARPROC16 ptr;
1647
1648 if (!lpofn || !FileDlg_Init()) return FALSE;
1649
1650 lfs = FILEDLG_AllocPrivate((LPARAM) ofn, LFS16, SAVE_DIALOG);
1651 if (lfs)
1652 {
1653 hInst = GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );
1654 ptr = GetProcAddress16(GetModuleHandle16("COMMDLG"), (LPCSTR) 7);
1655 bRet = DialogBoxIndirectParam16( hInst, lfs->hDlgTmpl16, lpofn->hwndOwner,
1656 (DLGPROC16) ptr, (DWORD) lfs);
1657 FILEDLG_DestroyPrivate(lfs);
1658 }
1659
1660 TRACE("return lpstrFile='%s' !\n", (char *)MapSL(lpofn->lpstrFile));
1661 return bRet;
1662}
1663#endif //__WIN32OS2__
1664
1665/***********************************************************************
1666 * GetOpenFileNameA (COMDLG32.10)
1667 *
1668 * Creates a dialog box for the user to select a file to open.
1669 *
1670 * RETURNS
1671 * TRUE on success: user enters a valid file
1672 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1673 *
1674 */
1675BOOL WINAPI GetOpenFileNameA(
1676 LPOPENFILENAMEA ofn) /* [in/out] address of init structure */
1677{
1678 BOOL newlook = TRUE; /* FIXME: TWEAK_WineLook */
1679
1680#ifdef __WIN32OS2__
1681 dprintf(("GetOpenFileNameA %x", ofn));
1682#endif
1683
1684 /* some flags don't allow to match the TWEAK_WineLook */
1685 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
1686 {
1687 newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
1688 }
1689
1690 if (newlook)
1691 {
1692 return GetFileDialog95A(ofn, OPEN_DIALOG);
1693 }
1694 else
1695 {
1696 return GetFileName31A(ofn, OPEN_DIALOG);
1697 }
1698}
1699
1700/***********************************************************************
1701 * GetOpenFileNameW (COMDLG32.11)
1702 *
1703 * Creates a dialog box for the user to select a file to open.
1704 *
1705 * RETURNS
1706 * TRUE on success: user enters a valid file
1707 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1708 *
1709 */
1710BOOL WINAPI GetOpenFileNameW(
1711 LPOPENFILENAMEW ofn) /* [in/out] address of init structure */
1712{
1713 BOOL newlook = TRUE; /* FIXME: TWEAK_WineLook */
1714
1715#ifdef __WIN32OS2__
1716 dprintf(("GetOpenFileNameW %x", ofn));
1717#endif
1718
1719 /* some flags don't allow to match the TWEAK_WineLook */
1720 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
1721 {
1722 newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
1723 }
1724
1725 if (newlook)
1726 {
1727 return GetFileDialog95W(ofn, OPEN_DIALOG);
1728 }
1729 else
1730 {
1731 return GetFileName31W(ofn, OPEN_DIALOG);
1732 }
1733}
1734
1735/***********************************************************************
1736 * GetSaveFileNameA (COMDLG32.12)
1737 *
1738 * Creates a dialog box for the user to select a file to save.
1739 *
1740 * RETURNS
1741 * TRUE on success: user enters a valid file
1742 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1743 *
1744 */
1745BOOL WINAPI GetSaveFileNameA(
1746 LPOPENFILENAMEA ofn) /* [in/out] address of init structure */
1747{
1748 BOOL newlook = TRUE; /* FIXME: TWEAK_WineLook */
1749
1750#ifdef __WIN32OS2__
1751 dprintf(("GetSaveFileNameA %x", ofn));
1752#endif
1753
1754 /* some flags don't allow to match the TWEAK_WineLook */
1755 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
1756 {
1757 newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
1758 }
1759
1760 if (newlook)
1761 {
1762 return GetFileDialog95A(ofn, SAVE_DIALOG);
1763 }
1764 else
1765 {
1766 return GetFileName31A(ofn, SAVE_DIALOG);
1767 }
1768}
1769
1770/***********************************************************************
1771 * GetSaveFileNameW (COMDLG32.13)
1772 *
1773 * Creates a dialog box for the user to select a file to save.
1774 *
1775 * RETURNS
1776 * TRUE on success: user enters a valid file
1777 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1778 *
1779 */
1780BOOL WINAPI GetSaveFileNameW(
1781 LPOPENFILENAMEW ofn) /* [in/out] address of init structure */
1782{
1783 BOOL newlook = TRUE; /* FIXME: TWEAK_WineLook */
1784
1785#ifdef __WIN32OS2__
1786 dprintf(("GetSaveFileNameW %x", ofn));
1787#endif
1788
1789 /* some flags don't allow to match the TWEAK_WineLook */
1790 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
1791 {
1792 newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
1793 }
1794
1795 if (newlook)
1796 {
1797 return GetFileDialog95W(ofn, SAVE_DIALOG);
1798 }
1799 else
1800 {
1801 return GetFileName31W(ofn, SAVE_DIALOG);
1802 }
1803}
Note: See TracBrowser for help on using the repository browser.