Windows timers are mechanisms that let you set one or more timers to be triggered at a specific number of milliseconds. If you set a timer to be triggered at a 1,000 millisecond interval, it triggers every second. When a timer triggers, it sends a WM_TIMER message to your application. You can use the Class Wizard to add a function to your application to handle this timer message.
Timer events are placed only in the application event queue if that queue is empty and the application is idle. Windows does not place timer event messages in the application event queue if the application is already busy. If your application has been busy and has missed several timer event messages, Windows places only a single timer message in the event queue. Windows does not send your application all the timer event messages that occurred while your application was busy. It doesn’t matter how many timer messages your application may have missed; Windows still places only a single
timer message in your queue.
When you start or stop a timer, you specify a timer ID, which can be any integer value. Your application uses this timer ID to determine which timer event has triggered, as well as to start and stop timers.
Creating the Project and Application
To create the application, follow these steps:
1. Create a new project, named TimerEvent, using the same AppWizard settings.
2. Choose SingleDocument
3. In the Step 6 , choose the base class as CFormView.
4. Select the Dialog from the Resources and the following controls as show in the Table.
TABLE CONTROL PROPERTY SETTINGS.
Object | Property | Setting |
Static Text |
ID | IDC_STATIC |
Caption | Current Time: |
|
Edit Box |
ID | IDC_CURRTIME |
Static Text |
ID | IDC_STATIC |
Caption | User Timer |
|
Edit Box |
ID | IDC_USERTIME |
Static Text |
ID | IDC_STATIC |
Caption | Task | |
Combo Box |
ID | IDC_OPERATION |
Button | ID | IDC_CANCEL |
Caption | Change Usertime |
|
Button | ID | IDC_EXIT |
Caption | Exit |
Now, right click on the Combobox, go to properties window. Select the Tab DATA and enter the following data :
Lock
LogOff
ShutDown
Restart
Adding the Application Variables
You need to add a few variables to the controls. With the clock timer, you needed only a single variable for updating the clock display. Now you need to add a few other variables for the other controls, as listed in Table below. CONTROL VARIABLES:
Name
Category
Typem_cCancel
Control
CButtonm_sCurrtime
Value
CStringm_cOperation
Control
CComboBoxm_sUsertime
Value
CStringm_cUTime
Control
CEditm_cExit
Control
CButton
Object IDC_CANCEL IDC_CURRTIME IDC_OPERATION IDC_USERTIME IDC_USERTIME IDC_EXIT
After you add all the variables using the Class Wizard,
Adding the Timer IDs:
#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif Add the following Code after this code in the TimerEventView.cpp:
#define IDT_TIMER WM_USER + 200 int iHour,iMinute,iSecond; // Global Variables CString Label; BOOL Status=FALSE;
Add the following Variables in the TimerEventView.h in the public section
UINT Timeval;
Add the following function definitions in the TimerEventView.h .After this comment write the following code.
Protected: //Generated message map functions afx_msg UINT StartTimer (UINT TimerDuration); // Start the Timer afx_msg BOOL StopTimer (UINT TimerVal); // Stop the Timer afx_msg BOOL MyTask(CString strType); //Perform the Operation afx_msg void OnCheck(); // Perform the Validation afx_msg void OnUnlock(); // Unlock the System Starting the Clock Timer:
To start the clock timer, you need to edit the OnInitUpdate function Add the new code:
void CShutEvtView::OnInitialUpdate() { CFormView::OnInitialUpdate(); GetParentFrame()->RecalcLayout(); ResizeParentToFit(); /*My Code Starts Here*/ m_cUTime.SetFocus(); m_cCancel.EnableWindow(FALSE); Timeval=StartTimer(1000); SetWindowPos(&CWnd::wndTop, 670, 350, 0, 0, SWP_SHOWWINDOW|SWP_NOSIZE); }
THE StartTimer FUNCTION:
UINT CTimerEventView::StartTimer (UINT TimerDuration) { UINT TimerVal; TimerVal = SetTimer (IDT_TIMER,TimerDuration, NULL); // Starting the Timer if (TimerVal == 0){ AfxMessageBox("Unable to obtain timer"); } return TimerVal; }// end StartTimer
THE StopTimer FUNCTION:
BOOL CTimerEventView::StopTimer (UINT TimerVal) { if (!KillTimer (TimerVal)) { return FALSE; } // Place clean-up code following this point. return TRUE; } // end StopTimer
THE OnCancel FUNCTION:
void CTimerEventView::OnCancel() { m_cUTime.EnableWindow(TRUE); //Enabling the Shutdown Time Edit Control m_cExit.EnableWindow(TRUE); //Enable Exit Button m_cOperation.EnableWindow(TRUE); //Enable List Control Status=TRUE; }
THE OnExit FUNCTION:
void CTimerEventView::OnExit()
{
if(StopTimer(Timeval)==FALSE)
::MessageBox(NULL,”Error While
Killing the Timer”,”ShutEvt”,1);
::PostQuitMessage(1);
}
THE OnUnlock FUNCTION:
void CTimerEventView::OnUnlock() { WinExec("rundll32 user32.dll,LockWorkStation",1); //Lock the System }
THE OnCheck FUNCTION:
This functions is to validate the date entered by user
void CTimerEventView::OnCheck() { int iLHour,iLMinute; CString tmpTime,subTime; UpdateData(); tmpTime=m_sUserTime; iLHour=tmpTime.Find(":",0); subTime=tmpTime.Left(iLHour); iHour=atoi(subTime); if(iLHour==2 && iHour>=0 && iHour<=24) { iLMinute=tmpTime.Find(":",iLHour); subTime=tmpTime.Mid(iLHour+1); subTime=subTime.Left(iLMinute); iMinute=atoi(subTime); if(iLMinute==2 && iMinute>=0 && iMinute<=60) { iSecond=atoi(tmpTime.Right(2)); if(iSecond>=0 && iSecond<=60) { m_cUTime.EnableWindow(FALSE); m_cCancel.EnableWindow(TRUE); m_cExit.EnableWindow(FALSE); m_cOperation.EnableWindow(FALSE); } else ::MessageBox(NULL,"Enter the Date in HH:MM:SS nn OR nn Seconds Should be between 0 and 60","ShutEvt",1); } else ::MessageBox(NULL,"Enter the Date in HH:MM:SSnn OR nn Minutes Should be between 0 and 60","ShutEvt",1); } else ::MessageBox(NULL,"Enter the Date in HH:MM:SS nn OR nn Hour should be between 0 and 24","ShutEvt",1); }
THE MyTask FUNCTION:
This function is to perform the task selected by user from the CComboBox
BOOL CTimerEventView::MyTask(CString strType) { HANDLE hToken; TOKEN_PRIVILEGES tkp; // Stop the timer before shutdown StopTimer(Timeval); // Get a token for this process. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return( FALSE ); // Get the LUID for the shutdown privilege. LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; //one privilege to set tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // Get the shutdown privilege for this process. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); if (GetLastError() != ERROR_SUCCESS) return FALSE; // Shut down the system and force all applications to close. // if (!ExitWindowsEx(EWX_POWEROFF | EWX_POWEROFF | EWX_FORCE, 0)) if(strType=="LogOff") { if(!ExitWindowsEx(EWX_LOGOFF | EWX_FORCE, 0)) return FALSE; } else if(strType=="ShutDown") { if(!ExitWindowsEx(EWX_SHUTDOWN|EWX_POWEROFF| EWX_FORCE, 0)) return FALSE; } else if(strType=="Restart") { if(!ExitWindowsEx(EWX_REBOOT| EWX_FORCE, 0)) return FALSE; } return TRUE; }
THE OnSelchangeOperation FUNCTION:
Add this function through ClassWizard for the Comboxbox Control.(CBN_SELCHANGE)
void CTimerEventView::OnSelchangeOperation() { Status=FALSE; int Selection=m_cOperation.GetCurSel(); OnCheck(); m_cOperation.GetLBText(Selection,Label); }
Handling the Clock Timer Event
Now that you’ve started a timer, you need to add the code to handle the timer event message. You can do this by following these steps:
1. Using the Class Wizard, add a variable to the IDC_STATIC control of type CString named m_sCurrtime.
2. Using the Class Wizard, add a function to handle the WM_TIMER message for the CTimerEvent object.
3. Edit the OnTimer function, adding the following code:
THE OnTimer FUNCTION.
void CTimerEventView::OnTimer(UINT nIDEvent) { CTime ct=CTime::GetCurrentTime(); char *str=new char[10];
UpdateData();
m_sCurrtime.Format(“%d : %d : %d “,ct.GetHour(),ct.GetMinute(),ct.GetSecond());
UpdateData(FALSE);
if(iHour==ct.GetHour() && iMinute==ct.GetMinute() && iSecond==ct.GetSecond() && Label==”Lock” && Status==FALSE)
{
OnUnlock();
m_cUTime.EnableWindow(TRUE);
//Enabling the Shutdown Time Edit Control
m_cExit.EnableWindow(TRUE);
//Enable Exit Button
m_cOperation.EnableWindow(TRUE);
//Enable List Control
//StopTimer(Timeval);
Status=TRUE;
}
if(iHour==ct.GetHour() && iMinute==ct.GetMinute() && iSecond==ct.GetSecond() && Label==”LogOff” && Status==FALSE)
{
MyTask (“LogOff”);
}
if(iHour==ct.GetHour() && iMinute==ct.GetMinute() && iSecond==ct.GetSecond() && Label==”ShutDown” && Status==FALSE)
{
MyTask (“ShutDown”);
}
if(iHour==ct.GetHour() && iMinute==ct.GetMinute() && iSecond==ct.GetSecond() && Label==”Restart” && Status==FALSE)
{
MyTask (“Restart”);
}
delete [] str;
CFormView::OnTimer(nIDEvent);
}
Download the Sample Project here.