Hello Bruno,
Saturday, June 20, 2009, 3:19:30 AM, you wrote:
BL> Compilo ok ahora y ejecuto
BL> pero al hacer click en el menu clientes
BL> Project raised exception 'External : SIGSEGV' BL> Esto es lo que ejecuta el click de menu:
BL> procedure TForm1.clientesClick(Sender: TObject); BL> begin
BL> FormCli.showmodal;
BL> end;
A ver, hay una gran diferencia entre definir un form, esto es sus controles y comportamiento, y otra instanciarlo. Haciendo el uses xxx; lo que haces es incluir la definici�n del form clientes en el form que est�s usando, pero nada m�s, por decirlo de otro modo "FormCli" apunta a una zona de memoria indeterminada y por lo tanto erronea.
C�mbialo por:
procedure TForm1.clientesClick(Sender: TObject);
var
InstancedFormCli: TFormCli;
begin
InstancedFormCli:=TFormCli.Create(Self);
InstancedFormCli.showmodal;
InstancedFormCli.Free;
end;
Resumiendo el c�digo, creas una copia de la definici�n de FormCli llamada "InstancedFormCli" (como si le quieres llamar Juan), despu�s le dices que la instancia (inicialice), luego que la muestre en modo modal, y al final que la libere.
Existe cierta tendecia malsana de la gente que viene de los primeros Delphi y de otros lenguajes tipo VB a crear todos los formularios en el arranque pero dej�ndolos invisibles y luego mostrarlos y ocultarlos seg�n convenga. Esto es un gasto de recursos brutal en algunos casos. Un form s�lo definido ocupa unos 4 bytes de memoria, instanciado puede ocupar megas.
Cada vez que defines un form, tanto delphi como Lazarus crean una variable global que es una definici�n del form (4 bytes), que ver�s en el c�digo del form, despu�s del "type", m�s abajo, ver�s "var FormCli: TFormCli", eso se usa para que Lazarus pueda crear una instancia de ese form autom�ticamente nada m�s arrancar si as� se lo mandas. Esto va bien si tienes que tener s�lo una instancia de cada form, pero muy mal por que hace creer al programador que esa es la �nica instancia posible del form.
Para ponerte un ejemplo, la funci�n de arriba c�mbiala por:
procedure TForm1.clientesClick(Sender: TObject);
var
InstancedFormCli: TFormCli;
Count: SizeInt;
begin
for Count:=1 to 20 do begin
InstancedFormCli:=TFormCli.Create(Self);
InstancedFormCli.Show;
end;
end;
Lazarus te ha creado 20 forms iguales pero independientes y encima has perdido el control individual de cada uno de ellos, ya que InstanceFormCli s�lo apunta al �ltimo. Puedes cerrarlos todos uno a uno, pero si cierras el principal (Form1) ver�s que los cierra todos de golpe, ya que L�zarus si sabe cuales est�n abiertos (lo apunta internamente).
Resumiendo, suele ser una buena t�cnica de programaci�n no usar la variable que define el form por defecto excepto en el form principal o en el caso seguro de que no van a existir m�s de una representaci�n de ese form a lo largo de todo el programa. A�n as� no debemos olvidarnos de comprobar si debemos instanciarlo cada vez que queramos mostrarlo. Una buena t�cnica que suele simplificar esto cuando usamos ShowModal habitualmente es:
procedure TForm1.clientesClick(Sender: TObject);
begin
if not Assigned(FormCli) then begin
FormCli:=TFormCli.Create(Self);
end;
FormCli.ShowModal;
FreeAndNIL(FormCli);
end;
De este modo si el form est� instanciado, lo muestra y despu�s lo libera. Si no est� instanciado, lo instancia, lo muestra y lo libera.
Best regards,
JoshyFun