Introduction

It shows how to calc 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 calculate 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 it's 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 divide 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 type of shutdown in the app;

In first type, a time is given and it is compared to the current time for ever 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 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 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 the those times be 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 it's 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 are 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.

推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架