Poner Sistema Inactivo cuando se deje de usar en un tiempo dado

1,225 views
Skip to first unread message

Samuel San Miguel

unread,
Feb 20, 2012, 10:06:26 AM2/20/12
to publice...@googlegroups.com
Hola Foro,
Estoy tratando de hacer que cuando un usuario deje de utilizar el sistema y este se encuentre abierto, este se bloquee y aparezca mi ventana de Login nuevamente.
Esta funcionalidad la quiero imitar tal como lo hace WINDOWS cuando dejas de utilizarlo, se cierra y te vuelve a pedir contraseña cada cierto tiempo de inactividad.

Pienso que una forma es utilizar Timer en mi ventan principal, otra es creando un prg, que se ejecute en el Ini de windows como un servicio, pero este último necesitaría ayuda de plasmarlo.

Alguna idea?

Saludos.

Guillermo Gimenez

unread,
Feb 20, 2012, 10:09:16 AM2/20/12
to publice...@googlegroups.com
Mira este ejemplo
 
 
Guille

--- El lun 20-feb-12, Samuel San Miguel <sasa...@gmail.com> escribió:

Victor Espina

unread,
Feb 20, 2012, 11:54:45 AM2/20/12
to publice...@googlegroups.com
Una forma de lograr el mismo efecto (o casi) pero sin necesidad de usar APIs de Windows, es usar el comando ON KEY LABEL MOUSE para detectar el momento en que el usuario pulsa alguno de los botones del mouse y usar dicho evento para reiniciar un timer.

La idea es que cada vez que el usuario hace click con el mouse el timer se reinicia de modo que la unica forma de que el evento Timer del timer se dispare es que el usuario pase una cierta cantidad de tiempo sin hacer click con el mouse, lo cual se puede tomar como "inactividad"

Ahora, puede darse el caso que el usuario este escribiendo una nota o un texto muy largo y que, mientras esta haciendo eso no pulse ningun boton del mouse durante el tiempo suficiente como para que se dispare el timer. Para evitar esta situacion, podemos usar el ON KEY LABEL SPACEBAR para que el timer se reinicie tambien cuando el usuario pulse la barra espaciadora.

La clase seria asi:

DEFINE CLASS InactivityMonitor AS Timer
 Interval = 15 * 1000
 onInactivity = ""  && Codigo a ejecutar cuando se detecte inactividad
 
 PROCEDURE Init(pnSeconds)
  PUBLIC goInactivityMonitor
  goInactivityMonitor = THIS
  THIS.Interval = EVL(pnSeconds,15)*60*1000   && Default de 15min
  ON KEY LABEL MOUSE goInactivityMonitor.Reset()
  ON KEY LABEL SPACEBAR goInactivityMonitor.Reset("{SPACEBAR}")
  THIS.Enabled = .T.
 ENDPROC
 
 PROCEDURE Timer
  THIS.Enabled = .F.
  EXECSCRIPT(THIS.onInactivity)
 ENDPROC
 
 PROCEDURE Reset(pcKeyboard)
  IF VARTYPE(pcKeyboard)="C"
   KEYBOARD (pcKeyboard) PLAIN
  ENDIF
  THIS.Interval = THIS.Interval
  THIS.Enabled = .T.
 ENDPROC
ENDDEFINE


Para usarla, debes colocar el siguiente codigo al inicio de tu programa:

LOCAL oIM
OIM = CREATE("InactivityMonitor",5)   && 5 minutos
oIM.onInactivity = "codigo a ejecutar"


Saludos


Victor Espina

Victor Espina

unread,
Feb 20, 2012, 11:56:35 AM2/20/12
to publice...@googlegroups.com
Un consejo: condicionen la declaracion del timer de inactividad para que no ejecute dentro del ambiente de desarrollo de VFP.


Carlos Miguel FARIAS

