MFC对话框程序实现托盘功能

 

托盘程序需要头文件:

#include <shellapi.h> //托盘程序 

 

1.用户自定义消息

#define WM_SYSTEMTRAY         (WM_USER+103) //响应鼠标在托盘图标上的事件

2.在对话框头文件中:

 //在托盘区添加图标 最小化到托盘函数
 void ToTray(void);
 //删除托盘中图标
 void DeleteTray();

 

////////////////////下面的方法是实现菜单响应函数//////////////////////////////////////////////////////////////////////////////

//定义右键托盘图标弹出的菜单ID

typedef enum
{
ID_SHIFT_WORKPATTERN = 10001,
ID_QUIT = 10002

}TRAY_MENU;

//自定义消息WM_SYSTEMTRAY的响应函数,处理鼠标事件,如:右键鼠标弹出菜单

afx_msg LRESULT OnSystemtray(WPARAM wParam, LPARAM lParam);

//在OnCommand中响应菜单消息: 

virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);

 

3.在对话框原文件中:

 

BEGIN_MESSAGE_MAP(CSSDlg, CDialog)

 ON_MESSAGE(WM_SYSTEMTRAY, &CSSDlg::OnSystemtray)
 
END_MESSAGE_MAP()

 

void CSSDlg::ToTray( void )
{
 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_SYSTEMTRAY;//自定义的消息名称
 nid.hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME));
 //wcscpy_s(nid.szTip, _T("****系统"));//信息提示条
 strcpy(nid.szTip, _T("****系统"));//信息提示条
 Shell_NotifyIcon(NIM_ADD, &nid);//在托盘区添加图标
 ShowWindow(SW_HIDE);//隐藏主窗口


 

void CSSDlg::DeleteTray()
{
 NOTIFYICONDATA nid;
 nid.cbSize = (DWORD)sizeof(NOTIFYICONDATA);
 nid.hWnd = this->m_hWnd;
 nid.uID = IDR_MAINFRAME;
 nid.uFlags = NIF_ICON;
 Shell_NotifyIcon(NIM_DELETE, &nid);//在托盘中删除图标
}

托盘鼠标事件响应函数:

LRESULT CSSDlg::OnSystemtray( WPARAM wParam, LPARAM lParam )
{
 //wParam接收的是图标的ID,而lParam接收的是鼠标的行为
 //  if(wParam!=IDR_MAINFRAME) 
 //      return    1;
 switch(lParam)
 {
 case  WM_RBUTTONDOWN://右键起来时弹出快捷菜单
  {
   LPPOINT lpoint = new tagPOINT;
   ::GetCursorPos(lpoint);//得到鼠标位置
   CMenu menu;
   menu.CreatePopupMenu();//声明一个弹出式菜单
   //增加菜单项“关闭”,点击则发送消息WM_DESTROY给主窗口(已隐藏),将程序结束。
  // menu.AppendMenu(MF_STRING, WM_DESTROY, _T("退出")); //调试的时候发现响应的是OnCancel(),不是OnDestroy

   menu.AppendMenu(MF_STRING, ID_QUIT, _T("退出"));  //响应OnDestroy()
   menu.AppendMenu(MF_STRING, ID_SHIFT_WORKPATTERN, _T("切换工作模式"));

SetForegroundWindow();//设置当失去焦点时菜单自动消失
   //确定弹出式菜单的位置
   menu.TrackPopupMenu(TPM_LEFTALIGN, lpoint->x, lpoint->y, this);
   //资源回收
   HMENU hmenu = menu.Detach();
   menu.DestroyMenu();
   delete lpoint;
  }
  break; 
 case WM_LBUTTONDOWN://左键单击的处理
  {
   ModifyStyleEx(0,WS_EX_TOPMOST);   //可以改变窗口的显示风格
   ShowWindow(SW_SHOWNORMAL);
   break;
  }
 case WM_LBUTTONDBLCLK://双击左键的处理
  {
   this->ShowWindow(SW_SHOW);//简单的显示主窗口
   this->ShowWindow(SW_RESTORE);
   DeleteTray();
   //break;
  }
  break;
 default:
  break;
 }
 return 0;
}

 

实现菜单消息函数:

BOOL CSSDlg::OnCommand( WPARAM wParam, LPARAM lParam )
{
int menuID = LOWORD(wParam);
if ( ID_SHIFT_WORKPATTERN == menuID )
{
do something......
return TRUE;
}
if(ID_QUIT == menuID)
{
DestroyWindow();
return TRUE;
}

return CDialog::OnCommand(wParam,lParam);

}

 

 4. 在关闭时最小化到托盘,而不是关闭:

void CSSDlg::OnSysCommand(UINT nID, LPARAM lParam)

{  

if ((nID & 0xFFF0) == IDM_ABOUTBOX)  

{   CAboutDlg dlgAbout;  }  

else if (nID == SC_CLOSE) //SC_MINIMIZE

 {   

ToTray();   

return;  

}

 CDialog::OnSysCommand(nID, lParam);  

}

 

或者重写close函数:

void CMyPlayerDlg::OnCancel()  //点击X 按钮或者按ESC键,最小化到系统托盘
{
    // TODO: 在此添加专用代码和/或调用基类
  ToTray( );
    //CDialogEx::OnCancel();
}

 

 

参考:

http://blog.csdn.net/CHIHUN_LOVE/article/details/53944553

利用CMenu类动态添加弹出菜单 - jackyxm - 博客园  http://www.cnblogs.com/yxmx/articles/1628058.html

[罗振辉]MFC中菜单命令路由方式 - CSDN博客  http://blog.csdn.net/xxxluozhen/article/details/3930472

 

posted on 2018-03-21 17:47  南枝  阅读(1431)  评论(0编辑  收藏  举报