📄 trayicon.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 + -