文章目录
- 前言
- 一、封装“其他功能”按钮的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++打造局域网聊天室第十三课: 任务栏托盘功能的实现。