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

Last change on this file since 10366 was 9522, checked in by sandervl, 23 years ago

bugfix

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