* Sync up to trunk head (r65120).
[reactos.git] / dll / win32 / shlwapi / msgbox.c
1 /*
2 * SHLWAPI message box functions
3 *
4 * Copyright 2004 Jon Griffiths
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #include "precomp.h"
22
23 extern HINSTANCE shlwapi_hInstance; /* in shlwapi_main.c */
24
25 static const WCHAR szDontShowKey[] = { 'S','o','f','t','w','a','r','e','\\',
26 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
27 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
28 'E','x','p','l','o','r','e','r','\\','D','o','n','t','S','h','o','w',
29 'M','e','T','h','i','s','D','i','a','l','o','g','A','g','a','i','n','\0'
30 };
31
32 INT_PTR WINAPI SHMessageBoxCheckExW(HWND,HINSTANCE,LPCWSTR,DLGPROC,LPARAM,INT_PTR,LPCWSTR);
33 INT_PTR WINAPI SHMessageBoxCheckW(HWND,LPCWSTR,LPCWSTR,DWORD,INT_PTR,LPCWSTR);
34
35 /* Data held by each general message boxes */
36 typedef struct tagDLGDATAEX
37 {
38 DLGPROC dlgProc; /* User supplied DlgProc */
39 LPARAM lParam; /* User supplied LPARAM for dlgProc */
40 LPCWSTR lpszId; /* Name of reg key holding whether to skip */
41 } DLGDATAEX;
42
43 /* Dialogue procedure for general message boxes */
44 static INT_PTR CALLBACK SHDlgProcEx(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
45 {
46 DLGDATAEX *d = (DLGDATAEX *)GetWindowLongPtrW(hDlg, DWLP_USER);
47
48 TRACE("(%p,%u,%ld,%ld) data %p\n", hDlg, uMsg, wParam, lParam, d);
49
50 switch (uMsg)
51 {
52 case WM_INITDIALOG:
53 {
54 /* FIXME: Not sure where native stores its lParam */
55 SetWindowLongPtrW(hDlg, DWLP_USER, lParam);
56 d = (DLGDATAEX *)lParam;
57 TRACE("WM_INITDIALOG: %p, %s,%p,%p\n", hDlg, debugstr_w(d->lpszId),
58 d->dlgProc, (void*)d->lParam);
59 if (d->dlgProc)
60 return d->dlgProc(hDlg, uMsg, wParam, d->lParam);
61 return TRUE;
62 }
63
64 case WM_COMMAND:
65 switch (LOWORD(wParam))
66 {
67 case IDYES:
68 wParam = MAKELONG(IDOK, HIWORD(wParam));
69 /* Fall through ... */
70 case IDNO:
71 if (LOWORD(wParam) == IDNO)
72 wParam = MAKELONG(IDCANCEL, HIWORD(wParam));
73 /* Fall through ... */
74 case IDOK:
75 case IDCANCEL:
76
77 TRACE("WM_COMMAND: id=%s data=%p\n",
78 LOWORD(wParam) == IDOK ? "IDOK" : "IDCANCEL", d);
79
80 if (SendMessageW(GetDlgItem(hDlg, IDC_ERR_DONT_SHOW), BM_GETCHECK, 0L, 0L))
81 {
82 DWORD dwZero = 0;
83
84 /* The user clicked 'don't show again', so set the key */
85 SHRegSetUSValueW(szDontShowKey, d->lpszId, REG_DWORD, &dwZero,
86 sizeof(dwZero), SHREGSET_DEFAULT);
87 }
88 if (!d->dlgProc || !d->dlgProc(hDlg, uMsg, wParam, lParam))
89 EndDialog(hDlg, wParam);
90 return TRUE;
91 }
92 break;
93
94 default:
95 break;
96 }
97
98 if (d && d->dlgProc)
99 return d->dlgProc(hDlg, uMsg, wParam, lParam);
100 return FALSE;
101 }
102
103 /*************************************************************************
104 * @ [SHLWAPI.291]
105 *
106 * Pop up a 'Don't show this message again' dialogue box.
107 *
108 * PARAMS
109 * hWnd [I] Window to be the dialogues' parent
110 * hInst [I] Instance of the module holding the dialogue resource
111 * lpszName [I] Resource Id of the dialogue resource
112 * dlgProc [I] Dialog procedure, or NULL for default handling
113 * lParam [I] LPARAM to pass to dlgProc
114 * iRet [I] Value to return if dialogue is not shown
115 * lpszId [I] Name of registry subkey which determines whether to show the dialog
116 *
117 * RETURNS
118 * Success: The value returned from the dialogue procedure.
119 * Failure: iRet, if the dialogue resource could not be loaded or the dialogue
120 * should not be shown.
121 *
122 * NOTES
123 * Both lpszName and lpszId must be less than MAX_PATH in length.
124 */
125 INT_PTR WINAPI SHMessageBoxCheckExA(HWND hWnd, HINSTANCE hInst, LPCSTR lpszName,
126 DLGPROC dlgProc, LPARAM lParam, INT_PTR iRet,
127 LPCSTR lpszId)
128 {
129 WCHAR szNameBuff[MAX_PATH], szIdBuff[MAX_PATH];
130 LPCWSTR szName = szNameBuff;
131
132 if (IS_INTRESOURCE(lpszName))
133 szName = (LPCWSTR)lpszName; /* Resource Id or NULL */
134 else
135 MultiByteToWideChar(CP_ACP, 0, lpszName, -1, szNameBuff, MAX_PATH);
136
137 MultiByteToWideChar(CP_ACP, 0, lpszId, -1, szIdBuff, MAX_PATH);
138
139 return SHMessageBoxCheckExW(hWnd, hInst, szName, dlgProc, lParam, iRet, szIdBuff);
140 }
141
142 /*************************************************************************
143 * @ [SHLWAPI.292]
144 *
145 * Unicode version of SHMessageBoxCheckExW.
146 */
147 INT_PTR WINAPI SHMessageBoxCheckExW(HWND hWnd, HINSTANCE hInst, LPCWSTR lpszName,
148 DLGPROC dlgProc, LPARAM lParam, INT_PTR iRet, LPCWSTR lpszId)
149 {
150 DLGDATAEX d;
151
152 if (!SHRegGetBoolUSValueW(szDontShowKey, lpszId, FALSE, TRUE))
153 return iRet;
154
155 d.dlgProc = dlgProc;
156 d.lParam = lParam;
157 d.lpszId = lpszId;
158 return DialogBoxParamW(hInst, lpszName, hWnd, SHDlgProcEx, (LPARAM)&d);
159 }
160
161 /* Data held by each shlwapi message box */
162 typedef struct tagDLGDATA
163 {
164 LPCWSTR lpszTitle; /* User supplied message title */
165 LPCWSTR lpszText; /* User supplied message text */
166 DWORD dwType; /* Message box type */
167 } DLGDATA;
168
169 /* Dialogue procedure for shlwapi message boxes */
170 static INT_PTR CALLBACK SHDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
171 {
172 TRACE("(%p,%u,%ld,%ld)\n", hDlg, uMsg, wParam, lParam);
173
174 switch (uMsg)
175 {
176 case WM_INITDIALOG:
177 {
178 DLGDATA *d = (DLGDATA *)lParam;
179 TRACE("WM_INITDIALOG: %p, %s,%s,%d\n", hDlg, debugstr_w(d->lpszTitle),
180 debugstr_w(d->lpszText), d->dwType);
181
182 SetWindowTextW(hDlg, d->lpszTitle);
183 SetWindowTextW(GetDlgItem(hDlg, IDS_ERR_USER_MSG), d->lpszText);
184
185 /* Set buttons according to dwType */
186 switch (d->dwType)
187 {
188 case 0:
189 ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_HIDE);
190 /* FIXME: Move OK button to position of the Cancel button (cosmetic) */
191 case 1:
192 ShowWindow(GetDlgItem(hDlg, IDYES), SW_HIDE);
193 ShowWindow(GetDlgItem(hDlg, IDNO), SW_HIDE);
194 break;
195 default:
196 ShowWindow(GetDlgItem(hDlg, IDOK), SW_HIDE);
197 ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_HIDE);
198 break;
199 }
200 return TRUE;
201 }
202 default:
203 break;
204 }
205 return FALSE;
206 }
207
208 /*************************************************************************
209 * @ [SHLWAPI.185]
210 *
211 * Pop up a 'Don't show this message again' dialogue box.
212 *
213 * PARAMS
214 * hWnd [I] Window to be the dialogues' parent
215 * lpszText [I] Text of the message to show
216 * lpszTitle [I] Title of the dialogue box
217 * dwType [I] Type of dialogue buttons (See below)
218 * iRet [I] Value to return if dialogue is not shown
219 * lpszId [I] Name of registry subkey which determines whether to show the dialog
220 *
221 * RETURNS
222 * Success: The value returned from the dialogue procedure (e.g. IDOK).
223 * Failure: iRet, if the default dialogue resource could not be loaded or the
224 * dialogue should not be shown.
225 *
226 * NOTES
227 * - Both lpszTitle and lpszId must be less than MAX_PATH in length.
228 * - Possible values for dwType are:
229 *| Value Buttons
230 *| ----- -------
231 *| 0 OK
232 *| 1 OK/Cancel
233 *| 2 Yes/No
234 */
235 INT_PTR WINAPI SHMessageBoxCheckA(HWND hWnd, LPCSTR lpszText, LPCSTR lpszTitle,
236 DWORD dwType, INT_PTR iRet, LPCSTR lpszId)
237 {
238 WCHAR szTitleBuff[MAX_PATH], szIdBuff[MAX_PATH];
239 WCHAR *szTextBuff = NULL;
240 int iLen;
241 INT_PTR iRetVal;
242
243 if (lpszTitle)
244 MultiByteToWideChar(CP_ACP, 0, lpszTitle, -1, szTitleBuff, MAX_PATH);
245
246 if (lpszText)
247 {
248 iLen = MultiByteToWideChar(CP_ACP, 0, lpszText, -1, NULL, 0);
249 szTextBuff = HeapAlloc(GetProcessHeap(), 0, iLen * sizeof(WCHAR));
250 MultiByteToWideChar(CP_ACP, 0, lpszText, -1, szTextBuff, iLen);
251 }
252
253 MultiByteToWideChar(CP_ACP, 0, lpszId, -1, szIdBuff, MAX_PATH);
254
255 iRetVal = SHMessageBoxCheckW(hWnd, szTextBuff, lpszTitle ? szTitleBuff : NULL,
256 dwType, iRet, szIdBuff);
257 HeapFree(GetProcessHeap(), 0, szTextBuff);
258 return iRetVal;
259 }
260
261 /*************************************************************************
262 * @ [SHLWAPI.191]
263 *
264 * Unicode version of SHMessageBoxCheckA.
265 */
266 INT_PTR WINAPI SHMessageBoxCheckW(HWND hWnd, LPCWSTR lpszText, LPCWSTR lpszTitle,
267 DWORD dwType, INT_PTR iRet, LPCWSTR lpszId)
268 {
269 DLGDATA d;
270
271 d.lpszTitle = lpszTitle;
272 d.lpszText = lpszText;
273 d.dwType = dwType;
274
275 return SHMessageBoxCheckExW(hWnd, shlwapi_hInstance, (LPCWSTR)IDD_ERR_DIALOG,
276 SHDlgProc, (LPARAM)&d, iRet, lpszId);
277 }