Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17


Play a wave

Posted on 2002-05-04
Medium Priority
Last Modified: 2012-06-27
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

Question by:elzohry
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
  • 6
  • 3
  • 2
LVL 16

Expert Comment

ID: 6990027
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

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.

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)
      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.
LVL 16

Expert Comment

ID: 6990033
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

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.

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
       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
     End If

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

     sndPlaySound bytSound(0), vntFlags
     End Sub
LVL 12

Expert Comment

ID: 6990445
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_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.

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

LVL 16

Expert Comment

ID: 6990565
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
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
LVL 12

Expert Comment

ID: 6991890
Overread that....GOOD ONE RICHIE! LOL
LVL 16

Expert Comment

ID: 6991937
roverm, you are welcome anytime ....:)

Author Comment

ID: 6992685
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 ) .
LVL 16

Expert Comment

ID: 6992857
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.

Author Comment

ID: 6995927
it's to hard to do that ?
i thinks there is another way
i saw some programs do that
LVL 16

Accepted Solution

Richie_Simonetti earned 150 total points
ID: 6996322
To me, doing so is a waste of resources (i mean, put wav files in a dll, extract each one to a temp file, play it and delete it)
I think it would be best to use plain wav files stored in a specific folder and load them from it inside the control but it is only what i would do.

Author Comment

ID: 6997933
it's the best what i got

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

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

This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
This article describes how to use a set of graphical playing cards to create a Draw Poker game in Excel or VB6.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
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…
Suggested Courses

715 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