could someone please gove me an example code of playing a mid, (filenamed finallevel_backmusic.mid) in the background of a form - also can u loop it?
thanks
FLY
Printable View
could someone please gove me an example code of playing a mid, (filenamed finallevel_backmusic.mid) in the background of a form - also can u loop it?
thanks
FLY
Try this.
Link
That link did not answer your looping question. Sorry :)
Try this one instead.
They are mainly talking about mp3's but use midi instead.
Hope that helps better. :D
I see that you've already gotten how to do this, but on the looping thing, I've tried all sorts of things, but none have worked. I thought perhaps the notify flag could be used, and work with the hWndCallback parameter, but that is a window handle, so it doesn't make sense to me. I could never get a concrete description on how to work with that. But there are ways to tell if a media file is still playing though. This is some quick and dirty stuff from a module I have when I don't want to type out the stuff myself. The important part is the last function, IsFinished(), which tells if a given MCI alias is complete. It uses the time format called "song pointer" (which I think is the default for midi files), so it might be better off to either use the OpenMIDI() sub here, or adapt yours to force the time format song pointer as in the OpenMIDI() sub here. To make a midi loop, all you'd have to do is set a timer or something, which is somewhat of a bad way around it, and then use this function to tell when the file is over. It's not the best of ways around it, but it works. I'd still prefer a way to instantly know when it's over, and loop it, without constantly checking.
VB Code:
Option Explicit Public Declare Function mciSendString Lib "winmm" Alias "mciSendStringA" (ByVal lpzCommand As String, ByVal lpzReturn As String, ByVal nReturnLength As Long, ByVal hWndCallback As Long) As Long Public Sub OpenMIDI(ByVal strMIDI As String, ByVal strAlias As String) 'opens the midi specified in strMIDI with the alias strAlias mciSendString "open " & strMIDI & " type sequencer alias " & strAlias, vbNullString, 0, 0 'makes the time format "song pointer" (used to tell if the file is done playing later) mciSendString "set " & strAlias & " time format song pointer", vbNullString, 0, 0 End Sub Public Sub PlayMIDI(ByVal strAlias As String) 'this function assumes strAlias is an aliased MCI device 'plays the midi aliased as strAlias mciSendString "play " & strAlias & " from 0", vbNullString, 0, 0 End Sub Public Sub StopMIDI(ByVal strAlias As String) 'this function assumes strAlias is an aliased MCI device 'stop the midi aliased as strAlias mciSendString "stop " & strAlias, vbNullString, 0, 0 End Sub Public Sub CloseMIDI(Optional ByVal strAlias As String = "") 'closes the midi aliased as strAlias, or all open MCI devices if no alias is given, or "" is given mciSendString "close " & IIf(strAlias = "", "all", strAlias), vbNullString, 0, 0 End Sub Public Function IsFinished(ByVal strAlias As String) As Boolean 'this function assumes strAlias is an aliased MCI device 'and that the aliased device has the time format "song pointer" 'if the given alias isn't an open MCI device, True is returned Dim strBuffer As String * 128 Dim lngLength As Long, lngPosition As Long 'get the current length of the midi aliased as strAlias (in song pointer units) mciSendString "status " & strAlias & " length", strBuffer, Len(strBuffer), 0 'trim out the valid part of the string, and store in the var lngLength = CLng(Val(Left$(strBuffer, InStr(strBuffer, vbNullChar) - 1))) 'get the current position midi aliased as strAlias (in song pointer units) mciSendString "status " & strAlias & " position", strBuffer, Len(strBuffer), 0 'trim out the valid part of the string, and store in the var lngPosition = CLng(Val(Left$(strBuffer, InStr(strBuffer, vbNullChar) - 1))) 'if the current position is equal to the length, it's over IsFinished = IIf(lngPosition = lngLength, True, False) End Function 'open a midi OpenMIDI "c:\myfile.mid", "myfile" 'play the midi (same sytax for StopMIDI and CloseMIDI) PlayMIDI "myfile" 'check on status If IsFinished("myfile") Then MsgBox "myfile is done playing"
I have some good news. After giving this another go, I finally had the insight to understand why the last param is called hWndCallback. WIth the notify flag, the MCI device will send a MM_MCINOTIFY message back to the window you specify when the device is finished what it was doing. To catch this, you'll have to subclass, so it's not necessarily the safest thing to do (but is fine as long as you do it correctly). This is what you'll need to set it up. Since this is subclassing, DO NOT press the IDE stop button, or you'll crash VB. Press the X on the form, or use Alt+F4. This isn't the fanciest example, as it only uses a single playing midi, but it shows how to get the loop effect.
VB Code:
'in a module Option Explicit Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Public Const GWL_WNDPROC As Long = -4 Public Const MCI_NOTIFY_SUCCESSFUL As Long = &H1 Public Const MCI_NOTIFY_ABORTED As Long = &H4 Public Const MM_MCINOTIFY As Long = &H3B9 Public lngOldProc As Long Public Sub Hook(ByVal hWnd As Long) lngOldProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf CustomProc) End Sub Public Sub UnHook(ByVal hWnd As Long) SetWindowLong hWnd, GWL_WNDPROC, lngOldProc End Sub Public Function CustomProc(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long If wMsg = MM_MCINOTIFY Then 'if the previous command finished successfully, replay the midi 'this assumes the midi has been aliased as "x" If wParam And MCI_NOTIFY_SUCCESSFUL Then mciSendString "play x from 0 notify", vbNullString, 0, hWnd 'the following isn't necessary, but it's something additional you can check 'if you use mciSendString and "play", "stop", or "close" on the midi 'while playing, MCI will set this flag If wParam And MCI_NOTIFY_ABORTED Then Debug.Print "aborted" End If 'let windows handle the rest CustomProc = CallWindowProc(lngOldProc, hWnd, wMsg, wParam, lParam) End Function 'inside your form Private Sub Form_Load() Hook Me.hWnd mciSendString "open c:\x.mid type sequencer alias x", vbNullString, 0, 0 mciSendString "play x from 0 notify", vbNullString, 0, Me.hWnd End Sub Private Sub Form_Unload(Cancel As Integer) mciSendString "close x", vbNullString, 0, 0 UnHook Me.hWnd End Sub
Kaverin-
That looks great! If you don't mid I'll add that to my code lib. :)