[TASKMGR] Process page: Allow using "Open File Location" functionality without runnin...
[reactos.git] / dll / cpl / intl / intl.c
1 /*
2 * ReactOS
3 * Copyright (C) 2004 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 /*
20 * PROJECT: ReactOS International Control Panel
21 * FILE: dll/cpl/intl/intl.c
22 * PURPOSE: Property sheet code
23 * PROGRAMMER: Eric Kohl
24 */
25
26 #include "intl.h"
27
28 #include <debug.h>
29
30 #define NUM_APPLETS (1)
31
32 #define BUFFERSIZE 512
33
34 static LONG APIENTRY
35 Applet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam);
36
37
38 HINSTANCE hApplet = 0;
39 HINF hSetupInf = INVALID_HANDLE_VALUE;
40 DWORD IsUnattendedSetupEnabled = 0;
41 DWORD UnattendLCID = 0;
42
43
44 /* Applets */
45 APPLET Applets[NUM_APPLETS] =
46 {
47 {IDC_CPLICON, IDS_CPLNAME, IDS_CPLDESCRIPTION, Applet}
48 };
49
50 VOID
51 PrintErrorMsgBox(UINT msg)
52 {
53 WCHAR szErrorText[BUFFERSIZE];
54 WCHAR szErrorCaption[BUFFERSIZE];
55
56 LoadStringW(hApplet, msg, szErrorText, sizeof(szErrorText) / sizeof(WCHAR));
57 LoadStringW(hApplet, IDS_ERROR, szErrorCaption, sizeof(szErrorCaption) / sizeof(WCHAR));
58
59 MessageBoxW(NULL, szErrorText, szErrorCaption, MB_OK | MB_ICONERROR);
60 }
61
62 INT
63 ResourceMessageBox(
64 HWND hwnd,
65 UINT uType,
66 UINT uCaptionId,
67 UINT uMessageId)
68 {
69 WCHAR szErrorText[BUFFERSIZE];
70 WCHAR szErrorCaption[BUFFERSIZE];
71
72 LoadStringW(hApplet, uMessageId, szErrorText, sizeof(szErrorText) / sizeof(WCHAR));
73 LoadStringW(hApplet, uCaptionId, szErrorCaption, sizeof(szErrorCaption) / sizeof(WCHAR));
74
75 return MessageBoxW(hwnd, szErrorText, szErrorCaption, uType);
76 }
77
78 static VOID
79 InitIntlPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc, LPARAM lParam)
80 {
81 ZeroMemory(psp, sizeof(PROPSHEETPAGE));
82 psp->dwSize = sizeof(PROPSHEETPAGE);
83 psp->dwFlags = PSP_DEFAULT;
84 psp->hInstance = hApplet;
85 psp->pszTemplate = MAKEINTRESOURCE(idDlg);
86 psp->pfnDlgProc = DlgProc;
87 psp->lParam = lParam;
88 }
89
90 BOOL
91 OpenSetupInf(VOID)
92 {
93 PWSTR lpCmdLine;
94 PWSTR lpSwitch;
95 size_t len;
96
97 lpCmdLine = GetCommandLineW();
98
99 lpSwitch = wcsstr(lpCmdLine, L"/f:\"");
100 if (!lpSwitch)
101 return FALSE;
102
103 len = wcslen(lpSwitch);
104 if (len < 5 || lpSwitch[len-1] != L'\"')
105 {
106 DPRINT1("Invalid switch: %ls\n", lpSwitch);
107 return FALSE;
108 }
109
110 lpSwitch[len-1] = L'\0';
111
112 hSetupInf = SetupOpenInfFileW(&lpSwitch[4], NULL, INF_STYLE_OLDNT, NULL);
113 if (hSetupInf == INVALID_HANDLE_VALUE)
114 {
115 DPRINT1("Failed to open INF file: %ls\n", &lpSwitch[4]);
116 return FALSE;
117 }
118
119 return TRUE;
120 }
121
122 VOID
123 ParseSetupInf(VOID)
124 {
125 INFCONTEXT InfContext;
126 WCHAR szBuffer[30];
127
128 if (!SetupFindFirstLineW(hSetupInf,
129 L"Unattend",
130 L"LocaleID",
131 &InfContext))
132 {
133 SetupCloseInfFile(hSetupInf);
134 DPRINT1("SetupFindFirstLine failed\n");
135 return;
136 }
137
138 if (!SetupGetStringFieldW(&InfContext, 1, szBuffer,
139 sizeof(szBuffer) / sizeof(WCHAR), NULL))
140 {
141 SetupCloseInfFile(hSetupInf);
142 DPRINT1("SetupGetStringField failed\n");
143 return;
144 }
145
146 UnattendLCID = wcstoul(szBuffer, NULL, 16);
147 IsUnattendedSetupEnabled = 1;
148 SetupCloseInfFile(hSetupInf);
149 }
150
151 static int CALLBACK
152 PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam)
153 {
154 // NOTE: This callback is needed to set large icon correctly.
155 HICON hIcon;
156 switch (uMsg)
157 {
158 case PSCB_INITIALIZED:
159 {
160 hIcon = LoadIconW(hApplet, MAKEINTRESOURCEW(IDC_CPLICON));
161 SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
162 break;
163 }
164 }
165 return 0;
166 }
167
168 static LONG APIENTRY
169 Applet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam)
170 {
171 PROPSHEETPAGE psp[3];
172 PROPSHEETHEADER psh;
173 PGLOBALDATA pGlobalData;
174 INT nPage = 0;
175 LONG ret;
176
177 if (OpenSetupInf())
178 {
179 ParseSetupInf();
180 }
181
182 if (uMsg == CPL_STARTWPARMSW && lParam != 0)
183 nPage = _wtoi((PWSTR)lParam);
184
185 pGlobalData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GLOBALDATA));
186 if (pGlobalData == NULL)
187 return FALSE;
188
189 pGlobalData->SystemLCID = GetSystemDefaultLCID();
190 pGlobalData->bIsUserAdmin = IsUserAdmin();
191
192 ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
193 psh.dwSize = sizeof(PROPSHEETHEADER);
194 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_USEICONID | PSH_USECALLBACK;
195 psh.hwndParent = hwnd;
196 psh.hInstance = hApplet;
197 psh.pszIcon = MAKEINTRESOURCEW(IDC_CPLICON);
198 psh.pszCaption = MAKEINTRESOURCEW(IDS_CPLNAME);
199 psh.nPages = 0;
200 psh.nStartPage = 0;
201 psh.ppsp = psp;
202 psh.pfnCallback = PropSheetProc;
203
204 InitIntlPropSheetPage(&psp[0], IDD_GENERALPAGE, GeneralPageProc, (LPARAM)pGlobalData);
205 psh.nPages++;
206 InitIntlPropSheetPage(&psp[1], IDD_LANGUAGESPAGE, LanguagesPageProc, (LPARAM)pGlobalData);
207 psh.nPages++;
208
209 if (pGlobalData->bIsUserAdmin)
210 {
211 InitIntlPropSheetPage(&psp[2], IDD_ADVANCEDPAGE, AdvancedPageProc, (LPARAM)pGlobalData);
212 psh.nPages++;
213 }
214
215 if (nPage != 0 && nPage <= psh.nPages)
216 psh.nStartPage = nPage;
217
218 ret = (LONG)(PropertySheet(&psh) != -1);
219 if (ret > 0)
220 SendMessageW(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)L"intl");
221
222 HeapFree(GetProcessHeap(), 0, pGlobalData);
223
224 return ret;
225 }
226
227
228 /* Control Panel Callback */
229 LONG APIENTRY
230 CPlApplet(HWND hwndCpl,
231 UINT uMsg,
232 LPARAM lParam1,
233 LPARAM lParam2)
234 {
235 UINT i = (UINT)lParam1;
236
237 switch (uMsg)
238 {
239 case CPL_INIT:
240 return TRUE;
241
242 case CPL_GETCOUNT:
243 return NUM_APPLETS;
244
245 case CPL_INQUIRE:
246 if (i < NUM_APPLETS)
247 {
248 CPLINFO *CPlInfo = (CPLINFO*)lParam2;
249 CPlInfo->lData = 0;
250 CPlInfo->idIcon = Applets[i].idIcon;
251 CPlInfo->idName = Applets[i].idName;
252 CPlInfo->idInfo = Applets[i].idDescription;
253 }
254 else
255 {
256 return TRUE;
257 }
258 break;
259
260 case CPL_DBLCLK:
261 if (i < NUM_APPLETS)
262 Applets[i].AppletProc(hwndCpl, uMsg, lParam1, lParam2);
263 else
264 return TRUE;
265 break;
266
267 case CPL_STARTWPARMSW:
268 if (i < NUM_APPLETS)
269 return Applets[i].AppletProc(hwndCpl, uMsg, lParam1, lParam2);
270 break;
271 }
272
273 return FALSE;
274 }
275
276
277 BOOL WINAPI
278 DllMain(HINSTANCE hinstDLL,
279 DWORD dwReason,
280 LPVOID lpReserved)
281 {
282 switch(dwReason)
283 {
284 case DLL_PROCESS_ATTACH:
285 case DLL_THREAD_ATTACH:
286 hApplet = hinstDLL;
287 break;
288 }
289
290 return TRUE;
291 }