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));