準備一組連續幀位圖(16×16),利用 CImageList 管理,定時器觸發幀切換,調用 WM_SETICON 更新視窗圖標,形成動畫效果。
class CAnimateIcon {
protected:
CImageList m_imgList; // 圖像列表
int m_iImageCounter; // 當前幀索引
int m_iMaxNumOfImages; // 總幀數
HICON hIcon, hPrevIcon; // 圖標句柄
public:
CAnimateIcon();
~CAnimateIcon();
bool SetImageList(int IDOfImageListResource, int numberOfImages, COLORREF transparentColor);
bool ShowNextImage();
};
CAnimateIcon::CAnimateIcon() : m_iImageCounter(-1), m_iMaxNumOfImages(-100) {
m_imgList.m_hImageList = NULL;
}
CAnimateIcon::~CAnimateIcon() { if (hPrevIcon) DestroyIcon(hPrevIcon); }
bool CAnimateIcon::SetImageList(int IDOfImageListResource, int numberOfImages, COLORREF transparentColor) {
if (numberOfImages <= 0) return false;
m_iMaxNumOfImages = numberOfImages;
return m_imgList.Create(IDOfImageListResource, 16, 1, transparentColor);
}
bool CAnimateIcon::ShowNextImage() {
if (!m_imgList.m_hImageList) return false;
m_iImageCounter = (m_iImageCounter + 1) % m_iMaxNumOfImages;
hIcon = m_imgList.ExtractIcon(m_iImageCounter);
hPrevIcon = (HICON)AfxGetMainWnd()->SendMessage(WM_SETICON, TRUE, (LPARAM)hIcon);
if (hPrevIcon) DestroyIcon(hPrevIcon);
return true;
}
IDB_BITMAP_ANIMAnimateIcon.h/.cppCAnimateIcon m_animIcon; UINT m_timerID;OnInitDialog 初始化:m_animIcon.SetImageList(IDB_BITMAP_ANIM, 6, RGB(0,0,0)); // 6 幀,黑色透明
m_timerID = SetTimer(99, 500, NULL); // 500ms 間隔
WM_TIMER 處理:void CAnimateDlgIconDlg::OnTimer(UINT nIDEvent) {
m_animIcon.ShowNextImage();
CDialog::OnTimer(nIDEvent);
}
WM_DESTROY 清理:void CAnimateDlgIconDlg::OnDestroy() {
if (m_timerID) KillTimer(m_timerID);
CDialog::OnDestroy();
}
SetTimer 間隔(建議 100~500ms)DestroyIcon 避免 GDI 洩漏WM_SETICON 參數 TRUE/FALSE)Pause()/Resume() 控制定時器狀態Shell_NotifyIcon)通過 CImageList + 定時器 + WM_SETICON 三步走策略,輕鬆實現標題欄動畫圖標。封裝類 CAnimateIcon 復用性強,代碼量極小,是 MFC 應用提升專業度的低成本高回報技巧。