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

VC++ 應用程序多媒體啟動封面實現(MCIWnd 播放 AVI)

     編輯:VC 教學

方案概述

為 VC++ 應用程序添加啟動動畫封面(播放 AVI 視頻),最簡便方法是使用 Video for Windows (VfW) SDK 提供的 MCIWnd 窗口類。相比底層 AVIFile API,MCIWnd 封裝了打開、播放、關閉等完整流程,幾行代碼即可實現專業級啟動動畫效果。

核心 API 函數

函數用途
MCIWndRegisterClass註冊 MCIWnd 窗口類(進程僅需調用一次)
MCIWndCreate創建 MCIWnd 窗口,返回窗口句柄
MCIWndOpen打開媒體文件(AVI/MPEG/WAV 等)
MCIWndPlay開始播放
MCIWndGetLength獲取媒體總時長(毫秒)
MCIWndDestroy關閉媒體並銷毀窗口
MCIWndUseTime設置時間格式為毫秒

完整實現步驟

1. 項目配置:Stdafx.h 添加 VfW 支持


// Stdafx.h
#include 
#include 
#include               // Video for Windows 標頭
#pragma comment(lib, "vfw32.lib") // 自動鏈接庫

2. 修改 CWinApp::InitInstance 播放啟動動畫


BOOL CMyApp::InitInstance()
{
    // 1. 註冊 MCIWnd 窗口類
    if (!MCIWndRegisterClass())
    {
        AfxMessageBox(_T("無法註冊 MCIWnd 類,請確認 vfw32.dll 存在"));
        return FALSE;
    }

    // 2. 創建播放窗口(無播放控制欄、可見、彈出式)
    HWND hMCIWnd = MCIWndCreate(
        NULL,                           // 父窗口:無(桌面級)
        AfxGetInstanceHandle(),         // 實例句柄
        MCIWNDF_NOPLAYBAR | WS_VISIBLE | WS_POPUP, // 風格
        NULL                            // 初始不打開文件
    );

    if (!hMCIWnd)
    {
        AfxMessageBox(_T("創建 MCI 窗口失敗"));
        return FALSE;
    }

    // 3. 打開 AVI 文件
    CString strAviPath = _T("D:\\Media\\Splash.avi"); // 實際項目中應從資源/配置讀取
    if (strAviPath.GetLength() > 0)
    {
        if (MCIWndOpen(hMCIWnd, strAviPath, 0) != 0)
        {
            AfxMessageBox(_T("無法打開視頻文件:") + strAviPath);
            MCIWndDestroy(hMCIWnd);
        }
        else
        {
            // 4. 設置時間格式為毫秒
            MCIWndUseTime(hMCIWnd);

            // 5. 獲取播放時長
            long lPlayTime = MCIWndGetLength(hMCIWnd); // 毫秒

            // 6. 開始播放
            MCIWndPlay(hMCIWnd);

            // 7. 關鍵:主線程休眠等待播放完成
            // 注意:Sleep 會阻塞消息泵,MCIWnd 內部有獨立消息泵可處理 WM_PAINT 等
            // 若視頻較長(>5秒),建議改用模態對話框+定時器方案
            ::Sleep(lPlayTime);

            // 8. 銷毀播放窗口
            MCIWndDestroy(hMCIWnd);
        }
    }

    // 9. 繼續標準 MFC 初始化流程
#ifdef _AFXDLL
    Enable3dControls();
#else
    Enable3dControlsStatic();
#endif

    // ... 後續文檔模板創建、主框架創建等標準代碼
    return TRUE;
}

關鍵技術點深度解析

為什麼需要 Sleep 等待?

MCIWnd 播放是異步的。若不等待直接進入主框架創建,動畫窗口會被主窗口遮蓋,或主窗口初始化過程導致動畫卡頓。Sleep(lPlayTime) 讓主線程阻塞,但 MCIWnd 窗口擁有獨立消息泵,仍能正常繪制視頻幀。

風格標誌選擇指南

風格效果
MCIWNDF_NOPLAYBAR隱藏播放控制條(進度條、音量等),純全屏播放
MCIWNDF_NOMENU禁用右鍵菜單
WS_POPUP無邊框彈出窗口,適合全屏封面
WS_VISIBLE創建即顯示

