虽然上一篇实现了的定时关机,但是还不够完善,比如开机自动启动,然后按照配置的时间定时关机,并最小化到任务栏。

先来说开机启动怎么实现,开机启动实现的方法有好几种,比如直接在开始菜单启动项里添加一个程序的快捷方式,路径为

  C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\

  不过这个路径不同的电脑可能不一样,因为这个路径可以改变,比如说改到D盘

也可以直接写入注册表,这个比较方便,这个开机启动项在注册表中的路径是

  HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run

WIN7 64位的注册表启动位置,这个根键和原来的不一样,路径也不一样。

  HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run

最小化到任务栏的实现需要NOTIFYICONDATA,这个结构体就可以实现我们需要的功能,并可以处理一些事件。

下面详细说说怎么实现。

1.先说注册表的实现

  几个和注册表相关的重要函数

RegOpenKeyEx,RegGetValue,RegSetValueEx,GetModuleFileName,RegDeleteValue,RegCloseKey

打开注册表中的某一项,如果成功就返回ERROR_SUCCESS,否则返回错误值,可在Winerror.h查找错误

 LSTATUS RegOpenKeyEx(
HKEY hKey,//根键
LPCTSTR lpSubKey,//子健
DWORD ulOptions,//保留参数,必须设置为0
REGSAM samDesired,//子健的使用权限
PHKEY phkResult//返回的值项的操作对象
);

然后就是获取值项的键值,函数成功则返回ERROR_SUCCESS,错误情况参照Winerror.h

 LONG WINAPI RegGetValue(
_In_ HKEY hkey,//根键
_In_opt_ LPCTSTR lpSubKey,//子健
_In_opt_ LPCTSTR lpValue,//值项的名称
_In_opt_ DWORD dwFlags,//值项的限制类型,包括RRF_ANY,这个没有类型限制,可以是下一个参数的任何类型,其他的不多说了
_Out_opt_ LPDWORD pdwType,//值项的数据类型,包括主要的四种,REG_BINARY,REG_DWORD,REG_SZ,DEFAULT
_Out_opt_ PVOID pvData,//获取的字符串
_Inout_opt_ LPDWORD pcbData//字符串结构的大小
);

打开启动路径后我们首先检查是否已经添加过启动项,结果体现在复选按钮上。然后我们设置值项的值

 LONG WINAPI RegSetValueEx(
_In_ HKEY hKey,//子健
_In_opt_ LPCTSTR lpValueName,//值项名称
_Reserved_ DWORD Reserved,//保留,为0
_In_ DWORD dwType,//类型
_In_ const BYTE *lpData,//数据字符串
_In_ DWORD cbData//数据大小,不包括结束支字符
);

还有一个函数用来获取当前运行的程序的路径,这个需要在设置注册表值时用到,返回值为程序路径名的长度

 DWORD WINAPI GetModuleFileName(
_In_opt_ HMODULE hModule,//加载的模式,这里选择为NULL,默认加载当前进程的路径
_Out_ LPTSTR lpFilename,//用来保存文件路径的字符串
_In_ DWORD nSize//字符串大小
);

如果复选按钮为空的话,就从注册表里删除值项

 LONG WINAPI RegDeleteValue(
_In_ HKEY hKey,//子健
_In_opt_ LPCTSTR lpValueName//值项名称
);

最后操作完成关闭注册表

LONG WINAPI RegCloseKey(
_In_ HKEY hKey//子健
);

需要这么几个重要函数,下面来说具体过程

  首先我们在程序启动后检查注册表里是否已经存在这个程序的启动项,如果存在就将结果保存在成员变量isInStartUp里,否则将isInStartUp设置为false,如果已经添加,就将复选按钮设置为选中状态,在OnInitDialog()里实现如下

 //获取启动项
