[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
257
258 /* Set number of digits in field */
259 static BOOL
260 SetCurrencyDigNum(HWND hwndDlg, PGLOBALDATA pGlobalData)
261 {
262 INT nCurrSel;
263
264 /* Get setted number of digits in field */
265 nCurrSel = SendDlgItemMessageW(hwndDlg, IDC_CURRENCYGRPNUM,
266 CB_GETCURSEL,
267 (WPARAM)0,
268 (LPARAM)0);
269
270 /* Save number of digits in field */
271 if (nCurrSel != CB_ERR)
272 pGlobalData->nCurrGrouping = nCurrSel;
273
274 return TRUE;
275 }
276
277 /* Set currency field separator */
278 static BOOL
279 SetCurrencyFieldSep(HWND hwndDlg, PGLOBALDATA pGlobalData)
280 {
281 /* Get setted currency field separator */
282 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYGRPSEP,
283 WM_GETTEXT,
284 (WPARAM)MAX_SAMPLES_STR_SIZE,
285 (LPARAM)pGlobalData->szCurrThousandSep);
286
287 return TRUE;
288 }
289
290 /* Set number of fractional symbols */
291 static BOOL
292 SetCurrencyFracSymNum(HWND hwndDlg, PGLOBALDATA pGlobalData)
293 {
294 INT nCurrSel;
295
296 /* Get setted number of fractional symbols */
297 nCurrSel = SendDlgItemMessageW(hwndDlg, IDC_CURRENCYDECNUM,
298 CB_GETCURSEL,
299 (WPARAM)0,
300 (LPARAM)0);
301 if (nCurrSel == CB_ERR)
302 return FALSE;
303
304 pGlobalData->nCurrDigits = nCurrSel;
305
306 return TRUE;
307 }
308
309 /* Set currency separator */
310 static BOOL
311 SetCurrencySep(HWND hwndDlg, PGLOBALDATA pGlobalData)
312 {
313 /* Get setted currency decimal separator */
314 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYDECSEP,
315 WM_GETTEXT,
316 (WPARAM)MAX_SAMPLES_STR_SIZE,
317 (LPARAM)pGlobalData->szCurrDecimalSep);
318
319 return TRUE;
320 }
321
322 /* Set negative currency sum format */
323 static BOOL
324 SetNegCurrencySumFmt(HWND hwndDlg, PGLOBALDATA pGlobalData)
325 {
326 INT nCurrSel;
327
328 /* Get setted currency unit */
329 nCurrSel = SendDlgItemMessageW(hwndDlg, IDC_CURRENCYNEGVALUE,
330 CB_GETCURSEL,
331 (WPARAM)0,
332 (LPARAM)0);
333 if (nCurrSel == CB_ERR)
334 return FALSE;
335
336 pGlobalData->nCurrNegFormat = nCurrSel;
337
338 return TRUE;
339 }
340
341 /* Set positive currency sum format */
342 static BOOL
343 SetPosCurrencySumFmt(HWND hwndDlg, PGLOBALDATA pGlobalData)
344 {
345 INT nCurrSel;
346
347 /* Get setted currency unit */
348 nCurrSel = SendDlgItemMessageW(hwndDlg, IDC_CURRENCYPOSVALUE,
349 CB_GETCURSEL,
350 (WPARAM)0,
351 (LPARAM)0);
352 if (nCurrSel == CB_ERR)
353 return FALSE;
354
355 pGlobalData->nCurrPosFormat = nCurrSel;
356
357 return TRUE;
358 }
359
360 /* Set currency symbol */
361 static BOOL
362 SetCurrencySymbol(HWND hwndDlg, PGLOBALDATA pGlobalData)
363 {
364 /* Get setted currency unit */
365 SendDlgItemMessageW(hwndDlg, IDC_CURRENCYSYMBOL,
366 WM_GETTEXT,
367 (WPARAM)MAX_SAMPLES_STR_SIZE,
368 (LPARAM)(PCWSTR)pGlobalData->szCurrSymbol);
369
370 return TRUE;
371 }
372
373 /* Property page dialog callback */
374 INT_PTR CALLBACK
375 CurrencyPageProc(HWND hwndDlg,
376 UINT uMsg,
377 WPARAM wParam,
378 LPARAM lParam)
379 {
380 PGLOBALDATA pGlobalData;
381
382 pGlobalData = (PGLOBALDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
383
384 switch (uMsg)
385 {
386 case WM_INITDIALOG:
387 pGlobalData = (PGLOBALDATA)((LPPROPSHEETPAGE)lParam)->lParam;
388 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pGlobalData);
389
390 InitCurrencySymbols(hwndDlg, pGlobalData);
391 InitCurrencyPositiveFormats(hwndDlg, pGlobalData);
392 InitCurrencyNegativeFormats(hwndDlg, pGlobalData);
393 InitCurrencyDecimalSeparators(hwndDlg, pGlobalData);
394 InitCurrencyNumFracDigits(hwndDlg, pGlobalData);
395 InitCurrencyGroupSeparators(hwndDlg, pGlobalData);
396 InitDigitGroupCB(hwndDlg, pGlobalData);
397 UpdateExamples(hwndDlg, pGlobalData);
398 break;
399
400 case WM_COMMAND:
401 switch (LOWORD(wParam))
402 {
403 case IDC_CURRENCYSYMBOL:
404 case IDC_CURRENCYPOSVALUE:
405 case IDC_CURRENCYNEGVALUE:
406 case IDC_CURRENCYDECSEP:
407 case IDC_CURRENCYDECNUM:
408 case IDC_CURRENCYGRPSEP:
409 case IDC_CURRENCYGRPNUM:
410 if (HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == CBN_EDITCHANGE)
411 {
412 /* Set "Apply" button enabled */
413 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
414 }
415 }
416 break;
417
418 case WM_NOTIFY:
419 if (((LPNMHDR)lParam)->code == (UINT)PSN_APPLY)
420 {
421 if (!SetCurrencySymbol(hwndDlg, pGlobalData))
422 break;
423
424 if (!SetCurrencyDigNum(hwndDlg, pGlobalData))
425 break;
426
427 if (!SetPosCurrencySumFmt(hwndDlg, pGlobalData))
428 break;
429
430 if (!SetNegCurrencySumFmt(hwndDlg, pGlobalData))
431 break;
432
433 if (!SetCurrencySep(hwndDlg, pGlobalData))
434 break;
435
436 if (!SetCurrencyFracSymNum(hwndDlg, pGlobalData))
437 break;
438
439 if (!SetCurrencyFieldSep(hwndDlg, pGlobalData))
440 break;
441
442 pGlobalData->bUserLocaleChanged = TRUE;
443
444 UpdateExamples(hwndDlg, pGlobalData);
445 }
446 break;
447 }
448 return FALSE;
449 }
450
451 /* EOF */