2 * COMMDLG - File Dialogs
4 * Copyright 1994 Martin Ayotte
5 * Copyright 1996 Albrecht Kleine
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #include "wine/winbase16.h"
30 #include "wine/winuser16.h"
31 #include "wine/unicode.h"
33 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(commdlg
);
42 /***********************************************************************
43 * FILEDLG_CallWindowProc16 [internal]
45 * Call the appropriate hook
47 static BOOL
FILEDLG_CallWindowProc16(LFSPRIVATE lfs
, UINT wMsg
, WPARAM wParam
,
52 return (BOOL16
) CallWindowProc16(
53 (WNDPROC16
)lfs
->ofn16
->lpfnHook
, HWND_16(lfs
->hwnd
),
54 (UINT16
)wMsg
, (WPARAM16
)wParam
, lParam
);
59 /***********************************************************************
60 * FILEDLG_WMInitDialog16 [internal]
61 * The is a duplicate of the 32bit FILEDLG_WMInitDialog function
62 * The only differnce is that it calls FILEDLG_CallWindowProc16
63 * for a 16 bit Window Proc.
66 static LONG
FILEDLG_WMInitDialog16(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
69 WCHAR tmpstr
[BUFFILE
];
70 LPWSTR pstr
, old_pstr
;
72 LFSPRIVATE lfs
= (LFSPRIVATE
) lParam
;
74 if (!lfs
) return FALSE
;
75 SetPropA(hWnd
, OFN_PROP
, (HANDLE
)lfs
);
79 TRACE("flags=%lx initialdir=%s\n", ofn
->Flags
, debugstr_w(ofn
->lpstrInitialDir
));
81 SetWindowTextW( hWnd
, ofn
->lpstrTitle
);
82 /* read custom filter information */
83 if (ofn
->lpstrCustomFilter
)
85 pstr
= ofn
->lpstrCustomFilter
;
87 TRACE("lpstrCustomFilter = %p\n", pstr
);
91 i
= SendDlgItemMessageW(hWnd
, cmb1
, CB_ADDSTRING
, 0,
92 (LPARAM
)(ofn
->lpstrCustomFilter
) + n
);
93 n
+= lstrlenW(pstr
) + 1;
94 pstr
+= lstrlenW(pstr
) + 1;
95 TRACE("add str=%s associated to %s\n",
96 debugstr_w(old_pstr
), debugstr_w(pstr
));
97 SendDlgItemMessageW(hWnd
, cmb1
, CB_SETITEMDATA
, i
, (LPARAM
)pstr
);
98 n
+= lstrlenW(pstr
) + 1;
99 pstr
+= lstrlenW(pstr
) + 1;
102 /* read filter information */
103 if (ofn
->lpstrFilter
) {
104 pstr
= (LPWSTR
) ofn
->lpstrFilter
;
108 i
= SendDlgItemMessageW(hWnd
, cmb1
, CB_ADDSTRING
, 0,
109 (LPARAM
)(ofn
->lpstrFilter
+ n
) );
110 n
+= lstrlenW(pstr
) + 1;
111 pstr
+= lstrlenW(pstr
) + 1;
112 TRACE("add str=%s associated to %s\n",
113 debugstr_w(old_pstr
), debugstr_w(pstr
));
114 SendDlgItemMessageW(hWnd
, cmb1
, CB_SETITEMDATA
, i
, (LPARAM
)pstr
);
115 n
+= lstrlenW(pstr
) + 1;
116 pstr
+= lstrlenW(pstr
) + 1;
119 /* set default filter */
120 if (ofn
->nFilterIndex
== 0 && ofn
->lpstrCustomFilter
== NULL
)
121 ofn
->nFilterIndex
= 1;
122 SendDlgItemMessageW(hWnd
, cmb1
, CB_SETCURSEL
, ofn
->nFilterIndex
- 1, 0);
123 lstrcpynW(tmpstr
, FILEDLG_GetFileType(ofn
->lpstrCustomFilter
,
124 (LPWSTR
)ofn
->lpstrFilter
, ofn
->nFilterIndex
- 1),BUFFILE
);
125 TRACE("nFilterIndex = %ld, SetText of edt1 to %s\n",
126 ofn
->nFilterIndex
, debugstr_w(tmpstr
));
127 SetDlgItemTextW( hWnd
, edt1
, tmpstr
);
130 DlgDirListComboBoxW(hWnd
, tmpstr
, cmb2
, 0, DDL_DRIVES
| DDL_EXCLUSIVE
);
131 /* read initial directory */
132 /* FIXME: Note that this is now very version-specific (See MSDN description of
133 * the OPENFILENAME structure). For example under 2000/XP any path in the
134 * lpstrFile overrides the lpstrInitialDir, but not under 95/98/ME
136 if (ofn
->lpstrInitialDir
!= NULL
)
139 lstrcpynW(tmpstr
, ofn
->lpstrInitialDir
, 511);
140 len
= lstrlenW(tmpstr
);
141 if (len
> 0 && tmpstr
[len
-1] != '\\' && tmpstr
[len
-1] != ':') {
148 if (!FILEDLG_ScanDir(hWnd
, tmpstr
)) {
150 if (!FILEDLG_ScanDir(hWnd
, tmpstr
))
151 WARN("Couldn't read initial directory %s!\n", debugstr_w(tmpstr
));
153 /* select current drive in combo 2, omit missing drives */
156 char str
[4] = "a:\\";
157 GetCurrentDirectoryA( sizeof(dir
), dir
);
158 for(i
= 0, n
= -1; i
< 26; i
++)
161 if (GetDriveTypeA(str
) > DRIVE_NO_ROOT_DIR
) n
++;
162 if (toupper(str
[0]) == toupper(dir
[0])) break;
165 SendDlgItemMessageW(hWnd
, cmb2
, CB_SETCURSEL
, n
, 0);
166 if (!(ofn
->Flags
& OFN_SHOWHELP
))
167 ShowWindow(GetDlgItem(hWnd
, pshHelp
), SW_HIDE
);
168 if (ofn
->Flags
& OFN_HIDEREADONLY
)
169 ShowWindow(GetDlgItem(hWnd
, chx1
), SW_HIDE
);
171 return (BOOL
) FILEDLG_CallWindowProc16(lfs
, WM_INITDIALOG
, wParam
, lfs
->lParam
);
175 /***********************************************************************
176 * FILEDLG_WMMeasureItem16 [internal]
178 static LONG
FILEDLG_WMMeasureItem16(HWND16 hWnd
, WPARAM16 wParam
, LPARAM lParam
)
180 LPMEASUREITEMSTRUCT16 lpmeasure
;
182 lpmeasure
= MapSL(lParam
);
183 lpmeasure
->itemHeight
= fldrHeight
;
187 /* ------------------ Dialog procedures ---------------------- */
189 /***********************************************************************
190 * FileOpenDlgProc (COMMDLG.6)
192 BOOL16 CALLBACK
FileOpenDlgProc16(HWND16 hWnd16
, UINT16 wMsg
, WPARAM16 wParam
,
195 HWND hWnd
= HWND_32(hWnd16
);
196 LFSPRIVATE lfs
= (LFSPRIVATE
)GetPropA(hWnd
,OFN_PROP
);
199 TRACE("msg=%x wparam=%x lParam=%lx\n", wMsg
, wParam
, lParam
);
200 if ((wMsg
!= WM_INITDIALOG
) && lfs
&& lfs
->hook
)
202 LRESULT lRet
= (BOOL16
)FILEDLG_CallWindowProc16(lfs
, wMsg
, wParam
, lParam
);
204 return lRet
; /* else continue message processing */
209 return FILEDLG_WMInitDialog16(hWnd
, wParam
, lParam
);
212 return FILEDLG_WMMeasureItem16(hWnd16
, wParam
, lParam
);
215 FILEDLG_MapDrawItemStruct(MapSL(lParam
), &dis
);
216 return FILEDLG_WMDrawItem(hWnd
, wParam
, lParam
, FALSE
, &dis
);
219 return FILEDLG_WMCommand(hWnd
, lParam
, HIWORD(lParam
),wParam
, lfs
);
222 SetBkColor((HDC16
)wParam
, 0x00C0C0C0);
223 switch (HIWORD(lParam
))
226 SetTextColor((HDC16
)wParam
, 0x00000000);
228 case CTLCOLOR_STATIC
:
229 SetTextColor((HDC16
)wParam
, 0x00000000);
238 /***********************************************************************
239 * FileSaveDlgProc (COMMDLG.7)
241 BOOL16 CALLBACK
FileSaveDlgProc16(HWND16 hWnd16
, UINT16 wMsg
, WPARAM16 wParam
,
244 HWND hWnd
= HWND_32(hWnd16
);
245 LFSPRIVATE lfs
= (LFSPRIVATE
)GetPropA(hWnd
,OFN_PROP
);
248 TRACE("msg=%x wparam=%x lParam=%lx\n", wMsg
, wParam
, lParam
);
249 if ((wMsg
!= WM_INITDIALOG
) && lfs
&& lfs
->hook
)
252 lRet
= (BOOL16
)FILEDLG_CallWindowProc16(lfs
, wMsg
, wParam
, lParam
);
254 return lRet
; /* else continue message processing */
258 return FILEDLG_WMInitDialog16(hWnd
, wParam
, lParam
);
261 return FILEDLG_WMMeasureItem16(hWnd16
, wParam
, lParam
);
264 FILEDLG_MapDrawItemStruct(MapSL(lParam
), &dis
);
265 return FILEDLG_WMDrawItem(hWnd
, wParam
, lParam
, TRUE
, &dis
);
268 return FILEDLG_WMCommand(hWnd
, lParam
, HIWORD(lParam
), wParam
, lfs
);
273 SetBkColor((HDC16)wParam, 0x00C0C0C0);
274 switch (HIWORD(lParam))
277 SetTextColor((HDC16)wParam, 0x00000000);
279 case CTLCOLOR_STATIC:
280 SetTextColor((HDC16)wParam, 0x00000000);
289 /* ------------------ APIs ---------------------- */
291 /***********************************************************************
292 * GetOpenFileName (COMMDLG.1)
294 * Creates a dialog box for the user to select a file to open.
297 * TRUE on success: user selected a valid file
298 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
301 * unknown, there are some FIXME's left.
303 BOOL16 WINAPI
GetOpenFileName16(
304 SEGPTR ofn
/* [in/out] address of structure with data*/
309 LPOPENFILENAME16 lpofn
= MapSL(ofn
);
313 if (!lpofn
|| !FileDlg_Init()) return FALSE
;
315 lfs
= FILEDLG_AllocPrivate((LPARAM
) ofn
, LFS16
, OPEN_DIALOG
);
318 hInst
= GetWindowWord( HWND_32(lpofn
->hwndOwner
), GWL_HINSTANCE
);
319 ptr
= GetProcAddress16(GetModuleHandle16("COMMDLG"), (LPCSTR
) 6);
320 bRet
= DialogBoxIndirectParam16( hInst
, lfs
->hDlgTmpl16
, lpofn
->hwndOwner
,
321 (DLGPROC16
) ptr
, (LPARAM
) lfs
);
322 FILEDLG_DestroyPrivate(lfs
);
325 TRACE("return lpstrFile='%s' !\n", (char *)MapSL(lpofn
->lpstrFile
));
329 /***********************************************************************
330 * GetSaveFileName (COMMDLG.2)
332 * Creates a dialog box for the user to select a file to save.
335 * TRUE on success: user enters a valid file
336 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
339 * unknown. There are some FIXME's left.
341 BOOL16 WINAPI
GetSaveFileName16(
342 SEGPTR ofn
/* [in/out] addess of structure with data*/
347 LPOPENFILENAME16 lpofn
= MapSL(ofn
);
351 if (!lpofn
|| !FileDlg_Init()) return FALSE
;
353 lfs
= FILEDLG_AllocPrivate((LPARAM
) ofn
, LFS16
, SAVE_DIALOG
);
356 hInst
= GetWindowWord( HWND_32(lpofn
->hwndOwner
), GWL_HINSTANCE
);
357 ptr
= GetProcAddress16(GetModuleHandle16("COMMDLG"), (LPCSTR
) 7);
358 bRet
= DialogBoxIndirectParam16( hInst
, lfs
->hDlgTmpl16
, lpofn
->hwndOwner
,
359 (DLGPROC16
) ptr
, (LPARAM
) lfs
);
360 FILEDLG_DestroyPrivate(lfs
);
363 TRACE("return lpstrFile='%s' !\n", (char *)MapSL(lpofn
->lpstrFile
));