1

I have a timer that each time displays a message box saying "Hello." I also have the code configured so whenever the window loses focus, it should stop the timer that keeps the boxes coming. However, they keep coming.

I have tried a similar thing in a similar program with way too long of code to post here, but what it did was it paused the first time, stop the timer, and when the timer was stopped again, it didn't work correctly. There was also some other code there that had a random element, that displayed a different prompt when a certain number was generated, but once it was generated, it kept using that same different prompt every time.

Is this a error of not enough time to process all the code and it "overlaps" some? I can delay the timer without that much different effects, but I think that my [lower end] CPU that it is running this program on, that with 1.6 GHz that it could handle a timer with a few message boxes. Though, VS is running at the same time, but I shouldn't have to export my code and close VS everytime that I need to test it.

If the problem is not enough time, is there a way that I can prevent my program from "multithreading" or whatever it is doing? It seems like a weird problem, but computers are very weird too. :P

Edit:

By "Focus" I mean the selected window that is the most apparent. For example, my browser is now "focused." I have been informed that the correct term is "selected." I must have been using the wrong type of event trigger... :P

Anonymous Penguin
  • 2,027
  • 4
  • 34
  • 49

2 Answers2

4

It doesn't generate a lost-focus event because the form doesn't have the focus in the first place. A control on the form always gets the focus, like a Button or TextBox. You could use the Deactivate event instead.

Or just not display the message box when the Tick event fires again. Roughly:

Private ShowingMsgBox As Boolean

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    '' Do stuff
    ''
    If Not ShowingMsgBox Then
        ShowingMsgBox = True
        MsgBox("yada")
        ShowingMsgBox = False
    End If
End Sub

The underlying reason for this behavior is that MsgBox pumps a message loop. It keeps normal Windows messages getting delivered, like WM_PAINT that keeps the windows painted. And WM_TIMER, the one that generates the Tick event. The only kind of messages that it blocks are input events, mouse and keyboard messages. Otherwise the reason that Application.DoEvents() is so very dangerous. It does the same thing as MsgBox() does, without disabling input.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • I am not sure if I am the only one misunderstanding your statement, but seems like you are saying that the form never gets the focus. This approach of triggering a MessageBox on Form losing focus is not excessively reliable but theoretically there shouldn't be any problem with it. Because the OP does not want the Form to lose the focus, but just to understand if a MessageBox does not trigger this event. – varocarbas Sep 25 '13 at 22:36
  • Yes, that's what I'm saying. Focus and activation are not the same thing. The form's Focused property will never be true if the form has any control that can receive the focus. The code in your answer cannot work. Doesn't compile either, just try it by yourself. – Hans Passant Sep 25 '13 at 22:42
  • Why are you saying that? I have tested it (I test all the codes I post here). Because of the MsgBox? I was doing some experiments but it works fine (with Option Strict Off at least). I create a blank form and both MessageBoxes are being triggered without any problem. – varocarbas Sep 25 '13 at 22:43
  • Because Focus is a method, not a property. The property name if Focused. – Hans Passant Sep 25 '13 at 22:45
  • ah! LOL. Sorry. Bug (but the tested version was fine) – varocarbas Sep 25 '13 at 22:46
  • Well... actually it does also work with focus (permissiveness of VB.NET) – varocarbas Sep 25 '13 at 22:47
2

Create a new project with a Timer (Timer1) and write this code:

Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick

    If (Me.Focused) Then
        MessageBox.Show("Hello")
    End If

End Sub

If you put the mouse over your form, you would see that a message box will popup after the given Interval is over. If you don't click on the accept button and keep the mouse on the form, you would see that no further messages appear: Me.Focus is False. If you click on the accept button, the messages would start poping up; you don't even need to select the form (the focus is transferred automatically from the MessageBox to the Form).

Summary: the MessageBox does make the Form to lose the focus, although it is a kind of a "tricky" lost as far as will automatically come back after clicking on the accept button.

UPDATE: the proposed configuration does trigger a LostFocus event of the form:

Private Sub Form1_LostFocus(sender As Object, e As System.EventArgs) Handles Me.LostFocus
    MsgBox("lost")
End Sub

Unlikely the other answers/comments, what I understood from your question is that you want to know the reason and if this is a normal behaviour, rather than getting a working solution to make the form to lose the focus (you are not even describing the exact conditions under which you want this to happen).

varocarbas
  • 12,354
  • 4
  • 26
  • 37
  • So is lost focus the mouse? I was more referring to the way that Windows makes the focused window more apparent. – Anonymous Penguin Sep 25 '13 at 22:48
  • @AnnonomusPerson There is always a "selected" window/control, this is the one with the focus. It is highlighted in different ways depending upon the properties/conditions. What you want exactly? – varocarbas Sep 25 '13 at 22:50
  • I should have made this more clear. I want to know when the form loses "selection." I must have been using the wrong property. By focus I mean that it is the more apparent looking window: usually sharper colors that only one is. – Anonymous Penguin Sep 25 '13 at 22:52
  • @AnnonomusPerson this is focus. But bear in mind that you have focus of the form with respect to all the other windows of the running programs (only one can get the focus) and within the controls in the form (again only one can get the focus), as explained by Hans Passant. If you do what I suggested (new form + timer + code), you would get the messageBoxes getting the focus and the form being turned gray. This is not what you want? – varocarbas Sep 25 '13 at 22:55
  • This is what I want. Thank you. Sorry for the confusion there, but I guess I should've looked up the difference, but I didn't know there were different ones. :P – Anonymous Penguin Sep 25 '13 at 22:57