unread,
Feb 20, 2012, 5:58:37 PM2/20/12
to publice...@googlegroups.com
Sin dejar de ser ingeniosa, la opcion indicada (timer) no funcionaria si la aplicaciòn o push o pop de las on keys o si se reasignan nuevas funciones a las keys indicadas.
Lo que hago es que cada formulario lleve su propio timer (activado cuando se da el activate del formulario y pausado cuando se da el deactivate).
Para resetear el timer, en la clase base de formulario (donde ademas defino el timer), pongo al principio del keypress que invoque al reseteador del timer, en cada formulario derivado, debo recordar de hacer un dodefault(), si agrego algun codigo especifico a su keypress
Todos los botones los derivo de una clase base que lo que hace en cualquer evento clic, es resetear al timer del formulario, y en cada boton donde recodifico el evento clic y demás, hago un dodefault() y ya esta.
De esa manera, lo unico que debo configurar para cada formulario, cuanto tiempo es el aceptable para estar "esperando".
En mi caso, si el usuario deja sin usar un formulario mas de "n" tiempo, directamente cierro el formulario sin guardar cambios, y voy asi susecivamente cerrando los formularios, hasta que cuando no queda ninguno abierto, ahi si le cierro sus sesión y meto la ventana de loggin.
Si no cierro los todos los formularios antes de invocar el loggin, puede darse la circunstancia que quede un formulario abierto con un nivel de acceso, y si el nuevo usuario se loguea, se encuentra con un formulario activo al que no tiene permiso.
Saludos: Miguel, Santa Rosa (LP)

Victor Espina

unread,
Feb 20, 2012, 6:03:26 PM2/20/12
to publice...@googlegroups.com
Claro miguel, eso es posible solo si tienes tu sistema completamente estructurado en clases base. Si no es asi, tienes que usar una de las alternativas genericas.

En todo caso, creo que yo nunca he programado el ON KEY LABEL MOUSE, asi que no creo que una solucion basado en eso sea un problema para nadie.

Saludos

Victor Espina

Carlos Miguel FARIAS

unread,
Feb 20, 2012, 6:24:38 PM2/20/12
to publice...@googlegroups.com
PUSH KEY y POP KEY afecta todas las ON KEY, si se usan ON KEY perdes tambien la del mouse.
Realmente, trabajar con un nivel de herencia de clases, ahorra muchismo tiempo de codificación, pruebas y funcionalidad que incorporas.
Además como el codigo de la clase esta una sola vez, no ocupa mucho mas lugar y podes reutilizarlo en cualquier lado.
En fin vale la pena el uso de la OOP.
Saludos: Miguel, La Pampa (RA)

Victor Espina

unread,
Feb 20, 2012, 6:34:43 PM2/20/12
to publice...@googlegroups.com
Ja ja, definitivamente no hablamos el mismo idioma Miguel.

Claro que la OOP es la mejor manera. Si pensaste en eso ANTES de hacer tu sistema, genial; la tienes facil. Pero que pasa con aquellos que NO dominaban el tema de la OOP y construyeron un sistema completo a la vieja usanza??

Para estas personas, reprogramar todo su sistema para poder heredar todas sus formas de una clase base y subclasear todos las clases visuales para luego sustituir las clases base por sus subclases particulares, SOLO para implementar la funcionalidad del auto-logout por inactividad, es algo que realmente no es una opcion viable.

Para estas personas, la UNICA opcion es una solucion generica, mediante un timer. Eso es lo que yo estoy diciendo; en ningun momento quiero dar a entender que esta solucion es MEJOR que una basada en OOP.

Saludos

Victor Espina

Carlos Miguel FARIAS

unread,
Feb 21, 2012, 6:44:45 AM2/21/12
to publice...@googlegroups.com
Estimado Victor:
No dije que tu solución no servía en absoluto, simplemente tire una forma de solucionarlo con OOP, el tema que si no entendi mal tu codigo, asocias la restauración del timer (que en OOP tambien lo estoy indicando como solución) a los ON KEY LABELs y lo que observo (a lo mejor entendi mal), es que si justamente a la vieja usansa se estan usando ON KEY LABELs para otra cosa, al hacer PUSH KEY y POP KEY, tu rutina general puede quedar "desconectada".
Lamentablemente, no se porque, al pasar a VFP, se saco la clausual TIMEOUT que tenian antes las ventanas que estaba espectacular para manejar esa situaciòn.
Como adhiero a la metodologia KISS, para mi OOP es lo mas simple que hay (ojo, di clases de programación estructurada durante casi 15 años, y unos 8 o 9 de OOP, son metodologias complementarias, no excluyentes).

Saludos: Miguel, Santa Rosa (LP)


Victor Espina

unread,
Feb 21, 2012, 8:08:53 AM2/21/12
to publice...@googlegroups.com
Miguel, tienes razon en todo lo que dices. Mi unico punto es que si no aplicaste OOP al inicio, no te queda de otra que una rutina general, bien sea con ON KEY LABEL o con WindowsAPI.

Saludos

Victor Espina

Carlos Miguel FARIAS

