Click here to Skip to main content
15,884,472 members
Articles / Desktop Programming / MFC

The ShutDown Alarm

Rate me:
Please Sign up or sign in to vote.
3.19/5 (27 votes)
13 Dec 2004CPOL5 min read 146.1K   3.5K   51   29
This application does shutdown, restart, logoff and power off on a given computer at a given time. It works on all OS.

ShutDown Alarm

Introduction

Before going in detail about the application, let me tell you what this application will do? As the name suggests, it is used for shutdown, log off or restarting of the computer at a user defined time.

So what is its use?

Today, the world is going digitized. Every thing is running day & night, but not human body; it needs rest. Think of a situation when at night, you want to download your favorite song or favorite software, or you want to defragment your hard disk or burn a CDR, or do some time consuming work, where your sitting for it is not required, But you have to sit, waiting for the task to complete so that you can switch off your PC, as if it is left open, it will waste precious net usage, electricity, and electrical component life of your PC.

So one day, me and my friend came up with a solution: Shutdown Timer/Alarm, that will shutdown your computer at a user defined time. It provides both IN and AT option; means, for e.g., you can shutdown your computer in 2 hrs or you can shutdown your computer at 1.00 PM. Me and my friend decided to release the software with source code so that other users get benefited with it and also we can find bugs in our application.

So how am I achieving it? (What is the code behind it?)

Basic power behind this software is some Win32 APIs, that provide support for shutdown of the computer. There are two APIs to achieve it; these are:

  • ExitWindowEx
    BOOL ExitWindowsEx
    (
      UINT uFlags, // shutdown operation 
      DWORD dwReason // shutdown reason
    );

    Advantage: Works with all Operating Systems.

  • InitiateSystemShutdown
    BOOL InitiateSystemShutdown
    ( 
        LPTSTR lpMachineName, // computer name 
        LPTSTR lpMessage, // message to display 
        DWORD dwTimeout, // length of time to display 
        BOOL bForceAppsClosed, // force closed option 
        BOOL bRebootAfterShutdown // reboot option 
    );

    Disadvantage: No support for Windows 9x/ME.

To provide backward sompatibility, I have written this software using the ExitWindowEx API.

Some Code Snippets

To shutdown the computer in Windows 9x/ME is very simple. Just call the ExitWindowEx with required parameters to perform system command. I.e., this way:

ExitWindowEx(EWX_SHUTDOWN,0);

Oh, I forgot to tell you about the various flags provided to perform different tasks by ExitWindowEx. Here are the options:

  • EWX_LOGOFF: Logoff the current user.
  • EWX_RESTART: Simply restart the computer.
  • EWX_SHUTDOWN: Shut down but 'AT' style.
  • EWX_POWEROFF: Shut down but 'ATX' style.

For forcibly shutting off your computer, you can use EWX_FORCE in combination with above four flags. Now, it is not that easy to shut down your computer under Windows multi-user systems like Window 2000 and XP (built on NT technology); you have to acquire the security privilege know as SE_SHUTDOWN_NAME to provide successful shutdown action.

Here is a code snippet to achieve that:

HANDLE hToken; // handle to process token

TOKEN_PRIVILEGES tkp; // pointer to token structure

OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken);

// Get the LUID for shutdown privilege.

LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);

tkp.PrivilegeCount = 1; // one privilege to set

 // Get shutdown privilege for this process.
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

AdjustTokenPrivileges(hToken,FALSE, &tkp,(PTOKEN_PRIVILEGES) NULL, 0);

// Cannot test the return value of AdjustTokenPrivileges.

if(GetLastError() != ERROR_SUCCESS)
{
       MessageBox("AdjustTokenPrivileges enable failed.");
       return;
}

Note: if you don’t enable SE_SHUTDOWN_NAME privilege, your computer will just logoff after ExitWindowEx or InitiateSystemShutdown API is called.

About System Tray Interface

This software has system tray interface, i.e., it can be operated from system tray. If you don’t know where system tray is, here I locate that for you:

System Tray

Image 2

Now you are wondering how to achieve that. It is very simple using the simple API names Shell_NotifyIcon. Here is the function declaration for Shell_NotifyIcon API.

BOOL Shell_NotifyIcon( DWORD dwMessage, PNOTIFYICONDATA lpdata);

Here are possible value of dwMessage:

  • NIM_ADD: add icon to system tray.
  • NIM_DELETE: delete icon from system tray.
  • NIM_MODIFY: modify the system tray icon.

(For e.g., when you connect to Yahoo! chat using Yahoo! messenger, the icon becomes active. And when you logoff, the icon becomes inactive).

And for parameter two, i.e., lpData, it is a pointer to the NOTIFYICONDATA structure which is some thing like this:

typedef struct  _NOTIFYICONDATA  { 
    DWORD cbSize;
    HWND  hWnd; 
    UINT  uID; 
    UINT  uFlags; 
    UINT  uCallbackMessage;
    HICON hIcon; 
    
    #if (_WIN32_IE < 0x0500)
     TCHAR szTip[64]; 
    #else 
     TCHAR szTip[128]; 
    #endif ) 
    
    DWORD dwState;
 } NOTIFYICONDATA,*PNOTIFYICONDATA;

Here is a little information for each:

  • cbSize: this variable is created to provide compatibility with other versions of NotifyIconData.
  • hIcon: icon for the system tray.
  • hWnd: handle to window which will handle the system tray icon message.
  • szTip: show tip when mouse hovers over icon.
  • CallbackMessage: application-defined message identifier. The system uses this identifier to send notifications to the window identified in hWnd. These notifications are sent when a mouse event occurs in the bounding rectangle of the icon, or when the icon is selected or activated with the keyboard.
  • uFlag: this flag notifies the system which of the above variables are to be used or not.
  • uID: any unique ID for icon.

Now, how to use that! That’s very simple. Just fill the required details and give the proper handle of the icon to the hIcon parameter to successfully plant an icon in the system bar. Let's say you have two handles for the icon: hIconSleep, hIconWake.

Now, here I initialize the structure:

#define MY_MESSAGE WM_APP+75
 ....
 NOTIFYICONDATA m_niData; //handling the ICON at System Tray Icon
 
 m_niData.cbSize=sizeof(NOTIFYICONDATA);
 m_niData.hIcon= hIconSleep; 
 m_niData.hWnd=this->m_hWnd; 
 sprintf(m_niData.szTip,"Shut Down Alarm :My Father Software inc @ 2003");
 m_niData.uCallbackMessage=MY_MESSAGE; 
 m_niData.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP;
 m_niData.uID=10001; 
 ......

For adding the icon to system tray:

Shell_NotifyIcon(NIM_ADD,&m_niData);

For modifying the icon:

  //now I am planting new Icon just Like Yahoo
  // does by showing Online and Offline status
  m_niData.hIcon= hIconWake; 
  Shell_NotifyIcon(NIM_MODIFY,&m_niData);

For deleting the icon from system tray:

Shell_NotifyIcon(NIM_DELETE,&m_niData);

Now, many of you must be wondering: when we click or right click the icon of any application on the system tray, a menu becomes visible; now how to get that menu? If you read the above source code, one member of the NotifyIcon structure helps in this case, which is:

  m_niData.uCallbackMessage=MY_MESSAGE;

That means, you have to handle MY_MESSAGE window message to handle the message by your system tray icon. Now, it's very important to note that to receive the message, it is essential to pass NIF_MESSAGE flag in m_niData.uFlags.

.....................
BEGIN_MESSAGE_MAP(you class, you parent class)
    ON_MESSAGE(MY _MESSAGE,OnSystemTrayMessage)
END_MESSAGE_MAP()
......................

Now to show popup menu or for doing some other task, here is a function that will handle that prerequisite: a menu IDR_MENU1 in your resource file.

void DlgShutDown::OnSystemBarMessage(WPARAM wParam, LPARAM lParam) 
{
 //check for window Message which come in LPARAM parameter 
 
 Switch(lParam)
 { 
    case WM_LBUTTONDOWN: 
            this->ShowWindow(SW_RESTORE); 
            bMiniShow=FALSE;
            break; 

    case WM_RBUTTONDOWN: 
        {
            //Now we are showing the menu on Right Click

            CMenu mnu; //load the Menu from resource
            mnu.LoadMenu(IDR_MENU1);
            CMenu *PopUpMenu; //get the popup menu form the Menu 

            PopUpMenu=mnu.GetSubMenu(0);
            CPoint pt; //get the current cursor position
            GetCursorPos(&pt); //show the popup menu

            PopUpMenu->TrackPopupMenu(TPM_RIGHTALIGN, 
                          pt.x,pt.y,this); break;
        }
  }
 }

You can handle the popup menu messages in your current dialog class.

How to Use it?

Using in ‘AT ‘way:-

Here is a graphic which shows how to use it in ‘at’ way:

Figure Showing 'AT' Way

Image 3

Here are the steps:

  • Step 1: Choose 'AT' way, i.e., Alarm.
  • Step 2: Set time.
  • Step 3: Set option for logoff, restart or shutdown.
  • Step 4: Click on button Set Timer to activate the timer.

Using ‘IN’ way

Here is a graphic that shows in way:

Figure Showing 'IN' Way

Image 4

Here are the steps:

  • Step 1: Choose 'IN' way, i.e., Time Out option.
  • Step 2: Set time.
  • Step 3: Set option for logoff, restart or shutdown.
  • Step 4: Click on button Set Timer to activate timer.

Update History

  • Version 1.1: Some bugs fixed. Minimize is now working without problem. Force option added.
  • Version 1.0: First release.

Special Thanks

  • My Parents
  • My friends

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
India India
He used to have biography here Smile | :) , but now he will hire someone (for free offcourse Big Grin | :-D ), Who writes his biography on his behalf Smile | :)

He is Great Fan of Mr. Johan Rosengren (his idol),Lim Bio Liong, Nishant S and DavidCrow and Believes that, he will EXCEL in his life by following there steps!!!

He started with Visual C++ then moved to C# then he become language agnostic, you give him task,tell him the language or platform, he we start immediately, if he knows the language otherwise he quickly learn it and start contributing productively

Last but not the least, For good 8 years he was Visual CPP MSMVP!

Comments and Discussions

 
GeneralGood job Pin
Mustafa Öner Dikdere (TR)4-Nov-07 5:34
Mustafa Öner Dikdere (TR)4-Nov-07 5:34 
GeneralRe: Good job Pin
ThatsAlok6-Mar-08 22:54
ThatsAlok6-Mar-08 22:54 
GeneralIf anyone needs a win32 version... Pin
e-sushi22-Apr-07 6:17
e-sushi22-Apr-07 6:17 
GeneralRe: If anyone needs a win32 version... Pin
ThatsAlok6-Mar-08 22:54
ThatsAlok6-Mar-08 22:54 
GeneralTurn off secondary monitor Pin
AKG23-Mar-07 2:50
AKG23-Mar-07 2:50 
GeneralInitiateSystemShutdown Pin
GuxBlack5-May-06 9:19
GuxBlack5-May-06 9:19 
Generalshutdown Pin
y_naga_malleswararao23-Feb-06 23:30
y_naga_malleswararao23-Feb-06 23:30 
GeneralRe: shutdown Pin
ThatsAlok25-Feb-06 19:08
ThatsAlok25-Feb-06 19:08 
GeneralLittle trouble Pin
meinhard_risch2-Mar-05 0:39
meinhard_risch2-Mar-05 0:39 
GeneralRe: Little trouble Pin
ThatsAlok23-Mar-05 18:37
ThatsAlok23-Mar-05 18:37 
GeneralResearch Research and more Research Pin
Anonymous14-Dec-04 7:31
Anonymous14-Dec-04 7:31 
GeneralRe: Research Research and more Research [modified] Pin
ThatsAlok15-Dec-04 17:31
ThatsAlok15-Dec-04 17:31 
Anonymous wrote:
The solution is already builtin windows http://www.pcmag.com/article2/0,1759,156438,00.asp[^]

Thanks for nice link, frankly speaking really I don't know that Window XP support this Feature.

Thanks



-----------------------------

modified on Friday, March 7, 2008 4:55 AM

GeneralNice Thing... Pin
vobject13-Dec-04 21:10
vobject13-Dec-04 21:10 
GeneralRe: Nice Thing... Pin
Ravi Bhavnani14-Dec-04 7:39
professionalRavi Bhavnani14-Dec-04 7:39 
GeneralRe: Nice Thing... Pin
15-Dec-04 17:25
suss15-Dec-04 17:25 
Questionwhy ? Pin
toxcct5-Oct-04 23:19
toxcct5-Oct-04 23:19 
AnswerRe: why ? Pin
ThatsAlok6-Oct-04 1:49
ThatsAlok6-Oct-04 1:49 
GeneralRe: why ? Pin
toxcct6-Oct-04 1:55
toxcct6-Oct-04 1:55 
GeneralRe: why ? Pin
ThatsAlok6-Oct-04 19:49
ThatsAlok6-Oct-04 19:49 
GeneralRe: why ? Pin
toxcct6-Oct-04 20:30
toxcct6-Oct-04 20:30 
GeneralRe: why ? [modified] Pin
ThatsAlok7-Oct-04 2:02
ThatsAlok7-Oct-04 2:02 
AnswerRe: why ? Pin
renato tome24-Nov-04 15:45
renato tome24-Nov-04 15:45 
GeneralRe: why ? Pin
ThatsAlok24-Nov-04 17:12
ThatsAlok24-Nov-04 17:12 
GeneralRe: why ? Pin
toxcct24-Nov-04 20:55
toxcct24-Nov-04 20:55 
GeneralWay Cool! Pin
therf8-Jul-04 10:08
therf8-Jul-04 10:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.