1*c2c66affSColin Finck /*
2*c2c66affSColin Finck * ReactOS
3*c2c66affSColin Finck * Copyright (C) 2004 ReactOS Team
4*c2c66affSColin Finck *
5*c2c66affSColin Finck * This program is free software; you can redistribute it and/or modify
6*c2c66affSColin Finck * it under the terms of the GNU General Public License as published by
7*c2c66affSColin Finck * the Free Software Foundation; either version 2 of the License, or
8*c2c66affSColin Finck * (at your option) any later version.
9*c2c66affSColin Finck *
10*c2c66affSColin Finck * This program is distributed in the hope that it will be useful,
11*c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
12*c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13*c2c66affSColin Finck * GNU General Public License for more details.
14*c2c66affSColin Finck *
15*c2c66affSColin Finck * You should have received a copy of the GNU General Public License along
16*c2c66affSColin Finck * with this program; if not, write to the Free Software Foundation, Inc.,
17*c2c66affSColin Finck * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18*c2c66affSColin Finck */
19*c2c66affSColin Finck /*
20*c2c66affSColin Finck * PROJECT: ReactOS International Control Panel
21*c2c66affSColin Finck * FILE: dll/cpl/intl/date.c
22*c2c66affSColin Finck * PURPOSE: Date property page
23*c2c66affSColin Finck * PROGRAMMERS: Eric Kohl
24*c2c66affSColin Finck * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
25*c2c66affSColin Finck */
26*c2c66affSColin Finck
27*c2c66affSColin Finck #include "intl.h"
28*c2c66affSColin Finck
29*c2c66affSColin Finck /* GLOBALS ******************************************************************/
30*c2c66affSColin Finck
31*c2c66affSColin Finck #define YEAR_STR_MAX_SIZE 5
32*c2c66affSColin Finck #define MAX_SHRT_DATE_SEPARATORS 3
33*c2c66affSColin Finck #define STD_DATE_SEP L"."
34*c2c66affSColin Finck #define YEAR_DIFF (99)
35*c2c66affSColin Finck #define MAX_YEAR (9999)
36*c2c66affSColin Finck
37*c2c66affSColin Finck static HWND hwndEnum = NULL;
38*c2c66affSColin Finck
39*c2c66affSColin Finck /* FUNCTIONS ****************************************************************/
40*c2c66affSColin Finck
41*c2c66affSColin Finck /* If char is 'y' or 'M' or 'd' return TRUE, else FALSE */
42*c2c66affSColin Finck BOOL
isDateCompAl(WCHAR alpha)43*c2c66affSColin Finck isDateCompAl(WCHAR alpha)
44*c2c66affSColin Finck {
45*c2c66affSColin Finck if ((alpha == L'y') || (alpha == L'M') || (alpha == L'd') || (alpha == L' '))
46*c2c66affSColin Finck return TRUE;
47*c2c66affSColin Finck else
48*c2c66affSColin Finck return FALSE;
49*c2c66affSColin Finck }
50*c2c66affSColin Finck
51*c2c66affSColin Finck /* Find first date separator in string */
52*c2c66affSColin Finck LPTSTR
FindDateSep(const WCHAR * szSourceStr)53*c2c66affSColin Finck FindDateSep(const WCHAR *szSourceStr)
54*c2c66affSColin Finck {
55*c2c66affSColin Finck PWSTR pszFoundSep;
56*c2c66affSColin Finck UINT nDateCompCount=0;
57*c2c66affSColin Finck UINT nDateSepCount=0;
58*c2c66affSColin Finck
59*c2c66affSColin Finck pszFoundSep = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, MAX_SAMPLES_STR_SIZE * sizeof(WCHAR));
60*c2c66affSColin Finck if (pszFoundSep == NULL)
61*c2c66affSColin Finck return NULL;
62*c2c66affSColin Finck
63*c2c66affSColin Finck wcscpy(pszFoundSep,STD_DATE_SEP);
64*c2c66affSColin Finck
65*c2c66affSColin Finck while (nDateCompCount < wcslen(szSourceStr))
66*c2c66affSColin Finck {
67*c2c66affSColin Finck if (!isDateCompAl(szSourceStr[nDateCompCount]) && (szSourceStr[nDateCompCount] != L'\''))
68*c2c66affSColin Finck {
69*c2c66affSColin Finck while (!isDateCompAl(szSourceStr[nDateCompCount]) && (szSourceStr[nDateCompCount] != L'\''))
70*c2c66affSColin Finck {
71*c2c66affSColin Finck pszFoundSep[nDateSepCount++] = szSourceStr[nDateCompCount];
72*c2c66affSColin Finck nDateCompCount++;
73*c2c66affSColin Finck }
74*c2c66affSColin Finck
75*c2c66affSColin Finck pszFoundSep[nDateSepCount] = L'\0';
76*c2c66affSColin Finck return pszFoundSep;
77*c2c66affSColin Finck }
78*c2c66affSColin Finck
79*c2c66affSColin Finck nDateCompCount++;
80*c2c66affSColin Finck }
81*c2c66affSColin Finck
82*c2c66affSColin Finck return pszFoundSep;
83*c2c66affSColin Finck }
84*c2c66affSColin Finck
85*c2c66affSColin Finck /* Replace given template in source string with string to replace and return received string */
86*c2c66affSColin Finck
87*c2c66affSColin Finck
88*c2c66affSColin Finck /* Setted up short date separator to registry */
89*c2c66affSColin Finck static BOOL
SetShortDateSep(HWND hwndDlg,PWSTR pszShortDateSep)90*c2c66affSColin Finck SetShortDateSep(HWND hwndDlg, PWSTR pszShortDateSep)
91*c2c66affSColin Finck {
92*c2c66affSColin Finck INT nSepStrSize;
93*c2c66affSColin Finck INT nSepCount;
94*c2c66affSColin Finck
95*c2c66affSColin Finck /* Get separator */
96*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_SHRTDATESEP_COMBO,
97*c2c66affSColin Finck WM_GETTEXT,
98*c2c66affSColin Finck (WPARAM)MAX_SAMPLES_STR_SIZE,
99*c2c66affSColin Finck (LPARAM)pszShortDateSep);
100*c2c66affSColin Finck
101*c2c66affSColin Finck /* Get separator string size */
102*c2c66affSColin Finck nSepStrSize = wcslen(pszShortDateSep);
103*c2c66affSColin Finck
104*c2c66affSColin Finck /* Check date components */
105*c2c66affSColin Finck for (nSepCount = 0; nSepCount < nSepStrSize; nSepCount++)
106*c2c66affSColin Finck {
107*c2c66affSColin Finck if (iswalnum(pszShortDateSep[nSepCount]) || (pszShortDateSep[nSepCount] == L'\''))
108*c2c66affSColin Finck {
109*c2c66affSColin Finck PrintErrorMsgBox(IDS_ERROR_SYMBOL_SEPARATE);
110*c2c66affSColin Finck return FALSE;
111*c2c66affSColin Finck }
112*c2c66affSColin Finck }
113*c2c66affSColin Finck
114*c2c66affSColin Finck if (nSepStrSize == 0)
115*c2c66affSColin Finck {
116*c2c66affSColin Finck PrintErrorMsgBox(IDS_ERROR_SYMBOL_SEPARATE);
117*c2c66affSColin Finck return FALSE;
118*c2c66affSColin Finck }
119*c2c66affSColin Finck
120*c2c66affSColin Finck return TRUE;
121*c2c66affSColin Finck }
122*c2c66affSColin Finck
123*c2c66affSColin Finck /* Setted up short date format to registry */
124*c2c66affSColin Finck static BOOL
SetShortDateFormat(HWND hwndDlg,PWSTR pszShortDateFmt)125*c2c66affSColin Finck SetShortDateFormat(HWND hwndDlg, PWSTR pszShortDateFmt)
126*c2c66affSColin Finck {
127*c2c66affSColin Finck WCHAR szShortDateSep[MAX_SAMPLES_STR_SIZE];
128*c2c66affSColin Finck WCHAR szFoundDateSep[MAX_SAMPLES_STR_SIZE];
129*c2c66affSColin Finck PWSTR pszResultStr;
130*c2c66affSColin Finck PWSTR pszFoundSep;
131*c2c66affSColin Finck BOOL OpenApostFlg = FALSE;
132*c2c66affSColin Finck INT nFmtStrSize;
133*c2c66affSColin Finck INT nDateCompCount;
134*c2c66affSColin Finck
135*c2c66affSColin Finck /* Get format */
136*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_SHRTDATEFMT_COMBO,
137*c2c66affSColin Finck WM_GETTEXT,
138*c2c66affSColin Finck (WPARAM)MAX_SAMPLES_STR_SIZE,
139*c2c66affSColin Finck (LPARAM)pszShortDateFmt);
140*c2c66affSColin Finck
141*c2c66affSColin Finck /* Get separator */
142*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_SHRTDATESEP_COMBO,
143*c2c66affSColin Finck WM_GETTEXT,
144*c2c66affSColin Finck (WPARAM)MAX_SAMPLES_STR_SIZE,
145*c2c66affSColin Finck (LPARAM)szShortDateSep);
146*c2c66affSColin Finck
147*c2c66affSColin Finck /* Get format-string size */
148*c2c66affSColin Finck nFmtStrSize = wcslen(pszShortDateFmt);
149*c2c66affSColin Finck
150*c2c66affSColin Finck /* Check date components */
151*c2c66affSColin Finck for (nDateCompCount = 0; nDateCompCount < nFmtStrSize; nDateCompCount++)
152*c2c66affSColin Finck {
153*c2c66affSColin Finck if (pszShortDateFmt[nDateCompCount] == L'\'')
154*c2c66affSColin Finck {
155*c2c66affSColin Finck OpenApostFlg = !OpenApostFlg;
156*c2c66affSColin Finck }
157*c2c66affSColin Finck
158*c2c66affSColin Finck if (iswalnum(pszShortDateFmt[nDateCompCount]) &&
159*c2c66affSColin Finck !isDateCompAl(pszShortDateFmt[nDateCompCount]) &&
160*c2c66affSColin Finck !OpenApostFlg)
161*c2c66affSColin Finck {
162*c2c66affSColin Finck PrintErrorMsgBox(IDS_ERROR_SYMBOL_FORMAT_SHORT);
163*c2c66affSColin Finck return FALSE;
164*c2c66affSColin Finck }
165*c2c66affSColin Finck }
166*c2c66affSColin Finck
167*c2c66affSColin Finck if (OpenApostFlg || nFmtStrSize == 0)
168*c2c66affSColin Finck {
169*c2c66affSColin Finck PrintErrorMsgBox(IDS_ERROR_SYMBOL_FORMAT_SHORT);
170*c2c66affSColin Finck return FALSE;
171*c2c66affSColin Finck }
172*c2c66affSColin Finck
173*c2c66affSColin Finck pszFoundSep = FindDateSep(pszShortDateFmt);
174*c2c66affSColin Finck if (pszFoundSep != NULL)
175*c2c66affSColin Finck {
176*c2c66affSColin Finck /* Substring replacement of separator */
177*c2c66affSColin Finck wcscpy(szFoundDateSep, pszFoundSep);
178*c2c66affSColin Finck pszResultStr = ReplaceSubStr(pszShortDateFmt, szShortDateSep, szFoundDateSep);
179*c2c66affSColin Finck if (pszResultStr != NULL)
180*c2c66affSColin Finck {
181*c2c66affSColin Finck wcscpy(pszShortDateFmt, pszResultStr);
182*c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, pszResultStr);
183*c2c66affSColin Finck }
184*c2c66affSColin Finck
185*c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, pszFoundSep);
186*c2c66affSColin Finck }
187*c2c66affSColin Finck
188*c2c66affSColin Finck return TRUE;
189*c2c66affSColin Finck }
190*c2c66affSColin Finck
191*c2c66affSColin Finck /* Setted up long date format to registry */
192*c2c66affSColin Finck static BOOL
SetLongDateFormat(HWND hwndDlg,PWSTR pszLongDateFmt)193*c2c66affSColin Finck SetLongDateFormat(HWND hwndDlg, PWSTR pszLongDateFmt)
194*c2c66affSColin Finck {
195*c2c66affSColin Finck BOOL OpenApostFlg = FALSE;
196*c2c66affSColin Finck INT nFmtStrSize;
197*c2c66affSColin Finck INT nDateCompCount;
198*c2c66affSColin Finck
199*c2c66affSColin Finck /* Get format */
200*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_LONGDATEFMT_COMBO,
201*c2c66affSColin Finck WM_GETTEXT,
202*c2c66affSColin Finck (WPARAM)MAX_SAMPLES_STR_SIZE,
203*c2c66affSColin Finck (LPARAM)pszLongDateFmt);
204*c2c66affSColin Finck
205*c2c66affSColin Finck /* Get format string size */
206*c2c66affSColin Finck nFmtStrSize = wcslen(pszLongDateFmt);
207*c2c66affSColin Finck
208*c2c66affSColin Finck /* Check date components */
209*c2c66affSColin Finck for (nDateCompCount = 0; nDateCompCount < nFmtStrSize; nDateCompCount++)
210*c2c66affSColin Finck {
211*c2c66affSColin Finck if (pszLongDateFmt[nDateCompCount] == L'\'')
212*c2c66affSColin Finck {
213*c2c66affSColin Finck OpenApostFlg = !OpenApostFlg;
214*c2c66affSColin Finck }
215*c2c66affSColin Finck
216*c2c66affSColin Finck if (iswalnum(pszLongDateFmt[nDateCompCount]) &&
217*c2c66affSColin Finck !isDateCompAl(pszLongDateFmt[nDateCompCount]) &&
218*c2c66affSColin Finck !OpenApostFlg)
219*c2c66affSColin Finck {
220*c2c66affSColin Finck PrintErrorMsgBox(IDS_ERROR_SYMBOL_FORMAT_LONG);
221*c2c66affSColin Finck return FALSE;
222*c2c66affSColin Finck }
223*c2c66affSColin Finck }
224*c2c66affSColin Finck
225*c2c66affSColin Finck if (OpenApostFlg || nFmtStrSize == 0)
226*c2c66affSColin Finck {
227*c2c66affSColin Finck PrintErrorMsgBox(IDS_ERROR_SYMBOL_FORMAT_LONG);
228*c2c66affSColin Finck return FALSE;
229*c2c66affSColin Finck }
230*c2c66affSColin Finck
231*c2c66affSColin Finck return TRUE;
232*c2c66affSColin Finck }
233*c2c66affSColin Finck
234*c2c66affSColin Finck /* Init short date separator control box */
235*c2c66affSColin Finck static VOID
InitShortDateSepSamples(HWND hwndDlg,PGLOBALDATA pGlobalData)236*c2c66affSColin Finck InitShortDateSepSamples(HWND hwndDlg, PGLOBALDATA pGlobalData)
237*c2c66affSColin Finck {
238*c2c66affSColin Finck PWSTR ShortDateSepSamples[MAX_SHRT_DATE_SEPARATORS] =
239*c2c66affSColin Finck {
240*c2c66affSColin Finck L".",
241*c2c66affSColin Finck L"/",
242*c2c66affSColin Finck L"-"
243*c2c66affSColin Finck };
244*c2c66affSColin Finck INT nCBIndex;
245*c2c66affSColin Finck INT nRetCode;
246*c2c66affSColin Finck
247*c2c66affSColin Finck /* Clear all box content */
248*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_SHRTDATESEP_COMBO,
249*c2c66affSColin Finck CB_RESETCONTENT,
250*c2c66affSColin Finck (WPARAM)0,
251*c2c66affSColin Finck (LPARAM)0);
252*c2c66affSColin Finck
253*c2c66affSColin Finck /* Create standard list of separators */
254*c2c66affSColin Finck for (nCBIndex = 0; nCBIndex < MAX_SHRT_DATE_SEPARATORS; nCBIndex++)
255*c2c66affSColin Finck {
256*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_SHRTDATESEP_COMBO,
257*c2c66affSColin Finck CB_ADDSTRING,
258*c2c66affSColin Finck 0,
259*c2c66affSColin Finck (LPARAM)ShortDateSepSamples[nCBIndex]);
260*c2c66affSColin Finck }
261*c2c66affSColin Finck
262*c2c66affSColin Finck /* Set current item to value from registry */
263*c2c66affSColin Finck nRetCode = SendDlgItemMessageW(hwndDlg, IDC_SHRTDATESEP_COMBO,
264*c2c66affSColin Finck CB_SELECTSTRING,
265*c2c66affSColin Finck -1,
266*c2c66affSColin Finck (LPARAM)pGlobalData->szDateSep);
267*c2c66affSColin Finck
268*c2c66affSColin Finck /* If it is not successful, add new value to list and select them */
269*c2c66affSColin Finck if (nRetCode == CB_ERR)
270*c2c66affSColin Finck {
271*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_SHRTDATESEP_COMBO,
272*c2c66affSColin Finck CB_ADDSTRING,
273*c2c66affSColin Finck 0,
274*c2c66affSColin Finck (LPARAM)pGlobalData->szDateSep);
275*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_SHRTDATESEP_COMBO,
276*c2c66affSColin Finck CB_SELECTSTRING,
277*c2c66affSColin Finck -1,
278*c2c66affSColin Finck (LPARAM)pGlobalData->szDateSep);
279*c2c66affSColin Finck }
280*c2c66affSColin Finck }
281*c2c66affSColin Finck
282*c2c66affSColin Finck static BOOL CALLBACK
ShortDateFormatEnumProc(PWSTR lpTimeFormatString)283*c2c66affSColin Finck ShortDateFormatEnumProc(PWSTR lpTimeFormatString)
284*c2c66affSColin Finck {
285*c2c66affSColin Finck SendMessageW(hwndEnum,
286*c2c66affSColin Finck CB_ADDSTRING,
287*c2c66affSColin Finck 0,
288*c2c66affSColin Finck (LPARAM)lpTimeFormatString);
289*c2c66affSColin Finck
290*c2c66affSColin Finck return TRUE;
291*c2c66affSColin Finck }
292*c2c66affSColin Finck
293*c2c66affSColin Finck /* Init short date control box */
294*c2c66affSColin Finck VOID
InitShortDateCB(HWND hwndDlg,PGLOBALDATA pGlobalData)295*c2c66affSColin Finck InitShortDateCB(HWND hwndDlg, PGLOBALDATA pGlobalData)
296*c2c66affSColin Finck {
297*c2c66affSColin Finck INT nRetCode;
298*c2c66affSColin Finck
299*c2c66affSColin Finck /* Limit text lengths */
300*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_SHRTDATEFMT_COMBO,
301*c2c66affSColin Finck CB_LIMITTEXT,
302*c2c66affSColin Finck MAX_SHORTDATEFORMAT,
303*c2c66affSColin Finck 0);
304*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_SHRTDATESEP_COMBO,
305*c2c66affSColin Finck CB_LIMITTEXT,
306*c2c66affSColin Finck MAX_DATESEPARATOR,
307*c2c66affSColin Finck 0);
308*c2c66affSColin Finck
309*c2c66affSColin Finck /* Clear all box content */
310*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_SHRTDATEFMT_COMBO,
311*c2c66affSColin Finck CB_RESETCONTENT,
312*c2c66affSColin Finck (WPARAM)0,
313*c2c66affSColin Finck (LPARAM)0);
314*c2c66affSColin Finck
315*c2c66affSColin Finck /* Enumerate short date formats */
316*c2c66affSColin Finck hwndEnum = GetDlgItem(hwndDlg, IDC_SHRTDATEFMT_COMBO);
317*c2c66affSColin Finck EnumDateFormatsW(ShortDateFormatEnumProc, pGlobalData->UserLCID, DATE_SHORTDATE);
318*c2c66affSColin Finck
319*c2c66affSColin Finck /* Set current item to value from registry */
320*c2c66affSColin Finck nRetCode = SendDlgItemMessageW(hwndDlg, IDC_SHRTDATEFMT_COMBO,
321*c2c66affSColin Finck CB_SELECTSTRING,
322*c2c66affSColin Finck -1,
323*c2c66affSColin Finck (LPARAM)pGlobalData->szShortDateFormat);
324*c2c66affSColin Finck
325*c2c66affSColin Finck /* If it is not successful, add new value to list and select them */
326*c2c66affSColin Finck if (nRetCode == CB_ERR)
327*c2c66affSColin Finck {
328*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_SHRTDATEFMT_COMBO,
329*c2c66affSColin Finck CB_ADDSTRING,
330*c2c66affSColin Finck 0,
331*c2c66affSColin Finck (LPARAM)pGlobalData->szShortDateFormat);
332*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_SHRTDATEFMT_COMBO,
333*c2c66affSColin Finck CB_SELECTSTRING,
334*c2c66affSColin Finck -1,
335*c2c66affSColin Finck (LPARAM)pGlobalData->szShortDateFormat);
336*c2c66affSColin Finck }
337*c2c66affSColin Finck }
338*c2c66affSColin Finck
339*c2c66affSColin Finck /* Init long date control box */
340*c2c66affSColin Finck static VOID
InitLongDateCB(HWND hwndDlg,PGLOBALDATA pGlobalData)341*c2c66affSColin Finck InitLongDateCB(HWND hwndDlg, PGLOBALDATA pGlobalData)
342*c2c66affSColin Finck {
343*c2c66affSColin Finck INT nRetCode;
344*c2c66affSColin Finck
345*c2c66affSColin Finck /* Limit text length */
346*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_LONGDATEFMT_COMBO,
347*c2c66affSColin Finck CB_LIMITTEXT,
348*c2c66affSColin Finck MAX_LONGDATEFORMAT,
349*c2c66affSColin Finck 0);
350*c2c66affSColin Finck
351*c2c66affSColin Finck /* Clear all box content */
352*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_LONGDATEFMT_COMBO,
353*c2c66affSColin Finck CB_RESETCONTENT,
354*c2c66affSColin Finck (WPARAM)0,
355*c2c66affSColin Finck (LPARAM)0);
356*c2c66affSColin Finck
357*c2c66affSColin Finck /* Enumerate short long formats */
358*c2c66affSColin Finck hwndEnum = GetDlgItem(hwndDlg, IDC_LONGDATEFMT_COMBO);
359*c2c66affSColin Finck EnumDateFormatsW(ShortDateFormatEnumProc, pGlobalData->UserLCID, DATE_LONGDATE);
360*c2c66affSColin Finck
361*c2c66affSColin Finck /* Set current item to value from registry */
362*c2c66affSColin Finck nRetCode = SendDlgItemMessageW(hwndDlg, IDC_LONGDATEFMT_COMBO,
363*c2c66affSColin Finck CB_SELECTSTRING,
364*c2c66affSColin Finck -1,
365*c2c66affSColin Finck (LPARAM)pGlobalData->szLongDateFormat);
366*c2c66affSColin Finck
367*c2c66affSColin Finck /* If it is not successful, add new value to list and select them */
368*c2c66affSColin Finck if (nRetCode == CB_ERR)
369*c2c66affSColin Finck {
370*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_LONGDATEFMT_COMBO,
371*c2c66affSColin Finck CB_ADDSTRING,
372*c2c66affSColin Finck 0,
373*c2c66affSColin Finck (LPARAM)pGlobalData->szLongDateFormat);
374*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_LONGDATEFMT_COMBO,
375*c2c66affSColin Finck CB_SELECTSTRING,
376*c2c66affSColin Finck -1,
377*c2c66affSColin Finck (LPARAM)pGlobalData->szLongDateFormat);
378*c2c66affSColin Finck }
379*c2c66affSColin Finck }
380*c2c66affSColin Finck
381*c2c66affSColin Finck /* Set up max date value to registry */
382*c2c66affSColin Finck static VOID
SetMaxDate(HWND hwndDlg,LCID lcid)383*c2c66affSColin Finck SetMaxDate(HWND hwndDlg, LCID lcid)
384*c2c66affSColin Finck {
385*c2c66affSColin Finck WCHAR szMaxDateVal[YEAR_STR_MAX_SIZE];
386*c2c66affSColin Finck HWND hWndYearSpin;
387*c2c66affSColin Finck INT nSpinVal;
388*c2c66affSColin Finck
389*c2c66affSColin Finck hWndYearSpin = GetDlgItem(hwndDlg, IDC_SCR_MAX_YEAR);
390*c2c66affSColin Finck
391*c2c66affSColin Finck /* Get spin value */
392*c2c66affSColin Finck nSpinVal = LOWORD(SendMessageW(hWndYearSpin,
393*c2c66affSColin Finck UDM_GETPOS,
394*c2c66affSColin Finck 0,
395*c2c66affSColin Finck 0));
396*c2c66affSColin Finck
397*c2c66affSColin Finck /* convert to wide char */
398*c2c66affSColin Finck _itow(nSpinVal, szMaxDateVal, DECIMAL_RADIX);
399*c2c66affSColin Finck
400*c2c66affSColin Finck /* Save max date value */
401*c2c66affSColin Finck SetCalendarInfoW(lcid,
402*c2c66affSColin Finck CAL_GREGORIAN,
403*c2c66affSColin Finck 48 , /* CAL_ITWODIGITYEARMAX */
404*c2c66affSColin Finck (PCWSTR)szMaxDateVal);
405*c2c66affSColin Finck }
406*c2c66affSColin Finck
407*c2c66affSColin Finck /* Get max date value from registry set */
408*c2c66affSColin Finck static INT
GetMaxDate(LCID lcid)409*c2c66affSColin Finck GetMaxDate(LCID lcid)
410*c2c66affSColin Finck {
411*c2c66affSColin Finck INT nMaxDateVal = 0;
412*c2c66affSColin Finck
413*c2c66affSColin Finck GetCalendarInfoW(lcid,
414*c2c66affSColin Finck CAL_GREGORIAN,
415*c2c66affSColin Finck CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER,
416*c2c66affSColin Finck NULL,
417*c2c66affSColin Finck 0, /* ret type - number */
418*c2c66affSColin Finck (LPDWORD)&nMaxDateVal);
419*c2c66affSColin Finck
420*c2c66affSColin Finck return nMaxDateVal;
421*c2c66affSColin Finck }
422*c2c66affSColin Finck
423*c2c66affSColin Finck /* Set's MIN data edit control value to MAX-99 */
424*c2c66affSColin Finck static VOID
SetMinDate(HWND hwndDlg)425*c2c66affSColin Finck SetMinDate(HWND hwndDlg)
426*c2c66affSColin Finck {
427*c2c66affSColin Finck WCHAR OutBuffer[YEAR_STR_MAX_SIZE];
428*c2c66affSColin Finck HWND hWndYearSpin;
429*c2c66affSColin Finck INT nSpinVal;
430*c2c66affSColin Finck
431*c2c66affSColin Finck hWndYearSpin = GetDlgItem(hwndDlg, IDC_SCR_MAX_YEAR);
432*c2c66affSColin Finck
433*c2c66affSColin Finck /* Get spin value */
434*c2c66affSColin Finck nSpinVal = LOWORD(SendMessageW(hWndYearSpin,
435*c2c66affSColin Finck UDM_GETPOS,
436*c2c66affSColin Finck 0,
437*c2c66affSColin Finck 0));
438*c2c66affSColin Finck
439*c2c66affSColin Finck /* Set min year value */
440*c2c66affSColin Finck wsprintf(OutBuffer, L"%d", (DWORD)nSpinVal - YEAR_DIFF);
441*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_FIRSTYEAR_EDIT,
442*c2c66affSColin Finck WM_SETTEXT,
443*c2c66affSColin Finck 0,
444*c2c66affSColin Finck (LPARAM)OutBuffer);
445*c2c66affSColin Finck }
446*c2c66affSColin Finck
447*c2c66affSColin Finck /* Init spin control */
448*c2c66affSColin Finck static VOID
InitMinMaxDateSpin(HWND hwndDlg,PGLOBALDATA pGlobalData)449*c2c66affSColin Finck InitMinMaxDateSpin(HWND hwndDlg, PGLOBALDATA pGlobalData)
450*c2c66affSColin Finck {
451*c2c66affSColin Finck WCHAR OutBuffer[YEAR_STR_MAX_SIZE];
452*c2c66affSColin Finck HWND hWndYearSpin;
453*c2c66affSColin Finck
454*c2c66affSColin Finck /* Limit text lengths */
455*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_FIRSTYEAR_EDIT,
456*c2c66affSColin Finck EM_LIMITTEXT,
457*c2c66affSColin Finck MAX_YEAR_EDIT,
458*c2c66affSColin Finck 0);
459*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_SECONDYEAR_EDIT,
460*c2c66affSColin Finck EM_LIMITTEXT,
461*c2c66affSColin Finck MAX_YEAR_EDIT,
462*c2c66affSColin Finck 0);
463*c2c66affSColin Finck
464*c2c66affSColin Finck hWndYearSpin = GetDlgItem(hwndDlg, IDC_SCR_MAX_YEAR);
465*c2c66affSColin Finck
466*c2c66affSColin Finck /* Init max date value */
467*c2c66affSColin Finck wsprintf(OutBuffer, L"%04d", (DWORD)GetMaxDate(pGlobalData->UserLCID));
468*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_SECONDYEAR_EDIT,
469*c2c66affSColin Finck WM_SETTEXT,
470*c2c66affSColin Finck 0,
471*c2c66affSColin Finck (LPARAM)OutBuffer);
472*c2c66affSColin Finck
473*c2c66affSColin Finck /* Init min date value */
474*c2c66affSColin Finck wsprintf(OutBuffer, L"%04d", (DWORD)GetMaxDate(pGlobalData->UserLCID) - YEAR_DIFF);
475*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_FIRSTYEAR_EDIT,
476*c2c66affSColin Finck WM_SETTEXT,
477*c2c66affSColin Finck 0,
478*c2c66affSColin Finck (LPARAM)OutBuffer);
479*c2c66affSColin Finck
480*c2c66affSColin Finck /* Init updown control */
481*c2c66affSColin Finck /* Set bounds */
482*c2c66affSColin Finck SendMessageW(hWndYearSpin,
483*c2c66affSColin Finck UDM_SETRANGE,
484*c2c66affSColin Finck 0,
485*c2c66affSColin Finck MAKELONG(MAX_YEAR,YEAR_DIFF));
486*c2c66affSColin Finck
487*c2c66affSColin Finck /* Set current value */
488*c2c66affSColin Finck SendMessageW(hWndYearSpin,
489*c2c66affSColin Finck UDM_SETPOS,
490*c2c66affSColin Finck 0,
491*c2c66affSColin Finck MAKELONG(GetMaxDate(pGlobalData->UserLCID),0));
492*c2c66affSColin Finck }
493*c2c66affSColin Finck
494*c2c66affSColin Finck /* Update all date locale samples */
495*c2c66affSColin Finck static VOID
UpdateDateLocaleSamples(HWND hwndDlg,PGLOBALDATA pGlobalData)496*c2c66affSColin Finck UpdateDateLocaleSamples(HWND hwndDlg,
497*c2c66affSColin Finck PGLOBALDATA pGlobalData)
498*c2c66affSColin Finck {
499*c2c66affSColin Finck WCHAR OutBuffer[MAX_SAMPLES_STR_SIZE];
500*c2c66affSColin Finck
501*c2c66affSColin Finck /* Get short date format sample */
502*c2c66affSColin Finck GetDateFormatW(pGlobalData->UserLCID, 0, NULL,
503*c2c66affSColin Finck pGlobalData->szShortDateFormat, OutBuffer,
504*c2c66affSColin Finck MAX_SAMPLES_STR_SIZE);
505*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_SHRTDATESAMPLE_EDIT, WM_SETTEXT,
506*c2c66affSColin Finck 0, (LPARAM)OutBuffer);
507*c2c66affSColin Finck
508*c2c66affSColin Finck /* Get long date sample */
509*c2c66affSColin Finck GetDateFormatW(pGlobalData->UserLCID, 0, NULL,
510*c2c66affSColin Finck pGlobalData->szLongDateFormat, OutBuffer,
511*c2c66affSColin Finck MAX_SAMPLES_STR_SIZE);
512*c2c66affSColin Finck SendDlgItemMessageW(hwndDlg, IDC_LONGDATESAMPLE_EDIT,
513*c2c66affSColin Finck WM_SETTEXT, 0, (LPARAM)OutBuffer);
514*c2c66affSColin Finck }
515*c2c66affSColin Finck
516*c2c66affSColin Finck
517*c2c66affSColin Finck static
518*c2c66affSColin Finck BOOL
GetDateSetting(HWND hwndDlg,PGLOBALDATA pGlobalData)519*c2c66affSColin Finck GetDateSetting(
520*c2c66affSColin Finck HWND hwndDlg,
521*c2c66affSColin Finck PGLOBALDATA pGlobalData)
522*c2c66affSColin Finck {
523*c2c66affSColin Finck WCHAR szLongDateFormat[MAX_LONGDATEFORMAT];
524*c2c66affSColin Finck WCHAR szShortDateFormat[MAX_SHORTDATEFORMAT];
525*c2c66affSColin Finck WCHAR szDateSeparator[MAX_DATESEPARATOR];
526*c2c66affSColin Finck
527*c2c66affSColin Finck if (!SetLongDateFormat(hwndDlg, szLongDateFormat) ||
528*c2c66affSColin Finck !SetShortDateFormat(hwndDlg, szShortDateFormat) ||
529*c2c66affSColin Finck !SetShortDateSep(hwndDlg, szDateSeparator))
530*c2c66affSColin Finck {
531*c2c66affSColin Finck return FALSE;
532*c2c66affSColin Finck }
533*c2c66affSColin Finck
534*c2c66affSColin Finck /* Store settings in global data */
535*c2c66affSColin Finck wcscpy(pGlobalData->szLongDateFormat, szLongDateFormat);
536*c2c66affSColin Finck wcscpy(pGlobalData->szShortDateFormat, szShortDateFormat);
537*c2c66affSColin Finck wcscpy(pGlobalData->szDateSep, szDateSeparator);
538*c2c66affSColin Finck
539*c2c66affSColin Finck return TRUE;
540*c2c66affSColin Finck }
541*c2c66affSColin Finck
542*c2c66affSColin Finck /* Property page dialog callback */
543*c2c66affSColin Finck INT_PTR CALLBACK
DatePageProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)544*c2c66affSColin Finck DatePageProc(HWND hwndDlg,
545*c2c66affSColin Finck UINT uMsg,
546*c2c66affSColin Finck WPARAM wParam,
547*c2c66affSColin Finck LPARAM lParam)
548*c2c66affSColin Finck {
549*c2c66affSColin Finck PGLOBALDATA pGlobalData;
550*c2c66affSColin Finck
551*c2c66affSColin Finck pGlobalData = (PGLOBALDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
552*c2c66affSColin Finck
553*c2c66affSColin Finck switch (uMsg)
554*c2c66affSColin Finck {
555*c2c66affSColin Finck case WM_INITDIALOG:
556*c2c66affSColin Finck pGlobalData = (PGLOBALDATA)((LPPROPSHEETPAGE)lParam)->lParam;
557*c2c66affSColin Finck SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pGlobalData);
558*c2c66affSColin Finck
559*c2c66affSColin Finck InitMinMaxDateSpin(hwndDlg, pGlobalData);
560*c2c66affSColin Finck UpdateDateLocaleSamples(hwndDlg, pGlobalData);
561*c2c66affSColin Finck InitShortDateCB(hwndDlg, pGlobalData);
562*c2c66affSColin Finck InitLongDateCB(hwndDlg, pGlobalData);
563*c2c66affSColin Finck InitShortDateSepSamples(hwndDlg, pGlobalData);
564*c2c66affSColin Finck /* TODO: Add other calendar types */
565*c2c66affSColin Finck pGlobalData->bEnableYearNotification = TRUE;
566*c2c66affSColin Finck break;
567*c2c66affSColin Finck
568*c2c66affSColin Finck case WM_COMMAND:
569*c2c66affSColin Finck switch (LOWORD(wParam))
570*c2c66affSColin Finck {
571*c2c66affSColin Finck case IDC_SECONDYEAR_EDIT:
572*c2c66affSColin Finck if (HIWORD(wParam) == EN_CHANGE &&
573*c2c66affSColin Finck pGlobalData != NULL &&
574*c2c66affSColin Finck pGlobalData->bEnableYearNotification == TRUE)
575*c2c66affSColin Finck {
576*c2c66affSColin Finck SetMinDate(hwndDlg);
577*c2c66affSColin Finck
578*c2c66affSColin Finck /* Enable the Apply button */
579*c2c66affSColin Finck PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
580*c2c66affSColin Finck }
581*c2c66affSColin Finck break;
582*c2c66affSColin Finck
583*c2c66affSColin Finck case IDC_CALTYPE_COMBO:
584*c2c66affSColin Finck case IDC_HIJCHRON_COMBO:
585*c2c66affSColin Finck case IDC_SHRTDATEFMT_COMBO:
586*c2c66affSColin Finck case IDC_LONGDATEFMT_COMBO:
587*c2c66affSColin Finck case IDC_SHRTDATESEP_COMBO:
588*c2c66affSColin Finck if (HIWORD(wParam) == CBN_SELCHANGE ||
589*c2c66affSColin Finck HIWORD(wParam) == CBN_EDITCHANGE)
590*c2c66affSColin Finck {
591*c2c66affSColin Finck /* Enable the Apply button */
592*c2c66affSColin Finck PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
593*c2c66affSColin Finck }
594*c2c66affSColin Finck break;
595*c2c66affSColin Finck }
596*c2c66affSColin Finck break;
597*c2c66affSColin Finck
598*c2c66affSColin Finck case WM_NOTIFY:
599*c2c66affSColin Finck if (((LPNMHDR)lParam)->code == (UINT)PSN_APPLY)
600*c2c66affSColin Finck {
601*c2c66affSColin Finck if (GetDateSetting(hwndDlg, pGlobalData))
602*c2c66affSColin Finck {
603*c2c66affSColin Finck pGlobalData->bUserLocaleChanged = TRUE;
604*c2c66affSColin Finck SetMaxDate(hwndDlg, pGlobalData->UserLCID);
605*c2c66affSColin Finck UpdateDateLocaleSamples(hwndDlg, pGlobalData);
606*c2c66affSColin Finck }
607*c2c66affSColin Finck }
608*c2c66affSColin Finck break;
609*c2c66affSColin Finck }
610*c2c66affSColin Finck
611*c2c66affSColin Finck return FALSE;
612*c2c66affSColin Finck }
613*c2c66affSColin Finck
614*c2c66affSColin Finck /* EOF */
615