Removed a few more inclusions of deprecated wine/obj_*.h headers.
[wine] / dlls / shell32 / dialogs.c
1 /*
2  *      common shell dialogs
3  *
4  * Copyright 2000 Juergen Schmied
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22 #include "wine/port.h"
23
24 #include <string.h>
25 #include <stdio.h>
26 #include "winerror.h"
27 #include "winreg.h"
28 #include "commdlg.h"
29 #include "wine/debug.h"
30
31 #include "shellapi.h"
32 #include "shlobj.h"
33 #include "shell32_main.h"
34 #include "undocshell.h"
35
36 typedef struct
37     {
38         HWND hwndOwner ;
39         HICON hIcon ;
40         LPCSTR lpstrDirectory ;
41         LPCSTR lpstrTitle ;
42         LPCSTR lpstrDescription ;
43         UINT uFlags ;
44     } RUNFILEDLGPARAMS ;
45
46 typedef BOOL (*LPFNOFN) (OPENFILENAMEA *) ;
47
48 WINE_DEFAULT_DEBUG_CHANNEL(shell);
49 INT_PTR CALLBACK RunDlgProc (HWND, UINT, WPARAM, LPARAM) ;
50 void FillList (HWND, char *) ;
51
52
53 /*************************************************************************
54  * PickIconDlg                                  [SHELL32.62]
55  *
56  */
57 BOOL WINAPI PickIconDlg(
58         HWND hwndOwner,
59         LPSTR lpstrFile,
60         DWORD nMaxFile,
61         LPDWORD lpdwIconIndex)
62 {
63         FIXME("(%p,%s,%08lx,%p):stub.\n",
64           hwndOwner, lpstrFile, nMaxFile,lpdwIconIndex);
65         return 0xffffffff;
66 }
67
68 /*************************************************************************
69  * RunFileDlg                                   [SHELL32.61]
70  *
71  * NOTES
72  *     Original name: RunFileDlg (exported by ordinal)
73  */
74 void WINAPI RunFileDlg(
75         HWND hwndOwner,
76         HICON hIcon,
77         LPCSTR lpstrDirectory,
78         LPCSTR lpstrTitle,
79         LPCSTR lpstrDescription,
80         UINT uFlags)
81 {
82
83     RUNFILEDLGPARAMS rfdp;
84     HRSRC hRes;
85     LPVOID template;
86     TRACE("\n");
87
88     rfdp.hwndOwner        = hwndOwner;
89     rfdp.hIcon            = hIcon;
90     rfdp.lpstrDirectory   = lpstrDirectory;
91     rfdp.lpstrTitle       = lpstrTitle;
92     rfdp.lpstrDescription = lpstrDescription;
93     rfdp.uFlags           = uFlags;
94
95     if(!(hRes = FindResourceA(shell32_hInstance, "SHELL_RUN_DLG", RT_DIALOGA)))
96         {
97         MessageBoxA (hwndOwner, "Couldn't find dialog.", "Nix", MB_OK) ;
98         return;
99         }
100     if(!(template = (LPVOID)LoadResource(shell32_hInstance, hRes)))
101         {
102         MessageBoxA (hwndOwner, "Couldn't load dialog.", "Nix", MB_OK) ;
103         return;
104         }
105
106     DialogBoxIndirectParamA((HINSTANCE)GetWindowLongA( hwndOwner,
107                                                        GWL_HINSTANCE ),
108                             template, hwndOwner, RunDlgProc, (LPARAM)&rfdp);
109
110 }
111
112 /* Dialog procedure for RunFileDlg */
113 INT_PTR CALLBACK RunDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
114     {
115     int ic ;
116     char *psz, szMsg[256] ;
117     static RUNFILEDLGPARAMS *prfdp = NULL ;
118
119     switch (message)
120         {
121         case WM_INITDIALOG :
122             prfdp = (RUNFILEDLGPARAMS *)lParam ;
123             SetWindowTextA (hwnd, prfdp->lpstrTitle) ;
124             SetClassLongA (hwnd, GCL_HICON, (LPARAM)prfdp->hIcon) ;
125             SendMessageA (GetDlgItem (hwnd, 12297), STM_SETICON, (WPARAM)LoadIconA (NULL, IDI_WINLOGOA), 0) ;
126             FillList (GetDlgItem (hwnd, 12298), NULL) ;
127             SetFocus (GetDlgItem (hwnd, 12298)) ;
128             return TRUE ;
129
130         case WM_COMMAND :
131             {
132             STARTUPINFOA si ;
133             PROCESS_INFORMATION pi ;
134
135             si.cb = sizeof (STARTUPINFOA) ;
136             si.lpReserved = NULL ;
137             si.lpDesktop = NULL ;
138             si.lpTitle = NULL ;
139             si.dwX = 0 ;
140             si.dwY = 0 ;
141             si.dwXSize = 0 ;
142             si.dwYSize = 0 ;
143             si.dwXCountChars = 0 ;
144             si.dwYCountChars = 0 ;
145             si.dwFillAttribute = 0 ;
146             si.dwFlags = 0 ;
147             si.cbReserved2 = 0 ;
148             si.lpReserved2 = NULL ;
149
150             switch (LOWORD (wParam))
151                 {
152                 case IDOK :
153                     {
154                     HWND htxt = NULL ;
155                     if ((ic = GetWindowTextLengthA (htxt = GetDlgItem (hwnd, 12298))))
156                         {
157                         psz = malloc (ic + 2) ;
158                         GetWindowTextA (htxt, psz, ic + 1) ;
159
160                         if (!CreateProcessA (NULL, psz, NULL, NULL, TRUE,
161                             NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi))
162                             {
163                             char *pszSysMsg = NULL ;
164                             FormatMessageA (
165                                 FORMAT_MESSAGE_ALLOCATE_BUFFER |
166                                 FORMAT_MESSAGE_FROM_SYSTEM |
167                                 FORMAT_MESSAGE_IGNORE_INSERTS,
168                                 NULL, GetLastError (),
169                                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
170                                 (LPSTR)&pszSysMsg, 0, NULL
171                                 ) ;
172                             sprintf (szMsg, "Error: %s", pszSysMsg) ;
173                             LocalFree ((HLOCAL)pszSysMsg) ;
174                             MessageBoxA (hwnd, szMsg, "Nix", MB_OK | MB_ICONEXCLAMATION) ;
175
176                             free (psz) ;
177                             SendMessageA (htxt, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
178                             return TRUE ;
179                             }
180                         FillList (htxt, psz) ;
181                         free (psz) ;
182                         EndDialog (hwnd, 0) ;
183                         }
184                     }
185
186                 case IDCANCEL :
187                     EndDialog (hwnd, 0) ;
188                     return TRUE ;
189
190                 case 12288 :
191                     {
192                     HMODULE hComdlg = (HMODULE)NULL ;
193                     LPFNOFN ofnProc = NULL ;
194                     static char szFName[1024] = "", szFileTitle[256] = "", szInitDir[768] = "" ;
195                     static OPENFILENAMEA ofn =
196                         {
197                         sizeof (OPENFILENAMEA),
198                         NULL,
199                         NULL,
200                         "Executable Files\0*.exe\0All Files\0*.*\0\0\0\0",
201                         (LPSTR)NULL,
202                         0,
203                         0,
204                         szFName,
205                         1023,
206                         szFileTitle,
207                         255,
208                         (LPCSTR)szInitDir,
209                         "Browse",
210                         OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST,
211                         0,
212                         0,
213                         (LPCSTR)NULL,
214                         0,
215                         (LPOFNHOOKPROC)NULL,
216                         (LPCSTR)NULL
217                         } ;
218
219                     ofn.hwndOwner = hwnd ;
220
221                     if ((HMODULE)NULL == (hComdlg = LoadLibraryExA ("comdlg32", (HANDLE)NULL, 0)))
222                         {
223                         MessageBoxA (hwnd, "Unable to display dialog box (LoadLibraryEx) !", "Nix", MB_OK | MB_ICONEXCLAMATION) ;
224                         return TRUE ;
225                         }
226
227                     if ((LPFNOFN)NULL == (ofnProc = (LPFNOFN)GetProcAddress (hComdlg, "GetOpenFileNameA")))
228                         {
229                         MessageBoxA (hwnd, "Unable to display dialog box (GetProcAddress) !", "Nix", MB_OK | MB_ICONEXCLAMATION) ;
230                         return TRUE ;
231                         }
232
233                     ofnProc (&ofn) ;
234
235                     SetFocus (GetDlgItem (hwnd, IDOK)) ;
236                     SetWindowTextA (GetDlgItem (hwnd, 12298), szFName) ;
237                     SendMessageA (GetDlgItem (hwnd, 12298), CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
238                     SetFocus (GetDlgItem (hwnd, IDOK)) ;
239
240                     FreeLibrary (hComdlg) ;
241
242                     return TRUE ;
243                     }
244                 }
245             return TRUE ;
246             }
247         }
248     return FALSE ;
249     }
250
251 /* This grabs the MRU list from the registry and fills the combo for the "Run" dialog above */
252 void FillList (HWND hCb, char *pszLatest)
253     {
254     HKEY hkey ;
255 /*    char szDbgMsg[256] = "" ; */
256     char *pszList = NULL, *pszCmd = NULL, cMatch = 0, cMax = 0x60, szIndex[2] = "-" ;
257     DWORD icList = 0, icCmd = 0 ;
258     UINT Nix ;
259
260     SendMessageA (hCb, CB_RESETCONTENT, 0, 0) ;
261
262     if (ERROR_SUCCESS != RegCreateKeyExA (
263         HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU",
264         0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL))
265         MessageBoxA (hCb, "Unable to open registry key !", "Nix", MB_OK) ;
266
267     RegQueryValueExA (hkey, "MRUList", NULL, NULL, NULL, &icList) ;
268
269     if (icList > 0)
270         {
271         pszList = malloc (icList) ;
272         if (ERROR_SUCCESS != RegQueryValueExA (hkey, "MRUList", NULL, NULL, pszList, &icList))
273             MessageBoxA (hCb, "Unable to grab MRUList !", "Nix", MB_OK) ;
274         }
275     else
276         {
277         pszList = malloc (icList = 1) ;
278         pszList[0] = 0 ;
279         }
280
281     for (Nix = 0 ; Nix < icList - 1 ; Nix++)
282         {
283         if (pszList[Nix] > cMax)
284             cMax = pszList[Nix] ;
285
286         szIndex[0] = pszList[Nix] ;
287
288         if (ERROR_SUCCESS != RegQueryValueExA (hkey, szIndex, NULL, NULL, NULL, &icCmd))
289             MessageBoxA (hCb, "Unable to grab size of index", "Nix", MB_OK) ;
290         pszCmd = realloc (pszCmd, icCmd) ;
291         if (ERROR_SUCCESS != RegQueryValueExA (hkey, szIndex, NULL, NULL, pszCmd, &icCmd))
292             MessageBoxA (hCb, "Unable to grab index", "Nix", MB_OK) ;
293
294         if (NULL != pszLatest)
295             {
296             if (!strcasecmp (pszCmd, pszLatest))
297                 {
298                 /*
299                 sprintf (szDbgMsg, "Found existing (%d).\n", Nix) ;
300                 MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ;
301                 */
302                 SendMessageA (hCb, CB_INSERTSTRING, 0, (LPARAM)pszCmd) ;
303                 SetWindowTextA (hCb, pszCmd) ;
304                 SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
305
306                 cMatch = pszList[Nix] ;
307                 memmove (&pszList[1], pszList, Nix) ;
308                 pszList[0] = cMatch ;
309                 continue ;
310                 }
311             }
312
313         if (26 != icList - 1 || icList - 2 != Nix || cMatch || NULL == pszLatest)
314             {
315             /*
316             sprintf (szDbgMsg, "Happily appending (%d).\n", Nix) ;
317             MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ;
318             */
319             SendMessageA (hCb, CB_ADDSTRING, 0, (LPARAM)pszCmd) ;
320             if (!Nix)
321                 {
322                 SetWindowTextA (hCb, pszCmd) ;
323                 SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
324                 }
325
326             }
327         else
328             {
329             /*
330             sprintf (szDbgMsg, "Doing loop thing.\n") ;
331             MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ;
332             */
333             SendMessageA (hCb, CB_INSERTSTRING, 0, (LPARAM)pszLatest) ;
334             SetWindowTextA (hCb, pszLatest) ;
335             SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
336
337             cMatch = pszList[Nix] ;
338             memmove (&pszList[1], pszList, Nix) ;
339             pszList[0] = cMatch ;
340             szIndex[0] = cMatch ;
341             RegSetValueExA (hkey, szIndex, 0, REG_SZ, pszLatest, strlen (pszLatest) + 1) ;
342             }
343         }
344
345     if (!cMatch && NULL != pszLatest)
346         {
347         /*
348         sprintf (szDbgMsg, "Simply inserting (increasing list).\n") ;
349         MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ;
350         */
351         SendMessageA (hCb, CB_INSERTSTRING, 0, (LPARAM)pszLatest) ;
352         SetWindowTextA (hCb, pszLatest) ;
353         SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
354
355         cMatch = ++cMax ;
356         pszList = realloc (pszList, ++icList) ;
357         memmove (&pszList[1], pszList, icList - 1) ;
358         pszList[0] = cMatch ;
359         szIndex[0] = cMatch ;
360         RegSetValueExA (hkey, szIndex, 0, REG_SZ, pszLatest, strlen (pszLatest) + 1) ;
361         }
362
363     RegSetValueExA (hkey, "MRUList", 0, REG_SZ, pszList, strlen (pszList) + 1) ;
364
365     free (pszCmd) ;
366     free (pszList) ;
367     }
368
369 /*************************************************************************
370  * ExitWindowsDialog                            [SHELL32.60]
371  *
372  * NOTES
373  *     exported by ordinal
374  */
375 void WINAPI ExitWindowsDialog (HWND hWndOwner)
376 {
377         TRACE("(%p)\n", hWndOwner);
378         if (MessageBoxA( hWndOwner, "Do you want to exit WINE?", "Shutdown", MB_YESNO|MB_ICONQUESTION) == IDYES)
379         {
380           SendMessageA ( hWndOwner, WM_QUIT, 0, 0);
381         }
382 }