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

VC++ 簡易實現啟動畫面淡入淡出:AnimateWindow API 一鍵搞定

     編輯:VC 教學

核心發現:AnimateWindow API

Windows 2000+ 內建 AnimateWindow (需 #define WINVER 0x0500) 直接支援視窗動畫:淡入、淡出、滑動、展開、旋轉等,無需手寫計時器/透明度迴圈。

必要設定

// stdafx.h 或對話方塊 cpp 最頂端,必須在 #include  之前
#undef WINVER
#define WINVER 0x0500  // 啟用 Windows 2000+ API

#include 

啟動畫面類完整實作 (CSplashWnd)

class CSplashWnd : public CDialog {
public:
    CSplashWnd() : CDialog(IDD_SPLASH) {} // 資源編輯器建立無邊框對話方塊 IDD_SPLASH

protected:
    virtual BOOL OnInitDialog() override {
        CDialog::OnInitDialog();
        CenterWindow(); // 置中顯示
        
        // 淡入動畫:500ms
        AnimateWindow(GetSafeHwnd(), 500, AW_BLEND | AW_ACTIVATE);
        
        // 3 秒後自動關閉
        SetTimer(1, 3000, NULL);
        return TRUE;
    }

    afx_msg void OnTimer(UINT_PTR nIDEvent) {
        if (nIDEvent == 1) {
            KillTimer(1);
            // 淡出動畫:500ms
            AnimateWindow(GetSafeHwnd(), 500, AW_BLEND | AW_HIDE);
            PostMessage(WM_CLOSE);
        }
    }

    afx_msg BOOL OnEraseBkgnd(CDC* pDC) {
        // 繪製背景圖片 (資源 IDB_SPLASH)
        CBitmap bmp; bmp.LoadBitmap(IDB_SPLASH);
        CDC memDC; memDC.CreateCompatibleDC(pDC);
        CBitmap* pOld = memDC.SelectObject(&bmp);
        BITMAP bm; bmp.GetBitmap(&bm);
        pDC->BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &memDC, 0, 0, SRCCOPY);
        memDC.SelectObject(pOld);
        return TRUE; // 已處理背景,避免閃爍
    }

    DECLARE_MESSAGE_MAP()
};

BEGIN_MESSAGE_MAP(CSplashWnd, CDialog)
    ON_WM_TIMER()
    ON_WM_ERASEBKGND()
END_MESSAGE_MAP()

應用程式啟動流程整合

// MyApp.cpp
BOOL CMyApp::InitInstance() {
    // ... 早期初始化 ...
    
    // 顯示啟動畫面
    CSplashWnd splash;
    splash.DoModal(); // 模態顯示,阻塞直到關閉
    
    // ... 主視窗建立 ...
    return TRUE;
}

AnimateWindow 旗標完整對照

進階:非模態啟動畫面 (不阻塞主線程初始化)

// MyApp.cpp
CSplashWnd* g_pSplash = nullptr;

BOOL CMyApp::InitInstance() {
    // 1. 建立非模態啟動畫面
    g_pSplash = new CSplashWnd;
    g_pSplash->Create(IDD_SPLASH, NULL);
    g_pSplash->ShowWindow(SW_SHOW);
    g_pSplash->UpdateWindow();
    
    // 2. 執行耗時初始化 (資料庫連線、載入插件、讀取設定...)
    DoLengthyInitialization(); // 期間啟動畫面可響應重繪
    
    // 3. 初始化完成,關閉啟動畫面
    if (g_pSplash) {
        g_pSplash->PostMessage(WM_CLOSE); // 觸發淡出
        // 可選:等待淡出完成
        // MSG msg; while (::IsWindow(g_pSplash->GetSafeHwnd()) && GetMessage(&msg, NULL, 0, 0)) DispatchMessage(&msg);
        g_pSplash = nullptr;
    }
    
    // 4. 建立主視窗...
    return TRUE;
}

// CSplashWnd 新增 OnClose 處理
void CSplashWnd::OnClose() {
    AnimateWindow(GetSafeHwnd(), 500, AW_BLEND | AW_HIDE);
    // 動畫為同步阻塞,完成後自動銷毀視窗
    DestroyWindow();
}

void CSplashWnd::PostNcDestroy() {
    delete this; // 非模態需自我刪除
}

注意事項

  • WINVER 0x0500 必須在 #include 之前定義,否則編譯器找不到 AnimateWindow
  • 動畫期間視窗訊息迴圈被阻塞,模態 DoModal 內部有迴圈無問題;非模態需確保主線程有訊息泵
  • 遠端桌面 (RDP) 環境下淡入淡出可能失效/閃爍,建議偵測 GetSystemMetrics(SM_REMOTESESSION) 時退回無動畫模式
  • 視窗需有 WS_EX_LAYERED 或系統自動處理,AnimateWindow 內部會暫時設定分層屬性

對比傳統做法

旗標效果常用組合
AW_BLEND淡入/淡出 (Alpha 混合)顯示: AW_BLEND | AW_ACTIVATE
隱藏: AW_BLEND | AW_HIDE
AW_SLIDE滑入/滑出需搭配 AW_HOR_POSITIVE/AW_HOR_NEGATIVE/AW_VER_POSITIVE/AW_VER_NEGATIVE
AW_CENTER從中心展開/向中心收縮AW_CENTER | AW_ACTIVATE / AW_HIDE
AW_HIDE隱藏動畫 (配合其他旗標)必須與 AW_BLEND/AW_SLIDE/AW_CENTER 組合
AW_ACTIVATE顯示動畫 (預設)可省略
做法代碼量效能視覺品質相容性
AnimateWindow極少 (5 行)系統級優化平滑、無閃爍Win2000+
SetLayeredWindowAttributes + Timer~50 行手動迴圈消耗 CPU易閃爍、需處理重繪Win2000+
GDI+ 漸變繪製~100 行CPU 繪圖開銷大可控制最高需 GDI+ 部署

一行 AnimateWindow,讓您的啟動畫面瞬間擁有專業級淡入淡出體驗,拒絕繁瑣手工動畫代碼!

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved