CTrayIcon类的头文件;
#ifndef _TRAYICON_H
#define _TRAYICON_H
class CTrayIcon : public CCmdTarget {
protected:
DECLARE_DYNAMIC(CTrayIcon)
NOTIFYICONDATA m_nid; // struct for Shell_NotifyIcon args
public:
CTrayIcon(UINT uID);
~CTrayIcon();
// Call this to receive tray notifications
void SetNotificationWnd(CWnd* pNotifyWnd, UINT uCbMsg);
BOOL SetIcon(UINT uID); // main variant you want to use
BOOL SetIcon(HICON hicon, LPCSTR lpTip);
BOOL SetIcon(LPCTSTR lpResName, LPCSTR lpTip)
{ return SetIcon(lpResName ?
AfxGetApp()->LoadIcon(lpResName) : NULL, lpTip); }
BOOL SetStandardIcon(LPCTSTR lpszIconName, LPCSTR lpTip)
{ return SetIcon(::LoadIcon(NULL, lpszIconName), lpTip); }
virtual LRESULT OnTrayNotification(WPARAM uID, LPARAM lEvent);
};
#endif
///CTrayIcon类的.CPP文件
#include "stdafx.h"
#include "trayicon.h"
#include <afxpriv.h> // for AfxLoadString
IMPLEMENT_DYNAMIC(CTrayIcon, CCmdTarget)
CTrayIcon::CTrayIcon(UINT uID)
{
memset(&m_nid, 0 , sizeof(m_nid)); // Initialize NOTIFYICONDATA
m_nid.cbSize = sizeof(m_nid);
m_nid.uID = uID; // never changes after construction
AfxLoadString(uID, m_nid.szTip, sizeof(m_nid.szTip));
// Use resource string as tip if there is one
}
CTrayIcon::~CTrayIcon()
{
SetIcon(0); // remove icon from system tray
}
void CTrayIcon::SetNotificationWnd(CWnd* pNotifyWnd, UINT uCbMsg)
{
// Set notification window. It must created already.
ASSERT(pNotifyWnd==NULL || ::IsWindow(pNotifyWnd->GetSafeHwnd()));
m_nid.hWnd = pNotifyWnd->GetSafeHwnd();
ASSERT(uCbMsg==0 || uCbMsg>=WM_USER);
m_nid.uCallbackMessage = uCbMsg;
}
BOOL CTrayIcon::SetIcon(UINT uID)
{
// Sets both the icon and tooltip from resource ID ,To remove the icon, call SetIcon(0)
HICON hicon=NULL;
if (uID) {
AfxLoadString(uID, m_nid.szTip, sizeof(m_nid.szTip));
hicon = AfxGetApp()->LoadIcon(uID);
}
return SetIcon(hicon, NULL);
}
BOOL CTrayIcon::SetIcon(HICON hicon, LPCSTR lpTip)
{
// Common SetIcon for all overloads.
UINT msg;
m_nid.uFlags = 0;
if (hicon) {
// Set the icon
msg = m_nid.hIcon ? NIM_MODIFY : NIM_ADD;
m_nid.hIcon = hicon; // Add or replace icon in system tray
m_nid.uFlags |= NIF_ICON;
} else {
if (m_nid.hIcon==NULL) // remove icon from tray
return TRUE; // already deleted
msg = NIM_DELETE;
}
if (lpTip) // Use the tip, if any
strncpy(m_nid.szTip, lpTip, sizeof(m_nid.szTip));
if (m_nid.szTip[0])
m_nid.uFlags |= NIF_TIP;
if (m_nid.uCallbackMessage && m_nid.hWnd) // Use callback if any
m_nid.uFlags |= NIF_MESSAGE;
BOOL bRet = Shell_NotifyIcon(msg, &m_nid); // Do it
if (msg==NIM_DELETE || !bRet)
m_nid.hIcon = NULL; // failed
return bRet;
}
LRESULT CTrayIcon::OnTrayNotification(WPARAM wID, LPARAM lEvent)
{
if (wID!=m_nid.uID || (lEvent!=WM_RBUTTONUP && lEvent!=WM_LBUTTONDBLCLK))
return 0;
CMenu menu;//装载上下文菜单;
if (!menu.LoadMenu(m_nid.uID))
return 0;
CMenu* pSubMenu = menu.GetSubMenu(0);
if (!pSubMenu)
return 0;
if (lEvent==WM_RBUTTONUP) {//设置第一个菜单项为默认菜单项目
::SetMenuDefaultItem(pSubMenu->m_hMenu, 0, TRUE);
//将当前菜单作为上下文菜单;
CPoint mouse;
GetCursorPos(&mouse);
::SetForegroundWindow(m_nid.hWnd);
::TrackPopupMenu(pSubMenu->m_hMenu, 0, mouse.x, mouse.y, 0,m_nid.hWnd, NULL);
} else // double click: execute first menu item
::SendMessage(m_nid.hWnd, WM_COMMAND, pSubMenu->GetMenuItemID(0), 0);
return 1;
}
/ MainFrm.h : interface of the CMainFrame class
#if !defined(AFX_MAINFRM_H__9ED70A69_C975_4F20_9D4E_B2877E3575D0__INCLUDED_)
#define AFX_MAINFRM_H__9ED70A69_C975_4F20_9D4E_B2877E3575D0__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "trayicon.h"
class CMainFrame : public CFrameWnd
{
public:
CMainFrame();
protected:
DECLARE_DYNAMIC(CMainFrame)
// Attributes
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMainFrame)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CMainFrame();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected: // control bar embedded members
CStatusBar m_wndStatusBar;
CTrayIcon m_trayIcon; // my tray icon
CEdit m_wndEdit; // to display tray notifications
int m_iWhichIcon; // which HICON to use
BOOL m_bShutdown; // OK to terminate TRAYTEST
BOOL m_bShowTrayNotifications; // display info in main window
// Generated message map functions
protected:
//{{AFX_MSG(CMainFrame)
afx_msg LRESULT OnTrayNotification(WPARAM wp, LPARAM lp);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnToggleIcon();
afx_msg void OnViewClear();
afx_msg void OnViewNotifications();
afx_msg void OnUpdateViewClear(CCmdUI* pCmdUI);
afx_msg void OnUpdateViewNotifications(CCmdUI* pCmdUI);
afx_msg void OnClose();
afx_msg void OnAppOpen();
afx_msg void OnAppSuspend();
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
///CMainFrm.cpp
#include "stdafx.h"
#include "TrayTest.h"
#include "MainFrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CMainFrame
// Message ID used for tray notifications
#define WM_MY_TRAY_NOTIFICATION WM_USER+0
IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code !
ON_MESSAGE(WM_MY_TRAY_NOTIFICATION, OnTrayNotification)
ON_WM_CREATE()
ON_COMMAND(ID_VIEW_CLEAR, OnViewClear)
ON_COMMAND(ID_TOGGLE_ICON, OnToggleIcon)
ON_COMMAND(ID_VIEW_NOTIFICATIONS, OnViewNotifications)
ON_UPDATE_COMMAND_UI(ID_VIEW_CLEAR, OnUpdateViewClear)
ON_UPDATE_COMMAND_UI(ID_VIEW_NOTIFICATIONS, OnUpdateViewNotifications)
ON_WM_CLOSE()
ON_COMMAND(ID_APP_OPEN, OnAppOpen)
ON_COMMAND(ID_APP_SUSPEND, OnAppSuspend)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
static UINT indicators[] =
{
ID_SEPARATOR, // status line indicator
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
/
// CMainFrame construction/destruction
CMainFrame::CMainFrame() : m_trayIcon(IDR_TRAYICON)
{
// TODO: add member initialization code here
m_bShowTrayNotifications = TRUE;//zxn
m_bShutdown = FALSE;//zxn
}
CMainFrame::~CMainFrame()
{}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndStatusBar.Create(this) ||!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar/n");
return -1; // fail to create
}
// Create child edit control for displaying messages
CRect rc;
if (!m_wndEdit.Create(
WS_VISIBLE|WS_CHILD|WS_VSCROLL|ES_MULTILINE|ES_READONLY, rc, this,
AFX_IDW_PANE_FIRST))
return -1;
// Set up tray icon
m_trayIcon.SetNotificationWnd(this, WM_MY_TRAY_NOTIFICATION);
m_iWhichIcon = 1;
m_trayIcon.SetIcon(IDI_MYICON);
return 0;
}
//
// Close window. Unless we are shutting down, just hide it.
void CMainFrame::OnClose()
{
if (m_bShutdown)
CFrameWnd::OnClose();
else
ShowWindow(SW_HIDE);
}
Handle notification from tray icon: display a message.
LRESULT CMainFrame::OnTrayNotification(WPARAM uID, LPARAM lEvent)
{
if (m_bShowTrayNotifications) {
static LPCSTR MouseMessages[] = { "WM_MOUSEMOVE",
"WM_LBUTTONDOWN", "WM_LBUTTONUP", "WM_LBUTTONDBLCLK",
"WM_RBUTTONDOWN", "WM_RBUTTONUP", "WM_RBUTTONDBLCLK",
"WM_MBUTTONDOWN","WM_MBUTTONUP","WM_MBUTTONDBLCLK" };
CString s;
s.Format("托盘通知消息: ID=%d, lEvent=0x%04x %s/r/n",
uID, lEvent, WM_MOUSEFIRST<=lEvent && lEvent<=WM_MOUSELAST ?
MouseMessages[lEvent-WM_MOUSEFIRST] : "(未知消息)");
m_wndEdit.SetSel(-1, -1); // end of edit text
m_wndEdit.ReplaceSel(s); // append string..
m_wndEdit.SendMessage(EM_SCROLLCARET); // ..and make visible
}
// let tray icon do default stuff
return m_trayIcon.OnTrayNotification(uID, lEvent);
}
// Command handlers below.
//
void CMainFrame::OnViewClear()
{
m_wndEdit.SetWindowText("");
}
void CMainFrame::OnUpdateViewClear(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_wndEdit.GetLineCount() > 1 || m_wndEdit.LineLength() > 0);
}
void CMainFrame::OnToggleIcon()
{
m_iWhichIcon=!m_iWhichIcon;
m_trayIcon.SetIcon(m_iWhichIcon ? IDI_MYICON : IDI_MYICON2);
}
void CMainFrame::OnViewNotifications()
{
m_bShowTrayNotifications = !m_bShowTrayNotifications;
}
void CMainFrame::OnUpdateViewNotifications(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(m_bShowTrayNotifications);
}
void CMainFrame::OnAppOpen()
{
ShowWindow(SW_NORMAL);
SetForegroundWindow();
}
void CMainFrame::OnAppSuspend()
{
m_bShutdown = TRUE; // really exit
SendMessage(WM_CLOSE);
}
/
// CMainFrame diagnostics
#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
CFrameWnd::AssertValid();
}
void CMainFrame::Dump(CDumpContext& dc) const
{
CFrameWnd::Dump(dc);
}
#endif //_DEBUG
///
BOOL CMyApp::InitInstance()
{
//在应用程序初始化函数中将程序的主框架隐藏起来;
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
CMainFrame* pFrame = new CMainFrame;
m_pMainWnd = pFrame;
pFrame->LoadFrame(IDR_MAINFRAME,
WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL, NULL);
pFrame->ShowWindow(SW_HIDE);
pFrame->UpdateWindow();
return TRUE;
}