Ir al contenido


Foto

Llamada entre ventanas usando un paquete


  • Por favor identifícate para responder
12 respuestas en este tema

#1 PittyDelphi

PittyDelphi

    Newbie

  • Miembros
  • Pip
  • 7 mensajes

Escrito 02 febrero 2011 - 01:28

Estoy usando un paquete (.bpl) que contiene todos los formularios que se usan en el proyecto. El problema se da así:

En el formulario 1 instancio el 2:



delphi
  1. fmFormularioDos:= TfmFormularioDos.Create(nil);



Ahora, cuando desde el formulario 2 quiero llamar al 1 o algún componente de este me da un error. Por ejemplo:



delphi
  1. if fmFormularioUno.cActividad.State = dsInsert then
  2.   begin
  3.       Self.Caption := 'Nueva Actividad';
  4.       cbTipo.ItemIndex := 0;
  5.       fmFormularioUno.cActividad.FieldByName('codactividad').Value := 0;
  6. end;



Usando un Try para obtener el mensaje técnico lo que obtengo es:

"AccessViolation at address 005BD9D0 in module 'Fuentes.bpl'. Read of address 000002F8'.

La dirección de memoria es donde esta la llamada al formulario 1. Lo que menciona de 'Fuentes.bpl' es lo que mencione donde están todos los formularios/fuentes que se usan en el proyecto.

Agradezco su ayuda.

Edito: Para asignar etiquetas Delphi
  • 0

#2 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 02 febrero 2011 - 01:34

Hola PittyDelphi, bienvenid@ a DelphiAccess

¿ No debe ser así ?



delphi
  1. fmFormularioDos:= TfmFormularioUNO.Create(nil);



Salud OS
  • 0

#3 andres1569

andres1569

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 431 mensajes

Escrito 02 febrero 2011 - 01:40

Bienvenido PittyDelphi,

¿podrías mostrar la linea donde creas el formulario 1? (mira en el código del proyecto a ver si está, menú Project - View source)

Saludos
  • 0

#4 Caral

Caral

    Advanced Member

  • Moderador
  • PipPipPip
  • 4.266 mensajes
  • LocationCosta Rica

Escrito 02 febrero 2011 - 01:47

Hola
Me da la impresion de que es que no estan enlazados los formularios en el uses, osea, las unit de estos.
Por otro lado, no deberia de llamarse asi:


delphi
  1. FmFormularioDos:=TFmFormularioDos.Create(self);
  2.   try
  3.       FmFormularioDos.ShowModal;
  4.   finally
  5.       FmFormularioDos.Free;
  6.   end;


Saludos
  • 0

#5 PittyDelphi

PittyDelphi

    Newbie

  • Miembros
  • Pip
  • 7 mensajes

Escrito 02 febrero 2011 - 01:49

Bienvenido PittyDelphi,

¿podrías mostrar la linea donde creas el formulario 1? (mira en el código del proyecto a ver si está, menú Project - View source)

Saludos


¡Muy buena pregunta!

Es un menú dinámico, que se hace a partir de filtros por rol de usuario. Luego, se hace una llamada al paquete (un único paquete que tiene más de 100 formularios, todos los de la aplicación) al formulario especifico. El código que corresponde al click en un item del menú (el que llama al formulario uno digamos) es el siguiente:



delphi
  1. procedure TfmMenu.tbbuttonClick(Sender: TObject);
  2. begin
  3.   with TFormClass(FindClass(TToolButton(sender).Name)).Create(self) do
  4.   begin
  5.     ShowModal;
  6.     Free;
  7.   end;
  8. end;


  • 0

#6 PittyDelphi

PittyDelphi

    Newbie

  • Miembros
  • Pip
  • 7 mensajes

Escrito 02 febrero 2011 - 01:52

Hola
Me da la impresion de que es que no estan enlazados los formularios en el uses, osea, las unit de estos.
Por otro lado, no deberia de llamarse asi:


delphi
  1. FmFormularioDos:=TFmFormularioDos.Create(self);
  2.   try
  3.       FmFormularioDos.ShowModal;
  4.   finally
  5.       FmFormularioDos.Free;
  6.   end;


Saludos


Eso creo que esta bien. Es proyecto con el que trabajo es uno común, donde al comienzo se instancian todos los formularios y después se van llamando entre sí, como bien mencionas, agregando la referencia en el uses (lo mismo con los modulos). Si la referencia no existe en el uses no se puede compilar :)

Pero la cosa viene por ahí, al trabajar con paquetes es como que no queda enlazadas o registradas en la aplicación.
  • 0

#7 andres1569

andres1569

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 431 mensajes

Escrito 02 febrero 2011 - 01:59

