利用MFC实现一个托盘功能

news2024/9/25 17:18:17

文章目录

    • 1.将主窗口隐藏起来,并移除任务栏图标显示
    • 2. 制作系统托盘
    • 3. 右键托盘得到信息
    • 4. 选择信息栏触发事件
    • 5. 添加开机自启动与关闭开机自启动OnSetPowerBoot与OnCancelPowerBoot

在这里插入图片描述
右键点击托盘,弹出如下的图标
在这里插入图片描述

1.将主窗口隐藏起来,并移除任务栏图标显示

在CMFCApplication2Dlg::OnInitDialog进行初始化

	int nFullWidth = GetSystemMetrics(SM_CXSCREEN);
	int nFullHeight = GetSystemMetrics(SM_CYSCREEN);
	SetWindowPos(NULL, nFullWidth, nFullHeight, 0, 0, SWP_NOZORDER);  
	//设置0像素,移到最角落  或者:MoveWindow(0,0,0,0);
	ShowWindow(SW_HIDE);
	ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW);  //移除任务栏图标显示

2. 制作系统托盘

在CMFCApplication2Dlg类中增加两个成员与一个函数

	NOTIFYICONDATA NotifyIcon;  //系统托盘类
	CMenu menu;
	afx_msg LRESULT OnSystemtray(WPARAM wParam, LPARAM lParam);

在BEGIN_MESSAGE_MAP(CMFCApplication2Dlg, CDialogEx) 与END_MESSAGE_MAP()之间添加自定义消息
#define WM_SYSTEMTRAY WM_USER+100

ON_MESSAGE(WM_SYSTEMTRAY, &CMFCApplication2Dlg::OnSystemtray)

OnSysCommand的实现

void CMFCApplication2Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

在CMFCApplication2Dlg::OnInitDialog进行初始化

	//设置系统托盘
	NotifyIcon.cbSize = sizeof(NOTIFYICONDATA);
	//NotifyIcon.hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	NotifyIcon.hIcon = m_hIcon;  //上面那句也可以
	NotifyIcon.hWnd = m_hWnd;
	lstrcpy(NotifyIcon.szTip, _T("更改端口"));
	NotifyIcon.uCallbackMessage = WM_SYSTEMTRAY;
	NotifyIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
	Shell_NotifyIcon(NIM_ADD, &NotifyIcon);   //添加系统托盘
	//声明一个弹出式菜单
	menu.CreatePopupMenu();
	menu.AppendMenu(MF_STRING, WM_DESTROY, _T("退出"));
	menu.AppendMenu(MF_STRING, WM_SETPOWERBOOT, _T("开启开机自启动"));
	menu.AppendMenu(MF_STRING, WM_CANCELPOWERBOOT, _T("关闭开机自启动"));

3. 右键托盘得到信息

在这里插入图片描述

afx_msg LRESULT CMFCApplication2Dlg::OnSystemtray(WPARAM wParam, LPARAM lParam)
{
	switch (lParam)
	{
	case  WM_RBUTTONDOWN://右键起来时弹出快捷菜单
	{
		//menu.LoadMenuW(IDR_MENU1);//加载菜单资源
		LPPOINT lpoint = new tagPOINT;
		::GetCursorPos(lpoint);//得到鼠标位置
		//确定弹出式菜单的位置
		menu.TrackPopupMenu(TPM_LEFTALIGN, lpoint->x, lpoint->y, this);
		break;
	}
	case  WM_LBUTTONDOWN://左键单击的处理     
	{
		//....
	}
	}
	return 0;
}

4. 选择信息栏触发事件

在这里插入图片描述

BOOL CMFCApplication2Dlg::OnCommand(WPARAM wParam, LPARAM lParam)
{
	// TODO: 在此添加专用代码和/或调用基类
	switch (LOWORD(wParam))
	{
	case WM_DESTROY:
	{
		OnDestroy();
		break;
	}
	case WM_SETPOWERBOOT:
	{
		OnSetPowerBoot(wParam, lParam);
		break;
	}
	case WM_CANCELPOWERBOOT:
	{
		OnCancelPowerBoot(wParam, lParam);
		break;
	}
	}
	return CDialogEx::OnCommand(wParam, lParam);
}

5. 添加开机自启动与关闭开机自启动OnSetPowerBoot与OnCancelPowerBoot

在BEGIN_MESSAGE_MAP(CMFCApplication2Dlg, CDialogEx) 与END_MESSAGE_MAP()之间添加自定义消息
#define WM_SETPOWERBOOT WM_USER+101
#define WM_CANCELPOWERBOOT WM_USER+102

	ON_MESSAGE(WM_SETPOWERBOOT, &CMFCApplication2Dlg::OnSetPowerBoot)
	ON_MESSAGE(WM_CANCELPOWERBOOT, &CMFCApplication2Dlg::OnCancelPowerBoot)
