⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trayicon.cpp

📁 远程网络监视程序的源码
💻 CPP
字号:
//---------------------------------------------------------------------------
//
// TrayIcon.cpp
//
// SUBSYSTEM:   Hook system
//				
// MODULE:      Hook server
//
// DESCRIPTION: This code has been based on the Paul DiLascia's sample
//              Copyright 1996 Microsoft Systems Journal.
// 				
//             
// AUTHOR:		Ivo Ivanov (ivopi@hotmail.com)
// DATE:		2001 December v1.00
//
//---------------------------------------------------------------------------
#include "stdafx.h"
#include "trayicon.h"
#include <afxpriv.h>		// for AfxLoadString

IMPLEMENT_DYNAMIC(CTrayIcon, CCmdTarget)

// set tray icon ID and tooltips
CTrayIcon::CTrayIcon(UINT uID)
	: m_uTrayMenuID(0)
{
	// Initialize NOTIFYICONDATA
	ZeroMemory( &m_stNotifyData, sizeof(m_stNotifyData) );
	m_stNotifyData.cbSize = sizeof(m_stNotifyData);
	m_stNotifyData.uID = uID;	// never changes after construction

	// Use resource string as tip if there is one
	AfxLoadString(uID, m_stNotifyData.szTip, sizeof(m_stNotifyData.szTip));
}

CTrayIcon::~CTrayIcon()
{
	SetIcon(0, 0); // remove icon from system tray
}

//---------------------------------------------------------------------------
// SetNotificationWnd
//
// Set notification window. It must been created already.
//---------------------------------------------------------------------------
void CTrayIcon::SetNotificationWnd(CWnd* pNotifyWnd, UINT uCbMsg)
{
	// If the following assert fails, you're probably
	// calling me before you created your window. Oops.
	ASSERT( pNotifyWnd == NULL || ::IsWindow(pNotifyWnd->GetSafeHwnd()) );
	m_stNotifyData.hWnd = pNotifyWnd->GetSafeHwnd();

	ASSERT( uCbMsg == 0 || uCbMsg >= WM_USER );
	m_stNotifyData.uCallbackMessage = uCbMsg;
}

//---------------------------------------------------------------------------
// SetIcon
//
// This is the main variant for setting the icon.
// Sets both the icon and menu id from resource ID
// note: you can set different icon and menu for one tray app if
// calling this function repeatly
// To remove the icon, call SetIcon(0, 0)
//---------------------------------------------------------------------------
BOOL CTrayIcon::SetIcon(UINT uIconID, UINT uMenuID)
{ 
	HICON hicon = NULL;

	if (uIconID) 
	{
		if( !m_stNotifyData.szTip[0] )
		{
			AfxLoadString(uIconID, m_stNotifyData.szTip, sizeof(m_stNotifyData.szTip));
		}

		hicon = AfxGetApp()->LoadIcon(uIconID);
	}

	return SetIcon(hicon, uMenuID, NULL);
}

//---------------------------------------------------------------------------
// SetIcon
//
// Common SetIcon for all overloads. 
//---------------------------------------------------------------------------
BOOL CTrayIcon::SetIcon(HICON hicon, UINT uMenuID, LPCTSTR lpTip) 
{
	UINT msg;
	m_stNotifyData.uFlags = 0;

	// Set the icon
	if (hicon) 
	{
		// Add or replace icon in system tray
		msg = m_stNotifyData.hIcon ? NIM_MODIFY : NIM_ADD;
		if( msg == NIM_MODIFY )
		{
			DestroyIcon(m_stNotifyData.hIcon);
		}

		m_stNotifyData.hIcon = hicon;
		m_stNotifyData.uFlags |= NIF_ICON;
	} 
	else 
	{
		// remove icon from tray
		if ( !m_stNotifyData.hIcon )
		{
			return TRUE;		// already deleted
		}
		msg = NIM_DELETE;
	}

	// set menu id
	m_uTrayMenuID = uMenuID;

	// Use the tip, if any
	if( lpTip )
	{
		strncpy( m_stNotifyData.szTip, lpTip, sizeof(m_stNotifyData.szTip) );
	}

	if( m_stNotifyData.szTip[0] )
	{
		m_stNotifyData.uFlags |= NIF_TIP;
	}

	// Use callback if any
	if( m_stNotifyData.uCallbackMessage && m_stNotifyData.hWnd )
	{
		m_stNotifyData.uFlags |= NIF_MESSAGE;
	}

	// Do it
	BOOL bRet = Shell_NotifyIcon( msg, &m_stNotifyData );
	if ( msg == NIM_DELETE || !bRet )
	{
		DestroyIcon(m_stNotifyData.hIcon);
		m_stNotifyData.hIcon = NULL;	// failed
	}

	return bRet;
}

//---------------------------------------------------------------------------
// OnTrayNotification
//
// Default event handler handles right-menu and doubleclick.
// Call this function from your own notification handler.
//---------------------------------------------------------------------------
LRESULT CTrayIcon::OnTrayNotification(WPARAM wID, LPARAM lEvent)
{
	if( !m_uTrayMenuID || (wID != m_stNotifyData.uID)
		 || ((lEvent != WM_RBUTTONUP) && (lEvent != WM_LBUTTONUP)) )
	{
		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(m_uTrayMenuID) )
		return 0;

	CMenu* pSubMenu = menu.GetSubMenu(0);
	if (!pSubMenu) 
		return 0;

	if (lEvent == WM_RBUTTONUP) 
	{
		//
		// 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_stNotifyData.hWnd);	
		::TrackPopupMenu(pSubMenu->m_hMenu, 0, mouse.x, mouse.y, 0,
			m_stNotifyData.hWnd, NULL);
	}
	else
	{
		// left button clicked: execute first menu item
		::SendMessage(m_stNotifyData.hWnd, WM_COMMAND, pSubMenu->GetMenuItemID(0), 0);
	}

	return 1; // handled
}

//----------------------------End of the file -------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -