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

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

  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. 【extjs6学习笔记】1.14 初始: ViewModel

    ViewModel是一个管理特定UI组件数据的类. 可以将其视为特定视图的记录容器. 它支持与UI组件的双向数据绑定,只要用户在视图中更改数据,它具有最新的副本. 与模型不同,它不能包含代理,因此它不 ...

  2. 【MATLAB】设定坐标的轴的范围

    set(gca,'XLim',[0 1.5]);%X轴的数据显示范围set(gca,'XTick',[0:0.1:1.5]);%设置要显示坐标刻度set(gca,'XTickLabel',[0:0.1 ...

  3. Wince 6.0获取设备的分辨率 自动设置窗体位置

    调用微软提供给wince的API  “coredll.dll” [DllImport("coredll.dll")] public static extern int GetSys ...

  4. Posgtes 常见命令

    postgres 版本查看命令sudo -u postgres psql --version

  5. mybatis-注解实现crud

    1.在接口上注解sql package com.java1234.mappers; import java.util.List; import org.apache.ibatis.annotation ...

  6. click

    click简介 Click是一个Python包,用于以可组合的方式创建漂亮的命令行界面,只需要很少的代码.这是“命令行界面创建工具包”.它具有高度可配置性,但具有开箱即用的合理默认值. 点击三点: 任 ...

  7. react树状组件

    最近在react项目中需要一个树状组件,但是又不想因为这个去引入一套UI组件,故自己封装了一个基于react的树状组件, 个人认为比较难得部分在于数据的处理,话不多说直接上代码: 下面是tree.js ...

  8. java设计模式——原型模式

    一. 定义与类型 定义:指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.不需要知道任何创建的细节,不调用构造函数 类型:创建型 二.使用场景 类初始化消耗较多资源 new 产生的一个对 ...

  9. 用正则表达式简单加密(C#为例)

    ") { List<" }; ") { foreach (char i in key) { keys[counter] = i.ToString(); counte ...

  10. base64转图片上传

    不成功,但是有一定的借鉴性 /** * @param base64Codes * 图片的base64编码 */ function sumitImageFile(base64Codes){ consol ...