vc实现托盘

来源:互联网 发布:朝鲜为什么恨中国知乎 编辑:程序博客网 时间:2024/05/19 23:00
 NOTIFYICONDATA结构体解释如下:

用来做任务栏右边的小图标

// 结构长度
m_NotifyIconData.cbSize = sizeof(NOTIFYICONDATA);

// 窗口,消息将发给该窗口
m_NotifyIconData.hWnd = this->m_hWnd;

// 表示消息发给该窗口时附带ID,那么你就能够if( id == IDR_MAINFRAME )
// { do your proc }
m_NotifyIconData.uID = IDR_MAINFRAME;

// 指定NOTIFYICONDATA结构中uCallbackMessage、hIcon、szTip有填内容
m_NotifyIconData.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;

// 表示要放入System tray(系统托盘,放输入法图标的那个地方)的图标
m_NotifyIconData.hIcon = LoadIcon(AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDR_MAINFRAME));

// 自定义消息例如#define WM_USER_CLICKME ( WM_USER + 1 )
// 当你鼠标点击等在图标上时,系统会发这个消息给你的窗口,那么你就可
// 以比如弹出一个菜单
m_NotifyIconData.uCallbackMessage = WM_USER_CLICKME;

 

1.准备一个菜单
 菜单有两上项“显示”和“退出”。
 菜单的名为“托盘菜单”ID为:IDR_MENU_TRAY,两个项分别为:IDR_MENU_SHOW,IDR_MENU_EXIT。
2.初始化托盘
(1)源代码
void CSmsDlg::InitTray()
{
 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_NOTIFYICON;//自定义的消息名称
 nid.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));
 strcpy(nid.szTip,"东讯短信平台");//信息提示
 Shell_NotifyIcon(NIM_ADD,&nid);//在托盘区添加图标  
}
(2)消息的定义#define WM_NOTIFYICON WM_USER+5,一般放在头文件的开始。
(3)所有到的变量 NOTIFYICONDATA nid; 一般在头文件中定义。
(4)初始化托盘函数一般在初始化对话框函数中引用或在单文档中int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)引用
3.响应托盘消息函数
(1)源代码
LONG CSmsDlg::OnNotifyIcon(WPARAM wParam, LPARAM lParam)
{
 //wParam中是响应消息的图标ID,lParam中则是Windows的消息
 CMenu pMenu;
 switch ( lParam )
 {
 case WM_RBUTTONDOWN:// 用户在托盘图标上单击鼠标左、右键,弹出菜单
 case WM_LBUTTONDOWN:
  
  if (pMenu.LoadMenu(IDR_MENU_TRAY))
  {
   CMenu* pPopup = pMenu.GetSubMenu(0);
   ASSERT(pPopup != NULL);
   CPoint Point;
   //if(IsIconic()) pPopup->EnableMenuItem(IDC_MIN,MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
   if (IsWindowVisible())
   {// 根据对话框窗口的显示/隐藏状态修改菜单名称
    if(!IsIconic())
     pPopup->EnableMenuItem(IDR_MENU_SHOW,MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
   }
   //else
   // pPopup->EnableMenuItem(ID_MENUITEM_HIDE,MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
   // 确定鼠标位置以便在该位置附近显示菜单
   GetCursorPos( &Point );
   SetForegroundWindow();
   pPopup->TrackPopupMenu(
    TPM_LEFTALIGN | TPM_RIGHTBUTTON,
    Point.x, Point.y, this);
           
  break;
 case WM_LBUTTONDBLCLK:
  OnMenuShow();
  break;
 default:
  break; 
 
 return 0;
}
(2)在头文件中定义函数
protected:
 HICON m_hIcon;

 // Generated message map functions
 //{{AFX_MSG(CSmsDlg)
 virtual BOOL OnInitDialog();
 afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
 afx_msg void OnPaint();
 afx_msg HCURSOR OnQueryDragIcon();
 virtual void OnOK();
 afx_msg void OnMenuShow();
 afx_msg void OnMenuExit();
 afx_msg void OnSize(UINT nType, int cx, int cy);
 afx_msg LONG OnNotifyIcon(WPARAM wParam, LPARAM lParam);//定义的一个
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
(3)在源文件中响应消息
BEGIN_MESSAGE_MAP(CSmsDlg, CDialog)
//{{AFX_MSG_MAP(CSmsDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_COMMAND(IDR_MENU_SHOW, OnMenuShow)
ON_COMMAND(IDR_MENU_EXIT, OnMenuExit)
ON_WM_SIZE()
ON_WM_CANCELMODE()
ON_MESSAGE(WM_NOTIFYICON, OnNotifyIcon)//手工添加托盘消息映射
//}}AFX_MSG_MAP

END_MESSAGE_MAP()
4.菜单函数的添加
(1)托盘显示菜单
void CSmsDlg::OnMenuShow()
{
 // TODO: Add your command handler code here
 ShowWindow(SW_SHOWNORMAL);
}

(2)托盘退出菜单
void CSmsDlg::OnMenuExit()
{
 // TODO: Add your command handler code here
 Shell_NotifyIcon(NIM_DELETE, &nid);
 CDialog::OnCancel();
}

2007.9.5添加

1.不在下边的状态栏显示

在OnSize中添加下列代码

void CMainFrame::OnSize(UINT nType, int cx, int cy)
{
 CFrameWnd::OnSize(nType, cx, cy);
 
 // TODO: Add your message handler code here
 if (nType == SIZE_MINIMIZED)
  ShowWindow(SW_HIDE);
}

2.关闭时不关闭,显示托盘

(1)基于对话框的将OnSysCommand的代码改为下边的代码

void CSmsDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
 {
  CAboutDlg dlgAbout;
  dlgAbout.DoModal();
 }
 else if ((nID & 0xFFF0)==SC_CLOSE)
 
  ShowWindow(SW_HIDE);//系统菜单的关闭也改为隐藏。
 }
 else
 {
  CDialog::OnSysCommand(nID, lParam);
 }
}

(2)基于单文档将OnClose的代码改为下边的代码

//关闭对话框  2007.09.10
void CMainFrame::OnClose()
{
 // TODO: Add your message handler code here and/or call default
 //InitTray();
  ShowWindow(SW_HIDE);//系统菜单的关闭也改为隐藏。
 
 //CFrameWnd::OnClose();
}

3.可以查看这个连接

http://blog.sina.com.cn/s/blog_4171e80d010007hx.html