3 * Copyright (C) 2004 ReactOS Team
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.
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.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * PROJECT: ReactOS International Control Panel
22 * FILE: lib/cpl/intl/numbers.c
23 * PURPOSE: Numbers property page
24 * PROGRAMMER: Eric Kohl
35 #define SAMPLE_NUMBER _T("123456789")
36 #define SAMPLE_NEG_NUMBER _T("-123456789")
37 #define MAX_NUM_SEP_SAMPLES 2
38 #define MAX_FRAC_NUM_SAMPLES 10
39 #define MAX_FIELD_SEP_SAMPLES 1
40 #define MAX_FIELD_DIG_SAMPLES 3
41 #define MAX_NEG_SIGN_SAMPLES 1
42 #define MAX_NEG_NUMBERS_SAMPLES 5
43 #define MAX_LEAD_ZEROES_SAMPLES 2
44 #define MAX_LIST_SEP_SAMPLES 1
45 #define MAX_UNITS_SYS_SAMPLES 2
47 static LPTSTR lpNumSepSamples
[MAX_NUM_SEP_SAMPLES
] =
49 static LPTSTR lpFieldSepSamples
[MAX_FIELD_SEP_SAMPLES
] =
51 static LPTSTR lpFieldDigNumSamples
[MAX_FIELD_DIG_SAMPLES
] =
52 {_T("0;0"), _T("3;0"), _T("3;2;0")};
53 static LPTSTR lpNegSignSamples
[MAX_NEG_SIGN_SAMPLES
] =
55 static LPTSTR lpNegNumFmtSamples
[MAX_NEG_NUMBERS_SAMPLES
] =
56 {_T("(1,1)"), _T("-1,1"), _T("- 1,1"), _T("1,1-"), _T("1,1 -")};
57 static LPTSTR lpLeadNumFmtSamples
[MAX_LEAD_ZEROES_SAMPLES
] =
58 {_T(",7"), _T("0,7")};
59 static LPTSTR lpListSepSamples
[MAX_LIST_SEP_SAMPLES
] =
61 static LPTSTR lpUnitsSysSamples
[MAX_UNITS_SYS_SAMPLES
] =
62 {_T("Metrics"), _T("Americans")};
65 /* Init num decimal separator control box */
67 InitNumDecimalSepCB(HWND hwndDlg
, LCID lcid
)
69 TCHAR szNumSep
[MAX_SAMPLES_STR_SIZE
];
73 /* Get current decimal separator */
77 MAX_SAMPLES_STR_SIZE
);
79 /* Clear all box content */
80 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERDSYMBOL
),
85 /* Create standard list of decimal separators */
86 for (nCBIndex
= 0; nCBIndex
< MAX_NUM_SEP_SAMPLES
; nCBIndex
++)
88 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERDSYMBOL
),
91 (LPARAM
)lpNumSepSamples
[nCBIndex
]);
94 /* Set current item to value from registry */
95 nRetCode
= SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERDSYMBOL
),
98 (LPARAM
)(LPCSTR
)szNumSep
);
100 /* if is not success, add new value to list and select them */
101 if (nRetCode
== CB_ERR
)
103 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERDSYMBOL
),
107 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERDSYMBOL
),
114 /* Init number of fractional symbols control box */
116 InitNumOfFracSymbCB(HWND hwndDlg
, LCID lcid
)
118 TCHAR szFracNum
[MAX_SAMPLES_STR_SIZE
];
119 TCHAR szFracCount
[MAX_SAMPLES_STR_SIZE
];
123 /* Get current number of fractional symbols */
127 MAX_SAMPLES_STR_SIZE
);
129 /* Clear all box content */
130 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSNDIGDEC
),
135 /* Create standard list of fractional symbols */
136 for (nCBIndex
= 0; nCBIndex
< MAX_FRAC_NUM_SAMPLES
; nCBIndex
++)
138 /* convert to wide char */
139 _itot(nCBIndex
, szFracCount
, DECIMAL_RADIX
);
141 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSNDIGDEC
),
144 (LPARAM
)szFracCount
);
147 /* Set current item to value from registry */
148 nRetCode
= SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSNDIGDEC
),
150 (WPARAM
)_ttoi(szFracNum
),
154 /* Init field separator control box */
156 InitNumFieldSepCB(HWND hwndDlg
, LCID lcid
)
158 TCHAR szFieldSep
[MAX_SAMPLES_STR_SIZE
];
162 /* Get current field separator */
166 MAX_SAMPLES_STR_SIZE
);
168 /* Clear all box content */
169 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSDIGITGRSYM
),
174 /* Create standart list of field separators */
175 for (nCBIndex
= 0; nCBIndex
< MAX_FIELD_SEP_SAMPLES
; nCBIndex
++)
177 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSDIGITGRSYM
),
180 (LPARAM
)lpFieldSepSamples
[nCBIndex
]);
183 /* Set current item to value from registry */
184 nRetCode
= SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSDIGITGRSYM
),
189 /* if is not success, add new value to list and select them */
190 if (nRetCode
== CB_ERR
)
192 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSDIGITGRSYM
),
194 MAX_FIELD_SEP_SAMPLES
+1,
196 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSDIGITGRSYM
),
203 /* Init number of digidts in field control box */
205 InitFieldDigNumCB(HWND hwndDlg
, LCID lcid
)
207 TCHAR szFieldDigNum
[MAX_SAMPLES_STR_SIZE
];
208 LPTSTR pszFieldDigNumSmpl
;
212 /* Get current field digits num */
216 MAX_SAMPLES_STR_SIZE
);
218 /* Clear all box content */
219 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSDGROUPING
),
224 /* Create standart list of field digits num */
225 for (nCBIndex
= 0; nCBIndex
< MAX_FIELD_DIG_SAMPLES
; nCBIndex
++)
228 pszFieldDigNumSmpl
= InsSpacesFmt(SAMPLE_NUMBER
, lpFieldDigNumSamples
[nCBIndex
]);
229 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSDGROUPING
),
232 (LPARAM
)pszFieldDigNumSmpl
);
233 free(pszFieldDigNumSmpl
);
236 pszFieldDigNumSmpl
= InsSpacesFmt(SAMPLE_NUMBER
, szFieldDigNum
);
237 /* Set current item to value from registry */
238 nRetCode
= SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSDGROUPING
),
241 (LPARAM
)pszFieldDigNumSmpl
);
243 /* if is not success, add new value to list and select them */
244 if (nRetCode
== CB_ERR
)
246 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSDGROUPING
),
248 MAX_FIELD_DIG_SAMPLES
+1,
249 (LPARAM
)pszFieldDigNumSmpl
);
250 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSDGROUPING
),
253 (LPARAM
)pszFieldDigNumSmpl
);
256 free(pszFieldDigNumSmpl
);
259 /* Init negative sign control box */
261 InitNegSignCB(HWND hwndDlg
, LCID lcid
)
263 TCHAR szNegSign
[MAX_SAMPLES_STR_SIZE
];
267 /* Get current negative sign */
269 LOCALE_SNEGATIVESIGN
,
271 MAX_SAMPLES_STR_SIZE
);
273 /* Clear all box content */
274 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSNSIGNSYM
),
279 /* Create standart list of signs */
280 for (nCBIndex
= 0; nCBIndex
< MAX_NEG_SIGN_SAMPLES
; nCBIndex
++)
282 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSNSIGNSYM
),
285 (LPARAM
)lpNegSignSamples
[nCBIndex
]);
288 /* Set current item to value from registry */
289 nRetCode
= SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSNSIGNSYM
),
294 /* if is not success, add new value to list and select them */
295 if (nRetCode
== CB_ERR
)
297 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSNSIGNSYM
),
299 MAX_NUM_SEP_SAMPLES
+1,
301 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSNSIGNSYM
),
308 /* Init negative numbers format control box */
310 InitNegNumFmtCB(HWND hwndDlg
, LCID lcid
)
312 TCHAR szNegNumFmt
[MAX_SAMPLES_STR_SIZE
];
313 TCHAR szNumSep
[MAX_SAMPLES_STR_SIZE
];
314 TCHAR szNegSign
[MAX_SAMPLES_STR_SIZE
];
315 TCHAR szNewSample
[MAX_SAMPLES_STR_SIZE
];
320 /* Get current negative numbers format */
324 MAX_SAMPLES_STR_SIZE
);
326 /* Clear all box content */
327 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSNNUMFORMAT
),
332 /* Get current decimal separator */
336 MAX_SAMPLES_STR_SIZE
);
338 /* Get current negative sign */
340 LOCALE_SNEGATIVESIGN
,
342 MAX_SAMPLES_STR_SIZE
);
344 /* Create standart list of negative numbers formats */
345 for (nCBIndex
= 0; nCBIndex
< MAX_NEG_NUMBERS_SAMPLES
; nCBIndex
++)
347 /* Replace standart separator to setted */
348 pszResultStr
= ReplaceSubStr(lpNegNumFmtSamples
[nCBIndex
],
351 _tcscpy(szNewSample
, pszResultStr
);
353 /* Replace standart negative sign to setted */
354 pszResultStr
= ReplaceSubStr(szNewSample
,
357 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSNNUMFORMAT
),
360 (LPARAM
)pszResultStr
);
364 /* Set current item to value from registry */
365 nRetCode
= SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSNNUMFORMAT
),
367 (WPARAM
)_ttoi(szNegNumFmt
),
371 /* Init leading zeroes control box */
373 InitLeadingZeroesCB(HWND hwndDlg
, LCID lcid
)
375 TCHAR szLeadNumFmt
[MAX_SAMPLES_STR_SIZE
];
376 TCHAR szNumSep
[MAX_SAMPLES_STR_SIZE
];
381 /* Get current leading zeroes format */
385 MAX_SAMPLES_STR_SIZE
);
387 /* Clear all box content */
388 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSDISPLEADZER
),
393 /* Get current decimal separator */
397 MAX_SAMPLES_STR_SIZE
);
399 /* Create list of standart leading zeroes formats */
400 for (nCBIndex
= 0; nCBIndex
< MAX_LEAD_ZEROES_SAMPLES
; nCBIndex
++)
402 pszResultStr
= ReplaceSubStr(lpLeadNumFmtSamples
[nCBIndex
],
405 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSDISPLEADZER
),
408 (LPARAM
)pszResultStr
);
412 /* Set current item to value from registry */
413 nRetCode
= SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSDISPLEADZER
),
415 (WPARAM
)_ttoi(szLeadNumFmt
),
420 InitListSepCB(HWND hwndDlg
,
423 TCHAR szListSep
[MAX_SAMPLES_STR_SIZE
];
427 /* Get current list separator */
431 MAX_SAMPLES_STR_SIZE
);
433 /* Clear all box content */
434 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSLSEP
),
439 /* Create standart list of signs */
440 for (nCBIndex
= 0; nCBIndex
< MAX_LIST_SEP_SAMPLES
; nCBIndex
++)
442 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSLSEP
),
445 (LPARAM
)lpListSepSamples
[nCBIndex
]);
448 /* Set current item to value from registry */
449 nRetCode
= SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSLSEP
),
454 /* if is not success, add new value to list and select them */
455 if (nRetCode
== CB_ERR
)
457 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSLSEP
),
459 MAX_LIST_SEP_SAMPLES
+1,
461 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSLSEP
),
468 /* Init system of units control box */
470 InitUnitsSysCB(HWND hwndDlg
,
473 TCHAR szUnitsSys
[MAX_SAMPLES_STR_SIZE
];
476 /* Get current system of units */
480 MAX_SAMPLES_STR_SIZE
);
482 /* Clear all box content */
483 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSMEASSYS
),
488 /* Create list of standart system of units */
489 for (nCBIndex
= 0; nCBIndex
< MAX_UNITS_SYS_SAMPLES
; nCBIndex
++)
491 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSMEASSYS
),
494 (LPARAM
)lpUnitsSysSamples
[nCBIndex
]);
497 /* Set current item to value from registry */
498 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSMEASSYS
),
500 (WPARAM
)_ttoi(szUnitsSys
),
504 /* Update all numbers locale samples */
506 UpdateNumSamples(HWND hwndDlg
,
509 TCHAR OutBuffer
[MAX_FMT_SIZE
];
511 /* Get positive number format sample */
512 GetNumberFormat(lcid
,
519 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSPOSSAMPLE
),
524 /* Get positive number format sample */
525 GetNumberFormat(lcid
,
532 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSNEGSAMPLE
),
538 /* Set num decimal separator */
540 SetNumDecimalSep(HWND hwndDlg
,
543 TCHAR szDecimalSep
[MAX_SAMPLES_STR_SIZE
];
545 /* Get setted decimal separator */
546 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERDSYMBOL
),
548 (WPARAM
)MAX_SAMPLES_STR_SIZE
,
549 (LPARAM
)szDecimalSep
);
551 /* Save decimal separator */
552 SetLocaleInfo(lcid
, LOCALE_SDECIMAL
, szDecimalSep
);
557 /* Set number of fractional symbols */
559 SetFracSymNum(HWND hwndDlg
,
562 TCHAR szFracSymNum
[MAX_SAMPLES_STR_SIZE
];
565 /* Get setted number of fractional symbols */
566 nCurrSel
= SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSNDIGDEC
),
571 /* convert to wide char */
572 _itot(nCurrSel
, szFracSymNum
, DECIMAL_RADIX
);
574 /* Save number of fractional symbols */
575 SetLocaleInfo(lcid
, LOCALE_IDIGITS
, szFracSymNum
);
580 /* Set field separator */
582 SetNumFieldSep(HWND hwndDlg
,
585 TCHAR szFieldSep
[MAX_SAMPLES_STR_SIZE
];
587 /* Get setted field separator */
588 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSDGROUPING
),
590 (WPARAM
)MAX_SAMPLES_STR_SIZE
,
593 /* Save field separator */
594 SetLocaleInfo(lcid
, LOCALE_STHOUSAND
, szFieldSep
);
599 /* Set number of digidts in field */
601 SetFieldDigNum(HWND hwndDlg
,
606 /* Get setted number of digidts in field */
607 nCurrSel
=SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSNSIGNSYM
),
612 /* Save number of digidts in field */
613 SetLocaleInfo(lcid
, LOCALE_SGROUPING
, lpFieldDigNumSamples
[nCurrSel
]);
618 /* Set negative sign */
620 SetNumNegSign(HWND hwndDlg
,
623 TCHAR szNegSign
[MAX_SAMPLES_STR_SIZE
];
625 /* Get setted negative sign */
626 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSNSIGNSYM
),
628 (WPARAM
)MAX_SAMPLES_STR_SIZE
,
631 /* Save negative sign */
632 SetLocaleInfo(lcid
, LOCALE_SNEGATIVESIGN
, szNegSign
);
637 /* Set negative sum format */
639 SetNegSumFmt(HWND hwndDlg
,
642 TCHAR szNegSumFmt
[MAX_SAMPLES_STR_SIZE
];
645 /* Get setted negative sum format */
646 nCurrSel
= SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSNNUMFORMAT
),
651 /* convert to wide char */
652 _itot(nCurrSel
, szNegSumFmt
,DECIMAL_RADIX
);
654 /* Save negative sum format */
655 SetLocaleInfo(lcid
, LOCALE_INEGNUMBER
, szNegSumFmt
);
660 /* Set leading zero */
662 SetNumLeadZero(HWND hwndDlg
,
665 TCHAR szLeadZero
[MAX_SAMPLES_STR_SIZE
];
668 /* Get setted leading zero format */
669 nCurrSel
= SendMessageW(GetDlgItem(hwndDlg
, IDC_NUMBERSDISPLEADZER
),
674 /* convert to wide char */
675 _itot(nCurrSel
, szLeadZero
, DECIMAL_RADIX
);
677 /* Save leading zero format */
678 SetLocaleInfo(lcid
, LOCALE_ILZERO
, szLeadZero
);
683 /* Set elements list separator */
685 SetNumListSep(HWND hwndDlg
,
688 TCHAR szListSep
[MAX_SAMPLES_STR_SIZE
];
690 /* Get setted list separator */
691 SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSLSEP
),
693 (WPARAM
)MAX_SAMPLES_STR_SIZE
,
696 /* Save list separator */
697 SetLocaleInfo(lcid
, LOCALE_SLIST
, szListSep
);
702 /* Set units system */
704 SetNumUnitsSys(HWND hwndDlg
,
707 TCHAR szUnitsSys
[MAX_SAMPLES_STR_SIZE
];
710 /* Get setted units system */
711 nCurrSel
= SendMessage(GetDlgItem(hwndDlg
, IDC_NUMBERSMEASSYS
),
716 /* convert to wide char */
717 _itot(nCurrSel
, szUnitsSys
, DECIMAL_RADIX
);
719 /* Save units system */
720 SetLocaleInfo(lcid
, LOCALE_IMEASURE
, szUnitsSys
);
725 /* Property page dialog callback */
727 NumbersPageProc(HWND hwndDlg
,
732 PGLOBALDATA pGlobalData
;
734 pGlobalData
= (PGLOBALDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
739 pGlobalData
= (PGLOBALDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
740 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pGlobalData
);
742 InitNumDecimalSepCB(hwndDlg
, pGlobalData
->lcid
);
743 InitNumOfFracSymbCB(hwndDlg
, pGlobalData
->lcid
);
744 InitNumFieldSepCB(hwndDlg
, pGlobalData
->lcid
);
745 InitFieldDigNumCB(hwndDlg
, pGlobalData
->lcid
);
746 InitNegSignCB(hwndDlg
, pGlobalData
->lcid
);
747 InitNegNumFmtCB(hwndDlg
, pGlobalData
->lcid
);
748 InitLeadingZeroesCB(hwndDlg
, pGlobalData
->lcid
);
749 InitListSepCB(hwndDlg
, pGlobalData
->lcid
);
750 InitUnitsSysCB(hwndDlg
, pGlobalData
->lcid
);
751 UpdateNumSamples(hwndDlg
, pGlobalData
->lcid
);
755 switch (LOWORD(wParam
))
757 case IDC_NUMBERDSYMBOL
:
758 case IDC_NUMBERSNDIGDEC
:
759 case IDC_NUMBERSDIGITGRSYM
:
760 case IDC_NUMBERSDGROUPING
:
761 case IDC_NUMBERSNSIGNSYM
:
762 case IDC_NUMBERSNNUMFORMAT
:
763 case IDC_NUMBERSDISPLEADZER
:
764 case IDC_NUMBERSLSEP
:
765 case IDC_NUMBERSMEASSYS
:
766 if (HIWORD(wParam
) == CBN_SELCHANGE
|| HIWORD(wParam
) == CBN_EDITCHANGE
)
768 /* Set "Apply" button enabled */
769 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
775 /* If push apply button */
776 if (((LPNMHDR
)lParam
)->code
== (UINT
)PSN_APPLY
)
778 if (!SetNumDecimalSep(hwndDlg
, pGlobalData
->lcid
))
781 if (!SetFracSymNum(hwndDlg
, pGlobalData
->lcid
))
784 if (!SetNumFieldSep(hwndDlg
, pGlobalData
->lcid
))
787 if (!SetFieldDigNum(hwndDlg
, pGlobalData
->lcid
))
790 if (!SetNumNegSign(hwndDlg
, pGlobalData
->lcid
))
793 if (!SetNegSumFmt(hwndDlg
, pGlobalData
->lcid
))
796 if (!SetNumLeadZero(hwndDlg
, pGlobalData
->lcid
))
799 if (!SetNumListSep(hwndDlg
, pGlobalData
->lcid
))
802 if (!SetNumUnitsSys(hwndDlg
, pGlobalData
->lcid
))
805 UpdateNumSamples(hwndDlg
, pGlobalData
->lcid
);