Posted on 1997-03-08
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

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

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate row…
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…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

726 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