views:

121

answers:

1

I've written a simple application for WinMo 6.x to entertain my daughter. It holds a set of animal image to animal noise pairs and randomly displays one of the images. When the image is clicked the animal noise plays and the two year old is distracted :-) and then the next image is displayed.

However, since she tends to bash at the screen the actual flow is that the image displays and she clicks several times; several animal noises are played and then the image changes to the next random animal.

My guess is that the OS is queueing the click events while the program is blocking as it plays the noise and then processing them as soon as it can. In much the same way as you can carry on typing while your machine hangs and the text displays when everything clears again.

So the form has two variables

Private thisCollectionOfThings As ObjectStore
Private currentObject As RealWorldObject

ObjectStore is a wrapper class around a List(Of RealWorldObject) that has a getNextObject method that returns a random RealWorldObject having checked that particluar pair hasn't been returned recently.

In the form we have...

Private Sub picBox_Click(ByVal sender As Object, ByVal e As EventArgs)
            RemoveHandler picBox.Click, AddressOf picBox_Click
            picBox.BackColor = Color.Gray
            If currentObject.getSoundLocation() <> "" Then
                currentObject.playSound()
                refreshScreen()
            End If
End Sub

Private Sub refreshScreen()
    picBox.Image = Nothing
    currentObject = thisCollectionOfThings.getNextObject()
    If Not currentObject Is Nothing Then addImage()
    AddHandler picBox.Click, AddressOf picBox_Click
End Sub

Private Sub addImage()
    picBox.Image = New Bitmap(currentObject.getImageLocation())
End Sub

You can see I've resorted to trying to remove the event handler to try and avoid the click queueing issue but it isn't working.

Any advice on how to avoid this would be super-appreciated... Otherwise I'll try writing my own wrapper around the picture box control to try and handle the click but I'm loathe to use up my time if someone else's experience suggests that wouldn't help.

+1  A: 

I'd go for simplicity (KISS):

  1. Use a boolean value called something like "IsPlaying" and set it to true right before you play the sound and false after it's done.
  2. Put the audio playing in a background thread so the UI remains responsive.
  3. If that boolean is true, ignore screen taps in the click handler.
ctacke
Sorry, should have been clearer... my initial approach was exactly that... but I replaced it with the add/remove handler when that wasn't working.I guess you're right that I should be putting the audio into a separate thread instead of being lazy.In fact I guess you are completely right. Since my guess is that the problem is due to an unresponsive UI I should be fixing that.
Paul D'Ambra
Without the thread, the boolean will do nothing, as the OS will queue the click events long before they are handed off to your app. It's the same reason removing the event handler does no good.
ctacke
popped in threading last night and it almost resolved the issue. The tail of multiple clicks were still picked up (I'm guessing the UI was blocking briefly as it took control back from the thread) so I added a timer that started when the thread returned that stopped itself and set the isPlaying flag back to false. Everything is wroking as I want now. Thanks for reminding me to KISS
Paul D'Ambra