Timer and SendKeys Problem

mjb3030

Regular
Joined
Aug 14, 2003
Messages
76
I have a form with one textbox and a timer on it. Other than the Form Designer generated code, this is all that is in my form:

Visual Basic:
    Private AllowKeys As Boolean

    Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) Handles TextBox1.KeyPress
        If Not AllowKeys Then
            e.Handled = True
        End If
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        AllowKeys = False
        Timer1.Start()
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        AllowKeys = True
        SendKeys.Send("hello")
        AllowKeys = False
    End Sub

If I try to type in the TextBox, nothing appears, which is as it should be. But, I would expect the word 'hello' to appear in my textbox every 5 seconds (the timer is set to 5000). But, it does not. Also, if I add a break point at either the Timer1_Tick event or the TextBox1_KeyPress event, the application will actually lock up when the timer event hits! I am assuming that it has something to do with the fact that it is a timer doing the sending. Why is this happening? Is there some way around it while still using SendKeys?
 
First off, you will have to make sure that your textbox has focus or else your just sending keys to the form.

I'm NOT sure if this will work, but you can try it:

Visual Basic:
' change the following to contain an else and restart timer

Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) Handles TextBox1.KeyPress
        If Not AllowKeys Then
            e.Handled = True
        Else
            Timer1.Start()
        End If
End Sub

' change the tick handler to stop the timer

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Timer1.Stop()
        AllowKeys = True
        SendKeys.Send("hello")
        AllowKeys = False
End Sub

' --------------------------------------------------------------------------
' or you can just change to this

Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) Handles TextBox1.KeyPress
        e.Handled = True
End Sub
' this will cause it to flash
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        If AllowKeys Then
               TextBox1.Text = "hello"               
        Else
               TextBox1.Text = ""
        End If
        AllowKeys = Not AllowKeys
End Sub

Also from what you have, I don't see how the text will flash because you never clear it out after you set it.
 
Thank you for your help. Unfortunately, that didn't work.

Yes, the textbox does have the focus because it is the only control on the form. I also added a TextBox1.Focus line just to be sure.

I made the changes you suggested, and it still did the same thing. I also tried using TextBox1.ReadOnly to control when it could be input instead of using the Boolean flag and the Keypress event. That didn't work either.

I am not trying to make the text flash. This little program was created only to solve this problem. I have a larger, more useful program for inputting tire treadwear data ( I work for a tire testing company ) in which I am encountering this problem. The data is coming from a depth probe plugged into the serial port. The timer is reading data from the probe. I don't want people to be able to type data into the textboxes. I tried just setting the Text property, but I had a lot of problems with events not firing when necessary in order to handle validation and moving from one textbox to the next. I don't remember exactly what the problems were now. But, it's starting to look like I am going to have to go back and work out those problems because the SendKeys method is beginning to look like less of an option.
 
hmmm, a readonly TextBox is just a Label. Nobody can type into a Label

Visual Basic:
' every 5 seconds update text in label
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Label1.Text = "hello"
End Sub

Also you can change the BackColor of the label to white so that it looks like a TextBox.

One other thing I would try:
Visual Basic:
Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) Handles TextBox1.KeyPress
        If Not AllowKeys Then e.Handled = True
End Sub

' change the tick handler to stop and start the timer

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Timer1.Stop()
        AllowKeys = True
        SendKeys.Send("hello")
        AllowKeys = False
        Timer1.Start()
End Sub
Good Luck!
 
Last edited:
I have had many troubles while trying to issue sendkeys in previous VB versions. Whenever I wished to move focus to the next control, I used sendkeys("{TAB}"). but now, there is SelectNextControl method, wich is much more reliable.
 
If I read the above problem correct, you have a timer running and try to update the text box in the Tick event of the timer.

What the timer does (without you seeing it) is creating a new thread that is used when the timer expires (and calls the Tick event). Next you try to set text from that thread which wont work and lead to all sorts of problems you have already encountered. Basicly the rule is that anything userinterface related should be handled from a user interface thread.
Read the lasts 2 posts in this thread:
http://www.xtremedotnettalk.com/showthread.php?t=87775&highlight=thread+begininvoke
or this thread:
http://www.xtremedotnettalk.com/showthread.php?t=87251&highlight=thread+begininvoke

Both threads deal with what you have to do to update the user interface if you work in another thread (like the timer).

Secondly:
Why do you use sendkeys and dont you just set the text property? A lot less can go wrong with that (although the threading story above still holds). You can even make the text ReadOnly (property of the textbox) so you dont have to use a construction with AllowKeys.
When it comes to using timers and multithreading Murphy's law basicly strikes 2 x as fast (everything that can go wrong will go wrong, anything that can't go wrong, will still go wrong), so the simpler and less if statements you use, the better.
 
Thank you!! You have solved my problem. Actually, I've had this same problem in the past with other projects also. So, you have solved several problems. I was not aware of the thread/control issue.
 
Back
Top