Multimedia

.


Play an AVI file in a Progress window

It can be attractive to play an animation, for example while the user has to wait while your application communicates with the AppServer.
The source in this example uses some of the MCI series of API commands, making it possible to use this source on a window or on a dialog, and making it possible to play AVI's with or without soundtrack!

The complete example source (aviwin.w) is attached. It is a UIB-generated window (not SmartWindow) so the source is a bit too large to show on this page.

The source relies on the availablity of windows.i and windows.p, timestamp Sep 8, 1997 or later.

The window contains two buttons: button-open and button-stop.

Button-open is used to open (and play) an AVI file, button-close calls the procedure to stop (and close) the AVI file. The AVI file repeats infinitely and has a low priority in order to perform other Progress tasks, like FOR EACH processing in the meantime.
Normally you won't offer your users these buttons, they are here for demonstration purposes only.

The window also contains a frame (frame fdisplay): this will be the target window where the AVI output will be shown. It does not have to be a frame: you might also play the AVI on a button...

The AVI file is not opened in shared mode, so if you forget to Close the AVI-player you won't be able to open the AVI file again!
This makes it extremely important to run the 'close' procedure when the AVI is not needed anymore: you must never close the window without closing the AVI first! This is implemented by 'run PlayerClose' after the mainblock's 'WAIT-FOR' loop. If you use this code in a SmartObject you should run PlayerClose in local-destroy or somewhere around there.

Attachments

anim.zip : download source example


PlaySound

Function PlaySoundA plays a waveform sound. This function replaces the obsolete function sndPlaySoundA.

&GLOB SND_ASYNC 1
&GLOB SND_NODEFAULT 2
&GLOB SND_LOOP 8
&GLOB SND_PURGE 64
&GLOB SND_APPLICATION 128
&GLOB SND_ALIAS 65536
&GLOB SND_FILENAME 131072
&GLOB SND_RESOURCE 262148
 
PROCEDURE PlaySoundA EXTERNAL "winmm.dll" PERSISTENT :
  DEFINE INPUT PARAMETER  pszSound    AS LONG.
  DEFINE INPUT PARAMETER  hmod        AS LONG.
  DEFINE INPUT PARAMETER  fdwSound    AS LONG.
  DEFINE RETURN PARAMETER ReturnValue AS LONG.
END PROCEDURE.

Notice the 'persistent' option: if the procedure is not declared as persistent it will not be possible to use the SND_ASYNC flag. Also notice that pszSound is declared as LONG. This is not convenient in most cases when you need to pass a character string, but has to be long to support {&SND_PURGE}.

Examples

In the first example, the first parameter is interpreted as a filename. De default system sound ('ting') will be played if the specified filename can not be found, because the flag SND_NODEFAULT is not specified.

DEFINE VARIABLE ReturnValue AS INTEGER NO-UNDO.
DEFINE VARIABLE szSound     AS MEMPTR  NO-UNDO.
DEFINE VARIABLE wavfile     AS CHARACTER    NO-UNDO.
 
wavfile = "c:\windows\media\logoff.wav".
SET-SIZE(szSound) = LENGTH(wavfile, "raw":U) + 1.
PUT-STRING(szSound,1) = wavfile.
 
RUN PlaySoundA (GET-POINTER-VALUE(szSound), 
                0, 
                {&SND_FILENAME},
                OUTPUT ReturnValue). 
SET-SIZE(szSound) = 0.

The next example plays the system sound associated in Registry with eventname "SystemExit".
This sound and others are found in registry key "HKCU\AppEvents\Schemes\Apps\.Default".

DEFINE VARIABLE ReturnValue AS INTEGER NO-UNDO.
DEFINE VARIABLE szSound     AS MEMPTR  NO-UNDO.
DEFINE VARIABLE eventname   AS CHARACTER    NO-UNDO.
 
eventname = "SystemExit".
SET-SIZE(szSound) = LENGTH(eventname, "raw":U) + 1.
PUT-STRING(szSound,1) = eventname.
 
RUN PlaySoundA (GET-POINTER-VALUE(szSound), 
                0, 
                {&SND_ALIAS} + {&SND_NODEFAULT},
                OUTPUT ReturnValue).
SET-SIZE(szSound) = 0.

The next example plays an application-specific sound event.
These can be registered in key "HKCU\AppEvents\Schemes\Apps\prowin32".

DEFINE VARIABLE ReturnValue AS INTEGER NO-UNDO.
DEFINE VARIABLE szSound     AS MEMPTR  NO-UNDO.
DEFINE VARIABLE eventname   AS CHARACTER    NO-UNDO.
 
eventname = "CUSTOMER_DELETED".
SET-SIZE(szSound) = LENGTH(eventname, "raw":U) + 1.
PUT-STRING(szSound,1) = eventname.
 
RUN PlaySoundA (GET-POINTER-VALUE(szSound), 
                0, 
                {&SND_APPLICATION} + {&SND_NODEFAULT},
                OUTPUT ReturnValue).
SET-SIZE(szSound) = 0.

It is also possible to link WAV resources into an executable or DLL. Suppose the DLL is identified by handle hSounds and contains a sound resource named "LOGIN_REJECTED" :

DEFINE VARIABLE ReturnValue AS INTEGER NO-UNDO.
DEFINE VARIABLE szSound     AS MEMPTR  NO-UNDO.
DEFINE VARIABLE eventname   AS CHARACTER    NO-UNDO.
 
eventname = "LOGIN_REJECTED".
SET-SIZE(szSound) = LENGTH(eventname, "raw":U) + 1.
PUT-STRING(szSound,1) = eventname.
 
RUN PlaySoundA (GET-POINTER-VALUE(szSound), 
                hSounds, 
                {&SND_RESOURCE} + {&SND_NODEFAULT},
                OUTPUT ReturnValue).
SET-SIZE(szSound) = 0.

The last example is submitted by Nenad Orlovic [norlovic@zg.tel.hr].
Sounds should always be played asynchronous, especially when it is a long sound clip, so the program can continue while the sound is playing. This is done by adding the SND_ASYNC flag. This is only possible when the PlaySound procedure is declared as persistent: otherwise Progress would free the winmm.dll library immediately which would cause the sound to stop.
The example also uses SND_LOOP to repeat the sound. SND_LOOP can not be used without SND_ASYNC.

DEFINE VARIABLE ReturnValue AS INTEGER NO-UNDO.
DEFINE VARIABLE szSound     AS MEMPTR  NO-UNDO.
DEFINE VARIABLE wavfile     AS CHARACTER    NO-UNDO.
 
wavfile = "c:\windows\media\logoff.wav".
SET-SIZE(szSound) = LENGTH(wavfile, "raw":U) + 1.
PUT-STRING(szSound,1) = wavfile.
 
RUN PlaySoundA (GET-POINTER-VALUE(szSound),
                0,
                {&SND_FILENAME} + {&SND_ASYNC} + {&SND_LOOP} + {&SND_NODEFAULT},
                OUTPUT ReturnValue).
SET-SIZE(szSound) = 0.
 
MESSAGE "Press OK to stop the music" VIEW-AS ALERT-BOX.
 
RUN PlaySoundA (0,
                0,
                {&SND_PURGE},
                OUTPUT ReturnValue).
 
MESSAGE "The music stopped" VIEW-AS ALERT-BOX.