0

So, I've made an iterative Towers of Hanoi algorithm in Visual Basic, that runs in a while loop (recursion is slow in VB). The catch is it compiles okey, it even runs okey when launched through Visual Studio, but when launched though the Debug and Release generated execs the animation stops with the following message:

enter image description here

After a while, I just see all the pieces moved to the destination pole and the message disappears. So its not a crash per say, as the application is still running in the background, its just this message that pops out, ruining the animation. I just want my program to run just as it runs when launched directly from Visual Studio.

After a bit of thinking ... I'm starting to believe this happens because Win7 treats the fact the application runs in a while loop as unresponsive (7 pieces in Towers of Hanoi ca take a while to rearrange), therefore it tries to close it.

How can I just make my application ignore Window's advertisements ?

  • If you click "Wait for the program to respond", does it eventually do so? – Cody Gray - on strike May 21 '14 at 05:46
  • Nope, the advertisement message disappears but the app's window remains gray. If I wait a while I just see all the pieces rearranged on a different pole. –  May 21 '14 at 06:02

1 Answers1

0

I suggest that you do the calculation in the application idle event just like you do when creating a windows game. This way you ensure that the message queue is not blocked.

Public Class Form1

    Public Sub New()
        Me.InitializeComponent()
        AddHandler Application.Idle, AddressOf Me.OnApplicationIdle
    End Sub

    Private Sub OnApplicationIdle(sender As Object, e As EventArgs)
        Static rnd As New Random()
        Dim message As MSG = Nothing
        Do While (Not PeekMessage(message, IntPtr.Zero, 0, 0, 0))
            '...
            Me.BackColor = Color.FromArgb(rnd.Next(0, 256), rnd.Next(0, 256), rnd.Next(0, 256))
            '...
        Loop
    End Sub

    <DllImport("user32.dll", CharSet:=CharSet.Auto)> _
    Friend Shared Function PeekMessage(<[In](), Out()> ByRef msg As MSG, ByVal hwnd As IntPtr, ByVal msgMin As Integer, ByVal msgMax As Integer, ByVal remove As Integer) As Boolean
    End Function

    <StructLayout(LayoutKind.Sequential)> _
    Friend Structure MSG
        Public hwnd As IntPtr
        Public message As Integer
        Public wParam As IntPtr
        Public lParam As IntPtr
        Public time As Integer
        Public pt_x As Integer
        Public pt_y As Integer
    End Structure

End Class
Bjørn-Roger Kringsjå
  • 9,849
  • 6
  • 36
  • 64
  • The `Application.Idle` event is only raised when the application is idle. There is no reason for you to process messages. If you're going to use `PeekMessage`, you might as well do it some place else. It will still keep the application responsive. That will keep you from leaking memory, since you fail to detach the event handler for `Application.Idle` in the code shown, a common mistake. – Cody Gray - on strike May 21 '14 at 05:48
  • @CodyGray Do not use `Application.DoEvents()`. Why? Read this SO post: [Use of Application.DoEvents](http://stackoverflow.com/questions/5181777/use-of-application-doevents). And here's a post explaining why/how you should use `Application.Idle`: [What is the standard C# / Windows Forms game loop?](http://gamedev.stackexchange.com/a/67652/45466) – Bjørn-Roger Kringsjå May 21 '14 at 17:44
  • Uh, when did I recommend the use of DoEvents? I've written countless answers and comments on this very site arguing against it. – Cody Gray - on strike May 22 '14 at 07:26
  • @CodyGray Ops, I've mistaken you with OP. My comment were in response to his/her answer. Sorry. – Bjørn-Roger Kringsjå May 22 '14 at 15:01