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

CButtonST 擴展實戰:為按鈕添加滑鼠經過播放聲音功能 (PlaySound + WAVE 資源)

     編輯:VC 教學

CButtonST 功能極強,但缺少「滑鼠經過播放聲音」這一增強交互體驗的小功能。本文展示如何通過修改源碼 (BtnST.h/.cpp) 為其添加聲音支援:**簡單 Beep 音或播放自訂 WAVE 資源**,並透過 SetPlaySound(BOOL, LPCTSTR) 統一介面控制。

修改步驟 (四步完成)

1. BtnST.h 引入多媒體庫與宣告新介面

#include 
#pragma comment(lib, "Winmm.lib")

class CButtonST : public CButton
{
private:
    CString m_strSoundID; // WAVE 資源 ID
    BOOL m_bPlaySound = FALSE; // 是否啟用聲音

public:
    void PlaySound(); // 內部播放邏輯
    void SetPlaySound(BOOL bPlaySound, LPCTSTR pszSoundID = NULL); // 公開設定介面
    // ... 原有成員 ...
};

2. 建構函數初始化

CButtonST::CButtonST() 
{
    m_bPlaySound = FALSE; 
    m_strSoundID = _T("");
    // ... 原有初始化 ...
}

3. 實現 PlaySound 與 SetPlaySound

void CButtonST::PlaySound()
{
    if (!m_bPlaySound) return;

    if (m_strSoundID.IsEmpty()) 
    {
        ::MessageBeep(-1); // 系統預設 Beep
        return;
    }

    // 播放專案內嵌 WAVE 資源
    HINSTANCE hInst = AfxGetInstanceHandle();
    HRSRC hRes = FindResource(hInst, m_strSoundID, _T("WAVE"));
    if (!hRes) return;
    HGLOBAL hGlob = LoadResource(hInst, hRes);
    if (!hGlob) return;
    LPSTR lpData = (LPSTR)LockResource(hGlob);
    if (!lpData) return;

    // SND_ASYNC 非同步播放,不阻塞 UI 執行緒
    ::sndPlaySound(lpData, SND_MEMORY | SND_ASYNC); 
    FreeResource(hGlob);
}

void CButtonST::SetPlaySound(BOOL bPlaySound, LPCTSTR pszSoundID)
{
    m_bPlaySound = bPlaySound;
    m_strSoundID = pszSoundID ? pszSoundID : _T("");
}

4. 核心整合:在 OnMouseMove 滑鼠進入判斷中觸發播放

// CButtonST::OnMouseMove 內部,滑鼠確認進入按鈕區域後
if (!m_bMouseOnButton) 
{
    m_bMouseOnButton = TRUE;
    Invalidate(); // 觸發重繪 (熱態)
    
    // 註冊離開追蹤
    m_csTME.cbSize = sizeof(m_csTME);
    m_csTME.dwFlags = TME_LEAVE;
    m_csTME.hwndTrack = m_hWnd;
    ::_TrackMouseEvent(&m_csTME);

    // ==== 新增:播放聲音 ====
    PlaySound(); 
}
// ... 原有邏輯 ...

使用方式 (於對話框 OnInitDialog)

模式代碼效果
系統 Beep 音m_btn.SetPlaySound(TRUE);滑鼠經過發出系統預設 "Ding" 音
自訂 WAVE 資源m_btn.SetPlaySound(TRUE, _T("IDR_WAVE1"));播放專案資源 ID 為 IDR_WAVE1 的 .wav 檔

資源準備

  1. ResourceView → 右鍵 Import → 選取 .wav 檔。
  2. 屬性中設定 Resource ID 為 IDR_WAVE1 (類型自動識別為 WAVE)。
  3. 確認 resource.h 定義 #define IDR_WAVE1 1000 (或類似)。

重要限制

  • **僅在 SetFlat(TRUE) (扁平模式) 下生效**,因聲音觸發邏輯綁定在扁平模式的滑鼠進入偵測中。
  • 非同步播放 (SND_ASYNC) 避免 UI 卡頓,但快速移動滑鼠可能疊加多聲音,實際專案可加入防抖邏輯 (如 m_bSoundPlaying 標記)。
  • 修改第三方庫源碼意味著升級維護成本,建議將擴展封裝為繼承類 CButtonSTEx : public CButtonST 而非直接修改原檔 (本文為演示原理直接修改)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved