Willem's...

{rue if I mellow}

  Home  |   Contact  |   Syndication    |   Login
  25 Posts | 0 Stories | 223 Comments | 51 Trackbacks

News

Archives

Post Categories

Businessware Architects

XML-FX.COM

We needed to write an application that would automatically execute a time-out action, the time-out being a prescribed length of time that has expired without any user input occurring during that period.

Not as easy as it sounds.  One way to do it is to setup a set of system-hooks using the message hook APIs provided by Win32.  I personally did not like this approach for the following reasons:

  • Using system-hooks is intrusive and reduces overall system performance.
  • Its more work, because the hooks provide callbacks for all the windows/processes running and they would have to be filtered.
  • There may be security and credentials constraints setting system-wide hooks while running the application as a user with certain permissions.

I discovered a little gem: the Win32 (user.lib) GetLastInputInfo function which returns a data structure containing the system tick-count when the last user input was detected. User input is defined as any captured mouse event or application keyboard event.  One problem with this very easy to use function is that if specific inputs have to recognized, eg only mouse events, this function cannot be used.

The following code-excerpt provides a means of detecting an application user-input idle timeout.  The example is an MFC application, and uses a timer event to periodically poll for the last user input time:

void CMyWindow::OnTimer(UINT nIDEvent)
{
    // timer event for polling for user-idle timeout.
    if(nIDEvent == TIMEOUT_TIMER_ID)
    {
        // Get the last input event info.
        LASTINPUTINFO li;
        li.cbSize = sizeof(LASTINPUTINFO);
        ::GetLastInputInfo(&li);
        // Calculate the time elapsed in seconds.
        DWORD te = ::GetTickCount();
        int elapsed = (te - li.dwTime) / 1000;
        // Test against a preset timeout period in
        // seconds.
        if(Application()->TimeOut() < elapsed)
        {
            // Call a function or set an application flag
            // that can be acted on outside this function.
            OnTimeout();
        }
    }
    ..
}

BTW, this API is only available in WIN 2000 onwards - correct your stdafx.h file as follows, to ensure correct compilation and linking:

#define WINVER 0x0500
#define _WIN32_WINNT 0x0500
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
posted on Sunday, October 30, 2005 7:29 PM

Feedback

# re: User input idle detection in MFC applications 5/29/2006 4:43 PM P. Lee

Couldn't get LASTINPUTINFO to compile until I saw your note on fixing stdafx.h.

Thanks!

# re: User input idle detection in MFC applications 8/3/2006 1:53 AM guy
Looks good, thanks for the tip.

# re: User input idle detection in MFC applications 3/25/2010 6:53 AM Gurmeet
I also need the same.
I want the system idle time that how much time system was idle.

Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: