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?
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.
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( ) 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
Attach the following code to the Open button's Click 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.
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. |
This technique works just as well 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. |
Normally, you'll call 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.
For more information on working with the Windows API, see Chapter 11.