多任務環境下的同步問題

Windows 多任務調度可能導致 Sleep 實際休眠時間超過預期。更穩健方案:


// 方案:使用等待定時器或事件,而非 Sleep
// MCIWnd 支持 MCI_NOTIFY 通知,但需設置回調窗口
// 簡單替代:循環檢查播放位置
long lLength = MCIWndGetLength(hMCIWnd);
long lPos = 0;
while (lPos < lLength)
{
    ::Sleep(100); // 短間隔輪詢
    lPos = MCIWndGetPosition(hMCIWnd);
    // 處理消息防止假死
    MSG msg;
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

現代替代方案對比

方案優點缺點適用場景
MCIWnd (VfW)代碼極簡、系統內置、無額外依賴僅支持舊格式(AVI/MPEG-1/WAVE)、無硬件加速、高 DPI 模糊維護老項目、簡單啟動動畫
DirectShow支持所有編解碼器、硬件加速、流媒體COM 復雜、代碼量大、需分發 quartz.dll專業播放器、複雜媒體處理
Media Foundation現代架構、高性能、硬件加速、DRMVista+、學習曲線陡峭Win7+ 新項目、高清視頻
WebView2 / HTML5 Video格式豐富、易於定製 UI、跨平台思維體積大(~100MB 運行時)、啟動慢現代 UI、需 Web 技術棧
GDI+ / Direct2D 逐幀繪製完全控制、無外部依賴需自行解碼、CPU 佔用高特殊效果、極小文件

資源嵌入最佳實踐

將 AVI 作為自定義資源嵌入 EXE,避免外部文件依賴:

  1. 資源視圖 → 右鍵 Add Resource → Import → 選擇 .avi → 類型輸入 AVI(自定義類型) → ID 如 IDR_AVI_SPLASH
  2. 運行時提取到臨時文件播放:

CString ExtractAviResource(UINT nResID)
{
    HRSRC hRes = FindResource(AfxGetInstanceHandle(), MAKEINTRESOURCE(nResID), _T("AVI"));
    if (!hRes) return _T("");
    
    HGLOBAL hGlob = LoadResource(AfxGetInstanceHandle(), hRes);
    DWORD dwSize = SizeofResource(AfxGetInstanceHandle(), hRes);
    LPVOID pData = LockResource(hGlob);
    
    CString strTemp = GetTempFileName(_T("avi"));
    CFile file(strTemp, CFile::modeCreate | CFile::modeWrite);
    file.Write(pData, dwSize);
    file.Close();
    
    return strTemp;
}

// InitInstance 中使用
CString strAvi = ExtractAviResource(IDR_AVI_SPLASH);
if (!strAvi.IsEmpty())
{
    MCIWndOpen(hMCIWnd, strAvi, 0);
    // ... 播放 ...
    DeleteFile(strAvi); // 播放後刪除臨時文件
}

常見問題排查

  • 無聲音/畫面異常:AVI 編碼格式不支持(如 H.264/HEVC),需轉碼為 MPEG-4 Part 2 (DivX/XviD)、MJPEG、未壓縮 RGB 等 VfW 支持格式
  • 全屏拉伸變形:MCIWndCreate 窗口尺寸默認 0,需 SetWindowPos 設置全屏尺寸,或使用 MCIWNDF_NOPLAYBAR 配合 MCIWndSetZoom
  • 高 DPI 模糊:VfW 無 DPI 感知,建議清單清單啟用 DPI 虛擬化或使用現代方案
  • 多顯示器位置錯誤:WS_POPUP 窗口默認主顯示器,需 SetWindowPos 移動到目標顯示器

總結

使用 VfW MCIWnd 實現啟動動畫封面是經典 VC++ 技術,代碼量極小、零外部依賴、部署簡單。雖然格式支持有限,但對於內部工具、老項目維護、簡單品牌展示動畫仍是極具性價比的選擇。現代新項目建議評估 Media Foundation 或 WebView2 等方案,獲得更好格式支持與高 DPI 適配。

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