Posted on 1997-03-08
Medium Priority
Last Modified: 2010-05-19
hi -
Have been trying to write routine that plays a MIDI file in a loop while moving a gif around on the screen. I have the VB4 STD edition, running in win95. Can someone please post how to tell when the midi file has stopped playing?  I believe it might be a return from a win32API call. I am using mciSendString() etc to play midi file, but can't find any other information on this. thanks  -slacker-
Question by:spenney
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions

Author Comment

ID: 1424389
Is there anywhere I can get a copy of the win32api?
Or do you have to buy a book or pro version of VB?

Accepted Solution

volking earned 200 total points
ID: 1424390
You'll need to read two articles. First one is below and the second one is in the MS Knowledgebase Q114557. You can get to the knowledge base over the web.

Direct Control of AVI Files from Viewer
Article ID: Q110384
Revision Date: 09-JAN-1996
The information in this article applies to:

 - Microsoft Multimedia Viewer Publishing Toolkit versions 2.0
   and 2.0a

This article describes two methods to play an Audio-Video Interleaved (.AVI) file without a controller, and then have the .AVI window close when the .AVI file is done playing. You can then execute commands when the AVI window closes.
Method 1 describes using the mciSendString() command from the MMSYSTEM.DLL that comes with the Windows 3.1 SDK (Software Development Kit). Method 2 describes how to use the standard Viewer ewX statement to play your .AVI file, and how to use hooks to be notified when the video finishes.

The simplest way to play an .AVI file without a controller and have the AVI window close when the .AVI is done is to use the mciSendString() function from MMSYSTEM.DLL that comes with the Windows 3.1 SDK.

NOTE: Using mciSendString() causes the .AVI file to be played in a window created by MMSYSTEM.DLL; the .AVI file will *not* be displayed in a regular pane.
 You could write a DLL function that calls mciSendString(), and call that DLL function from Viewer. To do this you would need to register your DLL function in the [CONFIG] section of your .MVP file. Or you could call mciSendString() directly from your Viewer title. In that case, you would need to register mciSendString() in the [CONFIG] section.
To register the mciSendString() function in your [CONFIG] section, add the following line to the [CONFIG] section of your .MVP file:


See pages 5-10 and 5-74 of the Viewer "Technical Reference" for more information on using RegisterRoutine().
You can start the .AVI file in many ways, including using topic entry commands, hot spot commands, buttons, and menu items. To create a button to play the COYOTE.AVI file (for example), add the following line to the [CONFIG] section of your .MVP file after the RegisterRoutine() function:

   CreateButton(`btn_avi', `Play AVI', `mciSendString("open
   coyote.avi",0,0,0):mciSendString("play coyote.avi
   wait",0,0,0):mciSendString("close coyote.avi",0,0,0)')

To start an .AVI file on topic entry, have the .AVI window close when the .AVI file finishes, and then jump to another topic, add the following topic entry commands:

   !mciSendString("open coyote.avi",0,0,0); mciSendString("play
   coyote.avi   wait",0,0,0); mciSendString("close coyote.avi",0,0,0);

NOTE: Because the CreateButton() function is in the .MVP file, the multiple commands are separated by a colon (:). If you specify multiple commands in your .RTF file, they should be separated by a semicolon (;) instead. In .MVP files, the semicolon (;) character means the rest of the line is commented out.
Method 2 uses a message hook to determine when the .AVI file is finished playing. If you play the .AVI file using an {ewX mvmci2, ViewerMCI...} statement, then Viewer's MVMCI2.DLL will ask the system to send an MM_MCINOTIFY message when the .AVI file is finished playing. You can put a message hook function in a DLL, and when the MM_MCINOTIFY message comes through, you could send the ClosePane() command to Viewer via the VwrCommand() Viewer API (Application Programming Interface) function.
There is a sample in the Microsoft Software Library called VWRHOOK that uses a DLL to implement a message hook to trap MM_MCINOTIFY. If you call SetGMHook() in your [CONFIG] section, the hook function will receive a notification message whenever any MCI element is finished playing. The Windows SDK documentation for SetWindowHook() and SetWindowsHookEx() has more information on setting hooks.
For additional information on the VWRHOOK sample, please see the following article in the Microsoft Knowledge Base:

   ARTICLE-ID: Q114557
   TITLE     : SAMPLE: Executing Viewer Commands When MCI Finishes Playing

Additional reference words: 2.00 2.00a hotspot

KBCategory: kbusage kbfile
KBSubcategory: MdkView


Expert Comment

ID: 1424391
There is a much easier way than is listed above....
This example was created in VB 3, but will work in any VB.

Create a form with two command buttons and two labels, do not rename them (or you'll have to edit the text below).
Paste the following code into the general declarations section of the form


Option Explicit

Declare Function mciSendString Lib "mmsystem" (ByVal lpstrCommand$, ByVal lpstrReturnStr As Any, ByVal wReturnLen%, ByVal hCallBack%) As Long

Sub Form_Load ()

    Dim X As Integer
    ' If we're already running, then quit
    If (App.PrevInstance = True) Then
    End If
    ' Open the midi file (This should all be on one line)
    X = mciSendString("open c:\dev\sound\mi2.mid type sequencer alias seq2", 0&, 0, hWnd)
    X = mciSendString("play seq2", 0&, 0, hWnd)
End Sub

Private Sub Form_Unload (Cancel As Integer)

Dim X As Integer

    'Close all MCI devices opened by this program
    X = mciSendString("close seq2", 0&, 0, hWnd)

End Sub

Private Sub Command1_Click ()

    Dim X As Integer
        ' Play the Midi file
        X = mciSendString("play seq2", 0&, 0, hWnd)

End Sub

Private Sub Command2_Click ()

    Dim X As Integer

    ' This will stop the file playing (well its more of a pause really)
    X = mciSendString("stop seq2 wait", 0&, 0, hWnd)

End Sub

Private Sub Timer1_Timer ()

    Dim X As Long
    Dim s As String * 128
    Dim iLength As Integer
    Dim iPosition As Integer
    ' Get the length of the MIDI file
    X = mciSendString("status seq2 length", s, Len(s), 0)
    label1.Caption = s
    iLength = Val(s)

    ' Get the distance through the file
    X = mciSendString("status seq2 position", s, Len(s), 0)
    Label2.Caption = s
    iPosition = Val(s)

    ' If the position is at the length then...
    If iPosition >= iLength Then
        ' Close the file and start it up again!!!
        X = mciSendString("close seq2", 0&, 0, hWnd)
        ' (This should all be on one line)
        X = mciSendString("open c:\dev\sound\mi2.mid type sequencer alias seq2", 0&, 0, hWnd)
        X = mciSendString("play seq2", 0&, 0, hWnd)

    End If

End Sub

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The debugging module of the VB 6 IDE can be accessed by way of the Debug menu item. That menu item can normally be found in the IDE's main menu line as shown in this picture.   There is also a companion Debug Toolbar that looks like the followin…
You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…
Suggested Courses

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question