Monitor user activity in vb.net - vb.net

I would like to make a program that monitors user activity. I do not need to know what the user is doing, all i need to know is that he is doing something. Moving the mouse, or typing. The program will be used to show to the company who is at the desk and who is gone from the workstation. So if there is no activity for 2 minutes, that means that the user is away from the computer.
I was thinking of using the keyboard hook and the mouse position to monitor changes every lets say 5 seconds. On every change I will reset the counter.
Is there a better way? (For example reading the screensaver countdown or something like that)

You can P/Invoke the WinAPI's GetLastInputInfo() function to be able to get the millisecond count at which point the last input was received since the computer was started.
Subtracting Environment.TickCount with the above will give you how many milliseconds have lapsed since the last input was received:
<DllImport("user32.dll")> _
Public Shared Function GetLastInputInfo(ByRef plii As LASTINPUTINFO) As Boolean
End Function
<StructLayout(LayoutKind.Sequential)> _
Public Structure LASTINPUTINFO
<MarshalAs(UnmanagedType.U4)> _
Public cbSize As Integer
<MarshalAs(UnmanagedType.U4)> _
Public dwTime As Integer
End Structure
Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
Dim LastInput As New LASTINPUTINFO With {.cbSize = Marshal.SizeOf(GetType(LASTINPUTINFO))} 'The "cbSize" field must be set every time we call the function.
If GetLastInputInfo(LastInput) = True AndAlso _
(Environment.TickCount - LastInput.dwTime) >= 120000 Then '120000 ms = 120 s = 2 min.
Timer1.Stop()
'Computer has been idle for 2 minutes. Do your stuff here.
End If
End Sub
This will check for both mouse and keyboard input.
The Timer's Interval property is set to 5000 to make it check every 5 seconds, and the Enabled property is set to True.
Keep in mind that you must restart the timer after the two minutes of idle time have lapsed if you want it to check again.

Related

Visual Basic: Image moves up and and then back down after a button click

I am attempting to make a character appear to jump straight up in the air and then come back down and return to the same level he started at. (y=100) The code below seems to make the program fight itself and move him up and down at the same time.
I have tried countless methods and all of them resulted in the guy either going up and not coming back down or flying off the page.
Private Sub btnJump_Click(sender As Object, e As EventArgs) Handles btnJump.Click
tmrJump.Start()
End Sub
Private Sub tmrJump_Tick(sender As Object, e As EventArgs) Handles tmrJump.Tick
For intCounterUp As Integer = 100 To 15
picSpaceRunner.Location = New Point(intCounterX, intCounterY)
intCounterY = intCounterUp
Next intCounterUp
For intCounterDown As Integer = 15 To 100
picSpaceRunner.Location = New Point(intCounterX, intCounterY)
intCounterY = intCounterDown
Next intCounterDown
End Sub
End Class
The code is running with no delay, so you're at the mercy of the machine.
I'm not a professional game coder, so I couldn't explain the intricacies of modern game engines. However, one of the basic ideas I learned a long time ago is to control your game/animation loop. Consider the frames per second.
In your code, it could be as simple as adding a delay within each loop iteration. If you want the character to complete his jump in 2 seconds (1 second up, 1 second down), then divide 1000 (1 sec = 1000 ms) by the number of iterations in each loop and delay by that amount. For example, you have 85 iterations, so each iteration would take approximately 12 ms.
If you don't mind blocking a thread, you can do this very easily with Threading.Thread.Sleep(12). If blocking is an issue, you'll likely want to use an external timer.
I found this link during a Google search. He explains how to set up a managed game loop in VB.Net.
http://www.vbforums.com/showthread.php?737805-Vb-Net-Managed-Game-Loop
UPDATE: Per OP's comment...
To do this using timers, you'll want to manipulate the character object directly within the Timer event handler (Tick). You wouldn't use loops at all.
Set the Timer's Interval to the value discussed earlier - the number of ms corresponding to how long it takes to move 1 pixel. Then, in the Timer's Tick handler, set the character object's Location equal to a new Point with the new value. Also in the Tick handler, check your upper bound (15), then reverse the process until it hits the lower bound (100).
For example,
Private Sub tmrJump_Tick(sender As Object, e As EventArgs) Handles tmrJump.Tick
If (intCounterY > 15 And blnGoingUp == True) Then
picSpaceRunner.Location = new Point(intCounterX, intCounterY - 1);
End If
... Remaining Code Goes Here ...
End Sub
Do not put the loop in the timer_tick. Increase or decrease the height by set interval instead and then check if the image had reached the maximum or minimum height.

Why is basic time/date output taking two seconds to display?

What I have:
I'm displaying the current time and date (real-time) at the bottom of a form using a timer element.
I'm using two labels to display the time and date respectively.
What I need:
I need the time and date labels to display as instantly as everything else.
My problem:
There is a two second delay in the displaying of the time and date labels.
My code:
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
'Format time and date labels.
TimeMain.Text = Format(Now, "hh:mm:ss")
DateMain.Text = Format(Now, "dddd, d/MM/yyyy")
End Sub
Note: The above is preceded by a Form_Load sub that simply defines a default accept button. The above is followed by 5 by five short subs.
Edit:
Though the steps for reproducing the problem have already provided in the comments I've been requested to reiterate here. The only difference between the two code blocks posted in this question is that I've left the label text at default to spare the reproducer having to type anything.
Drag two labels and a timer onto a new form and use the following code:
Public Class Form1
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
'Format time and date labels.
Label1.Text = Format(Now, "hh:mm:ss")
Label2.Text = Format(Now, "dddd, d/MM/yyyy")
End Sub
End Class
For the timer's properties, Enabled is defined as True and Interval as 1000.
I know this isn't exactly an answer but this is too long to fit in a comment. Also read here for a little more information on timers:
Why are .NET timers limited to 15 ms resolution?
Does the System.Windows.Forms.Timer run on a different thread than the UI?
Timer elapsed events from what i understand (which could very well be wrong) aren't guaranteed to fire exactly when the time has elapsed, it's more of... put it in queue to fire once the timer has elapsed.
Imagine your application/timer started at "00:00:01.999" and your label states "00:00:01" as the current time.
Exactly 1000 MS later you're at "00:00:02.999 and the elapsed event fires, completing at "2014-01-01 00:00:03.0045" and your label is updated to "2014-01-01 00:00:03" - you've already "lost" a second here.
You could try setting your interval to something lower than one second (say 750) which would get you a potentially more accurate looking counter. Additionally, ensure you're setting the timer labels on form load. I've not worked very much with timers and i'm having trouble finding the article i was reading earlier but you might need to worry about UI locking depending on the timer type used (there are apparently 4 timer classes in the .net framework.) Perhaps someone else can expand on that though, I don't know much about winforms.

How can I get a program to run automatically at specific times a day (VB.NET)

The application I'm developing right now allows the user to update an Excel sheet or Sql database for set metrics twice a day. The program does this by popping up at certain times (e.g. 6:00 AM, 5:00 PM, 3:42 PM, whatever the user sets). By having the program pop up at certain times, the program ("Auto Excel It!!!") allows you as the user to track set data (say, sales calls, sales presentations, meetings, number of hours coding, number of jalepeƱo burritos eaten, etc.).
How can a developer get this program to "pop up"/start/function automatically at specific times through the means of the Windows Scheduler API (or something better)?
Here's how my understanding's evolved lately:
Nothing --> Use Timers As The Program Runs In The Background --> Use Windows Scheduler's API To Run Automatically (Current) --> Possible New Understanding From Your Answer
For example, I'm aware of: DispatcherTimers, Timers, another timer I'm not aware of, Sleep(), Windows Scheduler. But with these in mind, I don't know what to do regarding the following: Automatically starting a program via Windows Scheduler; Preserving computer resources if a timer is used; or even how to get this top pop up automatically.
Update 1:
#nfell2009:Your logic helped me out big time. At first I had to toy around with converting your Timer here to a DispatcherTimer (WPF forms standard, it seems). Then, I switched the the "Handles" for the Sub tCheckTime to "AddHandler tCheckTime.Tick, AddressOf tCheckTime_Tick" --- Why I had to do this is a good question.
Then, once I had the basic EventHandlers set up, your idea for comparing the user's text (As Date) to the System.Date is good--When I screwed something up and couldn't get the code to work, I switched it up and converted System.Date to a String--i.e. I went from String->Date To Date->String... That's when I got the Timer to work. When my System.Time ticked to 3:12 PM, the MsgBox popped up with "Your Message Here."
(A Quick (Evil) Thank You! I've spent four-plus hours getting this to work)
Code:
From Using "Handles" At tCheckTime_Tick (Which seems like it 'should' work)
Private Sub tCheckTime_Tick(sender As Object, e As EventArgs) Handles tCheckTime.Tick
...
End Sub
To AddHandler blah, AddressOf tCheckTime_Tick (Does work)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Loaded
'MsgBox(Now().ToString("hh:mm")) 'String.Format("{hh:mm}", Now()))
AddHandler tCheckTime.Tick, AddressOf tCheckTime_Tick 'Why is this necessary?
tCheckTime.Interval = New TimeSpan(0, 1, 0)
End Sub
Public Class Form1
Dim iSetTime As Date
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub btnSetTime_Click(sender As Object, e As EventArgs) Handles btnSetTime.Click
If (tCheckTime.Enabled = True) Then
tCheckTime.Enabled = False
End If
iSetTime = txtTHour.Text + ":" + txtTMinute.Text + ":" + txtTSecond.Text
tCheckTime.Enabled = True
End Sub
Private Sub tCheckTime_Tick(sender As Object, e As EventArgs) Handles tCheckTime.Tick
If (TimeOfDay = iSetTime) Then
MsgBox("Your Message")
End If
End Sub
End Class
You will need error checking for the textboxs, but its simply:
3 textboxs with indication of which is which, so maybe a label each with H, M, S - or something.
A button which will set time and a timer. Naming:
Textboxs
Hours = txtTHour
Minutes = txtTMinute
Seconds = txtTSecond
Buttons
Start Button = btnSetTime
Timers
Timer = tCheckTime
I can think of two easy ways:
Have your program calculate the time until it should next appear in seconds and then set a timer with an elapsed time such that when the tick event is raised you can do whatever you need to do.
Use MS Task Manager to launch your program when and as needed.