HKEY key;
LPCTSTR szRun = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";//启动项的路径
if (RegOpenKeyEx(HKEY_CURRENT_USER,szRun,,KEY_ALL_ACCESS,&key) == ERROR_SUCCESS)
{
char szFileName[MAX_PATH] = {};
//DWORD dRet = GetModuleFileName(NULL,szFileName,MAX_PATH);
DWORD type = REG_SZ;
DWORD bufSize = sizeof(szFileName);
char file[MAX_PATH] = {};
long lRet = RegGetValue(HKEY_CURRENT_USER,szRun,"ShutDown",RRF_RT_ANY,&type,szFileName,&bufSize);
if (lRet == ERROR_SUCCESS)
{
isInStartUp = true;//已经添加启动项,设置checkbox为选中状态
m_checkbox.SetCheck(BST_CHECKED);
//MessageBox(szFileName);
}
else
{
isInStartUp = false;
m_checkbox.SetCheck(BST_UNCHECKED);
}
}
else
{
MessageBox("打开注册表失败");
}
RegCloseKey(key);

这个不用多解释,很简单。接着来,在单击过确定按钮后处理添加启动项,在OnBnClickedOk()处理后续操作

     //首先检查复选框是否选中
UINT ischecked = IsDlgButtonChecked(IDC_CHECK1); //获取选择的时间
hour = m_com_hour.GetCurSel();
minute = m_com_minute.GetCurSel();
second = m_com_second.GetCurSel(); //数据进行格式化处理
CString str = "";
str.Format("%2d时%2d分%2d秒", hour, minute, second);
// GetDlgItem(IDC_STATIC_NOW)->SetWindowText(str);
int resoult = MessageBox("确定要在"+str+"关机吗?","是否关机?",MB_OKCANCEL);
if (resoult == IDOK)
{
//是否添加到启动项
AutoStart(ischecked);
//更新程序窗口中显示的关机时间
GetDlgItem(IDC_STATIC_SHUT)->SetWindowText(str);
........
.........
}

上面关于注册表的操作封装到了函数AutoStart()中。

 //是否添加到启动项
void CAutoShutDownDlg::AutoStart(UINT check)
{
UINT ischecked = check;
//打开注册表选项
HKEY key;
LPCTSTR szRun = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";
if (RegOpenKeyEx(HKEY_CURRENT_USER,szRun,,KEY_SET_VALUE,&key) == ERROR_SUCCESS)
{
if (ischecked != )//选中
{
//打开成功,设置开机启动项
char szFileName[MAX_PATH] = {};
//获取当前进程的路径
DWORD dRet = GetModuleFileName(NULL,szFileName,MAX_PATH);
// 添加一个值项,即添加开机启动项,第二个参数为应用程序名,不加.exe后缀
long lRet = RegSetValueEx(key,"ShutDown",,REG_SZ,(BYTE *)szFileName,dRet);
if (lRet != ERROR_SUCCESS)
{
MessageBox("添加启动项失败");
}
else if(lRet == ERROR_SUCCESS)
{
isInStartUp = true;
MessageBox("添加启动项成功");
}
}
else if (ischecked == && isInStartUp)
{
long lRet = RegDeleteValue(key,"ShutDown"); if (lRet != ERROR_SUCCESS)
{
MessageBox("删除错误");
}
}
}
RegCloseKey(key);
}

好了,就这样吧,最小化到任务栏后面再说

MFC定时关机程序的实现2-添加启动项到注册表的更多相关文章

  1. MFC定时关机程序的实现1

    写个定时关机程序自用,界面简单实用,最终界面如下 第一步,新建一个MFC对话框应用程序,拖几个控件过来, 界面如下: 然后给下拉列表框,复选按钮绑定变量,以方便进行操作. CComboBox m_co ...

  2. MFC定时关机程序的实现3-最小化到托盘栏

    这个定时关机运行过后默认最小化到托盘栏最好了,不用每次都去点了. 现在来看看如何将程序显示在托盘栏. 首先在头文件里声明一个变量和一个消息响应函数 //最小化到托盘栏 //第一步,生成一个成员变量,或 ...

  3. 使用.netFx4.0提供的方法解决32位程序访问64位系统的64位注册表

    原文:使用.netFx4.0提供的方法解决32位程序访问64位系统的64位注册表 我们知道目标平台是32位的程序运行在64位的系统上,去访问部分注册表的时候系统自动重定向到win32node节点对应的 ...

  4. CentOS 7系统添加启动项

    CentOS 7系统已经把CentOS 6的 runlevel 系统服务管理替换成了systemd.在 /etc/rc[0-6S].d 下添加启动项已经不能在系统启动的时候自动执行,需要通过新的 sy ...

  5. 我的定时关机程序(MFC实现) .

    原理: 利用定时器去检查,如输入的是多少分钟后关机,就根据输入的分钟数产生一个COUNT计数器,计数器一直递减,直到1,然后执行关机.如输入的是几时几分关机,那么定时器会每次都检查系统的时间和你输入的 ...

  6. Windows添加启动项的两种方法

    方案1直接将脚本放到启动文件夹里面 C:\Users\XXX\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup 方案2 Win ...

  7. 在防火墙的例外中注册程序(Windows7和XP),改写注册表

    在写程序的时候,经常遇到被防火墙拦截的情况,尤其是一些网络程序,不管是对外访问还是外部连接,都会被拦截. 在大多情况下,Windows会静默拦截外部对内的连接访问,而内部对外的访问会提示用户信息. 现 ...

  8. LINUX下EFIBOOTMGR的使用,删除UEFI主板多余启动项和添加启动项

    用uefi装了几次次archlinux,搞的uefi启动选项下多出来好多启动项..这东西重格硬盘也是不好用的.发现以下方法可以解决. efibootmgr   //显示efi的启动项 删除一个引导项 ...

  9. 迁移桌面程序到MS Store(15)——通过注册表开启Developer Mode

    没想到该系列不仅没有太监,还打算更新一个小短篇.在各种大厂小厂工作的各位想必都知道Windows域的概念.入域的机器很多的设置就由不得当前登入所使用的域账号了,Windows的更新和安全等众多的设置均 ...

随机推荐

  1. 彻底解决Android 应用方法数不能超过65K的问题

    作为一名Android开发者,相信你对Android方法数不能超过65K的限制应该有所耳闻,随着应用程序功能不断的丰富,总有一天你会遇到一个异常: Conversion to Dalvik forma ...

  2. 数据字典的设计--3.首页添加删除表格(JS实现)

    页面效果: JS代码: 1.添加表格 function insertRows(){ //获取表格对象 var tb1 = $("#dictTbl"); var tempRow = ...

  3. shell实现mysql数据库备份

    #!/bin/bash DB_USER="root" #数据库用户名 DB_PASS="12345678" #数据库密码 BACK_DIR="/bac ...

  4. Codeforces Round #323 (Div. 2) C GCD Table 582A (贪心)

    对角线上的元素就是a[i],而且在所在行和列中最大, 首先可以确定的是最大的元素一定是a[i]之一,这让人想到到了排序. 经过排序后,每次选最大的数字,如果不是之前更大数字的gcd,那么只能是a[i] ...

  5. C/C++语言补缺 宏- extern "C"-C/C++互调

    1. 宏中的# 宏中的#的功能是将其后面的宏参数进行字符串化操作(Stringizing operator),简单说就是在它引用的宏变量的左右各加上一个双引号. 如定义好#define STRING( ...

  6. Python实现购物小程序

    一.需求 1.登录 { ‘xxx1’:{'passwd':'123','role':1,'moeny':10000,"carts":['mac']}, 'xxx1':{'passw ...

  7. 推荐一个WebIDE在线编程语言编译器C9.io

    有时借用别人电脑或者不想在电脑上安装各种乱七八糟的IDE,就可以考虑 Web IDE.随着Web技术发展,很多语言的编译工作都可以利用Web 浏览器来完成. 1. 推荐国外的 C9.io 个人可以免费 ...

  8. java: 非法字符: \65279

    IDEA导入项目后,编译的时候出现Error:(1, 1) java: 非法字符: \65279: 修改:找到编译报错的文件,用Notepad++工具,以UTF-8无BOM格式编码保存,然后重新编译即 ...

  9. BZOJ2023: [Usaco2005 Nov]Ant Counting 数蚂蚁(dp)

    题意 题目描述的很清楚...  有一天,贝茜无聊地坐在蚂蚁洞前看蚂蚁们进进出出地搬运食物.很快贝茜发现有些蚂蚁长得几乎一模一样,于是她认为那些蚂蚁是兄弟,也就是说它们是同一个家族里的成员.她也发现整个 ...

  10. 【点分树】codechef Yet Another Tree Problem

    已经连咕了好几天博客了:比较经典的题目 题目大意 给出一个 N 个点的树和$K_i$, 求每个点到其他所有点距离中第 $K_i$ 小的数值. 题目分析 做法一:点分树上$\log^3$ 首先暴力做法: ...