Introduction
It shows how to calculate system up time, set an alarm, set when the system turns off itself, threading in MFC, etc.
Describing the Code
Getting System Time
It gets current time with function CTime
class and calculates system up time as shown:
DWORD dwD,dwH,dwM,dwS;
CTime t = CTime::GetCurrentTime();
CString s = t.Format(_T("%#c"));
DWORD tick = GetTickCount();
tick /= 1000;
dwD = tick / 86400;
dwH = tick / 3600;
dwM = (tick % 3600)/60;
dwS = (tick % 3600)%60;
First declare a variable of type CTime
, then use its GetCurrentTime
method, and finally format the result by using "%#c
" format specifier.
For getting system up time, first we call GetTickCount()
.
It gives the number of milliseconds that have elapsed since the system was started, up to 49.7 days, then divides it by 1000 to get seconds.
After getting elapsed seconds, we can convert them to day:hour:minute:second notation like above.
Shutting Down the System
We have 2 types of shutdown in the app.
In the first type, a time is given and it is compared to the current time forever in a thread, as soon as the comparison is true
, the system is turned off.
for(;;)
{
if(m_bShutdownThread == false)
return 0;
GetLocalTime(&time);
if(
time.wHour == m_ShutdownTime.wHour &&
time.wSecond == m_ShutdownTime.wSecond &&
time.wMinute == m_ShutdownTime.wMinute
)
ShutdownWindows();
}
In the second type, a time in notation of day:hour:minute:second
is given and it is checked to see whether the time is elapsed in a thread as discussed in the above.
If the time is elapsed, system gets turned off.
DWORD dwD,dwH,dwM,dwS;
DWORD tick;
for(;;)
{
if(m_bUpTimeShutdownThread == false)
return 0;
tick = GetTickCount();
tick /= 1000;
dwD = tick / 86400;
dwH = tick / 3600;
dwM = (tick % 3600)/60;
dwS = (tick % 3600)%60;
if(m_UpTimeShutdownTime.wMinute == dwM &&
m_UpTimeShutdownTime.wSecond == dwS &&
m_UpTimeShutdownTime.wHour == dwH &&
m_UpTimeShutdownTime.wDay == dwD
)
ShutdownWindows();
}
Alarm
In the alarm section, user gives a time, a thread will be started and the current time is compared to the given time.
If those times are equal, a sound is played with function PlaySound
and the app flashes!
SYSTEMTIME time;
for(;;)
{
if(m_bAlarmThread == false)
return 0;
GetLocalTime(&time);
if(
time.wHour == m_AlarmTime.wHour &&
time.wSecond == m_AlarmTime.wSecond &&
time.wMinute == m_AlarmTime.wMinute
)
{
GetDlgItem(IDC_SETTURNOFF2)->EnableWindow();
GetDlgItem(IDC_CANCELALARM)->EnableWindow(FALSE);
GetDlgItem(IDC_HOUR2)->EnableWindow();
GetDlgItem(IDC_MINUTE2)->EnableWindow();
GetDlgItem(IDC_SECOND2)->EnableWindow();
FlashWindowEx(FLASHW_ALL,-1,0);
PlaySoundW(_T("alarm.wav"),
NULL,SND_LOOP|SND_FILENAME|SND_ASYNC);
GetDlgItem(IDC_MUTE)->EnableWindow();
CStringW strOut;
strOut.Format(_T(""));
GetDlgItem(IDC_AOUT)->SetWindowTextW(strOut);
break;
}
}
Some Notes
For shutting down, the app adjusts its Privilege
, and the calls function ExitWindowEx()
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) ;
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
&tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
(PTOKEN_PRIVILEGES)NULL, 0);
ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE,
SHTDN_REASON_MAJOR_OPERATINGSYSTEM |
SHTDN_REASON_MINOR_UPGRADE |
SHTDN_REASON_FLAG_PLANNED) ;
Points of Interest
There is a lot of GUI handling code in this application, but those are unrelated to the subject, so I haven't shown them in the article.
History
- 6th January, 2011: Initial post