当前位置: 首页 > article >正文

C++打造局域网聊天室第十三课: 任务栏托盘功能的实现

文章目录

  • 前言
  • 一、封装“其他功能”按钮的MFC消息映射机制函数
  • 二、添加任务栏托盘菜单的响应函数
  • 三、点击任务栏托盘图标后调用任务栏托盘图标响应函数
  • 四、任务栏托盘图标的一些响应
  • 总结


前言

C++打造局域网聊天室第十三课: 任务栏托盘功能的实现。


一、封装“其他功能”按钮的MFC消息映射机制函数

首先创建其他功能按钮的单击MFC消息映射机制函数框架,具体步骤见C++打造局域网聊天室第四课: 动态启用或禁用窗口及MFC消息映射机制。
在这里插入图片描述
要实现在点击其他功能后弹出菜单的功能,首先要添加一个菜单。选择资源视图,右键chartroom.rc,选择添加资源。
在这里插入图片描述
可以在列表中看到Menu,双击Menu即可在右侧看见Menu已被添加
在这里插入图片描述
在这里插入图片描述
点击进入Menu的编辑页面
在这里插入图片描述
菜单大体可分为两类:下拉式菜单(word上方的文件、视图等就是)和弹出式菜单(在桌面空白处点击鼠标右键出现的就是),这里使用弹出式菜单,如下图输入文字。注意:弹出式菜单第一个菜单项(顶层菜单)不会显示(图中Menu行)
在这里插入图片描述
下面实现函数void CchartroomDlg::OnBnClickedButton7(),该函数的功能就是点击更多功能后弹出刚刚创建的菜单。

void CchartroomDlg::OnBnClickedButton7() // 点击更多功能按钮的MFC消息映射机制函数实现
{
	// TODO: 在此添加控件通知处理程序代码
	// 功能为单击后弹出菜单
	CPoint pt; // 创建一个点实例
	CRect mRect; // 创建一个矩形实例
	CMenu mMenu;  // CMenu为Menu菜单资源对应的类
	CMenu* pMenu = NULL;
	GetDlgItem(IDC_BUTTON7)->GetWindowRect(& mRect); // 取得更多功能矩形框位置,将数据放入mRect变量中
	pt = mRect.BottomRight(); // 取得更多功能矩形框的右下角点
	pt.y = mRect.top + 10; // 为了美观将弹出的菜单框与更多功能矩形框错开一些
	mMenu.LoadMenu(IDR_MENU1); // 将创建的ID为IDR_MENU1的Menu资源与mMenu变量绑定
	//pMenu = &mMenu;
	pMenu = mMenu.GetSubMenu(0); // 由于弹出式菜单第一个菜单项不会显示,用pMenu指向mMenu的子菜单项,子菜单项即为顶层菜单的下一个
	pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, this); // 弹出菜单,
	//第一个参数为一些菜单项属性;第二个和第三个参数即pt.x和pt.y为弹出菜单的位置(矩形左上角坐标);第四个参数为菜单项的父窗口
}

二、添加任务栏托盘菜单的响应函数

先在chaartroomDlg.h头文件中声明函数。
在这里插入图片描述
在Server.h中定义一个回调信息

#define WM_TRAYICON_MSG (WM_USER + 100); //定义任务栏托盘的回调信息。WM_USER之前的消息值都被微软占用,一定要调用WM_USER+某一个正整数

然后在chaartroomDlg.cpp头文件中实现函数TrayMyIcon()。

BOOL CchartroomDlg::TrayMyIcon(BOOL bAdd) // 实现任务栏托盘菜单响应函数
{
	BOOL bRet = FALSE;
	NOTIFYICONDATA tnd; // 定义一个NOTIFYICONDATA类型结构,以便任务栏托盘API使用
	tnd.cbSize = sizeof(NOTIFYICONDATA); // 一定要赋值,微软用来管理版本的,结构的大小
	tnd.hWnd = GetSafeHwnd(); // 任务栏托盘图标所属句柄,直接取得本程序窗口句柄。当用户双击或右键图标时产生的消息就会返回到该句柄代表的窗口
	tnd.uID = IDR_MAINFRAME; // 程序图标ID,在资源视图的Icon下
	if (bAdd == TRUE) // 如果想要添加任务栏托盘图标
	{
		tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; // 开启一些功能:NIF_MESSAGE启用任务栏托盘图标可以接收鼠标点击信息;
		//NIF_ICON启用显示任务栏托盘自定义图标;NIF_TIP启用tnd.szTip成员
		tnd.uCallbackMessage = WM_TRAYICON_MSG; // 回调当用户双击或右键图标时产生的消息
		tnd.hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME)); // 在任务栏托盘中显示的图标,这里直接使用该程序默认Icon图标
		// LoadIcon第一个参数为本程序应用实例的句柄;第二个参数为图标资源
		_tcscpy_s(tnd.szTip, sizeof(tnd.szTip), _T("聊天室v1.0")); // szTip为鼠标放在任务栏托盘图标上时显示的消息文本
		ShowWindow(SW_MINIMIZE); // 将程序窗口最小化
		ShowWindow(SW_HIDE); // 将程序窗口隐藏
		bRet = Shell_NotifyIcon(NIM_ADD, &tnd); // 任务栏托盘API。第一个参数为想干嘛(删除任务栏图标、修改任务栏图标等),这里添加任务栏图标;第二个参数为NOTIFYICONDATA类型结构
	}
	else
	{
		ShowWindow(SW_SHOWNA); // 显示程序窗口
		SetForegroundWindow(); // 将程序窗口设置为前景窗口(置于顶层)
		bRet = Shell_NotifyIcon(NIM_DELETE, & tnd); // 任务栏托盘API。第一个参数为想干嘛(删除任务栏图标、修改任务栏图标等),这里删除任务栏图标;第二个参数为NOTIFYICONDATA类型结构
	}
	return bRet;
}

