VC里面要添加托盘图标和托盘菜单,大概过程:
MSDN中介绍的结构体:
typedef struct _NOTIFYICONDATA {
DWORD cbSize;//结构体的大小
HWND hWnd;//窗口句柄
UINT uID;//图标关联的ID,需要和多个托盘图标关联时用到
UINT uFlags;//标识,表明该托盘图标需要修改的内容,如图标,提示,状态等
UINT uCallbackMessage;//自定义回调消息
HICON hIcon;//图标
TCHAR szTip[64];//鼠标指着图标时的提示信息
DWORD dwState;//图标状态
DWORD dwStateMask;//指明dwState成员的那些位可以被设置或者访问
TCHAR szInfo[256];//气球提示内容
union {
UINT uTimeout;//气球提示的超时时间
UINT uVersion;//版本,用于Windows95和2000风格的图标消息接口
};
TCHAR szInfoTitle[64];//气球提示的标题
DWORD dwInfoFlags;//气球提示的图标
GUID guidItem;//保留
HICON hBalloonIcon;//气球提示的图标,VISTA以上使用
} NOTIFYICONDATA, *PNOTIFYICONDATA;
1. 先添加一个成员变量 NOTIFYICONDATA m_NotiIcon;
2.定义自定义一个消息: #define WM_MY_TRAY_NOTIFICATION WM_USER+100
3 .声明消息处理函数; LRESULT OnNotifyIcon(WPARAM wParam, LPARAM lParam);
4.将消息与消息处理函数联系起来: ON_MESSAGE(WM_MY_TRAY_NOTIFICATION,OnTrayNotification)
5. 实现消息处理:
LRESULT CW620Dlg::OnTrayNotification(WPARAM uID,LPARAM lEvent)
{
if (uID!=m_NotiIcon.uID ||
(lEvent!=WM_RBUTTONUP && lEvent!=WM_LBUTTONDBLCLK))
return 0;
// If there's a resource menu with the same ID as the icon, use it as
// the right-button popup menu. CTrayIcon will interprets the first
// item in the menu as the default command for WM_LBUTTONDBLCLK
//
CMenu menu;
if (!menu.LoadMenu(IDR_MENUICON))
return 0;
CMenu* pSubMenu = menu.GetSubMenu(0);
if (!pSubMenu)
return 0;
if (lEvent==WM_RBUTTONUP) {
// Make first menu item the default (bold font)
::SetMenuDefaultItem(pSubMenu->m_hMenu, 0, TRUE);
// Display the menu at the current mouse location. There's a "bug"
// (Microsoft calls it a feature) in Windows 95 that requires calling
// SetForegroundWindow. To find out more, search for Q135788 in MSDN.
//
CPoint mouse;
GetCursorPos(&mouse);
::SetForegroundWindow(m_NotiIcon.hWnd);
::TrackPopupMenu(pSubMenu->m_hMenu, 0, mouse.x, mouse.y, 0,
m_NotiIcon.hWnd, NULL);
} else // double click: execute first menu item
::SendMessage(m_NotiIcon.hWnd, WM_COMMAND, pSubMenu->GetMenuItemID(0), 0);
return 1; // handled
}
6. 添加托盘图标;
在你需要实现托盘的地方添加托盘
BOOL CW620Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
//////////////////////////////////////////////////////////////
/*
Set the min tray ICON
*/
//托盘结构体成员初始化
m_NotiIcon.cbSize=sizeof(NOTIFYICONDATA);
m_NotiIcon.hWnd=this->m_hWnd;
m_NotiIcon.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP;
m_NotiIcon.uCallbackMessage=WM_MY_TRAY_NOTIFICATION;
//用户定义的回调消息
CString szToolTip;
szToolTip=_T("W620 数据存储");
_tcscpy(m_NotiIcon.szTip, szToolTip);
m_NotiIcon.uID=IDI_ICON2/*IDR_MAINFRAME*/;
HICON hIcon;
hIcon=AfxGetApp()->LoadIcon(IDI_ICON2);
m_NotiIcon.hIcon=hIcon;
::Shell_NotifyIcon(NIM_ADD,&m_NotiIcon);
if(hIcon)::DestroyIcon(hIcon);
}
7. 销毁图标
void CW620Dlg::OnDestroy()
{
// TODO: Add your message handler code here
::Shell_NotifyIcon(NIM_DELETE,&m_NotiIcon);
}
8.如要隐藏任务栏程序:
void CW620Dlg::OnNcPaint()
{
// TODO: Add your message handler code here
static int i = 2;
if(i > 0)
{
i --;
ShowWindow(SW_HIDE);
}
else
{
CDialog::OnNcPaint();
}
// Do not call CDialog::OnNcPaint() for painting messages
}
9.处理最小化:
重载WindowProc函数:
WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
switch(message)
{
case WM_SYSCOMMAND://如果是系统消息
if(wParam==SC_MINIMIZE)
{
//接收到最小化消息时主窗口隐藏
AfxGetApp()->m_pMainWnd->ShowWindow(SW_HIDE);
return 0;
}
break;
}
return CWnd::WindowProc(message, wParam, lParam);
}
10. 显示窗体
AfxGetApp()->m_pMainWnd->ShowWindow(SW_SHOW);
11. 退出程序:
SendMessage(WM_CLOSE,0,0); or PostMessage(WM_QUITE,0,0)