Use Get|SetPropA to store lParam to retrieve the OPENFILENAME16 for a
[wine/gsoc_dplay.git] / dlls / commdlg / filedlg.c
blob7380cb25abedea93e81149da55e5f8e4f42488c7
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 <string.h>
10 #include "winbase.h"
11 #include "wine/winbase16.h"
12 #include "wine/winuser16.h"
13 #include "ldt.h"
14 #include "heap.h"
15 #include "commdlg.h"
16 #include "resource.h"
17 #include "dialog.h"
18 #include "dlgs.h"
19 #include "module.h"
20 #include "drive.h"
21 #include "debugtools.h"
22 #include "winproc.h"
23 #include "cderr.h"
24 #include "tweak.h"
26 DEFAULT_DEBUG_CHANNEL(commdlg)
28 #include "cdlg.h"
30 static HICON16 hFolder = 0;
31 static HICON16 hFolder2 = 0;
32 static HICON16 hFloppy = 0;
33 static HICON16 hHDisk = 0;
34 static HICON16 hCDRom = 0;
35 static HICON16 hNet = 0;
36 static int fldrHeight = 0;
37 static int fldrWidth = 0;
39 static const char defaultfilter[]=" \0\0";
40 #define OFN_PROP "FILEDLG_OFN_LPARAM"
42 /***********************************************************************
44 * Windows 3.1 OpenFileName/SaveFileName dialog
47 /***********************************************************************
48 * FileDlg_Init [internal]
50 static BOOL FileDlg_Init(void)
52 static BOOL initialized = 0;
53 CURSORICONINFO *fldrInfo;
55 if (!initialized) {
56 if (!hFolder) hFolder = LoadIcon16(0, MAKEINTRESOURCE16(OIC_FOLDER));
57 if (!hFolder2) hFolder2 = LoadIcon16(0, MAKEINTRESOURCE16(OIC_FOLDER2));
58 if (!hFloppy) hFloppy = LoadIcon16(0, MAKEINTRESOURCE16(OIC_FLOPPY));
59 if (!hHDisk) hHDisk = LoadIcon16(0, MAKEINTRESOURCE16(OIC_HDISK));
60 if (!hCDRom) hCDRom = LoadIcon16(0, MAKEINTRESOURCE16(OIC_CDROM));
61 if (!hNet) hNet = LoadIcon16(0, MAKEINTRESOURCE16(OIC_NETWORK));
62 if (hFolder == 0 || hFolder2 == 0 || hFloppy == 0 ||
63 hHDisk == 0 || hCDRom == 0 || hNet == 0)
65 ERR("Error loading icons !\n");
66 return FALSE;
68 fldrInfo = (CURSORICONINFO *) GlobalLock16( hFolder2 );
69 if (!fldrInfo)
71 ERR("Error measuring icons !\n");
72 return FALSE;
74 fldrHeight = fldrInfo -> nHeight;
75 fldrWidth = fldrInfo -> nWidth;
76 GlobalUnlock16( hFolder2 );
77 initialized = TRUE;
79 return TRUE;
82 /***********************************************************************
83 * FileOpenDlgProc [internal]
85 * FIXME: Convert to real 32-bit message processing
87 static LRESULT WINAPI FileOpenDlgProc(HWND hDlg, UINT msg,
88 WPARAM wParam, LPARAM lParam)
90 UINT16 msg16;
91 MSGPARAM16 mp16;
93 mp16.lParam = lParam;
94 if (WINPROC_MapMsg32ATo16( hDlg, msg, wParam,
95 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
96 return 0;
97 mp16.lResult = FileOpenDlgProc16( (HWND16)hDlg, msg16,
98 mp16.wParam, mp16.lParam );
100 WINPROC_UnmapMsg32ATo16( hDlg, msg, wParam, lParam, &mp16 );
101 return mp16.lResult;
104 /***********************************************************************
105 * FileSaveDlgProc [internal]
107 * FIXME: Convert to real 32-bit message processing
109 static LRESULT WINAPI FileSaveDlgProc(HWND hDlg, UINT msg,
110 WPARAM wParam, LPARAM lParam)
112 UINT16 msg16;
113 MSGPARAM16 mp16;
115 mp16.lParam = lParam;
116 if (WINPROC_MapMsg32ATo16( hDlg, msg, wParam,
117 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
118 return 0;
119 mp16.lResult = FileSaveDlgProc16( (HWND16)hDlg, msg16,
120 mp16.wParam, mp16.lParam );
122 WINPROC_UnmapMsg32ATo16( hDlg, msg, wParam, lParam, &mp16 );
123 return mp16.lResult;
126 /***********************************************************************
127 * GetOpenFileName16 (COMMDLG.1)
129 * Creates a dialog box for the user to select a file to open.
131 * RETURNS
132 * TRUE on succes: user selected a valid file
133 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
135 * BUGS
136 * unknown, there are some FIXME's left.
138 BOOL16 WINAPI GetOpenFileName16(
139 SEGPTR ofn /* addess of structure with data*/
142 HINSTANCE hInst;
143 HANDLE hDlgTmpl = 0, hResInfo;
144 BOOL bRet = FALSE, win32Format = FALSE;
145 HWND hwndDialog;
146 LPOPENFILENAME16 lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(ofn);
147 LPCVOID template;
148 char defaultopen[]="Open File";
149 char *str=0,*str1=0;
151 if (!lpofn || !FileDlg_Init()) return FALSE;
153 if (lpofn->Flags & OFN_WINE) {
154 if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE)
156 if (!(template = LockResource( MapHModuleSL(lpofn->hInstance ))))
158 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
159 return FALSE;
162 else if (lpofn->Flags & OFN_ENABLETEMPLATE)
164 if (!(hResInfo = FindResourceA(MapHModuleSL(lpofn->hInstance),
165 PTR_SEG_TO_LIN(lpofn->lpTemplateName), RT_DIALOGA)))
167 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
168 return FALSE;
170 if (!(hDlgTmpl = LoadResource( MapHModuleSL(lpofn->hInstance),
171 hResInfo )) ||
172 !(template = LockResource( hDlgTmpl )))
174 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
175 return FALSE;
177 } else {
178 if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "OPEN_FILE", RT_DIALOGA)))
180 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
181 return FALSE;
183 if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
184 !(template = LockResource( hDlgTmpl )))
186 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
187 return FALSE;
190 win32Format = TRUE;
191 } else {
192 if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE)
194 if (!(template = LockResource16( lpofn->hInstance )))
196 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
197 return FALSE;
200 else if (lpofn->Flags & OFN_ENABLETEMPLATE)
202 if (!(hResInfo = FindResource16(lpofn->hInstance,
203 lpofn->lpTemplateName,
204 RT_DIALOG16)))
206 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
207 return FALSE;
209 if (!(hDlgTmpl = LoadResource16( lpofn->hInstance, hResInfo )) ||
210 !(template = LockResource16( hDlgTmpl )))
212 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
213 return FALSE;
215 } else {
216 if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "OPEN_FILE", RT_DIALOGA)))
218 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
219 return FALSE;
221 if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
222 !(template = LockResource( hDlgTmpl )))
224 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
225 return FALSE;
227 win32Format = TRUE;
231 hInst = GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );
233 if (!(lpofn->lpstrFilter))
235 str = SEGPTR_ALLOC(sizeof(defaultfilter));
236 TRACE("Alloc %p default for Filetype in GetOpenFileName\n",str);
237 memcpy(str,defaultfilter,sizeof(defaultfilter));
238 lpofn->lpstrFilter=SEGPTR_GET(str);
241 if (!(lpofn->lpstrTitle))
243 str1 = SEGPTR_ALLOC(strlen(defaultopen)+1);
244 TRACE("Alloc %p default for Title in GetOpenFileName\n",str1);
245 strcpy(str1,defaultopen);
246 lpofn->lpstrTitle=SEGPTR_GET(str1);
249 /* FIXME: doesn't handle win32 format correctly yet */
250 hwndDialog = DIALOG_CreateIndirect( hInst, template, win32Format,
251 lpofn->hwndOwner,
252 (DLGPROC16)FileOpenDlgProc,
253 ofn, WIN_PROC_32A );
254 if (hwndDialog) bRet = DIALOG_DoDialogBox( hwndDialog, lpofn->hwndOwner );
256 if (str1)
258 TRACE("Freeing %p default for Title in GetOpenFileName\n",str1);
259 SEGPTR_FREE(str1);
260 lpofn->lpstrTitle=0;
263 if (str)
265 TRACE("Freeing %p default for Filetype in GetOpenFileName\n",str);
266 SEGPTR_FREE(str);
267 lpofn->lpstrFilter=0;
270 if (hDlgTmpl) {
271 if (lpofn->Flags & OFN_WINE)
272 FreeResource( hDlgTmpl );
273 else
274 FreeResource16( hDlgTmpl );
277 TRACE("return lpstrFile='%s' !\n",
278 (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
279 return bRet;
283 /***********************************************************************
284 * GetSaveFileName (COMMDLG.2)
286 * Creates a dialog box for the user to select a file to save.
288 * RETURNS
289 * TRUE on succes: user enters a valid file
290 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
292 * BUGS
293 * unknown. There are some FIXME's left.
295 BOOL16 WINAPI GetSaveFileName16(
296 SEGPTR ofn /* addess of structure with data*/
299 HINSTANCE hInst;
300 HANDLE hDlgTmpl = 0;
301 BOOL bRet = FALSE, win32Format = FALSE;
302 LPOPENFILENAME16 lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(ofn);
303 LPCVOID template;
304 HWND hwndDialog;
305 char defaultsave[]="Save as";
306 char *str =0,*str1=0;
308 if (!lpofn || !FileDlg_Init()) return FALSE;
310 if (lpofn->Flags & OFN_WINE) {
311 if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE)
313 if (!(template = LockResource( MapHModuleSL(lpofn->hInstance ))))
315 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
316 return FALSE;
319 else if (lpofn->Flags & OFN_ENABLETEMPLATE)
321 HANDLE hResInfo;
322 if (!(hResInfo = FindResourceA(MapHModuleSL(lpofn->hInstance),
323 PTR_SEG_TO_LIN(lpofn->lpTemplateName),
324 RT_DIALOGA)))
326 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
327 return FALSE;
329 if (!(hDlgTmpl = LoadResource(MapHModuleSL(lpofn->hInstance),
330 hResInfo)) ||
331 !(template = LockResource(hDlgTmpl)))
333 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
334 return FALSE;
336 win32Format= TRUE;
337 } else {
338 HANDLE hResInfo;
339 if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "SAVE_FILE", RT_DIALOGA)))
341 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
342 return FALSE;
344 if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
345 !(template = LockResource( hDlgTmpl )))
347 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
348 return FALSE;
350 win32Format = TRUE;
352 } else {
353 if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE)
355 if (!(template = LockResource16( lpofn->hInstance )))
357 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
358 return FALSE;
361 else if (lpofn->Flags & OFN_ENABLETEMPLATE)
363 HANDLE16 hResInfo;
364 if (!(hResInfo = FindResource16(lpofn->hInstance,
365 lpofn->lpTemplateName,
366 RT_DIALOG16)))
368 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
369 return FALSE;
371 if (!(hDlgTmpl = LoadResource16( lpofn->hInstance, hResInfo )) ||
372 !(template = LockResource16( hDlgTmpl )))
374 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
375 return FALSE;
377 } else {
378 HANDLE hResInfo;
379 if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "SAVE_FILE", RT_DIALOGA)))
381 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
382 return FALSE;
384 if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
385 !(template = LockResource( hDlgTmpl )))
387 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
388 return FALSE;
390 win32Format = TRUE;
394 hInst = GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );
396 if (!(lpofn->lpstrFilter))
398 str = SEGPTR_ALLOC(sizeof(defaultfilter));
399 TRACE("Alloc default for Filetype in GetSaveFileName\n");
400 memcpy(str,defaultfilter,sizeof(defaultfilter));
401 lpofn->lpstrFilter=SEGPTR_GET(str);
404 if (!(lpofn->lpstrTitle))
406 str1 = SEGPTR_ALLOC(sizeof(defaultsave)+1);
407 TRACE("Alloc default for Title in GetSaveFileName\n");
408 strcpy(str1,defaultsave);
409 lpofn->lpstrTitle=SEGPTR_GET(str1);
412 hwndDialog = DIALOG_CreateIndirect( hInst, template, win32Format,
413 lpofn->hwndOwner,
414 (DLGPROC16)FileSaveDlgProc,
415 ofn, WIN_PROC_32A );
416 if (hwndDialog) bRet = DIALOG_DoDialogBox( hwndDialog, lpofn->hwndOwner );
418 if (str1)
420 TRACE("Freeing %p default for Title in GetSaveFileName\n",str1);
421 SEGPTR_FREE(str1);
422 lpofn->lpstrTitle=0;
425 if (str)
427 TRACE("Freeing %p default for Filetype in GetSaveFileName\n",str);
428 SEGPTR_FREE(str);
429 lpofn->lpstrFilter=0;
432 if (hDlgTmpl) {
433 if (lpofn->Flags & OFN_WINE)
434 FreeResource( hDlgTmpl );
435 else
436 FreeResource16( hDlgTmpl );
439 TRACE("return lpstrFile='%s' !\n",
440 (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
441 return bRet;
444 /***********************************************************************
445 * FILEDLG_StripEditControl [internal]
446 * Strip pathnames off the contents of the edit control.
448 static void FILEDLG_StripEditControl(HWND16 hwnd)
450 char temp[512], *cp;
452 GetDlgItemTextA( hwnd, edt1, temp, sizeof(temp) );
453 cp = strrchr(temp, '\\');
454 if (cp != NULL) {
455 strcpy(temp, cp+1);
457 cp = strrchr(temp, ':');
458 if (cp != NULL) {
459 strcpy(temp, cp+1);
461 /* FIXME: shouldn't we do something with the result here? ;-) */
464 /***********************************************************************
465 * FILEDLG_ScanDir [internal]
467 static BOOL FILEDLG_ScanDir(HWND16 hWnd, LPSTR newPath)
469 char buffer[512];
470 char* str = buffer;
471 int drive;
472 HWND hlb;
474 lstrcpynA(buffer, newPath, sizeof(buffer));
476 if (str[0] && (str[1] == ':')) {
477 drive = toupper(str[0]) - 'A';
478 str += 2;
479 if (!DRIVE_SetCurrentDrive(drive))
480 return FALSE;
481 } else {
482 drive = DRIVE_GetCurrentDrive();
485 if (str[0] && !DRIVE_Chdir(drive, str)) {
486 return FALSE;
489 GetDlgItemTextA(hWnd, edt1, buffer, sizeof(buffer));
490 if ((hlb = GetDlgItem(hWnd, lst1)) != 0) {
491 char* scptr; /* ptr on semi-colon */
492 char* filter = buffer;
494 TRACE("Using filter %s\n", filter);
495 SendMessageA(hlb, LB_RESETCONTENT, 0, 0);
496 while (filter) {
497 scptr = strchr(filter, ';');
498 if (scptr) *scptr = 0;
499 TRACE("Using file spec %s\n", filter);
500 if (SendMessageA(hlb, LB_DIR, 0, (LPARAM)filter) == LB_ERR)
501 return FALSE;
502 if (scptr) *scptr = ';';
503 filter = (scptr) ? (scptr + 1) : 0;
507 strcpy(buffer, "*.*");
508 return DlgDirListA(hWnd, buffer, lst2, stc1, DDL_EXCLUSIVE | DDL_DIRECTORY);
511 /***********************************************************************
512 * FILEDLG_GetFileType [internal]
515 static LPSTR FILEDLG_GetFileType(LPSTR cfptr, LPSTR fptr, WORD index)
517 int n, i;
518 i = 0;
519 if (cfptr)
520 for ( ;(n = strlen(cfptr)) != 0; i++)
522 cfptr += n + 1;
523 if (i == index)
524 return cfptr;
525 cfptr += strlen(cfptr) + 1;
527 if (fptr)
528 for ( ;(n = strlen(fptr)) != 0; i++)
530 fptr += n + 1;
531 if (i == index)
532 return fptr;
533 fptr += strlen(fptr) + 1;
535 return "*.*"; /* FIXME */
538 /***********************************************************************
539 * FILEDLG_WMDrawItem [internal]
541 static LONG FILEDLG_WMDrawItem(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam,int savedlg)
543 LPDRAWITEMSTRUCT16 lpdis = (LPDRAWITEMSTRUCT16)PTR_SEG_TO_LIN(lParam);
544 char *str;
545 HICON16 hIcon;
546 COLORREF oldText = 0, oldBk = 0;
548 if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst1)
550 if (!(str = SEGPTR_ALLOC(512))) return FALSE;
551 SendMessage16(lpdis->hwndItem, LB_GETTEXT16, lpdis->itemID,
552 (LPARAM)SEGPTR_GET(str));
554 if ((lpdis->itemState & ODS_SELECTED) && !savedlg)
556 oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
557 oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
559 if (savedlg)
560 SetTextColor(lpdis->hDC,GetSysColor(COLOR_GRAYTEXT) );
562 ExtTextOut16(lpdis->hDC, lpdis->rcItem.left + 1,
563 lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
564 &(lpdis->rcItem), str, strlen(str), NULL);
566 if (lpdis->itemState & ODS_SELECTED)
567 DrawFocusRect16( lpdis->hDC, &(lpdis->rcItem) );
569 if ((lpdis->itemState & ODS_SELECTED) && !savedlg)
571 SetBkColor( lpdis->hDC, oldBk );
572 SetTextColor( lpdis->hDC, oldText );
574 SEGPTR_FREE(str);
575 return TRUE;
578 if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst2)
580 if (!(str = SEGPTR_ALLOC(512))) return FALSE;
581 SendMessage16(lpdis->hwndItem, LB_GETTEXT16, lpdis->itemID,
582 (LPARAM)SEGPTR_GET(str));
584 if (lpdis->itemState & ODS_SELECTED)
586 oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
587 oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
589 ExtTextOut16(lpdis->hDC, lpdis->rcItem.left + fldrWidth,
590 lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
591 &(lpdis->rcItem), str, strlen(str), NULL);
593 if (lpdis->itemState & ODS_SELECTED)
594 DrawFocusRect16( lpdis->hDC, &(lpdis->rcItem) );
596 if (lpdis->itemState & ODS_SELECTED)
598 SetBkColor( lpdis->hDC, oldBk );
599 SetTextColor( lpdis->hDC, oldText );
601 DrawIcon(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hFolder);
602 SEGPTR_FREE(str);
603 return TRUE;
605 if (lpdis->CtlType == ODT_COMBOBOX && lpdis->CtlID == cmb2)
607 if (!(str = SEGPTR_ALLOC(512))) return FALSE;
608 SendMessage16(lpdis->hwndItem, CB_GETLBTEXT16, lpdis->itemID,
609 (LPARAM)SEGPTR_GET(str));
610 switch(DRIVE_GetType( str[2] - 'a' ))
612 case TYPE_FLOPPY: hIcon = hFloppy; break;
613 case TYPE_CDROM: hIcon = hCDRom; break;
614 case TYPE_NETWORK: hIcon = hNet; break;
615 case TYPE_HD:
616 default: hIcon = hHDisk; break;
618 if (lpdis->itemState & ODS_SELECTED)
620 oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
621 oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
623 ExtTextOut16(lpdis->hDC, lpdis->rcItem.left + fldrWidth,
624 lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
625 &(lpdis->rcItem), str, strlen(str), NULL);
627 if (lpdis->itemState & ODS_SELECTED)
629 SetBkColor( lpdis->hDC, oldBk );
630 SetTextColor( lpdis->hDC, oldText );
632 DrawIcon(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hIcon);
633 SEGPTR_FREE(str);
634 return TRUE;
636 return FALSE;
639 /***********************************************************************
640 * FILEDLG_WMMeasureItem [internal]
642 static LONG FILEDLG_WMMeasureItem(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam)
644 LPMEASUREITEMSTRUCT16 lpmeasure;
646 lpmeasure = (LPMEASUREITEMSTRUCT16)PTR_SEG_TO_LIN(lParam);
647 lpmeasure->itemHeight = fldrHeight;
648 return TRUE;
651 /***********************************************************************
652 * FILEDLG_HookCallChk [internal]
654 static int FILEDLG_HookCallChk(LPOPENFILENAME16 lpofn)
656 if (lpofn)
657 if (lpofn->Flags & OFN_ENABLEHOOK)
658 if (lpofn->lpfnHook)
659 return 1;
660 return 0;
663 /***********************************************************************
664 * FILEDLG_CallWindowProc [internal]
666 * Adapt the structures back for win32 calls so the callee can read lpCustData
668 static BOOL FILEDLG_CallWindowProc(LPOPENFILENAME16 lpofn,HWND hwnd,
669 UINT wMsg,WPARAM wParam,LPARAM lParam
672 BOOL needstruct;
673 BOOL result = FALSE;
674 WINDOWPROCTYPE ProcType; /* Type of Hook Function to be called. */
676 /* TRUE if lParam points to the OPENFILENAME16 Structure */
677 needstruct = (PTR_SEG_TO_LIN(lParam) == lpofn);
679 ProcType = (lpofn->Flags & OFN_WINE)
680 ? (lpofn->Flags & OFN_UNICODE) /* 32-Bit call to GetOpenFileName */
681 ? WIN_PROC_32W : WIN_PROC_32A
682 : WIN_PROC_16; /* 16-Bit call to GetOpenFileName */
684 if (!(lpofn->Flags & OFN_WINE))
685 /* Call to 16-Bit Hooking function... No Problem at all. */
686 return (BOOL)CallWindowProc16(
687 (WNDPROC16)lpofn->lpfnHook,hwnd,(UINT16)wMsg,(WPARAM16)wParam,lParam
689 /* |OFN_WINE32 */
690 if (needstruct)
692 /* Parameter lParam points to lpofn... Convert Structure Data... */
693 if (lpofn->Flags & OFN_UNICODE)
695 OPENFILENAMEW ofnw;
697 /* FIXME: probably needs more converted */
698 ofnw.lCustData = lpofn->lCustData;
699 return (BOOL)CallWindowProcW(
700 (WNDPROC)lpofn->lpfnHook,hwnd,wMsg,wParam,(LPARAM)&ofnw
703 else /* ! |OFN_UNICODE */
705 OPENFILENAMEA ofna;
707 /* FIXME: probably needs more converted */
708 ofna.lCustData = lpofn->lCustData;
709 return (BOOL)CallWindowProcA(
710 (WNDPROC)lpofn->lpfnHook,hwnd,wMsg,wParam,(LPARAM)&ofna
714 else /* ! needstruct */
716 HWINDOWPROC hWindowProc=NULL;
718 if (WINPROC_SetProc(&hWindowProc, (WNDPROC16)lpofn->lpfnHook, ProcType, WIN_PROC_WINDOW))
720 /* Call Window Procedure converting 16-Bit Type Parameters to 32-Bit Type Parameters */
721 result = CallWindowProc16( (WNDPROC16)hWindowProc,
722 hwnd, wMsg, wParam, lParam );
724 result = LOWORD(result);
726 WINPROC_FreeProc( hWindowProc, WIN_PROC_WINDOW );
729 return result;
735 /***********************************************************************
736 * FILEDLG_WMInitDialog [internal]
739 static LONG FILEDLG_WMInitDialog(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam)
741 int i, n;
742 LPOPENFILENAME16 lpofn;
743 char tmpstr[512];
744 LPSTR pstr, old_pstr;
745 SetPropA(hWnd,OFN_PROP,lParam);
746 lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(lParam);
747 if (lpofn->lpstrTitle) SetWindowText16( hWnd, lpofn->lpstrTitle );
748 /* read custom filter information */
749 if (lpofn->lpstrCustomFilter)
751 pstr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter);
752 n = 0;
753 TRACE("lpstrCustomFilter = %p\n", pstr);
754 while(*pstr)
756 old_pstr = pstr;
757 i = SendDlgItemMessage16(hWnd, cmb1, CB_ADDSTRING16, 0,
758 (LPARAM)lpofn->lpstrCustomFilter + n );
759 n += strlen(pstr) + 1;
760 pstr += strlen(pstr) + 1;
761 TRACE("add str='%s' "
762 "associated to '%s'\n", old_pstr, pstr);
763 SendDlgItemMessage16(hWnd, cmb1, CB_SETITEMDATA16, i, (LPARAM)pstr);
764 n += strlen(pstr) + 1;
765 pstr += strlen(pstr) + 1;
768 /* read filter information */
769 if (lpofn->lpstrFilter) {
770 pstr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFilter);
771 n = 0;
772 while(*pstr) {
773 old_pstr = pstr;
774 i = SendDlgItemMessage16(hWnd, cmb1, CB_ADDSTRING16, 0,
775 (LPARAM)lpofn->lpstrFilter + n );
776 n += strlen(pstr) + 1;
777 pstr += strlen(pstr) + 1;
778 TRACE("add str='%s' "
779 "associated to '%s'\n", old_pstr, pstr);
780 SendDlgItemMessage16(hWnd, cmb1, CB_SETITEMDATA16, i, (LPARAM)pstr);
781 n += strlen(pstr) + 1;
782 pstr += strlen(pstr) + 1;
785 /* set default filter */
786 if (lpofn->nFilterIndex == 0 && lpofn->lpstrCustomFilter == (SEGPTR)NULL)
787 lpofn->nFilterIndex = 1;
788 SendDlgItemMessage16(hWnd, cmb1, CB_SETCURSEL16, lpofn->nFilterIndex - 1, 0);
789 strncpy(tmpstr, FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter),
790 PTR_SEG_TO_LIN(lpofn->lpstrFilter), lpofn->nFilterIndex - 1),511);
791 tmpstr[511]=0;
792 TRACE("nFilterIndex = %ld, SetText of edt1 to '%s'\n",
793 lpofn->nFilterIndex, tmpstr);
794 SetDlgItemTextA( hWnd, edt1, tmpstr );
795 /* get drive list */
796 *tmpstr = 0;
797 DlgDirListComboBoxA(hWnd, tmpstr, cmb2, 0, DDL_DRIVES | DDL_EXCLUSIVE);
798 /* read initial directory */
799 if (PTR_SEG_TO_LIN(lpofn->lpstrInitialDir) != NULL)
801 strncpy(tmpstr, PTR_SEG_TO_LIN(lpofn->lpstrInitialDir), 510);
802 tmpstr[510]=0;
803 if (strlen(tmpstr) > 0 && tmpstr[strlen(tmpstr)-1] != '\\'
804 && tmpstr[strlen(tmpstr)-1] != ':')
805 strcat(tmpstr,"\\");
807 else
808 *tmpstr = 0;
809 if (!FILEDLG_ScanDir(hWnd, tmpstr)) {
810 *tmpstr = 0;
811 if (!FILEDLG_ScanDir(hWnd, tmpstr))
812 WARN("Couldn't read initial directory %s!\n",tmpstr);
814 /* select current drive in combo 2, omit missing drives */
815 for(i=0, n=-1; i<=DRIVE_GetCurrentDrive(); i++)
816 if (DRIVE_IsValid(i)) n++;
817 SendDlgItemMessage16(hWnd, cmb2, CB_SETCURSEL16, n, 0);
818 if (!(lpofn->Flags & OFN_SHOWHELP))
819 ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
820 if (lpofn->Flags & OFN_HIDEREADONLY)
821 ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
822 if (FILEDLG_HookCallChk(lpofn))
823 return (BOOL16)FILEDLG_CallWindowProc(lpofn,hWnd,WM_INITDIALOG,wParam,lParam );
824 else
825 return TRUE;
828 /***********************************************************************
829 * FILEDLG_WMCommand [internal]
831 BOOL in_update=FALSE;
833 static LRESULT FILEDLG_WMCommand(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam)
835 LONG lRet;
836 LPOPENFILENAME16 lpofn;
837 OPENFILENAME16 ofn2;
838 char tmpstr[512], tmpstr2[512];
839 LPSTR pstr, pstr2;
840 UINT16 control,notification;
842 /* Notifications are packaged differently in Win32 */
843 control = wParam;
844 notification = HIWORD(lParam);
846 lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(GetPropA(hWnd,OFN_PROP));
847 switch (control)
849 case lst1: /* file list */
850 FILEDLG_StripEditControl(hWnd);
851 if (notification == LBN_DBLCLK)
852 goto almost_ok;
853 lRet = SendDlgItemMessage16(hWnd, lst1, LB_GETCURSEL16, 0, 0);
854 if (lRet == LB_ERR) return TRUE;
855 if ((pstr = SEGPTR_ALLOC(512)))
857 SendDlgItemMessage16(hWnd, lst1, LB_GETTEXT16, lRet,
858 (LPARAM)SEGPTR_GET(pstr));
859 SetDlgItemTextA( hWnd, edt1, pstr );
860 SEGPTR_FREE(pstr);
862 if (FILEDLG_HookCallChk(lpofn))
863 FILEDLG_CallWindowProc(lpofn,hWnd,
864 RegisterWindowMessageA( LBSELCHSTRING ),
865 control, MAKELONG(lRet,CD_LBSELCHANGE));
866 /* FIXME: for OFN_ALLOWMULTISELECT we need CD_LBSELSUB, CD_SELADD, CD_LBSELNOITEMS */
867 return TRUE;
868 case lst2: /* directory list */
869 FILEDLG_StripEditControl(hWnd);
870 if (notification == LBN_DBLCLK)
872 lRet = SendDlgItemMessage16(hWnd, lst2, LB_GETCURSEL16, 0, 0);
873 if (lRet == LB_ERR) return TRUE;
874 pstr = SEGPTR_ALLOC(512);
875 SendDlgItemMessage16(hWnd, lst2, LB_GETTEXT16, lRet,
876 (LPARAM)SEGPTR_GET(pstr));
877 strcpy( tmpstr, pstr );
878 SEGPTR_FREE(pstr);
879 if (tmpstr[0] == '[')
881 tmpstr[strlen(tmpstr) - 1] = 0;
882 strcpy(tmpstr,tmpstr+1);
884 strcat(tmpstr, "\\");
885 goto reset_scan;
887 return TRUE;
888 case cmb1: /* file type drop list */
889 if (notification == CBN_SELCHANGE)
891 *tmpstr = 0;
892 goto reset_scan;
894 return TRUE;
895 case chx1:
896 return TRUE;
897 case pshHelp:
898 return TRUE;
899 case cmb2: /* disk drop list */
900 FILEDLG_StripEditControl(hWnd);
901 lRet = SendDlgItemMessage16(hWnd, cmb2, CB_GETCURSEL16, 0, 0L);
902 if (lRet == LB_ERR) return 0;
903 pstr = SEGPTR_ALLOC(512);
904 SendDlgItemMessage16(hWnd, cmb2, CB_GETLBTEXT16, lRet,
905 (LPARAM)SEGPTR_GET(pstr));
906 sprintf(tmpstr, "%c:", pstr[2]);
907 SEGPTR_FREE(pstr);
908 reset_scan:
909 lRet = SendDlgItemMessage16(hWnd, cmb1, CB_GETCURSEL16, 0, 0);
910 if (lRet == LB_ERR)
911 return TRUE;
912 pstr = (LPSTR)SendDlgItemMessage16(hWnd, cmb1, CB_GETITEMDATA16, lRet, 0);
913 TRACE("Selected filter : %s\n", pstr);
914 SetDlgItemTextA( hWnd, edt1, pstr );
915 FILEDLG_ScanDir(hWnd, tmpstr);
916 in_update=TRUE;
917 case IDOK:
918 almost_ok:
919 ofn2=*lpofn; /* for later restoring */
920 GetDlgItemTextA( hWnd, edt1, tmpstr, sizeof(tmpstr) );
921 pstr = strrchr(tmpstr, '\\');
922 if (pstr == NULL)
923 pstr = strrchr(tmpstr, ':');
924 if (strchr(tmpstr,'*') != NULL || strchr(tmpstr,'?') != NULL)
926 /* edit control contains wildcards */
927 if (pstr != NULL)
929 strncpy(tmpstr2, pstr+1, 511); tmpstr2[511]=0;
930 *(pstr+1) = 0;
932 else
934 strcpy(tmpstr2, tmpstr);
935 *tmpstr=0;
937 TRACE("tmpstr=%s, tmpstr2=%s\n", tmpstr, tmpstr2);
938 SetDlgItemTextA( hWnd, edt1, tmpstr2 );
939 FILEDLG_ScanDir(hWnd, tmpstr);
940 return TRUE;
942 /* no wildcards, we might have a directory or a filename */
943 /* try appending a wildcard and reading the directory */
944 pstr2 = tmpstr + strlen(tmpstr);
945 if (pstr == NULL || *(pstr+1) != 0)
946 strcat(tmpstr, "\\");
947 lRet = SendDlgItemMessage16(hWnd, cmb1, CB_GETCURSEL16, 0, 0);
948 if (lRet == LB_ERR) return TRUE;
949 lpofn->nFilterIndex = lRet + 1;
950 TRACE("lpofn->nFilterIndex=%ld\n", lpofn->nFilterIndex);
951 lstrcpynA(tmpstr2,
952 FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter),
953 PTR_SEG_TO_LIN(lpofn->lpstrFilter),
954 lRet), sizeof(tmpstr2));
955 SetDlgItemTextA( hWnd, edt1, tmpstr2 );
956 if (!in_update)
957 /* if ScanDir succeeds, we have changed the directory */
958 if (FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
959 /* if not, this must be a filename */
960 *pstr2 = 0;
961 if (pstr != NULL)
963 /* strip off the pathname */
964 *pstr = 0;
965 SetDlgItemTextA( hWnd, edt1, pstr + 1 );
966 lstrcpynA(tmpstr2, pstr+1, sizeof(tmpstr2) );
967 /* Should we MessageBox() if this fails? */
968 if (!FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
969 strcpy(tmpstr, tmpstr2);
971 else SetDlgItemTextA( hWnd, edt1, tmpstr );
972 #if 0
973 ShowWindow16(hWnd, SW_HIDE); /* this should not be necessary ?! (%%%) */
974 #endif
976 int drive = DRIVE_GetCurrentDrive();
977 tmpstr2[0] = 'A'+ drive;
978 tmpstr2[1] = ':';
979 tmpstr2[2] = '\\';
980 strncpy(tmpstr2 + 3, DRIVE_GetDosCwd(drive), 507); tmpstr2[510]=0;
981 if (strlen(tmpstr2) > 3)
982 strcat(tmpstr2, "\\");
983 strncat(tmpstr2, tmpstr, 511-strlen(tmpstr2)); tmpstr2[511]=0;
984 if (lpofn->lpstrFile)
985 lstrcpynA(PTR_SEG_TO_LIN(lpofn->lpstrFile), tmpstr2,lpofn->nMaxFile);
987 lpofn->nFileOffset = strrchr(tmpstr2,'\\') - tmpstr2 +1;
988 lpofn->nFileExtension = 0;
989 while(tmpstr2[lpofn->nFileExtension] != '.' && tmpstr2[lpofn->nFileExtension] != '\0')
990 lpofn->nFileExtension++;
991 if (tmpstr2[lpofn->nFileExtension] == '\0')
992 lpofn->nFileExtension = 0;
993 else
994 lpofn->nFileExtension++;
996 if(in_update)
998 if (FILEDLG_HookCallChk(lpofn))
999 FILEDLG_CallWindowProc(lpofn,hWnd,
1000 RegisterWindowMessageA( LBSELCHSTRING ),
1001 control, MAKELONG(lRet,CD_LBSELCHANGE));
1003 in_update = FALSE;
1004 return TRUE;
1006 if (PTR_SEG_TO_LIN(lpofn->lpstrFileTitle) != NULL)
1008 lRet = SendDlgItemMessage16(hWnd, lst1, LB_GETCURSEL16, 0, 0);
1009 SendDlgItemMessage16(hWnd, lst1, LB_GETTEXT16, lRet,
1010 lpofn->lpstrFileTitle );
1012 if (FILEDLG_HookCallChk(lpofn))
1014 lRet= (BOOL16)FILEDLG_CallWindowProc(lpofn,
1015 hWnd, RegisterWindowMessageA( FILEOKSTRING ), 0, lParam );
1016 if (lRet)
1018 *lpofn=ofn2; /* restore old state */
1019 #if 0
1020 ShowWindow16(hWnd, SW_SHOW); /* only if above (%%%) SW_HIDE used */
1021 #endif
1022 break;
1025 if ((lpofn->Flags & OFN_ALLOWMULTISELECT) && (lpofn->Flags & OFN_EXPLORER)) {
1026 if (lpofn->lpstrFile) {
1027 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile);
1028 LPSTR ptr = strrchr(str, '\\');
1029 str[strlen(str) + 1] = '\0';
1030 *ptr = 0;
1033 EndDialog(hWnd, TRUE);
1034 return TRUE;
1035 case IDCANCEL:
1036 EndDialog(hWnd, FALSE);
1037 return TRUE;
1039 return FALSE;
1042 /***********************************************************************
1043 * FileOpenDlgProc16 (COMMDLG.6)
1045 LRESULT WINAPI FileOpenDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1046 LPARAM lParam)
1048 LPOPENFILENAME16 lpofn =(LPOPENFILENAME16)PTR_SEG_TO_LIN(GetPropA(hWnd,OFN_PROP));
1050 if (wMsg!=WM_INITDIALOG)
1051 if (FILEDLG_HookCallChk(lpofn))
1053 LRESULT lRet=(BOOL16)FILEDLG_CallWindowProc(lpofn,hWnd,wMsg,wParam,lParam);
1054 if (lRet)
1055 return lRet; /* else continue message processing */
1057 switch (wMsg)
1059 case WM_INITDIALOG:
1060 return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
1061 case WM_MEASUREITEM:
1062 return FILEDLG_WMMeasureItem(hWnd, wParam, lParam);
1063 case WM_DRAWITEM:
1064 return FILEDLG_WMDrawItem(hWnd, wParam, lParam, FALSE);
1065 case WM_COMMAND:
1066 return FILEDLG_WMCommand(hWnd, wParam, lParam);
1067 #if 0
1068 case WM_CTLCOLOR:
1069 SetBkColor((HDC16)wParam, 0x00C0C0C0);
1070 switch (HIWORD(lParam))
1072 case CTLCOLOR_BTN:
1073 SetTextColor((HDC16)wParam, 0x00000000);
1074 return hGRAYBrush;
1075 case CTLCOLOR_STATIC:
1076 SetTextColor((HDC16)wParam, 0x00000000);
1077 return hGRAYBrush;
1079 break;
1080 #endif
1082 return FALSE;
1085 /***********************************************************************
1086 * FileSaveDlgProc16 (COMMDLG.7)
1088 LRESULT WINAPI FileSaveDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1089 LPARAM lParam)
1091 LPOPENFILENAME16 lpofn =(LPOPENFILENAME16)PTR_SEG_TO_LIN(GetPropA(hWnd,OFN_PROP));
1093 if (wMsg!=WM_INITDIALOG)
1094 if (FILEDLG_HookCallChk(lpofn))
1096 LRESULT lRet=(BOOL16)FILEDLG_CallWindowProc(lpofn,hWnd,wMsg,wParam,lParam);
1097 if (lRet)
1098 return lRet; /* else continue message processing */
1100 switch (wMsg) {
1101 case WM_INITDIALOG:
1102 return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
1104 case WM_MEASUREITEM:
1105 return FILEDLG_WMMeasureItem(hWnd, wParam, lParam);
1107 case WM_DRAWITEM:
1108 return FILEDLG_WMDrawItem(hWnd, wParam, lParam, TRUE);
1110 case WM_COMMAND:
1111 return FILEDLG_WMCommand(hWnd, wParam, lParam);
1115 case WM_CTLCOLOR:
1116 SetBkColor((HDC16)wParam, 0x00C0C0C0);
1117 switch (HIWORD(lParam))
1119 case CTLCOLOR_BTN:
1120 SetTextColor((HDC16)wParam, 0x00000000);
1121 return hGRAYBrush;
1122 case CTLCOLOR_STATIC:
1123 SetTextColor((HDC16)wParam, 0x00000000);
1124 return hGRAYBrush;
1126 return FALSE;
1129 return FALSE;
1132 static BOOL Commdlg_GetFileNameA( BOOL16 (CALLBACK *dofunction)(SEGPTR x),
1133 LPOPENFILENAMEA ofn )
1135 BOOL16 ret;
1136 LPOPENFILENAME16 ofn16 = SEGPTR_ALLOC(sizeof(OPENFILENAME16));
1138 memset(ofn16,'\0',sizeof(*ofn16));
1139 ofn16->lStructSize = sizeof(*ofn16);
1140 ofn16->hwndOwner = ofn->hwndOwner;
1141 ofn16->hInstance = MapHModuleLS(ofn->hInstance);
1142 if (ofn->lpstrFilter) {
1143 LPSTR s,x;
1145 /* filter is a list... title\0ext\0......\0\0 */
1146 s = (LPSTR)ofn->lpstrFilter;
1147 while (*s)
1148 s = s+strlen(s)+1;
1149 s++;
1150 x = (LPSTR)SEGPTR_ALLOC(s-ofn->lpstrFilter);
1151 memcpy(x,ofn->lpstrFilter,s-ofn->lpstrFilter);
1152 ofn16->lpstrFilter = SEGPTR_GET(x);
1154 if (ofn->lpstrCustomFilter) {
1155 LPSTR s,x;
1157 /* filter is a list... title\0ext\0......\0\0 */
1158 s = (LPSTR)ofn->lpstrCustomFilter;
1159 while (*s)
1160 s = s+strlen(s)+1;
1161 s++;
1162 x = SEGPTR_ALLOC(s-ofn->lpstrCustomFilter);
1163 memcpy(x,ofn->lpstrCustomFilter,s-ofn->lpstrCustomFilter);
1164 ofn16->lpstrCustomFilter = SEGPTR_GET(x);
1166 ofn16->nMaxCustFilter = ofn->nMaxCustFilter;
1167 ofn16->nFilterIndex = ofn->nFilterIndex;
1168 if (ofn->nMaxFile)
1169 ofn16->lpstrFile = SEGPTR_GET(SEGPTR_ALLOC(ofn->nMaxFile));
1170 ofn16->nMaxFile = ofn->nMaxFile;
1171 ofn16->nMaxFileTitle = ofn->nMaxFileTitle;
1172 if (ofn16->nMaxFileTitle)
1173 ofn16->lpstrFileTitle = SEGPTR_GET(SEGPTR_ALLOC(ofn->nMaxFileTitle));
1174 if (ofn->lpstrInitialDir)
1175 ofn16->lpstrInitialDir = SEGPTR_GET(SEGPTR_STRDUP(ofn->lpstrInitialDir));
1176 if (ofn->lpstrTitle)
1177 ofn16->lpstrTitle = SEGPTR_GET(SEGPTR_STRDUP(ofn->lpstrTitle));
1178 ofn16->Flags = ofn->Flags|OFN_WINE;
1179 ofn16->nFileOffset = ofn->nFileOffset;
1180 ofn16->nFileExtension = ofn->nFileExtension;
1181 if (ofn->lpstrDefExt)
1182 ofn16->lpstrDefExt = SEGPTR_GET(SEGPTR_STRDUP(ofn->lpstrDefExt));
1183 ofn16->lCustData = ofn->lCustData;
1184 ofn16->lpfnHook = (LPOFNHOOKPROC16)ofn->lpfnHook;
1186 if (ofn->lpTemplateName)
1187 ofn16->lpTemplateName = SEGPTR_GET(SEGPTR_STRDUP(ofn->lpTemplateName));
1189 ret = dofunction(SEGPTR_GET(ofn16));
1191 ofn->nFileOffset = ofn16->nFileOffset;
1192 ofn->nFileExtension = ofn16->nFileExtension;
1193 if (ofn16->lpstrFilter)
1194 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFilter));
1195 if (ofn16->lpTemplateName)
1196 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpTemplateName));
1197 if (ofn16->lpstrDefExt)
1198 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrDefExt));
1199 if (ofn16->lpstrTitle)
1200 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrTitle));
1201 if (ofn16->lpstrInitialDir)
1202 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrInitialDir));
1203 if (ofn16->lpstrCustomFilter)
1204 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrCustomFilter));
1206 if (ofn16->lpstrFile)
1208 LPCSTR src = PTR_SEG_TO_LIN(ofn16->lpstrFile);
1209 LPSTR dst = ofn->lpstrFile;
1211 if ((ofn->Flags & OFN_ALLOWMULTISELECT) && (ofn->Flags & OFN_EXPLORER)) {
1212 /* FIXME(EPP): I tried to use:
1213 * memcpy(ofn->lpstrFile, PTR_SEG_TO_LIN(ofn16->lpstrFile, ofn->nMaxFile)
1214 * but it did crash with winamp 2.21, so copy string by string
1216 int len;
1217 do {
1218 strcpy(dst, src);
1219 len = strlen(dst) + 1; /* strlen(dst) == strlen(src) */
1220 dst += len;
1221 src += len;
1222 } while (len > 1);
1223 } else {
1224 strcpy(dst, src);
1226 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFile));
1229 if (ofn16->lpstrFileTitle)
1231 if (ofn->lpstrFileTitle)
1232 strcpy(ofn->lpstrFileTitle,
1233 PTR_SEG_TO_LIN(ofn16->lpstrFileTitle));
1234 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFileTitle));
1236 SEGPTR_FREE(ofn16);
1237 return ret;
1240 static BOOL Commdlg_GetFileNameW( BOOL16 (CALLBACK *dofunction)(SEGPTR x),
1241 LPOPENFILENAMEW ofn )
1243 BOOL16 ret;
1244 LPOPENFILENAME16 ofn16 = SEGPTR_ALLOC(sizeof(OPENFILENAME16));
1246 memset(ofn16,'\0',sizeof(*ofn16));
1247 ofn16->lStructSize = sizeof(*ofn16);
1248 ofn16->hwndOwner = ofn->hwndOwner;
1249 ofn16->hInstance = MapHModuleLS(ofn->hInstance);
1250 if (ofn->lpstrFilter) {
1251 LPWSTR s;
1252 LPSTR x,y;
1253 int n;
1255 /* filter is a list... title\0ext\0......\0\0 */
1256 s = (LPWSTR)ofn->lpstrFilter;
1257 while (*s)
1258 s = s+lstrlenW(s)+1;
1259 s++;
1260 n = s - ofn->lpstrFilter; /* already divides by 2. ptr magic */
1261 x = y = (LPSTR)SEGPTR_ALLOC(n);
1262 s = (LPWSTR)ofn->lpstrFilter;
1263 while (*s) {
1264 lstrcpyWtoA(x,s);
1265 x+=lstrlenA(x)+1;
1266 s+=lstrlenW(s)+1;
1268 *x=0;
1269 ofn16->lpstrFilter = SEGPTR_GET(y);
1271 if (ofn->lpstrCustomFilter) {
1272 LPWSTR s;
1273 LPSTR x,y;
1274 int n;
1276 /* filter is a list... title\0ext\0......\0\0 */
1277 s = (LPWSTR)ofn->lpstrCustomFilter;
1278 while (*s)
1279 s = s+lstrlenW(s)+1;
1280 s++;
1281 n = s - ofn->lpstrCustomFilter;
1282 x = y = (LPSTR)SEGPTR_ALLOC(n);
1283 s = (LPWSTR)ofn->lpstrCustomFilter;
1284 while (*s) {
1285 lstrcpyWtoA(x,s);
1286 x+=lstrlenA(x)+1;
1287 s+=lstrlenW(s)+1;
1289 *x=0;
1290 ofn16->lpstrCustomFilter = SEGPTR_GET(y);
1292 ofn16->nMaxCustFilter = ofn->nMaxCustFilter;
1293 ofn16->nFilterIndex = ofn->nFilterIndex;
1294 if (ofn->nMaxFile)
1295 ofn16->lpstrFile = SEGPTR_GET(SEGPTR_ALLOC(ofn->nMaxFile));
1296 ofn16->nMaxFile = ofn->nMaxFile;
1297 ofn16->nMaxFileTitle = ofn->nMaxFileTitle;
1298 if (ofn->nMaxFileTitle)
1299 ofn16->lpstrFileTitle = SEGPTR_GET(SEGPTR_ALLOC(ofn->nMaxFileTitle));
1300 if (ofn->lpstrInitialDir)
1301 ofn16->lpstrInitialDir = SEGPTR_GET(SEGPTR_STRDUP_WtoA(ofn->lpstrInitialDir));
1302 if (ofn->lpstrTitle)
1303 ofn16->lpstrTitle = SEGPTR_GET(SEGPTR_STRDUP_WtoA(ofn->lpstrTitle));
1304 ofn16->Flags = ofn->Flags|OFN_WINE|OFN_UNICODE;
1305 ofn16->nFileOffset = ofn->nFileOffset;
1306 ofn16->nFileExtension = ofn->nFileExtension;
1307 if (ofn->lpstrDefExt)
1308 ofn16->lpstrDefExt = SEGPTR_GET(SEGPTR_STRDUP_WtoA(ofn->lpstrDefExt));
1309 ofn16->lCustData = ofn->lCustData;
1310 ofn16->lpfnHook = (LPOFNHOOKPROC16)ofn->lpfnHook;
1311 if (ofn->lpTemplateName)
1312 ofn16->lpTemplateName = SEGPTR_GET(SEGPTR_STRDUP_WtoA(ofn->lpTemplateName));
1313 ret = dofunction(SEGPTR_GET(ofn16));
1315 ofn->nFileOffset = ofn16->nFileOffset;
1316 ofn->nFileExtension = ofn16->nFileExtension;
1317 if (ofn16->lpstrFilter)
1318 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFilter));
1319 if (ofn16->lpTemplateName)
1320 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpTemplateName));
1321 if (ofn16->lpstrDefExt)
1322 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrDefExt));
1323 if (ofn16->lpstrTitle)
1324 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrTitle));
1325 if (ofn16->lpstrInitialDir)
1326 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrInitialDir));
1327 if (ofn16->lpstrCustomFilter)
1328 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrCustomFilter));
1330 if (ofn16->lpstrFile)
1332 LPCSTR src = PTR_SEG_TO_LIN(ofn16->lpstrFile);
1333 LPWSTR dst = ofn->lpstrFile;
1335 if ((ofn->Flags & OFN_ALLOWMULTISELECT) && (ofn->Flags & OFN_EXPLORER)) {
1336 int len;
1337 do {
1338 lstrcpyAtoW(dst, src);
1339 dst += lstrlenW(dst) + 1;
1340 src += (len = strlen(src) + 1);
1341 } while (len > 1);
1342 } else {
1343 lstrcpyAtoW(ofn->lpstrFile,PTR_SEG_TO_LIN(ofn16->lpstrFile));
1345 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFile));
1348 if (ofn16->lpstrFileTitle) {
1349 if (ofn->lpstrFileTitle)
1350 lstrcpyAtoW(ofn->lpstrFileTitle,
1351 PTR_SEG_TO_LIN(ofn16->lpstrFileTitle));
1352 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFileTitle));
1354 SEGPTR_FREE(ofn16);
1355 return ret;
1357 /***********************************************************************
1358 * GetOpenFileNameA (COMDLG32.10)
1360 * Creates a dialog box for the user to select a file to open.
1362 * RETURNS
1363 * TRUE on succes: user enters a valid file
1364 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1366 * BUGS
1367 * unknown, calls its 16-bit equivalent.
1369 BOOL WINAPI GetOpenFileNameA(
1370 LPOPENFILENAMEA ofn /* address of init structure */
1373 if(TWEAK_WineLook > WIN31_LOOK)
1375 return GetFileDialog95A(ofn, OPEN_DIALOG);
1377 else
1379 BOOL16 (CALLBACK * dofunction)(SEGPTR ofn16) = GetOpenFileName16;
1380 return Commdlg_GetFileNameA(dofunction,ofn);
1384 /***********************************************************************
1385 * GetOpenFileNameW (COMDLG32.11)
1387 * Creates a dialog box for the user to select a file to open.
1389 * RETURNS
1390 * TRUE on succes: user enters a valid file
1391 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1393 * BUGS
1394 * unknown, calls its 16-bit equivalent.
1396 BOOL WINAPI GetOpenFileNameW(
1397 LPOPENFILENAMEW ofn /* address of init structure */
1400 if(TWEAK_WineLook > WIN31_LOOK)
1402 return GetFileDialog95W(ofn, OPEN_DIALOG);
1404 else
1406 BOOL16 (CALLBACK * dofunction)(SEGPTR ofn16) = GetOpenFileName16;
1407 return Commdlg_GetFileNameW(dofunction,ofn);
1411 /***********************************************************************
1412 * GetSaveFileNameA (COMDLG32.12)
1414 * Creates a dialog box for the user to select a file to save.
1416 * RETURNS
1417 * TRUE on succes: user enters a valid file
1418 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1420 * BUGS
1421 * unknown, calls its 16-bit equivalent.
1423 BOOL WINAPI GetSaveFileNameA(
1424 LPOPENFILENAMEA ofn /* address of init structure */
1427 if(TWEAK_WineLook > WIN31_LOOK)
1429 return GetFileDialog95A(ofn, SAVE_DIALOG);
1431 else
1433 BOOL16 (CALLBACK * dofunction)(SEGPTR ofn16) = GetSaveFileName16;
1434 return Commdlg_GetFileNameA(dofunction,ofn);
1439 /***********************************************************************
1440 * GetSaveFileNameW (COMDLG32.13)
1442 * Creates a dialog box for the user to select a file to save.
1444 * RETURNS
1445 * TRUE on succes: user enters a valid file
1446 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1448 * BUGS
1449 * unknown, calls its 16-bit equivalent.
1451 BOOL WINAPI GetSaveFileNameW(
1452 LPOPENFILENAMEW ofn /* address of init structure */
1455 if(TWEAK_WineLook > WIN31_LOOK)
1457 return GetFileDialog95W(ofn, SAVE_DIALOG);
1459 else
1461 BOOL16 (CALLBACK * dofunction)(SEGPTR ofn16) = GetSaveFileName16;
1462 return Commdlg_GetFileNameW(dofunction,ofn);