Restructure DirectSound. Remove dsound thread, use MM timers
[wine/testsucceed.git] / dlls / commdlg / filedlg.c
blobbefb8634dc38e60a9dc250aac0cdfd55744cc968
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
50 LRESULT WINAPI FileOpenDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
51 LPARAM lParam);
52 LRESULT WINAPI FileSaveDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
53 LPARAM lParam);
55 /***********************************************************************
56 * FileDlg_Init [internal]
58 static BOOL FileDlg_Init(void)
60 static BOOL initialized = 0;
61 CURSORICONINFO *fldrInfo;
63 if (!initialized) {
64 if (!hFolder) hFolder = LoadIcon16(0, MAKEINTRESOURCE16(OIC_FOLDER));
65 if (!hFolder2) hFolder2 = LoadIcon16(0, MAKEINTRESOURCE16(OIC_FOLDER2));
66 if (!hFloppy) hFloppy = LoadIcon16(0, MAKEINTRESOURCE16(OIC_FLOPPY));
67 if (!hHDisk) hHDisk = LoadIcon16(0, MAKEINTRESOURCE16(OIC_HDISK));
68 if (!hCDRom) hCDRom = LoadIcon16(0, MAKEINTRESOURCE16(OIC_CDROM));
69 if (!hNet) hNet = LoadIcon16(0, MAKEINTRESOURCE16(OIC_NETWORK));
70 if (hFolder == 0 || hFolder2 == 0 || hFloppy == 0 ||
71 hHDisk == 0 || hCDRom == 0 || hNet == 0)
73 ERR("Error loading icons !\n");
74 return FALSE;
76 fldrInfo = (CURSORICONINFO *) GlobalLock16( hFolder2 );
77 if (!fldrInfo)
79 ERR("Error measuring icons !\n");
80 return FALSE;
82 fldrHeight = fldrInfo -> nHeight;
83 fldrWidth = fldrInfo -> nWidth;
84 GlobalUnlock16( hFolder2 );
85 initialized = TRUE;
87 return TRUE;
90 /***********************************************************************
91 * FileOpenDlgProc [internal]
93 * FIXME: Convert to real 32-bit message processing
95 static LRESULT WINAPI FileOpenDlgProc(HWND hDlg, UINT msg,
96 WPARAM wParam, LPARAM lParam)
98 UINT16 msg16;
99 MSGPARAM16 mp16;
101 mp16.lParam = lParam;
102 if (WINPROC_MapMsg32ATo16( hDlg, msg, wParam,
103 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
104 return 0;
105 mp16.lResult = FileOpenDlgProc16( (HWND16)hDlg, msg16,
106 mp16.wParam, mp16.lParam );
108 WINPROC_UnmapMsg32ATo16( hDlg, msg, wParam, lParam, &mp16 );
109 return mp16.lResult;
112 /***********************************************************************
113 * FileSaveDlgProc [internal]
115 * FIXME: Convert to real 32-bit message processing
117 static LRESULT WINAPI FileSaveDlgProc(HWND hDlg, UINT msg,
118 WPARAM wParam, LPARAM lParam)
120 UINT16 msg16;
121 MSGPARAM16 mp16;
123 mp16.lParam = lParam;
124 if (WINPROC_MapMsg32ATo16( hDlg, msg, wParam,
125 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
126 return 0;
127 mp16.lResult = FileSaveDlgProc16( (HWND16)hDlg, msg16,
128 mp16.wParam, mp16.lParam );
130 WINPROC_UnmapMsg32ATo16( hDlg, msg, wParam, lParam, &mp16 );
131 return mp16.lResult;
134 /***********************************************************************
135 * GetOpenFileName16 (COMMDLG.1)
137 * Creates a dialog box for the user to select a file to open.
139 * RETURNS
140 * TRUE on success: user selected a valid file
141 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
143 * BUGS
144 * unknown, there are some FIXME's left.
146 BOOL16 WINAPI GetOpenFileName16(
147 SEGPTR ofn /* addess of structure with data*/
150 HINSTANCE hInst;
151 HANDLE hDlgTmpl = 0, hResInfo;
152 BOOL bRet = FALSE, win32Format = FALSE;
153 HWND hwndDialog;
154 LPOPENFILENAME16 lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(ofn);
155 LPCVOID template;
156 char defaultopen[]="Open File";
157 char *str=0,*str1=0;
159 if (!lpofn || !FileDlg_Init()) return FALSE;
161 if (lpofn->Flags & OFN_WINE) {
162 if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE)
164 if (!(template = LockResource( MapHModuleSL(lpofn->hInstance ))))
166 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
167 return FALSE;
170 else if (lpofn->Flags & OFN_ENABLETEMPLATE)
172 if (!(hResInfo = FindResourceA(MapHModuleSL(lpofn->hInstance),
173 PTR_SEG_TO_LIN(lpofn->lpTemplateName), RT_DIALOGA)))
175 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
176 return FALSE;
178 if (!(hDlgTmpl = LoadResource( MapHModuleSL(lpofn->hInstance),
179 hResInfo )) ||
180 !(template = LockResource( hDlgTmpl )))
182 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
183 return FALSE;
185 } else {
186 if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "OPEN_FILE", RT_DIALOGA)))
188 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
189 return FALSE;
191 if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
192 !(template = LockResource( hDlgTmpl )))
194 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
195 return FALSE;
198 win32Format = TRUE;
199 } else {
200 if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE)
202 if (!(template = LockResource16( lpofn->hInstance )))
204 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
205 return FALSE;
208 else if (lpofn->Flags & OFN_ENABLETEMPLATE)
210 if (!(hResInfo = FindResource16(lpofn->hInstance,
211 lpofn->lpTemplateName,
212 RT_DIALOG16)))
214 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
215 return FALSE;
217 if (!(hDlgTmpl = LoadResource16( lpofn->hInstance, hResInfo )) ||
218 !(template = LockResource16( hDlgTmpl )))
220 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
221 return FALSE;
223 } else {
224 if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "OPEN_FILE", RT_DIALOGA)))
226 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
227 return FALSE;
229 if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
230 !(template = LockResource( hDlgTmpl )))
232 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
233 return FALSE;
235 win32Format = TRUE;
239 hInst = GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );
241 if (!(lpofn->lpstrFilter))
243 str = SEGPTR_ALLOC(sizeof(defaultfilter));
244 TRACE("Alloc %p default for Filetype in GetOpenFileName\n",str);
245 memcpy(str,defaultfilter,sizeof(defaultfilter));
246 lpofn->lpstrFilter=SEGPTR_GET(str);
249 if (!(lpofn->lpstrTitle))
251 str1 = SEGPTR_ALLOC(strlen(defaultopen)+1);
252 TRACE("Alloc %p default for Title in GetOpenFileName\n",str1);
253 strcpy(str1,defaultopen);
254 lpofn->lpstrTitle=SEGPTR_GET(str1);
257 /* FIXME: doesn't handle win32 format correctly yet */
258 hwndDialog = DIALOG_CreateIndirect( hInst, template, win32Format,
259 lpofn->hwndOwner,
260 (DLGPROC16)FileOpenDlgProc,
261 ofn, WIN_PROC_32A );
262 if (hwndDialog) bRet = DIALOG_DoDialogBox( hwndDialog, lpofn->hwndOwner );
264 if (str1)
266 TRACE("Freeing %p default for Title in GetOpenFileName\n",str1);
267 SEGPTR_FREE(str1);
268 lpofn->lpstrTitle=0;
271 if (str)
273 TRACE("Freeing %p default for Filetype in GetOpenFileName\n",str);
274 SEGPTR_FREE(str);
275 lpofn->lpstrFilter=0;
278 if (hDlgTmpl) {
279 if (lpofn->Flags & OFN_WINE)
280 FreeResource( hDlgTmpl );
281 else
282 FreeResource16( hDlgTmpl );
285 TRACE("return lpstrFile='%s' !\n",
286 (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
287 return bRet;
291 /***********************************************************************
292 * GetSaveFileName (COMMDLG.2)
294 * Creates a dialog box for the user to select a file to save.
296 * RETURNS
297 * TRUE on succes: user enters a valid file
298 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
300 * BUGS
301 * unknown. There are some FIXME's left.
303 BOOL16 WINAPI GetSaveFileName16(
304 SEGPTR ofn /* addess of structure with data*/
307 HINSTANCE hInst;
308 HANDLE hDlgTmpl = 0;
309 BOOL bRet = FALSE, win32Format = FALSE;
310 LPOPENFILENAME16 lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(ofn);
311 LPCVOID template;
312 HWND hwndDialog;
313 char defaultsave[]="Save as";
314 char *str =0,*str1=0;
316 if (!lpofn || !FileDlg_Init()) return FALSE;
318 if (lpofn->Flags & OFN_WINE) {
319 if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE)
321 if (!(template = LockResource( MapHModuleSL(lpofn->hInstance ))))
323 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
324 return FALSE;
327 else if (lpofn->Flags & OFN_ENABLETEMPLATE)
329 HANDLE hResInfo;
330 if (!(hResInfo = FindResourceA(MapHModuleSL(lpofn->hInstance),
331 PTR_SEG_TO_LIN(lpofn->lpTemplateName),
332 RT_DIALOGA)))
334 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
335 return FALSE;
337 if (!(hDlgTmpl = LoadResource(MapHModuleSL(lpofn->hInstance),
338 hResInfo)) ||
339 !(template = LockResource(hDlgTmpl)))
341 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
342 return FALSE;
344 win32Format= TRUE;
345 } else {
346 HANDLE hResInfo;
347 if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "SAVE_FILE", RT_DIALOGA)))
349 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
350 return FALSE;
352 if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
353 !(template = LockResource( hDlgTmpl )))
355 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
356 return FALSE;
358 win32Format = TRUE;
360 } else {
361 if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE)
363 if (!(template = LockResource16( lpofn->hInstance )))
365 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
366 return FALSE;
369 else if (lpofn->Flags & OFN_ENABLETEMPLATE)
371 HANDLE16 hResInfo;
372 if (!(hResInfo = FindResource16(lpofn->hInstance,
373 lpofn->lpTemplateName,
374 RT_DIALOG16)))
376 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
377 return FALSE;
379 if (!(hDlgTmpl = LoadResource16( lpofn->hInstance, hResInfo )) ||
380 !(template = LockResource16( hDlgTmpl )))
382 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
383 return FALSE;
385 } else {
386 HANDLE hResInfo;
387 if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "SAVE_FILE", RT_DIALOGA)))
389 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
390 return FALSE;
392 if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
393 !(template = LockResource( hDlgTmpl )))
395 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
396 return FALSE;
398 win32Format = TRUE;
402 hInst = GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );
404 if (!(lpofn->lpstrFilter))
406 str = SEGPTR_ALLOC(sizeof(defaultfilter));
407 TRACE("Alloc default for Filetype in GetSaveFileName\n");
408 memcpy(str,defaultfilter,sizeof(defaultfilter));
409 lpofn->lpstrFilter=SEGPTR_GET(str);
412 if (!(lpofn->lpstrTitle))
414 str1 = SEGPTR_ALLOC(sizeof(defaultsave)+1);
415 TRACE("Alloc default for Title in GetSaveFileName\n");
416 strcpy(str1,defaultsave);
417 lpofn->lpstrTitle=SEGPTR_GET(str1);
420 hwndDialog = DIALOG_CreateIndirect( hInst, template, win32Format,
421 lpofn->hwndOwner,
422 (DLGPROC16)FileSaveDlgProc,
423 ofn, WIN_PROC_32A );
424 if (hwndDialog) bRet = DIALOG_DoDialogBox( hwndDialog, lpofn->hwndOwner );
426 if (str1)
428 TRACE("Freeing %p default for Title in GetSaveFileName\n",str1);
429 SEGPTR_FREE(str1);
430 lpofn->lpstrTitle=0;
433 if (str)
435 TRACE("Freeing %p default for Filetype in GetSaveFileName\n",str);
436 SEGPTR_FREE(str);
437 lpofn->lpstrFilter=0;
440 if (hDlgTmpl) {
441 if (lpofn->Flags & OFN_WINE)
442 FreeResource( hDlgTmpl );
443 else
444 FreeResource16( hDlgTmpl );
447 TRACE("return lpstrFile='%s' !\n",
448 (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
449 return bRet;
452 /***********************************************************************
453 * FILEDLG_StripEditControl [internal]
454 * Strip pathnames off the contents of the edit control.
456 static void FILEDLG_StripEditControl(HWND16 hwnd)
458 char temp[512], *cp;
460 GetDlgItemTextA( hwnd, edt1, temp, sizeof(temp) );
461 cp = strrchr(temp, '\\');
462 if (cp != NULL) {
463 strcpy(temp, cp+1);
465 cp = strrchr(temp, ':');
466 if (cp != NULL) {
467 strcpy(temp, cp+1);
469 /* FIXME: shouldn't we do something with the result here? ;-) */
472 /***********************************************************************
473 * FILEDLG_ScanDir [internal]
475 static BOOL FILEDLG_ScanDir(HWND16 hWnd, LPSTR newPath)
477 char buffer[512];
478 char* str = buffer;
479 int drive;
480 HWND hlb;
482 lstrcpynA(buffer, newPath, sizeof(buffer));
484 if (str[0] && (str[1] == ':')) {
485 drive = toupper(str[0]) - 'A';
486 str += 2;
487 if (!DRIVE_SetCurrentDrive(drive))
488 return FALSE;
489 } else {
490 drive = DRIVE_GetCurrentDrive();
493 if (str[0] && !DRIVE_Chdir(drive, str)) {
494 return FALSE;
497 GetDlgItemTextA(hWnd, edt1, buffer, sizeof(buffer));
498 if ((hlb = GetDlgItem(hWnd, lst1)) != 0) {
499 char* scptr; /* ptr on semi-colon */
500 char* filter = buffer;
502 TRACE("Using filter %s\n", filter);
503 SendMessageA(hlb, LB_RESETCONTENT, 0, 0);
504 while (filter) {
505 scptr = strchr(filter, ';');
506 if (scptr) *scptr = 0;
507 TRACE("Using file spec %s\n", filter);
508 if (SendMessageA(hlb, LB_DIR, 0, (LPARAM)filter) == LB_ERR)
509 return FALSE;
510 if (scptr) *scptr = ';';
511 filter = (scptr) ? (scptr + 1) : 0;
515 strcpy(buffer, "*.*");
516 return DlgDirListA(hWnd, buffer, lst2, stc1, DDL_EXCLUSIVE | DDL_DIRECTORY);
519 /***********************************************************************
520 * FILEDLG_GetFileType [internal]
523 static LPSTR FILEDLG_GetFileType(LPSTR cfptr, LPSTR fptr, WORD index)
525 int n, i;
526 i = 0;
527 if (cfptr)
528 for ( ;(n = strlen(cfptr)) != 0; i++)
530 cfptr += n + 1;
531 if (i == index)
532 return cfptr;
533 cfptr += strlen(cfptr) + 1;
535 if (fptr)
536 for ( ;(n = strlen(fptr)) != 0; i++)
538 fptr += n + 1;
539 if (i == index)
540 return fptr;
541 fptr += strlen(fptr) + 1;
543 return "*.*"; /* FIXME */
546 /***********************************************************************
547 * FILEDLG_WMDrawItem [internal]
549 static LONG FILEDLG_WMDrawItem(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam,int savedlg)
551 LPDRAWITEMSTRUCT16 lpdis = (LPDRAWITEMSTRUCT16)PTR_SEG_TO_LIN(lParam);
552 char *str;
553 HICON16 hIcon;
554 COLORREF oldText = 0, oldBk = 0;
556 if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst1)
558 if (!(str = SEGPTR_ALLOC(512))) return FALSE;
559 SendMessage16(lpdis->hwndItem, LB_GETTEXT16, lpdis->itemID,
560 (LPARAM)SEGPTR_GET(str));
562 if ((lpdis->itemState & ODS_SELECTED) && !savedlg)
564 oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
565 oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
567 if (savedlg)
568 SetTextColor(lpdis->hDC,GetSysColor(COLOR_GRAYTEXT) );
570 ExtTextOut16(lpdis->hDC, lpdis->rcItem.left + 1,
571 lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
572 &(lpdis->rcItem), str, strlen(str), NULL);
574 if (lpdis->itemState & ODS_SELECTED)
575 DrawFocusRect16( lpdis->hDC, &(lpdis->rcItem) );
577 if ((lpdis->itemState & ODS_SELECTED) && !savedlg)
579 SetBkColor( lpdis->hDC, oldBk );
580 SetTextColor( lpdis->hDC, oldText );
582 SEGPTR_FREE(str);
583 return TRUE;
586 if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst2)
588 if (!(str = SEGPTR_ALLOC(512))) return FALSE;
589 SendMessage16(lpdis->hwndItem, LB_GETTEXT16, lpdis->itemID,
590 (LPARAM)SEGPTR_GET(str));
592 if (lpdis->itemState & ODS_SELECTED)
594 oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
595 oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
597 ExtTextOut16(lpdis->hDC, lpdis->rcItem.left + fldrWidth,
598 lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
599 &(lpdis->rcItem), str, strlen(str), NULL);
601 if (lpdis->itemState & ODS_SELECTED)
602 DrawFocusRect16( lpdis->hDC, &(lpdis->rcItem) );
604 if (lpdis->itemState & ODS_SELECTED)
606 SetBkColor( lpdis->hDC, oldBk );
607 SetTextColor( lpdis->hDC, oldText );
609 DrawIcon(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hFolder);
610 SEGPTR_FREE(str);
611 return TRUE;
613 if (lpdis->CtlType == ODT_COMBOBOX && lpdis->CtlID == cmb2)
615 if (!(str = SEGPTR_ALLOC(512))) return FALSE;
616 SendMessage16(lpdis->hwndItem, CB_GETLBTEXT16, lpdis->itemID,
617 (LPARAM)SEGPTR_GET(str));
618 switch(DRIVE_GetType( str[2] - 'a' ))
620 case TYPE_FLOPPY: hIcon = hFloppy; break;
621 case TYPE_CDROM: hIcon = hCDRom; break;
622 case TYPE_NETWORK: hIcon = hNet; break;
623 case TYPE_HD:
624 default: hIcon = hHDisk; break;
626 if (lpdis->itemState & ODS_SELECTED)
628 oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
629 oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
631 ExtTextOut16(lpdis->hDC, lpdis->rcItem.left + fldrWidth,
632 lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
633 &(lpdis->rcItem), str, strlen(str), NULL);
635 if (lpdis->itemState & ODS_SELECTED)
637 SetBkColor( lpdis->hDC, oldBk );
638 SetTextColor( lpdis->hDC, oldText );
640 DrawIcon(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hIcon);
641 SEGPTR_FREE(str);
642 return TRUE;
644 return FALSE;
647 /***********************************************************************
648 * FILEDLG_WMMeasureItem [internal]
650 static LONG FILEDLG_WMMeasureItem(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam)
652 LPMEASUREITEMSTRUCT16 lpmeasure;
654 lpmeasure = (LPMEASUREITEMSTRUCT16)PTR_SEG_TO_LIN(lParam);
655 lpmeasure->itemHeight = fldrHeight;
656 return TRUE;
659 /***********************************************************************
660 * FILEDLG_HookCallChk [internal]
662 static int FILEDLG_HookCallChk(LPOPENFILENAME16 lpofn)
664 if (lpofn)
665 if (lpofn->Flags & OFN_ENABLEHOOK)
666 if (lpofn->lpfnHook)
667 return 1;
668 return 0;
671 /***********************************************************************
672 * FILEDLG_CallWindowProc [internal]
674 * Adapt the structures back for win32 calls so the callee can read lpCustData
676 static BOOL FILEDLG_CallWindowProc(LPOPENFILENAME16 lpofn,HWND hwnd,
677 UINT wMsg,WPARAM wParam,LPARAM lParam
680 BOOL needstruct;
681 BOOL result = FALSE;
682 WINDOWPROCTYPE ProcType; /* Type of Hook Function to be called. */
684 /* TRUE if lParam points to the OPENFILENAME16 Structure */
685 needstruct = (PTR_SEG_TO_LIN(lParam) == lpofn);
687 ProcType = (lpofn->Flags & OFN_WINE)
688 ? (lpofn->Flags & OFN_UNICODE) /* 32-Bit call to GetOpenFileName */
689 ? WIN_PROC_32W : WIN_PROC_32A
690 : WIN_PROC_16; /* 16-Bit call to GetOpenFileName */
692 if (!(lpofn->Flags & OFN_WINE))
693 /* Call to 16-Bit Hooking function... No Problem at all. */
694 return (BOOL)CallWindowProc16(
695 (WNDPROC16)lpofn->lpfnHook,hwnd,(UINT16)wMsg,(WPARAM16)wParam,lParam
697 /* |OFN_WINE32 */
698 if (needstruct)
700 /* Parameter lParam points to lpofn... Convert Structure Data... */
701 if (lpofn->Flags & OFN_UNICODE)
703 OPENFILENAMEW ofnw;
705 /* FIXME: probably needs more converted */
706 ofnw.lCustData = lpofn->lCustData;
707 return (BOOL)CallWindowProcW(
708 (WNDPROC)lpofn->lpfnHook,hwnd,wMsg,wParam,(LPARAM)&ofnw
711 else /* ! |OFN_UNICODE */
713 OPENFILENAMEA ofna;
715 /* FIXME: probably needs more converted */
716 ofna.lCustData = lpofn->lCustData;
717 return (BOOL)CallWindowProcA(
718 (WNDPROC)lpofn->lpfnHook,hwnd,wMsg,wParam,(LPARAM)&ofna
722 else /* ! needstruct */
724 HWINDOWPROC hWindowProc=NULL;
726 if (WINPROC_SetProc(&hWindowProc, (WNDPROC16)lpofn->lpfnHook, ProcType, WIN_PROC_WINDOW))
728 /* Call Window Procedure converting 16-Bit Type Parameters to 32-Bit Type Parameters */
729 result = CallWindowProc16( (WNDPROC16)hWindowProc,
730 hwnd, wMsg, wParam, lParam );
732 result = LOWORD(result);
734 WINPROC_FreeProc( hWindowProc, WIN_PROC_WINDOW );
737 return result;
743 /***********************************************************************
744 * FILEDLG_WMInitDialog [internal]
747 static LONG FILEDLG_WMInitDialog(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam)
749 int i, n;
750 LPOPENFILENAME16 lpofn;
751 char tmpstr[512];
752 LPSTR pstr, old_pstr;
753 SetPropA(hWnd,OFN_PROP,lParam);
754 lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(lParam);
755 if (lpofn->lpstrTitle) SetWindowText16( hWnd, lpofn->lpstrTitle );
756 /* read custom filter information */
757 if (lpofn->lpstrCustomFilter)
759 pstr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter);
760 n = 0;
761 TRACE("lpstrCustomFilter = %p\n", pstr);
762 while(*pstr)
764 old_pstr = pstr;
765 i = SendDlgItemMessage16(hWnd, cmb1, CB_ADDSTRING16, 0,
766 (LPARAM)lpofn->lpstrCustomFilter + n );
767 n += strlen(pstr) + 1;
768 pstr += strlen(pstr) + 1;
769 TRACE("add str='%s' "
770 "associated to '%s'\n", old_pstr, pstr);
771 SendDlgItemMessage16(hWnd, cmb1, CB_SETITEMDATA16, i, (LPARAM)pstr);
772 n += strlen(pstr) + 1;
773 pstr += strlen(pstr) + 1;
776 /* read filter information */
777 if (lpofn->lpstrFilter) {
778 pstr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFilter);
779 n = 0;
780 while(*pstr) {
781 old_pstr = pstr;
782 i = SendDlgItemMessage16(hWnd, cmb1, CB_ADDSTRING16, 0,
783 (LPARAM)lpofn->lpstrFilter + n );
784 n += strlen(pstr) + 1;
785 pstr += strlen(pstr) + 1;
786 TRACE("add str='%s' "
787 "associated to '%s'\n", old_pstr, pstr);
788 SendDlgItemMessage16(hWnd, cmb1, CB_SETITEMDATA16, i, (LPARAM)pstr);
789 n += strlen(pstr) + 1;
790 pstr += strlen(pstr) + 1;
793 /* set default filter */
794 if (lpofn->nFilterIndex == 0 && lpofn->lpstrCustomFilter == (SEGPTR)NULL)
795 lpofn->nFilterIndex = 1;
796 SendDlgItemMessage16(hWnd, cmb1, CB_SETCURSEL16, lpofn->nFilterIndex - 1, 0);
797 lstrcpynA(tmpstr, FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter),
798 PTR_SEG_TO_LIN(lpofn->lpstrFilter), lpofn->nFilterIndex - 1),512);
799 TRACE("nFilterIndex = %ld, SetText of edt1 to '%s'\n",
800 lpofn->nFilterIndex, tmpstr);
801 SetDlgItemTextA( hWnd, edt1, tmpstr );
802 /* get drive list */
803 *tmpstr = 0;
804 DlgDirListComboBoxA(hWnd, tmpstr, cmb2, 0, DDL_DRIVES | DDL_EXCLUSIVE);
805 /* read initial directory */
806 if (PTR_SEG_TO_LIN(lpofn->lpstrInitialDir) != NULL)
808 int len;
809 lstrcpynA(tmpstr, PTR_SEG_TO_LIN(lpofn->lpstrInitialDir), 511);
810 len=strlen(tmpstr);
811 if (len > 0 && tmpstr[len-1] != '\\' && tmpstr[len-1] != ':') {
812 tmpstr[len]='\\';
813 tmpstr[len+1]='\0';
816 else
817 *tmpstr = 0;
818 if (!FILEDLG_ScanDir(hWnd, tmpstr)) {
819 *tmpstr = 0;
820 if (!FILEDLG_ScanDir(hWnd, tmpstr))
821 WARN("Couldn't read initial directory %s!\n",tmpstr);
823 /* select current drive in combo 2, omit missing drives */
824 for(i=0, n=-1; i<=DRIVE_GetCurrentDrive(); i++)
825 if (DRIVE_IsValid(i)) n++;
826 SendDlgItemMessage16(hWnd, cmb2, CB_SETCURSEL16, n, 0);
827 if (!(lpofn->Flags & OFN_SHOWHELP))
828 ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
829 if (lpofn->Flags & OFN_HIDEREADONLY)
830 ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
831 if (FILEDLG_HookCallChk(lpofn))
832 return (BOOL16)FILEDLG_CallWindowProc(lpofn,hWnd,WM_INITDIALOG,wParam,lParam );
833 else
834 return TRUE;
837 /***********************************************************************
838 * FILEDLG_WMCommand [internal]
840 BOOL in_update=FALSE;
842 static LRESULT FILEDLG_WMCommand(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam)
844 LONG lRet;
845 LPOPENFILENAME16 lpofn;
846 OPENFILENAME16 ofn2;
847 char tmpstr[512], tmpstr2[512];
848 LPSTR pstr, pstr2;
849 UINT16 control,notification;
851 /* Notifications are packaged differently in Win32 */
852 control = wParam;
853 notification = HIWORD(lParam);
855 lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(GetPropA(hWnd,OFN_PROP));
856 switch (control)
858 case lst1: /* file list */
859 FILEDLG_StripEditControl(hWnd);
860 if (notification == LBN_DBLCLK)
861 goto almost_ok;
862 lRet = SendDlgItemMessage16(hWnd, lst1, LB_GETCURSEL16, 0, 0);
863 if (lRet == LB_ERR) return TRUE;
864 if ((pstr = SEGPTR_ALLOC(512)))
866 SendDlgItemMessage16(hWnd, lst1, LB_GETTEXT16, lRet,
867 (LPARAM)SEGPTR_GET(pstr));
868 SetDlgItemTextA( hWnd, edt1, pstr );
869 SEGPTR_FREE(pstr);
871 if (FILEDLG_HookCallChk(lpofn))
872 FILEDLG_CallWindowProc(lpofn,hWnd,
873 RegisterWindowMessageA( LBSELCHSTRING ),
874 control, MAKELONG(lRet,CD_LBSELCHANGE));
875 /* FIXME: for OFN_ALLOWMULTISELECT we need CD_LBSELSUB, CD_SELADD, CD_LBSELNOITEMS */
876 return TRUE;
877 case lst2: /* directory list */
878 FILEDLG_StripEditControl(hWnd);
879 if (notification == LBN_DBLCLK)
881 lRet = SendDlgItemMessage16(hWnd, lst2, LB_GETCURSEL16, 0, 0);
882 if (lRet == LB_ERR) return TRUE;
883 pstr = SEGPTR_ALLOC(512);
884 SendDlgItemMessage16(hWnd, lst2, LB_GETTEXT16, lRet,
885 (LPARAM)SEGPTR_GET(pstr));
886 strcpy( tmpstr, pstr );
887 SEGPTR_FREE(pstr);
888 if (tmpstr[0] == '[')
890 tmpstr[strlen(tmpstr) - 1] = 0;
891 strcpy(tmpstr,tmpstr+1);
893 strcat(tmpstr, "\\");
894 goto reset_scan;
896 return TRUE;
897 case cmb1: /* file type drop list */
898 if (notification == CBN_SELCHANGE)
900 *tmpstr = 0;
901 goto reset_scan;
903 return TRUE;
904 case chx1:
905 return TRUE;
906 case pshHelp:
907 return TRUE;
908 case cmb2: /* disk drop list */
909 FILEDLG_StripEditControl(hWnd);
910 lRet = SendDlgItemMessage16(hWnd, cmb2, CB_GETCURSEL16, 0, 0L);
911 if (lRet == LB_ERR) return 0;
912 pstr = SEGPTR_ALLOC(512);
913 SendDlgItemMessage16(hWnd, cmb2, CB_GETLBTEXT16, lRet,
914 (LPARAM)SEGPTR_GET(pstr));
915 sprintf(tmpstr, "%c:", pstr[2]);
916 SEGPTR_FREE(pstr);
917 if (notification != CBN_SELCHANGE) return TRUE;
918 reset_scan:
919 lRet = SendDlgItemMessage16(hWnd, cmb1, CB_GETCURSEL16, 0, 0);
920 if (lRet == LB_ERR)
921 return TRUE;
922 pstr = (LPSTR)SendDlgItemMessage16(hWnd, cmb1, CB_GETITEMDATA16, lRet, 0);
923 TRACE("Selected filter : %s\n", pstr);
924 SetDlgItemTextA( hWnd, edt1, pstr );
925 FILEDLG_ScanDir(hWnd, tmpstr);
926 in_update=TRUE;
927 case IDOK:
928 almost_ok:
929 ofn2=*lpofn; /* for later restoring */
930 GetDlgItemTextA( hWnd, edt1, tmpstr, sizeof(tmpstr) );
931 pstr = strrchr(tmpstr, '\\');
932 if (pstr == NULL)
933 pstr = strrchr(tmpstr, ':');
934 if (strchr(tmpstr,'*') != NULL || strchr(tmpstr,'?') != NULL)
936 /* edit control contains wildcards */
937 if (pstr != NULL)
939 lstrcpynA(tmpstr2, pstr+1, 512);
940 *(pstr+1) = 0;
942 else
944 strcpy(tmpstr2, tmpstr);
945 *tmpstr=0;
947 TRACE("tmpstr=%s, tmpstr2=%s\n", tmpstr, tmpstr2);
948 SetDlgItemTextA( hWnd, edt1, tmpstr2 );
949 FILEDLG_ScanDir(hWnd, tmpstr);
950 return TRUE;
952 /* no wildcards, we might have a directory or a filename */
953 /* try appending a wildcard and reading the directory */
954 pstr2 = tmpstr + strlen(tmpstr);
955 if (pstr == NULL || *(pstr+1) != 0)
956 strcat(tmpstr, "\\");
957 lRet = SendDlgItemMessage16(hWnd, cmb1, CB_GETCURSEL16, 0, 0);
958 if (lRet == LB_ERR) return TRUE;
959 lpofn->nFilterIndex = lRet + 1;
960 TRACE("lpofn->nFilterIndex=%ld\n", lpofn->nFilterIndex);
961 lstrcpynA(tmpstr2,
962 FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter),
963 PTR_SEG_TO_LIN(lpofn->lpstrFilter),
964 lRet), sizeof(tmpstr2));
965 SetDlgItemTextA( hWnd, edt1, tmpstr2 );
966 if (!in_update)
967 /* if ScanDir succeeds, we have changed the directory */
968 if (FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
969 /* if not, this must be a filename */
970 *pstr2 = 0;
971 if (pstr != NULL)
973 /* strip off the pathname */
974 *pstr = 0;
975 SetDlgItemTextA( hWnd, edt1, pstr + 1 );
976 lstrcpynA(tmpstr2, pstr+1, sizeof(tmpstr2) );
977 /* Should we MessageBox() if this fails? */
978 if (!FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
979 strcpy(tmpstr, tmpstr2);
981 else SetDlgItemTextA( hWnd, edt1, tmpstr );
982 #if 0
983 ShowWindow16(hWnd, SW_HIDE); /* this should not be necessary ?! (%%%) */
984 #endif
986 int lenstr2;
987 int drive = DRIVE_GetCurrentDrive();
988 tmpstr2[0] = 'A'+ drive;
989 tmpstr2[1] = ':';
990 tmpstr2[2] = '\\';
991 lstrcpynA(tmpstr2 + 3, DRIVE_GetDosCwd(drive), 507);
992 lenstr2=strlen(tmpstr2);
993 if (lenstr2 > 3)
994 tmpstr2[lenstr2++]='\\';
995 lstrcpynA(tmpstr2+lenstr2, tmpstr, 512-lenstr2);
996 if (lpofn->lpstrFile)
997 lstrcpynA(PTR_SEG_TO_LIN(lpofn->lpstrFile), tmpstr2,lpofn->nMaxFile);
999 lpofn->nFileOffset = strrchr(tmpstr2,'\\') - tmpstr2 +1;
1000 lpofn->nFileExtension = 0;
1001 while(tmpstr2[lpofn->nFileExtension] != '.' && tmpstr2[lpofn->nFileExtension] != '\0')
1002 lpofn->nFileExtension++;
1003 if (tmpstr2[lpofn->nFileExtension] == '\0')
1004 lpofn->nFileExtension = 0;
1005 else
1006 lpofn->nFileExtension++;
1008 if(in_update)
1010 if (FILEDLG_HookCallChk(lpofn))
1011 FILEDLG_CallWindowProc(lpofn,hWnd,
1012 RegisterWindowMessageA( LBSELCHSTRING ),
1013 control, MAKELONG(lRet,CD_LBSELCHANGE));
1015 in_update = FALSE;
1016 return TRUE;
1018 if (PTR_SEG_TO_LIN(lpofn->lpstrFileTitle) != NULL)
1020 lRet = SendDlgItemMessage16(hWnd, lst1, LB_GETCURSEL16, 0, 0);
1021 SendDlgItemMessage16(hWnd, lst1, LB_GETTEXT16, lRet,
1022 lpofn->lpstrFileTitle );
1024 if (FILEDLG_HookCallChk(lpofn))
1026 lRet= (BOOL16)FILEDLG_CallWindowProc(lpofn,
1027 hWnd, RegisterWindowMessageA( FILEOKSTRING ), 0, lParam );
1028 if (lRet)
1030 *lpofn=ofn2; /* restore old state */
1031 #if 0
1032 ShowWindow16(hWnd, SW_SHOW); /* only if above (%%%) SW_HIDE used */
1033 #endif
1034 break;
1037 if ((lpofn->Flags & OFN_ALLOWMULTISELECT) && (lpofn->Flags & OFN_EXPLORER)) {
1038 if (lpofn->lpstrFile) {
1039 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile);
1040 LPSTR ptr = strrchr(str, '\\');
1041 str[strlen(str) + 1] = '\0';
1042 *ptr = 0;
1045 EndDialog(hWnd, TRUE);
1046 return TRUE;
1047 case IDCANCEL:
1048 EndDialog(hWnd, FALSE);
1049 return TRUE;
1051 return FALSE;
1054 /***********************************************************************
1055 * FileOpenDlgProc16 (COMMDLG.6)
1057 LRESULT WINAPI FileOpenDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1058 LPARAM lParam)
1060 LPOPENFILENAME16 lpofn =(LPOPENFILENAME16)PTR_SEG_TO_LIN(GetPropA(hWnd,OFN_PROP));
1062 if (wMsg!=WM_INITDIALOG)
1063 if (FILEDLG_HookCallChk(lpofn))
1065 LRESULT lRet=(BOOL16)FILEDLG_CallWindowProc(lpofn,hWnd,wMsg,wParam,lParam);
1066 if (lRet)
1067 return lRet; /* else continue message processing */
1069 switch (wMsg)
1071 case WM_INITDIALOG:
1072 return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
1073 case WM_MEASUREITEM:
1074 return FILEDLG_WMMeasureItem(hWnd, wParam, lParam);
1075 case WM_DRAWITEM:
1076 return FILEDLG_WMDrawItem(hWnd, wParam, lParam, FALSE);
1077 case WM_COMMAND:
1078 return FILEDLG_WMCommand(hWnd, wParam, lParam);
1079 #if 0
1080 case WM_CTLCOLOR:
1081 SetBkColor((HDC16)wParam, 0x00C0C0C0);
1082 switch (HIWORD(lParam))
1084 case CTLCOLOR_BTN:
1085 SetTextColor((HDC16)wParam, 0x00000000);
1086 return hGRAYBrush;
1087 case CTLCOLOR_STATIC:
1088 SetTextColor((HDC16)wParam, 0x00000000);
1089 return hGRAYBrush;
1091 break;
1092 #endif
1094 return FALSE;
1097 /***********************************************************************
1098 * FileSaveDlgProc16 (COMMDLG.7)
1100 LRESULT WINAPI FileSaveDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1101 LPARAM lParam)
1103 LPOPENFILENAME16 lpofn =(LPOPENFILENAME16)PTR_SEG_TO_LIN(GetPropA(hWnd,OFN_PROP));
1105 if (wMsg!=WM_INITDIALOG)
1106 if (FILEDLG_HookCallChk(lpofn))
1108 LRESULT lRet=(BOOL16)FILEDLG_CallWindowProc(lpofn,hWnd,wMsg,wParam,lParam);
1109 if (lRet)
1110 return lRet; /* else continue message processing */
1112 switch (wMsg) {
1113 case WM_INITDIALOG:
1114 return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
1116 case WM_MEASUREITEM:
1117 return FILEDLG_WMMeasureItem(hWnd, wParam, lParam);
1119 case WM_DRAWITEM:
1120 return FILEDLG_WMDrawItem(hWnd, wParam, lParam, TRUE);
1122 case WM_COMMAND:
1123 return FILEDLG_WMCommand(hWnd, wParam, lParam);
1127 case WM_CTLCOLOR:
1128 SetBkColor((HDC16)wParam, 0x00C0C0C0);
1129 switch (HIWORD(lParam))
1131 case CTLCOLOR_BTN:
1132 SetTextColor((HDC16)wParam, 0x00000000);
1133 return hGRAYBrush;
1134 case CTLCOLOR_STATIC:
1135 SetTextColor((HDC16)wParam, 0x00000000);
1136 return hGRAYBrush;
1138 return FALSE;
1141 return FALSE;
1144 static BOOL Commdlg_GetFileNameA( BOOL16 (CALLBACK *dofunction)(SEGPTR x),
1145 LPOPENFILENAMEA ofn )
1147 BOOL16 ret;
1148 LPOPENFILENAME16 ofn16 = SEGPTR_ALLOC(sizeof(OPENFILENAME16));
1150 memset(ofn16,'\0',sizeof(*ofn16));
1151 ofn16->lStructSize = sizeof(*ofn16);
1152 ofn16->hwndOwner = ofn->hwndOwner;
1153 ofn16->hInstance = MapHModuleLS(ofn->hInstance);
1154 if (ofn->lpstrFilter) {
1155 LPSTR s,x;
1157 /* filter is a list... title\0ext\0......\0\0 */
1158 s = (LPSTR)ofn->lpstrFilter;
1159 while (*s)
1160 s = s+strlen(s)+1;
1161 s++;
1162 x = (LPSTR)SEGPTR_ALLOC(s-ofn->lpstrFilter);
1163 memcpy(x,ofn->lpstrFilter,s-ofn->lpstrFilter);
1164 ofn16->lpstrFilter = SEGPTR_GET(x);
1166 if (ofn->lpstrCustomFilter) {
1167 LPSTR s,x;
1169 /* filter is a list... title\0ext\0......\0\0 */
1170 s = (LPSTR)ofn->lpstrCustomFilter;
1171 while (*s)
1172 s = s+strlen(s)+1;
1173 s++;
1174 x = SEGPTR_ALLOC(s-ofn->lpstrCustomFilter);
1175 memcpy(x,ofn->lpstrCustomFilter,s-ofn->lpstrCustomFilter);
1176 ofn16->lpstrCustomFilter = SEGPTR_GET(x);
1178 ofn16->nMaxCustFilter = ofn->nMaxCustFilter;
1179 ofn16->nFilterIndex = ofn->nFilterIndex;
1180 if (ofn->nMaxFile)
1181 ofn16->lpstrFile = SEGPTR_GET(SEGPTR_ALLOC(ofn->nMaxFile));
1182 ofn16->nMaxFile = ofn->nMaxFile;
1183 ofn16->nMaxFileTitle = ofn->nMaxFileTitle;
1184 if (ofn16->nMaxFileTitle)
1185 ofn16->lpstrFileTitle = SEGPTR_GET(SEGPTR_ALLOC(ofn->nMaxFileTitle));
1186 if (ofn->lpstrInitialDir)
1187 ofn16->lpstrInitialDir = SEGPTR_GET(SEGPTR_STRDUP(ofn->lpstrInitialDir));
1188 if (ofn->lpstrTitle)
1189 ofn16->lpstrTitle = SEGPTR_GET(SEGPTR_STRDUP(ofn->lpstrTitle));
1190 ofn16->Flags = ofn->Flags|OFN_WINE;
1191 ofn16->nFileOffset = ofn->nFileOffset;
1192 ofn16->nFileExtension = ofn->nFileExtension;
1193 if (ofn->lpstrDefExt)
1194 ofn16->lpstrDefExt = SEGPTR_GET(SEGPTR_STRDUP(ofn->lpstrDefExt));
1195 ofn16->lCustData = ofn->lCustData;
1196 ofn16->lpfnHook = (LPOFNHOOKPROC16)ofn->lpfnHook;
1198 if (ofn->lpTemplateName)
1199 ofn16->lpTemplateName = SEGPTR_GET(SEGPTR_STRDUP(ofn->lpTemplateName));
1201 ret = dofunction(SEGPTR_GET(ofn16));
1203 ofn->nFileOffset = ofn16->nFileOffset;
1204 ofn->nFileExtension = ofn16->nFileExtension;
1205 if (ofn16->lpstrFilter)
1206 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFilter));
1207 if (ofn16->lpTemplateName)
1208 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpTemplateName));
1209 if (ofn16->lpstrDefExt)
1210 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrDefExt));
1211 if (ofn16->lpstrTitle)
1212 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrTitle));
1213 if (ofn16->lpstrInitialDir)
1214 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrInitialDir));
1215 if (ofn16->lpstrCustomFilter)
1216 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrCustomFilter));
1218 if (ofn16->lpstrFile)
1220 LPCSTR src = PTR_SEG_TO_LIN(ofn16->lpstrFile);
1221 LPSTR dst = ofn->lpstrFile;
1223 if ((ofn->Flags & OFN_ALLOWMULTISELECT) && (ofn->Flags & OFN_EXPLORER)) {
1224 /* FIXME(EPP): I tried to use:
1225 * memcpy(ofn->lpstrFile, PTR_SEG_TO_LIN(ofn16->lpstrFile, ofn->nMaxFile)
1226 * but it did crash with winamp 2.21, so copy string by string
1228 int len;
1229 do {
1230 strcpy(dst, src);
1231 len = strlen(dst) + 1; /* strlen(dst) == strlen(src) */
1232 dst += len;
1233 src += len;
1234 } while (len > 1);
1235 } else {
1236 strcpy(dst, src);
1238 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFile));
1241 if (ofn16->lpstrFileTitle)
1243 if (ofn->lpstrFileTitle)
1244 strcpy(ofn->lpstrFileTitle,
1245 PTR_SEG_TO_LIN(ofn16->lpstrFileTitle));
1246 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFileTitle));
1248 SEGPTR_FREE(ofn16);
1249 return ret;
1252 static BOOL Commdlg_GetFileNameW( BOOL16 (CALLBACK *dofunction)(SEGPTR x),
1253 LPOPENFILENAMEW ofn )
1255 BOOL16 ret;
1256 LPOPENFILENAME16 ofn16 = SEGPTR_ALLOC(sizeof(OPENFILENAME16));
1258 memset(ofn16,'\0',sizeof(*ofn16));
1259 ofn16->lStructSize = sizeof(*ofn16);
1260 ofn16->hwndOwner = ofn->hwndOwner;
1261 ofn16->hInstance = MapHModuleLS(ofn->hInstance);
1262 if (ofn->lpstrFilter) {
1263 LPWSTR s;
1264 LPSTR x,y;
1265 int n;
1267 /* filter is a list... title\0ext\0......\0\0 */
1268 s = (LPWSTR)ofn->lpstrFilter;
1269 while (*s)
1270 s = s+lstrlenW(s)+1;
1271 s++;
1272 n = s - ofn->lpstrFilter; /* already divides by 2. ptr magic */
1273 x = y = (LPSTR)SEGPTR_ALLOC(n);
1274 s = (LPWSTR)ofn->lpstrFilter;
1275 while (*s) {
1276 lstrcpyWtoA(x,s);
1277 x+=lstrlenA(x)+1;
1278 s+=lstrlenW(s)+1;
1280 *x=0;
1281 ofn16->lpstrFilter = SEGPTR_GET(y);
1283 if (ofn->lpstrCustomFilter) {
1284 LPWSTR s;
1285 LPSTR x,y;
1286 int n;
1288 /* filter is a list... title\0ext\0......\0\0 */
1289 s = (LPWSTR)ofn->lpstrCustomFilter;
1290 while (*s)
1291 s = s+lstrlenW(s)+1;
1292 s++;
1293 n = s - ofn->lpstrCustomFilter;
1294 x = y = (LPSTR)SEGPTR_ALLOC(n);
1295 s = (LPWSTR)ofn->lpstrCustomFilter;
1296 while (*s) {
1297 lstrcpyWtoA(x,s);
1298 x+=lstrlenA(x)+1;
1299 s+=lstrlenW(s)+1;
1301 *x=0;
1302 ofn16->lpstrCustomFilter = SEGPTR_GET(y);
1304 ofn16->nMaxCustFilter = ofn->nMaxCustFilter;
1305 ofn16->nFilterIndex = ofn->nFilterIndex;
1306 if (ofn->nMaxFile)
1307 ofn16->lpstrFile = SEGPTR_GET(SEGPTR_ALLOC(ofn->nMaxFile));
1308 ofn16->nMaxFile = ofn->nMaxFile;
1309 ofn16->nMaxFileTitle = ofn->nMaxFileTitle;
1310 if (ofn->nMaxFileTitle)
1311 ofn16->lpstrFileTitle = SEGPTR_GET(SEGPTR_ALLOC(ofn->nMaxFileTitle));
1312 if (ofn->lpstrInitialDir)
1313 ofn16->lpstrInitialDir = SEGPTR_GET(SEGPTR_STRDUP_WtoA(ofn->lpstrInitialDir));
1314 if (ofn->lpstrTitle)
1315 ofn16->lpstrTitle = SEGPTR_GET(SEGPTR_STRDUP_WtoA(ofn->lpstrTitle));
1316 ofn16->Flags = ofn->Flags|OFN_WINE|OFN_UNICODE;
1317 ofn16->nFileOffset = ofn->nFileOffset;
1318 ofn16->nFileExtension = ofn->nFileExtension;
1319 if (ofn->lpstrDefExt)
1320 ofn16->lpstrDefExt = SEGPTR_GET(SEGPTR_STRDUP_WtoA(ofn->lpstrDefExt));
1321 ofn16->lCustData = ofn->lCustData;
1322 ofn16->lpfnHook = (LPOFNHOOKPROC16)ofn->lpfnHook;
1323 if (ofn->lpTemplateName)
1324 ofn16->lpTemplateName = SEGPTR_GET(SEGPTR_STRDUP_WtoA(ofn->lpTemplateName));
1325 ret = dofunction(SEGPTR_GET(ofn16));
1327 ofn->nFileOffset = ofn16->nFileOffset;
1328 ofn->nFileExtension = ofn16->nFileExtension;
1329 if (ofn16->lpstrFilter)
1330 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFilter));
1331 if (ofn16->lpTemplateName)
1332 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpTemplateName));
1333 if (ofn16->lpstrDefExt)
1334 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrDefExt));
1335 if (ofn16->lpstrTitle)
1336 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrTitle));
1337 if (ofn16->lpstrInitialDir)
1338 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrInitialDir));
1339 if (ofn16->lpstrCustomFilter)
1340 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrCustomFilter));
1342 if (ofn16->lpstrFile)
1344 LPCSTR src = PTR_SEG_TO_LIN(ofn16->lpstrFile);
1345 LPWSTR dst = ofn->lpstrFile;
1347 if ((ofn->Flags & OFN_ALLOWMULTISELECT) && (ofn->Flags & OFN_EXPLORER)) {
1348 int len;
1349 do {
1350 lstrcpyAtoW(dst, src);
1351 dst += lstrlenW(dst) + 1;
1352 src += (len = strlen(src) + 1);
1353 } while (len > 1);
1354 } else {
1355 lstrcpyAtoW(ofn->lpstrFile,PTR_SEG_TO_LIN(ofn16->lpstrFile));
1357 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFile));
1360 if (ofn16->lpstrFileTitle) {
1361 if (ofn->lpstrFileTitle)
1362 lstrcpyAtoW(ofn->lpstrFileTitle,
1363 PTR_SEG_TO_LIN(ofn16->lpstrFileTitle));
1364 SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFileTitle));
1366 SEGPTR_FREE(ofn16);
1367 return ret;
1369 /***********************************************************************
1370 * GetOpenFileNameA (COMDLG32.10)
1372 * Creates a dialog box for the user to select a file to open.
1374 * RETURNS
1375 * TRUE on succes: user enters a valid file
1376 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1379 BOOL WINAPI GetOpenFileNameA(
1380 LPOPENFILENAMEA ofn) /* address of init structure */
1382 BOOL newlook;
1384 /* some flags don't allow to match the TWEAK_WineLook */
1385 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
1387 newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
1389 else
1391 /* no special flags set, we can match the TWEAK_WineLook */
1392 newlook = (TWEAK_WineLook>WIN31_LOOK) ? TRUE : FALSE;
1395 if (newlook)
1397 return GetFileDialog95A(ofn, OPEN_DIALOG);
1399 else
1401 BOOL16 (CALLBACK * dofunction)(SEGPTR ofn16) = GetOpenFileName16;
1402 return Commdlg_GetFileNameA(dofunction,ofn);
1406 /***********************************************************************
1407 * GetOpenFileNameW (COMDLG32.11)
1409 * Creates a dialog box for the user to select a file to open.
1411 * RETURNS
1412 * TRUE on succes: user enters a valid file
1413 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1416 BOOL WINAPI GetOpenFileNameW(
1417 LPOPENFILENAMEW ofn) /* address of init structure */
1419 BOOL newlook;
1421 /* some flags don't allow to match the TWEAK_WineLook */
1422 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
1424 newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
1426 else
1428 /* no special flags set, we can match the TWEAK_WineLook */
1429 newlook = (TWEAK_WineLook>WIN31_LOOK) ? TRUE : FALSE;
1432 if (newlook)
1434 return GetFileDialog95W(ofn, OPEN_DIALOG);
1436 else
1438 BOOL16 (CALLBACK * dofunction)(SEGPTR ofn16) = GetOpenFileName16;
1439 return Commdlg_GetFileNameW(dofunction,ofn);
1443 /***********************************************************************
1444 * GetSaveFileNameA (COMDLG32.12)
1446 * Creates a dialog box for the user to select a file to save.
1448 * RETURNS
1449 * TRUE on succes: user enters a valid file
1450 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1453 BOOL WINAPI GetSaveFileNameA(
1454 LPOPENFILENAMEA ofn) /* address of init structure */
1456 BOOL newlook;
1458 /* some flags don't allow to match the TWEAK_WineLook */
1459 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
1461 newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
1463 else
1465 /* no special flags set, we can match the TWEAK_WineLook */
1466 newlook = (TWEAK_WineLook>WIN31_LOOK) ? TRUE : FALSE;
1469 if (newlook)
1471 return GetFileDialog95A(ofn, SAVE_DIALOG);
1473 else
1475 BOOL16 (CALLBACK * dofunction)(SEGPTR ofn16) = GetSaveFileName16;
1476 return Commdlg_GetFileNameA(dofunction,ofn);
1480 /***********************************************************************
1481 * GetSaveFileNameW (COMDLG32.13)
1483 * Creates a dialog box for the user to select a file to save.
1485 * RETURNS
1486 * TRUE on succes: user enters a valid file
1487 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
1490 BOOL WINAPI GetSaveFileNameW(
1491 LPOPENFILENAMEW ofn) /* address of init structure */
1493 BOOL newlook;
1495 /* some flags don't allow to match the TWEAK_WineLook */
1496 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
1498 newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
1500 else
1502 /* no special flags set, we can match the TWEAK_WineLook */
1503 newlook = (TWEAK_WineLook>WIN31_LOOK) ? TRUE : FALSE;
1506 if (newlook)
1508 return GetFileDialog95W(ofn, SAVE_DIALOG);
1510 else
1512 BOOL16 (CALLBACK * dofunction)(SEGPTR ofn16) = GetSaveFileName16;
1513 return Commdlg_GetFileNameW(dofunction,ofn);