直接上代码:
void CIconDemoDlg::InitTrayIcon(void)
{
//--------------------------------------------------
// NOTIFYICONDATA:
// cbSize: 这个结构的字节大小
// hwnd: 窗口句柄,当鼠标事件发生在系统托盘上时,这个窗口将接收通知码。
// uID: 作为图标标识的一常数。你可以取任意值,但是值必须是唯一的。因为,当有多个图标在托盘上时,你将要区分鼠标消息来自于那个图标。故这个值必须取唯一值。
// uFlags 指定这个结构的那些成员变量有效。
// NIF_ICON hIcon 成员有效
// NIF_MESSAGE uCallbackMessage 成员有效
// NIF_TIP SzTip 成员有效
// uCallbackMessage:自定义消息。当鼠标事件在托盘图标上发生时,windows将通过hwnd成员发送给指定的窗口。你可以自己创建这个消息。
// hIcon: 你想放在系统托盘上的图标的句柄。
// SzTip: 一个64位的数组,这个数组存放的是---当鼠标停留在小图标上时,作为提示文本的字符串。
//--------------------------------------------------
NOTIFYICONDATA nta = {sizeof(NOTIFYICONDATA), GetSafeHwnd()};
nta.uID = IDR_MAINFRAME;
nta.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
nta.uCallbackMessage = MY_TRAY_MSG;
nta.hIcon = m_hIcon;
CString szTip = TEXT("oNLY");
#if _MSC_VER >= 1400
_tcscpy_s(nta.szTip, szTip);
#else
_tcscpy(nta.szTip, szTip);
#endif
nta.uTimeout = 30000;
//------------------------------------------------------------
// Shell_NotifyIcon:
// DwMessage 是发送给windows外壳的消息.
// NIM_ADD 往状态栏上增加一个图标.
// NIM_DELETE 从状态栏上删除一图标.
// NIM_MODIFY 在状态栏中修改一图标.
// -----------------------------------------------------------
Shell_NotifyIcon(NIM_ADD, &nta);
}
2.在OnInitDialog加入InitTrayIcon();
3.处理自定义消息,用于弹出菜单:
LRESULT XXXX::OnTrayMsg(WPARAM wParam, LPARAM lParam)
{
switch (lParam)
{
case WM_RBUTTONUP:
{
CPoint pt;
GetCursorPos(&pt);
//------------------------------------------
// 弹出式菜单被显示时,如果你在菜单以外任何地方点击了鼠标
//,这个弹出式菜单不会立即消失不见。
// 因为接收菜单消息的窗口必须是前景窗口。
// 调用SetForegroundWindow设置前景窗口
//------------------------------------------
//------------------------------------------------
// 暂记下,没有出现过------------hgy notes
// 在调用SetForegroundWindow函数后,
// 你将发现第一次弹出的菜单正常显示并且工作的很好,
// 但是在后来,弹出式菜单弹出便立即关闭。
// 引用MSDN这样的行为是“故意的”。
// 为了使得弹出菜单保持住,必须要求下一个切换到的是程序的主窗口。
// 你能通过置入任何消息给程序的窗口来强制的切换任务。
// 但是只能用PostMessage函数而不能用SendMessage函数
//-----------------------------------------------
SetForegroundWindow();
m_TrayMenu.TrackPopupMenu(TPM_LEFTALIGN, pt.x, pt.y, this) ;
}
break;
default:
break;
}
return TRUE;
}