MCIによる、お手軽サウンドプレイヤー
公式サイトで毎日のようにABのバグフィックスが行われていた頃…公式にMCIを使った解説があった。
AB4.24のサンプルにCDPlayerがあるが、これもMCIを使ったもの。
MCIでmpegやavi、waveやmidiなどを簡単に再生することができるので、
エロゲー制作にはもってこいだ。
ただしMCIには問題があって、再生終了などのメッセージを受け取るには
ウインドウハンドルが必要なことだ。
つまり、
コンソールアプリ、N88アプリでは、扱えないということになってしまうような気がする。
その回避方法は、ダミーウインドウを作り、そいつにメッセージを送らせるようにする。
ダミーと言ってもウインドウ。見えないだけ。
そこで登場するのがサブクラス化だ。
ウインドウプロシージャを横取りするものである。
#N88BASIC
#include <api_mmsys.sbp>
Function callback(hwnd As HWND, msg As DWord, wp As WPARAM, lp As LPARAM) As Long
Dim dwCallback As DWord
If msg=MM_MCINOTIFY And wp=MCI_NOTIFY_SUCCESSFUL Then
'デバイスを閉じる
mciSendCommand(mop.wDeviceID,MCI_STOP,MCI_WAIT,dwCallback)
mciSendCommand(mop.wDeviceID,MCI_CLOSE,MCI_WAIT,dwCallback)
mop.wDeviceID=0
Exit Function
End If
callback = CallWindowProc(DefProc , hwnd , msg , wp , lp)
End Function
Function mciplay() As Long
If mop.wDeviceID <> 0 Then Exit Function
Dim ofn As OPENFILENAME
Dim mpp As MCI_PLAY_PARMS
Dim bErr As Long
Dim buffer[MAX_PATH-1] As Byte
'ファイル名を取得
ofn.lStructSize=SizeOf(OPENFILENAME)
ofn.hwndOwner=_PromptSys_hWnd
ofn.lpstrFilter=Ex"音楽 ファイル(*.wav;*.mid;*.mp3;*.wma)\0*.wav;*.mid;*.mp3;*.wma;\0動画 ファイル(*.avi;*.mpg;*.wmv;)\0*.avi;*.mpg;*.wmv;\0すべてのファイル(*.*)\0*\0\0"
ofn.nFilterIndex=1
ofn.nMaxFile=MAX_PATH
ofn.lpstrFile=buffer
If GetOpenFileName(ofn) = FALSE Then
MessageBox(_PromptSys_hWnd,"ファイルのオープンに失敗","error",MB_OK)
Exit Function
End If
mop.lpstrElementName=buffer
If mciSendCommand(0,MCI_OPEN,MCI_OPEN_ELEMENT or MCI_WAIT,mop) Then
MessageBox(_PromptSys_hWnd,"デバイスのオープンに失敗","error",MB_OK)
Exit Function
End If
mpp.dwCallback=_PromptSys_hWnd
If mciSendCommand(mop.wDeviceID,MCI_PLAY,MCI_NOTIFY,mpp) Then
MessageBox(_PromptSys_hWnd,"デバイスの再生に失敗","error",MB_OK)
Exit Function
End If
Print "再生>";MakeStr(buffer)
mciplay = GetTickCount()
End Function
Function GetTime() As Long
If mop.wDeviceID = 0 Then Exit Function
Dim msp As MCI_STATUS_PARMS
msp.dwItem=MCI_STATUS_POSITION
mciSendCommand(mop.wDeviceID,MCI_STATUS,MCI_WAIT or MCI_STATUS_ITEM,msp)
GetTime=msp.dwReturn
End Function
'ここからメイン処理
Dim mop As MCI_OPEN_PARMS
'サブクラス
Dim DefProc As Long
DefProc = GetWindowLong(_PromptSys_hWnd, GWL_WNDPROC)
SetWindowLong(_PromptSys_hWnd , GWL_WNDPROC , AddressOf(callback))
*INFINITY
If mciplay() = 0 Then End
While(mop.wDeviceID)
Locate 0,2
Print "時間>";GetTime()
Sleep(500)
Wend
MessageBox(_PromptSys_hWnd,"再生終了しました。","N88MCI",MB_OK)
Cls 3
Goto *INFINITY
最終更新:2017年06月18日 21:13