VB.NET - need to detect inactivity in program with multiple forms - 500pts

Posted on 2006-05-07
Medium Priority
Last Modified: 2008-01-09
Hello Experts,

This seems to be a somewhat common task based on my searches, but I have not found a solution that I have been able to get working propely.  I am trying to implement a feature where if the program is idle, the "home page" is launched  --essentially, this is a screensaver feature for my program.  This application will run on a touch-screen kiosk, so I am mainly concerned with detecting "mouse" inactivity.  The most straightforward way of doing this appears to be through the Windows API, but I haven't been able to get those implementations to work.

I need to be able to disable and enable the inactivity feature at will.  ( I want to disable it while the user is recording a video,  which is one of the features of my program, but then reenable it.  --there is a seperate timer used on the video recording feature).

One problem I have encountered  is related to the use of the on screen keyboard which I have implemented.  I discovered that the keyboard would not send values to the form that it was located on, so what I ended up doing was creating a dedicated, small little form for the on screen keyboard.  The on screen keyboard form is then drawn on top of the form in which I need the data to be entered on, which solved the issue with the keyboard form not being able to send keystrokes to itself.  This workaround seemed to cause problems with my inactivity timer though (inactivity was not detected properly with both of the forms on the screen at the same time).  Because of this issue, I was thinking that the API function would be better for solving my idle time issue.

I am a beginner at programming, so I am looking for the exact code I would need to use.

some of the topics I have looked at that have not panned out for me are:



Thank you,


Question by:SINEtist
  • 3
  • 3
  • 2
  • +1
LVL 86

Accepted Solution

Mike Tomlinson earned 2000 total points
ID: 16625971
Since this is a kiosk, and most likely only your application is running, is it safe to say that ANY mouse/keyboard activity is related to your app?

If so, you can use a low level keyboard and a low level mouse hook to detect this activity.  You can simply reset a Timer each time any keyboard/mouse activity is detected.

Low level keyboard hook:

Low level mouse hook:

Note that if you are using VB.Net 2005, the hooks do NOT work in the IDE but only in the release version of the application.

Author Comment

ID: 16626102

Q: Since this is a kiosk, and most likely only your application is running, is it safe to say that ANY mouse/keyboard activity is related to your app?
A: yes, that is correct.

I implemented the low level mouse hook from the link you provided.  I added a class to my project and pasted in the code.  I get 1 error, which occurs at the following line of code:

     Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32, 0)

Error: "Name 'Marshal' is not decalred."

I have seen other solutions, some I'm pretty sure were even provided by you, that other people seem to have no problem with, but I always get that same error whren trying to use the "Marshal" thing.  I say 'thing', because I'm really not sure what to call it.

Assuming that the 'Marshal' issue can be fixed, I just want to verify that in order to start detecting for idle time, I call the Hook() function and to stop detecting, the Unhook() function.

Also, I wanted to verify that my action (which is go to formA, btw) would go under your comment that says 'do something....'  (code from your example below)

        If (nCode = HC_ACTION) Then
            Select Case wParam
                Case WM_MOUSEMOVE
                    ' using GetCursorPos() API because a service might not
                    ' have access to System.Windows.Forms.Cursor.Position()
                    If curPos.x = 500 AndAlso curPos.y = 250 Then
                        ' do something...
                    End If

            End Select
        End If

And finally, I was not sure how I could incorporate my form_activity_timeoutInteger value with the code you provided.  Will I somehow need to invoke a timer?  

here is my outline of what I'm trying to accomplish is psuedocode.  I don't even think it is really psuedocode, but I think you'll get the idea.
IF no mouse movement for form_activity_timeoutInteger THEN show inactivity_panel

[inactivity_panel is shown]: if "i am here, but just not actively entering information" button is NOT hit in 30 seconds THEN goto homepage.

Otherwise: "i am here, but just not actively entering information" button is hit, then

[no mouse movement is st back to 0]
[inactivity_panel is hidden]

Thank you,

and I'm sorry Im such a noob.

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Author Comment

ID: 16626108
I'm using VB.NET 2003 by the way
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 16626270
For the Marshal error, you need this line at the top of your code (outside the Class):

Imports System.Runtime.InteropServices

So after you have installed the hook, anytime the mouse is moved you will get a WM_MOUSEMOVE message.  What you can do is make the LowLevelMouseHook() class raise a custom event each time the mouse is moved.  From your main form, you can trap the event and reset a Timer each time the event is raised.  If the Timer event fires, then there must not have been any activity for the Interval of the Timer.

Something like...

    Public Class LowLevelMouseHook

        Public Event MouseMoved()  '  <--- your custom event

                    Case WM_MOUSEMOVE
                        RaiseEvent MouseMoved()   ' <--- raise custom event whenver mouse is moved

    End Class

    Public Class formA

        Private WithEvents llm As LowLevelMouseHook   ' <-- declared WithEvents so we can trap the custom event

        Private Sub formA_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            llm = New LowLevelMouseHook
            Timer1.Interval = 30000 ' 30 seconds
        End Sub

        Private Sub llm_MouseMoved() Handles llm.MouseMoved
            ' reset the Timer everytime the mouse is moved...
        End Sub

        Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
            ' if the code here runs then there was NO mouse movement for the
            ' interval of the Timer...
        End Sub

    End Class

Author Comment

ID: 16627274
Thanks Idle_Mind.

You really know how to take care of business!


Expert Comment

ID: 25828280
Hi Idle Mind,

I am using vb.net 2008 and the hook still does not work in IDE mode, is there any MS update or patches to make it work in IDE mode?

I am using your solution for a kiosk application, and your solution is just what i need!

LVL 86

Expert Comment

by:Mike Tomlinson
ID: 25830145
Hi BSKhoo,

I've never gone digging real deep to find a fix that allows hooks to be trapped while in the IDE.  I believe it has something to do with how the debugger attaches to the process so there is already a hook in place and they interfere with each other...not exactly sure though.

I just always run the EXE in the bin folder...makes troubleshooting problems a bit tricker though.  =\

Expert Comment

ID: 25832438
Ok, thanks a lot Idle Mind!

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an analog clock UserControl seems fairly straight forward.  It is, after all, essentially just a circle with several lines in it!  Two common approaches for rendering an analog clock typically involve either manually calculating points with…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
This video shows how to quickly and easily deploy an email signature for all users in Office 365 and prevent it from being added to replies and forwards. (the resulting signature is applied on the server level in Exchange Online) The email signat…
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …

840 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question