xref: /reactos/dll/cpl/intl/intl.c (revision 6d8aafb6)
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     TCHAR Caption[BUFFERSIZE];
172     PROPSHEETPAGE psp[3];
173     PROPSHEETHEADER psh;
174     PGLOBALDATA pGlobalData;
175     INT nPage = 0;
176     LONG ret;
177 
178     if (OpenSetupInf())
179     {
180         ParseSetupInf();
181     }
182 
183     if (uMsg == CPL_STARTWPARMSW && lParam != 0)
184         nPage = _wtoi((PWSTR)lParam);
185 
186     pGlobalData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GLOBALDATA));
187     if (pGlobalData == NULL)
188         return FALSE;
189 
190     pGlobalData->SystemLCID = GetSystemDefaultLCID();
191     pGlobalData->bIsUserAdmin = IsUserAdmin();
192 
193     LoadString(hApplet, IDS_CPLNAME, Caption, sizeof(Caption) / sizeof(TCHAR));
194 
195     ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
196     psh.dwSize = sizeof(PROPSHEETHEADER);
197     psh.dwFlags =  PSH_PROPSHEETPAGE | PSH_USEICONID | PSH_USECALLBACK;
198     psh.hwndParent = hwnd;
199     psh.hInstance = hApplet;
200     psh.pszIcon = MAKEINTRESOURCEW(IDC_CPLICON);
201     psh.pszCaption = Caption;
202     psh.nPages = 0;
203     psh.nStartPage = 0;
204     psh.ppsp = psp;
205     psh.pfnCallback = PropSheetProc;
206 
207     InitIntlPropSheetPage(&psp[0], IDD_GENERALPAGE, GeneralPageProc, (LPARAM)pGlobalData);
208     psh.nPages++;
209     InitIntlPropSheetPage(&psp[1], IDD_LANGUAGESPAGE, LanguagesPageProc, (LPARAM)pGlobalData);
210     psh.nPages++;
211 
212     if (pGlobalData->bIsUserAdmin)
213     {
214         InitIntlPropSheetPage(&psp[2], IDD_ADVANCEDPAGE, AdvancedPageProc, (LPARAM)pGlobalData);
215         psh.nPages++;
216     }
217 
218     if (nPage != 0 && nPage <= psh.nPages)
219         psh.nStartPage = nPage;
220 
221     ret = (LONG)(PropertySheet(&psh) != -1);
222     if (ret > 0)
223         SendMessageW(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)L"intl");
224 
225     HeapFree(GetProcessHeap(), 0, pGlobalData);
226 
227     return ret;
228 }
229 
230 
231 /* Control Panel Callback */
232 LONG APIENTRY
233 CPlApplet(HWND hwndCpl,
234           UINT uMsg,
235           LPARAM lParam1,
236           LPARAM lParam2)
237 {
238     switch (uMsg)
239     {
240         case CPL_INIT:
241             return TRUE;
242 
243         case CPL_GETCOUNT:
244             return NUM_APPLETS;
245 
246         case CPL_INQUIRE:
247         {
248             CPLINFO *CPlInfo = (CPLINFO*)lParam2;
249             UINT uAppIndex = (UINT)lParam1;
250 
251             CPlInfo->lData = 0;
252             CPlInfo->idIcon = Applets[uAppIndex].idIcon;
253             CPlInfo->idName = Applets[uAppIndex].idName;
254             CPlInfo->idInfo = Applets[uAppIndex].idDescription;
255             break;
256         }
257 
258         case CPL_DBLCLK:
259             Applets[(UINT)lParam1].AppletProc(hwndCpl, uMsg, lParam1, lParam2);
260             break;
261 
262         case CPL_STARTWPARMSW:
263             return Applets[(UINT)lParam1].AppletProc(hwndCpl, uMsg, lParam1, lParam2);
264     }
265 
266     return FALSE;
267 }
268 
269 
270 BOOL WINAPI
271 DllMain(HINSTANCE hinstDLL,
272         DWORD dwReason,
273         LPVOID lpReserved)
274 {
275     switch(dwReason)
276     {
277         case DLL_PROCESS_ATTACH:
278         case DLL_THREAD_ATTACH:
279             hApplet = hinstDLL;
280             break;
281     }
282 
283   return TRUE;
284 }
285