PDA

Ver la Versión Completa : Acces Violation al Crear Form


Neeruu
07-12-2017, 03:11:41
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.

ComponentsColorDataSetStatus(DataSource1.DataSet.State,Form1);


El procedimiento es este:


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


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, 18: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, 17:07:46
Hola Gracias por tu respuesta.

Para cerrar mis formularios lo hago con un close.
Y en el evente onclose del formulario tengo
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, 18: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, 19:38:49
Estas usando variables globales para los formularios? Como creas los dos formularios que mencionas?

Neeruu
11-12-2017, 15: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, 14:20:18
Doy y doy vueltas y no puedo encontrar porque se me produce el error... y la verdad me tiene desconcertado...