從獨立程式到 ActiveX 控件
上一篇實作了獨立的錄音機程式,本文進一步將其封裝為 MFC ActiveX 控件,使其能嵌入 Internet Explorer、Macromedia Director、Authorware 等支援 ActiveX 的容器中。控件提供錄音、播放、停止、暫停等基本功能,並透過屬性頁面設定錄音格式、取樣率等參數。
控件架構與核心類別
- CAudioCtrl:繼承
COleControl,為控件主類別,處理視窗建立、繪製、訊息對應與屬性/方法/事件定義。
- CWaveIn/CWaveOut:封裝
waveInOpen/waveOutOpen 等 MCI 或底層 Waveform Audio API,負責實際錄製與播放資料流。
- 屬性頁:提供標準屬性頁,讓使用者在設計階段設定音訊格式(PCM/ADPCM)、聲道、取樣率、位元深度等。
關鍵實作細節
1. 控件視窗建立與繪製
BOOL CAudioCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) {
if (COleControl::OnCreate(lpCreateStruct) == -1) return FALSE;
// 建立子視窗:錄音/播放按鈕、音量滑桿、波形顯示區等
m_btnRecord.Create(...);
m_btnPlay.Create(...);
// ...
return TRUE;
}
void CAudioCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) {
// 繪製控件背景、波形圖、狀態指示等
pdc->FillSolidRect(rcBounds, GetBackColor());
// 若有波形資料,繪製波形圖
if (m_pWaveData) DrawWaveform(pdc, rcBounds);
}
2. 錄音與播放核心邏輯(簡化版)
// 開始錄音
void CAudioCtrl::StartRecord() {
WAVEFORMATEX wfx = {0};
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = m_nChannels; // 屬性:聲道數
wfx.nSamplesPerSec = m_nSampleRate; // 屬性:取樣率
wfx.wBitsPerSample = m_nBitsPerSample; // 屬性:位元深度
wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8;
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
waveInOpen(&m_hWaveIn, WAVE_MAPPER, &wfx,
(DWORD_PTR)WaveInProc, (DWORD_PTR)this, CALLBACK_FUNCTION);
// 準備緩衝區、啟動錄音...
waveInStart(m_hWaveIn);
}
// 錄音回呼
void CALLBACK CAudioCtrl::WaveInProc(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance,
DWORD_PTR dwParam1, DWORD_PTR dwParam2) {
CAudioCtrl* pThis = (CAudioCtrl*)dwInstance;
if (uMsg == WIM_DATA) {
// 將緩衝區資料寫入檔案或記憶體
pThis->OnWaveDataReceived((WAVEHDR*)dwParam1);
}
}
3. 對外公開的方法與事件
| 方法 | 說明 |
StartRecord() | 開始錄音 |
StopRecord() | 停止錄音並儲存檔案 |
Play() | 播放目前載入的音訊檔 |
Pause() | 暫停播放/錄音 |
SetFileName(LPCTSTR) | 設定錄音輸出/播放輸入檔案路徑 |
| 事件 | 說明 |
RecordingStarted() | 錄音開始 |
RecordingStopped() | 錄音結束 |
PlaybackFinished() | 播放完成 |
Error(LONG errCode, BSTR desc) | 發生錯誤 |
部署與測試
- 編譯產生
AudioCtrl.ocx。
- 使用
regsvr32 AudioCtrl.ocx 註冊控件。
- 在 HTML 頁面中嵌入:
<object id="AudioCtrl1" classid="clsid:YOUR-CLSID-HERE"
width="320" height="240">
<param name="FileName" value="test.wav">
</object>
<script>
AudioCtrl1.StartRecord();
// ...
</script>
- 或在 VB6、VC++、Director、Authorware 專案中插入 ActiveX 控件測試。
已知限制與改進方向
- 本範例為 Demo,錯誤處理、資源釋放、多執行緒同步尚未完善。
- 未實作持久化儲存 (
IPersistStreamInit),設計階段設定無法保存。
- 波形繪製效率可透過 GDI+ 或 Direct2D 提升。
- 歡迎社群共同完善,打造生產級音訊 ActiveX 控件。
本文配套源碼