VB.NET loop timer, multiple "IF" conditions - vb.net

Writing the title to try and explain my query I think was harder than the problem I'm actually facing :) - Anyway on to the question.
So I have a 20 second timer but I want two different things to happen on the first and second 10 seconds. Specifically to change the active tab.
So I thought to myself I'll just write an if Statement in the timer tick event that if it = 10 seconds to change to the second tab and when it hits 0 to switch back to the first, then to restart the timer.
Below is my code but nothing happens, I think the problem lies with reading the current remaining time.
Private timeLeft2 As Integer
Private Sub timerCountdown2()
timeLeft2 = 20
End Sub
Private Sub tabTimer_Tick(sender As Object, e As EventArgs) Handles tabTimer.Tick
If timeLeft2 = 10 Then
TabControlVertical1.SelectTab(1)
End If
If timeLeft2 = 0 Then
TabControlVertical1.SelectTab(0)
tabTimer.Stop()
tabTimer.Start()
End If
End Sub
The properties of my timer are enabled = true and Interval = 1000
What am I doing wrong?

You should set the timer to trigger the Tick event every 10 seconds, not every 20 (or 1 as by your edit above).
Every time the Tick event is triggered, you look at the value of a global boolean variable.
If this variable is true you execute the code reserved for the first 10 seconds and invert the value of the boolean. When the timer triggers again, you execute the code for the second case and invert again the value of the boolean
So, somewhere in your code or in the designer set the tabTimer interval to 10 seconds
tabTimer.Interval = 10000
and declare a global boolean variable (In the same forms class probably)
Private tabSwitcher as Boolean = True
Now the Tick event could be written as:
(no need to stop the timer if this process needs to continue)
Private Sub tabTimer_Tick(sender As Object, e As EventArgs) Handles tabTimer.Tick
If tabSwitcher = True Then
TabControlVertical1.SelectTab(1)
else
TabControlVertical1.SelectTab(0)
End If
tabSwitcher = Not tabSwitcher
End Sub

This is what I think you are asking:
do something in 10 timer ticks - timer set to 1000
do something else 10 timer ticks later
repeat
Try this
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Static ct As Integer = 0
ct += 1
If ct = 10 Then
'do 10 stuff here
Debug.WriteLine("10")
ElseIf ct = 20 Then
'do 20 stuff here
Debug.WriteLine("20")
'then reset ct <<<<<<<<<<<<
ct = 0
End If
End Sub

Friend Class timerCtrl : Inherits Timer
Private ReadOnly tickFunc As EventHandler = Nothing
Friend Sub New(ByRef theFunc As EventHandler, ByVal theInterval As Integer, Optional ByVal autoStart As Boolean = True)
tickFunc = theFunc
Interval = theInterval
AddHandler Tick, tickFunc
If (autoStart) Then Start()
End Sub
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
RemoveHandler Tick, tickFunc
End If
MyBase.Dispose(disposing)
End Sub
End Class
Friend Class TabClass
Private timerStep As Boolean = False
Private timerTabs As timerCtrl = Nothing
Friend Sub New()
timerTabs = New timerCtrl(AddressOf timerTabsTick, 10000)
End Sub
Private Sub timerTabsTick(ByVal sender As Object, ByVal e As EventArgs)
timerStep = Not timerStep
If timerStep Then
' condition 1
Else
' condition 2
End If
End Sub
End Class
a simple timer helper class for abstraction. to kill the timer, not just .Stop it, use timerTabs.Dispose(). eliminates the need to detach the event handler separately.

Seems to me that your timer is never getting to the value you are asking for in the if statements due to the fact that you have set the timer to the value of 20.
Also, I've use visual basics and am not to sure but doens't it need to be timeleft2.value?
Also, by stoping and starting the timer, it isn't actually restarting the timer, when you stop it say on 15 secs, and the restart, the timer restarts from 15 secs.
Try this.
If timeLeft2.Value = 10 Then
TabControlVertical1.SelectTab(1)
else if timeLeft2.Value = 0 Then
TabControlVertical1.SelectTab(0)
tabTimer.Stop()
timeLeft2.value = 0
tabTimer.Start()
End If

Related

Open multiple URLs successively in WebBrowser control in VB.NET

