Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Misterio. TTimer se activan solos? (https://www.clubdelphi.com/foros/showthread.php?t=95295)

amadis 20-07-2021 16:16:57

Misterio. TTimer se activan solos?
 
Hola colegas,

he descubierto algo en un proyecto que es un misterio. LOS TTimer se activan solos?

Tengo una aplicacion win32, DB Firebird , conexion firedac.

en la misma, tengo un TIMER, cada 500 ms (enabled on designtime). (este timer muestra en la statusbar, la fehca/hora y el estado de NUM LOCK Y CAPS LOCK)

Ahora he necesitado agregar un timer 3000 ms (disabled desigtime). Luego de que la aplicacion realiza varios procesos en el evento ON SHOW, activo el NUEVOTIMER pasandole true a la propiedad enabled, (este conecta a una BD MySql Remota).
En teoría, una vez terminado el inicio del programa, esteparia 3 segundos, y comenzaria el NUEVOTIMER (cuya primer linea es enabled false).

Resulta que he descubierto que este NUEVOTIMER, y cualquier otro que exista, estando desactivados en tiempo de diseño, INICIAL ENABLED al ejecutar el programa.

la pregunta es si alguien conoce si existe alguna propiedad del IDE o del proyecto que sea por ej AUTO ENABLE TIMERS? o algo similar?

He creado un nuevo proyecto vació varios timer apagados, y estos se quedan apagados hasta que los encienda.

¿que podrá ser que me encienda todos los Timer?

Casimiro Notevi 20-07-2021 17:04:01

Revísalo con cuidado, eso no puede ocurrir.

amadis 20-07-2021 19:47:15

se puede de alguna forma dentro del ON TIMER, saber ¿que proceso le dio el ENABLED?

Los timer son creador en tiempo de diseño, y salvo el de la hora que esta siempre enabled que siempre los demas se activan en ejecucion.

Casimiro Notevi 20-07-2021 21:07:29

Creo que lo más simple es hacer una simple búsqueda ctrl-f y buscar timer2 (o como se llame) y mirar dónde lo pones enabled o active=true

Neftali [Germán.Estévez] 21-07-2021 08:29:30

Yo en estos casos, cambio el nombre al componente y recompilo, para que vayan saliendo todas líneas donde se usa.
Cuidado con los with que a veces juegan malas pasadas.
Incluso alguna vez un IF...THEN (sin begin) ha ejecutado menos líneas de las esperadas y me ha dado alguna sorpresa.

movorack 21-07-2021 16:29:21

Hola amadis.

Sí es posible saber quien activa el timer.

Debes colocar un punto de parada en el procedimiento TTimer.SetEnabled de la unidad Vcl.ExtCtrls. Al detenerse, en la ventana CallStack te muestra que evento hizo el llamado de la propiedad Enabled.


amadis 22-07-2021 00:02:09

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 541961)
Yo en estos casos, cambio el nombre al componente y recompilo, para que vayan saliendo todas líneas donde se usa.
Cuidado con los with que a veces juegan malas pasadas.
Incluso alguna vez un IF...THEN (sin begin) ha ejecutado menos líneas de las esperadas y me ha dado alguna sorpresa.

Antes de postear hice lo que comentaba Casimiro, y tambien renombré, y solo hay una llamada al enabled true, que es la correcta.

Luego descubrí que todos los timer que ponga se activan solos, por lo que veo en el ON CREATE, del proyecto, o al menos eso sospecho al ver unos SHOWMESSAGE(''); que les puse a los timer para rastrear.

amadis 22-07-2021 00:24:40

Cita:

Empezado por movorack (Mensaje 541997)
Hola amadis.

Sí es posible saber quien activa el timer.

Debes colocar un punto de parada en el procedimiento TTimer.SetEnabled de la unidad Vcl.ExtCtrls. Al detenerse, en la ventana CallStack te muestra que evento hizo el llamado de la propiedad Enabled.


Me paré en la linea del If value del SetEnabled, le puse F5, marque punto de parada.

Y luego F9, pero no para nada, se ejecuta normalmente.

Y la sentencia que pones en el boton5 no me hace ningun efecto.

Casimiro Notevi 22-07-2021 11:03:46

Cita:

Empezado por amadis (Mensaje 542008)
Antes de postear hice lo que comentaba Casimiro, y tambien renombré, y solo hay una llamada al enabled true, que es la correcta.

¿Y active?

amadis 22-07-2021 11:57:34

No hay Nada mio que active los timer, estoy tratando de desarmar todo para llegar al fondo.

Es un misterio realmente porque cualquier timer nuevo que ponga, en cualquier form del proyecto lo dejo DISABLED, y al ejecutar SE EJECUTA

amadis 22-07-2021 12:49:04

EUREKA dijo Arquimedes
 
En contra de lo que hace unos minutos afirmaba, en realidad si había un código mio que activaba todos los timer de todos los forms.

Y era un procedimiento que utilizo para Activar o Desactivar funciones se acuerdo al usuario logueado al sistema.
Y lo que hace el procedimiento es dar ENABLED TRUE, a los componentes de acuerdo a su TAG, y al valor asignado al usuario.

Y por si no me había dado cuenta los TIMER son un componente mas aunque invisibles... y también los estaba activando

Aquí debajo dejo el procedimiento que causaba el misterio. Alguna vez lo tomé de un hilo de aqui sobre control de usuarios. Así que si alguien más usa esta forma de control deberá prestar atención a los timer.

Código Delphi [-]
procedure NivelAcceso(aForm: TForm; const UserAccessLevel: Integer);
var
  PInfo  : PPropInfo;
  i, vTag: Integer;
