August 1998

Wave-out messages

by Kent Reisdorph

Windows defines three messages for wave output devices, as described in Table A.

Table A: Windows wave-out messages
Message Description
MM_WOM_OPEN The device has been opened.
MM_WOM_CLOSE The device has been closed.
MM_WOM_DONE The device has finished playing

Of these messages, you'll usually care only about MM_WOM_DONE, which tells you when the buffer has finished playing. You need to know when the buffer is finished so you can perform cleanup chores. The MM_WOM_DONE message is sent either when the sound finishes normally or when the sound is interrupted. (To stop playback of the sound once it's started, call the waveOutReset function.)

As we mention in the accompanying article, you can use a callback function rather than having Windows send messages to your window procedure. According to the Multimedia Programmer's Reference (MMEDIA.HLP), the notification messages sent to the callback function have slightly different names: WOM_OPEN, WOM_CLOSE, and WOM_DONE, respectively. It doesn't matter which set of constants you use, though, because they contain exactly the same values.

 

Catching wave-out messages

In order to catch the MM_WOM_DONE message, you need to implement a message map. You can do so with C++Builder's MESSAGE_MAP macro. We've discussed handling custom messages in past journals, but you can probably benefit from a refresher course. The first step in implementing a handler for a particular message is to declare a generic message-handling function. Next, add a message map to your class declaration. The following example shows the pertinent parts of a main form's class declaration, which implements a message map entry for the MM_WOM_DONE message:

 

class TForm1 : public TForm
{
// things omitted
private:  
  void OnWaveDone(TMessage& msg);
public:
  __fastcall TForm1(TComponent* Owner);
  BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER(
      MM_WOM_DONE, TMessage, OnWaveDone)
  END_MESSAGE_MAP(TForm)
};
Finally, you need to define the OnWaveDone function in your source unit. The empty OnWaveDone function is as follows:
void TForm1::OnWaveDone(TMessage& msg)
{
}