PDA

Ver la Versión Completa : Error al entrar en sesion windows


LuisAlf::
27-09-2010, 23:54:39
Hola a todos de nuevo!!

Como dije anteriormente, he estado trabajando con una aplicación tipo gadget...
Desde hace tiempo que lo monte en mi Laptop, he tenido un problema que no tengo ni idea de como resolverlo....

Lo que pasa es que cada vez que trato de entrar a mi sesion ya sea por inactividad o por cerrarla, mi windows 7 me manda un error de que el programa a dejado de trabajar correctamente, y muchas ventanitas de error...

Segun supongo yo, creo que es por el timer que mueve la form, es que siempre se esta moviendo la aplicacion y cuando se cierra sesion algo pasa, eso creo yo...

La cuestion es que como soluciono ese problema? como detengo el timer antes de que se cierre sesion o antes de que se suspenda?..

Los dejo con mis dudas y cualquier ayuda pues sera bienvenida!:D

Ñuño Martínez
05-10-2010, 11:49:22
Me da la sensación de que creas muchos TTimer y cada ventana de error se corresponde con uno de ellos. No sé los detalles, pero posiblemente cada TTimer cree un hilo nuevo, de ahí el problema.

La solución está en capturar el mensaje de cierre de sesión, que ahora mismo no recuerdo cuál es pero está descrito en la documentación del API.

LuisAlf::
05-10-2010, 20:14:39
Mira...

Nada mas manejo dos timers...
Estuve comentando codigo...hasta ver cual era el del conflicto y si es dentro de uno de los timers...
Es una funcion que utilizo para detectar que el cursor esta fuera de la forma...
if PtInRect(Self.BoundsRect, Mouse.CursorPos) then...

Y es en este bloque donde sale el error....detectado por Windows cuando trato de entrar al escritorio...(ya que si quito el if no me vuelve a saltar el error de la aplicacion al entrar al escritorio)