Pues efectivamente te falta asociar ese formulario que has creado a la variable fmFormularioUno, aunque veo que usas una forma genérica de crear los formularios y deberías asociar cada vez cada variable con su formulario correspondiente  ^o|




delphi
  1. procedure TfmMenu.tbbuttonClick(Sender: TObject);
  2. var
  3.   AForm : TCustomForm;
  4. begin
  5. // almacenamos en una variable el formulario recién creado
  6.   AForm := TFormClass(FindClass(TToolButton(sender).Name)).Create(self);
  7. // si es de la clase TfmFormularioUNO lo asociamos a la variable correspondiente
  8.   if AForm is TfmFormularioUNO then fmFormularioUNO := TfmFormularioUNO(AForm);
  9.   with AForm do
  10.   begin
  11.     ShowModal;
  12.     Free;
  13.   end;
  14. end;



Obviamente, esto es un engorro que supone hacer la misma comprobación para cada formulario que crees, rompiéndote esa dinámica de crear formularios genéricos según el nombre del Botón, si quieres esa flexibilidad quizás debieras programarte una rutina que comparara cada vez el nombre, o la clase, del formulario recién creado y que haga las oportunas asignaciones a dichas variables


  • 0

#8 PittyDelphi

PittyDelphi

    Newbie

  • Miembros
  • Pip
  • 7 mensajes

Escrito 02 febrero 2011 - 02:03

Pues efectivamente te falta asociar ese formulario que has creado a la variable fmFormularioUno, aunque veo que usas una forma genérica de crear los formularios y deberías asociar cada vez cada variable con su formulario correspondiente  ^o|




delphi
  1. procedure TfmMenu.tbbuttonClick(Sender: TObject);
  2. var
  3.   AForm : TCustomForm;
  4. begin
  5. // almacenamos en una variable el formulario recién creado
  6.   AForm := TFormClass(FindClass(TToolButton(sender).Name)).Create(self);
  7. // si es de la clase TfmFormularioUNO lo asociamos a la variable correspondiente
  8.   if AForm is TfmFormularioUNO then fmFormularioUNO := TfmFormularioUNO(AForm);
  9.   with AForm do
  10.   begin
  11.     ShowModal;
  12.     Free;
  13.   end;
  14. end;



Obviamente, esto es un engorro que supone hacer la misma comprobación para cada formulario que crees, rompiéndote esa dinámica de crear formularios genéricos según el nombre del Botón, si quieres esa flexibilidad quizás debieras programarte una rutina que comparara cada vez el nombre, o la clase, del formulario recién creado y que haga las oportunas asignaciones a dichas variables


¡Muchas gracias! Lo voy a probar y les cuento como me fue.
  • 0

#9 PittyDelphi

PittyDelphi

    Newbie

  • Miembros
  • Pip
  • 7 mensajes

Escrito 02 febrero 2011 - 02:37


Pues efectivamente te falta asociar ese formulario que has creado a la variable fmFormularioUno, aunque veo que usas una forma genérica de crear los formularios y deberías asociar cada vez cada variable con su formulario correspondiente  ^o|




delphi
  1. procedure TfmMenu.tbbuttonClick(Sender: TObject);
  2. var
  3.   AForm : TCustomForm;
  4. begin
  5. // almacenamos en una variable el formulario recién creado
  6.   AForm := TFormClass(FindClass(TToolButton(sender).Name)).Create(self);
  7. // si es de la clase TfmFormularioUNO lo asociamos a la variable correspondiente
  8.   if AForm is TfmFormularioUNO then fmFormularioUNO := TfmFormularioUNO(AForm);
  9.   with AForm do
  10.   begin
  11.     ShowModal;
  12.     Free;
  13.   end;
  14. end;



Obviamente, esto es un engorro que supone hacer la misma comprobación para cada formulario que crees, rompiéndote esa dinámica de crear formularios genéricos según el nombre del Botón, si quieres esa flexibilidad quizás debieras programarte una rutina que comparara cada vez el nombre, o la clase, del formulario recién creado y que haga las oportunas asignaciones a dichas variables


¡Muchas gracias! Lo voy a probar y les cuento como me fue.


Sigue dando el mismo error de AccessViolation que ponía en un primer momento. Hice un código de prueba y puse 'a mano' el formulario que se tiene que abrir. Se abre bien, pero al querer mostrar en pantalla un dato del formulario desde que lo cree da error.

Estaba viendo que no se como aplicar esto en el menú principal ya que me parece que tengo que poner el nombre del formulario en el uses y ahí ya se registra al iniciar la aplicación.

¿Alguna otra idea? Sí tienen ejemplos de trabajar con paquetes y llamadas entre ventana también son bienvenidos. Soy un poco novato en esto todavía
  • 0

#10 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.486 mensajes
  • LocationMexico City

Escrito 02 febrero 2011 - 02:55

