ReactOS  0.4.14-dev-358-gbef841c
currency.c
Go to the documentation of this file.
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,
51  &CurrencyFormat, szBuffer, MAX_FMT_SIZE);
52 
54 
55  /* Negative example */
56  GetCurrencyFormatW(pGlobalData->UserLCID, 0,
58  &CurrencyFormat, szBuffer, MAX_FMT_SIZE);
59 
61 }
62 
63 
64 static VOID
65 InitCurrencySymbols(HWND hwndDlg, PGLOBALDATA pGlobalData)
66 {
67  /* Limit text length */
70  MAX_CURRSYMBOL - 1,
71  0);
72 
73  /* Set currency symbols */
76  0,
77  (LPARAM)pGlobalData->szCurrSymbol);
78 
81  0, /* Index */
82  0);
83 }
84 
85 
86 static VOID
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 
111  -1,
112  (LPARAM)szBuffer);
113  }
114 
116  CB_SETCURSEL,
117  pGlobalData->nCurrPosFormat,
118  0);
119 }
120 
121 
122 static VOID
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 
147  -1,
148  (LPARAM)szBuffer);
149  }
150 
152  CB_SETCURSEL,
153  pGlobalData->nCurrNegFormat,
154  0);
155 }
156 
157 
158 static VOID
160 {
161  /* Limit text length */
163  CB_LIMITTEXT,
164  MAX_CURRDECIMALSEP - 1,
165  0);
166 
167  /* Decimal separator */
169  CB_ADDSTRING,
170  0,
171  (LPARAM)pGlobalData->szCurrDecimalSep);
172 
174  CB_SETCURSEL,
175  0, /* Index */
176  0);
177 }
178 
179 
180 /* Initialize the number of fractional digits */
181 static VOID
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;
193  CB_ADDSTRING,
194  0,
195  (LPARAM)szBuffer);
196  }
197 
199  CB_SETCURSEL,
200  pGlobalData->nCurrDigits,
201  0);
202 }
203 
204 
205 /* Initialize the list of group separators */
206 static VOID
208 {
209  /* Limit text length */
211  CB_LIMITTEXT,
213  0);
214 
215  /* Digit group separator */
217  CB_ADDSTRING,
218  0,
219  (LPARAM)pGlobalData->szCurrThousandSep);
220 
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  {
247 
248  GetCurrencyFormatW(pGlobalData->UserLCID, 0,
249  L"123456789",
250  &cyFmt, szBuffer, MAX_FMT_SIZE);
253  -1,
254  (LPARAM)szBuffer);
255  }
256 
258  CB_SETCURSEL,
259  pGlobalData->nCurrGrouping,
260  0);
261 }
262 
263 
264 static
265 BOOL
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,
281  szCurrSymbol,
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,
294  &nCurrPosFormat);
295 
296  /* Negative Amount */
297  GetSelectedComboBoxIndex(hwndDlg,
299  &nCurrNegFormat);
300 
301  /* Decimal separator */
302  GetSelectedComboBoxText(hwndDlg,
304  szCurrDecimalSep,
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,
317  &nCurrDigits);
318 
319  /* Grouping symbol */
320  GetSelectedComboBoxText(hwndDlg,
322  szCurrThousandSep,
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,
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 */
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:
382  case IDC_CURRENCYDECSEP:
383  case IDC_CURRENCYDECNUM:
384  case IDC_CURRENCYGRPSEP:
385  case IDC_CURRENCYGRPNUM:
386  if (HIWORD(wParam) == CBN_SELCHANGE ||
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 */
static VOID InitCurrencyNumFracDigits(HWND hwndDlg, PGLOBALDATA pGlobalData)
Definition: currency.c:182
struct _GLOBALDATA * PGLOBALDATA
WCHAR szCurrSymbol[MAX_CURRSYMBOL]
Definition: intl.h:81
static VOID UpdateExamples(HWND hwndDlg, PGLOBALDATA pGlobalData)
Definition: currency.c:34
VOID GetSelectedComboBoxText(HWND hwndDlg, INT nIdDlgItem, PWSTR Buffer, UINT uSize)
Definition: misc.c:176
static VOID InitCurrencyPositiveFormats(HWND hwndDlg, PGLOBALDATA pGlobalData)
Definition: currency.c:87
#define TRUE
Definition: types.h:120
UINT PositiveOrder
Definition: winnls.h:615
UINT Grouping
Definition: winnls.h:611
VOID GetSelectedComboBoxIndex(HWND hwndDlg, INT nIdDlgItem, PINT pValue)
Definition: misc.c:223
UINT NegativeOrder
Definition: winnls.h:614
UINT LeadingZero
Definition: winnls.h:610
INT WINAPI GetCurrencyFormatW(LCID lcid, DWORD dwFlags, LPCWSTR lpszValue, const CURRENCYFMTW *lpFormat, LPWSTR lpCurrencyStr, int cchOut)
Definition: lcformat.c:1564
#define IDC_CURRENCYGRPSEP
Definition: resource.h:32
INT nCurrNegFormat
Definition: intl.h:85
#define CALLBACK
Definition: compat.h:27
static VOID InitDigitGroupCB(HWND hwndDlg, PGLOBALDATA pGlobalData)
Definition: currency.c:229
UINT_PTR WPARAM
Definition: windef.h:207
LPWSTR lpThousandSep
Definition: winnls.h:613
#define PSN_APPLY
Definition: prsht.h:117
int32_t INT_PTR
Definition: typedefs.h:62
int32_t INT
Definition: typedefs.h:56
#define SetWindowLongPtr
Definition: treelist.c:70
WPARAM wParam
Definition: combotst.c:138
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int BOOL
Definition: ntddk_ex.h:94
static VOID InitCurrencySymbols(HWND hwndDlg, PGLOBALDATA pGlobalData)
Definition: currency.c:65
#define CB_ADDSTRING
Definition: winuser.h:1918
#define CB_INSERTSTRING
Definition: winuser.h:1939
#define LPPROPSHEETPAGE
Definition: prsht.h:372
INT nNumLeadingZero
Definition: intl.h:75
INT_PTR CALLBACK CurrencyPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: currency.c:351
LONG_PTR LPARAM
Definition: windef.h:208
#define CB_LIMITTEXT
Definition: winuser.h:1940
WCHAR szCurrDecimalSep[MAX_CURRDECIMALSEP]
Definition: intl.h:82
#define WM_SETTEXT
Definition: winuser.h:1599
INT nCurrGrouping
Definition: intl.h:87
#define IDC_CURRENCYPOSSAMPLE
Definition: resource.h:25
#define CBN_EDITCHANGE
Definition: winuser.h:1957
#define MAX_CURRSYMBOL
Definition: intl.h:33
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define PropSheet_Changed(d, w)
Definition: prsht.h:326
#define MAX_GROUPINGFORMATS
Definition: intl.h:51
#define IDC_CURRENCYGRPNUM
Definition: resource.h:33
#define IDC_CURRENCYNEGSAMPLE
Definition: resource.h:26
LRESULT WINAPI SendDlgItemMessageW(_In_ HWND, _In_ int, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
static BOOL GetCurrencySetting(HWND hwndDlg, PGLOBALDATA pGlobalData)
Definition: currency.c:266
#define IDC_CURRENCYNEGVALUE
Definition: resource.h:29
static VOID InitCurrencyDecimalSeparators(HWND hwndDlg, PGLOBALDATA pGlobalData)
Definition: currency.c:159
GROUPINGDATA GroupingFormats[MAX_GROUPINGFORMATS]
Definition: generalp.c:44
LPWSTR lpDecimalSep
Definition: winnls.h:612
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define IDC_CURRENCYDECNUM
Definition: resource.h:31
static const WCHAR L[]
Definition: oid.c:1250
#define DWLP_USER
Definition: winuser.h:866
WCHAR szCurrThousandSep[MAX_CURRTHOUSANDSEP]
Definition: intl.h:83
#define CB_SETCURSEL
Definition: winuser.h:1943
#define POSITIVE_EXAMPLE
Definition: currency.c:29
#define WM_COMMAND
Definition: winuser.h:1722
#define MAX_FMT_SIZE
Definition: intl.h:22
#define NEGATIVE_EXAMPLE
Definition: currency.c:30
#define IDC_CURRENCYSYMBOL
Definition: resource.h:27
#define IDC_CURRENCYPOSVALUE
Definition: resource.h:28
LPWSTR lpCurrencySymbol
Definition: winnls.h:616
HWND WINAPI GetParent(_In_ HWND)
static VOID InitCurrencyNegativeFormats(HWND hwndDlg, PGLOBALDATA pGlobalData)
Definition: currency.c:123
INT nCurrPosFormat
Definition: intl.h:84
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
#define IDC_CURRENCYDECSEP
Definition: resource.h:30
#define CBN_SELCHANGE
Definition: winuser.h:1961
#define MAX_CURRTHOUSANDSEP
Definition: intl.h:35
UINT NumDigits
Definition: winnls.h:609
#define MAX_CURRDECIMALSEP
Definition: intl.h:34
#define HIWORD(l)
Definition: typedefs.h:246
INT nCurrDigits
Definition: intl.h:86
#define GetWindowLongPtr
Definition: treelist.c:73
UINT nInteger
Definition: intl.h:127
#define WM_INITDIALOG
Definition: winuser.h:1721
LPARAM lParam
Definition: combotst.c:139
#define LOWORD(l)
Definition: pedump.c:82
#define WM_NOTIFY
Definition: richedit.h:61
LCID UserLCID
Definition: intl.h:113
static VOID InitCurrencyGroupSeparators(HWND hwndDlg, PGLOBALDATA pGlobalData)
Definition: currency.c:207