「マルチメディア」の編集履歴(バックアップ)一覧に戻る

マルチメディア - (2017/06/18 (日) 21:13:02) のソース

[[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