Shell_NotifyIcon托盘图标闪烁

之前的同事留下了一个程序会莫名闪退的bug,今天终于发现是托盘图标闪烁使得gdi资源耗尽导致的。


先定义

#include "shellapi.h" //托盘图标引用

NOTIFYICONDATA        m_NotifyIconData;

m_NotifyIconData.cbSize = sizeof(NOTIFYICONDATA);//长度
m_NotifyIconData.hWnd = m_hWnd;//窗口句柄
m_NotifyIconData.hIcon = GETRESPROVIDER->LoadIcon(_T("CROWD_ICON"),16);;//加载图标进去
m_NotifyIconData.uCallbackMessage = WM_NOTIFYICON;//这个是点击图标的事件消息,我们在消息处理函数WndProc()里面写一个case WM_NOTIFYICON:去处理鼠标点击图标事件
m_NotifyIconData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;//图标样式

_tcscpy(m_NotifyIconData.szTip, _T("程序名"));//当鼠标移动到图标的时候显示

Shell_NotifyIcon(NIM_ADD, &m_NotifyIconData);

//设置闪烁的定时器
SetTimer(TIMMER_SPANGLED_ICON,200);

在定时器里面实现闪烁

case TIMMER_SPANGLED_ICON:
    {
        if( m_NotifyIconData.hIcon)
        {
            DestroyIcon(m_NotifyIconData.hIcon) ;
            m_NotifyIconData.hIcon = NULL;
            Shell_NotifyIcon(NIM_MODIFY, &m_NotifyIconData);
        }
        else
        {
            DestroyIcon(m_NotifyIconData.hIcon) ;
            m_NotifyIconData.hIcon = GETRESPROVIDER->LoadIcon(_T("CROWD_ICON"),16);;//加载图标进去
            Shell_NotifyIcon(NIM_MODIFY, &m_NotifyIconData);
        }
    }
    break;

这里要注意DestroyIcon(m_NotifyIconData.hIcon) ;这一句,如果不用这一句,每次闪烁都会使得GDI资源的增加,最终耗尽GDI资源导致崩溃。GDI资源情况可在任务管理器—>详细信息  中看到。

image

最后删除

DestroyIcon(m_NotifyIconData.hIcon) ;
Shell_NotifyIcon(NIM_DELETE,&m_NotifyIconData);
原文地址:https://www.cnblogs.com/betterwgo/p/8269593.html