Link to home
Start Free TrialLog in
Avatar of Hosam
HosamFlag for Egypt

asked on

Play a wave

I do a project, .wav files stored in .Res files, then to .Dlls.
I can play any sound from dll, Can play that sound through mciwndx.ocx control

elzohry
Avatar of Richie_Simonetti
Richie_Simonetti
Flag of Argentina image

This example is for VB3, just replace API declarations listed here for ones founded in API viewer


VB3 Using Visual Basic 3.0 to Play WAVE Files Stored in a DLL
Last reviewed: January 9, 1997
Article ID: Q141060  
The information in this article applies to:
Microsoft Windows Software Development Kit (SDK) version 3.1
Microsoft Visual Basic version 3.0


SUMMARY
By calling the necessary Windows API, a Visual Basic program can access and play wave files stored in a dynamic-link library (DLL). Generally, a DLL that contains only resources such as wave files is referred to as a resource-only library.

NOTE: Visual Basic 3.0 does not support the insertion of resources such as wave files into a DLL. A third-party tool such as the Microsoft C++ Compiler and its accompanying Resource Compiler are needed to accomplish this.



MORE INFORMATION
The following example shows how to create a resource-only library using Microsoft Visual C++ 1.5. For this example, the resource-only library contains the two wave files Ding.wav and Chimes.wav.


Create a text file and place the following lines of code in it:

   #include <windows.h>
   int FAR PASCAL LibMain(HANDLE hInstance, WORD wDataSeg, WORD wHeapSize,
   LPSTR lpszCmdLine)
   {
      if (wHeapSize > 0)
         UnlockData(0);
      return 1;
   }



Save the above file with the extension .c.

Create another file and place the following text in it (the lines below assume that both wave files are currently located in the c:\windows directory):


    Sound1 WAVE c:\windows\ding.wav
    Sound2 WAVE c:\windows\chimes.wav

Save this file with the extension .rc. This will identify it as a
    resource file.

From within Visual C++ version 1.5, click New on the Project menu to
    specify the name of your project. Then set the Project Type to "Windows
    dynamic-link library (.DLL)" and click OK.

Use the Edit dialog box that appears next to add the .c and .rc files
    created in steps 1-3.

On the Project menu, click Build. This will take the files created above
   and generate the resource-only library from them. This DLL contains the
   two wave files Ding.wav and Chimes.wav.


The following Visual Basic 3.0 code can then be used to play the wave files imbedded in the DLL created above:

In the Visual Basic programs "General Declaration" section add the following code:

   Declare Function sndPlaySound Lib "mmsystem.dll" (ByVal lpRes As Any,
   ByVal wflags As Integer) As Integer

   Declare Function LoadLibrary Lib "kernel" (ByVal lpLibFileName As
   String) As Integer

   Declare Function FindResource Lib "kernel" (ByVal hInstance As Integer,
   ByVal lpname As String, ByVal lpType As Any) As Integer

   Declare Function LoadResource Lib "kernel" (ByVal hInstance As Integer,
   ByVal hResInfo As Integer) As Integer

   Declare Function LockResource Lib "kernel" (ByVal hResData As Integer)
   As Long

   Declare Function FreeResource Lib "kernel" (ByVal hResData As Integer)
   As Integer

   Declare Sub FreeLibrary Lib "kernel" (ByVal hInstance As Integer)

   Const SND_MEMORY = 4



In a subroutine add the following Visual Basic code. This is the code that actually opens the DLL and plays the Ding.wav file:
Dim hInstance As Integer Dim hResInfo As Integer Dim hRes As Integer Dim lpRes As Long Dim iReturn As Integer

hInstance = LoadLibrary("c:\wavedll.dll") hResInfo = FindResource(hInstance, "Sound1", "WAVE") hRes = LoadResource(hInstance, hResInfo) lpRes = LockResource(hRes) iReturnVal = sndPlaySound(lpRes, SND_MEMORY)

