cbruce Posted August 12, 2008 Posted August 12, 2008 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. expandcollapse popup#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
ResNullius Posted August 12, 2008 Posted August 12, 2008 Welcome to the forums cbruce!Looks like you know you stuff.For a similar idea made into a UDF you might want to check out the quoted post at http://www.autoitscript.com/forum/index.ph...mp;#entry343430 (original post has been deleted).
PsaltyDS Posted August 12, 2008 Posted August 12, 2008 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 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
cbruce Posted August 12, 2008 Author Posted August 12, 2008 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 ActiveWhen the user is IdleHow long ActiveHow long IdleTake action after a certain number of cycles of ActivityTake 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
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now