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 Timedate Control Panel
22 * FILE: lib/cpl/timedate/timedate.c
23 * PURPOSE: ReactOS Timedate Control Panel
24 * PROGRAMMER: Eric Kohl
35 typedef struct _TZ_INFO
40 SYSTEMTIME StandardDate
;
41 SYSTEMTIME DaylightDate
;
44 typedef struct _TIMEZONE_ENTRY
46 struct _TIMEZONE_ENTRY
*Prev
;
47 struct _TIMEZONE_ENTRY
*Next
;
48 WCHAR Description
[64]; /* 'Display' */
49 WCHAR StandardName
[32]; /* 'Std' */
50 WCHAR DaylightName
[32]; /* 'Dlt' */
51 TZ_INFO TimezoneInfo
; /* 'TZI' */
52 ULONG Index
; /* 'Index ' */
53 } TIMEZONE_ENTRY
, *PTIMEZONE_ENTRY
;
56 #define NUM_APPLETS (1)
59 Applet(HWND hwnd
, UINT uMsg
, LONG wParam
, LONG lParam
);
62 HINSTANCE hApplet
= 0;
64 PTIMEZONE_ENTRY TimeZoneListHead
= NULL
;
65 PTIMEZONE_ENTRY TimeZoneListTail
= NULL
;
69 APPLET Applets
[NUM_APPLETS
] =
71 {IDC_CPLICON
, IDS_CPLNAME
, IDS_CPLDESCRIPTION
, Applet
}
76 SetLocalSystemTime(HWND hwnd
)
81 if (DateTime_GetSystemTime(GetDlgItem(hwnd
, IDC_DATEPICKER
), &Date
) != GDT_VALID
)
86 if (DateTime_GetSystemTime(GetDlgItem(hwnd
, IDC_TIMEPICKER
), &Time
) != GDT_VALID
)
91 Time
.wYear
= Date
.wYear
;
92 Time
.wMonth
= Date
.wMonth
;
93 Time
.wDayOfWeek
= Date
.wDayOfWeek
;
94 Time
.wDay
= Date
.wDay
;
101 SetTimeZoneName(HWND hwnd
)
103 TIME_ZONE_INFORMATION TimeZoneInfo
;
104 WCHAR TimeZoneString
[128];
107 TimeZoneId
= GetTimeZoneInformation(&TimeZoneInfo
);
109 wsprintf(TimeZoneString
,
110 L
"Current time zone: %s\n",
111 (TimeZoneId
== TIME_ZONE_ID_DAYLIGHT
) ? TimeZoneInfo
.DaylightName
: TimeZoneInfo
.StandardName
);
113 SendDlgItemMessageW(hwnd
, IDC_TIMEZONE
, WM_SETTEXT
, 0, (LPARAM
)TimeZoneString
);
117 /* Property page dialog callback */
119 DateTimePageProc(HWND hwndDlg
,
128 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
132 case DTN_DATETIMECHANGE
:
134 /* Enable the 'Apply' button */
135 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
139 SetTimeZoneName(hwndDlg
);
143 SetLocalSystemTime(hwndDlg
);
144 SetWindowLong(hwndDlg
, DWL_MSGRESULT
, PSNRET_NOERROR
);
158 static PTIMEZONE_ENTRY
159 GetLargerTimeZoneEntry(DWORD Index
)
161 PTIMEZONE_ENTRY Entry
;
163 Entry
= TimeZoneListHead
;
164 while (Entry
!= NULL
)
166 if (Entry
->Index
>= Index
)
177 CreateTimeZoneList(VOID
)
179 WCHAR szKeyName
[256];
187 PTIMEZONE_ENTRY Entry
;
188 PTIMEZONE_ENTRY Current
;
190 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
191 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
201 lError
= RegEnumKeyExW(hZonesKey
,
209 if (lError
!= ERROR_SUCCESS
&& lError
!= ERROR_MORE_DATA
)
212 if (RegOpenKeyExW(hZonesKey
,
219 Entry
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(TIMEZONE_ENTRY
));
222 RegCloseKey(hZoneKey
);
226 dwValueSize
= 64 * sizeof(WCHAR
);
227 if (RegQueryValueExW(hZoneKey
,
231 (LPBYTE
)&Entry
->Description
,
234 RegCloseKey(hZoneKey
);
238 dwValueSize
= 32 * sizeof(WCHAR
);
239 if (RegQueryValueExW(hZoneKey
,
243 (LPBYTE
)&Entry
->StandardName
,
246 RegCloseKey(hZoneKey
);
250 dwValueSize
= 32 * sizeof(WCHAR
);
251 if (RegQueryValueExW(hZoneKey
,
255 (LPBYTE
)&Entry
->DaylightName
,
258 RegCloseKey(hZoneKey
);
262 dwValueSize
= sizeof(DWORD
);
263 if (RegQueryValueExW(hZoneKey
,
267 (LPBYTE
)&Entry
->Index
,
270 RegCloseKey(hZoneKey
);
274 dwValueSize
= sizeof(TZ_INFO
);
275 if (RegQueryValueExW(hZoneKey
,
279 (LPBYTE
)&Entry
->TimezoneInfo
,
282 RegCloseKey(hZoneKey
);
286 RegCloseKey(hZoneKey
);
288 if (TimeZoneListHead
== NULL
&&
289 TimeZoneListTail
== NULL
)
293 TimeZoneListHead
= Entry
;
294 TimeZoneListTail
= Entry
;
298 Current
= GetLargerTimeZoneEntry(Entry
->Index
);
301 if (Current
== TimeZoneListHead
)
303 /* Prepend to head */
305 Entry
->Next
= TimeZoneListHead
;
306 TimeZoneListHead
->Prev
= Entry
;
307 TimeZoneListHead
= Entry
;
311 /* Insert before current */
312 Entry
->Prev
= Current
->Prev
;
313 Entry
->Next
= Current
;
314 Current
->Prev
->Next
= Entry
;
315 Current
->Prev
= Entry
;
321 Entry
->Prev
= TimeZoneListTail
;
323 TimeZoneListTail
->Next
= Entry
;
324 TimeZoneListTail
= Entry
;
331 RegCloseKey(hZonesKey
);
336 DestroyTimeZoneList(VOID
)
338 PTIMEZONE_ENTRY Entry
;
340 while (TimeZoneListHead
!= NULL
)
342 Entry
= TimeZoneListHead
;
344 TimeZoneListHead
= Entry
->Next
;
345 if (TimeZoneListHead
!= NULL
)
347 TimeZoneListHead
->Prev
= NULL
;
350 HeapFree(GetProcessHeap(), 0, Entry
);
353 TimeZoneListTail
= NULL
;
358 ShowTimeZoneList(HWND hwnd
)
360 TIME_ZONE_INFORMATION TimeZoneInfo
;
361 PTIMEZONE_ENTRY Entry
;
365 GetTimeZoneInformation(&TimeZoneInfo
);
369 Entry
= TimeZoneListHead
;
370 while (Entry
!= NULL
)
375 (LPARAM
)Entry
->Description
);
377 if (!wcscmp(Entry
->StandardName
, TimeZoneInfo
.StandardName
))
392 SetLocalTimeZone(HWND hwnd
)
394 TIME_ZONE_INFORMATION TimeZoneInformation
;
395 PTIMEZONE_ENTRY Entry
;
399 dwIndex
= SendMessage(hwnd
,
405 Entry
= TimeZoneListHead
;
415 wcscpy(TimeZoneInformation
.StandardName
,
416 Entry
->StandardName
);
417 wcscpy(TimeZoneInformation
.DaylightName
,
418 Entry
->DaylightName
);
420 TimeZoneInformation
.Bias
= Entry
->TimezoneInfo
.Bias
;
421 TimeZoneInformation
.StandardBias
= Entry
->TimezoneInfo
.StandardBias
;
422 TimeZoneInformation
.DaylightBias
= Entry
->TimezoneInfo
.DaylightBias
;
424 memcpy(&TimeZoneInformation
.StandardDate
,
425 &Entry
->TimezoneInfo
.StandardDate
,
427 memcpy(&TimeZoneInformation
.DaylightDate
,
428 &Entry
->TimezoneInfo
.DaylightDate
,
431 /* Set time zone information */
432 SetTimeZoneInformation(&TimeZoneInformation
);
437 GetAutoDaylightInfo(HWND hwnd
)
441 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
442 L
"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
448 if (RegQueryValueExW(hKey
,
449 L
"DisableAutoDaylightTimeSet",
455 SendMessage(hwnd
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
459 SendMessage(hwnd
, BM_SETCHECK
, (WPARAM
)BST_UNCHECKED
, 0);
467 SetAutoDaylightInfo(HWND hwnd
)
472 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
473 L
"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
479 if (SendMessage(hwnd
, BM_GETCHECK
, 0, 0) == BST_UNCHECKED
)
482 L
"DisableAutoDaylightTimeSet",
490 RegDeleteValueW(hKey
,
491 L
"DisableAutoDaylightTimeSet");
498 /* Property page dialog callback */
500 TimeZonePageProc(HWND hwndDlg
,
508 CreateTimeZoneList();
509 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
));
510 GetAutoDaylightInfo(GetDlgItem(hwndDlg
, IDC_AUTODAYLIGHT
));
514 if ((LOWORD(wParam
) == IDC_TIMEZONELIST
&& HIWORD(wParam
) == CBN_SELCHANGE
) ||
515 (LOWORD(wParam
) == IDC_AUTODAYLIGHT
&& HIWORD(wParam
) == BN_CLICKED
))
517 /* Enable the 'Apply' button */
518 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
523 DestroyTimeZoneList();
528 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
533 SetAutoDaylightInfo(GetDlgItem(hwndDlg
, IDC_AUTODAYLIGHT
));
534 SetLocalTimeZone(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
));
535 SetWindowLong(hwndDlg
, DWL_MSGRESULT
, PSNRET_NOERROR
);
551 InitPropSheetPage(PROPSHEETPAGE
*psp
, WORD idDlg
, DLGPROC DlgProc
)
553 ZeroMemory(psp
, sizeof(PROPSHEETPAGE
));
554 psp
->dwSize
= sizeof(PROPSHEETPAGE
);
555 psp
->dwFlags
= PSP_DEFAULT
;
556 psp
->hInstance
= hApplet
;
557 psp
->pszTemplate
= MAKEINTRESOURCE(idDlg
);
558 psp
->pfnDlgProc
= DlgProc
;
563 Applet(HWND hwnd
, UINT uMsg
, LONG wParam
, LONG lParam
)
566 PROPSHEETPAGE psp
[3];
569 LoadString(hApplet
, IDS_CPLNAME
, Caption
, sizeof(Caption
) / sizeof(TCHAR
));
571 ZeroMemory(&psh
, sizeof(PROPSHEETHEADER
));
572 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
573 psh
.dwFlags
= PSH_PROPSHEETPAGE
| PSH_PROPTITLE
;
574 psh
.hwndParent
= NULL
;
575 psh
.hInstance
= hApplet
;
576 psh
.hIcon
= LoadIcon(hApplet
, MAKEINTRESOURCE(IDC_CPLICON
));
577 psh
.pszCaption
= Caption
;
578 psh
.nPages
= sizeof(psp
) / sizeof(PROPSHEETPAGE
);
582 InitPropSheetPage(&psp
[0], IDD_DATETIMEPAGE
, DateTimePageProc
);
583 InitPropSheetPage(&psp
[1], IDD_TIMEZONEPAGE
, TimeZonePageProc
);
585 return (LONG
)(PropertySheet(&psh
) != -1);
589 /* Control Panel Callback */
591 CPlApplet(HWND hwndCpl
,
596 int i
= (int)lParam1
;
608 CPLINFO
*CPlInfo
= (CPLINFO
*)lParam2
;
610 CPlInfo
->idIcon
= Applets
[i
].idIcon
;
611 CPlInfo
->idName
= Applets
[i
].idName
;
612 CPlInfo
->idInfo
= Applets
[i
].idDescription
;
618 Applets
[i
].AppletProc(hwndCpl
, uMsg
, lParam1
, lParam2
);
627 DllMain(HINSTANCE hinstDLL
,
633 case DLL_PROCESS_ATTACH
:
635 INITCOMMONCONTROLSEX InitControls
;
637 InitControls
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
638 InitControls
.dwICC
= ICC_DATE_CLASSES
| ICC_PROGRESS_CLASS
| ICC_UPDOWN_CLASS
;
639 InitCommonControlsEx(&InitControls
);