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 SystemSetTime(LPSYSTEMTIME lpSystemTime
,
22 TOKEN_PRIVILEGES priv
, previouspriv
;
26 * Enable the SeSystemtimePrivilege privilege
29 if (OpenProcessToken(GetCurrentProcess(),
30 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
,
33 priv
.PrivilegeCount
= 1;
34 priv
.Privileges
[0].Attributes
= SE_PRIVILEGE_ENABLED
;
36 if (LookupPrivilegeValueW(NULL
,
38 &priv
.Privileges
[0].Luid
))
40 if (AdjustTokenPrivileges(hToken
,
46 GetLastError() == ERROR_SUCCESS
)
49 * We successfully enabled it, we're permitted to change the time.
50 * Check the second parameter for SystemTime and if TRUE set System Time.
51 * Otherwise, if FALSE set the Local Time.
52 * Call SetLocalTime twice to ensure correct results.
56 Ret
= SetSystemTime(lpSystemTime
);
60 Ret
= SetLocalTime(lpSystemTime
) &&
61 SetLocalTime(lpSystemTime
);
65 * For the sake of security, restore the previous status again
67 if (previouspriv
.PrivilegeCount
> 0)
69 AdjustTokenPrivileges(hToken
,
86 SetLocalSystemTime(HWND hwnd
)
90 if (DateTime_GetSystemtime(GetDlgItem(hwnd
,
92 &Time
) == GDT_VALID
&&
93 SendMessageW(GetDlgItem(hwnd
,
99 /* Set Local Time with SystemTime = FALSE */
100 SystemSetTime(&Time
, FALSE
);
102 SetWindowLongPtrW(hwnd
,
106 SendMessageW(GetDlgItem(hwnd
,
112 /* Broadcast the time change message */
113 SendMessageW(HWND_BROADCAST
,
122 SetTimeZoneName(HWND hwnd
)
124 TIME_ZONE_INFORMATION TimeZoneInfo
;
125 WCHAR TimeZoneString
[128];
126 WCHAR TimeZoneText
[128];
127 WCHAR TimeZoneName
[128];
130 TimeZoneId
= GetTimeZoneInformation(&TimeZoneInfo
);
132 LoadStringW(hApplet
, IDS_TIMEZONETEXT
, TimeZoneText
, 128);
136 case TIME_ZONE_ID_STANDARD
:
137 case TIME_ZONE_ID_UNKNOWN
:
138 wcscpy(TimeZoneName
, TimeZoneInfo
.StandardName
);
141 case TIME_ZONE_ID_DAYLIGHT
:
142 wcscpy(TimeZoneName
, TimeZoneInfo
.DaylightName
);
145 case TIME_ZONE_ID_INVALID
:
147 LoadStringW(hApplet
, IDS_TIMEZONEINVALID
, TimeZoneName
, 128);
151 wsprintfW(TimeZoneString
, TimeZoneText
, TimeZoneName
);
152 SendDlgItemMessageW(hwnd
, IDC_TIMEZONE
, WM_SETTEXT
, 0, (LPARAM
)TimeZoneString
);
157 FillMonthsComboBox(HWND hCombo
)
159 SYSTEMTIME LocalDate
= {0};
164 GetLocalTime(&LocalDate
);
175 i
= GetLocaleInfoW(LOCALE_USER_DEFAULT
,
176 ((Month
< 13) ? LOCALE_SMONTHNAME1
+ Month
- 1 : LOCALE_SMONTHNAME13
),
178 sizeof(szBuf
) / sizeof(szBuf
[0]));
181 i
= (INT
)SendMessageW(hCombo
,
192 if (Month
== (UINT
)LocalDate
.wMonth
)
206 GetCBSelectedMonth(HWND hCombo
)
211 i
= (INT
)SendMessageW(hCombo
,
217 i
= (INT
)SendMessageW(hCombo
,
222 if (i
>= 1 && i
<= 13)
231 ChangeMonthCalDate(HWND hMonthCal
,
236 SendMessageW(hMonthCal
,
245 AutoUpdateMonthCal(HWND hwndDlg
,
246 PNMMCCAUTOUPDATE lpAutoUpdate
)
248 UNREFERENCED_PARAMETER(lpAutoUpdate
);
250 /* Update the controls */
251 FillMonthsComboBox(GetDlgItem(hwndDlg
,
256 static INT_PTR CALLBACK
265 /* Stop the timer when the user is about to change the time */
266 if ((wParam
!= VK_LEFT
) & (wParam
!= VK_RIGHT
))
267 KillTimer(GetParent(hwnd
), ID_TIMER
);
271 return CallWindowProcW(pOldWndProc
, hwnd
, uMsg
, wParam
, lParam
);
274 /* Property page dialog callback */
276 DateTimePageProc(HWND hwndDlg
,
287 FillMonthsComboBox(GetDlgItem(hwndDlg
,
290 SetTimer(hwndDlg
, ID_TIMER
, 1000, NULL
);
292 /* Set range and current year */
293 SendMessageW(GetDlgItem(hwndDlg
, IDC_YEAR
), UDM_SETRANGE
, 0, MAKELONG ((short) 9999, (short) 1900));
294 SendMessageW(GetDlgItem(hwndDlg
, IDC_YEAR
), UDM_SETPOS
, 0, MAKELONG( (short) st
.wYear
, 0));
296 pOldWndProc
= (WNDPROC
)SetWindowLongPtrW(GetDlgItem(hwndDlg
, IDC_TIMEPICKER
), GWLP_WNDPROC
, (LONG_PTR
)DTPProc
);
300 SendMessageW(GetDlgItem(hwndDlg
, IDC_TIMEPICKER
), DTM_SETSYSTEMTIME
, GDT_VALID
, (LPARAM
) &st
);
304 switch (LOWORD(wParam
))
307 if (HIWORD(wParam
) == CBN_SELCHANGE
)
309 ChangeMonthCalDate(GetDlgItem(hwndDlg
,
312 GetCBSelectedMonth((HWND
)lParam
),
319 case WM_CTLCOLORSTATIC
:
320 if ((HWND
)lParam
== GetDlgItem(hwndDlg
, IDC_YEARTEXT
))
321 return (INT_PTR
)GetSysColorBrush(COLOR_WINDOW
);
326 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
328 switch (lpnm
->idFrom
)
336 LPNMUPDOWN updown
= (LPNMUPDOWN
)lpnm
;
337 wYear
= (SHORT
)SendMessageW(GetDlgItem(hwndDlg
, IDC_YEAR
), UDM_GETPOS
, 0, 0);
338 /* Enable the 'Apply' button */
339 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
340 ChangeMonthCalDate(GetDlgItem(hwndDlg
,
344 (WORD
) (wYear
+ updown
->iDelta
));
353 case DTN_DATETIMECHANGE
:
355 KillTimer(hwndDlg
, ID_TIMER
);
357 /* Tell the clock to stop ticking */
358 SendDlgItemMessageW(hwndDlg
, IDC_CLOCKWND
, CLM_STOPCLOCK
,
361 /* Enable the 'Apply' button */
362 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
367 case IDC_MONTHCALENDAR
:
371 /* Enable the 'Apply' button */
372 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
375 case MCCN_AUTOUPDATE
:
376 AutoUpdateMonthCal(hwndDlg
,
377 (PNMMCCAUTOUPDATE
)lpnm
);
386 SetTimeZoneName(hwndDlg
);
390 SetLocalSystemTime(hwndDlg
);
391 SetTimer(hwndDlg
, ID_TIMER
, 1000, NULL
);
393 /* Tell the clock to start ticking */
394 SendDlgItemMessageW(hwndDlg
, IDC_CLOCKWND
, CLM_STARTCLOCK
,
404 /* FIXME: We don't get this message as we're not a top-level window... */
405 SendMessageW(GetDlgItem(hwndDlg
,
413 KillTimer(hwndDlg
, ID_TIMER
);