Detecting Application Idle State in Windows Forms

On a recent project, I had the need to detect whether or not the application is idle, and if so, for how long has the idle state persisted. Idle in my case is defined as no mouse movement or keyboard activity when any of the forms of the application are in focus. If a different program is in focus, I define this as being an application-idle state (for my app), regardless of whether or not there is input activity from keyboard or mouse.

On researching the subject, I found several approaches. The main approach I have seen is to use the static Application.Idle event. This event fires whenever “application finishes processing and is about to enter the idle state” – In other words, whenever the application’s message queue is empty. The problem with this approach is that this event fires a lot, so much that it becomes impractical for tracking idle state the way that I need it (it doesn’t help that any Timer operating to track how long the idle state persists would set off Application.Idle, further complicating the situation).

The other approach that I have seen is to set up some Windows hooks to detect mouse and keyboard activity. I have zero experience operating with the Windows API, so thankfully, I found a post by Johan Danforth that gives some working code for doing exactly what I needed: Detecting Idle Time with Mouse and Keyboard Hooks. I integrated the code with my application and tested it out and it worked great.

There was one problem however: this code detects idle time for all applications. In other words, if your application is open but not in focus and you use your mouse or keyboard, the code changes your application status from Idle to Active. For my purposes (see definition if idle above) this is not good enough. So I inspected different properties of the System,Windows.Forms.Form class to see what could tell me whether or not a given form is active. The first candidates were Focused, TopLevel, TopMost and Visible, but none of these did the job. The property that ended up telling me exactly what I needed to know is ContainsFocus. This is a property of the Control class (from which Form inherits) and it “Gets a value indicating whether the control, or one of its child controls, currently has the input focus”. (Focused is not good enough, since it only returns true when the form itself has focus, but returns false when a child control contained within the form has focus).

I also needed to detect whether any of the secondary forms of my application had focus (since I could have more than one window open at a time, only one of which could have focus). Here is the code that I used:

private bool DoesApplicationHaveFocus() {
  bool hasFocus = false;
  if (ContainsFocus) {
    hasFocus = true;
  } else {
    FormCollection forms = Application.OpenForms;
    foreach (Form f in forms) {
      if (f != null && f.ContainsFocus) {
        hasFocus = true;
        break;
      }
    }
  }
  return hasFocus;
}
Tagged , , , . Bookmark the permalink.

7 Responses to Detecting Application Idle State in Windows Forms

  1. I have used something similar Johan’s technique, but much simpler. It is actually pretty easy, because .NET provides the System.Windows.Forms.IMessageFilter interface. This worked well, and would work for you, because it is limited to the activity on my own windows. Email me and I will send you the (VB.NET) code.

  2. Jai says:

    Can anyone help me how to detect idleness of a web system using vb.net? I’ve already referred to the article of Detecting Idle Time with Mouse and Keyboard Hooks by Johan Danforth but he is using c#. I’ve already convert that code to the vb.net code but unfortunately there is still some error need to be consider. Can anyone help me how to the steps that need to follow to detect idleness using vb.net in web system?

  3. Manish says:

    thanks a lot.

  4. govindh says:

    hi Steve,

    Its great to see that you guys had put much of time on this and have a handful solution for the same. it would be great that if you could share the vb.net code that you talked about to my ID govindharajr@gmail.com

    thanks a lot

  5. Joe says:

    kindly email me the code for idle in vb.net

  6. krushnavadan says:

    hello joe, you can use System.Windows.Forms.IMessageFilter
    for creating deriving class of that in this you can take place watch on messages and make easy code

    krushnavadan

Leave a Reply

Your email address will not be published. Required fields are marked *