I'm trying to make a "rotator" on a form that cycles through a series of urls and displays the url in the WebBrowser control. The following code displays my form, but the form remains white/blank and then the last url in the array appears after a while. When I put a MessageBox in-between each url, to create a stop, it works and each url appears. I've tried putting a Sleep in place of the MessageBox, but that didn't work. I've also tried increasing the Sleep time, but that didn't work either. How can I make it work correctly?
Sub Rotate()
Dim Urls() As String = {"www.stackoverflow.com", "www.google.com", "www.yahoo.com"}
Dim counter As Integer = 0
Form3.Show()
Do Until counter = 3
Form3.WebBrowser1.ScriptErrorsSuppressed = True
Form3.WebBrowser1.Navigate(Urls(counter))
'MessageBox.Show("Next")
counter = counter + 1
System.Threading.Thread.Sleep(2000)
Loop
End Sub
You can call Application.DoEvents after changing the URL so that the control gets the chance to redraw itself.
However, a better approach would be to use a timer which fires every 2 seconds and then change the URL in the event handler so that your UI keeps responsive.
For example setup a new field myTimer in your form, init it in your form's loading event and in the Tick event you call your Rotate method. As Rotate is now called several times, we have to move the counter variable out of the method and make it a field so that we keep its value between the invocations. I usually write C# so hopefully I did not make some typos below :)
Private WithEvents myTimer As System.Windows.Forms.Timer
Private counter As Integer
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
' ... your existing code ...
counter = 0
myTimer = New System.Windows.Forms.Timer
myTimer.Interval = 2000
myTimer.Enabled = True
myTimer.Start()
End Sub
Private Sub myTimerTick() Handles myTimer.Tick
Rotate()
End Sub
Sub Rotate()
Dim Urls() As String = {"www.stackoverflow.com", "www.google.com", "www.yahoo.com"}
WebBrowser1.ScriptErrorsSuppressed = True
WebBrowser1.Navigate(Urls(counter))
counter = counter + 1
If counter > 3 Then myTimer.Stop()
End Sub

Vb.Net Background Worker Updating UI Not Working

I have a background worker that is supposed to be updating a ToolStripLabel with some status messages. However, the updating is not happening, but no errors are being thrown. Here's the code I am using:
Private Sub BackgroundWorker3_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker3.DoWork
BackgroundWorker3.WorkerReportsProgress = True
Dim Counter As Integer = 0
Do Until BW1Running = False
Counter = Counter + 1
Threading.Thread.Sleep(1000)
Incident_Form.BackgroundWorker3.ReportProgress(Counter)
If Counter >= 100 Then
e.Result = False
Return
End If
Loop
If BW1Running = False Then
Counter = 100
Incident_Form.BackgroundWorker3.ReportProgress(Counter)
End If
End Sub
Private Sub BackgroundWorker3_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles BackgroundWorker3.ProgressChanged
Me.ToolStripStatusLabel1.Text = e.ProgressPercentage.ToString
End Sub
Nothing happens when the ProgressChanged is fired. I've debugged it and it'll print a line to the output window, but it will not update that label. Any ideas on what I'm missing?
You're calling:
Incident_Form.BackgroundWorker3.ReportProgress()
instead of just:
BackgroundWorker3.ReportProgress()
Your BackgroundWorker3_ProgressChanged method is subscribed to the ProgressChanged event of the BackgroundWorker located in the current form, not in the Incident_Form form.
Remove Incident_Form from the beginning of the BackgroundWorker3.ReportProgress() calls and you should be good to go.

How to add programatically timer and other controls with source code VB.net

I want to specify in a text field how many timers I want to add to my form and specify the code that should be into the timer.
For instance: My textbox says "2" and then I click a button and it creates two timers and adds a specific source code for both timers.
I have tried different codes and while they worked, I wasn't able to specify the number of controls on a form to create.
How can I achieve this efficiently?
Thanks
Just to create one timer
Public Class Form1
private _timer as Windows.Forms.Timer
...
Public Sub New()
...
_timer = New Timer(Me)
_timer.Interval = 1000 'Timer will trigger one second after start
AddHandler _timer.tick, AddressOf Timer_tick 'Timer will call this sub when done
End Sub
Sub Button_click(sender as Object, e as EventArgs)
_timer.Start() 'Start the timer
...
End Sub
Private Sub Timer_tick(sender as Object, e as EventArgs)
MessageBox.Show("Timerrr!!")
End Sub
...
End Class
Now if you want to create more than one timer, you can use an array of Timer.
In this case, I used a form conatining a NumericUpDown controll element, a button and a label, plus two labels which only contain text.See this picture
To create the timers, I use the function add_timers(timercount), which looks like this:
Function add_timers(timercount As Integer)
'Using a loop to creat <timercount> timers
For g As Integer = 1 To timercount
'Creating new timer 't'
Dim t As New Timer()
'setting interval of t
t.Interval = 1000
'Enabling timer
t.Enabled = True
'Code which runs when t ticks
AddHandler t.Tick, AddressOf TimerTick
Next
End Function
This function gets called when Button1, the start button gets pressed. It uses NumericUpDown1.Value as the parameter for the function. The function uses a loop to create new timers t, sets their intervals and the code to run when they tick.
Unfourtunately, I didn't find a way to dynamically create code, so every timer performs the same action. Using arrays and loops in a clever way might enable you to use different value for each timer. To create code for the timer use a Sub:
Sub TimerTick(ByVal sender As Object, e As EventArgs)
'Add your code here
Label1.Text += 1
End Sub
The complete code I use is:
Public Class Form1
Function add_timers(timercount As Integer)
'Using a loop to creat <timercount> timers
For g As Integer = 1 To timercount
'Creating new timer 't'
Dim t As New Timer()
'setting interval of t
t.Interval = 1000
'Enabling timer
t.Enabled = True
'Code which runs when t ticks
AddHandler t.Tick, AddressOf TimerTick
Next
End Function
Sub TimerTick(ByVal sender As Object, e As EventArgs)
'Add your code here
Label1.Text += 1
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
add_timers(NumericUpDown1.Value)
End Sub
End Class
Packing the timers into an array is possible, that way you can easily access each timer with its index. Serach for it on the internet, and if you then have no idea of how to do it, tell me in the comments.

