自定义托盘菜单

首先给个程序最小化为托盘的例子:

 

void CMyDlg::ToTray() { NOTIFYICONDATA nid; nid.cbSize=(DWORD)sizeof(NOTIFYICONDATA); nid.hWnd=this->m_hWnd; nid.uID=IDR_MAINFRAME; nid.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP ; nid.uCallbackMessage=WM_SHOWTASK;//自定义的消息名称 nid.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME)); strcpy(nid.szTip,"对话框测试.exe"); //信息提示条 Shell_NotifyIcon(NIM_ADD,&nid); //在托盘区添加图标 ShowWindow(SW_HIDE); //隐藏主窗口 } int CMyDlg::OnShowTask(WPARAM wparam,LPARAM lparam) { if(wparam!=IDR_MAINFRAME) return 1; switch(lparam) { case WM_RBUTTONUP://右键起来时弹出快捷菜单,这里只有一个“关闭” { LPPOINT lpoint=new tagPOINT; ::GetCursorPos(lpoint);//得到鼠标位置 CMenu menu; menu.CreatePopupMenu();//声明一个弹出式菜单 //增加菜单项“关闭”,点击则发送消息WM_DESTROY给主窗口(已 //隐藏),将程序结束。 menu.AppendMenu(MF_STRING,WM_DESTROY,"关闭"); //确定弹出式菜单的位置 menu.AppendMenu(MF_STRING,WM_RESHOW,"显示"); menu.TrackPopupMenu(TPM_LEFTALIGN,lpoint->x,lpoint->y,this); //资源回收 HMENU hmenu=menu.Detach(); menu.DestroyMenu(); delete lpoint; } break; case WM_LBUTTONDBLCLK://双击左键的处理 { this->ShowWindow(SW_SHOW);//简单的显示主窗口完事儿 DeleteTray(); } break; default: break; } return 0; } void CMyDlg::DeleteTray() { NOTIFYICONDATA nid; nid.cbSize=(DWORD)sizeof(NOTIFYICONDATA); nid.hWnd=this->m_hWnd; nid.uID=IDR_MAINFRAME; nid.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP ; nid.uCallbackMessage=WM_SHOWTASK;//自定义的消息名称 nid.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME)); strcpy(nid.szTip,"对话框测试.exe"); //信息提示条为“计划任务提醒” Shell_NotifyIcon(NIM_DELETE,&nid); //在托盘区删除图标 } void CMyDlg::OnButton1() { // TODO: Add your control notification handler code here ToTray(); } void CMyDlg::OnReshow() { ShowWindow(SW_SHOW); DeleteTray(); }

 

程序里没有写自定义消息、添加消息响应等操作。这个可以自己加上去。

 

通过上面的程序,可以将程序最小化到托盘,并且右击图标时会弹出菜单“关闭”,点击后就关闭了。双击图标会重新显示程序窗口。

 

那么我现在要在该菜单里新添加几个菜单项该怎么办呢?可以看到程序里有这样的代码:

menu.AppendMenu(MF_STRING,WM_DESTROY,"关闭");

 

这就是添加菜单项的代码,它传递了一个WM_DESTROY命令给主窗口,因此我们可以按同样的方法添加自己的命令

menu.AppendMenu(MF_STRING,WM_RESHOW,"显示");

 

WM_RESHOW是我自己定义的命令,表示重新显示程序窗口,效果同双击该图标一样。

 

可奇怪的是当我单击该菜单项时并没有如我所预想的那样重新显示程序窗口。

 

经过思索我找到了原因:

 

你定义了消息后,选择从弹出菜单响应,但是你用了ON_MESSAGE宏,这个宏只是作出通常消息的映射,而不是命令消息的映射。既然是菜单,当然要用命令消息。WM_DESTROY之所以能够成功,正是因为它用了命令消息映射。
所以解决办法就是把

 

        ON_MESSAGE(WM_RESHOW,OnReshow)

改成 ON_COMMAND(WM_RESHOW,OnReshow)

 

最终实现了我要的功能,接着就可以按自己的要求添加菜单项了。

 

你可能感兴趣的:(MFC)