Release 20000326.
[wine/gsoc-2012-control.git] / dlls / commdlg / filedlg.c
blobb788edbd76c2725a83495ede8afcf37e7e827720
1 /*
2 * COMMDLG - File Dialogs
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 "winbase.h"
13 #include "wingdi.h"
14 #include "wine/winbase16.h"
15 #include "wine/winuser16.h"
16 #include "ldt.h"
17 #include "heap.h"
18 #include "commdlg.h"
19 #include "dialog.h"
20 #include "dlgs.h"
21 #include "module.h"
22 #include "drive.h"
23 #include "debugtools.h"
24 #include "winproc.h"
25 #include "cderr.h"
26 #include "tweak.h"
28 DEFAULT_DEBUG_CHANNEL(commdlg);
30 #include "cdlg.h"
32 static HICON16 hFolder = 0;
33 static HICON16 hFolder2 = 0;
34 static HICON16 hFloppy = 0;
35 static HICON16 hHDisk = 0;
36 static HICON16 hCDRom = 0;
37 static HICON16 hNet = 0;
38 static int fldrHeight = 0;
39 static int fldrWidth = 0;
41 static const char defaultfilter[]=" \0\0";
42 #define OFN_PROP "FILEDLG_OFN_LPARAM"
44 /***********************************************************************
46 * Windows 3.1 OpenFileName/SaveFileName dialog
49 /***********************************************************************
50 * FileDlg_Init [internal]
52 static BOOL FileDlg_Init(void)
54 static BOOL initialized = 0;
55 CURSORICONINFO *fldrInfo;
57 if (!initialized) {
58 if (!hFolder) hFolder = LoadIcon16(0, MAKEINTRESOURCE16(OIC_FOLDER));
59 if (!hFolder2) hFolder2 = LoadIcon16(0, MAKEINTRESOURCE16(OIC_FOLDER2));
60 if (!hFloppy) hFloppy = LoadIcon16(0, MAKEINTRESOURCE16(OIC_FLOPPY));
61 if (!hHDisk) hHDisk = LoadIcon16(0, MAKEINTRESOURCE16(OIC_HDISK));
62 if (!hCDRom) hCDRom = LoadIcon16(0, MAKEINTRESOURCE16(OIC_CDROM));
63 if (!hNet) hNet = LoadIcon16(0, MAKEINTRESOURCE16(OIC_NETWORK));
64 if (hFolder == 0 || hFolder2 == 0 || hFloppy == 0 ||
65 hHDisk == 0 || hCDRom == 0 || hNet == 0)
67 ERR("Error loading icons !\n");
68 return FALSE;
70 fldrInfo = (CURSORICONINFO *) GlobalLock16( hFolder2 );
71 if (!fldrInfo)
73 ERR("Error measuring icons !\n");
74 return FALSE;
76 fldrHeight = fldrInfo -> nHeight;
77 fldrWidth = fldrInfo -> nWidth;
78 GlobalUnlock16( hFolder2 );
79 initialized = TRUE;
81 return TRUE;
84 /***********************************************************************
85 * FileOpenDlgProc [internal]
87 * FIXME: Convert to real 32-bit message processing
89 static LRESULT WINAPI FileOpenDlgProc(HWND hDlg, UINT msg,
90 WPARAM wParam, LPARAM lParam)
92 UINT16 msg16;
93 MSGPARAM16 mp16;
95 mp16.lParam = lParam;
96 if (WINPROC_MapMsg32ATo16( hDlg, msg, wParam,
97 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
98 return 0;
99 mp16.lResult = FileOpenDlgProc16( (HWND16)hDlg, msg16,
100 mp16.wParam, mp16.lParam );
102 WINPROC_UnmapMsg32ATo16( hDlg, msg, wParam, lParam, &mp16 );
103 return mp16.lResult;
106 /***********************************************************************
107 * FileSaveDlgProc [internal]
109 * FIXME: Convert to real 32-bit message processing
111 static LRESULT WINAPI FileSaveDlgProc(HWND hDlg, UINT msg,
112 WPARAM wParam, LPARAM lParam)
114 UINT16 msg16;
115 MSGPARAM16 mp16;
117 mp16.lParam = lParam;
118 if (WINPROC_MapMsg32ATo16( hDlg, msg, wParam,
119 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
120 return 0;
121 mp16.lResult = FileSaveDlgProc16( (HWND16)hDlg, msg16,
122 mp16.wParam, mp16.lParam );
124 WINPROC_UnmapMsg32ATo16( hDlg, msg, wParam, lParam, &mp16 );
125 return mp16.lResult;
128 /***********************************************************************
129 * GetOpenFileName16 (COMMDLG.1)
131 * Creates a dialog box for the user to select a file to open.
133 * RETURNS
134 * TRUE on success: user selected a valid file
135 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
137 * BUGS
138 * unknown, there are some FIXME's left.
140 BOOL16 WINAPI GetOpenFileName16(
141 SEGPTR ofn /* addess of structure with data*/
144 HINSTANCE hInst;
145 HANDLE hDlgTmpl = 0, hResInfo;
146 BOOL bRet = FALSE, win32Format = FALSE;
147 HWND hwndDialog;
148 LPOPENFILENAME16 lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(ofn);
149 LPCVOID template;
150 char defaultopen[]="Open File";
151 char *str=0,*str1=0;
153 if (!lpofn || !FileDlg_Init()) return FALSE;
155 if (lpofn->Flags & OFN_WINE) {
156 if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE)
158 if (!(template = LockResource( MapHModuleSL(lpofn->hInstance ))))
160 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
161 return FALSE;
164 else if (lpofn->Flags & OFN_ENABLETEMPLATE)
166 if (!(hResInfo = FindResourceA(MapHModuleSL(lpofn->hInstance),
167 PTR_SEG_TO_LIN(lpofn->lpTemplateName), RT_DIALOGA)))
169 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
170 return FALSE;
172 if (!(hDlgTmpl = LoadResource( MapHModuleSL(lpofn->hInstance),
173 hResInfo )) ||
174 !(template = LockResource( hDlgTmpl )))
176 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
177 return FALSE;
179 } else {
180 if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "OPEN_FILE", RT_DIALOGA)))
182 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
183 return FALSE;
185 if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
186 !(template = LockResource( hDlgTmpl )))
188 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
189 return FALSE;
192 win32Format = TRUE;
193 } else {
194 if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE)
196 if (!(template = LockResource16( lpofn->hInstance )))
198 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
199 return FALSE;
202 else if (lpofn->Flags & OFN_ENABLETEMPLATE)
204 if (!(hResInfo = FindResource16(lpofn->hInstance,
205 lpofn->lpTemplateName,
206 RT_DIALOG16)))
208 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
209 return FALSE;
211 if (!(hDlgTmpl = LoadResource16( lpofn->hInstance, hResInfo )) ||
212 !(template = LockResource16( hDlgTmpl )))
214 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
215 return FALSE;
217 } else {
218 if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "OPEN_FILE", RT_DIALOGA)))
220 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
221 return FALSE;
223 if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
224 !(template = LockResource( hDlgTmpl )))
226 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
227 return FALSE;
229 win32Format = TRUE;
233 hInst = GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );
235 if (!(lpofn->lpstrFilter))
237 str = SEGPTR_ALLOC(sizeof(defaultfilter));
238 TRACE("Alloc %p default for Filetype in GetOpenFileName\n",str);
239 memcpy(str,defaultfilter,sizeof(defaultfilter));
240 lpofn->lpstrFilter=SEGPTR_GET(str);
243 if (!(lpofn->lpstrTitle))
245 str1 = SEGPTR_ALLOC(strlen(defaultopen)+1);
246 TRACE("Alloc %p default for Title in GetOpenFileName\n",str1);
247 strcpy(str1,defaultopen);
248 lpofn->lpstrTitle=SEGPTR_GET(str1);
251 /* FIXME: doesn't handle win32 format correctly yet */
252 hwndDialog = DIALOG_CreateIndirect( hInst, template, win32Format,
253 lpofn->hwndOwner,
254 (DLGPROC16)FileOpenDlgProc,
255 ofn, WIN_PROC_32A );
256 if (hwndDialog) bRet = DIALOG_DoDialogBox( hwndDialog, lpofn->hwndOwner );
258 if (str1)
260 TRACE("Freeing %p default for Title in GetOpenFileName\n",str1);
261 SEGPTR_FREE(str1);
262 lpofn->lpstrTitle=0;
265 if (str)
267 TRACE("Freeing %p default for Filetype in GetOpenFileName\n",str);
268 SEGPTR_FREE(str);
269 lpofn->lpstrFilter=0;
272 if (hDlgTmpl) {
273 if (lpofn->Flags & OFN_WINE)
274 FreeResource( hDlgTmpl );
275 else
276 FreeResource16( hDlgTmpl );
279 TRACE("return lpstrFile='%s' !\n",
280 (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
281 return bRet;
285 /***********************************************************************
286 * GetSaveFileName (COMMDLG.2)
288 * Creates a dialog box for the user to select a file to save.
290 * RETURNS
291 * TRUE on succes: user enters a valid file
292 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
294 * BUGS
295 * unknown. There are some FIXME's left.
297 BOOL16 WINAPI GetSaveFileName16(
298 SEGPTR ofn /* addess of structure with data*/
301 HINSTANCE hInst;
302 HANDLE hDlgTmpl = 0;
303 BOOL bRet = FALSE, win32Format = FALSE;
304 LPOPENFILENAME16 lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(ofn);
305 LPCVOID template;
306 HWND hwndDialog;
307 char defaultsave[]="Save as";
308 char *str =0,*str1=0;
310 if (!lpofn || !FileDlg_Init()) return FALSE;
312 if (lpofn->Flags & OFN_WINE) {
313 if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE)
315 if (!(template = LockResource( MapHModuleSL(lpofn->hInstance ))))
317 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
318 return FALSE;
321 else if (lpofn->Flags & OFN_ENABLETEMPLATE)
323 HANDLE hResInfo;
324 if (!(hResInfo = FindResourceA(MapHModuleSL(lpofn->hInstance),
325 PTR_SEG_TO_LIN(lpofn->lpTemplateName),
326 RT_DIALOGA)))
328 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
329 return FALSE;
331 if (!(hDlgTmpl = LoadResource(MapHModuleSL(lpofn->hInstance),
332 hResInfo)) ||
333 !(template = LockResource(hDlgTmpl)))
335 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
336 return FALSE;
338 win32Format= TRUE;
339 } else {
340 HANDLE hResInfo;
341 if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "SAVE_FILE", RT_DIALOGA)))
343 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
344 return FALSE;
346 if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
347 !(template = LockResource( hDlgTmpl )))
349 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
350 return FALSE;
352 win32Format = TRUE;
354 } else {
355 if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE)
357 if (!(template = LockResource16( lpofn->hInstance )))
359 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
360 return FALSE;
363 else if (lpofn->Flags & OFN_ENABLETEMPLATE)
365 HANDLE16 hResInfo;
366 if (!(hResInfo = FindResource16(lpofn->hInstance,
367 lpofn->lpTemplateName,
368 RT_DIALOG16)))
370 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
371 return FALSE;
373 if (!(hDlgTmpl = LoadResource16( lpofn->hInstance, hResInfo )) ||
374 !(template = LockResource16( hDlgTmpl )))
376 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
377 return FALSE;
379 } else {
380 HANDLE hResInfo;
381 if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "SAVE_FILE", RT_DIALOGA)))
383 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
384 return FALSE;
386 if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
387 !(template = LockResource( hDlgTmpl )))
389 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
390 return FALSE;
392 win32Format = TRUE;
396 hInst = GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );
398 if (!(lpofn->lpstrFilter))
400 str = SEGPTR_ALLOC(sizeof(defaultfilter));
401 TRACE("Alloc default for Filetype in GetSaveFileName\n");
402 memcpy(str,defaultfilter,sizeof(defaultfilter));
403 lpofn->lpstrFilter=SEGPTR_GET(str);
406 if (!(lpofn->lpstrTitle))
408 str1 = SEGPTR_ALLOC(sizeof(defaultsave)+1);
409 TRACE("Alloc default for Title in GetSaveFileName\n");
410 strcpy(str1,defaultsave);
411 lpofn->lpstrTitle=SEGPTR_GET(str1);
414 hwndDialog = DIALOG_CreateIndirect( hInst, template, win32Format,
415 lpofn->hwndOwner,
416 (DLGPROC16)FileSaveDlgProc,
417 ofn, WIN_PROC_32A );
418 if (hwndDialog) bRet = DIALOG_DoDialogBox( hwndDialog, lpofn->hwndOwner );
420 if (str1)
422 TRACE("Freeing %p default for Title in GetSaveFileName\n",str1);
423 SEGPTR_FREE(str1);
424 lpofn->lpstrTitle=0;
427 if (str)
429 TRACE("Freeing %p default for Filetype in GetSaveFileName\n",str);
430 SEGPTR_FREE(str);
431 lpofn->lpstrFilter=0;
434 if (hDlgTmpl) {
435 if (lpofn->Flags & OFN_WINE)
436 FreeResource( hDlgTmpl );
437 else
438 FreeResource16( hDlgTmpl );
441 TRACE("return lpstrFile='%s' !\n",
442 (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
443 return bRet;
446 /***********************************************************************
447 * FILEDLG_StripEditControl [internal]
448 * Strip pathnames off the contents of the edit control.
450 static void FILEDLG_StripEditControl(HWND16 hwnd)
452 char temp[512], *cp;
454 GetDlgItemTextA( hwnd, edt1, temp, sizeof(temp) );
455 cp = strrchr(temp, '\\');
456 if (cp != NULL) {
457 strcpy(temp, cp+1);
459 cp = strrchr(temp, ':');
460 if (cp != NULL) {
461 strcpy(temp, cp+1);
463 /* FIXME: shouldn't we do something with the result here? ;-) */
466 /***********************************************************************
467 * FILEDLG_ScanDir [internal]
469 static BOOL FILEDLG_ScanDir(HWND16 hWnd, LPSTR newPath)
471 char buffer[512];
472 char* str = buffer;
473 int drive;
474 HWND hlb;
476 lstrcpynA(buffer, newPath, sizeof(buffer));
478 if (str[0] && (str[1] == ':')) {
479 drive = toupper(str[0]) - 'A';
480 str += 2;
481 if (!DRIVE_SetCurrentDrive(drive))
482 return FALSE;
483 } else {
484 drive = DRIVE_GetCurrentDrive();
487 if (str[0] && !DRIVE_Chdir(drive, str)) {
488 return FALSE;
491 GetDlgItemTextA(hWnd, edt1, buffer, sizeof(buffer));
492 if ((hlb = GetDlgItem(hWnd, lst1)) != 0) {
493 char* scptr; /* ptr on semi-colon */
494 char* filter = buffer;
496 TRACE("Using filter %s\n", filter);
497 SendMessageA(hlb, LB_RESETCONTENT, 0, 0);
498 while (filter) {
499 scptr = strchr(filter, ';');
500 if (scptr) *scptr = 0;
501 TRACE("Using file spec %s\n", filter);
502 if (SendMessageA(hlb, LB_DIR, 0, (LPARAM)filter) == LB_ERR)
503 return FALSE;
504 if (scptr) *scptr = ';';
505 filter = (scptr) ? (scptr + 1) : 0;
509 strcpy(buffer, "*.*");
510 return DlgDirListA(hWnd, buffer, lst2, stc1, DDL_EXCLUSIVE | DDL_DIRECTORY);
513 /***********************************************************************
514 * FILEDLG_GetFileType [internal]
517 static LPSTR FILEDLG_GetFileType(LPSTR cfptr, LPSTR fptr, WORD index)
519 int n, i;
520 i = 0;
521 if (cfptr)
522 for ( ;(n = strlen(cfptr)) != 0; i++)
524 cfptr += n + 1;
525 if (i == index)
526 return cfptr;
527 cfptr += strlen(cfptr) + 1;
529 if (fptr)
530 for ( ;(n = strlen(fptr)) != 0; i++)
532 fptr += n + 1;
533 if (i == index)
534 return fptr;
535 fptr += strlen(fptr) + 1;
537 return "*.*"; /* FIXME */
540 /***********************************************************************
541 * FILEDLG_WMDrawItem [internal]
543 static LONG FILEDLG_WMDrawItem(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam,int savedlg)
545 LPDRAWITEMSTRUCT16 lpdis = (LPDRAWITEMSTRUCT16)PTR_SEG_TO_LIN(lParam);
546 char *str;
547 HICON16 hIcon;
548 COLORREF oldText = 0, oldBk = 0;
550 if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst1)
552 if (!(str = SEGPTR_ALLOC(512))) return FALSE;
553 SendMessage16(lpdis->hwndItem, LB_GETTEXT16, lpdis->itemID,
554 (LPARAM)SEGPTR_GET(str));
556 if ((lpdis->itemState & ODS_SELECTED) && !savedlg)
558 oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
559 oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
561 if (savedlg)
562 SetTextColor(lpdis->hDC,GetSysColor(COLOR_GRAYTEXT) );
564 ExtTextOut16(lpdis->hDC, lpdis->rcItem.left + 1,
565 lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
566 &(lpdis->rcItem), str, strlen(str), NULL);
568 if (lpdis->itemState & ODS_SELECTED)
569 DrawFocusRect16( lpdis->hDC, &(lpdis->rcItem) );
571 if ((lpdis->itemState & ODS_SELECTED) && !savedlg)
573 SetBkColor( lpdis->hDC, oldBk );
574 SetTextColor( lpdis->hDC, oldText );
576 SEGPTR_FREE(str);
577 return TRUE;
580 if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst2)
582 if (!(str = SEGPTR_ALLOC(512))) return FALSE;
583 SendMessage16(lpdis->hwndItem, LB_GETTEXT16, lpdis->itemID,
584 (LPARAM)SEGPTR_GET(str));
586 if (lpdis->itemState & ODS_SELECTED)
588 oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
589 oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
591 ExtTextOut16(lpdis->hDC, lpdis->rcItem.left + fldrWidth,
592 lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
593 &(lpdis->rcItem), str, strlen(str), NULL);
595 if (lpdis->itemState & ODS_SELECTED)
596 DrawFocusRect16( lpdis->hDC, &(lpdis->rcItem) );
598 if (lpdis->itemState & ODS_SELECTED)
600 SetBkColor( lpdis->hDC, oldBk );
601 SetTextColor( lpdis->hDC, oldText );
603 DrawIcon(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hFolder);
604 SEGPTR_FREE(str);
605 return TRUE;
607 if (lpdis->CtlType == ODT_COMBOBOX && lpdis->CtlID == cmb2)
609 if (!(str = SEGPTR_ALLOC(512))) return FALSE;
610 SendMessage16(lpdis->hwndItem, CB_GETLBTEXT16, lpdis->itemID,
611 (LPARAM)SEGPTR_GET(str));
612 switch(DRIVE_GetType( str[2] - 'a' ))
614 case TYPE_FLOPPY: hIcon = hFloppy; break;
615 case TYPE_CDROM: hIcon = hCDRom; break;
616 case TYPE_NETWORK: hIcon = hNet; break;
617 case TYPE_HD:
618 default: hIcon = hHDisk; break;
620 if (lpdis->itemState & ODS_SELECTED)
622 oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
623 oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
625 ExtTextOut16(lpdis->hDC, lpdis->rcItem.left + fldrWidth,
626 lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
627 &(lpdis->rcItem), str, strlen(str), NULL);
629 if (lpdis->itemState & ODS_SELECTED)
631 SetBkColor( lpdis->hDC, oldBk );
632 SetTextColor( lpdis->hDC, oldText );
634 DrawIcon(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hIcon);
635 SEGPTR_FREE(str);
636 return TRUE;
638 return FALSE;
641 /***********************************************************************
642 * FILEDLG_WMMeasureItem [internal]
644 static LONG FILEDLG_WMMeasureItem(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam)
646 LPMEASUREITEMSTRUCT16 lpmeasure;
648 lpmeasure = (LPMEASUREITEMSTRUCT16)PTR_SEG_TO_LIN(lParam);
649 lpmeasure->itemHeight = fldrHeight;
650 return TRUE;
653 /***********************************************************************
654 * FILEDLG_HookCallChk [internal]
656 static int FILEDLG_HookCallChk(LPOPENFILENAME16 lpofn)
658 if (lpofn)
659 if (lpofn->Flags & OFN_ENABLEHOOK)
660 if (lpofn->lpfnHook)
661 return 1;
662 return 0;
665 /***********************************************************************
666 * FILEDLG_CallWindowProc [internal]
668 * Adapt the structures back for win32 calls so the callee can read lpCustData
670 static BOOL FILEDLG_CallWindowProc(LPOPENFILENAME16 lpofn,HWND hwnd,
671 UINT wMsg,WPARAM wParam,LPARAM lParam
674 BOOL needstruct;
675 BOOL result = FALSE;
676 WINDOWPROCTYPE ProcType; /* Type of Hook Function to be called. */
678 /* TRUE if lParam points to the OPENFILENAME16 Structure */
679 needstruct = (PTR_SEG_TO_LIN(lParam) == lpofn);
681 ProcType = (lpofn->Flags & OFN_WINE)
682 ? (lpofn->Flags & OFN_UNICODE) /* 32-Bit call to GetOpenFileName */
683 ? WIN_PROC_32W : WIN_PROC_32A
684 : WIN_PROC_16; /* 16-Bit call to GetOpenFileName */
686 if (!(lpofn->Flags & OFN_WINE))
687 /* Call to 16-Bit Hooking function... No Problem at all. */
688 return (BOOL)CallWindowProc16(
689 (WNDPROC16)lpofn->lpfnHook,hwnd,(UINT16)wMsg,(WPARAM16)wParam,lParam
691 /* |OFN_WINE32 */
692 if (needstruct)
694 /* Parameter lParam points to lpofn... Convert Structure Data... */
695 if (lpofn->Flags & OFN_UNICODE)
697 OPENFILENAMEW ofnw;
699 /* FIXME: probably needs more converted */
700 ofnw.lCustData = lpofn->lCustData;
701 return (BOOL)CallWindowProcW(
702 (WNDPROC)lpofn->lpfnHook,hwnd,wMsg,wParam,(LPARAM)&ofnw
705 else /* ! |OFN_UNICODE */
707 OPENFILENAMEA ofna;
709 /* FIXME: probably needs more converted */
710 ofna.lCustData = lpofn->lCustData;
711 return (BOOL)CallWindowProcA(
712 (WNDPROC)lpofn->lpfnHook,hwnd,wMsg,wParam,(LPARAM)&ofna
716 else /* ! needstruct */
718 HWINDOWPROC hWindowProc=NULL;
720 if (WINPROC_SetProc(&hWindowProc, (WNDPROC16)lpofn->lpfnHook, ProcType, WIN_PROC_WINDOW))
722 /* Call Window Procedure converting 16-Bit Type Parameters to 32-Bit Type Parameters */
723 result = CallWindowProc16( (WNDPROC16)hWindowProc,
724 hwnd, wMsg, wParam, lParam );
726 result = LOWORD(result);
728 WINPROC_FreeProc( hWindowProc, WIN_PROC_WINDOW );
731 return result;
737 /***********************************************************************
738 * FILEDLG_WMInitDialog [internal]
741 static LONG FILEDLG_WMInitDialog(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam)
743 int i, n;
744 LPOPENFILENAME16 lpofn;
745 char tmpstr[512];
746 LPSTR pstr, old_pstr;
747 SetPropA(hWnd,OFN_PROP,lParam);
748 lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(lParam);
749 if (lpofn->lpstrTitle) SetWindowText16( hWnd, lpofn->lpstrTitle );
750 /* read custom filter information */
751 if (lpofn->lpstrCustomFilter)
753 pstr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter);
754 n = 0;
755 TRACE("lpstrCustomFilter = %p\n", pstr);
756 while(*pstr)
758 old_pstr = pstr;
759 i = SendDlgItemMessage16(hWnd, cmb1, CB_ADDSTRING16, 0,
760 (LPARAM)lpofn->lpstrCustomFilter + n );
761 n += strlen(pstr) + 1;
762 pstr += strlen(pstr) + 1;
763 TRACE("add str='%s' "
764 "associated to '%s'\n", old_pstr, pstr);
765 SendDlgItemMessage16(hWnd, cmb1, CB_SETITEMDATA16, i, (LPARAM)pstr);
766 n += strlen(pstr) + 1;
767 pstr += strlen(pstr) + 1;
770 /* read filter information */
771 if (lpofn->lpstrFilter) {
772 pstr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFilter);
773 n = 0;
774 while(*pstr) {
775 old_pstr = pstr;
776 i = SendDlgItemMessage16(hWnd, cmb1, CB_ADDSTRING16, 0,
777 (LPARAM)lpofn->lpstrFilter + n );
778 n += strlen(pstr) + 1;
779 pstr += strlen(pstr) + 1;
780 TRACE("add str='%s' "
781 "associated to '%s'\n", old_pstr, pstr);
782 SendDlgItemMessage16(hWnd, cmb1, CB_SETITEMDATA16, i, (LPARAM)pstr);
783 n += strlen(pstr) + 1;
784 pstr += strlen(pstr) + 1;
787 /* set default filter */
788 if (lpofn->nFilterIndex == 0 && lpofn->lpstrCustomFilter == (SEGPTR)NULL)
789 lpofn->nFilterIndex = 1;
790 SendDlgItemMessage16(hWnd, cmb1, CB_SETCURSEL16, lpofn->nFilterIndex - 1, 0);
791 lstrcpynA(tmpstr, FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter),
792 PTR_SEG_TO_LIN(lpofn->lpstrFilter), lpofn->nFilterIndex - 1),512);
793 TRACE("nFilterIndex = %ld, SetText of edt1 to '%s'\n",
794 lpofn->nFilterIndex, tmpstr);
795 SetDlgItemTextA( hWnd, edt1, tmpstr );
796 /* get drive list */
797 *tmpstr = 0;
798 DlgDirListComboBoxA(hWnd, tmpstr, cmb2, 0, DDL_DRIVES | DDL_EXCLUSIVE);
799 /* read initial directory */
800 if (PTR_SEG_TO_LIN(lpofn->lpstrInitialDir) != NULL)
802 int len;
803 lstrcpynA(tmpstr, PTR_SEG_TO_LIN(lpofn->lpstrInitialDir), 511);
804 len=strlen(tmpstr);
805 if (len > 0 && tmpstr[len-1] != '\\' && tmpstr[len-1] != ':') {
806 tmpstr[len]='\\';
807 tmpstr[len+1]='\0';
810 else
811 *tmpstr = 0;
812 if (!FILEDLG_ScanDir(hWnd, tmpstr)) {
813 *tmpstr = 0;
814 if (!FILEDLG_ScanDir(hWnd, tmpstr))
815 WARN("Couldn't read initial directory %s!\n",tmpstr);
817 /* select current drive in combo 2, omit missing drives */
818 for(i=0, n=-1; i<=DRIVE_GetCurrentDrive(); i++)
819 if (DRIVE_IsValid(i)) n++;
820 SendDlgItemMessage16(hWnd, cmb2, CB_SETCURSEL16, n, 0);
821 if (!(lpofn->Flags & OFN_SHOWHELP))
822 ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
823 if (lpofn->Flags & OFN_HIDEREADONLY)
824 ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
825 if (FILEDLG_HookCallChk(lpofn))
826 return (BOOL16)FILEDLG_CallWindowProc(lpofn,hWnd,WM_INITDIALOG,wParam,lParam );
827 else
828 return TRUE;
831 /***********************************************************************
832 * FILEDLG_WMCommand [internal]
834 BOOL in_update=FALSE;
836 static LRESULT FILEDLG_WMCommand(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam)
838 LONG lRet;
839 LPOPENFILENAME16 lpofn;
840 OPENFILENAME16 ofn2;
841 char tmpstr[512], tmpstr2[512];
842 LPSTR pstr, pstr2;
843 UINT16 control,notification;
845 /* Notifications are packaged differently in Win32 */
846 control = wParam;
847 notification = HIWORD(lParam);
849 lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(GetPropA(hWnd,OFN_PROP));
850 switch (control)
852 case lst1: /* file list */
853 FILEDLG_StripEditControl(hWnd);
854 if (notification == LBN_DBLCLK)
855 goto almost_ok;
856 lRet = SendDlgItemMessage16(hWnd, lst1, LB_GETCURSEL16, 0, 0);
857 if (lRet == LB_ERR) return TRUE;
858 if ((pstr = SEGPTR_ALLOC(512)))
860 SendDlgItemMessage16(hWnd, lst1, LB_GETTEXT16, lRet,
861 (LPARAM)SEGPTR_GET(pstr));
862 SetDlgItemTextA( hWnd, edt1, pstr );
863 SEGPTR_FREE(pstr);
865 if (FILEDLG_HookCallChk(lpofn))
866 FILEDLG_CallWindowProc(lpofn,hWnd,
867 RegisterWindowMessageA( LBSELCHSTRING ),
868 control, MAKELONG(lRet,CD_LBSELCHANGE));
869 /* FIXME: for OFN_ALLOWMULTISELECT we need CD_LBSELSUB, CD_SELADD, CD_LBSELNOITEMS */
870 return TRUE;
871 case lst2: /* directory list */
872 FILEDLG_StripEditControl(hWnd);
873 if (notification == LBN_DBLCLK)
875 lRet = SendDlgItemMessage16(hWnd, lst2, LB_GETCURSEL16, 0, 0);
876 if (lRet == LB_ERR) return TRUE;
877 pstr = SEGPTR_ALLOC(512);
878 SendDlgItemMessage16(hWnd, lst2, LB_GETTEXT16, lRet,
879 (LPARAM)SEGPTR_GET(pstr));
880 strcpy( tmpstr, pstr );
881 SEGPTR_FREE(pstr);
882 if (tmpstr[0] == '[')
884 tmpstr[strlen(tmpstr) - 1] = 0;
885 strcpy(tmpstr,tmpstr+1);
887 strcat(tmpstr, "\\");
888 goto reset_scan;
890 return TRUE;
891 case cmb1: /* file type drop list */
892 if (notification == CBN_SELCHANGE)
894 *tmpstr = 0;
895 goto reset_scan;
897 return TRUE;
898 case chx1:
899 return TRUE;
900 case pshHelp:
901 return TRUE;
902 case cmb2: /* disk drop list */
903 FILEDLG_StripEditControl(hWnd);
904 lRet = SendDlgItemMessage16(hWnd, cmb2, CB_GETCURSEL16, 0, 0L);
905 if (lRet == LB_ERR) return 0;
906 pstr = SEGPTR_ALLOC(512);
907 SendDlgItemMessage16(hWnd, cmb2, CB_GETLBTEXT16, lRet,
908 (LPARAM)SEGPTR_GET(pstr));
909 sprintf(tmpstr, "%c:", pstr[2]);
910 SEGPTR_FREE(pstr);
911 if (notification != CBN_SELCHANGE) return TRUE;
912 reset_scan:
913 lRet = SendDlgItemMessage16(hWnd, cmb1, CB_GETCURSEL16, 0, 0);
914 if (lRet == LB_ERR)
915 return TRUE;
916 pstr = (LPSTR)SendDlgItemMessage16(hWnd, cmb1, CB_GETITEMDATA16, lRet, 0);
917 TRACE("Selected filter : %s\n", pstr);
918 SetDlgItemTextA( hWnd, edt1, pstr );
919 FILEDLG_ScanDir(hWnd, tmpstr);
920 in_update=TRUE;
921 case IDOK:
922 almost_ok:
923 ofn2=*lpofn; /* for later restoring */
924 GetDlgItemTextA( hWnd, edt1, tmpstr, sizeof(tmpstr) );
925 pstr = strrchr(tmpstr, '\\');
926 if (pstr == NULL)
927 pstr = strrchr(tmpstr, ':');
928 if (strchr(tmpstr,'*') != NULL || strchr(tmpstr,'?') != NULL)
930 /* edit control contains wildcards */
931 if (pstr != NULL)
933 lstrcpynA(tmpstr2, pstr+1, 512);
934 *(pstr+1) = 0;
936 else
938 strcpy(tmpstr2, tmpstr);
939 *tmpstr=0;
941 TRACE("tmpstr=%s, tmpstr2=%s\n", tmpstr, tmpstr2);
942 SetDlgItemTextA( hWnd, edt1, tmpstr2 );
943 FILEDLG_ScanDir(hWnd, tmpstr);
944 return TRUE;
946 /* no wildcards, we might have a directory or a filename */
947 /* try appending a wildcard and reading the directory */
948 pstr2 = tmpstr + strlen(tmpstr);
949 if (pstr == NULL || *(pstr+1) != 0)
950 strcat(tmpstr, "\\");
951 lRet = SendDlgItemMessage16(hWnd, cmb1, CB_GETCURSEL16, 0, 0);
952 if (lRet == LB_ERR) return TRUE;
953 lpofn->nFilterIndex = lRet + 1;
954 TRACE("lpofn->nFilterIndex=%ld\n", lpofn->nFilterIndex);
955 lstrcpynA(tmpstr2,
956 FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter),
957 PTR_SEG_TO_LIN(lpofn->lpstrFilter),
958 lRet), sizeof(tmpstr2));
959 SetDlgItemTextA( hWnd, edt1, tmpstr2 );
960 if (!in_update)
961 /* if ScanDir succeeds, we have changed the directory */
962 if (FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
963 /* if not, this must be a filename */
964 *pstr2 = 0;
965 if (pstr != NULL)
967 /* strip off the pathname */
968 *pstr = 0;
969 SetDlgItemTextA( hWnd, edt1, pstr + 1 );
970 lstrcpynA(tmpstr2, pstr+1, sizeof(tmpstr2) );
971 /* Should we MessageBox() if this fails? */
972 if (!FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
973 strcpy(tmpstr, tmpstr2);
975 else SetDlgItemTextA( hWnd, edt1, tmpstr );
976 #if 0
977 ShowWindow16(hWnd, SW_HIDE); /* this should not be necessary ?! (%%%) */
978 #endif
980 int lenstr2;
981 int drive = DRIVE_GetCurrentDrive();
982 tmpstr2[0] = 'A'+ drive;
983 tmpstr2[1] = ':';
984 tmpstr2[2] = '\\';
985 lstrcpynA(tmpstr2 + 3, DRIVE_GetDosCwd(drive), 507);
986 lenstr2=strlen(tmpstr2);
987 if (lenstr2 > 3)
988 tmpstr2[lenstr2++]='\\';
989 lstrcpynA(tmpstr2+lenstr2, tmpstr, 512-lenstr2);
990 if (lpofn->lpstrFile)
991 lstrcpynA(PTR_SEG_TO_LIN(lpofn->lpstrFile), tmpstr2,lpofn->nMaxFile);
993 lpofn->nFileOffset = strrchr(tmpstr2,'\\') - tmpstr2 +1;
994 lpofn->nFileExtension = 0;
995 while(tmpstr2[lpofn->nFileExtension] != '.' && tmpstr2[lpofn->nFileExtension] != '\0')
996 lpofn->nFileExtension++;
997 if (tmpstr2[lpofn->nFileExtension] == '\0')
998 lpofn->nFileExtension = 0;
999 else
1000 lpofn->nFileExtension++;
1002 if(in_update)
1004 if (FILEDLG_HookCallChk(lpofn))
1005 FILEDLG_CallWindowProc(lpofn,hWnd,
1006 RegisterWindowMessageA( LBSELCHSTRING ),
1007 control, MAKELONG(lRet,CD_LBSELCHANGE));
1009 in_update = FALSE;
1010 return TRUE;
1012 if (PTR_SEG_TO_LIN(lpofn->lpstrFileTitle) != NULL)
1014 lRet = SendDlgItemMessage16(hWnd, lst1, LB_GETCURSEL16, 0, 0);
1015 SendDlgItemMessage16(hWnd, lst1, LB_GETTEXT16, lRet,
1016 lpofn->lpstrFileTitle );
1018 if (FILEDLG_HookCallChk(lpofn))
1020 lRet= (BOOL16)FILEDLG_CallWindowProc(lpofn,
1021 hWnd, RegisterWindowMessageA( FILEOKSTRING ), 0, lParam );
1022 if (lRet)
1024 *lpofn=ofn2; /* restore old state */
1025 #if 0
1026 ShowWindow16(hWnd, SW_SHOW); /* only if above (%%%) SW_HIDE used */
1027 #endif
1028 break;
1031 if ((lpofn->Flags & OFN_ALLOWMULTISELECT) && (lpofn->Flags & OFN_EXPLORER)) {
1032 if (lpofn->lpstrFile) {
1033 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile);
1034 LPSTR ptr = strrchr(str, '\\');
1035 str[strlen(str) + 1] = '\0';
1036 *ptr = 0;
1039 EndDialog(hWnd, TRUE);
1040 return TRUE;
1041 case IDCANCEL:
1042 EndDialog(hWnd, FALSE);
1043 return TRUE;
1045 return FALSE;
1048 /***********************************************************************
1049 * FileOpenDlgProc16 (COMMDLG.6)
1051 LRESULT WINAPI FileOpenDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1052 LPARAM lParam)
1054 LPOPENFILENAME16 lpofn =(LPOPENFILENAME16)PTR_SEG_TO_LIN(GetPropA(hWnd,OFN_PROP));
1056 if (wMsg!=WM_INITDIALOG)
1057 if (FILEDLG_HookCallChk(lpofn))
1059 LRESULT lRet=(BOOL16)FILEDLG_CallWindowProc(lpofn,hWnd,wMsg,wParam,lParam);
1060 if (lRet)
1061 return lRet; /* else continue message processing */
1063 switch (wMsg)
1065 case WM_INITDIALOG:
1066 return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
1067 case WM_MEASUREITEM:
1068 return FILEDLG_WMMeasureItem(hWnd, wParam, lParam);
1069 case WM_DRAWITEM:
1070 return FILEDLG_WMDrawItem(hWnd, wParam, lParam, FALSE);
1071 case WM_COMMAND:
1072 return FILEDLG_WMCommand(hWnd, wParam, lParam);
1073 #if 0
1074 case WM_CTLCOLOR:
1075 SetBkColor((HDC16)wParam, 0x00C0C0C0);
1076 switch (HIWORD(lParam))
1078 case CTLCOLOR_BTN:
1079 SetTextColor((HDC16)wParam, 0x00000000);
1080 return hGRAYBrush;
1081 case CTLCOLOR_STATIC:
1082 SetTextColor((HDC16)wParam, 0x00000000);
1083 return hGRAYBrush;
1085 break;
1086 #endif
1088 return FALSE;
1091 /***********************************************************************
1092 * FileSaveDlgProc16 (COMMDLG.7)
1094 LRESULT WINAPI FileSaveDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1095 LPARAM lParam)
1097 LPOPENFILENAME16 lpofn =(LPOPENFILENAME16)PTR_SEG_TO_LIN(GetPropA(hWnd,OFN_PROP));
1099 if (wMsg!=WM_INITDIALOG)
1100 if (FILEDLG_HookCallChk(lpofn))
1102 LRESULT lRet=(BOOL16)FILEDLG_CallWindowProc(lpofn,hWnd,wMsg,wParam,lParam);
1103 if (lRet)
1104 return lRet; /* else continue message processing */
1106 switch (wMsg) {
1107 case WM_INITDIALOG:
1108 return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
1110 case WM_MEASUREITEM:
1111 return FILEDLG_WMMeasureItem(hWnd, wParam, lParam);
1113 case WM_DRAWITEM:
1114 return FILEDLG_WMDrawItem(hWnd, wParam, lParam, TRUE);
1116 case WM_COMMAND:
1117 return FILEDLG_WMCommand(hWnd, wParam, lParam);
1121 case WM_CTLCOLOR:
1122 SetBkColor((HDC16)wParam, 0x00C0C0C0);
1123 switch (HIWORD(lParam))
1125 case CTLCOLOR_BTN:
1126 SetTextColor((HDC16)wParam, 0x00000000);
1127 return hGRAYBrush;
1128 case CTLCOLOR_STATIC:
1129 SetTextColor((HDC16)wParam, 0x00000000);
1130 return hGRAYBrush;
1132 return FALSE;
1135 return FALSE;
1138 static BOOL Commdlg_GetFileNameA( BOOL16 (CALLBACK *dofunction)(SEGPTR x),
1139 LPOPENFILENAMEA ofn )
1141 BOOL16 ret;
1142 LPOPENFILENAME16 ofn16 = SEGPTR_ALLOC(sizeof(OPENFILENAME16));
1144 memset(ofn16,'\0',sizeof(*ofn16));
1145 ofn16->lStructSize = sizeof(*ofn16);
1146 ofn16->hwndOwner = ofn->hwndOwner;
1147 ofn16->hInstance = MapHModuleLS(ofn->hInstance);
1148 if (ofn->lpstrFilter) {
1149 LPSTR s,x;
1151 /* filter is a list... title\0ext\0......\0\0 */
1152 s = (LPSTR)ofn->lpstrFilter;
1153 while (*s)
1154 s = s+strlen(s)+1;
1155 s++;
1156 x = (LPSTR)SEGPTR_ALLOC(s-ofn->lpstrFilter);
1157 memcpy(x,ofn->lpstrFilter,s-ofn->lpstrFilter);
1158 ofn16->lpstrFilter = SEGPTR_GET(x);
1160 if (ofn->lpstrCustomFilter) {
1161 LPSTR s,x;
1163 /* filter is a list... title\0ext\0......\0\0 */
1164 s = (LPSTR)ofn->lpstrCustomFilter;
1165 while (*s)
1166 s = s+strlen(s)+1;
1167 s++;
1168 x = SEGPTR_ALLOC(s-ofn->lpstrCustomFilter);
1169 memcpy(x,ofn->lpstrCustomFilter,s-ofn->lpstrCustomFilter);
1170 ofn16->lpstrCustomFilter = SEGPTR_GET(x);
1172 ofn16->nMaxCustFilter = ofn->nMaxCustFilter;
1173 ofn16->nFilterIndex = ofn->nFilterIndex;
1174 if (ofn->nMaxFile)
1175 ofn16->lpstrFile = SEGPTR_GET(SEGPTR_ALLOC(ofn->nMaxFile));
1176 ofn16->nMaxFile = ofn->nMaxFile;
1177 ofn16->nMaxFileTitle = ofn->nMaxFileTitle;
1178 if (ofn16->nMaxFileTitle)
1179 ofn16->lpstrFileTitle = SEGPTR_GET(SEGPTR_ALLOC(ofn->nMaxFileTitle));
1180 if (ofn->lpstrInitialDir)
1181 ofn16->lpstrInitialDir = SEGPTR_GET(SEGPTR_STRDUP(ofn->lpstrInitialDir));
1182 if (ofn->lpstrTitle)
1183 ofn16->lpstrTitle = SEGPTR_GET(SEGPTR_STRDUP(ofn->lpstrTitle));
1184 ofn16->Flags = ofn->Flags|OFN_WINE;
1185 ofn16->nFileOffset = ofn->nFileOffset;
1186 ofn16->nFileExtension = ofn->nFileExtension;
1187 if (ofn->lpstrDefExt)
1188 ofn16->lpstrDefExt = SEGPTR_GET(SEGPTR_STRDUP(ofn->lpstrDefExt));
1189 ofn16->lCustData = ofn->lCustData;
1190 ofn16->lpfnHook = (LPOFNHOOKPROC16)ofn->lpfnHook;
1192 if (ofn->lpTemplateName)
1193 ofn16->lpTemplateName = SEGPTR_GET(SEGPTR_STRDUP(ofn->lpTemplateName));
1195 ret = dofunction(SEGPTR_GET(ofn16));
1197 ofn->nFileOffset = ofn16->nFileOffset;
1198 ofn->nFileExtension = ofn16->nFileExtension;
1199 if (ofn16->lpstrFilter)
1200 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFilter));
1201 if (ofn16->lpTemplateName)
1202 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpTemplateName));
1203 if (ofn16->lpstrDefExt)
1204 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrDefExt));
1205 if (ofn16->lpstrTitle)
1206 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrTitle));
1207 if (ofn16->lpstrInitialDir)
1208 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrInitialDir));
1209 if (ofn16->lpstrCustomFilter)
1210 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrCustomFilter));
1212 if (ofn16->lpstrFile)
1214 LPCSTR src = PTR_SEG_TO_LIN(ofn16->lpstrFile);
1215 LPSTR dst = ofn->lpstrFile;
1217 if ((ofn->Flags & OFN_ALLOWMULTISELECT) && (ofn->Flags & OFN_EXPLORER)) {
1218 /* FIXME(EPP): I tried to use:
1219 * memcpy(ofn->lpstrFile, PTR_SEG_TO_LIN(ofn16->lpstrFile, ofn->nMaxFile)
1220 * but it did crash with winamp 2.21, so copy string by string
1222 int len;
1223 do {
1224 strcpy(dst, src);
1225 len = strlen(dst) + 1; /* strlen(dst) == strlen(src) */
1226 dst += len;
1227 src += len;
1228 } while (len > 1);
1229 } else {
1230 strcpy(dst, src);
1232 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFile));
1235 if (ofn16->lpstrFileTitle)
1237 if (ofn->lpstrFileTitle)
1238 strcpy(ofn->lpstrFileTitle,
1239 PTR_SEG_TO_LIN(ofn16->lpstrFileTitle));
1240 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFileTitle));
1242 SEGPTR_FREE(ofn16);
1243 return ret;
1246 static BOOL Commdlg_GetFileNameW( BOOL16 (CALLBACK *dofunction)(SEGPTR x),
1247 LPOPENFILENAMEW ofn )
1249 BOOL16 ret;
1250 LPOPENFILENAME16 ofn16 = SEGPTR_ALLOC(sizeof(OPENFILENAME16));
1252 memset(ofn16,'\0',sizeof(*ofn16));
1253 ofn16->lStructSize = sizeof(*ofn16);
1254 ofn16->hwndOwner = ofn->hwndOwner;
1255 ofn16->hInstance = MapHModuleLS(ofn->hInstance);
1256 if (ofn->lpstrFilter) {
1257 LPWSTR s;
1258 LPSTR x,y;
1259 int n;
1261 /* filter is a list... title\0ext\0......\0\0 */
1262 s = (LPWSTR)ofn->lpstrFilter;
1263 while (*s)
1264 s = s+lstrlenW(s)+1;
1265 s++;
1266 n = s - ofn->lpstrFilter; /* already divides by 2. ptr magic */
1267 x = y = (LPSTR)SEGPTR_ALLOC(n);
1268 s = (LPWSTR)ofn->lpstrFilter;
1269 while (*s) {
1270 lstrcpyWtoA(x,s);
1271 x+=lstrlenA(x)+1;
1272 s+=lstrlenW(s)+1;
1274 *x=0;
1275 ofn16->lpstrFilter = SEGPTR_GET(y);
1277 if (ofn->lpstrCustomFilter) {
1278 LPWSTR s;
1279 LPSTR x,y;
1280 int n;
1282 /* filter is a list... title\0ext\0......\0\0 */
1283 s = (LPWSTR)ofn->lpstrCustomFilter;
1284 while (*s)
1285 s = s+lstrlenW(s)+1;
1286 s++;
1287 n = s - ofn->lpstrCustomFilter;
1288 x = y = (LPSTR)SEGPTR_ALLOC(n);
1289 s = (LPWSTR)ofn->lpstrCustomFilter;
1290 while (*s) {
1291 lstrcpyWtoA(x,s);
1292 x+=lstrlenA(x)+1;
1293 s+=lstrlenW(s)+1;
1295 *x=0;
1296 ofn16->lpstrCustomFilter = SEGPTR_GET(y);
1298 ofn16->nMaxCustFilter = ofn->nMaxCustFilter;
1299 ofn16->nFilterIndex = ofn->nFilterIndex;
1300 if (ofn->nMaxFile)
1301 ofn16->lpstrFile = SEGPTR_GET(SEGPTR_ALLOC(ofn->nMaxFile));
1302 ofn16->nMaxFile = ofn->nMaxFile;
1303 ofn16->nMaxFileTitle = ofn->nMaxFileTitle;
1304 if (ofn->nMaxFileTitle)
1305 ofn16->lpstrFileTitle = SEGPTR_GET(SEGPTR_ALLOC(ofn->nMaxFileTitle));
1306 if (ofn->lpstrInitialDir)
1307 ofn16->lpstrInitialDir = SEGPTR_GET(SEGPTR_STRDUP_WtoA(ofn->lpstrInitialDir));
1308 if (ofn->lpstrTitle)
1309 ofn16->lpstrTitle = SEGPTR_GET(SEGPTR_STRDUP_WtoA(ofn->lpstrTitle));
1310 ofn16->Flags = ofn->Flags|OFN_WINE|OFN_UNICODE;
1311 ofn16->nFileOffset = ofn->nFileOffset;
1312 ofn16->nFileExtension = ofn->nFileExtension;
1313 if (ofn->lpstrDefExt)
1314 ofn16->lpstrDefExt = SEGPTR_GET(SEGPTR_STRDUP_WtoA(ofn->lpstrDefExt));
1315 ofn16->lCustData = ofn->lCustData;
1316 ofn16->lpfnHook = (LPOFNHOOKPROC16)ofn->lpfnHook;
1317 if (ofn->lpTemplateName)
1318 ofn16->lpTemplateName = SEGPTR_GET(SEGPTR_STRDUP_WtoA(ofn->lpTemplateName));
1319 ret = dofunction(SEGPTR_GET(ofn16));
1321 ofn->nFileOffset = ofn16->nFileOffset;
1322 ofn->nFileExtension = ofn16->nFileExtension;
1323 if (ofn16->lpstrFilter)
1324 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFilter));
1325 if (ofn16->lpTemplateName)
1326 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpTemplateName));
1327 if (ofn16->lpstrDefExt)
1328 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrDefExt));
1329 if (ofn16->lpstrTitle)
1330 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrTitle));
1331 if (ofn16->lpstrInitialDir)
1332 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrInitialDir));
1333 if (ofn16->lpstrCustomFilter)
1334 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrCustomFilter));
1336 if (ofn16->lpstrFile)
1338 LPCSTR src = PTR_SEG_TO_LIN(ofn16->lpstrFile);
1339 LPWSTR dst = ofn->lpstrFile;
1341 if ((ofn->Flags & OFN_ALLOWMULTISELECT) && (ofn->Flags & OFN_EXPLORER)) {
1342 int len;
1343 do {
1344 lstrcpyAtoW(dst, src);
1345 dst += lstrlenW(dst) + 1;
1346 src += (len = strlen(src) + 1);
1347 } while (len > 1);
1348 } else {
1349 lstrcpyAtoW(ofn->lpstrFile,PTR_SEG_TO_LIN(ofn16->lpstrFile));
1351 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFile));
1354 if (ofn16->lpstrFileTitle) {
1355 if (ofn->lpstrFileTitle)
1356 lstrcpyAtoW(ofn->lpstrFileTitle,
1357 PTR_SEG_TO_LIN(ofn16->lpstrFileTitle));
1358 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFileTitle));
1360 SEGPTR_FREE(ofn16);
1361 return ret;
1363 /***********************************************************************
1364 * GetOpenFileNameA (COMDLG32.10)
1366 * Creates a dialog box for the user to select a file to open.
1368 * RETURNS
1369 * TRUE on succes: user enters a valid file
1370 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1373 BOOL WINAPI GetOpenFileNameA(
1374 LPOPENFILENAMEA ofn) /* address of init structure */
1376 BOOL newlook;
1378 /* some flags don't allow to match the TWEAK_WineLook */
1379 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
1381 newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
1383 else
1385 /* no special flags set, we can match the TWEAK_WineLook */
1386 newlook = (TWEAK_WineLook>WIN31_LOOK) ? TRUE : FALSE;
1389 if (newlook)
1391 return GetFileDialog95A(ofn, OPEN_DIALOG);
1393 else
1395 BOOL16 (CALLBACK * dofunction)(SEGPTR ofn16) = GetOpenFileName16;
1396 return Commdlg_GetFileNameA(dofunction,ofn);
1400 /***********************************************************************
1401 * GetOpenFileNameW (COMDLG32.11)
1403 * Creates a dialog box for the user to select a file to open.
1405 * RETURNS
1406 * TRUE on succes: user enters a valid file
1407 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1410 BOOL WINAPI GetOpenFileNameW(
1411 LPOPENFILENAMEW ofn) /* address of init structure */
1413 BOOL newlook;
1415 /* some flags don't allow to match the TWEAK_WineLook */
1416 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
1418 newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
1420 else
1422 /* no special flags set, we can match the TWEAK_WineLook */
1423 newlook = (TWEAK_WineLook>WIN31_LOOK) ? TRUE : FALSE;
1426 if (newlook)
1428 return GetFileDialog95W(ofn, OPEN_DIALOG);
1430 else
1432 BOOL16 (CALLBACK * dofunction)(SEGPTR ofn16) = GetOpenFileName16;
1433 return Commdlg_GetFileNameW(dofunction,ofn);
1437 /***********************************************************************
1438 * GetSaveFileNameA (COMDLG32.12)
1440 * Creates a dialog box for the user to select a file to save.
1442 * RETURNS
1443 * TRUE on succes: user enters a valid file
1444 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1447 BOOL WINAPI GetSaveFileNameA(
1448 LPOPENFILENAMEA ofn) /* address of init structure */
1450 BOOL newlook;
1452 /* some flags don't allow to match the TWEAK_WineLook */
1453 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
1455 newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
1457 else
1459 /* no special flags set, we can match the TWEAK_WineLook */
1460 newlook = (TWEAK_WineLook>WIN31_LOOK) ? TRUE : FALSE;
1463 if (newlook)
1465 return GetFileDialog95A(ofn, SAVE_DIALOG);
1467 else
1469 BOOL16 (CALLBACK * dofunction)(SEGPTR ofn16) = GetSaveFileName16;
1470 return Commdlg_GetFileNameA(dofunction,ofn);
1474 /***********************************************************************
1475 * GetSaveFileNameW (COMDLG32.13)
1477 * Creates a dialog box for the user to select a file to save.
1479 * RETURNS
1480 * TRUE on succes: user enters a valid file
1481 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1484 BOOL WINAPI GetSaveFileNameW(
1485 LPOPENFILENAMEW ofn) /* address of init structure */
1487 BOOL newlook;
1489 /* some flags don't allow to match the TWEAK_WineLook */
1490 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
1492 newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
1494 else
1496 /* no special flags set, we can match the TWEAK_WineLook */
1497 newlook = (TWEAK_WineLook>WIN31_LOOK) ? TRUE : FALSE;
1500 if (newlook)
1502 return GetFileDialog95W(ofn, SAVE_DIALOG);
1504 else
1506 BOOL16 (CALLBACK * dofunction)(SEGPTR ofn16) = GetSaveFileName16;
1507 return Commdlg_GetFileNameW(dofunction,ofn);