关于自动关机程序设计说明书

关于设计。
《1》
感谢。
在这个小程序的制作过程中,作者我遇到了许多许多技术或非技术的问题。
许多的问题作者由于能力有限,自己无法解决,所以作者在网上看了大量资料,
使的自己能力有了提高和这个小作品的问世。
在此,
感谢编程牛人宋雷
感谢SDK路报的作者在网上提供的相关资料!
感谢常州VC编程网给予我巨大的技术资料。
感谢所有无私分享技术,资料和代码的无私程序员和相关人员。
   
关于作者。
本程序的作者是北京交通大学软件学院的红火蚁,如果您对作者的这个程序有什么意见或想法,欢迎您通过E-mail和作者联系。
作者E-mail:hello-lucky-dog@163.com
     QQ: 282948182
         379510638
关于界面介绍。

首先我们来看看怎样才能实现电脑关机的功能啊,或许你回赶紧回答用ShutDown()这个函数啊,但是如果在XP(其他环境下我没使过)直接调用ShutDown()在按照MSDN上的参数传给它时,你就会发现情况不好使了,怎么只能注销,不能关机啊?呵呵,这个你不能直接关机,因为你的权限不够,那怎么弄呢?好,下来让我们解决这个问题,看下面的代码:
  DWORD g_version;
    g_version = GetVersion(); /* 得到版本 */
if (g_version < 0x80000000)  /* NT系列 */
  {
     HANDLE handle;
     TOKEN_PRIVILEGES tp;
       // 提升权限 
     OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &handle);
     LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tp.Privileges[0].Luid);
     tp.PrivilegeCount = 1;
     tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
     AdjustTokenPrivileges(handle, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
       // 关机
     ExitWindowsEx(EWX_SHUTDOWN, 0);
  }
  else /* 9X系列 */
  {
       ExitWindowsEx(EWX_SHUTDOWN, 0);    
  }
这段代码就是判断是不是NT系列,如果是,就要提升用户的权限OpenProcessToken(),
LookupPrivilegeValue(),AdjustTokenPrivileges()读者可以在MSDN上看到他们详细的解释,
由于我的这个程序使用了托盘技术,所以下来让我们看看怎么实现系统托盘技术:
            static NOTIFYICONDATA notify; /* 托盘数组 */
            //给托盘结构初始化
      notify.cbSize = sizeof(NOTIFYICONDATA);
      notify.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_ICON1));
      notify.hWnd = hwnd;
      strcpy(notify.szTip, ("定时关机程序")); 
      notify.uCallbackMessage = WM_ICON;
      notify.uFlags = NIF_MESSAGE | NIF_TIP | NIF_ICON;
      notify.uID = IDI_ICON1;
好了,现在将这个结构的各个参数都付值了,下来如果你想点一个按扭让程序”变到”系统的托盘里,那么你只要在哪个按扭的处理函数里面加上Shell_NotifyIcon(NIM_ADD, &notify);
就可以实现您的功能了,
大家可能都看到了,我的这个程序是能得到系统时间的,那这个该怎么实现呢?不用急,现在我们看看这个实现代码:
          TCHAR time[50]; /* 格式时间 */
          SYSTEMTIME st; /* 时间 */
        GetLocalTime(&st);
      GetTimeFormat(NULL, 
             TIME_FORCE24HOURFORMAT, 
             &st, 
             "HH':'mm':'ss'", 
             time,
             sizeof(time)
             );               
            // 设置时间 
      SetWindowText(GetDlgItem(hwnd, IDC_TIMER), time);
这段代码就是将得到的系统时间设置到那些显示时间的控件中去。
可能您已经想到这个问题了,你的界面中不是让用户自己输入关6的时间吗?怎么才能得到用户输入的时间啊,呵呵,OK,下来让我们来实现,看下面的代码:
           case IDC_HOUR: /* 设置hour */
            if (HIWORD(wParam) == LBN_SELCHANGE)
    hour = SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0);
            return 0;
这个就可以在选择小时的时候把所选的数字传给变量hour;
对了,另外一个重要的东西忘了,那就是当程序”变到”系统托盘后,你在图表上按鼠标右键时它回弹出一个菜单,(是不是感觉很神奇啊),这个怎么实现的呢?下来先看看我们在程序中创建的一个menu:
 
这个就是将来你点鼠标右键后出现的哪个菜单,现在你明白了吧,原来是先要自己创建一个menu,然后把它设置到鼠标点击的哪个事件中啊,(真聪明!!!鼓励以下);下来我门看看这个代码:
           case WM_RBUTTONDOWN:
             {
               POINT point;
               HMENU hMenu, hsubMenu;
        GetCursorPos(&point);               hMenu=LoadMenu(NULL,MAKEINTRESOURCE(IDR_MENU1));
               hsubMenu = GetSubMenu(hMenu, 0);
               SetForegroundWindow(hwnd);
  TrackPopupMenu(hsubMenu,                           TPM_LEFTBUTTON|TPM_RIGHTBUTTON|TPM_LEFTALIGN,
                      point.x,
                      point.y,
                      0, hwnd, 
                      NULL);
             }
好了,如果您对什么函数不是很懂的话,请赶紧查看MSDN,如果您想看这个的代码,那赶紧下载源代码.