sndPlaySound 需將整個 WAV 載入實體記憶體,檔案超過可用記憶體即失效,約略限制 100KB。
封裝 CWave 類別,管理波形音訊裝置與元素:
class CWave : public CObject {
public:
CWave(); virtual ~CWave();
DWORD OpenDevice(); // 開啟波形裝置
DWORD CloseDevice(); // 關閉裝置
DWORD Play(CWnd* pWnd, LPCSTR pszFile); // 異步播放,完成送 MM_MCINOTIFY 到 pWnd
DWORD Stop(); // 關閉目前元素
protected:
MCIDEVICEID m_nDeviceID, m_nElementID;
void DisplayErrorMsg(DWORD err);
};
mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID|MCI_WAIT, &parms),parms.lpstrDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO,取得裝置 ID。MCI_OPEN_PARMS 設定 lpstrElementName = pszFile,mciSendCommand(m_nDeviceID, MCI_OPEN, MCI_OPEN_ELEMENT, ...) 開啟檔案元素,取得元素 ID。MCI_PLAY_PARMS 設定 dwCallback = pWnd->m_hWnd,mciSendCommand(m_nElementID, MCI_PLAY, MCI_NOTIFY, ...) 開始異步播放。mciSendCommand(m_nElementID, MCI_CLOSE, 0, 0) 關閉元素。Stop() + CloseDevice() 確保資源釋放。void CWave::DisplayErrorMsg(DWORD err) {
if (err) {
char msg[256];
mciGetErrorString(err, msg, 256) ? AfxMessageBox(msg) : AfxMessageBox("Unknown Error");
}
}
CWave wave;
wave.OpenDevice();
wave.Play(this, "C:\\Music\\BigSong.wav"); // 異步播放,視窗收到 MM_MCINOTIFY 表示結束
// ... 使用者按停止 ...
wave.Stop();
此法不受檔案大小限制,適合長音訊、有聲書、背景音樂等場景。