2 * PROJECT: ReactOS Timedate Control Panel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/cpl/timedate/dateandtime.c
5 * PURPOSE: Date & Time property page
6 * COPYRIGHT: Copyright 2004-2007 Eric Kohl
7 * Copyright 2006 Ged Murphy <gedmurphy@gmail.com>
8 * Copyright 2006 Thomas Weidenmueller <w3seek@reactos.com>
14 static WNDPROC pOldWndProc
= NULL
;
17 SystemSetLocalTime(LPSYSTEMTIME lpSystemTime
)
21 TOKEN_PRIVILEGES priv
, previouspriv
;
25 * Enable the SeSystemtimePrivilege privilege
28 if (OpenProcessToken(GetCurrentProcess(),
29 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
,
32 priv
.PrivilegeCount
= 1;
33 priv
.Privileges
[0].Attributes
= SE_PRIVILEGE_ENABLED
;
35 if (LookupPrivilegeValueW(NULL
,
37 &priv
.Privileges
[0].Luid
))
39 if (AdjustTokenPrivileges(hToken
,
45 GetLastError() == ERROR_SUCCESS
)
48 * We successfully enabled it, we're permitted to change the system time
49 * Call SetLocalTime twice to ensure correct results
51 Ret
= SetLocalTime(lpSystemTime
) &&
52 SetLocalTime(lpSystemTime
);
55 * For the sake of security, restore the previous status again
57 if (previouspriv
.PrivilegeCount
> 0)
59 AdjustTokenPrivileges(hToken
,
76 SetLocalSystemTime(HWND hwnd
)
80 if (DateTime_GetSystemtime(GetDlgItem(hwnd
,
82 &Time
) == GDT_VALID
&&
83 SendMessageW(GetDlgItem(hwnd
,
89 SystemSetLocalTime(&Time
);
91 SetWindowLongPtrW(hwnd
,
95 SendMessageW(GetDlgItem(hwnd
,
101 /* Broadcast the time change message */
102 SendMessageW(HWND_BROADCAST
,
111 SetTimeZoneName(HWND hwnd
)
113 TIME_ZONE_INFORMATION TimeZoneInfo
;
114 WCHAR TimeZoneString
[128];
115 WCHAR TimeZoneText
[128];
116 WCHAR TimeZoneName
[128];
119 TimeZoneId
= GetTimeZoneInformation(&TimeZoneInfo
);
121 LoadStringW(hApplet
, IDS_TIMEZONETEXT
, TimeZoneText
, 128);
125 case TIME_ZONE_ID_STANDARD
:
126 wcscpy(TimeZoneName
, TimeZoneInfo
.StandardName
);
129 case TIME_ZONE_ID_DAYLIGHT
:
130 wcscpy(TimeZoneName
, TimeZoneInfo
.DaylightName
);
133 case TIME_ZONE_ID_UNKNOWN
:
134 LoadStringW(hApplet
, IDS_TIMEZONEUNKNOWN
, TimeZoneName
, 128);
137 case TIME_ZONE_ID_INVALID
:
139 LoadStringW(hApplet
, IDS_TIMEZONEINVALID
, TimeZoneName
, 128);
143 wsprintfW(TimeZoneString
, TimeZoneText
, TimeZoneName
);
144 SendDlgItemMessageW(hwnd
, IDC_TIMEZONE
, WM_SETTEXT
, 0, (LPARAM
)TimeZoneString
);
149 FillMonthsComboBox(HWND hCombo
)
151 SYSTEMTIME LocalDate
= {0};
156 GetLocalTime(&LocalDate
);
167 i
= GetLocaleInfoW(LOCALE_USER_DEFAULT
,
168 ((Month
< 13) ? LOCALE_SMONTHNAME1
+ Month
- 1 : LOCALE_SMONTHNAME13
),
170 sizeof(szBuf
) / sizeof(szBuf
[0]));
173 i
= (INT
)SendMessageW(hCombo
,
184 if (Month
== (UINT
)LocalDate
.wMonth
)
198 GetCBSelectedMonth(HWND hCombo
)
203 i
= (INT
)SendMessageW(hCombo
,
209 i
= (INT
)SendMessageW(hCombo
,
214 if (i
>= 1 && i
<= 13)
223 ChangeMonthCalDate(HWND hMonthCal
,
228 SendMessageW(hMonthCal
,
237 AutoUpdateMonthCal(HWND hwndDlg
,
238 PNMMCCAUTOUPDATE lpAutoUpdate
)
240 UNREFERENCED_PARAMETER(lpAutoUpdate
);
242 /* update the controls */
243 FillMonthsComboBox(GetDlgItem(hwndDlg
,
248 static INT_PTR CALLBACK
257 /* stop the timer when the user is about to change the time */
258 if ((wParam
!= VK_LEFT
) & (wParam
!= VK_RIGHT
))
259 KillTimer(GetParent(hwnd
), ID_TIMER
);
263 return CallWindowProcW(pOldWndProc
, hwnd
, uMsg
, wParam
, lParam
);
266 /* Property page dialog callback */
268 DateTimePageProc(HWND hwndDlg
,
279 FillMonthsComboBox(GetDlgItem(hwndDlg
,
282 SetTimer(hwndDlg
, ID_TIMER
, 1000, NULL
);
284 /* set range and current year */
285 SendMessageW(GetDlgItem(hwndDlg
, IDC_YEAR
), UDM_SETRANGE
, 0, MAKELONG ((short) 9999, (short) 1900));
286 SendMessageW(GetDlgItem(hwndDlg
, IDC_YEAR
), UDM_SETPOS
, 0, MAKELONG( (short) st
.wYear
, 0));
288 pOldWndProc
= (WNDPROC
) SetWindowLongPtrW(GetDlgItem(hwndDlg
, IDC_TIMEPICKER
), GWL_WNDPROC
, (INT_PTR
) DTPProc
);
292 SendMessageW(GetDlgItem(hwndDlg
, IDC_TIMEPICKER
), DTM_SETSYSTEMTIME
, GDT_VALID
, (LPARAM
) &st
);
296 switch (LOWORD(wParam
))
299 if (HIWORD(wParam
) == CBN_SELCHANGE
)
301 ChangeMonthCalDate(GetDlgItem(hwndDlg
,
304 GetCBSelectedMonth((HWND
)lParam
),
311 case WM_CTLCOLORSTATIC
:
312 if ((HWND
)lParam
== GetDlgItem(hwndDlg
, IDC_YEARTEXT
))
313 return (INT_PTR
)GetSysColorBrush(COLOR_WINDOW
);
318 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
320 switch (lpnm
->idFrom
)
328 LPNMUPDOWN updown
= (LPNMUPDOWN
)lpnm
;
329 wYear
= (SHORT
)SendMessageW(GetDlgItem(hwndDlg
, IDC_YEAR
), UDM_GETPOS
, 0, 0);
330 /* Enable the 'Apply' button */
331 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
332 ChangeMonthCalDate(GetDlgItem(hwndDlg
,
336 (WORD
) (wYear
+ updown
->iDelta
));
345 case DTN_DATETIMECHANGE
:
347 KillTimer(hwndDlg
, ID_TIMER
);
349 /* Tell the clock to stop ticking */
350 SendDlgItemMessageW(hwndDlg
, IDC_CLOCKWND
, CLM_STOPCLOCK
,
353 /* Enable the 'Apply' button */
354 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
359 case IDC_MONTHCALENDAR
:
363 /* Enable the 'Apply' button */
364 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
367 case MCCN_AUTOUPDATE
:
368 AutoUpdateMonthCal(hwndDlg
,
369 (PNMMCCAUTOUPDATE
)lpnm
);
378 SetTimeZoneName(hwndDlg
);
382 SetLocalSystemTime(hwndDlg
);
383 SetTimer(hwndDlg
, ID_TIMER
, 1000, NULL
);
385 /* Tell the clock to start ticking */
386 SendDlgItemMessageW(hwndDlg
, IDC_CLOCKWND
, CLM_STARTCLOCK
,
396 /* FIXME - we don't get this message as we're not a top-level window... */
397 SendMessageW(GetDlgItem(hwndDlg
,
405 KillTimer(hwndDlg
, ID_TIMER
);