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