托盘图标和弹出菜单的实现

直接上代码:

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;
}


 

原文地址:https://www.cnblogs.com/hgy413/p/3693586.html