找回密码
 注册
搜索
查看: 743|回复: 0

VC实现托盘程序

[复制链接]
发表于 2010-7-27 00:18:05 | 显示全部楼层 |阅读模式
  现在很多程序都有托盘功能,下面介绍一下如何在VC下实现托盘程序的功能:

  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();

  }
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|QQ客服|联系我们|Archiver|手机版|小黑屋|悉远网络 ( 鄂ICP备09013446号 )

GMT+8, 2024-11-21 21:40 , Processed in 0.034448 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表