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

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

Wine resync

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