user32: only set the window text and the label text if a string is passed
[wine/kumbayo.git] / dlls / shell32 / dialogs.c
blobb1efa21410907a035855805de1fd6b5d6e1a95d7
1 /*
2 * common shell dialogs
4 * Copyright 2000 Juergen Schmied
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.
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.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
22 #include "wine/port.h"
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"
36 #include "shellapi.h"
37 #include "shlobj.h"
38 #include "shell32_main.h"
39 #include "shresdef.h"
40 #include "undocshell.h"
42 typedef struct
44 HWND hwndOwner ;
45 HICON hIcon ;
46 LPCSTR lpstrDirectory ;
47 LPCSTR lpstrTitle ;
48 LPCSTR lpstrDescription ;
49 UINT uFlags ;
50 } RUNFILEDLGPARAMS ;
52 typedef BOOL (*LPFNOFN) (OPENFILENAMEA *) ;
54 WINE_DEFAULT_DEBUG_CHANNEL(shell);
55 static INT_PTR CALLBACK RunDlgProc (HWND, UINT, WPARAM, LPARAM) ;
56 static void FillList (HWND, char *) ;
59 /*************************************************************************
60 * PickIconDlg [SHELL32.62]
63 BOOL WINAPI PickIconDlg(
64 HWND hwndOwner,
65 LPSTR lpstrFile,
66 DWORD nMaxFile,
67 LPDWORD lpdwIconIndex)
69 FIXME("(%p,%s,%08x,%p):stub.\n",
70 hwndOwner, lpstrFile, nMaxFile,lpdwIconIndex);
71 return 0xffffffff;
74 /*************************************************************************
75 * RunFileDlg [SHELL32.61]
77 * NOTES
78 * Original name: RunFileDlg (exported by ordinal)
80 void WINAPI RunFileDlg(
81 HWND hwndOwner,
82 HICON hIcon,
83 LPCSTR lpstrDirectory,
84 LPCSTR lpstrTitle,
85 LPCSTR lpstrDescription,
86 UINT uFlags)
89 RUNFILEDLGPARAMS rfdp;
90 TRACE("\n");
92 rfdp.hwndOwner = hwndOwner;
93 rfdp.hIcon = hIcon;
94 rfdp.lpstrDirectory = lpstrDirectory;
95 rfdp.lpstrTitle = lpstrTitle;
96 rfdp.lpstrDescription = lpstrDescription;
97 rfdp.uFlags = uFlags;
99 DialogBoxParamA(shell32_hInstance, "SHELL_RUN_DLG", hwndOwner, RunDlgProc, (LPARAM)&rfdp);
102 /* Dialog procedure for RunFileDlg */
103 static INT_PTR CALLBACK RunDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
105 int ic ;
106 char *psz, szMsg[256] ;
107 static RUNFILEDLGPARAMS *prfdp = NULL ;
109 switch (message)
111 case WM_INITDIALOG :
112 prfdp = (RUNFILEDLGPARAMS *)lParam ;
113 if(prfdp->lpstrTitle)
114 SetWindowTextA (hwnd, prfdp->lpstrTitle) ;
115 if(prfdp->lpstrDescription)
116 SetWindowTextA (GetDlgItem (hwnd, 12289), prfdp->lpstrDescription) ;
117 if(prfdp->hIcon)
118 SendMessageW (GetDlgItem (hwnd, 12297), STM_SETICON,
119 (WPARAM)prfdp->hIcon, 0);
120 FillList (GetDlgItem (hwnd, 12298), NULL) ;
121 SetFocus (GetDlgItem (hwnd, 12298)) ;
122 return TRUE ;
124 case WM_COMMAND :
125 switch (LOWORD (wParam))
127 case IDOK :
129 HWND htxt = NULL ;
130 if ((ic = GetWindowTextLengthA (htxt = GetDlgItem (hwnd, 12298))))
132 psz = HeapAlloc( GetProcessHeap(), 0, (ic + 2) );
133 GetWindowTextA (htxt, psz, ic + 1) ;
135 if (ShellExecuteA(NULL, "open", psz, NULL, NULL, SW_SHOWNORMAL) < (HINSTANCE)33)
137 char *pszSysMsg = NULL ;
138 FormatMessageA (
139 FORMAT_MESSAGE_ALLOCATE_BUFFER |
140 FORMAT_MESSAGE_FROM_SYSTEM |
141 FORMAT_MESSAGE_IGNORE_INSERTS,
142 NULL, GetLastError (),
143 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
144 (LPSTR)&pszSysMsg, 0, NULL
146 sprintf (szMsg, "Error: %s", pszSysMsg) ;
147 LocalFree ((HLOCAL)pszSysMsg) ;
148 MessageBoxA (hwnd, szMsg, "Nix", MB_OK | MB_ICONEXCLAMATION) ;
150 HeapFree(GetProcessHeap(), 0, psz);
151 SendMessageA (htxt, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
152 return TRUE ;
154 FillList (htxt, psz) ;
155 HeapFree(GetProcessHeap(), 0, psz);
156 EndDialog (hwnd, 0) ;
160 case IDCANCEL :
161 EndDialog (hwnd, 0) ;
162 return TRUE ;
164 case 12288 :
166 HMODULE hComdlg = NULL ;
167 LPFNOFN ofnProc = NULL ;
168 static char szFName[1024] = "", szFileTitle[256] = "", szInitDir[768] = "" ;
169 static OPENFILENAMEA ofn =
171 sizeof (OPENFILENAMEA),
172 NULL,
173 NULL,
174 "Executable Files\0*.exe\0All Files\0*.*\0\0\0\0",
175 NULL,
178 szFName,
179 1023,
180 szFileTitle,
181 255,
182 (LPCSTR)szInitDir,
183 "Browse",
184 OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST,
187 NULL,
189 (LPOFNHOOKPROC)NULL,
190 NULL
193 ofn.hwndOwner = hwnd ;
195 if (NULL == (hComdlg = LoadLibraryExA ("comdlg32", NULL, 0)))
197 MessageBoxA (hwnd, "Unable to display dialog box (LoadLibraryEx) !", "Nix", MB_OK | MB_ICONEXCLAMATION) ;
198 return TRUE ;
201 if ((LPFNOFN)NULL == (ofnProc = (LPFNOFN)GetProcAddress (hComdlg, "GetOpenFileNameA")))
203 MessageBoxA (hwnd, "Unable to display dialog box (GetProcAddress) !", "Nix", MB_OK | MB_ICONEXCLAMATION) ;
204 return TRUE ;
207 ofnProc (&ofn) ;
209 SetFocus (GetDlgItem (hwnd, IDOK)) ;
210 SetWindowTextA (GetDlgItem (hwnd, 12298), szFName) ;
211 SendMessageA (GetDlgItem (hwnd, 12298), CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
212 SetFocus (GetDlgItem (hwnd, IDOK)) ;
214 FreeLibrary (hComdlg) ;
216 return TRUE ;
219 return TRUE ;
221 return FALSE ;
224 /* This grabs the MRU list from the registry and fills the combo for the "Run" dialog above */
225 static void FillList (HWND hCb, char *pszLatest)
227 HKEY hkey ;
228 /* char szDbgMsg[256] = "" ; */
229 char *pszList = NULL, *pszCmd = NULL, cMatch = 0, cMax = 0x60, szIndex[2] = "-" ;
230 DWORD icList = 0, icCmd = 0 ;
231 UINT Nix ;
233 SendMessageA (hCb, CB_RESETCONTENT, 0, 0) ;
235 if (ERROR_SUCCESS != RegCreateKeyExA (
236 HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU",
237 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL))
238 MessageBoxA (hCb, "Unable to open registry key !", "Nix", MB_OK) ;
240 RegQueryValueExA (hkey, "MRUList", NULL, NULL, NULL, &icList) ;
242 if (icList > 0)
244 pszList = HeapAlloc( GetProcessHeap(), 0, icList) ;
245 if (ERROR_SUCCESS != RegQueryValueExA (hkey, "MRUList", NULL, NULL, (LPBYTE)pszList, &icList))
246 MessageBoxA (hCb, "Unable to grab MRUList !", "Nix", MB_OK) ;
248 else
250 icList = 1 ;
251 pszList = HeapAlloc( GetProcessHeap(), 0, icList) ;
252 pszList[0] = 0 ;
255 for (Nix = 0 ; Nix < icList - 1 ; Nix++)
257 if (pszList[Nix] > cMax)
258 cMax = pszList[Nix] ;
260 szIndex[0] = pszList[Nix] ;
262 if (ERROR_SUCCESS != RegQueryValueExA (hkey, szIndex, NULL, NULL, NULL, &icCmd))
263 MessageBoxA (hCb, "Unable to grab size of index", "Nix", MB_OK) ;
264 if( pszCmd )
265 pszCmd = HeapReAlloc(GetProcessHeap(), 0, pszCmd, icCmd) ;
266 else
267 pszCmd = HeapAlloc(GetProcessHeap(), 0, icCmd) ;
268 if (ERROR_SUCCESS != RegQueryValueExA (hkey, szIndex, NULL, NULL, (LPBYTE)pszCmd, &icCmd))
269 MessageBoxA (hCb, "Unable to grab index", "Nix", MB_OK) ;
271 if (NULL != pszLatest)
273 if (!lstrcmpiA(pszCmd, pszLatest))
276 sprintf (szDbgMsg, "Found existing (%d).\n", Nix) ;
277 MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ;
279 SendMessageA (hCb, CB_INSERTSTRING, 0, (LPARAM)pszCmd) ;
280 SetWindowTextA (hCb, pszCmd) ;
281 SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
283 cMatch = pszList[Nix] ;
284 memmove (&pszList[1], pszList, Nix) ;
285 pszList[0] = cMatch ;
286 continue ;
290 if (26 != icList - 1 || icList - 2 != Nix || cMatch || NULL == pszLatest)
293 sprintf (szDbgMsg, "Happily appending (%d).\n", Nix) ;
294 MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ;
296 SendMessageA (hCb, CB_ADDSTRING, 0, (LPARAM)pszCmd) ;
297 if (!Nix)
299 SetWindowTextA (hCb, pszCmd) ;
300 SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
304 else
307 sprintf (szDbgMsg, "Doing loop thing.\n") ;
308 MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ;
310 SendMessageA (hCb, CB_INSERTSTRING, 0, (LPARAM)pszLatest) ;
311 SetWindowTextA (hCb, pszLatest) ;
312 SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
314 cMatch = pszList[Nix] ;
315 memmove (&pszList[1], pszList, Nix) ;
316 pszList[0] = cMatch ;
317 szIndex[0] = cMatch ;
318 RegSetValueExA (hkey, szIndex, 0, REG_SZ, (LPBYTE)pszLatest, strlen (pszLatest) + 1) ;
322 if (!cMatch && NULL != pszLatest)
325 sprintf (szDbgMsg, "Simply inserting (increasing list).\n") ;
326 MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ;
328 SendMessageA (hCb, CB_INSERTSTRING, 0, (LPARAM)pszLatest) ;
329 SetWindowTextA (hCb, pszLatest) ;
330 SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
332 cMatch = ++cMax ;
333 if( pszList )
334 pszList = HeapReAlloc(GetProcessHeap(), 0, pszList, ++icList) ;
335 else
336 pszList = HeapAlloc(GetProcessHeap(), 0, ++icList) ;
337 memmove (&pszList[1], pszList, icList - 1) ;
338 pszList[0] = cMatch ;
339 szIndex[0] = cMatch ;
340 RegSetValueExA (hkey, szIndex, 0, REG_SZ, (LPBYTE)pszLatest, strlen (pszLatest) + 1) ;
343 RegSetValueExA (hkey, "MRUList", 0, REG_SZ, (LPBYTE)pszList, strlen (pszList) + 1) ;
345 HeapFree( GetProcessHeap(), 0, pszCmd) ;
346 HeapFree( GetProcessHeap(), 0, pszList) ;
350 /*************************************************************************
351 * ConfirmDialog [internal]
353 * Put up a confirm box, return TRUE if the user confirmed
355 static BOOL ConfirmDialog(HWND hWndOwner, UINT PromptId, UINT TitleId)
357 WCHAR Prompt[256];
358 WCHAR Title[256];
360 LoadStringW(shell32_hInstance, PromptId, Prompt, sizeof(Prompt) / sizeof(WCHAR));
361 LoadStringW(shell32_hInstance, TitleId, Title, sizeof(Title) / sizeof(WCHAR));
362 return MessageBoxW(hWndOwner, Prompt, Title, MB_YESNO|MB_ICONQUESTION) == IDYES;
366 /*************************************************************************
367 * RestartDialogEx [SHELL32.730]
370 int WINAPI RestartDialogEx(HWND hWndOwner, LPCWSTR lpwstrReason, DWORD uFlags, DWORD uReason)
372 TRACE("(%p)\n", hWndOwner);
374 /* FIXME: use lpwstrReason */
375 if (ConfirmDialog(hWndOwner, IDS_RESTART_PROMPT, IDS_RESTART_TITLE))
377 HANDLE hToken;
378 TOKEN_PRIVILEGES npr;
380 /* enable the shutdown privilege for the current process */
381 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
383 LookupPrivilegeValueA(0, "SeShutdownPrivilege", &npr.Privileges[0].Luid);
384 npr.PrivilegeCount = 1;
385 npr.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
386 AdjustTokenPrivileges(hToken, FALSE, &npr, 0, 0, 0);
387 CloseHandle(hToken);
389 ExitWindowsEx(EWX_REBOOT, uReason);
392 return 0;
396 /*************************************************************************
397 * RestartDialog [SHELL32.59]
400 int WINAPI RestartDialog(HWND hWndOwner, LPCWSTR lpstrReason, DWORD uFlags)
402 return RestartDialogEx(hWndOwner, lpstrReason, uFlags, 0);
406 /*************************************************************************
407 * ExitWindowsDialog [SHELL32.60]
409 * NOTES
410 * exported by ordinal
412 void WINAPI ExitWindowsDialog (HWND hWndOwner)
414 TRACE("(%p)\n", hWndOwner);
416 if (ConfirmDialog(hWndOwner, IDS_SHUTDOWN_PROMPT, IDS_SHUTDOWN_TITLE))
418 HANDLE hToken;
419 TOKEN_PRIVILEGES npr;
421 /* enable shutdown privilege for current process */
422 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
424 LookupPrivilegeValueA(0, "SeShutdownPrivilege", &npr.Privileges[0].Luid);
425 npr.PrivilegeCount = 1;
426 npr.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
427 AdjustTokenPrivileges(hToken, FALSE, &npr, 0, 0, 0);
428 CloseHandle(hToken);
430 ExitWindowsEx(EWX_SHUTDOWN, 0);