直接上代码:
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; }