首页
社区
课程
招聘
[原创]用SDK实现自动定时关机
2006-6-10 13:28 8244

[原创]用SDK实现自动定时关机

2006-6-10 13:28
8244
关于自动关机程序设计说明书
<一>关于设计。
<二>感谢。
<三>关于作者。
<四>关于界面介绍。
<五>详细功能介绍。
<六>核心代码分析。

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

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

程序的运行界面如下:
       

详细功能介绍。
如上图所示:

核心代码分析。
关于重要控件的ID号如下图所示

首先我们来看看怎样才能实现电脑关机的功能啊,或许你回赶紧回答用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, ¬ify);
就可以实现您的功能了,
大家可能都看到了,我的这个程序是能得到系统时间的,那这个该怎么实现呢?不用急,现在我们看看这个实现代码:
                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,如果您想看这个的代码,那赶紧下载源代码.

[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

上传的附件:
收藏
点赞7
打赏
分享
最新回复 (9)
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
北极星2003 25 2006-6-10 14:51
2
0
不错,讲的很详细
期待更多佳作
雪    币: 313
活跃值: (250)
能力值: ( LV9,RANK:650 )
在线值:
发帖
回帖
粉丝
hbqjxhw 16 2006-6-10 15:12
3
0
又有牛人出现,算法分析讲解全面。
谢谢分享~
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
Isaiah 10 2006-6-10 17:08
4
0
界面不是一般的难看啊~
希望能改改。
我也正想写个类似的软件。我晚上经常带了耳机听音乐。每次最后还要爬起来关电脑,不爽。其他的关软件又体积庞大。现在可好了~

其实有个对NT以上系统的万能关机办法。
就是杀winlogin进程,不想关都不行。
只不过这样关机不是很安全,可能造成数据丢失。
雪    币: 260
活跃值: (102)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
firefly 4 2006-6-10 19:06
5
0
最初由 Isaiah 发布
界面不是一般的难看啊~
希望能改改。
我也正想写个类似的软件。我晚上经常带了耳机听音乐。每次最后还要爬起来关电脑,不爽。其他的关软件又体积庞大。现在可好了~

其实有个对NT以上系统的万能关机办法。
........

界面是有点难看,lz改改吧.
雪    币: 179
活跃值: (131)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
WAKU 7 2006-6-10 23:32
6
0
XP很流行了吧,我一般都shutdown -s -t 1800...
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
protocol 2006-6-11 16:32
7
0
谢谢分享。我的WIN2000用这种方法只能退出WINDOWS,关不了电源。
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
esun 2006-6-14 10:18
8
0
呵呵,东西还算不错,挺适合教学的。。。。下这个例子
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
心有独钟 2006-6-15 18:52
9
0
不错,讲的很详细
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
viviann 2006-6-15 21:18
10
0
最初由 WAKU 发布
XP很流行了吧,我一般都shutdown -s -t 1800...


你只是知道用,却不知道如何实现功能的。
游客
登录 | 注册 方可回帖
返回