Get rid of the memory allocation macros, use real functions instead.
[wine/wine64.git] / dlls / commdlg / filedlg16.c
blob4f798b065581058e04d900cb17e67062c48153d0
1 /*
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
21 #include <ctype.h>
22 #include <stdlib.h>
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "winnls.h"
30 #include "wine/winbase16.h"
31 #include "wine/winuser16.h"
32 #include "wine/unicode.h"
33 #include "winuser.h"
34 #include "commdlg.h"
35 #include "wine/debug.h"
36 #include "cderr.h"
37 #include "winreg.h"
38 #include "winternl.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
42 #include "cdlg.h"
43 #include "filedlg.h"
45 /***********************************************************************
46 * FILEDLG_CallWindowProc16 [internal]
48 * Call the appropriate hook
50 static BOOL FILEDLG_CallWindowProc16(LFSPRIVATE lfs, UINT wMsg, WPARAM wParam,
51 LPARAM lParam)
53 if (lfs->ofn16)
55 return (BOOL16) CallWindowProc16(
56 (WNDPROC16)lfs->ofn16->lpfnHook, HWND_16(lfs->hwnd),
57 (UINT16)wMsg, (WPARAM16)wParam, lParam);
59 return FALSE;
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)
71 int i, n;
72 WCHAR tmpstr[BUFFILE];
73 LPWSTR pstr, old_pstr;
74 LPOPENFILENAMEW ofn;
75 LFSPRIVATE lfs = (LFSPRIVATE) lParam;
77 if (!lfs) return FALSE;
78 SetPropA(hWnd, OFN_PROP, (HANDLE)lfs);
79 lfs->hwnd = hWnd;
80 ofn = lfs->ofnW;
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;
89 n = 0;
90 TRACE("lpstrCustomFilter = %p\n", pstr);
91 while(*pstr)
93 old_pstr = 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;
108 n = 0;
109 while(*pstr) {
110 old_pstr = pstr;
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 );
131 /* get drive list */
132 *tmpstr = 0;
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)
141 int len;
142 lstrcpynW(tmpstr, ofn->lpstrInitialDir, 511);
143 len = lstrlenW(tmpstr);
144 if (len > 0 && tmpstr[len-1] != '\\' && tmpstr[len-1] != ':') {
145 tmpstr[len]='\\';
146 tmpstr[len+1]='\0';
149 else
150 *tmpstr = 0;
151 if (!FILEDLG_ScanDir(hWnd, tmpstr)) {
152 *tmpstr = 0;
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 */
158 char dir[MAX_PATH];
159 char str[4] = "a:\\";
160 GetCurrentDirectoryA( sizeof(dir), dir );
161 for(i = 0, n = -1; i < 26; i++)
163 str[0] = 'a' + 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);
173 if (lfs->hook)
174 return (BOOL) FILEDLG_CallWindowProc16(lfs, WM_INITDIALOG, wParam, lfs->lParam);
175 return TRUE;
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;
187 return TRUE;
190 /* ------------------ Dialog procedures ---------------------- */
192 /***********************************************************************
193 * FileOpenDlgProc (COMMDLG.6)
195 BOOL16 CALLBACK FileOpenDlgProc16(HWND16 hWnd16, UINT16 wMsg, WPARAM16 wParam,
196 LPARAM lParam)
198 HWND hWnd = HWND_32(hWnd16);
199 LFSPRIVATE lfs = (LFSPRIVATE)GetPropA(hWnd,OFN_PROP);
200 DRAWITEMSTRUCT dis;
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);
206 if (lRet)
207 return lRet; /* else continue message processing */
209 switch (wMsg)
211 case WM_INITDIALOG:
212 return FILEDLG_WMInitDialog16(hWnd, wParam, lParam);
214 case WM_MEASUREITEM:
215 return FILEDLG_WMMeasureItem16(hWnd16, wParam, lParam);
217 case WM_DRAWITEM:
218 FILEDLG_MapDrawItemStruct(MapSL(lParam), &dis);
219 return FILEDLG_WMDrawItem(hWnd, wParam, lParam, FALSE, &dis);
221 case WM_COMMAND:
222 return FILEDLG_WMCommand(hWnd, lParam, HIWORD(lParam),wParam, lfs);
223 #if 0
224 case WM_CTLCOLOR:
225 SetBkColor((HDC16)wParam, 0x00C0C0C0);
226 switch (HIWORD(lParam))
228 case CTLCOLOR_BTN:
229 SetTextColor((HDC16)wParam, 0x00000000);
230 return hGRAYBrush;
231 case CTLCOLOR_STATIC:
232 SetTextColor((HDC16)wParam, 0x00000000);
233 return hGRAYBrush;
235 break;
236 #endif
238 return FALSE;
241 /***********************************************************************
242 * FileSaveDlgProc (COMMDLG.7)
244 BOOL16 CALLBACK FileSaveDlgProc16(HWND16 hWnd16, UINT16 wMsg, WPARAM16 wParam,
245 LPARAM lParam)
247 HWND hWnd = HWND_32(hWnd16);
248 LFSPRIVATE lfs = (LFSPRIVATE)GetPropA(hWnd,OFN_PROP);
249 DRAWITEMSTRUCT dis;
251 TRACE("msg=%x wparam=%x lParam=%lx\n", wMsg, wParam, lParam);
252 if ((wMsg != WM_INITDIALOG) && lfs && lfs->hook)
254 LRESULT lRet;
255 lRet = (BOOL16)FILEDLG_CallWindowProc16(lfs, wMsg, wParam, lParam);
256 if (lRet)
257 return lRet; /* else continue message processing */
259 switch (wMsg) {
260 case WM_INITDIALOG:
261 return FILEDLG_WMInitDialog16(hWnd, wParam, lParam);
263 case WM_MEASUREITEM:
264 return FILEDLG_WMMeasureItem16(hWnd16, wParam, lParam);
266 case WM_DRAWITEM:
267 FILEDLG_MapDrawItemStruct(MapSL(lParam), &dis);
268 return FILEDLG_WMDrawItem(hWnd, wParam, lParam, TRUE, &dis);
270 case WM_COMMAND:
271 return FILEDLG_WMCommand(hWnd, lParam, HIWORD(lParam), wParam, lfs);
275 case WM_CTLCOLOR:
276 SetBkColor((HDC16)wParam, 0x00C0C0C0);
277 switch (HIWORD(lParam))
279 case CTLCOLOR_BTN:
280 SetTextColor((HDC16)wParam, 0x00000000);
281 return hGRAYBrush;
282 case CTLCOLOR_STATIC:
283 SetTextColor((HDC16)wParam, 0x00000000);
284 return hGRAYBrush;
286 return FALSE;
289 return FALSE;
292 /* ------------------ APIs ---------------------- */
294 /***********************************************************************
295 * GetOpenFileName (COMMDLG.1)
297 * Creates a dialog box for the user to select a file to open.
299 * RETURNS
300 * TRUE on success: user selected a valid file
301 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
303 * BUGS
304 * unknown, there are some FIXME's left.
306 BOOL16 WINAPI GetOpenFileName16(
307 SEGPTR ofn /* [in/out] address of structure with data*/
310 HINSTANCE16 hInst;
311 BOOL bRet = FALSE;
312 LPOPENFILENAME16 lpofn = MapSL(ofn);
313 LFSPRIVATE lfs;
314 FARPROC16 ptr;
316 if (!lpofn || !FileDlg_Init()) return FALSE;
318 lfs = FILEDLG_AllocPrivate((LPARAM) ofn, LFS16, OPEN_DIALOG);
319 if (lfs)
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));
329 return bRet;
332 /***********************************************************************
333 * GetSaveFileName (COMMDLG.2)
335 * Creates a dialog box for the user to select a file to save.
337 * RETURNS
338 * TRUE on success: user enters a valid file
339 * FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
341 * BUGS
342 * unknown. There are some FIXME's left.
344 BOOL16 WINAPI GetSaveFileName16(
345 SEGPTR ofn /* [in/out] addess of structure with data*/
348 HINSTANCE16 hInst;
349 BOOL bRet = FALSE;
350 LPOPENFILENAME16 lpofn = MapSL(ofn);
351 LFSPRIVATE lfs;
352 FARPROC16 ptr;
354 if (!lpofn || !FileDlg_Init()) return FALSE;
356 lfs = FILEDLG_AllocPrivate((LPARAM) ofn, LFS16, SAVE_DIALOG);
357 if (lfs)
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));
367 return bRet;