22 de marzo de 2016

Detectar inactividad

Pueden utilizar la siguiente función para detectar un período de inactividad, ya sea en todo Windows o solamente en la aplicación.

CLEAR
PUBLIC tmrCheck
tmrCheck = NEWOBJECT("DetectActivity")
RETURN

DEFINE CLASS DetectActivity as Timer
  * Sólo detecta inactividad mientras está en este programa?
  JustInThisApp = .T.
  * Intervalo de inactividad tras el cual dispara OnInactivity (en segundos)
  InactivityInterval = 5
  * Intervalo cada el que chequea actividad
  Interval = 1000
  LastCursorPos = ""
  LastKeybState = ""
  LastActivity = DATETIME()
  CursorPos = ""
  KeybState = ""
  IgnoreNext = .T.

  PROCEDURE Init
    DECLARE INTEGER GetKeyboardState IN WIN32API STRING @ sStatus
    DECLARE INTEGER GetCursorPos IN WIN32API STRING @ sPos
    DECLARE INTEGER GetForegroundWindow IN WIN32API
  ENDPROC

  PROCEDURE Destroy
    CLEAR DLLS GetKeyboardState, GetCursorPos, GetForegroundWindow
  ENDPROC

  PROCEDURE Timer
    WITH This
      IF ! .CheckActivity()
        * Si no hubo actividad veo si es tiempo de disparar OnInactivity
        IF ! ISNULL(.LastActivity) AND ;
            DATETIME() - .LastActivity > .InactivityInterval
          .LastActivity = NULL && Prevengo disparo múltiple de OnInactivity
          .OnInactivity()
        ENDIF
      ENDIF
    ENDWITH
  ENDPROC

  * Chequeo si hay actividad
  PROCEDURE CheckActivity
    LOCAL lRet
    WITH This
      IF .JustInThisApp
        IF GetForegroundWindow() <> _VFP.hWnd
          * Estoy en otro programa
          RETURN lRet
        ENDIF
      ENDIF
      .GetCurState()
      IF (!.CursorPos == .LastCursorPos OR !.KeybState == .LastKeybState)
        IF ! .IgnoreNext && La 1ra vez no ejecuto
          lRet = .T. && Hubo actividad
          .OnActivity()
          .LastActivity = DATETIME()
        ELSE
          .IgnoreNext = .F.
        ENDIF
        .LastCursorPos = .CursorPos
        .LastKeybState = .KeybState
      ENDIF
    ENDWITH
    RETURN lRet
  ENDPROC

  * Devuelve el estado actual
  PROCEDURE GetCurState
    LOCAL sPos, sState
    WITH This
      sPos = SPACE(8)
      sState = SPACE(256)
      GetCursorPos (@sPos)
      GetKeyboardState (@sState)
      .CursorPos = sPos
      .KeybState = sState
    ENDWITH
  ENDPROC

  PROCEDURE OnInactivity
    WAIT WINDOW "Inactividad a las " + TIME() NOWAIT
  ENDPROC

  * Hubo actividad
  PROCEDURE OnActivity
    WAIT WINDOW "Actividad a las " + TIME() NOWAIT
  ENDPROC
ENDDEFINE

Mario Lopez

No hay comentarios. :

Publicar un comentario