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 case TIME_ZONE_ID_UNKNOWN
:
127 wcscpy(TimeZoneName
, TimeZoneInfo
.StandardName
);
130 case TIME_ZONE_ID_DAYLIGHT
:
131 wcscpy(TimeZoneName
, TimeZoneInfo
.DaylightName
);
134 case TIME_ZONE_ID_INVALID
:
136 LoadStringW(hApplet
, IDS_TIMEZONEINVALID
, TimeZoneName
, 128);
140 wsprintfW(TimeZoneString
, TimeZoneText
, TimeZoneName
);
141 SendDlgItemMessageW(hwnd
, IDC_TIMEZONE
, WM_SETTEXT
, 0, (LPARAM
)TimeZoneString
);
146 FillMonthsComboBox(HWND hCombo
)
148 SYSTEMTIME LocalDate
= {0};
153 GetLocalTime(&LocalDate
);
164 i
= GetLocaleInfoW(LOCALE_USER_DEFAULT
,
165 ((Month
< 13) ? LOCALE_SMONTHNAME1
+ Month
- 1 : LOCALE_SMONTHNAME13
),
167 sizeof(szBuf
) / sizeof(szBuf
[0]));
170 i
= (INT
)SendMessageW(hCombo
,
181 if (Month
== (UINT
)LocalDate
.wMonth
)
195 GetCBSelectedMonth(HWND hCombo
)
200 i
= (INT
)SendMessageW(hCombo
,
206 i
= (INT
)SendMessageW(hCombo
,
211 if (i
>= 1 && i
<= 13)
220 ChangeMonthCalDate(HWND hMonthCal
,
225 SendMessageW(hMonthCal
,
234 AutoUpdateMonthCal(HWND hwndDlg
,
235 PNMMCCAUTOUPDATE lpAutoUpdate
)
237 UNREFERENCED_PARAMETER(lpAutoUpdate
);
239 /* Update the controls */
240 FillMonthsComboBox(GetDlgItem(hwndDlg
,
245 static INT_PTR CALLBACK
254 /* Stop the timer when the user is about to change the time */
255 if ((wParam
!= VK_LEFT
) & (wParam
!= VK_RIGHT
))
256 KillTimer(GetParent(hwnd
), ID_TIMER
);
260 return CallWindowProcW(pOldWndProc
, hwnd
, uMsg
, wParam
, lParam
);
263 /* Property page dialog callback */
265 DateTimePageProc(HWND hwndDlg
,
276 FillMonthsComboBox(GetDlgItem(hwndDlg
,
279 SetTimer(hwndDlg
, ID_TIMER
, 1000, NULL
);
281 /* Set range and current year */
282 SendMessageW(GetDlgItem(hwndDlg
, IDC_YEAR
), UDM_SETRANGE
, 0, MAKELONG ((short) 9999, (short) 1900));
283 SendMessageW(GetDlgItem(hwndDlg
, IDC_YEAR
), UDM_SETPOS
, 0, MAKELONG( (short) st
.wYear
, 0));
285 pOldWndProc
= (WNDPROC
) SetWindowLongPtrW(GetDlgItem(hwndDlg
, IDC_TIMEPICKER
), GWL_WNDPROC
, (INT_PTR
) DTPProc
);
289 SendMessageW(GetDlgItem(hwndDlg
, IDC_TIMEPICKER
), DTM_SETSYSTEMTIME
, GDT_VALID
, (LPARAM
) &st
);
293 switch (LOWORD(wParam
))
296 if (HIWORD(wParam
) == CBN_SELCHANGE
)
298 ChangeMonthCalDate(GetDlgItem(hwndDlg
,
301 GetCBSelectedMonth((HWND
)lParam
),
308 case WM_CTLCOLORSTATIC
:
309 if ((HWND
)lParam
== GetDlgItem(hwndDlg
, IDC_YEARTEXT
))
310 return (INT_PTR
)GetSysColorBrush(COLOR_WINDOW
);
315 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
317 switch (lpnm
->idFrom
)
325 LPNMUPDOWN updown
= (LPNMUPDOWN
)lpnm
;
326 wYear
= (SHORT
)SendMessageW(GetDlgItem(hwndDlg
, IDC_YEAR
), UDM_GETPOS
, 0, 0);
327 /* Enable the 'Apply' button */
328 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
329 ChangeMonthCalDate(GetDlgItem(hwndDlg
,
333 (WORD
) (wYear
+ updown
->iDelta
));
342 case DTN_DATETIMECHANGE
:
344 KillTimer(hwndDlg
, ID_TIMER
);
346 /* Tell the clock to stop ticking */
347 SendDlgItemMessageW(hwndDlg
, IDC_CLOCKWND
, CLM_STOPCLOCK
,
350 /* Enable the 'Apply' button */
351 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
356 case IDC_MONTHCALENDAR
:
360 /* Enable the 'Apply' button */
361 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
364 case MCCN_AUTOUPDATE
:
365 AutoUpdateMonthCal(hwndDlg
,
366 (PNMMCCAUTOUPDATE
)lpnm
);
375 SetTimeZoneName(hwndDlg
);
379 SetLocalSystemTime(hwndDlg
);
380 SetTimer(hwndDlg
, ID_TIMER
, 1000, NULL
);
382 /* Tell the clock to start ticking */
383 SendDlgItemMessageW(hwndDlg
, IDC_CLOCKWND
, CLM_STARTCLOCK
,
393 /* FIXME: We don't get this message as we're not a top-level window... */
394 SendMessageW(GetDlgItem(hwndDlg
,
402 KillTimer(hwndDlg
, ID_TIMER
);