detect system date change, visual basics

I am writing an application on Windows-7 using Visual Basics 2010. I am accessing System Date with
Dim today As Integer
today = Format(Now, "dd")
Well, that works fine. But I need some indication/notification when system date changes, so that I can retrieve the new date. Is there any function/way to achieve that ?
Thanks
The system date may change for two reasons:
The user manually changed the system date/time. This can be detected using the method described here: http://vbnet.mvps.org/index.html?code/subclass/datetime.htm
Time passes, the clock goes from 23:59:59 to 00:00:00. I'm don't know of any system event that will tell you when this happens, but you can detect it easily by using a Timer in VB6. By using a Timer you will get an event at a predefined interval. You might then check, say everey minute, if the date has changed.
To use the standard VB6 Timer control, you need a Form on which you put your Timer, but there are other alternatives, like this one: http://www.codeproject.com/KB/vb-interop/TimerLib.aspx
My code example uses the standard VB6 Timer on a Form to watch for "change in minute". My Timer control has the original name of Timer1
Dim iMinute As Integer 'The "current" minute
Private Sub Form_Load()
'Initialize
iMinute = Format(Now, "n") 'Get the current time as minute
Timer1.Interval = 1000 'Set interval = 1000 milliseconds
Timer1.Enabled = True 'Start Timer1 (my Timer)
End Sub
Private Sub Timer1_Timer()
'This happens when the given Interval has passed (in this case, every second)
Dim iMinuteNow As Integer
iMinuteNow = Format(Now, "n")
If iMinuteNow <> iMinute Then
MsgBox "You are now in a new minute"
iMinute = iMinuteNow
End If
End Sub

Visual Basic - Reset at 00:00

I've got an question about resetting a label every night at the same time.
What do i mean:
1. when starting the program my label.text = 750
every time someone clicks a button the label text reduces with 1 so
750
749
748 etc etc
but now i want that every day at 00:00 the label's text resets to 750.
is that possible??
Javed Akram's comment is correct -- none of this is going to matter, if the program isn't running at midnight.
However, for what you actually asked for - resetting a count at midnight - consider adding a TIMER to your project. You really only need the timer to click once a day (at midnight):
Private Sub SetInterval()
' Calculate how many milliseconds until the timer ticks again:
' Start by calculating the number of seconds between now and tomorrow.
' Multiply by 1000, then add 50 more -- this is to make sure that the
' timer runs 1/50 of a second AFTER midnight, so that we can
' re-calculate the interval again at that time.
Timer1.Interval = CInt( _
DateDiff(DateInterval.Second, Now, Today.AddDays(1)) * 1000 + 50)
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Timer1.Tick
' Reset the interval, so that we run again tomorrow at midnight.
SetInterval()
' Now, reset your label
Label1.Text = "750" ' Or whatever else needs to happen to reset the count
End Sub
You'll also need to add a call to SetInterval in Form_Load (or whatever your program initialization is), to set up the very first interval.
On an almost completely UN-related note, does anyone know why the Date class has an AddMilliseconds function, but Microsoft.VisualBasic.DateInterval (and therefore the DateDiff function) doesn't have Milliseconds? It's non-symmetrical.