Keeping track of the active form and control
When I first thought to the possible solutions, I remembered an old VB5/6 application that needed to shut down every night. To enable this feature, I was keeping track of the active form and active control every 30 seconds. If one of these 2 was modified then that was meaning that the user was still using the application and I was resetting a variable. If nothing was modified for 5 minutes, I simply shut down the application.
This method is still valid using .Net.
The required code
This code is very simple. Every time the timer triggers the Tick event (every second in the demo application but should be longer in a real application no to use too much resources), you need to check the current form and the current control. You could also check the value but then you would need to compare different properties based on the control class (ie: Text for a TextBox, Checked for a CheckBox ...).
I have created a form that contains the Timer control, that is doing all the comparison and which terminates the application if required. This form is named fTimer1.
To retain the active form and control name, I declare static variables. If you are not familiar with them, you may think of them as having the same scope as a class level member (they will exist and keep their value as long as the instance of the class is in memory) but is only visible from within the method in which they are declared. So here is the variables’ declaration:
Static sstrPreviousForm As String = String.Empty Static sstrPreviousControl As String = String.Empty Static sdtmLastAction As DateTime
Dim strCurrentForm As String If ActiveForm IsNot Nothing Then strCurrentForm = ActiveForm.Name Else strCurrentForm = String.Empty End If Dim strCurrentControl As String If ActiveForm IsNot Nothing AndAlso ActiveForm.ActiveControl IsNot Nothing Then strCurrentControl = ActiveForm.ActiveControl.Name Else strCurrentControl = String.Empty End If
We now have everything to compare current and previous values using this code:
If (strCurrentForm <> sstrPreviousForm) OrElse (strCurrentControl <> sstrPreviousControl) Then sstrPreviousForm = strCurrentForm sstrPreviousControl = strCurrentControl sdtmLastAction = Date.Now Label1.Text = sstrPreviousForm Label2.Text = sstrPreviousControl End If
We are now ready to calculate the elapsed time since the last time an action was detected. The DateDiff method is the easiest way to handle that task. This method requires that you pass an interval (the unit used for the calculation, ie: seconds, minutes, days, months ...) and the 2 dates to on which you want to do the calculation. In my case, I wanted the result to be calculated in seconds:
Dim intSeconds As Int64 = DateDiff(DateInterval.Second, sdtmLastAction, Date.Now)
Label3.Text = intSeconds.ToString + " seconds since last activity detected."
If intSeconds > 30 Then Application.Exit()
Using the timer form
The last thing you want to do is to put this logic into each form your application contains. That’s why the timer form should be self contained. You only need to load it once in an application. For example, your main form can load a new instance of this form like this (its Load event is a good place):
Dim x As New fTimer1
For testing/debugging purposes, you can also make the timer form visible (but it is not required to have it working properly):
x.Show()
Figure 1: The demo application in action
The Application’s Idle event
After I have completed the previous example, I remembered that the Application object provides an Idle event. After a quick test, I was convinced that it wasn’t really good for me. In the downloadable demo, I have provided my test forms that are using this event and I have never been able to get it to work properly. If you find a way, drop me a note!
Conclusion
I thought that this feature could be helpful for some of you.
I hope you appreciated the topic and see you next month.