三、点击任务栏托盘图标后调用任务栏托盘图标响应函数

右键创建的任务栏托盘按键,选择添加时间处理程序
在这里插入图片描述
选择如下类和消息类型,COMMAND表示单击消息类型,点击确定
在这里插入图片描述
直接调用函数TrayMyIcon即可

void CchartroomDlg::OnMenu32771()// 实现单击菜单任务栏托盘的响应函数
{
	// TODO: 在此添加命令处理程序代码
	TrayMyIcon(1); // 添加任务栏图标
}

点击更多功能后会出现任务栏菜单,点击菜单中的任务栏托盘后会出现任务栏托盘图标,同时鼠标放上去有提示信息。
在这里插入图片描述
在这里插入图片描述

四、任务栏托盘图标的一些响应

我们再添加一个菜单项,
在这里插入图片描述

则创建了空白的IDR_MENU2,添加显示程序和退出程序的按键
在这里插入图片描述
由于这里需要实现右键任务栏托盘图标时弹出菜单,并且在实现任务栏托盘菜单响应函数TrayMyIcon(BOOL bAdd)时我们已经定义了右键产生的信息
在这里插入图片描述
还需要定义一个该消息的响应函数。在chartroomDlg.h头文件中声明函数

LRESULT OnTrayCallBackMsg(WPARAM wparam, LPARAM Lparam); // 声明右键任务栏托盘信息的响应函数

由于这里我们要实现右键任务栏托盘图标的MFC消息映射机制,所以这里我们无法像之前一样添加事件处理程序,这里我们手动添加
在这里插入图片描述

然后在chartroomDlg.cpp源文件中实现上述消息的响应函数

LRESULT CchartroomDlg::OnTrayCallBackMsg(WPARAM wparam, LPARAM lparam) // 实现右键任务栏托盘信息的响应函数,WM_TRAYICON_MSG当鼠标略过图标时就会产生消息
{
	// 第二个参数为鼠标动作消息号
	switch (lparam)
	{
	case WM_RBUTTONUP: // 鼠标右键弹起消息,出现菜单
	{
	    CMenu mMenu;
	    CMenu* pMenu = NULL;
	    CPoint pt;
	    mMenu.LoadMenu(IDR_MENU2); // 将创建的ID为IDR_MENU2的Menu资源与mMenu变量绑定
	    pMenu = mMenu.GetSubMenu(0);
	    GetCursorPos(& pt);
	    SetForegroundWindow();
	    pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, this);
	    break;
	}
	case WM_LBUTTONDBLCLK: // 鼠标左键双击消息,出现程序窗口,删掉任务栏图标
	{
		ShowWindow(SW_RESTORE); // 出现程序窗口
		SetForegroundWindow();
		TrayMyIcon(0); //删掉任务栏图标
		break;
	}
	default: break;
	}
	return NULL;
}

之后还需要进行右键菜单项显示程序和退出程序的处理,同样添加事件处理程序
在这里插入图片描述

其中显示程序的代码和鼠标双击任务栏托盘图标的代码是一样的

void CchartroomDlg::OnMenu32776() // 实现任务栏托盘右键显示程序的函数
{
	// TODO: 在此添加命令处理程序代码
	ShowWindow(SW_RESTORE); // 出现程序窗口
	SetForegroundWindow();
	TrayMyIcon(0); //删掉任务栏图标
}

退出程序的功能和点击关闭窗口按钮的功能一样,这里直接调用函数即可,并且要进行托盘图标的删除。

void CchartroomDlg::OnMenu32777() // 实现任务栏托盘右键退出程序的函数
{
	// TODO: 在此添加命令处理程序代码
	TrayMyIcon(0); //删掉任务栏图标
	OnBnClickedButton6(); // 调用关闭窗口的函数即可
}

这里需要注意:TrayMyIcon(0)一定要在OnBnClickedButton6()上面调用,因为要先删除图标,再进行程序的结束。否则程序已经结束了,再删除图标就会造成资源访问违规。

至此,C++打造局域网聊天室基本功能已经介绍完毕。


总结

C++打造局域网聊天室第十三课: 任务栏托盘功能的实现。


http://www.kler.cn/a/454113.html

相关文章:

  • [2003].第2-01节:关系型数据库表及SQL简介
  • [bug]java导出csv用Microsoft Office Excel打开乱码解决
  • 【K8S问题系列 | 20 】K8S如何删除异常对象(Pod、Namespace、PV、PVC)
  • 各种网站(学习资源、常用工具及其他,持续更新中~)
  • Python - 获取当前函数中的所有参数信息(名称和值)
  • 【Rust自学】7.3. 路径(Path)Pt.2:访问父级模块、pub关键字在结构体和枚举类型上的使用
  • Redis基础知识分享(含5种数据类型介绍+增删改查操作)
  • c#自定义事件
  • 2023年软件产业报告|2023年我国软件业经济运行情况及未来发展趋势预期
  • 【论文阅读笔记】Scalable, Detailed and Mask-Free Universal Photometric Stereo
  • 数据库系统概论
  • ctfshow-web入门-文件包含(web82-web86)条件竞争实现session会话文件包含
  • Llama3.370B超越GPT-4o和Claude3.5 Sonnet
  • 从随机生成到深度学习:使用DCGAN和CycleGAN生成图像的实战教程
  • Android 开发中自定义Toast
  • Metricbeat安装教程——Linux——Metricbeat监控ES集群
  • 从安全角度看 SEH 和 VEH
  • 软件测试之Android-sdk环境搭建
  • 网络安全top国际会议
  • C#数学相关开发性能优化方法