首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

VC++ 在應用程式中嵌入微型動畫:CImageList 實現 GIF-like 動畫於客戶區/工具列/狀態列/標題列

     編輯:關於VC++

利用 MFC CImageList 管理等尺寸圖像序列,配合 SetTimer 週期性呼叫 Draw,可在視窗客戶區、工具列、狀態列、甚至標題列圖示播放類 GIF 動畫。本文提供四種位置的完整實作碼與資源製作指南。

一、核心原理與資源準備

  1. 資源編輯器建立多個圖示 (Icon) 資源:IDI_ICON1、IDI_ICON2...,大小統一 (如 64×32),色彩深度 256 色或真彩色。
  2. 宣告 CImageList m_ImageList、int m_nFrame、int m_nTotalFrames、POINT m_ptDraw。
  3. OnCreate 中建立 ImageList 並載入所有圖示:

void CMyView::CreateImageList() {
  m_ImageList.Create(64, 32, ILC_COLOR24 | ILC_MASK, 5, 2);
  for (int i = 1; i <= 5; i++) {
    HICON hIcon = ::LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ICON1 + i - 1));
    m_ImageList.Add(hIcon);
    ::DestroyIcon(hIcon); // Add 會複製,原控制代碼可釋放
  }
  m_nTotalFrames = 5;
  m_nFrame = 0;
}

二、四大播放位置實作

1. 視圖客戶區


void CMyView::OnTimer(UINT nIDEvent) {
  CDC* pDC = GetDC();
  if (m_nFrame >= m_nTotalFrames) m_nFrame = 0;
  m_ImageList.Draw(pDC, m_nFrame, m_ptDraw, ILD_TRANSPARENT);
  m_nFrame++;
  ReleaseDC(pDC);
  CView::OnTimer(nIDEvent);
}

2. 狀態列 (CStatusBar)


void CMainFrame::OnTimer(UINT nIDEvent) {
  if (m_nFrame >= m_nTotalFrames) m_nFrame = 0;
  CDC* pDC = m_wndStatusBar.GetDC();
  POINT pt = {1, 1}; // 左上角
  m_ImageList.Draw(pDC, m_nFrame, pt, ILD_TRANSPARENT);
  ReleaseDC(pDC);
  m_nFrame++;
  CFrameWnd::OnTimer(nIDEvent);
}

3. 工具列 (CToolBar) - 右側對齊


void CMainFrame::OnTimer(UINT nIDEvent) {
  if (m_nFrame >= m_nTotalFrames) m_nFrame = 0;
  CRect rect;
  m_wndToolBar.GetClientRect(&rect);
  CDC* pDC = m_wndToolBar.GetDC();
  POINT pt = {rect.right - 64, 1}; // 圖示寬 64
  m_ImageList.Draw(pDC, m_nFrame, pt, ILD_TRANSPARENT);
  ReleaseDC(pDC);
  m_nFrame++;
  CFrameWnd::OnTimer(nIDEvent);
}
注意:工具列邊框可能導致實際可見區域偏移。若需貼齊主視窗右側,改用 GetDC() (主視窗 DC) 並計算 pt.x = rect.right - 64、pt.y = rect.top + 3。

4. 標題列圖示動畫 (SetIcon)


void CMainFrame::OnTimer(UINT nIDEvent) {
  if (m_nFrame >= m_nTotalFrames) m_nFrame = 0;
  HICON hIcon = m_ImageList.ExtractIcon(m_nFrame);
  SetIcon(hIcon, FALSE); // FALSE = 小圖示 (標題列)
  ::DestroyIcon(hIcon); // ExtractIcon 回傳新控制代碼需自行釋放
  m_nFrame++;
  CFrameWnd::OnTimer(nIDEvent);
}

同理可用 SetClassLong(GCL_HICONSM) 修改類別圖示 (影響所有同類視窗)。

三、資源清理


void CMyView::OnDestroy() {
  KillTimer(1);
  m_ImageList.DeleteImageList();
  CView::OnDestroy();
}

四、進階技巧與替代方案

  • 真彩色/Alpha 通道:使用 ILC_COLOR32 載入 32-bit 圖示 (含 Alpha),Draw 參數加 ILD_IMAGE。
  • 動畫控制項:CAnimateCtrl 直接播放 AVI (無壓縮/RLE),適用於較長動畫。
  • GIF 解碼:整合 GDI+ (Image/Bitmap) 或 CxImage 庫支援原生 GIF 播放。
  • 高 DPI 適配:依 GetDpiForWindow 載入對應尺寸圖示集 (100%/125%/150%)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved