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
30 #include "wine/winbase16.h"
31 #include "wine/winuser16.h"
32 #include "wine/unicode.h"
35 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(commdlg
);
45 /***********************************************************************
46 * FILEDLG_CallWindowProc16 [internal]
48 * Call the appropriate hook
50 static BOOL
FILEDLG_CallWindowProc16(LFSPRIVATE lfs
, UINT wMsg
, WPARAM wParam
,
55 return (BOOL16
) CallWindowProc16(
56 (WNDPROC16
)lfs
->ofn16
->lpfnHook
, HWND_16(lfs
->hwnd
),
57 (UINT16
)wMsg
, (WPARAM16
)wParam
, lParam
);
62 /***********************************************************************
63 * FILEDLG_WMInitDialog16 [internal]
64 * The is a duplicate of the 32bit FILEDLG_WMInitDialog function
65 * The only differnce is that it calls FILEDLG_CallWindowProc16
66 * for a 16 bit Window Proc.
69 static LONG
FILEDLG_WMInitDialog16(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
72 WCHAR tmpstr
[BUFFILE
];
73 LPWSTR pstr
, old_pstr
;
75 LFSPRIVATE lfs
= (LFSPRIVATE
) lParam
;
77 if (!lfs
) return FALSE
;
78 SetPropA(hWnd
, OFN_PROP
, (HANDLE
)lfs
);
82 TRACE("flags=%lx initialdir=%s\n", ofn
->Flags
, debugstr_w(ofn
->lpstrInitialDir
));
84 SetWindowTextW( hWnd
, ofn
->lpstrTitle
);
85 /* read custom filter information */
86 if (ofn
->lpstrCustomFilter
)
88 pstr
= ofn
->lpstrCustomFilter
;
90 TRACE("lpstrCustomFilter = %p\n", pstr
);
94 i
= SendDlgItemMessageW(hWnd
, cmb1
, CB_ADDSTRING
, 0,
95 (LPARAM
)(ofn
->lpstrCustomFilter
) + n
);
96 n
+= lstrlenW(pstr
) + 1;
97 pstr
+= lstrlenW(pstr
) + 1;
98 TRACE("add str=%s associated to %s\n",
99 debugstr_w(old_pstr
), debugstr_w(pstr
));
100 SendDlgItemMessageW(hWnd
, cmb1
, CB_SETITEMDATA
, i
, (LPARAM
)pstr
);
101 n
+= lstrlenW(pstr
) + 1;
102 pstr
+= lstrlenW(pstr
) + 1;
105 /* read filter information */
106 if (ofn
->lpstrFilter
) {
107 pstr
= (LPWSTR
) ofn
->lpstrFilter
;
111 i
= SendDlgItemMessageW(hWnd
, cmb1
, CB_ADDSTRING
, 0,
112 (LPARAM
)(ofn
->lpstrFilter
+ n
) );
113 n
+= lstrlenW(pstr
) + 1;
114 pstr
+= lstrlenW(pstr
) + 1;
115 TRACE("add str=%s associated to %s\n",
116 debugstr_w(old_pstr
), debugstr_w(pstr
));
117 SendDlgItemMessageW(hWnd
, cmb1
, CB_SETITEMDATA
, i
, (LPARAM
)pstr
);
118 n
+= lstrlenW(pstr
) + 1;
119 pstr
+= lstrlenW(pstr
) + 1;
122 /* set default filter */
123 if (ofn
->nFilterIndex
== 0 && ofn
->lpstrCustomFilter
== NULL
)
124 ofn
->nFilterIndex
= 1;
125 SendDlgItemMessageW(hWnd
, cmb1
, CB_SETCURSEL
, ofn
->nFilterIndex
- 1, 0);
126 lstrcpynW(tmpstr
, FILEDLG_GetFileType(ofn
->lpstrCustomFilter
,
127 (LPWSTR
)ofn
->lpstrFilter
, ofn
->nFilterIndex
- 1),BUFFILE
);
128 TRACE("nFilterIndex = %ld, SetText of edt1 to %s\n",
129 ofn
->nFilterIndex
, debugstr_w(tmpstr
));
130 SetDlgItemTextW( hWnd
, edt1
, tmpstr
);
133 DlgDirListComboBoxW(hWnd
, tmpstr
, cmb2
, 0, DDL_DRIVES
| DDL_EXCLUSIVE
);
134 /* read initial directory */
135 /* FIXME: Note that this is now very version-specific (See MSDN description of
136 * the OPENFILENAME structure). For example under 2000/XP any path in the
137 * lpstrFile overrides the lpstrInitialDir, but not under 95/98/ME
139 if (ofn
->lpstrInitialDir
!= NULL
)
142 lstrcpynW(tmpstr
, ofn
->lpstrInitialDir
, 511);
143 len
= lstrlenW(tmpstr
);
144 if (len
> 0 && tmpstr
[len
-1] != '\\' && tmpstr
[len
-1] != ':') {
151 if (!FILEDLG_ScanDir(hWnd
, tmpstr
)) {
153 if (!FILEDLG_ScanDir(hWnd
, tmpstr
))
154 WARN("Couldn't read initial directory %s!\n", debugstr_w(tmpstr
));
156 /* select current drive in combo 2, omit missing drives */
159 char str
[4] = "a:\\";
160 GetCurrentDirectoryA( sizeof(dir
), dir
);
161 for(i
= 0, n
= -1; i
< 26; i
++)
164 if (GetDriveTypeA(str
) > DRIVE_NO_ROOT_DIR
) n
++;
165 if (toupper(str
[0]) == toupper(dir
[0])) break;
168 SendDlgItemMessageW(hWnd
, cmb2
, CB_SETCURSEL
, n
, 0);
169 if (!(ofn
->Flags
& OFN_SHOWHELP
))
170 ShowWindow(GetDlgItem(hWnd
, pshHelp
), SW_HIDE
);
171 if (ofn
->Flags
& OFN_HIDEREADONLY
)
172 ShowWindow(GetDlgItem(hWnd
, chx1
), SW_HIDE
);
174 return (BOOL
) FILEDLG_CallWindowProc16(lfs
, WM_INITDIALOG
, wParam
, lfs
->lParam
);
178 /***********************************************************************
179 * FILEDLG_WMMeasureItem16 [internal]
181 static LONG
FILEDLG_WMMeasureItem16(HWND16 hWnd
, WPARAM16 wParam
, LPARAM lParam
)
183 LPMEASUREITEMSTRUCT16 lpmeasure
;
185 lpmeasure
= MapSL(lParam
);
186 lpmeasure
->itemHeight
= fldrHeight
;
190 /* ------------------ Dialog procedures ---------------------- */
192 /***********************************************************************
193 * FileOpenDlgProc (COMMDLG.6)
195 BOOL16 CALLBACK
FileOpenDlgProc16(HWND16 hWnd16
, UINT16 wMsg
, WPARAM16 wParam
,
198 HWND hWnd
= HWND_32(hWnd16
);
199 LFSPRIVATE lfs
= (LFSPRIVATE
)GetPropA(hWnd
,OFN_PROP
);
202 TRACE("msg=%x wparam=%x lParam=%lx\n", wMsg
, wParam
, lParam
);
203 if ((wMsg
!= WM_INITDIALOG
) && lfs
&& lfs
->hook
)
205 LRESULT lRet
= (BOOL16
)FILEDLG_CallWindowProc16(lfs
, wMsg
, wParam
, lParam
);
207 return lRet
; /* else continue message processing */
212 return FILEDLG_WMInitDialog16(hWnd
, wParam
, lParam
);
215 return FILEDLG_WMMeasureItem16(hWnd16
, wParam
, lParam
);
218 FILEDLG_MapDrawItemStruct(MapSL(lParam
), &dis
);
219 return FILEDLG_WMDrawItem(hWnd
, wParam
, lParam
, FALSE
, &dis
);
222 return FILEDLG_WMCommand(hWnd
, lParam
, HIWORD(lParam
),wParam
, lfs
);
225 SetBkColor((HDC16
)wParam
, 0x00C0C0C0);
226 switch (HIWORD(lParam
))
229 SetTextColor((HDC16
)wParam
, 0x00000000);
231 case CTLCOLOR_STATIC
:
232 SetTextColor((HDC16
)wParam
, 0x00000000);
241 /***********************************************************************
242 * FileSaveDlgProc (COMMDLG.7)
244 BOOL16 CALLBACK
FileSaveDlgProc16(HWND16 hWnd16
, UINT16 wMsg
, WPARAM16 wParam
,
247 HWND hWnd
= HWND_32(hWnd16
);
248 LFSPRIVATE lfs
= (LFSPRIVATE
)GetPropA(hWnd
,OFN_PROP
);
251 TRACE("msg=%x wparam=%x lParam=%lx\n", wMsg
, wParam
, lParam
);
252 if ((wMsg
!= WM_INITDIALOG
) && lfs
&& lfs
->hook
)
255 lRet
= (BOOL16
)FILEDLG_CallWindowProc16(lfs
, wMsg
, wParam
, lParam
);
257 return lRet
; /* else continue message processing */
261 return FILEDLG_WMInitDialog16(hWnd
, wParam
, lParam
);
264 return FILEDLG_WMMeasureItem16(hWnd16
, wParam
, lParam
);
267 FILEDLG_MapDrawItemStruct(MapSL(lParam
), &dis
);
268 return FILEDLG_WMDrawItem(hWnd
, wParam
, lParam
, TRUE
, &dis
);
271 return FILEDLG_WMCommand(hWnd
, lParam
, HIWORD(lParam
), wParam
, lfs
);
276 SetBkColor((HDC16)wParam, 0x00C0C0C0);
277 switch (HIWORD(lParam))
280 SetTextColor((HDC16)wParam, 0x00000000);
282 case CTLCOLOR_STATIC:
283 SetTextColor((HDC16)wParam, 0x00000000);
292 /* ------------------ APIs ---------------------- */
294 /***********************************************************************
295 * GetOpenFileName (COMMDLG.1)
297 * Creates a dialog box for the user to select a file to open.
300 * TRUE on success: user selected a valid file
301 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
304 * unknown, there are some FIXME's left.
306 BOOL16 WINAPI
GetOpenFileName16(
307 SEGPTR ofn
/* [in/out] address of structure with data*/
312 LPOPENFILENAME16 lpofn
= MapSL(ofn
);
316 if (!lpofn
|| !FileDlg_Init()) return FALSE
;
318 lfs
= FILEDLG_AllocPrivate((LPARAM
) ofn
, LFS16
, OPEN_DIALOG
);
321 hInst
= GetWindowWord( HWND_32(lpofn
->hwndOwner
), GWL_HINSTANCE
);
322 ptr
= GetProcAddress16(GetModuleHandle16("COMMDLG"), (LPCSTR
) 6);
323 bRet
= DialogBoxIndirectParam16( hInst
, lfs
->hDlgTmpl16
, lpofn
->hwndOwner
,
324 (DLGPROC16
) ptr
, (LPARAM
) lfs
);
325 FILEDLG_DestroyPrivate(lfs
);
328 TRACE("return lpstrFile='%s' !\n", (char *)MapSL(lpofn
->lpstrFile
));
332 /***********************************************************************
333 * GetSaveFileName (COMMDLG.2)
335 * Creates a dialog box for the user to select a file to save.
338 * TRUE on success: user enters a valid file
339 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
342 * unknown. There are some FIXME's left.
344 BOOL16 WINAPI
GetSaveFileName16(
345 SEGPTR ofn
/* [in/out] addess of structure with data*/
350 LPOPENFILENAME16 lpofn
= MapSL(ofn
);
354 if (!lpofn
|| !FileDlg_Init()) return FALSE
;
356 lfs
= FILEDLG_AllocPrivate((LPARAM
) ofn
, LFS16
, SAVE_DIALOG
);
359 hInst
= GetWindowWord( HWND_32(lpofn
->hwndOwner
), GWL_HINSTANCE
);
360 ptr
= GetProcAddress16(GetModuleHandle16("COMMDLG"), (LPCSTR
) 7);
361 bRet
= DialogBoxIndirectParam16( hInst
, lfs
->hDlgTmpl16
, lpofn
->hwndOwner
,
362 (DLGPROC16
) ptr
, (LPARAM
) lfs
);
363 FILEDLG_DestroyPrivate(lfs
);
366 TRACE("return lpstrFile='%s' !\n", (char *)MapSL(lpofn
->lpstrFile
));