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
);
181 static PTIMEZONE_ENTRY
182 GetLargerTimeZoneEntry(DWORD Index
)
184 PTIMEZONE_ENTRY Entry
;
186 Entry
= TimeZoneListHead
;
187 while (Entry
!= NULL
)
189 if (Entry
->Index
>= Index
)
200 CreateTimeZoneList(VOID
)
202 WCHAR szKeyName
[256];
210 PTIMEZONE_ENTRY Entry
;
211 PTIMEZONE_ENTRY Current
;
213 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
214 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
224 lError
= RegEnumKeyExW(hZonesKey
,
232 if (lError
!= ERROR_SUCCESS
&& lError
!= ERROR_MORE_DATA
)
235 if (RegOpenKeyExW(hZonesKey
,
242 Entry
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(TIMEZONE_ENTRY
));
245 RegCloseKey(hZoneKey
);
249 dwValueSize
= 64 * sizeof(WCHAR
);
250 if (RegQueryValueExW(hZoneKey
,
254 (LPBYTE
)&Entry
->Description
,
257 RegCloseKey(hZoneKey
);
261 dwValueSize
= 32 * sizeof(WCHAR
);
262 if (RegQueryValueExW(hZoneKey
,
266 (LPBYTE
)&Entry
->StandardName
,
269 RegCloseKey(hZoneKey
);
273 dwValueSize
= 32 * sizeof(WCHAR
);
274 if (RegQueryValueExW(hZoneKey
,
278 (LPBYTE
)&Entry
->DaylightName
,
281 RegCloseKey(hZoneKey
);
285 dwValueSize
= sizeof(DWORD
);
286 if (RegQueryValueExW(hZoneKey
,
290 (LPBYTE
)&Entry
->Index
,
293 RegCloseKey(hZoneKey
);
297 dwValueSize
= sizeof(TZ_INFO
);
298 if (RegQueryValueExW(hZoneKey
,
302 (LPBYTE
)&Entry
->TimezoneInfo
,
305 RegCloseKey(hZoneKey
);
309 RegCloseKey(hZoneKey
);
311 if (TimeZoneListHead
== NULL
&&
312 TimeZoneListTail
== NULL
)
316 TimeZoneListHead
= Entry
;
317 TimeZoneListTail
= Entry
;
321 Current
= GetLargerTimeZoneEntry(Entry
->Index
);
324 if (Current
== TimeZoneListHead
)
326 /* Prepend to head */
328 Entry
->Next
= TimeZoneListHead
;
329 TimeZoneListHead
->Prev
= Entry
;
330 TimeZoneListHead
= Entry
;
334 /* Insert before current */
335 Entry
->Prev
= Current
->Prev
;
336 Entry
->Next
= Current
;
337 Current
->Prev
->Next
= Entry
;
338 Current
->Prev
= Entry
;
344 Entry
->Prev
= TimeZoneListTail
;
346 TimeZoneListTail
->Next
= Entry
;
347 TimeZoneListTail
= Entry
;
354 RegCloseKey(hZonesKey
);
359 DestroyTimeZoneList(VOID
)
361 PTIMEZONE_ENTRY Entry
;
363 while (TimeZoneListHead
!= NULL
)
365 Entry
= TimeZoneListHead
;
367 TimeZoneListHead
= Entry
->Next
;
368 if (TimeZoneListHead
!= NULL
)
370 TimeZoneListHead
->Prev
= NULL
;
373 HeapFree(GetProcessHeap(), 0, Entry
);
376 TimeZoneListTail
= NULL
;
381 ShowTimeZoneList(HWND hwnd
)
383 TIME_ZONE_INFORMATION TimeZoneInfo
;
384 PTIMEZONE_ENTRY Entry
;
388 GetTimeZoneInformation(&TimeZoneInfo
);
392 Entry
= TimeZoneListHead
;
393 while (Entry
!= NULL
)
398 (LPARAM
)Entry
->Description
);
400 if (!wcscmp(Entry
->StandardName
, TimeZoneInfo
.StandardName
))
415 SetLocalTimeZone(HWND hwnd
)
417 TIME_ZONE_INFORMATION TimeZoneInformation
;
418 PTIMEZONE_ENTRY Entry
;
422 dwIndex
= SendMessage(hwnd
,
428 Entry
= TimeZoneListHead
;
438 wcscpy(TimeZoneInformation
.StandardName
,
439 Entry
->StandardName
);
440 wcscpy(TimeZoneInformation
.DaylightName
,
441 Entry
->DaylightName
);
443 TimeZoneInformation
.Bias
= Entry
->TimezoneInfo
.Bias
;
444 TimeZoneInformation
.StandardBias
= Entry
->TimezoneInfo
.StandardBias
;
445 TimeZoneInformation
.DaylightBias
= Entry
->TimezoneInfo
.DaylightBias
;
447 memcpy(&TimeZoneInformation
.StandardDate
,
448 &Entry
->TimezoneInfo
.StandardDate
,
450 memcpy(&TimeZoneInformation
.DaylightDate
,
451 &Entry
->TimezoneInfo
.DaylightDate
,
454 /* Set time zone information */
455 SetTimeZoneInformation(&TimeZoneInformation
);
460 GetAutoDaylightInfo(HWND hwnd
)
464 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
465 L
"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
471 if (RegQueryValueExW(hKey
,
472 L
"DisableAutoDaylightTimeSet",
478 SendMessage(hwnd
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
482 SendMessage(hwnd
, BM_SETCHECK
, (WPARAM
)BST_UNCHECKED
, 0);
490 SetAutoDaylightInfo(HWND hwnd
)
495 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
496 L
"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
502 if (SendMessage(hwnd
, BM_GETCHECK
, 0, 0) == BST_UNCHECKED
)
505 L
"DisableAutoDaylightTimeSet",
513 RegDeleteValueW(hKey
,
514 L
"DisableAutoDaylightTimeSet");
521 /* Property page dialog callback */
523 TimeZonePageProc(HWND hwndDlg
,
531 CreateTimeZoneList();
532 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
));
533 GetAutoDaylightInfo(GetDlgItem(hwndDlg
, IDC_AUTODAYLIGHT
));
537 if ((LOWORD(wParam
) == IDC_TIMEZONELIST
&& HIWORD(wParam
) == CBN_SELCHANGE
) ||
538 (LOWORD(wParam
) == IDC_AUTODAYLIGHT
&& HIWORD(wParam
) == BN_CLICKED
))
540 /* Enable the 'Apply' button */
541 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
546 DestroyTimeZoneList();
551 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
556 SetAutoDaylightInfo(GetDlgItem(hwndDlg
, IDC_AUTODAYLIGHT
));
557 SetLocalTimeZone(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
));
558 SetWindowLong(hwndDlg
, DWL_MSGRESULT
, PSNRET_NOERROR
);
573 /* Property page dialog callback */
575 InetTimePageProc(HWND hwndDlg
,
609 InitPropSheetPage(PROPSHEETPAGE
*psp
, WORD idDlg
, DLGPROC DlgProc
)
611 ZeroMemory(psp
, sizeof(PROPSHEETPAGE
));
612 psp
->dwSize
= sizeof(PROPSHEETPAGE
);
613 psp
->dwFlags
= PSP_DEFAULT
;
614 psp
->hInstance
= hApplet
;
615 psp
->pszTemplate
= MAKEINTRESOURCE(idDlg
);
616 psp
->pfnDlgProc
= DlgProc
;
621 Applet(HWND hwnd
, UINT uMsg
, LONG wParam
, LONG lParam
)
624 PROPSHEETPAGE psp
[3];
627 LoadString(hApplet
, IDS_CPLNAME
, Caption
, sizeof(Caption
) / sizeof(TCHAR
));
629 ZeroMemory(&psh
, sizeof(PROPSHEETHEADER
));
630 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
631 psh
.dwFlags
= PSH_PROPSHEETPAGE
| PSH_PROPTITLE
;
632 psh
.hwndParent
= NULL
;
633 psh
.hInstance
= hApplet
;
634 psh
.hIcon
= LoadIcon(hApplet
, MAKEINTRESOURCE(IDC_CPLICON
));
635 psh
.pszCaption
= Caption
;
636 psh
.nPages
= sizeof(psp
) / sizeof(PROPSHEETPAGE
);
640 InitPropSheetPage(&psp
[0], IDD_DATETIMEPAGE
, DateTimePageProc
);
641 InitPropSheetPage(&psp
[1], IDD_TIMEZONEPAGE
, TimeZonePageProc
);
642 InitPropSheetPage(&psp
[2], IDD_INETTIMEPAGE
, InetTimePageProc
);
644 return (LONG
)(PropertySheet(&psh
) != -1);
648 /* Control Panel Callback */
650 CPlApplet(HWND hwndCpl
,
655 int i
= (int)lParam1
;
667 CPLINFO
*CPlInfo
= (CPLINFO
*)lParam2
;
669 CPlInfo
->idIcon
= Applets
[i
].idIcon
;
670 CPlInfo
->idName
= Applets
[i
].idName
;
671 CPlInfo
->idInfo
= Applets
[i
].idDescription
;
677 Applets
[i
].AppletProc(hwndCpl
, uMsg
, lParam1
, lParam2
);
686 DllMain(HINSTANCE hinstDLL
,
692 case DLL_PROCESS_ATTACH
:
694 INITCOMMONCONTROLSEX InitControls
;
696 InitControls
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
697 InitControls
.dwICC
= ICC_DATE_CLASSES
| ICC_PROGRESS_CLASS
| ICC_UPDOWN_CLASS
;
698 InitCommonControlsEx(&InitControls
);