Sign in to follow this  
Followers 0
cbruce

Example - How to tell if a User is ACTIVE or IDLE

4 posts in this topic

Sorry, this is my first post and I can't post it in Examples, because you have to have at least 10 posts before you can.

Anyway, I needed this for something else I was working on and thought it might be useful to others.

#cs
       Script:   beh__Example__API_GetLastInputInfo.au3
       Author:   Bruce Huber (cbruce)
       AutoIt:   v3.2.12.1
       Date:       2008.08.09 - Original release
   
       Purpose:
           This example script uses the API GetLastInputInfo() to determine if a user is active or idle.
   
       License:
           Public domain.
   
       Note:
           This example does nothing useful, itself, except to show how the the API GetLastInputInfo()
       should be used.  But, that can be very useful.
   
       Note:
           This example does not even have any output, unless $DEBUG_nnn = True and Sysinternals DebugView
       is running.  If you run Sysinternals DebugView utility, you will be able to view, and optionally
       log, the output from the DebugPrint() function.
       http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx
       Get the full download so that you get the DebugView help file also.  (DON'T RUN their LIVE version).
   
       Note:
           Does the API GetLastInputInfo() have a global hook at its base?  MSDN says that API
       GetLastInputInfo() only sees the current "session" - but doesn't define session.  Anyway, it
       appears to be effective at detecting mouse and keyboard activity across all apps, and the desktop
       itself, on my single monitor Win/XP system.
   #ce
   
   #include <Date.au3>
   
   
   HotKeySet( "{Esc}", "ExitMyScript")
   
   Global $DEBUG_001 = False
   Global $DEBUG_002 = True
   
   Dim $Time_1 = GetLastInputTime_ticks()
   Dim $Time_2
   
   Dim Enum $UIS_ACTIVE, $UIS_IDLE
   Dim $UserInputState = $UIS_ACTIVE
   
   Dim $Active_Count = 0, $Total_Active_Count = 0, $Idle_Count = 0, $Total_Idle_Count = 0
   
   Dim $Active_StartTime = _NowCalc()
   Dim $Active_StopTime = $Active_StartTime
   Dim $Idle_StartTime = $Active_StartTime
   Dim $Idle_StopTime = $Active_StartTime
   
   
   While 1
       Sleep( 1000)
      ; -------------------------------------------------------------------------------------------------------------------------
      ; Determine if the user is ACTIVE or IDLE.
       $Time_2 = GetLastInputTime_ticks()
       If ( $Time_2 - $Time_1) <> 0 Then
          ; Since there IS a difference, between $Time_2 and $Time_1, there is ACTIVE user input.
                                       If $DEBUG_001 Then DebugPrint( "ACTIVE - Prev: " & $Time_1 & "   Curr: " & $Time_2)
           If $UserInputState <> $UIS_ACTIVE Then
              ; We are transitioning from IDLE to ACTIVE state.
               $Idle_StopTime = _NowCalc()
               $Active_StartTime = $Idle_StopTime
               $Active_Count = 0
                                       If $DEBUG_002 Then DebugPrint( "-----------------")
                                       If $DEBUG_002 Then DebugPrint( "IDLE   - From: " & $Idle_StartTime & "   To: " & $Idle_StopTime)
           EndIf
           $Active_Count += 1
           $Total_Active_Count += 1
           $UserInputState = $UIS_ACTIVE
           $Time_1 = $Time_2
                                       If $DEBUG_001 Then DebugPrint( "ACTIVE - Active_Count: " & $Active_Count)
       Else
          ; Since there is NOT a difference, between $Time_2 and $Time_1, the user is IDLE (NO user input).
                                       If $DEBUG_001 Then DebugPrint( "IDLE   - Prev: " & $Time_1 & "   Curr: " & $Time_2)
           If $UserInputState <> $UIS_IDLE Then
              ; We are transitioning from ACTIVE to IDLE state.
               $Active_StopTime = _NowCalc()
               $Idle_StartTime = $Active_StopTime
               $Idle_Count = 0
                                       If $DEBUG_002 Then DebugPrint( "-----------------")
                                       If $DEBUG_002 Then DebugPrint( "ACTIVE - From: " & $Active_StartTime & " To: " & $Active_StopTime)
           EndIf
           $Idle_Count += 1
           $Total_Idle_Count += 1
           $UserInputState = $UIS_IDLE
                                       If $DEBUG_001 Then DebugPrint( "IDLE   - Idle_Count: " & $Idle_Count)
       EndIf
      ; -------------------------------------------------------------------------------------------------------------------------
       #cs
           ************************************
           Good place to put code that is dependant on whether the user was ACTIVE or IDLE.
           ************************************
       #ce
       If $UserInputState = $UIS_ACTIVE Then
          ; Do something based on user being ACTIVE.
                                       If $DEBUG_002 Then DebugPrint( "ACTIVE - From: " & $Active_StartTime & " To: " & _NowCalc())
           If Mod( $Active_Count, 2) = 0 Then
                                       If $DEBUG_002 Then DebugPrint( "ACTIVE - That's another 2 CURRENT ACTIVE cycles...")
           EndIf
           If Mod( $Total_Active_Count, 4) = 0 Then
                                       If $DEBUG_002 Then DebugPrint( "ACTIVE - That's another 4 TOTAL ACTIVE cycles...")
           EndIf
       Else
          ; Do something based on user being IDLE.
                                       If $DEBUG_002 Then DebugPrint( "IDLE   - From: " & $Idle_StartTime & "   To: " & _NowCalc())
           If Mod( $Idle_Count, 3) = 0 Then
                                       If $DEBUG_002 Then DebugPrint( "IDLE   - That's another 3 CURRENT IDLE cycles...")
           EndIf
           If Mod( $Total_Idle_Count, 5) = 0 Then
                                       If $DEBUG_002 Then DebugPrint( "IDLE   - That's another 5 TOTAL IDLE cycles...")
           EndIf
       EndIf
      ; -------------------------------------------------------------------------------------------------------------------------
   WEnd
   
   
  ; ===============================================================================================

==================================================================================================
  ; FUNCTIONS
  ; ===============================================================================================

==================================================================================================
   
  ; If you run Sysinternals DebugView utility, you will be able to view, and optionally log, the output from
  ; this DebugPrint() function.
  ; http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx
  ; Get the full download so that you get the help file also.
   Func DebugPrint( $Output_string)
       DllCall( "kernel32.dll", "none", "OutputDebugString", "str", $Output_string)
   EndFunc; DebugPrint
   
  ; Exit function is tied to HotKey.
   Func ExitMyScript( )
       Exit
   EndFunc; ExitMyScript
   
   #cs
           API GetLastInputInfo() captures the result of API GetTickCount() everytime the user
       uses the mouse or keyboard.
           So, to make use of API GetLastInputInfo(), call it at TIME_1, wait awhile, and then call it again at
       TIME_2.  If there is a difference between TIME_1 and TIME_2, then the user was ACTIVE between the two
       calls.  If TIME_1 = TIME_2, then the user was IDLE between the two calls.
           Note: API GetTickCount() counts up to 4Gig ticks and then rolls over.  So you can't use this function,
       directly, to calculate IDLE time, etc.  If that is what you want, you will need to keep track of the time
       between calls, to API GetTickCount(), and accumulate that into total times yourself.
   #ce
   Func GetLastInputTime_ticks()
       Local $GLII_struct = DllStructCreate( "uint; dword")
       DllStructSetData( $GLII_struct, 1, DllStructGetSize( $GLII_struct))
       DllCall( "user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr( $GLII_struct))
      ; Returns GetTickCount() as of the last time the user did anything.
       Return DllStructGetData( $GLII_struct, 2)
   EndFunc; GetLastInputTime_ticks

cbruce

Share this post


Link to post
Share on other sites



That's a little over complicated, since the Beta Timers.au3 UDF now has _Timer_GetIdleTime() (demo must be run with Beta, Alt-F5 in SciTE, and writes to the SciTE console):

#AutoIt3Wrapper_Au3Check_Parameters= -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6

#include <Timers.au3>

HotKeySet("{ESC}", "_Quit")

Global $iIdleTime = _Timer_GetIdleTime(), $iDeltaIdleTime, $iIdleSec
ConsoleWrite("Debug: $iIdleTime = " & $iIdleTime & @LF)

While 1
    $iDeltaIdleTime = _Timer_GetIdleTime()
    If $iDeltaIdleTime < $iIdleTime Then
        $iIdleSec = Round($iIdleTime / 1000, 0)
        ConsoleWrite("User active after being idle approx " & $iIdleSec & " secs" & @LF)
    EndIf
    $iIdleTime = $iDeltaIdleTime
    Sleep(250)
WEnd

Func _Quit()
    Exit
EndFunc  ;==>_Quit

:P


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

Thanks Psalty - I'm glad they added the new function and demo - and I agree that it is simpler.

My example shows where a lot of feature functionality can fit, because it is the base framework for a utility that I've been working on that utilizes all of that functionality.

I need to know:

  • When the user is Active
  • When the user is Idle
  • How long Active
  • How long Idle
  • Take action after a certain number of cycles of Activity
  • Take action after a certain number of cycles of In-Activity
Like I said, my example is a core framework that lends itself to use for basing certain utilities on.

cbruce

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0