• The 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
      Collapse Copy Code
      BOOL ExitWindowsEx
      (
        UINT uFlags, // shutdown operation 
        DWORD dwReason // shutdown reason
      );

      Advantage: Works with all Operating Systems.

    • InitiateSystemShutdown
      Collapse Copy Code
      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:

    Collapse Copy Code
    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:

    Collapse Copy Code
     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

    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.

    Collapse Copy Code
    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:

    Collapse Copy Code
    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:

    Collapse Copy Code
    #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:

    Collapse Copy Code
    Shell_NotifyIcon(NIM_ADD,&m_niData);

    For modifying the icon:

    Collapse Copy Code
      //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:

    Collapse Copy Code
      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:

    Collapse Copy Code
      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.

    Collapse Copy Code
            .....................
            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.

    Collapse Copy Code
    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

    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

    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

  • 相关阅读:
    在window10系统下安装redis
    Dubbo 基础用法
    vue处理对象值改变时dom值没有跟着变化的问题
    KMP算法
    Leetcode 502 IPO
    vue页面无法正常渲染的问题
    vue锚点双向绑定
    JavaScript克隆一个对象
    el-table刷新后table出现抖动现象
    el-table组件去掉滚动条的问题
  • 原文地址:https://www.cnblogs.com/wuhenke/p/1753500.html
Copyright © 2020-2023  润新知