iReturnVal = FreeResource(hRes) FreeLibrary(hInstance)


You can then call the subroutine the code in step 9 was added to whenever you want the sound played.
 
Also, Take a look at MSDN article:


Using LoadResData with Binary Data
Last reviewed: May 16, 1996
Article ID: Q141505  
The information in this article applies to:
Professional and Enterprise Editions of Microsoft Visual Basic, 16-bit and 32-bit, for Windows, version
4.0


SUMMARY
Visual Basic 4.0 introduces a new function called LoadResData, which can be used to retrieve binary
data from a resource (.res) file. The sample in this document demonstrates how to create a resource
file and use binary data from it in all versions of Visual Basic 4.0.



MORE INFORMATION
The following code is a resource script that can be compile by using the 16 and 32-bit versions of Rc.exe.



///////////////////////////////////////////////////////////////////////
//////
  // Myres.rc - 16 & 32 bit script. This must be compiled into two .res
  // files using the 16 & 32 bit versions of RC.

///////////////////////////////////////////////////////////////////////
//////
  // Wave Resources - You must copy these files from your \Windows
  // directory to the directory where your .rc script resides.

  CHIMES                  WAVE    DISCARDABLE     "Chimes.wav"
  DING                    WAVE    DISCARDABLE     "Ding.wav"


Steps to Create a Resource File

Save the above code in Notepad as Myres.rc in the directory where Rc.exe exists on your hard disk.

Copy Chimes.wav and Ding.wav from your Windows directory (or your \Windows\Media directory on Windows
95) to the same directory where you saved Myres.rc.

At the command line, type "RC -r Myres.rc" If you want a 16-bit and 32- bit version of your resource
file, then you will have to save two copies of your resource file as Myres32.rc and Myres16.rc, and
compile each separately with the appropriate resource compiler.

Steps to Run the Sample Application

Create a new project and add a command button to Form1.

Add the following code to Form1:

'*********************************************************************

     ' Form1.frm - Calls PlayWaveRes to play a wave resource file.

'*********************************************************************

     Sub Command1_Click()
        PlayWaveRes "Chimes"
        PlayWaveRes "Ding"
     End Sub



Add your resource file to the project.

Type the following code in a new code module:

'*********************************************************************

     ' Baswave.bas - Plays a wave file from a resource using LoadResData.

'*********************************************************************

     Option Explicit
     #If Win32 Then
       Private Declare Function sndPlaySound Lib "winmm" Alias

"sndPlaySoundA" _
                           (lpszSoundName As Any, ByVal uFlags As

Long) As Long
     #Else
       Private Declare Function sndPlaySound Lib "MMSYSTEM" ( _
                          lpszSoundName As Any, ByVal uFlags%) As Integer
     #End If

'*********************************************************************

     '  Flag values for wFlags parameter.

'*********************************************************************

     Public Const SND_SYNC = &H0        ' Play synchronously (default)
     'Public Const SND_ASYNC = &H1       ' Play asynchronously (see
                                         ' note below!)
     Public Const SND_NODEFAULT = &H2   ' Don't use default sound
     Public Const SND_MEMORY = &H4      ' lpszSoundName points to a
                                        ' memory file.
     Public Const SND_LOOP = &H8        ' Loop the sound until next
                                        ' sndPlaySound.
     Public Const SND_NOSTOP = &H10     ' Don't stop any currently
                                        ' playing sound.

'*********************************************************************

     ' Plays a wave file from a resource.

'*********************************************************************

     Public Sub PlayWaveRes(vntResourceID As Variant, Optional vntFlags)
     '-----------------------------------------------------------------
     ' WARNING:  If you want to play sound files asynchronously in
     '           Win32, then you MUST change bytSound() from a local
     '           variable to a module-level or static variable. Doing
     '           this prevents your array from being destroyed before
     '           sndPlaySound is complete. If you fail to do this, you
     '           will pass an invalid memory pointer, which will cause
     '           a GPF in the Multimedia Control Interface (MCI).
     '-----------------------------------------------------------------
     Dim bytSound() As Byte ' Always store binary data in byte arrays!

     bytSound = LoadResData(vntResourceID, "WAVE")

     If IsMissing(vntFlags) Then
        vntFlags = SND_NODEFAULT Or SND_SYNC Or SND_MEMORY
     End If

     If (vntFlags And SND_MEMORY) = 0 Then
        vntFlags = vntFlags Or SND_MEMORY
     End If

     sndPlaySound bytSound(0), vntFlags
     End Sub
Wow Richie! How difficult can you make this ? ;-)

