首页 > 代码库 > 系统托盘图标

系统托盘图标

系统托盘图标

系统托盘图标的创建主要使用 Shell_NotifyIcon 函数来实现,实现过程比较简单。

注意:
要创建系统托盘图标,必须要有窗口;要创建窗口,必须要有窗口过程函数。
一个窗口可以有多个系统托盘图标;图标彼此间用 hWnd 和 uID 区分;
窗口过程函数接收到事件后, wParam 表示 uID,lParam 表示 message;


以下是封装的托盘类代码:

// notifyicon.h

#ifndef _NOTIFYICON_H_#define _NOTIFYICON_H_#include <windows.h>#include <shellapi.h>#include <map>typedef VOID (*NotifyIconCallback) (UINT uID, UINT message);class NotifyIcon{public:    static UINT AddIcon(HICON hIcon, WCHAR* szTip);    static VOID DelIcon(UINT uID);    static VOID ModIcon(UINT uID, HICON hIcon, WCHAR* szTip);    static UINT Attach(NotifyIconCallback pCallback);    static VOID Detach(UINT uCookie);private:    static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);private:    static HWND m_hWnd;    static UINT m_uCookieCount;    static std::map<UINT,NotifyIconCallback> m_mapCallback;    static UINT m_uIDCount;    static std::map<UINT,NOTIFYICONDATA> m_mapNotifyData;};#endif

 

 

// notifyicon.cpp

#include "notifyicon.h"HWND NotifyIcon::m_hWnd = NULL;UINT NotifyIcon::m_uCookieCount = 0;std::map<UINT,NotifyIconCallback> NotifyIcon::m_mapCallback;UINT NotifyIcon::m_uIDCount = 0;std::map<UINT,NOTIFYICONDATA> NotifyIcon::m_mapNotifyData;UINT NotifyIcon::AddIcon( HICON hIcon, WCHAR* szTip ){    // 创建窗口    LPCTSTR pszClassName = TEXT("NotifyIcon_ClassName");    LPCTSTR pszWndName = TEXT("NotifyIcon_WndName");    HINSTANCE hInstance = GetModuleHandle(NULL);    WNDCLASS wndClass;    if (GetClassInfo(hInstance, pszClassName, &wndClass) == 0)    {        wndClass.style = CS_HREDRAW | CS_VREDRAW;        wndClass.lpfnWndProc = NotifyIcon::WndProc;        wndClass.cbClsExtra = 0;        wndClass.cbWndExtra = 0;        wndClass.hInstance = hInstance;        wndClass.hIcon = NULL;        wndClass.hCursor = NULL;        wndClass.hbrBackground = NULL;        wndClass.lpszClassName = pszClassName;        wndClass.lpszMenuName = NULL;        if (RegisterClass(&wndClass) == NULL)        {            return NULL;        }    }    if (FindWindow(pszClassName, pszWndName) == NULL)    {        m_hWnd = CreateWindowEx(WS_EX_TOOLWINDOW,            pszClassName, pszWndName,             WS_POPUP,            CW_USEDEFAULT,            CW_USEDEFAULT,            CW_USEDEFAULT,            CW_USEDEFAULT,            NULL, NULL, hInstance, NULL);        if (m_hWnd == NULL)        {            return NULL;        }    }    UINT uID = m_uIDCount;    m_uIDCount++;        NOTIFYICONDATA nd;    nd.cbSize = sizeof(nd);    nd.hWnd = m_hWnd;    nd.uID = uID;    nd.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;    nd.uCallbackMessage = WM_USER;    nd.hIcon = hIcon;    if (szTip != NULL && lstrlen(szTip) < 127)    {        lstrcpy(nd.szTip, szTip);    }    if(Shell_NotifyIcon(NIM_ADD, &nd) == TRUE)    {        m_mapNotifyData.insert(std::make_pair(uID, nd));        return uID;    }    return NULL;}VOID NotifyIcon::DelIcon( UINT uID ){    if (m_hWnd == NULL)    {        return;    }    std::map<UINT, NOTIFYICONDATA>::iterator iter = m_mapNotifyData.find(uID);    if (iter != m_mapNotifyData.end())    {        Shell_NotifyIcon(NIM_DELETE, &(iter->second));        m_mapNotifyData.erase(iter);    }}VOID NotifyIcon::ModIcon( UINT uID, HICON hIcon, WCHAR* szTip ){    if (m_hWnd == NULL)    {        return;    }    std::map<UINT, NOTIFYICONDATA>::iterator iter = m_mapNotifyData.find(uID);    if (iter != m_mapNotifyData.end())    {        if (hIcon != NULL)        {            iter->second.hIcon = hIcon;        }        if (szTip && lstrlen(szTip) < 127)        {            lstrcpy(iter->second.szTip, szTip);        }        else        {            lstrcpy(iter->second.szTip, L"");        }        Shell_NotifyIcon(NIM_MODIFY, &(iter->second));    }}UINT NotifyIcon::Attach( NotifyIconCallback pCallback ){    if (pCallback == NULL)    {        return NULL;    }    UINT uCookie = m_uCookieCount;    m_uCookieCount ++;    m_mapCallback.insert(std::make_pair(uCookie, pCallback));    return uCookie;}VOID NotifyIcon::Detach( UINT uCookie ){    std::map<UINT, NotifyIconCallback>::iterator iter = m_mapCallback.find(uCookie);    if (iter != m_mapCallback.end())    {        m_mapCallback.erase(iter);    }}LRESULT CALLBACK NotifyIcon::WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ){    switch(message)    {    case WM_CREATE:        break;    case WM_DESTROY:        break;    case WM_USER:        for (std::map<UINT, NotifyIconCallback>::iterator iter = m_mapCallback.begin(); iter != m_mapCallback.end(); ++iter)        {            NotifyIconCallback pCallback = iter->second;            pCallback(wParam, lParam);        // wParam --> uID, lParam --> message        }        break;    default:        break;    }    return DefWindowProc(hwnd, message, wParam, lParam);}

 

 

// main.cpp 测试

#include <windows.h>#include "notifyicon.h"void callbackFunc(UINT uID, UINT message);int main(){    HINSTANCE hInstance = GetModuleHandle(NULL);    HICON hIcon = LoadIcon(hInstance, IDI_APPLICATION);    WCHAR szTip[128] = L"哈哈哈";    UINT uID1 = NotifyIcon::AddIcon(hIcon, szTip);    UINT uID2 = NotifyIcon::AddIcon(hIcon, szTip);    UINT uID3 = NotifyIcon::AddIcon(hIcon, szTip);    NotifyIcon::ModIcon(uID3, hIcon, NULL);    NotifyIcon::DelIcon(uID2);    UINT uCookie = NotifyIcon::Attach(callbackFunc);    NotifyIcon::Detach(uCookie);    MSG msg;    while (GetMessage(&msg, NULL, 0, 0))     {        TranslateMessage(&msg);        DispatchMessage(&msg);    }    return 0;}void callbackFunc(UINT uID, UINT message){    if (message == WM_LBUTTONDOWN || message == WM_LBUTTONUP || message == WM_LBUTTONDBLCLK ||        message == WM_RBUTTONDOWN || message == WM_RBUTTONUP || message == WM_RBUTTONDBLCLK)    {        WCHAR szDbg[256];        ZeroMemory(szDbg,256);        wsprintf(szDbg, L"[Dongyu] uID = %d, message = %x", uID, message);        OutputDebugString(szDbg);    }}

 

 

参考文章:

http://www.nowamagic.net/librarys/veda/detail/227