LRESULT CMFCApplication2Dlg::OnSetPowerBoot(WPARAM wParam, LPARAM lParam)
{
	HKEY hKey;
	//找到系统的启动项
	CString lpRun = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
	//打开启动项
	long lRet = RegOpenKeyEx(HKEY_CURRENT_USER, lpRun, 0, KEY_ALL_ACCESS, &hKey);
	//找到程序自身路径
	TCHAR pFileName[MAX_PATH] = {};
	GetModuleFileName(NULL, pFileName, MAX_PATH);

	//判断是否已经设置开机启动
	TCHAR PowerBoot[MAX_PATH] = {};
	DWORD nLongth = MAX_PATH;
	long result = RegGetValue(hKey, NULL, _T("PowerBoot"), RRF_RT_REG_SZ, 0, PowerBoot, &nLongth);
	if (result == ERROR_SUCCESS)        //自启状态
	{
		if (lRet == ERROR_SUCCESS)
		{
			MessageBox(_T("已是自启状态"), _T("PanTum"));
		}
	}
	else        //未自启状态
	{
		//设置自启
		lRet = RegSetValueEx(hKey, _T("PowerBoot"), 0, REG_SZ, (LPBYTE)pFileName, (lstrlen(pFileName) + 1) * sizeof(TCHAR));
		if (lRet == ERROR_SUCCESS)
		{
			MessageBox(_T("设置自启成功"), _T("PanTum"));
		}
	}
	//关闭注册表
	RegCloseKey(hKey);
	return 0;

}

