Cast time_t to long for printing.
[wine] / dlls / commdlg / filedlg16.c
1 /*
2  * COMMDLG - File Dialogs
3  *
4  * Copyright 1994 Martin Ayotte
5  * Copyright 1996 Albrecht Kleine
6  *
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.
11  *
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.
16  *
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
20  */
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"
39
40 WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
41
42 #include "cdlg.h"
43 #include "filedlg.h"
44
45 /***********************************************************************
46  *                              FILEDLG_CallWindowProc16          [internal]
47  *
48  *      Call the appropriate hook
49  */
50 static BOOL FILEDLG_CallWindowProc16(LFSPRIVATE lfs, UINT wMsg, WPARAM wParam,
51                                    LPARAM lParam)
52 {
53     if (lfs->ofn16)
54     {
55         return (BOOL16) CallWindowProc16(
56           (WNDPROC16)lfs->ofn16->lpfnHook, HWND_16(lfs->hwnd),
57           (UINT16)wMsg, (WPARAM16)wParam, lParam);
58     }
59     return FALSE;
60 }
61
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.
67  */
68
69 static LONG FILEDLG_WMInitDialog16(HWND hWnd, WPARAM wParam, LPARAM lParam)
70 {
71   int i, n;
72   WCHAR tmpstr[BUFFILE];
73   LPWSTR pstr, old_pstr;
74   LPOPENFILENAMEW ofn;
75   LFSPRIVATE lfs = (LFSPRIVATE) lParam;
76
77   if (!lfs) return FALSE;
78   SetPropA(hWnd, OFN_PROP, (HANDLE)lfs);
79   lfs->hwnd = hWnd;
80   ofn = lfs->ofnW;
81
82   TRACE("flags=%lx initialdir=%s\n", ofn->Flags, debugstr_w(ofn->lpstrInitialDir));
83
84   SetWindowTextW( hWnd, ofn->lpstrTitle );
85   /* read custom filter information */
86   if (ofn->lpstrCustomFilter)
87     {
88       pstr = ofn->lpstrCustomFilter;
89       n = 0;
90       TRACE("lpstrCustomFilter = %p\n", pstr);
91       while(*pstr)
92         {
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;
103         }
104     }
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;
120         }
121   }
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
138    */
139   if (ofn->lpstrInitialDir != NULL)
140     {
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';
147       }
148     }
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));
155   }
156   /* select current drive in combo 2, omit missing drives */
157   {
158       char dir[MAX_PATH];
159       char str[4] = "a:\\";
160       GetCurrentDirectoryA( sizeof(dir), dir );
161       for(i = 0, n = -1; i < 26; i++)
162       {
163           str[0] = 'a' + i;
164           if (GetDriveTypeA(str) > DRIVE_NO_ROOT_DIR) n++;
165           if (toupper(str[0]) == toupper(dir[0])) break;
166       }
167   }
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;
176 }
177
178 /***********************************************************************
179  *                              FILEDLG_WMMeasureItem16         [internal]
180  */
181 static LONG FILEDLG_WMMeasureItem16(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam)
182 {
183     LPMEASUREITEMSTRUCT16 lpmeasure;
184
185     lpmeasure = MapSL(lParam);
186     lpmeasure->itemHeight = fldrHeight;
187     return TRUE;
188 }
189
190 /* ------------------ Dialog procedures ---------------------- */
191
192 /***********************************************************************
193  *           FileOpenDlgProc   (COMMDLG.6)
194  */
195 BOOL16 CALLBACK FileOpenDlgProc16(HWND16 hWnd16, UINT16 wMsg, WPARAM16 wParam,
196                                LPARAM lParam)
197 {
198     HWND hWnd = HWND_32(hWnd16);
199     LFSPRIVATE lfs = (LFSPRIVATE)GetPropA(hWnd,OFN_PROP);
200     DRAWITEMSTRUCT dis;
201
202     TRACE("msg=%x wparam=%x lParam=%lx\n", wMsg, wParam, lParam);
203     if ((wMsg != WM_INITDIALOG) && lfs && lfs->hook)
204         {
205             LRESULT lRet = (BOOL16)FILEDLG_CallWindowProc16(lfs, wMsg, wParam, lParam);
206             if (lRet)
207                 return lRet;         /* else continue message processing */
208         }
209     switch (wMsg)
210     {
211     case WM_INITDIALOG:
212         return FILEDLG_WMInitDialog16(hWnd, wParam, lParam);
213
214     case WM_MEASUREITEM:
215         return FILEDLG_WMMeasureItem16(hWnd16, wParam, lParam);
216
217     case WM_DRAWITEM:
218         FILEDLG_MapDrawItemStruct(MapSL(lParam), &dis);
219         return FILEDLG_WMDrawItem(hWnd, wParam, lParam, FALSE, &dis);
220
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))
227          {
228          case CTLCOLOR_BTN:
229              SetTextColor((HDC16)wParam, 0x00000000);
230              return hGRAYBrush;
231         case CTLCOLOR_STATIC:
232              SetTextColor((HDC16)wParam, 0x00000000);
233              return hGRAYBrush;
234         }
235       break;
236 #endif
237     }
238     return FALSE;
239 }
240
241 /***********************************************************************
242  *           FileSaveDlgProc   (COMMDLG.7)
243  */
244 BOOL16 CALLBACK FileSaveDlgProc16(HWND16 hWnd16, UINT16 wMsg, WPARAM16 wParam,
245                                LPARAM lParam)
246 {
247  HWND hWnd = HWND_32(hWnd16);
248  LFSPRIVATE lfs = (LFSPRIVATE)GetPropA(hWnd,OFN_PROP);
249  DRAWITEMSTRUCT dis;
250
251  TRACE("msg=%x wparam=%x lParam=%lx\n", wMsg, wParam, lParam);
252  if ((wMsg != WM_INITDIALOG) && lfs && lfs->hook)
253   {
254    LRESULT  lRet;
255    lRet = (BOOL16)FILEDLG_CallWindowProc16(lfs, wMsg, wParam, lParam);
256    if (lRet)
257     return lRet;         /* else continue message processing */
258   }
259   switch (wMsg) {
260    case WM_INITDIALOG:
261       return FILEDLG_WMInitDialog16(hWnd, wParam, lParam);
262
263    case WM_MEASUREITEM:
264       return FILEDLG_WMMeasureItem16(hWnd16, wParam, lParam);
265
266    case WM_DRAWITEM:
267       FILEDLG_MapDrawItemStruct(MapSL(lParam), &dis);
268       return FILEDLG_WMDrawItem(hWnd, wParam, lParam, TRUE, &dis);
269
270    case WM_COMMAND:
271       return FILEDLG_WMCommand(hWnd, lParam, HIWORD(lParam), wParam, lfs);
272   }
273
274   /*
275   case WM_CTLCOLOR:
276    SetBkColor((HDC16)wParam, 0x00C0C0C0);
277    switch (HIWORD(lParam))
278    {
279     case CTLCOLOR_BTN:
280      SetTextColor((HDC16)wParam, 0x00000000);
281      return hGRAYBrush;
282     case CTLCOLOR_STATIC:
283      SetTextColor((HDC16)wParam, 0x00000000);
284      return hGRAYBrush;
285    }
286    return FALSE;
287
288    */
289   return FALSE;
290 }
291
292 /* ------------------ APIs ---------------------- */
293
294 /***********************************************************************
295  *           GetOpenFileName   (COMMDLG.1)
296  *
297  * Creates a dialog box for the user to select a file to open.
298  *
299  * RETURNS
300  *    TRUE on success: user selected a valid file
301  *    FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
302  *
303  * BUGS
304  *    unknown, there are some FIXME's left.
305  */
306 BOOL16 WINAPI GetOpenFileName16(
307                                 SEGPTR ofn /* [in/out] address of structure with data*/
308                                 )
309 {
310     HINSTANCE16 hInst;
311     BOOL bRet = FALSE;
312     LPOPENFILENAME16 lpofn = MapSL(ofn);
313     LFSPRIVATE lfs;
314     FARPROC16 ptr;
315
316     if (!lpofn || !FileDlg_Init()) return FALSE;
317
318     lfs = FILEDLG_AllocPrivate((LPARAM) ofn, LFS16, OPEN_DIALOG);
319     if (lfs)
320     {
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);
326     }
327
328     TRACE("return lpstrFile='%s' !\n", (char *)MapSL(lpofn->lpstrFile));
329     return bRet;
330 }
331
332 /***********************************************************************
333  *           GetSaveFileName   (COMMDLG.2)
334  *
335  * Creates a dialog box for the user to select a file to save.
336  *
337  * RETURNS
338  *    TRUE on success: user enters a valid file
339  *    FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
340  *
341  * BUGS
342  *    unknown. There are some FIXME's left.
343  */
344 BOOL16 WINAPI GetSaveFileName16(
345                                 SEGPTR ofn /* [in/out] addess of structure with data*/
346                                 )
347 {
348     HINSTANCE16 hInst;
349     BOOL bRet = FALSE;
350     LPOPENFILENAME16 lpofn = MapSL(ofn);
351     LFSPRIVATE lfs;
352     FARPROC16 ptr;
353
354     if (!lpofn || !FileDlg_Init()) return FALSE;
355
356     lfs = FILEDLG_AllocPrivate((LPARAM) ofn, LFS16, SAVE_DIALOG);
357     if (lfs)
358     {
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);
364     }
365
366     TRACE("return lpstrFile='%s' !\n", (char *)MapSL(lpofn->lpstrFile));
367     return bRet;
368 }