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

打造自動循環播放的 MP3 播放器(下):核心播放邏輯與介面控制實作

     編輯:VC 教學

前言

承接上一篇文章,我們已經完成了 MP3 播放器的基本架構與音樂清單管理。本篇將深入探討播放器的核心邏輯:對話框初始化、系統托盤整合、播放進度條拖曳控制,以及自動循環播放的定時器機制。完整掌握這些技術,即可打造一款隱藏於托盤、無需人工干預即可定時循環播放的企業級音樂播放器。

一、對話框初始化與系統托盤整合

OnInitDialog() 是對話框啟動的關鍵入口。在此階段,我們不僅要完成基本的圖示設定,還需建立定時器、隱藏工作列按鈕、將程式最小化至系統托盤。以下是關鍵步驟解析:

1. 視覺風格與圖示設定

BOOL CMp3PlayerDlg::OnInitDialog()
{
    // 設定視窗標題
    m_DlgStyle.sTitleName = _T("音樂播放器");
    COwnerDrawDialog::OnInitDialog();

    // 設定大小圖示
    SetIcon(m_hIcon, TRUE);   // 大圖示
    SetIcon(m_hIcon, FALSE);  // 小圖示
    ...
}

2. 定時器機制啟動

啟動兩個定時器分別服務於不同用途:

  • 定時器 4 (100ms 間隔):用於高頻率更新播放進度條、音量控制等即時介面回饋。
  • 定時器 1 (1000ms 間隔):僅在 m_bAutoRun 為真時啟動,負責檢查排程時間、觸發自動播放/停止邏輯。
SetTimer(4, 100, NULL); // 介面更新定時器
if (m_bAutoRun)
    SetTimer(1, 1000, NULL); // 自動排程定時器

3. 隱藏工作列、駐留系統托盤

透過修改擴充視窗風格 WS_EX_TOOLWINDOW 可隱藏工作列按鈕;接著使用 Shell_NotifyIcon API 在系統托盤區建立圖示,並指定自訂訊息 WM_DLG_SHOW 作為回呼,以處理滑鼠互動。

// 修改視窗風格:隱藏工作列按鈕
long wl = GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);
SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, WS_EX_TOOLWINDOW);

// 建立托盤圖示資料結構
NOTIFYICONDATA tnd = {0};
tnd.cbSize = sizeof(NOTIFYICONDATA);
tnd.hWnd = m_hWnd;
tnd.uID = IDI_MAINFRAME;
tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
tnd.uCallbackMessage = WM_DLG_SHOW; // 自訂回呼訊息
tnd.hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_MAINFRAME));
_strcpy(tnd.szTip, _T("音樂播放器"));

// 加入托盤
Shell_NotifyIcon(NIM_ADD, &tnd);

二、播放進度條拖曳控制 (OnHScroll)

使用者拖曳進度條時,需即時更新播放位置。OnHScroll 處理 CScrollBar 事件,重點在於 SB_THUMBTRACK(拖曳中)與 SB_THUMBPOSITION / SB_ENDSCROLL(拖曳結束)的區別處理。

void CMp3PlayerDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
    if (pScrollBar == &m_MPBar) // 確認是播放進度條
    {
        switch (nSBCode)
        {
        case SB_THUMBTRACK: // 正在拖曳
            m_nPos = nPos;  // 暫存目標位置,不立即跳轉播放
            break;
        case SB_THUMBPOSITION:
        case SB_ENDSCROLL:  // 拖曳結束
            // 真正設定播放位置 (毫秒)
            m_Music.SetPosition(m_nPos * 1000);
            break;
        }
    }
    CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}

關鍵點:

  • 拖曳過程中 (SB_THUMBTRACK) 僅更新介面顯示位置,避免頻繁呼叫 SetPosition 造成卡頓。
  • 拖曳釋放後,一次性設定播放位置,確保音訊同步。
  • 進度條範圍 (SetScrollRange) 在 Play() 函式中依音樂總長度動態設定。

三、自動循環播放核心邏輯

定時器 1 每秒觸發一次,檢查目前時間是否落於任一排程時段(如上班、午休、下班)。若符合且播放清單非空,則呼叫 PlayNext() 循環播放;時段結束時自動停止。完整排程判斷邏輯可參考專案原始碼中的 OnTimer(UINT nIDEvent) 實作。

四、總結與延伸

本篇完整呈現了 MP3 播放器從初始化、托盤駐留、進度條互動到自動排程的關鍵技術。結合上一篇的音樂清單管理與多檔案過濾,已構成一個功能完整的企業級自動播放系統。後續可擴充:

  • 支援多種音訊格式解碼 (FFmpeg 整合)
  • 網路串流播放能力
  • 圖形化排程編輯介面
  • 多語系支援與設定匯入/匯出

完整原始碼與專案檔可至原文連結下載。若有任何技術疑問,歡迎留言交流。

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