LRESULT CMFCApplication2Dlg::OnCancelPowerBoot(WPARAM wParam, LPARAM lParam)
{
	HKEY hKey;
	//找到系统的启动项
	CString lpRun = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
	//打开启动项
	long lRet = RegOpenKeyEx(HKEY_CURRENT_USER, lpRun, 0, KEY_ALL_ACCESS, &hKey);
	//找到程序自身路径
	TCHAR pFileName[MAX_PATH] = {};
	GetModuleFileName(NULL, pFileName, MAX_PATH);

	//判断是否已经设置开机启动
	TCHAR PowerBoot[MAX_PATH] = {};
	DWORD nLongth = MAX_PATH;
	long result = RegGetValue(hKey, NULL, _T("PowerBoot"), RRF_RT_REG_SZ, 0, PowerBoot, &nLongth);
	if (result == ERROR_SUCCESS)        //自启状态
	{
		//取消自动启动
		lRet = RegDeleteValue(hKey, _T("PowerBoot"));
		if (lRet == ERROR_SUCCESS)
		{
			MessageBox(_T("关闭自启成功"), _T("PanTum"));
		}
	}
	else        //未自启状态
	{
		//设置自启
		MessageBox(_T("已关闭自启状态"), _T("PanTum"));
	}

	//关闭注册表
	RegCloseKey(hKey);

	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/439333.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt开发技术:Q3D图表开发笔记(三):Q3DSurface三维曲面图介绍、Demo以及代码详解

若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/130264470 各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究 红胖子网络科技博…

怎么批量把heic格式转化jpg,3招快速解决

怎么批量把heic格式转化jpg?heic是一种新型的图像文件格式,是苹果独家搞出来的一个图片格式,它小巧玲珑,而且图像质量超好,专门给iOS11系统用户用的。这种格式比老JPEG更厉害,不仅图片质量好,而…

如何减少电脑内存占用或优化内存?

内存(Memory)是计算机一个重要的组成部件,也称为内存储器或主存储器。它可以暂时存放CPU中运算的数据,以及与硬盘等外部存储器交换的数据,是CPU和硬盘之间的桥梁。若电脑内存占用过高,这会影响到电脑运行的速度,那该如…

Redis的哈希槽分区

目录 1. 一致性算法分区的缺点2. 哈希槽分区3. Redis为什么是16384个槽 1. 一致性算法分区的缺点 可以参考一致性哈希算法分区这篇文章 2. 哈希槽分区 Redis集群中内置了16384个哈希槽。redis会根据服务器节点数量大致均等的将哈希槽映射到不同的节点 当写入一条数据&#x…

Java版本的工程项目管理系统源代码之工程项目管理系统面临的挑战

​ ​工程项目管理系统是指从事工程项目管理的企业(以下简称工程项目管理企业)受业主委托,按照合同约定,代表业主对工程项目的组织实施进行全过程或若干阶段的管理和服务。 ​系统定义 工程项目管理企业不直接与该工程项目的总承包…

UE4/5多人游戏详解(六、多人游戏插件的菜单,创建会话设置和加入)

目录 简单的菜单 创建新的c类: 这里可能出现的报错: 菜单设置: 代码: UI创建: C类中创建按钮的指针: 子系统创建 创建会话函数: 创建会话后前往大厅: 重载函数 变量添加…

Java 线程

线程:线程是进程的组成部分,一个进程可以拥有多个线程,而一个线程必须拥有一个父进程。线程可以拥有自己的堆栈,自己的程序计数器和自己的局部变量,但不能拥有系统资源。它与父进程的其他线程共享该进程的所有资源。 …

PowerShell install Docker+docker-compoer

docker 前言 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。 …

Linux搭建SVN服务器详细教程

前言 本文讲解 Linux 系统下如何搭建 SVN 服务器,详细说明各配置项的功能,最终实现可管控多个项目的复杂配置。 SVN 是 subversion 的缩写,是一个开放源代码的版本控制系统,通过采用分支管理系统的高效管理,实现最终集…

【转】使用Midjourney绘制小漫画

原帖地址:【Midjourney教程】设计麻瓜也能15分钟一篇小漫画 Midjourney能帮我画漫画,话不多说,下方成品图 Part 1 你想画什么 画漫画当然要有故事情节,你总得确定,你要画个啥?也就是专业人士说的画面分镜,当然咱们是“野狐禅”,就不扯的太细,太细我也不会… 由于只…

软考中级软件评测师备考攻略

软件评测师属于软考中级,考试虽然没有软考高级难度大,但是会比软考初级要难,所以想要通过软件评测师考试还是需要花时间去用心备考的。 一、软件评测师职业前景: 随着互联网技术的不断发展,软件评测师的市场需求也会…

【CocosCreator入门】CocosCreator组件 | Canvas(画布)组件

Cocos Creator 是一款流行的游戏开发引擎,具有丰富的组件和工具,其中的Canvas能够将游戏物体渲染到屏幕上。 目录 一、组件介绍 二、渲染模式 三、组件属性 四、组件使用 五、脚本示例 一、组件介绍 Canvas组件是Cocos Creator中重要的组件之一。在…

【Socket】之TCP数据报套接字

1. 介绍下API 1.1 ServerSocket API 这是创建TCP服务端Socket的API。 构造方法方法说明ServerSocket(int port)创建一个服务端流套接字Socket,并绑定到指定端口 普通方法方法说明ServerSocket.accept()开始监听指定端口(创建时绑定的端口&#xff09…

Spring学习——Nginx

Nginx概述 Nginx介绍 Nginx是一款轻量级的web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx的网…

Python学习之DateTime

文章目录 前言一、pandas是什么?二、使用步骤1.引入库2.使用date.today()打印日期3.Python当前日期和时间:now() today()总结 4.如何使用 Strftime()格式化日期和时间输出1. 首先,我们将看到一个简单的如何格式化年份的步骤。通过一个例子来理…

【微服务笔记18】微服务组件之Gateway实现服务限流(计数器算法、漏桶算法、令牌桶算法)

这篇文章,主要介绍微服务组件之Gateway实现服务限流(计数器算法、漏桶算法、令牌桶算法)。 目录 一、服务限流 1.1、几种限流算法 (1)计数器算法 (2)漏桶算法 (3)令…

叮咚,你的耳鼻喉专科医院营销策略快来查收

进入后疫情时代以来,人们对健康意识的不断提高,医疗行业也开始卷起来了,通过各种渠道来宣传和推广医院,吸引更多的患者。那么今天就以耳鼻喉专科医院为主,聊聊这类医院该怎么在Z时代做好营销。 医院营销可以分为线上和…

【行为型模式】观察者模式

文章目录 1、概述2、结构3、实现方式3.1、案例引入3.2、结构分析3.3、具体实现 4、观察者模式优缺点5、应用场景 1、概述 观察者模式(Observer)是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,其他所有依…

【C++】二叉搜索树的应用

前言 二叉搜索树本质也是二叉树,但因为其数据存储的特殊 — 左子树的值都更小,右子树的值都更大,所以在大部分情况下,查找更为高效。本篇博客将讲述二叉搜索树两个应用搜索的场景 那么话不多说,马上开始今天的学习。 文…

linux运维必了解的日志文件系统

目录 一、inode与block1.1inode和block概述1.1.1inode和block的关系 1.2inode的内容1.2.1inode包含文件的元信息1.2.2linux文件系统的三个时间戳1.2.3目录文件结构 1.3inode的号码1.3.1 硬盘分区后的结构 1.4inode的大小1.5恢复误删除的xfs文件1.6EXT类型文件恢复误删除 二、分…