• 系统托盘图标


    系统托盘图标

    系统托盘图标的创建主要使用 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

  • 相关阅读:
    hibernate联合主键 注解方式
    使用Json出现java.lang.NoClassDefFoundError解决方法
    Spring 定时任务2
    Spring 定时任务1
    Javasocket1
    volatile
    Java中byte与16进制字符串的互相转换
    Spring 源码学习
    web服务器工作原理
    SpringMVC国际化
  • 原文地址:https://www.cnblogs.com/zuibunan/p/3895497.html
Copyright © 2020-2023  润新知