Amig@ PittyDelphi...

Una pregunta:

La referencia que haces desde el formulario 2 al formulario 1, quiero suponer que es necesaria porque el formulario 1 tiene datos necesarios para que el formulario 2 trabaje... Estoy en lo cierto ?

Saludox ! :)
  • 0

#11 PittyDelphi

PittyDelphi

    Newbie

  • Miembros
  • Pip
  • 7 mensajes

Escrito 04 febrero 2011 - 05:49

Amig@ PittyDelphi...

Una pregunta:

La referencia que haces desde el formulario 2 al formulario 1, quiero suponer que es necesaria porque el formulario 1 tiene datos necesarios para que el formulario 2 trabaje... Estoy en lo cierto ?

Saludox ! :)


Claro, suelen ser datos del formulario (un item seleccionado en un combo o un campo) o consultas/datos de algún componente TSQLDataSet u otro. Estos datos son necesarios para mostrar datos en pantalla o para hacer una nueva consulta.

La solución inmediata que encontré es, cuando instancio el formulario 2, setear los datos que necesito desde el formulario 1 y después trabajar con ellos. El problema se da cuando trabajo con una grilla (insertar o editar) ya que estoy accediendo directamente al componente del formulario 1 para agregar un dato.

Saludos
  • 0

#12 andres1569

andres1569

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 431 mensajes

Escrito 04 febrero 2011 - 10:29

Hola PittyDelphi:

Por si las moscas, y volviendo a tu mensaje inicial, dices que te salta el error en la linea donde accedes al formulario 1, pero ahí pudiera saltar un AV también al acceder a un campo que no existiera, ¿te salta en la primera sentencia del código o cuando llamas a FiledByName?



delphi
  1. if fmFormularioUno.cActividad.State = dsInsert then
  2.   begin
  3.       Self.Caption := 'Nueva Actividad';
  4.       cbTipo.ItemIndex := 0;
  5.       fmFormularioUno.cActividad.FieldByName('codactividad').Value := 0;
  6. end;



Haz la siguiente prueba, en vez de acceder directamente al campo obtenido con FieldByName, guarda en una variable el resultado de llamar a FindField, y trata de averiguar (mostrando un mensajito por ejemplo) si es nil o si tiene un valor válido.



delphi
  1. var
  2.   AField : TField;
  3. begin
  4.   if fmFormularioUno.cActividad.State = dsInsert then
  5.   begin
  6.     Self.Caption := 'Nueva Actividad';
  7.     cbTipo.ItemIndex := 0;
  8.     AField := fmFormularioUno.cActividad.FindField('codactividad');
  9.     if Assigned(AField) then AField.Value := 0
  10.     else ShowMessage('No existe el campo ' + QuotedStr(codactividad));
  11.   end;
  12. end;



Saludos
  • 0

#13 PittyDelphi

PittyDelphi

    Newbie

  • Miembros
  • Pip
  • 7 mensajes

Escrito 06 febrero 2011 - 05:18

Hola PittyDelphi:

Por si las moscas, y volviendo a tu mensaje inicial, dices que te salta el error en la linea donde accedes al formulario 1, pero ahí pudiera saltar un AV también al acceder a un campo que no existiera, ¿te salta en la primera sentencia del código o cuando llamas a FiledByName?



delphi
  1. if fmFormularioUno.cActividad.State = dsInsert then
  2.   begin
  3.       Self.Caption := 'Nueva Actividad';
  4.       cbTipo.ItemIndex := 0;
  5.       fmFormularioUno.cActividad.FieldByName('codactividad').Value := 0;
  6. end;



Haz la siguiente prueba, en vez de acceder directamente al campo obtenido con FieldByName, guarda en una variable el resultado de llamar a FindField, y trata de averiguar (mostrando un mensajito por ejemplo) si es nil o si tiene un valor válido.



delphi
  1. var
  2.   AField : TField;
  3. begin
  4.   if fmFormularioUno.cActividad.State = dsInsert then
  5.   begin
  6.     Self.Caption := 'Nueva Actividad';
  7.     cbTipo.ItemIndex := 0;
  8.     AField := fmFormularioUno.cActividad.FindField('codactividad');
  9.     if Assigned(AField) then AField.Value := 0
  10.     else ShowMessage('No existe el campo ' + QuotedStr(codactividad));
  11.   end;
  12. end;



Saludos


Hola Andres! Gracias por la respuesta. Lo he intentado y el error salta ni bien se hace referencia al formulario uno. Puede ser al llamar un campo o en un bloque de código donde se utiliza el formulario para hacer distintas llamadas. Por eso tengo la idea de que no queda registrado en memoria porque directamente no se puede acceder para nada.

Saludos
  • 0




IP.Board spam blocked by CleanTalk.