MFC

在VC++中,想实现最小化MFC程序的时候,最小化到系统托盘,需要调用NOTIFYICONDATA数据结构

下面我们就来讲解一下如何简单实现一个系统托盘 我们以对话框程序为列

第一步:在Dlg类中//定义一个NOTIFYICONDATA数据结构的成员变量,用来设置托盘

NOTIFYICONDATA NotifyIcon;

第二步:声明一个消息响应函数

 afx_msg LRESULT OnNotifyIcon(WPARAM wParam,LPARAM IParam);

afx_msg void OnOption();  //用于托盘右键菜单的选项

上面那条代码也放在Dlg的头文件中

第三步:定义一个自定义消息

#define WM_NIC WM_USER+100

#define WM_APP_OPTION WM_USER+101 //用于托盘右键菜单的选项

上面那条代码也在Dlg的头文件中声明

在消息映射中注册 ON_MESSAGE(WM_NIC,OnNotifyIcon)

ON_COMMAND(WM_APP_OPTION,OnOption) //用于托盘右键菜单的选项

上面那条代码在Dlg类中

第四步:在Dlg头文件中添加一个函数 用来响应点击最小化按钮

void ChangeStatusToMinisize();

并在Dlg类中实现这个函数

 

//处理拦截的最小化事件
void MainBody_Client::ChangeStatusToMinisize(){
      ShowWindow(SW_HIDE);
      NotifyIcon.cbSize=sizeof(NOTIFYICONDATA);
      NotifyIcon.hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);
      NotifyIcon.hWnd=m_hWnd;
      lstrcpy(NotifyIcon.szTip,"MiniQick服务器");   //当鼠标移动到上面显示的信息,不要包含太多字符
      NotifyIcon.uCallbackMessage=WM_NIC;
      NotifyIcon.uFlags=NIF_ICON | NIF_MESSAGE | NIF_TIP;
      Shell_NotifyIcon(NIM_ADD,&NotifyIcon);
}

第五步:截获最小化事件

在Dlg类中找到OnSysCommand函数,进行重写操作

代码如下

if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
   CAboutDlg dlgAbout;
   dlgAbout.DoModal();
}

//添加代码如下,拦截最小化事件

 if (nID == SC_MINIMIZE)
 {
  ChangeStatusToMinisize();

  return;
  //MessageBox(_T("SC_MINIMIZE"),NULL,NULL);
 }//用我们自己的消息响应最小化事件
else
{
   CDialog::OnSysCommand(nID, lParam);
}

第六步:响应托盘的鼠标事件 也是实现我们第二部声明的消息响应函数

LRESULT MainBody_Client::OnNotifyIcon(WPARAM wParam,LPARAM IParam)
{

if (lParam == WM_LBUTTONDOWN )  //左键
 {
  ModifyStyleEx(0,WS_EX_TOPMOST);
  ShowWindow(SW_SHOW);
  return NULL;
 }

 if (lParam == WM_RBUTTONUP) //右击事件
 {
  //右键起来时弹出快捷菜单,这里显示“关闭”等选项  
 
  LPPOINT lpoint=new tagPOINT;  
  ::GetCursorPos(lpoint);//得到鼠标位置  
  CMenu   menu;  
  menu.CreatePopupMenu();//声明一个弹出式菜单 

  //增加菜单项“关闭”,点击则发送消息WM_DESTROY给主窗口(已隐藏),将程序结束。
  menu.AppendMenu(MF_STRING,WM_APP_OPTION,L"选项...");
  menu.AppendMenu(MF_SEPARATOR,0,L"");             //添加分割线
  menu.AppendMenu(MF_STRING,WM_DESTROY,L"退出");
  
  //确定弹出式菜单的位置  
  menu.TrackPopupMenu(TPM_LEFTALIGN,lpoint->x,lpoint->y,this);  
  //资源回收  
  HMENU   hmenu=menu.Detach();  
  menu.DestroyMenu();  
  delete   lpoint;  
 }

return NULL;
}

第七步: 设置托盘右键菜单的选项功能

//选项对话框
void MainBody_Client::OnOption()
{
    CDlgOption dlg;

    int nResponse=dlg.DoModal();

    if(nResponse == IDOK)
    {

    }
    else
    {

    }   
}

最后一步:在类的析构函数中 记得销毁托盘图标对象

Shell_NotifyIcon(NIM_DELETE, &NotifyIcon);