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