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