PDA

Ver la Versión Completa : Evento de formulario posterior a onshow


apicito
11-06-2004, 13:43:44
No se si habrá algun evento en un formulario que se lance despues del onshow y que permita cerrar el formulario. El Objetivo es poder cerrarlo o no en función de lo que haya pasado durante el evetno onshow.

__cadetill
11-06-2004, 13:59:21
Quizás podría servirte el Loaded, protegido en el padre.


type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure FormKeyPress(Sender: TObject; var Key: Char);
private
{ Private declarations }
public
{ Public declarations }
procedure Loaded; override;
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Loaded;
begin
inherited;

end;


O si nos explicas las condiciones quizás alguna otra manera (incluso no llegar a crear el formulario haciendo las comprovaciones antes)

apicito
11-06-2004, 14:19:06
En el form padre creo el formulario, después le asigno valores a una variables públicas y con esas variables publicas, en el onshow hago comprobaciones en la base de datos. El problema es que algunas veces, como consecuencia de esas comprobaciones, me interesa hacer un showmessage y cerrar el formulario, pero no lo consigo ya que en el onshow no funciona el close.

__cadetill
11-06-2004, 14:26:29
Vale, bien..... y no te sería más sencillo hacer las comprovaciones antes de mostrar el formulario (antes del Show)??


procedure TForm1.Button1Click(Sender: TObject);
begin
Form2 := TForm2.Create(Application);
try
// Como el formulario lo tengo creado, puedo acceder a sus variables
// públicas y hacer las comprovaciones necesarias en este punto
// y si las comprovaciones no me interesan, sencillamente no hago
// el Show (o ShowModal) de la ventana y me limito a liberarla
if Comprovaciones then
Form2.Show;
finally
FreeAndNil(Form2);
end;
end;

Espero te sirva

apicito
11-06-2004, 14:29:15
En la creación del formulario la hago por referencia, ya que se llama muchos formularios distintos y con distintas comprobaciones, entonces las comprobaciones las tengo que hacer en el formulario hijo.

apicito
11-06-2004, 14:33:39
mira el procedimiento de llamada:
if Sender.ClassType = TToolButton then
FormaClase:=TExpFormClass(GetClass('TExp'+inttostr((Sender as TToolButton).Tag)))
else if Sender.ClassType = TMenuItem then
FormaClase:=TExpFormClass(GetClass('TExp'+inttostr((Sender as TMenuItem).Tag)))
else
Exit;
if FormaClase<>nil then
begin
Forma:=FormaClase.Create(Self);
Forma.codigo:=0;
Forma.Expte:=QueryDia.fieldbyName('EXPDIA_CODIGO').AsInt64;
Forma.Modo:='A';
Forma.Part:=Part;
Forma.Tipo:='EXP'+Part+QueryDia.fieldbyName('EXPDIA_TIPO').AsString;
Forma.ExpAno:=EAno.Text;
Forma.ExpNum:=ENumero.Text;
Forma.Idioma:=Idioma;
Forma.Dni:=EDni.Text;
Forma.DniDup:=EDniDup.Text;
Forma.ShowModal;

__cadetill
11-06-2004, 15:28:14
Bien, si es así, podrías mirar de usar un truquillo con el evento OnActivate


procedure TForm1.FormActivate(Sender: TObject);
begin
// Si las comprovaciones me hacen cerrar el formulario, pos se cierro
if comprovaciones then
Close;

// Sólo quiero que se lance una vez este evento, así que quito el OnActivate
OnActivate := nil;
end;


A ver ahora que tal ;)

apicito
11-06-2004, 16:31:25
Gracias 1000.

marto
11-06-2004, 17:13:39
Wop!

Aunque el truco que te comenta Cadetill funciona a las 100 maravillas, aquí te dejo otra manera de hacerlo. Para mi es mejor, porque se usa un método explícito de la clase en lugar del evento OnActivate. Cuando busques en el proyecto tras dos años, te será mucho más fácil de seguir.
La ides es definir una interfaz que contenga un solo método:

type IValidaForm = interface
function Valida: Boolean;
end;


El form que queremos que pueda "autovalidarse" antes de mostrarse, lo declaramos implementando la interfaz:


type TForm1 = class(TForm, IValidaForm)
...
public Valida: Boolean;
..
end;

implementation

public TForm1.Valida: Boolean;
begin
Result := MisCondiciones;
end;


Ahora solo nos queda controlar la validación desde el form "padre":


procedure TFormPadre.MuestraHijo;
begin
with TForm1.Create(Self) do
begin
try
if Valida then
ShowModal;
finally
Free;
end;
end;
end;


Esto mismo lo podrías hacer sin interfaz, simplemente creando el método Valida en el form. La potencia que te da este mecanismo aparece cuando necesitas que varios forms tengan este comportamiento y no necesariamente tenga que derivar de una misma clase. Puedes crear un procedimiento para crear los forms:

function CreateValidaForm(FormClass: TFormClass): TForm;
var
IForm: IValidaForm;
begin
Result := FormClass.Create(Self);
if Succeded(Result.QueryInterface(IValidaForm, IForm) and
IForm.Valida then
Result.ShowModal
else
FreeAndNil(Result);
end;

roman
11-06-2004, 18:04:01
No se si habrá algun evento en un formulario que se lance despues del onshow y que permita cerrar el formulario.

El evento en sí no existe pero lo puedes crear tú mismo como muestro en el mensaje http://www.clubdelphi.com/foros/showpost.php?p=23759&postcount=6

// Saludos

ruina
17-06-2004, 18:32:38
Aunque no os lo creais no me vale ninguno de los trucos ateriores en este caso particular, os explico:

Bien, estamos en una aplicacion CLX (delphi 7.0 - kylix 3), y quiero (lease me obligan) una pantalla de selección Pre-formulario principal, el caso es que si pulsan cerrar en ese pre-form no debo sacar el formulario principal, cerrando la aplicación.

¿por qué no puedo hacer que la pantalla "pre" sea la principal y esconderla?
porque no se que pasa pero el comportamiento de las ventanas en clx es ligeramente diferente y en cuanto la aplicación pierde el foco al volver sale siempre la pantalla "pre". Y si hago un hide desaparece de la barra de tareas.

El truco del Activate me da siempre una excepcion.



El truco de los mensages ya lo habia usado antes y funciona muy bien pero... estamos en una aplicación CLX y aqui son QMessages y yo no he conseguido poner un mensage a la cola, siempre me saltan de inmediato.

Ahora voy a intentar
plan a) enredar en dpr (Application.Initialize...) a ver si consigo mostrar la pre y cerrar la aplicación si le dan a salir.

plan b) poner un timer, activarlo en el OnShow y cerrar el form (¡¡peazo de plan b!!)

ya os contaré

marto
17-06-2004, 19:03:02
mmmm opción a:

program Project2;

uses
QForms,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2};

{$R *.res}

begin
Application.Initialize;
Form1 := TForm1.Create(Application);
if (Form1.ShowModal = 1) then
begin
Form1.Free;
Form2 := TForm2.Create(Application);
Form2.ShowModal;
end;
Application.Run;
end.


probado y chuta ;)

ruina
18-06-2004, 10:58:20
Perfecto!

justo ayer por la tarde me salio lo mismo ^_^ para mi que me mandaste la solusión telepaticamente.

Muchas Gracias a todos