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.
19 /* $Id: timedate.c,v 1.4 2004/11/11 12:24:56 ekohl Exp $
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
}
75 /* Property page dialog callback */
77 DateTimePageProc(HWND hwndDlg
,
86 TIME_ZONE_INFORMATION TimeZoneInfo
;
88 GetTimeZoneInformation(&TimeZoneInfo
);
90 SendDlgItemMessageW(hwndDlg
, IDC_TIMEZONE
, WM_SETTEXT
, 0, (LPARAM
)TimeZoneInfo
.StandardName
);
96 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
100 case DTN_DATETIMECHANGE
:
102 /* Enable the 'Apply' button */
103 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
107 /* FIXME: Update the time zone name */
112 /* FIXME: Set date and time */
114 SetWindowLong(hwndDlg
, DWL_MSGRESULT
, PSNRET_NOERROR
);
129 static PTIMEZONE_ENTRY
130 GetLargerTimeZoneEntry(DWORD Index
)
132 PTIMEZONE_ENTRY Entry
;
134 Entry
= TimeZoneListHead
;
135 while (Entry
!= NULL
)
137 if (Entry
->Index
>= Index
)
148 CreateTimeZoneList(VOID
)
150 WCHAR szKeyName
[256];
158 PTIMEZONE_ENTRY Entry
;
159 PTIMEZONE_ENTRY Current
;
161 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
162 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
172 lError
= RegEnumKeyExW(hZonesKey
,
180 if (lError
!= ERROR_SUCCESS
&& lError
!= ERROR_MORE_DATA
)
183 if (RegOpenKeyExW(hZonesKey
,
190 Entry
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(TIMEZONE_ENTRY
));
193 RegCloseKey(hZoneKey
);
197 dwValueSize
= 64 * sizeof(WCHAR
);
198 if (RegQueryValueExW(hZoneKey
,
202 (LPBYTE
)&Entry
->Description
,
205 RegCloseKey(hZoneKey
);
209 dwValueSize
= 32 * sizeof(WCHAR
);
210 if (RegQueryValueExW(hZoneKey
,
214 (LPBYTE
)&Entry
->StandardName
,
217 RegCloseKey(hZoneKey
);
221 dwValueSize
= 32 * sizeof(WCHAR
);
222 if (RegQueryValueExW(hZoneKey
,
226 (LPBYTE
)&Entry
->DaylightName
,
229 RegCloseKey(hZoneKey
);
233 dwValueSize
= sizeof(DWORD
);
234 if (RegQueryValueExW(hZoneKey
,
238 (LPBYTE
)&Entry
->Index
,
241 RegCloseKey(hZoneKey
);
245 dwValueSize
= sizeof(TZ_INFO
);
246 if (RegQueryValueExW(hZoneKey
,
250 (LPBYTE
)&Entry
->TimezoneInfo
,
253 RegCloseKey(hZoneKey
);
257 RegCloseKey(hZoneKey
);
259 if (TimeZoneListHead
== NULL
&&
260 TimeZoneListTail
== NULL
)
264 TimeZoneListHead
= Entry
;
265 TimeZoneListTail
= Entry
;
269 Current
= GetLargerTimeZoneEntry(Entry
->Index
);
272 if (Current
== TimeZoneListHead
)
274 /* Prepend to head */
276 Entry
->Next
= TimeZoneListHead
;
277 TimeZoneListHead
->Prev
= Entry
;
278 TimeZoneListHead
= Entry
;
282 /* Insert before current */
283 Entry
->Prev
= Current
->Prev
;
284 Entry
->Next
= Current
;
285 Current
->Prev
->Next
= Entry
;
286 Current
->Prev
= Entry
;
292 Entry
->Prev
= TimeZoneListTail
;
294 TimeZoneListTail
->Next
= Entry
;
295 TimeZoneListTail
= Entry
;
302 RegCloseKey(hZonesKey
);
307 DestroyTimeZoneList(VOID
)
309 PTIMEZONE_ENTRY Entry
;
311 while (TimeZoneListHead
!= NULL
)
313 Entry
= TimeZoneListHead
;
315 TimeZoneListHead
= Entry
->Next
;
316 if (TimeZoneListHead
!= NULL
)
318 TimeZoneListHead
->Prev
= NULL
;
321 HeapFree(GetProcessHeap(), 0, Entry
);
324 TimeZoneListTail
= NULL
;
329 ShowTimeZoneList(HWND hwnd
)
331 TIME_ZONE_INFORMATION TimeZoneInfo
;
332 PTIMEZONE_ENTRY Entry
;
336 GetTimeZoneInformation(&TimeZoneInfo
);
340 Entry
= TimeZoneListHead
;
341 while (Entry
!= NULL
)
346 (LPARAM
)Entry
->Description
);
348 if (!wcscmp(Entry
->StandardName
, TimeZoneInfo
.StandardName
))
363 SetLocalTimeZone(HWND hwnd
)
365 TIME_ZONE_INFORMATION TimeZoneInformation
;
366 PTIMEZONE_ENTRY Entry
;
370 dwIndex
= SendMessage(hwnd
,
376 Entry
= TimeZoneListHead
;
386 wcscpy(TimeZoneInformation
.StandardName
,
387 Entry
->StandardName
);
388 wcscpy(TimeZoneInformation
.DaylightName
,
389 Entry
->DaylightName
);
391 TimeZoneInformation
.Bias
= Entry
->TimezoneInfo
.Bias
;
392 TimeZoneInformation
.StandardBias
= Entry
->TimezoneInfo
.StandardBias
;
393 TimeZoneInformation
.DaylightBias
= Entry
->TimezoneInfo
.DaylightBias
;
395 memcpy(&TimeZoneInformation
.StandardDate
,
396 &Entry
->TimezoneInfo
.StandardDate
,
398 memcpy(&TimeZoneInformation
.DaylightDate
,
399 &Entry
->TimezoneInfo
.DaylightDate
,
402 /* Set time zone information */
403 SetTimeZoneInformation(&TimeZoneInformation
);
408 GetAutoDaylightInfo(HWND hwnd
)
412 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
413 L
"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
419 if (RegQueryValueExW(hKey
,
420 L
"DisableAutoDaylightTimeSet",
426 SendMessage(hwnd
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
430 SendMessage(hwnd
, BM_SETCHECK
, (WPARAM
)BST_UNCHECKED
, 0);
438 SetAutoDaylightInfo(HWND hwnd
)
443 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
444 L
"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
450 if (SendMessage(hwnd
, BM_GETCHECK
, 0, 0) == BST_UNCHECKED
)
453 L
"DisableAutoDaylightTimeSet",
462 L
"DisableAutoDaylightTimeSet");
469 /* Property page dialog callback */
471 TimeZonePageProc(HWND hwndDlg
,
479 CreateTimeZoneList();
480 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
));
481 GetAutoDaylightInfo(GetDlgItem(hwndDlg
, IDC_AUTODAYLIGHT
));
485 if ((LOWORD(wParam
) == IDC_TIMEZONELIST
&& HIWORD(wParam
) == CBN_SELCHANGE
) ||
486 (LOWORD(wParam
) == IDC_AUTODAYLIGHT
&& HIWORD(wParam
) == BN_CLICKED
))
488 /* Enable the 'Apply' button */
489 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
494 DestroyTimeZoneList();
499 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
504 SetAutoDaylightInfo(GetDlgItem(hwndDlg
, IDC_AUTODAYLIGHT
));
505 SetLocalTimeZone(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
));
506 SetWindowLong(hwndDlg
, DWL_MSGRESULT
, PSNRET_NOERROR
);
522 InitPropSheetPage(PROPSHEETPAGE
*psp
, WORD idDlg
, DLGPROC DlgProc
)
524 ZeroMemory(psp
, sizeof(PROPSHEETPAGE
));
525 psp
->dwSize
= sizeof(PROPSHEETPAGE
);
526 psp
->dwFlags
= PSP_DEFAULT
;
527 psp
->hInstance
= hApplet
;
528 psp
->pszTemplate
= MAKEINTRESOURCE(idDlg
);
529 psp
->pfnDlgProc
= DlgProc
;
534 Applet(HWND hwnd
, UINT uMsg
, LONG wParam
, LONG lParam
)
537 PROPSHEETPAGE psp
[3];
540 LoadString(hApplet
, IDS_CPLNAME
, Caption
, sizeof(Caption
) / sizeof(TCHAR
));
542 ZeroMemory(&psh
, sizeof(PROPSHEETHEADER
));
543 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
544 psh
.dwFlags
= PSH_PROPSHEETPAGE
| PSH_PROPTITLE
;
545 psh
.hwndParent
= NULL
;
546 psh
.hInstance
= hApplet
;
547 psh
.hIcon
= LoadIcon(hApplet
, MAKEINTRESOURCE(IDC_CPLICON
));
548 psh
.pszCaption
= Caption
;
549 psh
.nPages
= sizeof(psp
) / sizeof(PROPSHEETPAGE
);
553 InitPropSheetPage(&psp
[0], IDD_DATETIMEPAGE
, DateTimePageProc
);
554 InitPropSheetPage(&psp
[1], IDD_TIMEZONEPAGE
, TimeZonePageProc
);
556 return (LONG
)(PropertySheet(&psh
) != -1);
560 /* Control Panel Callback */
562 CPlApplet(HWND hwndCpl
,
567 int i
= (int)lParam1
;
579 CPLINFO
*CPlInfo
= (CPLINFO
*)lParam2
;
581 CPlInfo
->idIcon
= Applets
[i
].idIcon
;
582 CPlInfo
->idName
= Applets
[i
].idName
;
583 CPlInfo
->idInfo
= Applets
[i
].idDescription
;
589 Applets
[i
].AppletProc(hwndCpl
, uMsg
, lParam1
, lParam2
);
598 DllMain(HINSTANCE hinstDLL
,
604 case DLL_PROCESS_ATTACH
:
606 INITCOMMONCONTROLSEX InitControls
;
608 InitControls
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
609 InitControls
.dwICC
= ICC_DATE_CLASSES
| ICC_PROGRESS_CLASS
| ICC_UPDOWN_CLASS
;
610 InitCommonControlsEx(&InitControls
);