Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Acces Violation al Crear Form (https://www.clubdelphi.com/foros/showthread.php?t=92600)

Neeruu 07-12-2017 04:11:41

Acces Violation al Crear Form
 
Hola a todos...

Les comento un problema que me trae un par de días dando vueltas y vueltas y no puedo solucionarlo.

Tengo un sistema grande, con cerca de 270 formularios y un modulo de datos con 130 querys aprox.
Utilizo para conectarme a Firebird 2.1, los tibobjects. (TIBOQuerys)
Utilizo delphi 2010.

Cuando creo un formulario, en el create del form instancio el modulo de datos (para cada formulario) y abro el query., Este Tiboquery, esta enlazado a los componetes por medio de un tdatasource.
En el evento StateChange del datasource llamo a una procedimiento que me pinta los componentes de color según el estado del dataset.
Código Delphi [-]
ComponentsColorDataSetStatus(DataSource1.DataSet.State,Form1);

El procedimiento es este:

Código Delphi [-]
Procedure ComponentsColorDataSetStatus(myState:TDataSetState; MyForm: TControl);
Var i:Integer;
myColor, myColorReadOnly:TColor;
  procedure ChangeColorComponent(myComponent:TComponent);
    begin
      if myComponent is TcxDBSpinEdit then
        begin
          if Not TcxDBSpinEdit(myComponent).Properties.ReadOnly then
            TcxDBSpinEdit(myComponent).Style.Color := myColor
          else TcxDBSpinEdit(myComponent).Style.Color := myColorReadOnly;
        end
      else
      if myComponent is TcxDBTextEdit then
        begin
          if Not TcxDBTextEdit(myComponent).Properties.ReadOnly then
            TcxDBTextEdit(myComponent).Style.Color := myColor
          else TcxDBTextEdit(myComponent).Style.Color := myColorReadOnly;
        end
      else
      if myComponent is TcxDBLookupComboBox then
        begin
          if Not TcxDBLookupComboBox(myComponent).Properties.ReadOnly then
            TcxDBLookupComboBox(myComponent).Style.Color := myColor
          else TcxDBLookupComboBox(myComponent).Style.Color := myColorReadOnly;
        end
      else
      if myComponent is TcxDBMemo then
        begin
          if Not TcxDBMemo(myComponent).Properties.ReadOnly then
            TcxDBMemo(myComponent).Style.Color := myColor
          else TcxDBMemo(myComponent).Style.Color := myColorReadOnly;
        end
      else
      if myComponent is TcxDBDateEdit then
        begin
          if Not TcxDBDateEdit(myComponent).Properties.ReadOnly then
            TcxDBDateEdit(myComponent).Style.Color := myColor
          else TcxDBDateEdit(myComponent).Style.Color := myColorReadOnly;
        end
      else
      if myComponent is TcxDBCurrencyEdit then
        begin
          if Not TcxDBCurrencyEdit(myComponent).Properties.ReadOnly then
            TcxDBCurrencyEdit(myComponent).Style.Color := myColor
          else TcxDBCurrencyEdit(myComponent).Style.Color := myColorReadOnly;
        end
      else
        if myComponent is TcxDBButtonEdit then
          if Not TcxDBButtonEdit(myComponent).Properties.ReadOnly then
            TcxDBButtonEdit(myComponent).Style.Color := myColor
          else TcxDBButtonEdit(myComponent).Style.Color := myColorReadOnly;
    end;
begin
  if (MyForm = nil) then Exit;

  Case myState of
    dsInactive: myColor := clGray;
    dsBrowse  : myColor := clWindow;
    dsEdit    : myColor := $00BFDFFF;//$00B7DBFF;
    dsInsert  : myColor := $00F0DBCE;//$00C5DEC9;
  end;

  myColorReadOnly := clSilver;

  if ((myState = dsInactive) or
     (myState = dsBrowse) or
     (myState = dsEdit) or
     (myState = dsInsert)) then
    begin
      if myForm is TForm then //--> Esta es la linea.
        begin
          for I := 0 to TForm(myForm).ComponentCount - 1 do
            begin
              ChangeColorComponent(TForm(myForm).Components[i]);
            end;
        end
      else
      if myForm is TFrame then
        begin
          for I := 0 to TFrame(myForm).ComponentCount - 1 do
            begin
              ChangeColorComponent(TFrame(myForm).Components[i]);
            end;
        end;
    end;

Repacemos el circuito:
Creo el Form1.
En el Create Hago el OPen del query que esta en el modulo de datos.
Al hacer el open se ejecuta el evento de StateChange del datasource.
Y en el evento llamo al procedimiento ComponentsColorDataSetStatus(DataSource1.DataSet.State,Form1);
Hasta aca todo espectacular anda en todos los formularios de mi proyecto sin ningun problema.

Resulta que agregue un nuevo form (Vamos a llamarlo Form1) al proyecto y lo configure como comento arriba.
Pero resulta que detecte que si abro el Form1, luego lo cierro, abro el FormularioX, cierro el FormularioX y vuelvo a Abrir el Form1 se produce un error en
la linea

Código Delphi [-]
 if myForm is TForm then

del procedimiento que cambia los colores.

Aclaro que el FormularioX es siempre el mismo formulario, por lo que en principio creí que podría haber alguna relación entre ambos.

Ustedes dirán que puede ser algo que quede mal en el FormularioX, lo cambie, desde cero, es mas, no puse ningún control, solo la apertura del query de FormularioX. Lo mismo con el Form1, desde cero, sin ningún componente, solo la apertura del query.

Llegue a pensar que podía ser un problema de la base de datos, primero cambie el query a otra tabla, cambie la base de datos.
Y el problema esta en el FormularioX con el Form1, en ningún otro lado tengo este problema siendo que trabajo de la misma forma para todos los formularios.

Lo único que me queda pensar es alguna restricción en la memoria, en la cantidad de objectos en el modulo de datos, en la cantidad de formularios en un proyecto.
La verdad no se donde esta el problema.

Necesito ideas para seguir buscando. Espero se les ocurra algo...

Saludos.

maeyanes 07-12-2017 19:59:14

Hola...

Podría ser que la variable myForm esté haciendo referencia a una zona de memoria no usada o liberada anteriormente, esto es, el hacer Form1.Free, libera la memoria, pero no limpia la referencia a esa memoria. Esto sin saber exactamente cual es el mensaje de error y como haces para cerrar tus formularios.


Saludos...

Neeruu 08-12-2017 18:07:46

Hola Gracias por tu respuesta.

Para cerrar mis formularios lo hago con un close.
Y en el evente onclose del formulario tengo
Código Delphi [-]
Action := caFree;

Justamente el error se produce porque al procedimiento la Variable Form1 llega vació, pero no se porque pasa eso cuando abro el FormularioX, si no abro el FormularioX todo anda bien...

maeyanes 08-12-2017 19:06:11

Hola...

Entonces hay algo en FormularioX que "ensucia" la variable Form1... tendrías que seguir paso a paso la ejecución de tu programa desde que se abre FormularioX hasta que mandas a llamar la función donde te marca la excepción para poder encontrar el problema...



Saludos...

AgustinOrtu 08-12-2017 20:38:49

Estas usando variables globales para los formularios? Como creas los dos formularios que mencionas?

Neeruu 11-12-2017 16:01:46

Hola, si utilizo las variables que se crean cuando se crea el formulario...

ejemplo: Form1:TForm1;

y para crearlos:

From1 := TForm1.create(Self);

Neeruu 12-12-2017 15:20:18

Doy y doy vueltas y no puedo encontrar porque se me produce el error... y la verdad me tiene desconcertado...


La franja horaria es GMT +2. Ahora son las 13:09:24.

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