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:
|
Object
|
Name
|
Category
|
Type
|
|
IDC_CANCEL
|
m_cCancel
|
Control
|
CButton
|
|
IDC_CURRTIME
|
m_sCurrtime
|
Value
|
CString
|
|
IDC_OPERATION
|
m_cOperation
|
Control
|
CComboBox
|
|
IDC_USERTIME
|
m_sUsertime
|
Value
|
CString
|
|
IDC_USERTIME
|
m_cUTime
|
Control
|
CEdit
|
|
IDC_EXIT
|
m_cExit
|
Control
|
CButton
|
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 \n\n OR \n\n Seconds
Should be between 0 and 60","ShutEvt",1);
}
else
::MessageBox(NULL,"Enter the Date
in HH:MM:SS\n\n OR \n\n Minutes Should be between 0 and
60","ShutEvt",1);
}
else
::MessageBox(NULL,"Enter the Date
in HH:MM:SS \n\n OR \n\n 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.