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];
105 WCHAR TimeZoneText
[128];
106 WCHAR TimeZoneName
[128];
109 TimeZoneId
= GetTimeZoneInformation(&TimeZoneInfo
);
111 LoadString(hApplet
, IDS_TIMEZONETEXT
, TimeZoneText
, 128);
115 case TIME_ZONE_ID_STANDARD
:
116 wcscpy(TimeZoneName
, TimeZoneInfo
.StandardName
);
119 case TIME_ZONE_ID_DAYLIGHT
:
120 wcscpy(TimeZoneName
, TimeZoneInfo
.DaylightName
);
123 case TIME_ZONE_ID_UNKNOWN
:
124 LoadString(hApplet
, IDS_TIMEZONEUNKNOWN
, TimeZoneName
, 128);
127 case TIME_ZONE_ID_INVALID
:
129 LoadString(hApplet
, IDS_TIMEZONEINVALID
, TimeZoneName
, 128);
133 wsprintf(TimeZoneString
, TimeZoneText
, TimeZoneName
);
134 SendDlgItemMessageW(hwnd
, IDC_TIMEZONE
, WM_SETTEXT
, 0, (LPARAM
)TimeZoneString
);
138 /* Property page dialog callback */
140 DateTimePageProc(HWND hwndDlg
,
149 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
153 case DTN_DATETIMECHANGE
:
155 /* Enable the 'Apply' button */
156 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
160 SetTimeZoneName(hwndDlg
);
164 SetLocalSystemTime(hwndDlg
);
165 SetWindowLong(hwndDlg
, DWL_MSGRESULT
, PSNRET_NOERROR
);
179 static PTIMEZONE_ENTRY
180 GetLargerTimeZoneEntry(DWORD Index
)
182 PTIMEZONE_ENTRY Entry
;
184 Entry
= TimeZoneListHead
;
185 while (Entry
!= NULL
)
187 if (Entry
->Index
>= Index
)
198 CreateTimeZoneList(VOID
)
200 WCHAR szKeyName
[256];
208 PTIMEZONE_ENTRY Entry
;
209 PTIMEZONE_ENTRY Current
;
211 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
212 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
222 lError
= RegEnumKeyExW(hZonesKey
,
230 if (lError
!= ERROR_SUCCESS
&& lError
!= ERROR_MORE_DATA
)
233 if (RegOpenKeyExW(hZonesKey
,
240 Entry
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(TIMEZONE_ENTRY
));
243 RegCloseKey(hZoneKey
);
247 dwValueSize
= 64 * sizeof(WCHAR
);
248 if (RegQueryValueExW(hZoneKey
,
252 (LPBYTE
)&Entry
->Description
,
255 RegCloseKey(hZoneKey
);
259 dwValueSize
= 32 * sizeof(WCHAR
);
260 if (RegQueryValueExW(hZoneKey
,
264 (LPBYTE
)&Entry
->StandardName
,
267 RegCloseKey(hZoneKey
);
271 dwValueSize
= 32 * sizeof(WCHAR
);
272 if (RegQueryValueExW(hZoneKey
,
276 (LPBYTE
)&Entry
->DaylightName
,
279 RegCloseKey(hZoneKey
);
283 dwValueSize
= sizeof(DWORD
);
284 if (RegQueryValueExW(hZoneKey
,
288 (LPBYTE
)&Entry
->Index
,
291 RegCloseKey(hZoneKey
);
295 dwValueSize
= sizeof(TZ_INFO
);
296 if (RegQueryValueExW(hZoneKey
,
300 (LPBYTE
)&Entry
->TimezoneInfo
,
303 RegCloseKey(hZoneKey
);
307 RegCloseKey(hZoneKey
);
309 if (TimeZoneListHead
== NULL
&&
310 TimeZoneListTail
== NULL
)
314 TimeZoneListHead
= Entry
;
315 TimeZoneListTail
= Entry
;
319 Current
= GetLargerTimeZoneEntry(Entry
->Index
);
322 if (Current
== TimeZoneListHead
)
324 /* Prepend to head */
326 Entry
->Next
= TimeZoneListHead
;
327 TimeZoneListHead
->Prev
= Entry
;
328 TimeZoneListHead
= Entry
;
332 /* Insert before current */
333 Entry
->Prev
= Current
->Prev
;
334 Entry
->Next
= Current
;
335 Current
->Prev
->Next
= Entry
;
336 Current
->Prev
= Entry
;
342 Entry
->Prev
= TimeZoneListTail
;
344 TimeZoneListTail
->Next
= Entry
;
345 TimeZoneListTail
= Entry
;
352 RegCloseKey(hZonesKey
);
357 DestroyTimeZoneList(VOID
)
359 PTIMEZONE_ENTRY Entry
;
361 while (TimeZoneListHead
!= NULL
)
363 Entry
= TimeZoneListHead
;
365 TimeZoneListHead
= Entry
->Next
;
366 if (TimeZoneListHead
!= NULL
)
368 TimeZoneListHead
->Prev
= NULL
;
371 HeapFree(GetProcessHeap(), 0, Entry
);
374 TimeZoneListTail
= NULL
;
379 ShowTimeZoneList(HWND hwnd
)
381 TIME_ZONE_INFORMATION TimeZoneInfo
;
382 PTIMEZONE_ENTRY Entry
;
386 GetTimeZoneInformation(&TimeZoneInfo
);
390 Entry
= TimeZoneListHead
;
391 while (Entry
!= NULL
)
396 (LPARAM
)Entry
->Description
);
398 if (!wcscmp(Entry
->StandardName
, TimeZoneInfo
.StandardName
))
413 SetLocalTimeZone(HWND hwnd
)
415 TIME_ZONE_INFORMATION TimeZoneInformation
;
416 PTIMEZONE_ENTRY Entry
;
420 dwIndex
= SendMessage(hwnd
,
426 Entry
= TimeZoneListHead
;
436 wcscpy(TimeZoneInformation
.StandardName
,
437 Entry
->StandardName
);
438 wcscpy(TimeZoneInformation
.DaylightName
,
439 Entry
->DaylightName
);
441 TimeZoneInformation
.Bias
= Entry
->TimezoneInfo
.Bias
;
442 TimeZoneInformation
.StandardBias
= Entry
->TimezoneInfo
.StandardBias
;
443 TimeZoneInformation
.DaylightBias
= Entry
->TimezoneInfo
.DaylightBias
;
445 memcpy(&TimeZoneInformation
.StandardDate
,
446 &Entry
->TimezoneInfo
.StandardDate
,
448 memcpy(&TimeZoneInformation
.DaylightDate
,
449 &Entry
->TimezoneInfo
.DaylightDate
,
452 /* Set time zone information */
453 SetTimeZoneInformation(&TimeZoneInformation
);
458 GetAutoDaylightInfo(HWND hwnd
)
462 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
463 L
"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
469 if (RegQueryValueExW(hKey
,
470 L
"DisableAutoDaylightTimeSet",
476 SendMessage(hwnd
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
480 SendMessage(hwnd
, BM_SETCHECK
, (WPARAM
)BST_UNCHECKED
, 0);
488 SetAutoDaylightInfo(HWND hwnd
)
493 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
494 L
"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
500 if (SendMessage(hwnd
, BM_GETCHECK
, 0, 0) == BST_UNCHECKED
)
503 L
"DisableAutoDaylightTimeSet",
511 RegDeleteValueW(hKey
,
512 L
"DisableAutoDaylightTimeSet");
519 /* Property page dialog callback */
521 TimeZonePageProc(HWND hwndDlg
,
529 CreateTimeZoneList();
530 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
));
531 GetAutoDaylightInfo(GetDlgItem(hwndDlg
, IDC_AUTODAYLIGHT
));
535 if ((LOWORD(wParam
) == IDC_TIMEZONELIST
&& HIWORD(wParam
) == CBN_SELCHANGE
) ||
536 (LOWORD(wParam
) == IDC_AUTODAYLIGHT
&& HIWORD(wParam
) == BN_CLICKED
))
538 /* Enable the 'Apply' button */
539 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
544 DestroyTimeZoneList();
549 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
554 SetAutoDaylightInfo(GetDlgItem(hwndDlg
, IDC_AUTODAYLIGHT
));
555 SetLocalTimeZone(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
));
556 SetWindowLong(hwndDlg
, DWL_MSGRESULT
, PSNRET_NOERROR
);
572 InitPropSheetPage(PROPSHEETPAGE
*psp
, WORD idDlg
, DLGPROC DlgProc
)
574 ZeroMemory(psp
, sizeof(PROPSHEETPAGE
));
575 psp
->dwSize
= sizeof(PROPSHEETPAGE
);
576 psp
->dwFlags
= PSP_DEFAULT
;
577 psp
->hInstance
= hApplet
;
578 psp
->pszTemplate
= MAKEINTRESOURCE(idDlg
);
579 psp
->pfnDlgProc
= DlgProc
;
584 Applet(HWND hwnd
, UINT uMsg
, LONG wParam
, LONG lParam
)
587 PROPSHEETPAGE psp
[3];
590 LoadString(hApplet
, IDS_CPLNAME
, Caption
, sizeof(Caption
) / sizeof(TCHAR
));
592 ZeroMemory(&psh
, sizeof(PROPSHEETHEADER
));
593 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
594 psh
.dwFlags
= PSH_PROPSHEETPAGE
| PSH_PROPTITLE
;
595 psh
.hwndParent
= NULL
;
596 psh
.hInstance
= hApplet
;
597 psh
.hIcon
= LoadIcon(hApplet
, MAKEINTRESOURCE(IDC_CPLICON
));
598 psh
.pszCaption
= Caption
;
599 psh
.nPages
= sizeof(psp
) / sizeof(PROPSHEETPAGE
);
603 InitPropSheetPage(&psp
[0], IDD_DATETIMEPAGE
, DateTimePageProc
);
604 InitPropSheetPage(&psp
[1], IDD_TIMEZONEPAGE
, TimeZonePageProc
);
606 return (LONG
)(PropertySheet(&psh
) != -1);
610 /* Control Panel Callback */
612 CPlApplet(HWND hwndCpl
,
617 int i
= (int)lParam1
;
629 CPLINFO
*CPlInfo
= (CPLINFO
*)lParam2
;
631 CPlInfo
->idIcon
= Applets
[i
].idIcon
;
632 CPlInfo
->idName
= Applets
[i
].idName
;
633 CPlInfo
->idInfo
= Applets
[i
].idDescription
;
639 Applets
[i
].AppletProc(hwndCpl
, uMsg
, lParam1
, lParam2
);
648 DllMain(HINSTANCE hinstDLL
,
654 case DLL_PROCESS_ATTACH
:
656 INITCOMMONCONTROLSEX InitControls
;
658 InitControls
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
659 InitControls
.dwICC
= ICC_DATE_CLASSES
| ICC_PROGRESS_CLASS
| ICC_UPDOWN_CLASS
;
660 InitCommonControlsEx(&InitControls
);