Entonces...como le hago para detener el timer antes de que se suspenda la laptop....???
Estuve implementando el manejador para el mensaje WM_QUERYENDSESSION
Pero no me ejecuta el showmessage que pongo en el...:(

Ñuño Martínez
15-10-2010, 11:13:49
Disculpa la tardanza.

Estuve implementando el manejador para el mensaje WM_QUERYENDSESSION
Pero no me ejecuta el showmessage que pongo en el...:(

Si no recuerdo mal, cuando la ventana de la aplicación recibe el mensaje WM_QUERYENDSESSION ya está todo el pescado vendido, no hay marcha atrás; es decir, la aplicación va a terminarse sí o sí. En los tiempos del Win16, Mr. Norton recomendaba no usar la API cuando se procesaba este mensaje, con excepción de unas pocas funciones que liberan recursos (o más específicamente los handlers de estos recursos). Existía una forma de "colgar" el sistema que consistía en intentar crear una ventana nueva en ese momento asignándole como "padre" la ventana principal de la aplicación. El cuelgue se producía, según creo, porque dicha ventana quedaba huérfana, dejando recursos y mensajes en el limbo.

Supongo (y es una suposición) que el "ShowMessage" intenta asignar la ventana principal de tu aplicación como "padre", pero al no existir esta el sistema simplemente ignora la petición. Pero ya digo que es una suposición, porque hace mucho que no me veo en estos bretes.

LuisAlf::
17-10-2010, 23:47:32
:(

:o
Que onda!!

Gracias por responder...

Sabes que encontre el motivo de porque sale ese error...

Estuve programando el xeyes en otra aplicacion y me di cuenta que tambien le pasa lo mismo....

Y Yo creo que es por las propiedades del objeto mouse.curpos.X y mouse.curPos.y.....

Ya que en los dos utilizo el acceso a las propiedades del mouse....

Cualquiera que quiera intentarlo para probar lo que les dijo..

pongan un timer que se este ejecutando muy rapido para que este leyendo estas propiedades del mouse....claro en una lap con windows 7..no se si pase lo mismo en una pc...

var coordenadax:integer;
begin
coordenadax:=mouse.curPos.X;
end;



y traten de suspenderla y entrar otra vez a su session y el error se produce luego restaurada la session:mad:...

La verdad no se como proceder:confused:...

Ñuño Martínez
19-10-2010, 10:31:17
¡Pues claro que falla, jomío! ¿A quién se le ocurre utilizar un "timer" para leer la posición del ratón? :eek: Si es que...

Después de la bronca, te recomiendo que replantees la aplicación. Casi es mejor que utilices un bucle (cuasi)infinito para hacer esto. Lo que no tengo muy claro es dónde colocarlo, pero sería tal que así:


TMiForm = CLASS (TFORM)
{ ... blablabla ... }
PRIVATE
(* Marca de final. Poner a FALSE en "OnCreate" y a TRUE en "OnClose". *)
Terminar: BOOLEAN;
{ ... blablabla ... }
(* El meollo de la cuestión. *)
PROCEDURE BuclePrincipal;
BEGIN
REPEAT
coordenadax:=mouse.curPos.X;
coordenadax:=mouse.curPos.X;
Application.ProcessMessages;
UNTIL Terminar;
END;


Como digo, el problema aquí reside en desde dónde llamar al método "BuclePrincipal".:confused:

mcs
19-10-2010, 11:45:51
¡Pues claro que falla, jomío! ¿A quién se le ocurre utilizar un "timer" para leer la posición del ratón? :eek: Si es que...

Después de la bronca, te recomiendo que replantees la aplicación. Casi es mejor que utilices un bucle (cuasi)infinito para hacer esto. Lo que no tengo muy claro es dónde colocarlo, pero sería tal que así:

Código Delphi [-] (http://www.clubdelphi.com/foros/#)TMiForm = CLASS (TFORM) { ... blablabla ... } PRIVATE (* Marca de final. Poner a FALSE en "OnCreate" y a TRUE en "OnClose". *) Terminar: BOOLEAN; { ... blablabla ... } (* El meollo de la cuestión. *) PROCEDURE BuclePrincipal; BEGIN REPEAT coordenadax:=mouse.curPos.X; coordenadax:=mouse.curPos.X; Application.ProcessMessages; UNTIL Terminar; END;


Como digo, el problema aquí reside en desde dónde llamar al método "BuclePrincipal".:confused:

No lo entiendo... Dónde está el problema en usar un timer para leer las coordenadas del mouse? Si se deja un intervalo "generoso" (seguro que con 100ms es suficiente), no debe haber ningún problema.

Por lo que entiendo, el problema lo tiene cuando se cierra la sesión y no finaliza el programa. Por lo que imagino, lo que ocurre es que el programa de LuisAlf no puede acceder a los datos del mouse, porque este está deshabilitado para la sesión o algo similar.

Por tanto, la solución sería capturar la salida de sesión (no sé como), y si se sale de sesión, parar de leer las coordenadas. O quizá con un bloque try..finally se solucionaría todo...

LuisAlf::
19-10-2010, 17:06:36
¿A quién se le ocurre utilizar un "timer" para leer la posición del ratón?...

Jajajaja....pues a mi..claro!!!:cool:

Mira exacto!!! No hay ningun problema al utilizar un timer para este objetivo, ya que es un procedimiento que se llama cada determinado tiempo y es exactamente lo que tu me planteaste un procedimiento que lee las posiciones del cursor...cada cierto tiempo...

O quizá con un bloque try..finally se solucionaría todo...
Esto ya lo habia contemplado, ya que un amigo me dijo algo de manejo de la excepcion... para encapsular el error y si...por hay fue mi solucion, yo batallando con la suspension de la sesion...jajaja mal enfoque del problema:p

Asi es lo que hice ayer fue eso, manipule el evento manejador de excepciones

private
{ Private declarations }
procedure TratarExcepciones (sender: tObject; e : Exception);
....

procedure TForm1.FormCreate(Sender: TObject);
begin
...
Application.OnException := TratarExcepciones;
.....
end;


creando un procedimento de tipo object, y que creen lo que puse en el procedure...
pues "nada":D
jajaja

procedure tForm1.TratarExcepciones (sender: tObject; e:Exception);
begin
//NADADENADA
end;
Dejenme explicarme, lo que pasa es que puse un showmessage en el procedimento para ver si encapsulaba el error que me mostraba windows y si efectivamente el showmessage se muestra en lugar de las otras ventanas del error que el propio windows me mostraba...

Y como yo no quiero que muestre ningun mensaje pues le quite el showmessage... de esta forma el error no se muestra y la aplicacion sola se estabiliza, trabajando correctamente despues de restaurada la sesion....

No se si sea la forma mas ortodoxa de solucionarlo pero funciona....;):D

Ñuño Martínez
20-10-2010, 10:20:14
Dónde está el problema en usar un timer para leer las coordenadas del mouse?

Pues, precisamente, en que el timer puede "activarse" fuera de contexto (que es lo que sospecho que le pasa a nuestro compañero LuisAlf::). No se puede garantizar que las interrupciones se produzcan en un momento determinado: se producirán cuando se produzcan y ya está.

Un ejemplo práctico es el procedimiento "Sleep". Tú le puedes decir que duerma durante 100 milisegundos, pero nada garantiza que exactamente 100 milisegundos después el sistema devuelva el control al programa. No sé cómo implementa los timer Delphi (supongo que usando MSG_TIMER del API, y posiblemente con un hilo [fork] paralelo) pero las posibilidades de que pase lo mismo son importantes. No olvidemos, tampoco, que Windows no es un sistema operativo de "tiempo real", como sí lo es MS-DOS, por ejemplo.

Si se quiere utilizar un timer, habrá de asegurarse de eliminarlo antes de que se salga del contexto, o al menos evitar que funcione si está fuera de él. Se me ocurre que antes de obtener las coordenadas del ratón, quizá se pueda comprobar si el objeto "mouse" o el contenedor del mismo sigue existiendo. Algo así como:

IF mouse <> NIL THEN
BEGIN
CoordenadaX := mouse.curPos.x;
END;


O quizá usar "SELF" o "Application" en lugar de "mouse".

<-- Evitar doble post -->

Jajajaja....pues a mi..claro!!!:cool:

Mira exacto!!! No hay ningun problema al utilizar un timer para este objetivo, ya que es un procedimiento que se llama cada determinado tiempo y es exactamente lo que tu me planteaste un procedimiento que lee las posiciones del cursor...cada cierto tiempo...


Esto ya lo habia contemplado, ya que un amigo me dijo algo de manejo de la excepcion... para encapsular el error y si...por hay fue mi solucion, yo batallando con la suspension de la sesion...jajaja mal enfoque del problema:p

Asi es lo que hice ayer fue eso, manipule el evento manejador de excepciones

private
{ Private declarations }
procedure TratarExcepciones (sender: tObject; e : Exception);
....

procedure TForm1.FormCreate(Sender: TObject);
begin
...
Application.OnException := TratarExcepciones;
.....
end;


creando un procedimento de tipo object, y que creen lo que puse en el procedure...
pues "nada":D
jajaja

procedure tForm1.TratarExcepciones (sender: tObject; e:Exception);
begin
//NADADENADA
end;
Dejenme explicarme, lo que pasa es que puse un showmessage en el procedimento para ver si encapsulaba el error que me mostraba windows y si efectivamente el showmessage se muestra en lugar de las otras ventanas del error que el propio windows me mostraba...

Y como yo no quiero que muestre ningun mensaje pues le quite el showmessage... de esta forma el error no se muestra y la aplicacion sola se estabiliza, trabajando correctamente despues de restaurada la sesion....

No se si sea la forma mas ortodoxa de solucionarlo pero funciona....;):D

No se me había ocurrido esta solución.

Aunque funcionar, funcionar... El problema aquí es que si se produce otro error, entonces no te enterarás... Quizá sea buena idea dejar constancia de los errores en algún sitio, como por ejemplo en un archivo de disco, por si las moscas.

LuisAlf::
20-10-2010, 16:21:59
No se me había ocurrido esta solución.

Aunque funcionar, funcionar... El problema aquí es que si se produce otro error, entonces no te enterarás... Quizá sea buena idea dejar constancia de los errores en algún sitio, como por ejemplo en un archivo de disco, por si las moscas.

Gracias por la respuesta Ñuño!!

Pues la verdad no se me habia ocurrido lo del mouse<>nil
Creo que tambien podria funcionar!!, voy a intentarlo, en cuanto a los errores, no cre oque se produzca otro error importante, yo creo que en este era en lo que estaba batallando y ya funciona bien...
jjaja

Gracias!!!

LuisAlf::
20-10-2010, 17:28:33
No, lo del mouse<>nil no funciona...

Lo que pasa es que el "objeto" o referencia si esta creado, el problema es que no se puede acceder a las propiedades antes mencionadas...

Hablando del procedimiento que no hace nada, es posible encapsular nada mas el error EOeserror del objeto mouse, en el parametro "e" del procedimiento, y no hacer nada con el...