Here's an straight forward (and simple) example:

Const SND_ASYNC = &H1
Const SND_FILENAME = &H20000
Const SND_SYNC = &H0
Const SND_NODEFAULT = &H2
Const SND_LOOP = &H8
Const SND_NOSTOP = &H10
Const SND_NOWAIT = &H2000

Public Function PlayWav(SoundFile As String) As Boolean

    PlayWav = sndPlaySound(SoundFile, SND_ASYNC Or SND_NODEFAULT)

End Function

Now just call the function. The SoundFile parameter is the wave file to play.
Works for all windows versions.

D'Mzzl!
RoverM
The wav file is located in a dll.
Optionally, you could try with:

Private Const SND_APPLICATION = &H80         '  look for application specific association
Private Const SND_ALIAS = &H10000     '  name is a WIN.INI [sounds] entry
Private Const SND_ALIAS_ID = &H110000    '  name is a WIN.INI [sounds] entry identifier
Private Const SND_ASYNC = &H1         '  play asynchronously
Private Const SND_FILENAME = &H20000     '  name is a file name
Private Const SND_LOOP = &H8         '  loop the sound until next sndPlaySound
Private Const SND_MEMORY = &H4         '  lpszSoundName points to a memory file
Private Const SND_NODEFAULT = &H2         '  silence not default, if sound not found
Private Const SND_NOSTOP = &H10        '  don't stop any currently playing sound
Private Const SND_NOWAIT = &H2000      '  don't wait if the driver is busy
Private Const SND_PURGE = &H40               '  purge non-static events for task
Private Const SND_RESOURCE = &H40004     '  name is a resource name or atom
Private Const SND_SYNC = &H0         '  play synchronously (default)
Private Declare Function PlaySound Lib "winmm.dll" Alias "PlaySoundA" (ByVal lpszName As String, ByVal hModule As Long, ByVal dwFlags As Long) As Long
Private Sub Form_Load()
    'KPD-Team 2000
    'URL: http://www.allapi.net/
    'E-Mail: KPDTeam@Allapi.net
Dim hInstance As long
Dim hResInfo As long
Dim hRes As long
Dim lpRes As Long
Dim iReturn As long

hInstance = LoadLibrary("c:\wavedll.dll")
hResInfo = FindResource(hInstance, "Sound1", "WAVE")
hRes = LoadResource(hInstance, hResInfo)
lpRes = LockResource(hRes)
    PlaySound byval lpRes , byval hInstance , SND_RESOURCE
End Sub
Overread that....GOOD ONE RICHIE! LOL
roverm, you are welcome anytime ....:)
Avatar of Hosam

ASKER

Thanks all
But , I want to Play a wave File from Dll With Mciwndx.ocx control or MMultimedia Control .
or How i know when the Wave is end ( Stopped ) .
Thanks
Well, i think ypu need to save the contents of dll (for wav file) to a temporary file in hard disk and play it from there.
Avatar of Hosam

ASKER

it's to hard to do that ?
i thinks there is another way
i saw some programs do that
ASKER CERTIFIED SOLUTION
Avatar of Richie_Simonetti
Richie_Simonetti
Flag of Argentina image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Hosam

ASKER

it's the best what i got