unread,
Feb 21, 2012, 8:24:08 AM2/21/12
to publice...@googlegroups.com
Si. En las viejas epocas, con Fox Dino, tenia rutinas para cargar las ON KEY LABELs genéricas, cuando entraba en un formulario desactivaba todas las vigentes (las mandaba a la pila), cargaba las ON KEY específicas y luego las genéricas ( o al reves, no es relevante ), cuando salia del formulario, recuperaba las ON KEY de la pila.
De esa manera, no habia que resetear situaciones. En todos los casos, si no lo haces con clases, debería preverse una pila de timers tambien, para que cuando se abre el nuevo formulario, se pause el anterior y se reactive al volver.

Saludos: Miguel, La Pampa (RA)

Carlos Miguel FARIAS

unread,
Feb 21, 2012, 5:35:48 PM2/21/12
to publice...@googlegroups.com
Estimado Samuel:
En el caso de no querer perder los datos que se estan grabando, al cerrar automatico, guardo lo que este cargado en modo carga pendiente, cuando el usuario se vuelve a registrar, o le mando un mensaje con que tiene cargas pendientes o al intentar dar un nuevo alta, le recupero lo guardado como carga incompleta.
Manejar los estados de los registros se hace con campo de caracter de 1 byte, y sirve para llevar un control transaccional.
Lo que planteas no está mal, es una solución, que si funciona, KISS y listo.
El inconveniente que le veo es que si dejas formularios abiertos, dejas tablas abiertas y si algún HDP va y apaga la maquina, u otra burrada (según Murphy, la probabilidad del hecho es directamente proporcional a la inconveniencia de que dicho hecho se produzca) y los datos a la vista, Hasta la Vista, Baby, o sea dejas abierta la posibilidad de perdidas de datos (y la conocidad asociación entre el gran bonete y yo no fui) y la asignación de culpas al sistema.
En fin, esto lo aprendi en la vieja escuela cuando el control de transacciones era solo a mano BEGIN TRANSACTION, COMMIT, ROLLBACK a manopla.

Saludos: Miguel, Santa Rosa (LP)


El 21 de febrero de 2012 12:41, Samuel San Miguel <sasa...@gmail.com> escribió:
Hola Miguel,
yo trabajo siempre con Full clases y herencias por ese lado todo bien... pensaré en implementarlo de esa forma tuya con Timers (porque ya veo que no existe otra o algún api no lo sé)...
sólo un pequeño cambio, veo qe tu cuentas o te fijas si esta abierto un formulario lo cierras hasta que no te quede uno abierto y luego cierras tu sistema e invocas todo nuevamente apareciendo el Login.

Personalmente ahí esta nuestra diferencia, yo lo pensaría así y espero te sirva si deseas modificar tu funcionalidad:

Si mi tiempo se agotó solo invocaré  a mi formulario LOGIN sin cerrar los formularios , ya que puede ser que el usuario dejo una tarea pendiente, un ejemplo ingresando una O/C ó Pedido ó Fondo Fijo, que son formularios que cargan muchos Items en su detalle, y este quizas no lo grabó antes y lo dejo abierto para regresar a continuar; en este caso si yo lo cierro a la fuerza estaría faltando y ocasionando quejas con mi SISTEMA. y peor aún si hay varios forms abiertos (Aunque no lo creas estas cosas suceden por más ordenando que sea el negocio y el usuario.. nos pasa).
Continuando, sólo haría que se cargue nuevamente mi LOGIN Modal pero este cargaría con el mismo usuario de ese equipo o logeado en ese equipo y desabilitado el texto para que no lo cambie por ningún otro, solo digitaría su contraseña (sabemos que esto se hace pasándole parámetros en el init y activando o desactivando la caja de texto de usuario).. de esta forma ya no corres el riesgo que otro usuario entre con su usuario y contraseña y vea los Forms que quedaron abiertos.
Entonces cuando el usuario correcto regrese introducirá su contraseña y volverá a ver su formulario que dejo a medias de trabjar y continuará registrando.

SALUDOS.
Samuel - Lima-Perú


Samuel San Miguel

unread,
Feb 21, 2012, 5:49:51 PM2/21/12
to publice...@googlegroups.com
Miguel, te comento que no trabajo con Entorno de Datos, sólo trabajo con full cursores, modo desconectado y con DBMS Sql Server, Postgresql.
Si alguien apaga el computador a la mala, pues si eso si es perdida de lo temporal, pero no se dañan las tablas, de igual forma lo tendré presente.

Bueno en la noche comenzaré hacer las pruebas respectivas tomando las consideraciones del caso.
Saludos.

Carlos Miguel FARIAS

unread,
Feb 21, 2012, 6:18:41 PM2/21/12
to publice...@googlegroups.com
El metodo de estados lo puse a prueba a full con un sistema tecnologia internet (clientes delgados con navegador) progamado en php, pero el problema de perdida de datos por "EL USUARIO", porque cerro el navegador, o apago la máquina asi como asi, o porque simplemente se fue (FUE) la conexion a internet. Y por supuesto el servidor sigue funcionando, no se rompen las tablas, pero los datos quedan truncos.

Saludos: Miguel, La Pampa (RA)

P.D: Quema, quema, neuronas, que te va a quedar barbaro.

Walter R. Ojeda Valiente

unread,
Feb 21, 2012, 8:40:03 PM2/21/12
to publice...@googlegroups.com
Pregunta:

¿Por qué la barra espaciadora y no CUALQUIER TECLA?

En mi caso, si presiona cualquier botón del mouse o cualquier tecla se reinicia el Timer, ya que evidentemente algo está haciendo el fulano.

Saludos.

Walter.




Date: Mon, 20 Feb 2012 08:54:45 -0800
From: vesp...@gmail.com
To: publice...@googlegroups.com
Subject: Re: [vfp] Poner Sistema Inactivo cuando se deje de usar en un tiempo dado

Victor Espina

unread,
Feb 22, 2012, 6:44:40 AM2/22/12
to publice...@googlegroups.com
Por que no hay un ON KEY que sirva para cualquier tecla pulsada, hasta donde se.  No es un metodo perfecto, pero si suficiente para el uso real que los usuarios dan a un sistema.

Victor Espina

Carlos Miguel FARIAS

unread,
Feb 22, 2012, 6:55:22 AM2/22/12
to publice...@googlegroups.com
En la solución que propongo, mas alla la complejidad de instrumentar
por aquellos que no usan clases "adaptadas" para la definición de sus
formularios u objetos visuales, es que al principio del evento
keypress del formulario (con el keypreview activado), reseteo el
timer.
Si en un formulario heredado, necesito insertar codigo especifico, al
principio del metodo solo inserto un DODEFAULT() y ya está.
En los controles base (principalmente botones), tambien en sus
funciones de acceso (los clic de ratón o cuando obtienen el foco),
reseteo el timer (que es parte del formulario base) y tambien cuando
agrego codigo especifico lo primero que pongo es un DODEFAULT().
De esa manera, cualquier acción por parte del usuario, resetea el
timer del formulario activo.
En los otros formularios, en su metodo deactivate, previamente habia
pausado el timer (disabled).
Si es cierto que con solo interceptar la barra espaciadora, salvo que
el espacio en blanco sea una entrada habitual, no logra resetear el
timer (debería interceptar mas de 100 teclas directas mas las dobles),
o sea, sin comentarios.
Posiblemente sería mejor tecla tab, porque con ella se pasa de un
control a otro, pero si hay un pase natural (valid retornando .T. o
distinto de 0), no hay tab o en todo caso enter.
En fin, es un temita que puede llegar a establecer la conveniencia de
reconvertir toda la interfaz.
Siempre hay que buscar la solución KISS.

Saludos: Miguel, Santa Rosa (LP)


El 21/02/12, Walter R. Ojeda Valiente <wr...@hotmail.com> escribió:


>
> Pregunta:
>
> ¿Por qué la barra espaciadora y no CUALQUIER TECLA?
>
> En mi caso, si presiona cualquier botón del mouse o cualquier tecla se
> reinicia el Timer, ya que evidentemente algo está haciendo el fulano.
>
> Saludos.
>
> Walter.
>
>
>

ZeRoberto

unread,
Feb 22, 2012, 4:02:13 PM2/22/12
to publice...@googlegroups.com
Hay una API que te permite saber si es que machuco cualquier tecla, pero no lo recuerdo voy a buscarlos.
 
Si mal no recuerdo se buscar el flag en todo el buffer del teclado.
 
Saludos

Samuel San Miguel

unread,
Feb 22, 2012, 11:27:08 PM2/22/12
to publice...@googlegroups.com
Hola Roberto,
haber si lo encuentras y lo comentas pronto... seria genial utilizar las API para no inventar la rueda.
Saludos.

Samuel San Miguel

unread,
Feb 21, 2012, 10:41:06 AM2/21/12
to publice...@googlegroups.com

Miguel A.

unread,
Apr 16, 2018, 5:42:50 AM4/16/18
to Comunidad de Visual Foxpro en Español
Reply all
Reply to author
Forward
0 new messages