Detecting mouse moves and key strokes in vb.net

i want that when user is idle for some particular time and mouse doesnot moves on system than it starts counting time from then ownwards and when user moves mouse then time stops and i can save this time in a varianble
You can use the GetLastInputInfo API call.
The following code is mainly from here: http://pinvoke.net/default.aspx/user32/GetLastInputInfo.html
Imports System.Runtime.InteropServices
Public Class Form1
<StructLayout(LayoutKind.Sequential)> _
Structure LASTINPUTINFO
<MarshalAs(UnmanagedType.U4)> _
Public cbSize As Integer
<MarshalAs(UnmanagedType.U4)> _
Public dwTime As Integer
End Structure
<DllImport("user32.dll")> _
Shared Function GetLastInputInfo(ByRef plii As LASTINPUTINFO) As Boolean
End Function
Dim idletime As Integer
Dim lastInputInf As New LASTINPUTINFO()
Public Function GetLastInputTime() As Integer
idletime = 0
lastInputInf.cbSize = Marshal.SizeOf(lastInputInf)
lastInputInf.dwTime = 0
If GetLastInputInfo(lastInputInf) Then
idletime = Environment.TickCount - lastInputInf.dwTime
End If
If idletime > 0 Then
Return idletime / 1000
Else : Return 0
End If
End Function
Private sumofidletime As TimeSpan = New TimeSpan(0)
Private LastLastIdletime As Integer = 0
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Dim it As Integer = GetLastInputTime()
If LastLastIdletime > it Then
Label1.Text = "IDLE STATE CHANGED!"
sumofidletime = sumofidletime.Add(TimeSpan.FromSeconds(LastLastIdletime))
Label2.Text = "Sum of idle time: " & sumofidletime.ToString
Else
Label1.Text = GetLastInputTime()
End If
LastLastIdletime = it
End Sub
End Class
This code displays the seconds the user has been idle since the last input action in the label on every timer tick. It also checks if the idle state has changed. So at this point you can react to it and save the LastLastIdletime as the amount of time in seconds that the user was inactive.
To prevent having to handle this for many controls you can rearrange things a bit and cache the information needed to know if cursor has moved and how long the idle time is, to do this you need a Point variable and a Date variable. The Timer needs to tick all the time. In addition, to balance the cursor Show/Hide calls you need a variable to keep track of its visibility state. Here is the complete code sample:
Private loc As Point, idle As Date, hidden As Boolean
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If loc <> Cursor.Position Then
If hidden Then
Cursor.Show()
hidden = False
End If
loc = Cursor.Position
idle = Date.Now
ElseIf Not hidden AndAlso (Date.Now - idle).TotalSeconds > 3 Then
Cursor.Hide()
hidden = True
End If
End Sub
This Timer can tick each 1/2-1 seconds depending on how responsive you want it, the idle time is set to 3 seconds. The code should be easy to understand when you read it and give it some thought, if not ask

How do I call a function every x minutes in VB.NET?

How do I call a function every x minutes.
I assume I'd have to add a timer to the form?
here is a simple example:
Public Class SampleCallEveryXMinute
Private WithEvents xTimer as new System.Windows.Forms.Timer
Public Sub New(TickValue as integer)
xTimer = new System.Windows.Forms.Timer
xTimer.Interval = TickValue
End Sub
Public Sub StartTimer
xTimer.Start
End Sub
Public Sub StopTimer
xTimer.Stop
End Sub
Private Sub Timer_Tick Handles xTimer.Tick
SampleProcedure
End Sub
Private Sub SampleProcedure
'SomeCodesHERE
End Sub
End Class
USAGE:
Dim xSub as new SampleCallEveryXMinute(60000) ' 1000 ms = 1 sec so 60000 ms = 1 min
xSub.StartTimer
Yes, you could add a timer to the form, and set its interval to x*60000, where x is the number of minutes between calls.
Remember that the timer runs on the UI thread, so don't do anything intensive in the function. Also, if the UI thread is busy, the timer event will not fire until the UI thread finishes whatever event it is currently processing. If your function is going to be CPU-intensive, then consider having the timer start up a background worker
If you require a longer time period between function calls (ie, one thats too big for a timer interval) then you could have a timer function that fires every minute, and increments a counter until the desired amount of time has passed, before going on to call the function.
ALTERNATIVE 1
Here is good guide to use the Timer Control in VB.net.
The advantage is that you don't have to worry about modifying UI objects from non UI thread.
ALTERNATIVE 2
Another alternative is to spawn another thread and do the work and sleep the remaining x minutes.
The advantage here is that if your function doesn't touch UI objects your application will remain responsive to user input while the function is being called
Private Sub Form_Load()
_timer.Enabled = True
End Sub
Private Sub _timer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
ListBox1.Items.Add(DateTime.Now.ToLongTimeString() + "," + DateTime.Now.ToLongDateString())
End Sub