xref: /reactos/dll/cpl/intl/numbers.c (revision 1734f297)
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/numbers.c
22  * PURPOSE:         Numbers property page
23  * PROGRAMMERS:     Eric Kohl
24  *                  Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
25  */
26 
27 #include "intl.h"
28 
29 #define SAMPLE_NUMBER               L"123456789"
30 #define SAMPLE_NEG_NUMBER           L"-123456789"
31 #define MAX_NUM_SEP_SAMPLES         2
32 #define MAX_FRAC_NUM_SAMPLES        10
33 #define MAX_FIELD_SEP_SAMPLES       1
34 #define MAX_FIELD_DIG_SAMPLES       3
35 #define MAX_NEG_SIGN_SAMPLES        1
36 #define MAX_NEG_NUMBERS_SAMPLES     5
37 #define MAX_LEAD_ZEROES_SAMPLES     2
38 #define MAX_LIST_SEP_SAMPLES        1
39 #define MAX_UNITS_SYS_SAMPLES       2
40 
41 static PWSTR lpNumSepSamples[MAX_NUM_SEP_SAMPLES] =
42     {L",", L"."};
43 static PWSTR lpFieldSepSamples[MAX_FIELD_SEP_SAMPLES] =
44     {L" "};
45 static PWSTR lpFieldDigNumSamples[MAX_FIELD_DIG_SAMPLES] =
46     {L"0;0", L"3;0", L"3;2;0"};
47 static PWSTR lpNegSignSamples[MAX_NEG_SIGN_SAMPLES] =
48     {L"-"};
49 static PWSTR lpNegNumFmtSamples[MAX_NEG_NUMBERS_SAMPLES] =
50     {L"(1,1)", L"-1,1", L"- 1,1", L"1,1-", L"1,1 -"};
51 static PWSTR lpLeadNumFmtSamples[MAX_LEAD_ZEROES_SAMPLES] =
52     {L",7", L"0,7"};
53 static PWSTR lpListSepSamples[MAX_LIST_SEP_SAMPLES] =
54     {L";"};
55 
56 
57 /* Init num decimal separator control box */
58 static VOID
59 InitNumDecimalSepCB(HWND hwndDlg, PGLOBALDATA pGlobalData)
60 {
61     INT nCBIndex;
62     INT nRetCode;
63 
64     /* Limit text length */
65     SendDlgItemMessageW(hwndDlg, IDC_NUMBERDSYMBOL,
66                         CB_LIMITTEXT,
67                         MAX_NUMDECIMALSEP - 1,
68                         0);
69 
70     /* Clear all box content */
71     SendDlgItemMessageW(hwndDlg, IDC_NUMBERDSYMBOL,
72                         CB_RESETCONTENT,
73                         (WPARAM)0,
74                         (LPARAM)0);
75 
76     /* Create standard list of decimal separators */
77     for (nCBIndex = 0; nCBIndex < MAX_NUM_SEP_SAMPLES; nCBIndex++)
78     {
79         SendDlgItemMessageW(hwndDlg, IDC_NUMBERDSYMBOL,
80                             CB_ADDSTRING,
81                             0,
82                             (LPARAM)lpNumSepSamples[nCBIndex]);
83     }
84 
85     /* Set current item to value from registry */
86     nRetCode = SendDlgItemMessageW(hwndDlg, IDC_NUMBERDSYMBOL,
87                                    CB_SELECTSTRING,
88                                    -1,
89                                    (LPARAM)pGlobalData->szNumDecimalSep);
90 
91     /* If it is not successful, add new values to list and select them */
92     if (nRetCode == CB_ERR)
93     {
94         SendDlgItemMessageW(hwndDlg, IDC_NUMBERDSYMBOL,
95                             CB_ADDSTRING,
96                             MAX_NUM_SEP_SAMPLES,
97                             (LPARAM)pGlobalData->szNumDecimalSep);
98         SendDlgItemMessageW(hwndDlg, IDC_NUMBERDSYMBOL,
99                             CB_SELECTSTRING,
100                             -1,
101                             (LPARAM)pGlobalData->szNumDecimalSep);
102     }
103 }
104 
105 /* Init number of fractional symbols control box */
106 static VOID
107 InitNumOfFracSymbCB(HWND hwndDlg, PGLOBALDATA pGlobalData)
108 {
109     WCHAR szFracCount[MAX_SAMPLES_STR_SIZE];
110     INT nCBIndex;
111 
112     /* Clear all box content */
113     SendDlgItemMessageW(hwndDlg, IDC_NUMBERSNDIGDEC,
114                         CB_RESETCONTENT,
115                         (WPARAM)0,
116                         (LPARAM)0);
117 
118     /* Create standard list of fractional symbols */
119     for (nCBIndex = 0; nCBIndex < MAX_FRAC_NUM_SAMPLES; nCBIndex++)
120     {
121         /* Convert to wide char */
122         _itow(nCBIndex, szFracCount, DECIMAL_RADIX);
123 
124         SendDlgItemMessageW(hwndDlg, IDC_NUMBERSNDIGDEC,
125                             CB_ADDSTRING,
126                             0,
127                             (LPARAM)szFracCount);
128     }
129 
130     /* Set current item to value from registry */
131     SendDlgItemMessageW(hwndDlg, IDC_NUMBERSNDIGDEC,
132                         CB_SETCURSEL,
133                         (WPARAM)pGlobalData->nNumDigits,
134                         (LPARAM)0);
135 }
136 
137 /* Init field separator control box */
138 static VOID
139 InitNumFieldSepCB(HWND hwndDlg, PGLOBALDATA pGlobalData)
140 {
141     INT nCBIndex;
142     INT nRetCode;
143 
144     /* Limit text length */
145     SendDlgItemMessageW(hwndDlg, IDC_NUMBERSDIGITGRSYM,
146                         CB_LIMITTEXT,
147                         MAX_NUMTHOUSANDSEP - 1,
148                         0);
149 
150     /* Clear all box content */
151     SendDlgItemMessageW(hwndDlg, IDC_NUMBERSDIGITGRSYM,
152                         CB_RESETCONTENT,
153                         (WPARAM)0,
154                         (LPARAM)0);
155 
156     /* Create standard list of field separators */
157     for (nCBIndex = 0; nCBIndex < MAX_FIELD_SEP_SAMPLES; nCBIndex++)
158     {
159         SendDlgItemMessageW(hwndDlg, IDC_NUMBERSDIGITGRSYM,
160                             CB_ADDSTRING,
161                             0,
162                             (LPARAM)lpFieldSepSamples[nCBIndex]);
163     }
164 
165     /* Set current item to value from registry */
166     nRetCode = SendDlgItemMessageW(hwndDlg, IDC_NUMBERSDIGITGRSYM,
167                                    CB_SELECTSTRING,
168                                    -1,
169                                    (LPARAM)pGlobalData->szNumThousandSep);
170 
171     /* If it is not success, add new values to list and select them */
172     if (nRetCode == CB_ERR)
173     {
174         SendDlgItemMessageW(hwndDlg, IDC_NUMBERSDIGITGRSYM,
175                             CB_ADDSTRING,
176                             0,
177                             (LPARAM)pGlobalData->szNumThousandSep);
178         SendDlgItemMessageW(hwndDlg, IDC_NUMBERSDIGITGRSYM,
179                             CB_SELECTSTRING,
180                             -1,
181                             (LPARAM)pGlobalData->szNumThousandSep);
182     }
183 }
184 
185 /* Init number of digits in field control box */
186 static VOID
187 InitFieldDigNumCB(HWND hwndDlg, PGLOBALDATA pGlobalData)
188 {
189     PWSTR pszFieldDigNumSmpl;
190     INT nCBIndex;
191 
192     /* Clear all box content */
193     SendDlgItemMessageW(hwndDlg, IDC_NUMBERSDGROUPING,
194                         CB_RESETCONTENT,
195                         (WPARAM)0,
196                         (LPARAM)0);
197 
198     /* Create standard list of field digits num */
199     for (nCBIndex = 0; nCBIndex < MAX_FIELD_DIG_SAMPLES; nCBIndex++)
200     {
201         pszFieldDigNumSmpl = InsSpacesFmt(SAMPLE_NUMBER, lpFieldDigNumSamples[nCBIndex]);
202         if (pszFieldDigNumSmpl != NULL)
203         {
204             SendDlgItemMessageW(hwndDlg, IDC_NUMBERSDGROUPING,
205                                 CB_ADDSTRING,
206                                 0,
207                                 (LPARAM)pszFieldDigNumSmpl);
208             HeapFree(GetProcessHeap(), 0, pszFieldDigNumSmpl);
209         }
210     }
211 
212     SendDlgItemMessageW(hwndDlg, IDC_NUMBERSDGROUPING,
213                         CB_SETCURSEL,
214                         (WPARAM)pGlobalData->nNumGrouping,
215                         (LPARAM)0);
216 }
217 
218 /* Init negative sign control box */
219 static VOID
220 InitNegSignCB(HWND hwndDlg, PGLOBALDATA pGlobalData)
221 {
222     INT nCBIndex;
223     INT nRetCode;
224 
225     /* Limit text length */
226     SendDlgItemMessageW(hwndDlg, IDC_NUMBERSNSIGNSYM,
227                         CB_LIMITTEXT,
228                         MAX_NUMNEGATIVESIGN - 1,
229                         0);
230 
231     /* Clear all box content */
232     SendDlgItemMessageW(hwndDlg, IDC_NUMBERSNSIGNSYM,
233                         CB_RESETCONTENT,
234                         (WPARAM)0,
235                         (LPARAM)0);
236 
237     /* Create standard list of signs */
238     for (nCBIndex = 0; nCBIndex < MAX_NEG_SIGN_SAMPLES; nCBIndex++)
239     {
240         SendDlgItemMessageW(hwndDlg, IDC_NUMBERSNSIGNSYM,
241                             CB_ADDSTRING,
242                             0,
243                             (LPARAM)lpNegSignSamples[nCBIndex]);
244     }
245 
246     /* Set current item to value from registry */
247     nRetCode = SendDlgItemMessageW(hwndDlg, IDC_NUMBERSNSIGNSYM,
248                                    CB_SELECTSTRING,
249                                    -1,
250                                    (LPARAM)pGlobalData->szNumNegativeSign);
251 
252     /* If  it is not successful, add new values to list and select them */
253     if (nRetCode == CB_ERR)
254     {
255         SendDlgItemMessageW(hwndDlg, IDC_NUMBERSNSIGNSYM,
256                             CB_ADDSTRING,
257                             0,
258                             (LPARAM)pGlobalData->szNumNegativeSign);
259         SendDlgItemMessageW(hwndDlg, IDC_NUMBERSNSIGNSYM,
260                             CB_SELECTSTRING,
261                             -1,
262                             (LPARAM)pGlobalData->szNumNegativeSign);
263     }
264 }
265 
266 /* Init negative numbers format control box */
267 static VOID
268 InitNegNumFmtCB(HWND hwndDlg, PGLOBALDATA pGlobalData)
269 {
270     PWSTR pszString1, pszString2;
271     INT nCBIndex;
272 
273     /* Clear all box content */
274     SendDlgItemMessageW(hwndDlg, IDC_NUMBERSNNUMFORMAT,
275                         CB_RESETCONTENT,
276                         (WPARAM)0,
277                         (LPARAM)0);
278 
279     /* Create standard list of negative numbers formats */
280     for (nCBIndex = 0; nCBIndex < MAX_NEG_NUMBERS_SAMPLES; nCBIndex++)
281     {
282         /* Replace standard separator to setted */
283         pszString1 = ReplaceSubStr(lpNegNumFmtSamples[nCBIndex],
284                                    pGlobalData->szNumDecimalSep,
285                                    L",");
286         if (pszString1 != NULL)
287         {
288             /* Replace standard negative sign to setted */
289             pszString2 = ReplaceSubStr(pszString1,
290                                        pGlobalData->szNumNegativeSign,
291                                        L"-");
292             if (pszString2 != NULL)
293             {
294                 SendDlgItemMessageW(hwndDlg, IDC_NUMBERSNNUMFORMAT,
295                                     CB_ADDSTRING,
296                                     0,
297                                     (LPARAM)pszString2);
298 
299                 HeapFree(GetProcessHeap(), 0, pszString2);
300             }
301 
302             HeapFree(GetProcessHeap(), 0, pszString1);
303         }
304     }
305 
306     /* Set current item to value from registry */
307     SendDlgItemMessageW(hwndDlg, IDC_NUMBERSNNUMFORMAT,
308                         CB_SETCURSEL,
309                         (WPARAM)pGlobalData->nNumNegFormat,
310                         (LPARAM)0);
311 }
312 
313 /* Init leading zeroes control box */
314 static VOID
315 InitLeadingZeroesCB(HWND hwndDlg, PGLOBALDATA pGlobalData)
316 {
317     PWSTR pszResultStr;
318     INT nCBIndex;
319 
320     /* Clear all box content */
321     SendDlgItemMessageW(hwndDlg, IDC_NUMBERSDISPLEADZER,
322                         CB_RESETCONTENT,
323                         (WPARAM)0,
324                         (LPARAM)0);
325 
326     /* Create list of standard leading zeroes formats */
327     for (nCBIndex = 0; nCBIndex < MAX_LEAD_ZEROES_SAMPLES; nCBIndex++)
328     {
329         pszResultStr = ReplaceSubStr(lpLeadNumFmtSamples[nCBIndex],
330                                      pGlobalData->szNumDecimalSep,
331                                      L",");
332         if (pszResultStr != NULL)
333         {
334             SendDlgItemMessage(hwndDlg, IDC_NUMBERSDISPLEADZER,
335                                CB_ADDSTRING,
336                                0,
337                                (LPARAM)pszResultStr);
338             HeapFree(GetProcessHeap(), 0, pszResultStr);
339         }
340     }
341 
342     /* Set current item to value from registry */
343     SendDlgItemMessageW(hwndDlg, IDC_NUMBERSDISPLEADZER,
344                         CB_SETCURSEL,
345                         (WPARAM)pGlobalData->nNumLeadingZero,
346                         (LPARAM)0);
347 }
348 
349 static VOID
350 InitListSepCB(HWND hwndDlg,
351               PGLOBALDATA pGlobalData)
352 {
353     INT nCBIndex;
354     INT nRetCode;
355 
356     /* Limit text length */
357     SendDlgItemMessageW(hwndDlg, IDC_NUMBERSLSEP,
358                         CB_LIMITTEXT,
359                         MAX_NUMLISTSEP - 1,
360                         0);
361 
362     /* Clear all box content */
363     SendDlgItemMessageW(hwndDlg, IDC_NUMBERSLSEP,
364                         CB_RESETCONTENT,
365                         (WPARAM)0,
366                         (LPARAM)0);
367 
368     /* Create standard list of signs */
369     for (nCBIndex = 0; nCBIndex < MAX_LIST_SEP_SAMPLES; nCBIndex++)
370     {
371         SendDlgItemMessageW(hwndDlg, IDC_NUMBERSLSEP,
372                             CB_ADDSTRING,
373                             0,
374                             (LPARAM)lpListSepSamples[nCBIndex]);
375     }
376 
377     /* Set current item to value from registry */
378     nRetCode = SendDlgItemMessageW(hwndDlg, IDC_NUMBERSLSEP,
379                                    CB_SELECTSTRING,
380                                    -1,
381                                    (LPARAM)pGlobalData->szNumListSep);
382 
383     /* If it is not successful, add new values to list and select them */
384     if (nRetCode == CB_ERR)
385     {
386         SendDlgItemMessageW(hwndDlg, IDC_NUMBERSLSEP,
387                             CB_ADDSTRING,
388                             0,
389                             (LPARAM)pGlobalData->szNumListSep);
390         SendDlgItemMessageW(hwndDlg, IDC_NUMBERSLSEP,
391                             CB_SELECTSTRING,
392                             -1,
393                             (LPARAM)pGlobalData->szNumListSep);
394     }
395 }
396 
397 /* Init system of units control box */
398 static VOID
399 InitUnitsSysCB(HWND hwndDlg,
400                PGLOBALDATA pGlobalData)
401 {
402     WCHAR szUnitName[128];
403     INT nCBIndex;
404 
405     /* Clear all box content */
406     SendDlgItemMessageW(hwndDlg, IDC_NUMBERSMEASSYS,
407                         CB_RESETCONTENT,
408                         (WPARAM)0,
409                         (LPARAM)0);
410 
411     /* Create list of standard system of units */
412     for (nCBIndex = 0; nCBIndex < MAX_UNITS_SYS_SAMPLES; nCBIndex++)
413     {
414         LoadStringW(hApplet, IDS_METRIC + nCBIndex, szUnitName, 128);
415 
416         SendDlgItemMessageW(hwndDlg, IDC_NUMBERSMEASSYS,
417                             CB_ADDSTRING,
418                             0,
419                             (LPARAM)szUnitName);
420     }
421 
422     /* Set current item to value from registry */
423     SendDlgItemMessageW(hwndDlg, IDC_NUMBERSMEASSYS,
424                         CB_SETCURSEL,
425                         (WPARAM)pGlobalData->nNumMeasure,
426                         (LPARAM)0);
427 }
428 
429 /* Update all numbers locale samples */
430 static VOID
431 UpdateNumSamples(HWND hwndDlg,
432                  PGLOBALDATA pGlobalData)
433 {
434     WCHAR OutBuffer[MAX_FMT_SIZE];
435     NUMBERFMT NumberFormat;
436 
437     NumberFormat.NumDigits = pGlobalData->nNumDigits;
438     NumberFormat.LeadingZero = pGlobalData->nNumLeadingZero;
439     NumberFormat.Grouping = GroupingFormats[pGlobalData->nNumGrouping].nInteger;
440     NumberFormat.lpDecimalSep = pGlobalData->szNumDecimalSep;
441     NumberFormat.lpThousandSep = pGlobalData->szNumThousandSep;
442     NumberFormat.NegativeOrder = pGlobalData->nNumNegFormat;
443 
444     /* Get positive number format sample */
445     GetNumberFormatW(pGlobalData->UserLCID,
446                      0,
447                      SAMPLE_NUMBER,
448                      &NumberFormat,
449                      OutBuffer,
450                      MAX_FMT_SIZE);
451 
452     SendDlgItemMessageW(hwndDlg, IDC_NUMBERSPOSSAMPLE,
453                         WM_SETTEXT,
454                         0,
455                         (LPARAM)OutBuffer);
456 
457     /* Get positive number format sample */
458     GetNumberFormatW(pGlobalData->UserLCID,
459                      0,
460                      SAMPLE_NEG_NUMBER,
461                      &NumberFormat,
462                      OutBuffer,
463                      MAX_FMT_SIZE);
464 
465     SendDlgItemMessageW(hwndDlg, IDC_NUMBERSNEGSAMPLE,
466                         WM_SETTEXT,
467                         0,
468                         (LPARAM)OutBuffer);
469 }
470 
471 
472 static
473 BOOL
474 GetNumberSetting(
475     HWND hwndDlg,
476     PGLOBALDATA pGlobalData)
477 {
478     WCHAR szNumDecimalSep[MAX_NUMDECIMALSEP];
479     WCHAR szNumThousandSep[MAX_NUMTHOUSANDSEP];
480     WCHAR szNumNegativeSign[MAX_NUMNEGATIVESIGN];
481     WCHAR szNumListSep[MAX_NUMLISTSEP];
482     INT nNumDigits;
483     INT nNumGrouping;
484     INT nNumNegFormat;
485     INT nNumLeadingZero;
486     INT nNumMeasure;
487 
488     /* Decimal symbol */
489     GetSelectedComboBoxText(hwndDlg,
490                             IDC_NUMBERDSYMBOL,
491                             szNumDecimalSep,
492                             MAX_NUMDECIMALSEP);
493 
494     if (szNumDecimalSep[0] == L'\0')
495     {
496         /* TODO: Show error message */
497 
498         return FALSE;
499     }
500 
501     /* Number of digits after decimal */
502     GetSelectedComboBoxIndex(hwndDlg,
503                              IDC_NUMBERSNDIGDEC,
504                              &nNumDigits);
505 
506     /* Digit grouping symbol */
507     GetSelectedComboBoxText(hwndDlg,
508                             IDC_NUMBERSDIGITGRSYM,
509                             szNumThousandSep,
510                             MAX_NUMTHOUSANDSEP);
511 
512     if (szNumThousandSep[0] == L'\0')
513     {
514         /* TODO: Show error message */
515 
516         return FALSE;
517     }
518 
519     /* Digit grouping */
520     GetSelectedComboBoxIndex(hwndDlg,
521                              IDC_NUMBERSDGROUPING,
522                              &nNumGrouping);
523 
524     /* Negative sign symbol */
525     GetSelectedComboBoxText(hwndDlg,
526                             IDC_NUMBERSNSIGNSYM,
527                             szNumNegativeSign,
528                             MAX_NUMNEGATIVESIGN);
529 
530     if (szNumNegativeSign[0] == L'\0')
531     {
532         /* TODO: Show error message */
533 
534         return FALSE;
535     }
536 
537     /* Negative number format */
538     GetSelectedComboBoxIndex(hwndDlg,
539                              IDC_NUMBERSNNUMFORMAT,
540                              &nNumNegFormat);
541 
542     /* Display leading zeros */
543     GetSelectedComboBoxIndex(hwndDlg,
544                              IDC_NUMBERSDISPLEADZER,
545                              &nNumLeadingZero);
546 
547     /* List separator */
548     GetSelectedComboBoxText(hwndDlg,
549                             IDC_NUMBERSLSEP,
550                             szNumListSep,
551                             MAX_NUMLISTSEP);
552 
553     if (szNumListSep[0] == L'\0')
554     {
555         /* TODO: Show error message */
556 
557         return FALSE;
558     }
559 
560     /* Measurement system */
561     GetSelectedComboBoxIndex(hwndDlg,
562                              IDC_NUMBERSMEASSYS,
563                              &nNumMeasure);
564 
565     /* Store settings in global data */
566     wcscpy(pGlobalData->szNumDecimalSep, szNumDecimalSep);
567     wcscpy(pGlobalData->szNumThousandSep, szNumThousandSep);
568     wcscpy(pGlobalData->szNumNegativeSign, szNumNegativeSign);
569     wcscpy(pGlobalData->szNumListSep, szNumListSep);
570     pGlobalData->nNumGrouping = nNumGrouping;
571     pGlobalData->nNumDigits = nNumDigits;
572     pGlobalData->nNumNegFormat = nNumNegFormat;
573     pGlobalData->nNumLeadingZero = nNumLeadingZero;
574     pGlobalData->nNumMeasure = nNumMeasure;
575 
576     return TRUE;
577 }
578 
579 /* Property page dialog callback */
580 INT_PTR CALLBACK
581 NumbersPageProc(HWND hwndDlg,
582                 UINT uMsg,
583                 WPARAM wParam,
584                 LPARAM lParam)
585 {
586     PGLOBALDATA pGlobalData;
587 
588     pGlobalData = (PGLOBALDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
589 
590     switch (uMsg)
591     {
592         case WM_INITDIALOG:
593             pGlobalData = (PGLOBALDATA)((LPPROPSHEETPAGE)lParam)->lParam;
594             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pGlobalData);
595 
596             InitNumDecimalSepCB(hwndDlg, pGlobalData);
597             InitNumOfFracSymbCB(hwndDlg, pGlobalData);
598             InitNumFieldSepCB(hwndDlg, pGlobalData);
599             InitFieldDigNumCB(hwndDlg, pGlobalData);
600             InitNegSignCB(hwndDlg, pGlobalData);
601             InitNegNumFmtCB(hwndDlg, pGlobalData);
602             InitLeadingZeroesCB(hwndDlg, pGlobalData);
603             InitListSepCB(hwndDlg, pGlobalData);
604             InitUnitsSysCB(hwndDlg, pGlobalData);
605             UpdateNumSamples(hwndDlg, pGlobalData);
606             break;
607 
608         case WM_COMMAND:
609             switch (LOWORD(wParam))
610             {
611                 case IDC_NUMBERDSYMBOL:
612                 case IDC_NUMBERSNDIGDEC:
613                 case IDC_NUMBERSDIGITGRSYM:
614                 case IDC_NUMBERSDGROUPING:
615                 case IDC_NUMBERSNSIGNSYM:
616                 case IDC_NUMBERSNNUMFORMAT:
617                 case IDC_NUMBERSDISPLEADZER:
618                 case IDC_NUMBERSLSEP:
619                 case IDC_NUMBERSMEASSYS:
620                     if (HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == CBN_EDITCHANGE)
621                     {
622                         /* Enable the Apply button */
623                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
624                     }
625             }
626             break;
627 
628         case WM_NOTIFY:
629             if (((LPNMHDR)lParam)->code == (UINT)PSN_APPLY)
630             {
631                 if (GetNumberSetting(hwndDlg, pGlobalData))
632                 {
633                     pGlobalData->bUserLocaleChanged = TRUE;
634                     UpdateNumSamples(hwndDlg, pGlobalData);
635                 }
636             }
637             break;
638     }
639     return FALSE;
640 }
641 
642 /* EOF */
643