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

Last change on this file since 6688 was 6645, checked in by bird, 24 years ago

Added $Id:$ keyword.

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