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

VC++ 打造簡易 Flash 播放器:Shockwave Flash ActiveX 控件完整包裝

     編輯:VC 教學

核心控件

Shockwave Flash Object (ProgID: ShockwaveFlash.ShockwaveFlash,CLSID: {D27CDB6E-AE6D-11CF-96B8-444553540000}),方法/屬性對應 Flash Player JS API。

對話框資源佈局

  • 按鈕:開啟、播放、暫停、停止、重播、後退、前進、末幀、快退、快進、放大、縮小、還原、關閉、全螢幕;
  • ActiveX:IDC_FLASH → 變數 m_flash (類型 CShockwaveFlash);
  • Slider:IDC_SLIDER_PROGRESS → 變數 m_slider (範圍 0~100)。

關鍵成員變數

UINT m_nTimer = 0;
BOOL m_bTimerActive = FALSE;
BOOL m_bFullScreen = FALSE;
BOOL m_bFileOpen = FALSE;
CRect m_rcFlash;               // Flash 控件原始矩形
WINDOWPLACEMENT m_wpFlash;     // Flash 控件原始狀態
WINDOWPLACEMENT m_wpDlg;       // 對話框原始狀態

核心功能實作

1. 開啟檔案

void CPlayerDlg::OnBtnOpen() {
    CFileDialog dlg(TRUE, _T("swf"), _T("*.swf"), OFN_FILEMUSTEXIST|OFN_HIDEREADONLY,
        _T("Flash Files (*.swf)|*.swf||"), this);
    if (dlg.DoModal() != IDOK) return;

    m_flash.put_Movie(dlg.GetPathName());
    m_bFileOpen = TRUE;

    if (!m_bTimerActive) {
        m_nTimer = SetTimer(1, 100, NULL); // 100ms 更新進度條
        m_bTimerActive = TRUE;
    }
}

2. 播放控制 (直接映射控件方法)


// 播放
m_flash.Play();
// 暫停
m_flash.Stop();
// 停止 (倒帶+停止)
m_flash.Rewind(); m_flash.Stop();
// 重播
m_flash.Rewind(); m_flash.Play();
// 後退/前進 (逐幀)
m_flash.Back(); / m_flash.Forward();
// 末幀
m_flash.GotoFrame(m_flash.get_TotalFrames() - 1);
// 快退/快進 (跳 5 幀)
long cur = m_flash.CurrentFrame();
long tot = m_flash.get_TotalFrames();
if (cur > 4) m_flash.GotoFrame(cur - 5); else m_flash.put_FrameNum(0); // 快退
if (cur < tot - 5) m_flash.GotoFrame(cur + 5); else m_flash.put_FrameNum(tot - 1); // 快進
// 縮放
m_flash.Zoom(50);  // 放大 50%
m_flash.Zoom(200); // 縮小 200%
m_flash.Zoom(0);   // 還原 100%
// 關閉
m_flash.put_Movie(_T("about:blank")); // 卸載
KillTimer(m_nTimer); m_bTimerActive = FALSE; m_bFileOpen = FALSE;
m_slider.SetPos(0);

3. 進度條同步 (WM_TIMER)

void CPlayerDlg::OnTimer(UINT nIDEvent) {
    if (nIDEvent == m_nTimer && m_bFileOpen) {
        long cur = m_flash.CurrentFrame();
        long tot = m_flash.get_TotalFrames();
        if (tot > 0) m_slider.SetPos(cur * 100 / tot);
    }
    CDialog::OnTimer(nIDEvent);
}

4. Slider 拖曳定位 (NM_RELEASEDCAPTURE)

void CPlayerDlg::OnReleasedcaptureSlider(NMHDR* pNMHDR, LRESULT* pResult) {
    if (m_bFileOpen) {
        int pos = m_slider.GetPos(); // 0~100
        long frame = pos * m_flash.get_TotalFrames() / 100;
        m_flash.GotoFrame(frame);
    }
    *pResult = 0;
}

5. 全螢幕模擬 (簡易版)

void CPlayerDlg::OnBtnFullScreen() {
    if (m_bFullScreen || !m_bFileOpen) return;

    // 1. 記錄原始狀態
    GetWindowPlacement(&m_wpDlg);
    m_flash.GetWindowPlacement(&m_wpFlash);
    m_flash.GetWindowRect(&m_rcFlash); ScreenToClient(&m_rcFlash);

    // 2. 隱藏 Slider
    m_slider.ShowWindow(SW_HIDE);

    // 3. 移除標題列、最大化覆蓋全螢幕
    LONG style = GetWindowLong(m_hWnd, GWL_STYLE);
    SetWindowLong(m_hWnd, GWL_STYLE, style & ~WS_CAPTION);
    CClientDC dc(this);
    MoveWindow(0, 0, dc.GetDeviceCaps(HORZRES), dc.GetDeviceCaps(VERTRES));

    // 4. Flash 鋪滿客戶區
    m_flash.SetWindowPos(&CWnd::wndTop, 0, 0,
        dc.GetDeviceCaps(HORZRES), dc.GetDeviceCaps(VERTRES), SWP_SHOWWINDOW);

    m_bFullScreen = TRUE;
}

6. ESC 退出全螢幕 (PreTranslateMessage)

BOOL CPlayerDlg::PreTranslateMessage(MSG* pMsg) {
    if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE && m_bFullScreen) {
        // 還原視窗樣式
        LONG style = GetWindowLong(m_hWnd, GWL_STYLE);
        SetWindowLong(m_hWnd, GWL_STYLE, style | WS_CAPTION);
        ShowWindow(SW_HIDE); // 必須先隱藏再恢復 placement
        SetWindowPlacement(&m_wpDlg);
        m_flash.MoveWindow(m_rcFlash);
        m_flash.SetWindowPlacement(&m_wpFlash);
        m_slider.ShowWindow(SW_SHOW);
        m_bFullScreen = FALSE;
        return TRUE;
    }
    return CDialog::PreTranslateMessage(pMsg);
}

清理資源

BOOL CPlayerDlg::DestroyWindow() {
    if (m_bTimerActive) KillTimer(m_nTimer);
    return CDialog::DestroyWindow();
}

已知限制與改進方向

  • 全螢幕為**視窗樣式切換模擬**,非真正 Direct3D 獨佔模式,多顯示器/任務列處理不完美;
  • 建議改用 FlashExternalInterface 雙向呼叫 JS/AS3 實現真全螢幕;
  • Flash 已停止更新 (2020 EOL),新專案建議遷移至 **HTML5 Video / WebGL / Ruffle (WASM 模擬器)**。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved