這次我們來看一下設定中加入音樂的功能,加入音樂的功能很單純,就是用檔案對話盒加入檔案而已 ,如果你要改用VB內附的Common Dialog Control,也不用有什麼大變動,只要將User指定的檔名代 入txtWavFile.Text或txtMidiFile.Text即可,什麼frmFileDialog.Show那幾個步驟就可以免了, 接者才是重點,就是提供User馬上試聽的功能,這裡提供了兩個我自己寫的Function - PlayMusic 和StopMusic,當按下試聽的時候檢查一下該物件的Caption是"試聽"還是"停止",再分別執行程式。 在這裡我沒有用StopMusic,因為我是把它寫成同時停止Wav和Midi,所以在這裡另外處理。先來看一下 PlayMusic的程式
Public Function PlayMusic(FileName As String, MusicType As Integer) As Long
Dim ShortName As String
Dim rc As Long
Dim s As String

'Play Music, 1. Get Music File ShortName,Check API Error
'            2. Select Music Type(Midi,Wave) Close Device,Open & Play
'            3. Check API Error & Start Timer tmrDetMusic,Check Music Status

ShortName = String(LenB(FileName), Chr$(0))
rc = GetShortPathName(FileName, ShortName, Len(ShortName))

If rc = 0 Then
   MsgBox "無法取得檔案名稱,無法播放音效檔!請確定檔案名稱及路徑是正確的", vbInformation Or vbOKOnly
   Exit Function
End If

ShortName = Left$(ShortName, InStr(ShortName, Chr$(0)) - 1)

Select Case MusicType
Case MIDI_FILE
     rc = mciSendString("close MidiDevice", vbNullString, 0, 0)
     rc = mciSendString("open " & ShortName & " alias MidiDevice", vbNullString, 0, 0)
     rc = mciSendString("play MidiDevice", vbNullString, 0, 0)
     
     If rc <> 0 Then    'Open Error!
        s = String(256, Chr$(0))
        mciGetErrorString rc, s, Len(s)
        s = Left$(s, InStr(s, Chr$(0)) - 1)
        
        MsgBox "Open MidiFile Error!" & Chr$(13) & s, vbInformation Or vbOKOnly
        Exit Function
     End If
     MusicStatus(MIDI_FILE) = True
     PlayMusic = True
     If frmScrSetUP.tmrDetMusic.Tag = 0 Then
        frmScrSetUP.tmrDetMusic.Enabled = True
        frmScrSetUP.tmrDetMusic.Tag = 1
     End If
     
Case WAV_FILE
     rc = mciSendString("close WavDevice", vbNullString, 0, 0)
     rc = mciSendString("open " & ShortName & " alias WavDevice", vbNullString, 0, 0)
     rc = mciSendString("play WavDevice", vbNullString, 0, 0)
     
     If rc <> 0 Then    'Open Error!
        s = String(256, Chr$(0))
        mciGetErrorString rc, s, Len(s)
        s = Left$(s, InStr(s, Chr$(0)) - 1)
        
        MsgBox "Open WavFile Error!" & Chr$(13) & s, vbInformation Or vbOKOnly
        Exit Function
     End If
     MusicStatus(WAV_FILE) = True
     PlayMusic = True
     If frmScrSetUP.tmrDetMusic.Tag = 0 Then
        frmScrSetUP.tmrDetMusic.Enabled = True
        frmScrSetUP.tmrDetMusic.Tag = 1
     End If
End Select
End Function

這個Function要傳入兩個參數,FileName - 檔案名,MusicType - 播放的音樂檔類型, 由於我使用的mciSendString這個API規定傳入的檔名需要是短檔名的格式,所以我們要先 使用GetShortPathName這個API來取得檔案的短檔名,如果討厭用API,利用FileSystemObject 也可以取得短檔名,接下來判斷MusicType來執行mci指令,觀察之後,你可以發現,其實兩段 程式大同小異,在mciSendString的使用上,除了一些比較特別的mci裝置外,播放的方法其實都大 同小異的,因此如果你把檔案改成AVI檔,你會發覺程式依然可以執行,AVI檔也可以正常播放, 我把它分成兩個部份,是為了給予不同的別名,方便管理。否則檔案亂開亂放,到時候可不好玩! 在開啟一個mci裝置前,通常我們都會先執行Close的指令,這是為了確保程式不會因為有忘了關閉 mci裝置而導致錯誤,接者我們才執行開檔的動作,這裡我分別用MidiDevice、WavDevice來作為別名, 當然,也是為了管理方便,使用上沒有硬性規定要給別名的,只不過你就要多設變數來記錄開檔的檔名, 而且在作Close的動作時,你也沒有辦法確保你關閉的是正確的檔案(如果程式出錯),還是建議你使用 統一的別名,比較不會有問題。接下來只要使用Play就可以播放mci裝置了。如果執行mciSendString 的傳回值不等於0,代表執行有問題,傳回的值就是錯誤碼,我們可以再以此呼叫mciGetErrorString 取得錯誤訊息,告知User錯誤訊息。然後我設了一個變數來判斷目前音樂是否播放,啟動一個Timer 來觀察mci裝置的播放狀況,並在mci裝置播放完畢時將mci裝置關閉,Timer的程式如下:
Private Sub tmrDetMusic_Timer()
Dim i As Integer
Dim X As String
tmrDetMusic.Enabled = False

'Check Music Status then Stop Music

If MusicStatus(MIDI_FILE) = True Then
   X = String(256, Chr$(0))
   mciSendString "status MidiDevice mode", X, Len(X), 0
   If Left$(X, 7) = "stopped" Or Left$(X, 2) = "停止" Then
      mciSendString "close MidiDevice", vbNullString, 0, 0
      MusicStatus(MIDI_FILE) = False
      cmdMIDIPlay.Caption = "試聽"
   End If
End If
If MusicStatus(WAV_FILE) = True Then
   X = String(256, Chr$(0))
   mciSendString "status WavDevice mode", X, Len(X), 0
   If Left$(X, 7) = "stopped" Or Left$(X, 2) = "停止" Then
      mciSendString "close WavDevice", vbNullString, 0, 0
      MusicStatus(WAV_FILE) = False
      cmdWAVPlay.Caption = "試聽"
   End If
End If


If MusicStatus(MIDI_FILE) = True Or MusicStatus(WAV_FILE) = True Then
   tmrDetMusic.Interval = 1000
   tmrDetMusic.Enabled = True
Else
   tmrDetMusic.Tag = 0
End If
End Sub


在進入Timer時先將Timer Disible,否則可能程式還沒Run完,下一次的Timer又跑起來了, 接下來以MusicStatus這個變數確定mci裝置是否在播放中,如果正在播放,就以 "status mci裝置名稱 mode"這個mci指令來查詢播放狀態,如果傳回的是"stopped"(Win95/98)或是 "停止"(Win NT中文版)就代表mci裝置播放結束了。接者使用API將mci裝置Close就行了, 因為只是試聽而已,所以我並沒有作重覆播放的功能,如果你覺得需要的話,也只要將mci指令 改為使用"seek mci裝置名稱 to start"及"play mci裝置名稱",就可以作出重覆播放的效果了 。而StopMusic這個程式則是在你試聽中,關了視窗、換了設定檔....等需要將音樂停止時使用的 ,程式與上面並沒有太大差別,自己看一看就行了。一定要注意的是,離開程式前,mci裝置一定要 記得關閉,一個是為了釋放佔用的資源,另一個則是為了避免別名被佔用,萬一有另外一個程式也 使用這個別名,卻沒有先做Close的動作,那就會發生別名已使用的錯誤,一定要注意。

後記:
關於mci的播放大概就是這樣子了,至於有人問說mciSendString可不可以播放mp3呢? 在這裡告訴你,理論上是可以的,為什麼說理論上呢?mci裝置可以播放的檔案其實是在 Windows已經註冊為mci類別的檔案,這些檔案都可以透過mciSendString或MCI Control來直接 控制,而聽說(因為我沒裝過)裝了IE5或WIN98 SE之後就可以用mciSendString來播放mp3了, 有興趣的就試試看吧! 下回要講解的是存檔及開檔的部份,敬請期待
如果對教學內容有任何意見的話,歡迎EMail 給我一起討論,謝謝!

回到VB教學教室