begin
  with aForm do
  begin
    for i := 0 to ComponentCount - 1 do
    begin      
          if (GetPropInfo(Components[i].ClassInfo, 'Enabled') <> nil) and
             (GetPropInfo(Components[i].ClassInfo, 'Tag') <> nil)
             then
                begin
                  if GetOrdProp(Components[i], 'Tag') > UserAccessLevel
                   then SetOrdProp(Components[i], 'Enabled', Integer(False))

                  else
                    SetOrdProp(Components[i], 'Enabled', Integer(True));
                end;
    end;
  end;
end;

Lo solucioné agregando el CLASSNAME del componente así.


Código Delphi [-]
procedure NivelAcceso(aForm: TForm; const UserAccessLevel: Integer);
var
  PInfo  : PPropInfo;
  i, vTag: Integer;
begin
  with aForm do
  begin
    for i := 0 to ComponentCount - 1 do
    begin
       if Components[i].ClassName <> 'TTimer'
       then
        begin
          if (GetPropInfo(Components[i].ClassInfo, 'Enabled') <> nil) and
             (GetPropInfo(Components[i].ClassInfo, 'Tag') <> nil)
             then
                begin
                  if GetOrdProp(Components[i], 'Tag') > UserAccessLevel
                   then SetOrdProp(Components[i], 'Enabled', Integer(False))

                  else
                    SetOrdProp(Components[i], 'Enabled', Integer(True));
                end;
        end;
    end;
  end;
end;

Neftali [Germán.Estévez] 22-07-2021 13:03:21

Cita:

Empezado por amadis (Mensaje 542029)
Y era un procedimiento que utilizo para Activar o Desactivar funciones se acuerdo al usuario logueado al sistema.
Y lo que hace el procedimiento es dar ENABLED TRUE, a los componentes de acuerdo a su TAG, y al valor asignado al usuario.

Y por si no me había dado cuenta los TIMER son un componente mas aunque invisibles... y también los estaba activando

Lo solucioné agregando el CLASSNAME del componente así.


Ojo a otros componentes "no visuales" que puedas estar afectando.
Estoy pensando en TAction, TrayIcon, HotKeys, Notificaciones,... que no deban verse afectados por temas visuales o de permisos...

El hecho de poner TODOS los ENABLED a True o False, me parece "peligroso" y fuente de problemas futuros.

amadis 22-07-2021 14:11:52

Tienes toda la Razón German.

Los tag por defecto de los Componentes siempre estan en 0 por lo que no se DESACTIVARIAN NUNCA.

El caso que justo me hizo saltar la alarma fue el TIMER, que deberia activarse cuando yo quiera.

De todas formas por seguridad agregaré las clases que mencionas.

¿o seria mejor si pudiera afectar solo a componentes visuales?

¿como puedo saber si un componente es visual??.

Neftali [Germán.Estévez] 23-07-2021 08:39:10

Cita:

Empezado por amadis (Mensaje 542037)
¿o seria mejor si pudiera afectar solo a componentes visuales?
¿como puedo saber si un componente es visual??.


Hay varios métodos de hacerlo.

Podrías utilizar las clases tal y como has hecho para filtrar las que no quieres que se vean afectadas.
En cuanto a los componentes visuales puedes probar a revisar las herencias. Se me ocurre que los componentes visuales "normalmente" derivan de TwinControl, pero habría que comprobar si esto se cumple en todos los casos. Y también revisarlo para componentes externos (si es que los usas).
También se podría revisaraquellos que poseen la propiedad Visible, aunque también habría que comprobar si se cumple en todos los casos.

amadis 23-07-2021 12:15:43

Creo que lo mejor es ir omitiendo las clases deseadas, ya que ahora caigo en que uso TActionManager (seria no visual) y lo uso y a las acciones dentro las activo o desactivo según el usuario con este procedimiento problemático.

Al González 02-08-2021 08:36:10

Hola a todos. Sí, de nuevo visitando los foros. :)

Subscribo lo dicho por Germán, y celebro la propuesta de usar el depurador de Miguel.

Cita:

Empezado por amadis (Mensaje 542010)
Me paré en la linea del If value del SetEnabled, le puse F5, marque punto de parada.

Y luego F9, pero no para nada, se ejecuta normalmente.

Esto seguramente es porque al compilar faltó recoger información de depuración. Asegúrate de generar el ejecutable con la opción "Use debug DCUs", eso te permitirá poner puntos de ruptura en el código fuente de las unidades nativas de la VCL.

Cita:

Empezado por amadis (Mensaje 542061)
Creo que lo mejor es ir omitiendo las clases deseadas

Yo te aconsejaría ir agregando las clases deseadas. Bajo la lógica de que es mejor que falte algo bueno y corregir, a que sobre algo malo, reparar daños y corregir. En la VCL, TControl (padre de TWinControl) es la clase base de todos los componentes visuales. Digamos que puedes ir agregando diferentes "ramas" que consideres completamente seguras, empezando con TControl si estás seguro de que todos y cada uno de los componentes visuales con propiedad Enabled deben entrar en el comportamiento que deseas.

Dos cosas más:
  • Siempre que puedas utiliza ClassType, InheritsFrom o el operador Is en lugar de ClassName; es más eficiente porque no comparas contra una cadena de caracteres.
  • Evita usar With, fuente potencial de muchos problemas.

Un abrazo por el interminable y magnífico Delphi. :)

Al González.

amadis 07-08-2021 01:10:57

Muchas gracias, la semana próxima volveré a revisar eso.

Por ahora eso quedó resuelto como decimos aquí los argentinos, a lo IGNACIO COPANI, Lo atamo con alambre....

Y esas ataduras a veces quedan mucho tiempo.

Pero reveré las cuestiones y comentare.

Gracias a todos


La franja horaria es GMT +2. Ahora son las 10:34:16.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi