[INTL]
[reactos.git] / reactos / dll / cpl / intl / currency.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/currency.c
22 * PURPOSE: Currency property page
23 * PROGRAMMER: Eric Kohl
24 */
25
26 #include "intl.h"
27
28 #define POSITIVE_EXAMPLE L"123456789.00"
29 #define NEGATIVE_EXAMPLE L"-123456789.00"
30
31
32 static VOID
33 UpdateExamples(HWND hwndDlg, PGLOBALDATA pGlobalData)
34 {
35 WCHAR szBuffer[MAX_FMT_SIZE];
36
37 /* Positive example */
38 GetCurrencyFormatW(pGlobalData->UserLCID, 0,
39 POSITIVE_EXAMPLE,
40 NULL, szBuffer, MAX_FMT_SIZE);
41
42 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYPOSSAMPLE, WM_SETTEXT, 0, (LPARAM)szBuffer);
43
44 /* Negative example */
45 GetCurrencyFormatW(pGlobalData->UserLCID, 0,
46 NEGATIVE_EXAMPLE,
47 NULL, szBuffer, MAX_FMT_SIZE);
48
49 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYNEGSAMPLE, WM_SETTEXT, 0, (LPARAM)szBuffer);
50 }
51
52
53 static VOID
54 InitCurrencySymbols(HWND hwndDlg, PGLOBALDATA pGlobalData)
55 {
56 /* Limit text length */
57 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYSYMBOL,
58 CB_LIMITTEXT,
59 MAX_CURRSYMBOL - 1,
60 0);
61
62 /* Set currency symbols */
63 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYSYMBOL,
64 CB_ADDSTRING,
65 0,
66 (LPARAM)pGlobalData->szCurrSymbol);
67
68 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYSYMBOL,
69 CB_SETCURSEL,
70 0, /* Index */
71 0);
72 }
73
74
75 static VOID
76 InitCurrencyPositiveFormats(HWND hwndDlg, PGLOBALDATA pGlobalData)
77 {
78 WCHAR szBuffer[MAX_FMT_SIZE];
79 CURRENCYFMTW cyFmt;
80 INT i;
81
82 /* positive currency values */
83 cyFmt.NumDigits = pGlobalData->nCurrDigits;
84 cyFmt.LeadingZero = 0;
85 cyFmt.Grouping = 3;
86 cyFmt.lpDecimalSep = pGlobalData->szCurrDecimalSep;
87 cyFmt.lpThousandSep = pGlobalData->szCurrThousandSep;
88 cyFmt.lpCurrencySymbol = pGlobalData->szCurrSymbol;
89 cyFmt.NegativeOrder = 0;
90
91 for (i = 0; i < 4; i++)
92 {
93 cyFmt.PositiveOrder = i;
94 GetCurrencyFormatW(pGlobalData->UserLCID, 0,
95 L"1.1",
96 &cyFmt, szBuffer, MAX_FMT_SIZE);
97
98 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYPOSVALUE,
99 CB_INSERTSTRING,
100 -1,
101 (LPARAM)szBuffer);
102 }
103
104 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYPOSVALUE,
105 CB_SETCURSEL,
106 pGlobalData->nCurrPosFormat,
107 0);
108 }
109
110
111 static VOID
112 InitCurrencyNegativeFormats(HWND hwndDlg, PGLOBALDATA pGlobalData)
113 {
114 WCHAR szBuffer[MAX_FMT_SIZE];
115 CURRENCYFMTW cyFmt;
116 int i;
117
118 /* negative currency values */
119 cyFmt.NumDigits = pGlobalData->nCurrDigits;
120 cyFmt.LeadingZero = 0;
121 cyFmt.Grouping = 3;
122 cyFmt.lpDecimalSep = pGlobalData->szCurrDecimalSep;
123 cyFmt.lpThousandSep = pGlobalData->szCurrThousandSep;
124 cyFmt.lpCurrencySymbol = pGlobalData->szCurrSymbol;
125 cyFmt.PositiveOrder = 0;
126
127 for (i = 0; i < 16; i++)
128 {
129 cyFmt.NegativeOrder = i;
130 GetCurrencyFormatW(pGlobalData->UserLCID, 0,
131 L"-1.1",
132 &cyFmt, szBuffer, MAX_FMT_SIZE);
133
134 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYNEGVALUE,
135 CB_INSERTSTRING,
136 -1,
137 (LPARAM)szBuffer);
138 }
139
140 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYNEGVALUE,
141 CB_SETCURSEL,
142 pGlobalData->nCurrNegFormat,
143 0);
144 }
145
146
147 static VOID
148 InitCurrencyDecimalSeparators(HWND hwndDlg, PGLOBALDATA pGlobalData)
149 {
150 /* Limit text length */
151 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYDECSEP,
152 CB_LIMITTEXT,
153 MAX_CURRDECIMALSEP - 1,
154 0);
155
156 /* Decimal separator */
157 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYDECSEP,
158 CB_ADDSTRING,
159 0,
160 (LPARAM)pGlobalData->szCurrDecimalSep);
161
162 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYDECSEP,
163 CB_SETCURSEL,
164 0, /* Index */
165 0);
166 }
167
168
169 /* Initialize the number of fractional digits */
170 static VOID
171 InitCurrencyNumFracDigits(HWND hwndDlg, PGLOBALDATA pGlobalData)
172 {
173 WCHAR szBuffer[MAX_FMT_SIZE];
174 int i;
175
176 /* Create standard list of fractional symbols */
177 for (i = 0; i < 10; i++)
178 {
179 szBuffer[0] = L'0' + i;
180 szBuffer[1] = 0;
181 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYDECNUM,
182 CB_ADDSTRING,
183 0,
184 (LPARAM)szBuffer);
185 }
186
187 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYDECNUM,
188 CB_SETCURSEL,
189 pGlobalData->nCurrDigits,
190 0);
191 }
192
193
194 /* Initialize the list of group separators */
195 static VOID
196 InitCurrencyGroupSeparators(HWND hwndDlg, PGLOBALDATA pGlobalData)
197 {
198 /* Limit text length */
199 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYGRPSEP,
200 CB_LIMITTEXT,
201 MAX_CURRTHOUSANDSEP - 1,
202 0);
203
204 /* Digit group separator */
205 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYGRPSEP,
206 CB_ADDSTRING,
207 0,
208 (LPARAM)pGlobalData->szCurrThousandSep);
209
210 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYGRPSEP,
211 CB_SETCURSEL,
212 0, /* Index */
213 0);
214 }
215
216
217 static VOID
218 InitDigitGroupCB(HWND hwndDlg, PGLOBALDATA pGlobalData)
219 {
220 WCHAR szBuffer[MAX_FMT_SIZE];
221 CURRENCYFMTW cyFmt;
222
223 /* Digit grouping */
224 cyFmt.NumDigits = 0;
225 cyFmt.LeadingZero = 0;
226 cyFmt.lpDecimalSep = L"";
227 cyFmt.lpThousandSep = pGlobalData->szCurrThousandSep;
228 cyFmt.PositiveOrder = 0;
229 cyFmt.NegativeOrder = 0;
230 cyFmt.lpCurrencySymbol = L"";
231 cyFmt.Grouping = 0;
232 GetCurrencyFormatW(pGlobalData->UserLCID, 0,
233 L"123456789",
234 &cyFmt, szBuffer, MAX_FMT_SIZE);
235 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYGRPNUM,
236 CB_INSERTSTRING,
237 -1,
238 (LPARAM)szBuffer);
239
240 cyFmt.Grouping = 3;
241 GetCurrencyFormatW(pGlobalData->UserLCID, 0,
242 L"123456789",
243 &cyFmt, szBuffer, MAX_FMT_SIZE);
244 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYGRPNUM,
245 CB_INSERTSTRING,
246 -1,
247 (LPARAM)szBuffer);
248
249 cyFmt.Grouping = 32;
250 GetCurrencyFormatW(pGlobalData->UserLCID, 0,
251 L"123456789",
252 &cyFmt, szBuffer, MAX_FMT_SIZE);
253 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYGRPNUM,
254 CB_INSERTSTRING,
255 -1,
256 (LPARAM)szBuffer);
257
258 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYGRPNUM,
259 CB_SETCURSEL,
260 pGlobalData->nCurrGrouping, /* Index */
261 0);
262 }
263
264
265 /* Set number of digits in field */
266 static BOOL
267 SetCurrencyDigNum(HWND hwndDlg, PGLOBALDATA pGlobalData)
268 {
269 INT nCurrSel;
270
271 /* Get setted number of digits in field */
272 nCurrSel = SendDlgItemMessageW(hwndDlg, IDC_CURRENCYGRPNUM,
273 CB_GETCURSEL,
274 (WPARAM)0,
275 (LPARAM)0);
276
277 /* Save number of digits in field */
278 if (nCurrSel != CB_ERR)
279 pGlobalData->nCurrGrouping = nCurrSel;
280
281 return TRUE;
282 }
283
284 /* Set currency field separator */
285 static BOOL
286 SetCurrencyFieldSep(HWND hwndDlg, PGLOBALDATA pGlobalData)
287 {
288 /* Get setted currency field separator */
289 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYGRPSEP,
290 WM_GETTEXT,
291 (WPARAM)MAX_SAMPLES_STR_SIZE,
292 (LPARAM)pGlobalData->szCurrThousandSep);
293
294 return TRUE;
295 }
296
297 /* Set number of fractional symbols */
298 static BOOL
299 SetCurrencyFracSymNum(HWND hwndDlg, PGLOBALDATA pGlobalData)
300 {
301 INT nCurrSel;
302
303 /* Get setted number of fractional symbols */
304 nCurrSel = SendDlgItemMessageW(hwndDlg, IDC_CURRENCYDECNUM,
305 CB_GETCURSEL,
306 (WPARAM)0,
307 (LPARAM)0);
308 if (nCurrSel == CB_ERR)
309 return FALSE;
310
311 pGlobalData->nCurrDigits = nCurrSel;
312
313 return TRUE;
314 }
315
316 /* Set currency separator */
317 static BOOL
318 SetCurrencySep(HWND hwndDlg, PGLOBALDATA pGlobalData)
319 {
320 /* Get setted currency decimal separator */
321 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYDECSEP,
322 WM_GETTEXT,
323 (WPARAM)MAX_SAMPLES_STR_SIZE,
324 (LPARAM)pGlobalData->szCurrDecimalSep);
325
326 return TRUE;
327 }
328
329 /* Set negative currency sum format */
330 static BOOL
331 SetNegCurrencySumFmt(HWND hwndDlg, PGLOBALDATA pGlobalData)
332 {
333 INT nCurrSel;
334
335 /* Get setted currency unit */
336 nCurrSel = SendDlgItemMessageW(hwndDlg, IDC_CURRENCYNEGVALUE,
337 CB_GETCURSEL,
338 (WPARAM)0,
339 (LPARAM)0);
340 if (nCurrSel == CB_ERR)
341 return FALSE;
342
343 pGlobalData->nCurrNegFormat = nCurrSel;
344
345 return TRUE;
346 }
347
348 /* Set positive currency sum format */
349 static BOOL
350 SetPosCurrencySumFmt(HWND hwndDlg, PGLOBALDATA pGlobalData)
351 {
352 INT nCurrSel;
353
354 /* Get setted currency unit */
355 nCurrSel = SendDlgItemMessageW(hwndDlg, IDC_CURRENCYPOSVALUE,
356 CB_GETCURSEL,
357 (WPARAM)0,
358 (LPARAM)0);
359 if (nCurrSel == CB_ERR)
360 return FALSE;
361
362 pGlobalData->nCurrPosFormat = nCurrSel;
363
364 return TRUE;
365 }
366
367 /* Set currency symbol */
368 static BOOL
369 SetCurrencySymbol(HWND hwndDlg, PGLOBALDATA pGlobalData)
370 {
371 /* Get setted currency unit */
372 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYSYMBOL,
373 WM_GETTEXT,
374 (WPARAM)MAX_SAMPLES_STR_SIZE,
375 (LPARAM)(PCWSTR)pGlobalData->szCurrSymbol);
376
377 return TRUE;
378 }
379
380 /* Property page dialog callback */
381 INT_PTR CALLBACK
382 CurrencyPageProc(HWND hwndDlg,
383 UINT uMsg,
384 WPARAM wParam,
385 LPARAM lParam)
386 {
387 PGLOBALDATA pGlobalData;
388
389 pGlobalData = (PGLOBALDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
390
391 switch (uMsg)
392 {
393 case WM_INITDIALOG:
394 pGlobalData = (PGLOBALDATA)((LPPROPSHEETPAGE)lParam)->lParam;
395 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pGlobalData);
396
397 InitCurrencySymbols(hwndDlg, pGlobalData);
398 InitCurrencyPositiveFormats(hwndDlg, pGlobalData);
399 InitCurrencyNegativeFormats(hwndDlg, pGlobalData);
400 InitCurrencyDecimalSeparators(hwndDlg, pGlobalData);
401 InitCurrencyNumFracDigits(hwndDlg, pGlobalData);
402 InitCurrencyGroupSeparators(hwndDlg, pGlobalData);
403 InitDigitGroupCB(hwndDlg, pGlobalData);
404 UpdateExamples(hwndDlg, pGlobalData);
405 break;
406
407 case WM_COMMAND:
408 switch (LOWORD(wParam))
409 {
410 case IDC_CURRENCYSYMBOL:
411 case IDC_CURRENCYPOSVALUE:
412 case IDC_CURRENCYNEGVALUE:
413 case IDC_CURRENCYDECSEP:
414 case IDC_CURRENCYDECNUM:
415 case IDC_CURRENCYGRPSEP:
416 case IDC_CURRENCYGRPNUM:
417 if (HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == CBN_EDITCHANGE)
418 {
419 /* Set "Apply" button enabled */
420 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
421 }
422 }
423 break;
424
425 case WM_NOTIFY:
426 if (((LPNMHDR)lParam)->code == (UINT)PSN_APPLY)
427 {
428 if (!SetCurrencySymbol(hwndDlg, pGlobalData))
429 break;
430
431 if (!SetCurrencyDigNum(hwndDlg, pGlobalData))
432 break;
433
434 if (!SetPosCurrencySumFmt(hwndDlg, pGlobalData))
435 break;
436
437 if (!SetNegCurrencySumFmt(hwndDlg, pGlobalData))
438 break;
439
440 if (!SetCurrencySep(hwndDlg, pGlobalData))
441 break;
442
443 if (!SetCurrencyFracSymNum(hwndDlg, pGlobalData))
444 break;
445
446 if (!SetCurrencyFieldSep(hwndDlg, pGlobalData))
447 break;
448
449 pGlobalData->fUserLocaleChanged = TRUE;
450
451 UpdateExamples(hwndDlg, pGlobalData);
452 }
453 break;
454 }
455 return FALSE;
456 }
457
458 /* EOF */