tags:

views:

360

answers:

2

Hello,

C# 2008 SP1

I am using the following code to record, play, and stop save the recording. Everything works fine. However, I would like to add a call back that will fire when the playback has finished.

I am P/Invoke using the winmm.dll library.

Many thanks for any advice.

public partial class SoundTest : Form
    {
        const uint SND_ASYNC = 0x0001;
        const uint SND_FILENAME = 0x00020000;
        const uint SND_NODEFAULT = 0x0002;

        [DllImport("winmm.dll")]
        private static extern int mciSendString(string lpstrCommand, string lpstrReturnString, 
                                                int returnLength, int hwndCallBack);

        [DllImport("winmm.dll")]
        private static extern bool PlaySound(string pszsound, UIntPtr hmod, uint fdwSound);

        public SoundTest()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // Disable stop button
            this.btnSaveStop.Enabled = false;
        }

        private void btnRecord_Click(object sender, EventArgs e)
        {
            // Disable play and record button
            this.btnRecord.Enabled = false;
            this.btnPlay.Enabled = false;
            // Enable stop button
            this.btnSaveStop.Enabled = true;

            // Record from microphone
            mciSendString("Open new Type waveaudio Alias recsound", "", 0, 0);
            mciSendString("record recsound", "", 0, 0);     
        }

        private void btnSaveStop_Click(object sender, EventArgs e)
        {
            // Enable play and record
            this.btnRecord.Enabled = true;
            this.btnPlay.Enabled = true;
            // Disable Stop button
            this.btnSaveStop.Enabled = false;
            mciSendString("save recsound c:\\record.wav", "", 0, 0);
            mciSendString("close recsound ", "", 0, 0);
        }

        private void btnPlay_Click(object sender, EventArgs e)
        {
            //// Diable record button while playing back
            //this.btnRecord.Enabled = false;
            PlaySound("c:\\record.wav", UIntPtr.Zero, SND_ASYNC | SND_FILENAME | SND_NODEFAULT);   
        }
    }
+1  A: 

As far as I can tell, the only way you will be able to do this is by calling a callbackfunction yourself right after you call the PlaySound API function and passing a SND_SYNC parameter instead of SND_ASYNC.

private void btnPlay_Click(object sender, EventArgs e)
{
    //// Disable record button while playing back
    //this.btnRecord.Enabled = false;
    PlaySound("c:\\record.wav", UIntPtr.Zero, SND_SYNC | SND_FILENAME | SND_NODEFAULT);   

    //write your callback code here
}
Peter
+1  A: 

The 'callback' from MCI is actually a windows message. If you pass the handle of your form as the hwndcallback and override the WndProc you can handle the message.

There's some more information on the WndProc here, and a 64-bit friendly dllimport specification here.

marklam