Recipe 12.1 Play an Embedded Sound File from Within an Application
12.1.1 Problem
Your application stores WAV files
as OLE objects within a table, and you'd like to be
able to play them on demand. You know that users can double-click on
the icon in a form to play the sounds, but you'd
like some control over this. Is there a way to play one of these
embedded sounds when you need to?
12.1.2 Solution
Access
gives you substantial control over the use of OLE objects. Using the
Action property of the control that's displaying the
OLE object, you can tell the object to activate itself, copy itself
to or paste itself from the Windows clipboard, update its data, and
close or delete itself. The Action property can be used for bound or
unbound OLE objects and graphs, too. You can also call up the Insert
Object or Paste Special dialog to place data into the control. This
solution uses a bound OLE field, but it works just as well with an
unbound object on a form.Load and run frmOLE (shown in Figure 12-1) from
12-01.MDB. This is a continuous form, pulling the data from the table
tblOLE. If you click on an Activate button, the form activates that
OLE object, which is stored in the OLEObject field of the table. The
sample table includes a few WAV files, one Microsoft Graph object,
and a MIDI file. Clicking on the Activate button will either play the
sound or activate Microsoft Graph so you can edit the tiny graph
object. Click on the Insert button to call up the Insert Object
dialog, which allows you to insert any OLE object you like into the
table. Click on the Open button to open the object in its own editing
window rather than activating it in place.
Figure 12-1. frmOLE allows you to play or insert OLE objects
Follow these simple steps to create such a form:
- Create a new table or modify an
existing table, adding a column (named OLEObject in the sample) with
its Data Type set to OLE object. Note that you cannot index on an OLE
field, and therefore it can't be your primary key
for the table. - Create a new form. To emulate the sample
form, the only property you need to set is the DefaultView property.
Set it to Continuous Forms so that you'll see
multiple rows at the same time. This isn't
necessary, but it will make your form look like the sample. - Create a bound OLE object (the cactus picture with the XYZ across the
top on the toolbar) on the form. The code in this example is based on
a control named objOLE; adjust the code
appropriately if you name your control something else. The sample
form includes the description field from tblOLE as
a text box, but this isn't used in the sample code. - Add three buttons:
cmdOpen, cmdActivate, and
cmdInsert, with captions Open, Activate, and
Insert, respectively. Attach the following code to the Activate
button's Click event (see the Preface for more
information on creating event procedures):Private Sub cmdActivate_Click( )
Attach the following code to the Open button's Click
Dim ctl As Control
On Error Resume Next
Set ctl = Me.objOLE
ctl.Verb = acOLEVerbPrimary
ctl.Action = acOLEActivate
Err.Clear
End Sub
Attach the following code to the Insert button's Click event:
Private Sub cmdInsert_Click( )
On Error Resume Next
Me.objOLE.Action = acOLEInsertObjDlg
Err.Clear
End Sub
event:Private Sub cmdOpen_Click( )
Dim ctl As Control
On Error Resume Next
Set ctl = Me.objOLE
' Open, rather than just activate in place.
ctl.Verb = acOLEVerbOpen
ctl.Action = acOLEActivate
Err.Clear
End Sub - Save your form and run it. When you click
on the Insert button, you'll see the Insert Object
dialog (Figure 12-2). This dialog allows you to
create a new object or to insert one from an existing file. Once you
make your choice, Access places the object into the table and
displays it on the form. When you want to activate the object, click
on the Activate button. For a WAV or MIDI file, this causes your
sound to play; for a Microsoft Graph object, it activates Microsoft
Graph. To open an editing window for the object, click on the Open
button.
Figure 12-2. The Insert Object dialog
12.1.3 Discussion
The Action property for OLE objects in
Access is different from almost any other property, in that setting
its value causes an action to take place. Normally, properties
describe characteristics of an object, and methods cause actions to
take place. In this case, however, when you set the Action property
to the constant acOLEActivate, Access activates
the control at the time you set the property. If you set the Action
property to the constant acOLEInsertObjDlg, Access
displays the modal Insert Object dialog at the time you change the
property. By changing the OLE control's Action
property, the code tells Access what action to take at that point. By
changing the Verb property from acOleVerbPrimary
(to activate the object) to acOleVerbOpen, you
control how the object is opened: in place, or in its own window.Table 12-1 lists the values that
you're likely to use for the Action property. Others
are available, but this list will get you started. For more
information, see the online help topics on the Action and Verb
properties.
Constant | Value | Description |
---|---|---|
acOLECopy | 4 | Same as choosing the Edit Copy menu item. Copies the OLE object onto the Windows clipboard. |
acOLEPaste | 5 | Same as choosing the Edit Paste menu item. Pastes the OLE object from the Windows clipboard into your control. |
acOLEUpdate | 6 | Retrieves the most current data for the OLE object from the application that created it and displays it as a graphic. |
acOLEActivate | 7 | Same as double-clicking the control. You must set the control's Verb property before you can use this Action. |
acOLEClose | 9 | Closes the OLE object and ends the active connection with the application that provided the object. |
acOLEInsertObjDlg | 14 | Displays the Insert Object modal dialog, allowing the user to insert an object. |
for unbound objects on forms. For example, if you have an embedded
Word document, you could use code to activate the OLE object (named
Embedded0 in the following example), set its first
paragraph to bold, and then close the object:
Dim objWord As Object
' Activate the OLE object, using the primary verb.
Me.Embedded0.Verb = acOLEVerbPrimary
Me.Embedded0.Action = acOLEActivate
Set objWord = Me.Embedded0.Object.Application.WordBasic
objWord.StartOfDocument
objWord.ParaDown 1, 1
objWord.Bold 1
Set objWord = Nothing
' Close the OLE object.
Me.Embedded0.Action = acOLEClose
By the way, if you need to play a WAV
file but don't want to embed an OLE object or use
OLE at all, you can use the Windows API sndPlaySound function to do
your work. (This function is aliased as
acb_apiSndPlaySound in
12-01.MDB .) Just insert the following
declarations and constants in a form's module:
Private Declare Function sndPlaySound Lib "winmm.dll" _
Alias "sndPlaySoundA" (ByVal lpszSoundName As String, _
ByVal uFlags As Long) As Long
Private Const SND_SYNC = &H0
Private Const SND_ASYNC = &H1
Private Const SND_NODEFAULT = &H2
Private Const SND_LOOP = &H8
Private Const SND_NOSTOP = &H10
Table 12-2 describes the possible flag values for
the sndPlaySound function call.
Constant | Value | Description |
SND_SYNC | 0 | Plays the sound synchronously and does not return from the function until the sound ends. |
SND_ASYNC | 1 | Plays the sound asynchronously and returns from the function immediately after beginning the sound. To terminate a sound once it's started, call acb_apiSndPlaySound , passing vbNullChar as the first parameter. |
SND_NODEFAULT | 2 | Doesn't play the default sound if the requested sound can't be found. |
SND_LOOP | 8 | The sound continues to play repeatedly until you call acb_apiSndPlaySound with the first parameter set to vbNullChar. You must also specify the SND_ASYNC flag to loop sounds. |
SND_NOSTOP | 16 | Returns immediately with a value of FALSE without playing the requested sound if a sound is currently playing. |
the sndPlaySound function to play the WAV file. If you use the
SND_ASYNC or SND_LOOP flags,
you'll need to call the sndPlaySound function again,
passing the vbNullChar constant as the first
parameter. The following code example is the simplest way to play a
WAV file using the Windows API. You can try this out by loading the
form frmSndPlaySound from
12-01.MDB and pressing the button on the form,
which executes the following code:
Private Sub Button0_Click( )
Dim varSound As Variant
Dim intFlags As Integer
Dim intResult As Integer
Dim strWinDir As String
Dim intCount As Integer
Const conMaxLen = 255
' Find the Windows directory.
strWinDir = Space(conMaxLen)
intCount = GetWindowsDirectory(strWinDir, conMaxLen)
strWinDir = Left(strWinDir, intCount)
' Get the file name, using the common file open dialog.
varSound = acbCommonFileOpenSave(InitialDir:=strWinDir, _
Filter:=acbAddFilterItem(", "WAV Files", "*.WAV"), _
DialogTitle:="Choose a WAV File")
If Not IsNull(varSound) Then
intFlags = SND_ASYNC Or SND_NODEFAULT
intResult = sndPlaySound(varSound, intFlags)
If intResult = 0 Then
MsgBox "Unable to play sound."
End If
End If
End Sub
This example is complicated by the fact that it uses the Windows File
Open dialog to request the name of the WAV file that
you'd like to play (the folder named Media is a good
place to look), but the heart of the routine is quite simple.
12.1.4 See Also
For more information on working with the Windows API, see Chapter 11.