Colegas Ismael y Maxi:
Disculpen mi intromisi�n en su excelente colaboraci�n pero quisiera compartir con ustedes la forma en que generalmente trato de hacer estas cosas
Supongamos que vamos a desarrollar un proyecto que tenga los siguientes requerimientos funcionales:
0- Gesti�n de Base de Datos.
1- Impresi�n de informaci�n (reportes).
1- Multiusuario.
2- Varias interfaces de trabajo (formularios).
�Como lo hago?
0- Los siguientes formularios son creados automaticamente por el proyecto:
a) Ventana principal
b) Modulo de datos (TDataModule)
c) Formulario para creaci�n de reportes si se utiliza el entorno gr�fico del IDE para especificar sus propiedades. Tambi�n utilizo unidades en caso que toda la generaci�n de los reportes se implemente por c�digo
d) Una unidad en la que implemento todos los procedimientos y funciones de alcance general es decir que puedan ser necesarias en diferentes momentos.
e) Creaci�n y destrucci�n de las restantes interfaces en el momento que son requeridas, tengamos en cuenta que todo lo que inicialicemos, variables e instancias de clases consumen memoria. f) Seg�n sea necesario incluyo en la clausula �uses� de las interfaces descritas en en el inciso �B� las correspondientes a los incisos: b, c, d.
Un ejemplo:
tengo un proyecto con 4 clases:
0- TForm principal
1- TForm de login
2- TDatamodule
3- Unidad de funciones
El fuente del proyecto quedar�a as�:
Application.Initialize;
Application.CreateForm(TdmDatos, dmDatos);
Application.CreateForm(TfrmMain, frmMain);
Application.Run;
Como ven llamo al TDataModule (dmDatos) antes del TForm principal (frmMain),con esto garantizo cargar al menos la conexi�n a la BD y las tablas: usuarios y privilegios de usuarios.
----------------------------------------------------------------
En el evento OnCreate del formulario principal llamo al form que gestiona usuarios y aplica sus privilegios en el programa
procedure TfrmMain.FormCreate(Sender: TObject);
begin
Application.CreateForm(TfrmLogin, frmLogin);
frmLogin.ShowModal;
frmLogin.Free;
end;
----------------------------------------------------------------
En la clausula uses de frmLogin incluyo la unidad que almacena mis funciones generales y los objetos de BD :
uses module, functions;
Esto me permite llamar al la funci�n de verificaci�n de privilegios implementada en la unidad �functions� y que afecta a la ventana principal �frmMain� en el evento OnClick del bot�n �aceptar� en frmLogin
procedure TfrmLogin.btnAceptClick(Sender: TObject); begin
{
verificar usuario y contrase�a
si coinciden entonces llamar a la funci�n
que verifica privilegios y cerrar el TForm
env�o como argumento el �id� del usuario
}
usersConcession(id);
frmLogin.Close;
{
en caso contrario notificaci�n del error en los datos de
inicio de sesi�n
}
end;
----------------------------------------------------------------
La unidad con mis funciones generales quedar�a as�:
unit functions;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Process, Forms, Controls, Dialogs, ZConnection, ...
procedure usersConcession(User : Integer);
...
implementation
uses module, main;
procedure usersConcession(User : Integer);
var
access : Boolean;
begin
{
Hacer la rutina para el chequeo de privilegios
por usuario para luego habilitar/deshabilitar
objetos seg�n necesidad, asignando el valor
(True o False) a la variabnle �access�.
}
with frmMain do
begin
{
habilitando/deshabilitando un objeto del tipo
TAction en la ventana principal, la ventaja de
utilizar este tipo de objeto y enlazarlos con los
TMenuItem y los TToolButton es que deshabilitando el
TAction se inhabilitan los TMenuItem y los TToolButton
relacionados.
}
...
actConfig.Enabled := access;
...
end;
end;
----------------------------------------------------------------
Un trozo del modulo de datos, en el evento OnCreate establezco la conexi�n a la Base de Datos.
...
TdmDatos = class(TDataModule)
connect: TZConnection;
qryTmp: TZQuery;
...
procedure DataModuleCreate(Sender: TObject);
...
procedure TPerpe.DataModuleCreate(Sender: TObject);
begin
with connect do begin
Database := '/ruta/a/base/de/datos';
Protocol := 'sqlite-3';
Connected := True;
end;
end;
Saludos,
Maikel
El mar, 21-07-2015 a las 16:36 -0400, Ismael L. Donis Garcia escribi�:
Show quoted text 366 lines
Respondo entre L�neas
========
| ISMAEL |
========
Only for the small landowners and Cubans companies
Website: www.sisconge.byethost15.com
www.sisconge.hol.es
>----- Original Message -----
>From: "Maxi" <maximiliano.duarte en gmail.com>
>To: "Spanish version of Lazarus List"
><lazarus-es en lists.lazarus.freepascal.org>
>Sent: Monday, July 20, 2015 4:25 PM
>Subject: Re: [Lazarus-es] Error en formularios y lazreport
>
>es porque en algun momento estas llamando algo que ya se destruy� o el
>reporte intenta acceder a algo que no puede.
>
>Cada formulario tiene una variable publlica con el objeto por lo que
>si puedes llamarlo.
>
>Si Tdm.IniSis(); se usa para iniciar para que lo vuelves a llamar?
Porque al logearte seleccionas la unidad en la que vas a trabajar, y seg�n
el usuario que te logees seran los permisos que tengas y a las opciones del
sistema que puedas entrar y que tengas visibles en los menus.
>Te digo como hago siempre yo en mis aplicaciones
>
>Desde el proyecto dejo crear automaticamente:
>Modulo de datos con conexion a DB solamente
>->Antes del seguir valido el usuario sino cierro todo
>Modulo de datos con tablas y consultas
>Modulo de datos con lookups
>Formulario principal
Tengo antes un formulario de informaci�n que es el splash
Despu�s un formulario de logeo donde seleccionas la entidad en la que vas a
trabajar y se logea el usuario con el sistema
Y despu�s de logeado es que entra el formulario principal.
>Despues de iniciar recien llamo al resto de cosas despues de iniciar
>el form principal. Y uso herencia de formularios, me ahorra mucho
>codigo y configuraciones.
>Lo que not� que el splash lo creas pero no lo destruyes. y si un
>formulario lo vas a recrear luego he visto que usan .FreeAndNil.
>Por eso es mejor crearlo en en proyecto y destruirlo lo antes posible.
Si lo destuyo lo que lo hago en otro procedimieto que no te lo hav�a puesto
por no considerarlo necesario:
procedure Tdm.entrar();
begin
if length(struser) = 0 then struser := 'administrador';
if (cnsc.Connected or cnsch.Connected or cnos.Connected) then
FinConexServer();
IniConexServer;
Application.CreateForm(Tflogin, flogin);
flogin.ShowModal;
flogin.Free;
if blnend then
cerrarme()
else
begin
fconta.lblestado.Caption := 'Listo';
fconta.Show;
fsplash.Free;
end;
end;
>
>cambia la creacion:
>Application.CreateForm(Tfconta, fconta);
>por
>Tfconta.Create(Application);
>
No lo puedo hacer porque sino falla el siguiente procedimieto que est�
dentro del formulario "flogin" ya que no encuentra inicialzado al formulario
"fconta"
procedure Tflogin.mnuother(buser: boolean);
begin
with fconta do begin
mnuherod.Visible := buser;
mnuherbh.Visible := buser;
mnuhercs.Visible := buser;
mnuherbar2.Visible := buser;
mnuherec.Visible := buser;
mnuhercp.Visible := buser;
mnuherbar3.Visible := buser;
mnuherid.Visible := buser;
mnuhereh.Visible := buser;
mnuherbar4.Visible := buser;
end;
end;
>Aunque insisto que eso solo sirve si deseas que el objeto Application
>se encargue de destruir todo al cerrar la aplicacion.
>
>Para el splash esto:
>begin
> RequireDerivedFormResource := True;
> Application.Initialize;
> splash :=(TFormSplash.Create(nil);
> splash.update;
> Application.CreateForm(TForm1, Form1);
> Application.CreateForm(TForm2, Form2);
> Application.CreateForm(TForm3, Form3);
> ... mas formularios
> splash.Free;
> Application.Run;
>end.
Para splah lo cambi� por:
fsplash:=Tfsplash.Create(nil);
fsplash.Update;
Como me comentaste pero sigue dando el mismo error al generar el error
despu�s de ejecutar el procedimiento procedure Tdm.IniSis(); por segunda
vez.
Tambi�n cambie a fconta por:
fconta:=Tfconta.Create(nil);
fconta.Update;
Y ejecuta igual que como lo ten�a antes, pero tambi�n da el mismo error.
>
>Seguimos en contacto
>
Este d�a lo tove todo ocupado que recien ahora es que me puedo sentar
delante de la PC
Seguimos en contacto
>El d�a 20 de julio de 2015, 16:49, Ismael L. Donis Garcia
><slibre en citricos.co.cu> escribi�:
>> Respondo entre lineas.
>>
>> Ante todo recuerda que nunca he trabajado con Delphi por lo que provengo
>> de
>> la filosof�a de Microsoft la cual de hecho me gusta mucho "me refiero la
>> filosof�a de programaci�n".
>>
>>> ----- Original Message ----- From: "Maxi" <maximiliano.duarte en gmail.com>
>>> To: "Spanish version of Lazarus List"
>>> <lazarus-es en lists.lazarus.freepascal.org>
>>> Sent: Monday, July 20, 2015 12:54 PM
>>> Subject: [Lazarus-es] Error en formularios y lazreport
>>>
>>
>>> El d�a 18 de julio de 2015, 11:57, Ismael L. Donis Garcia
>>> <slibre en citricos.co.cu> escribi�:
>>>
>>>> En el encabezamiento del grupo das click secundario y marcas las opci�n
>>>> de
>>>> Forzar Nueva P�gina.
>>>>
>>>> Respecto a Delphi ni me preguntes. Jamas en la vida lo he usado, nunca
>>>> me
>>>> ha
>>>> gustado. En windows siempre hab�a trabajado con Visual Estudio.
>>>>
>>>> He mirado a Lazarus porque es libre y multiplataforma y como yo me he
>>>> tirado
>>>> ultimamente para Linux, soy el encargado en mi empresa en difundir el
>>>> soft
>>>> libre. De hecho el sistema operativo que uso por defecto es Jessie,
>>>> aunque
>>>> tengo PC virtuales con 1 mill�n de sistemas porque viy haciendo
>>>> estudios
>>>> de
>>>> los que puedo hacerme, ahora mismo estoy mirando a Manjaro OpenRC el
>>>> cual
>>>> ha
>>>> tenido una bueba aceptaci�n.
>>>>
>>>> En estos momentos estoy parado en Lazarus, hoy voy a instalar la
>>>> versi�n
>>>> 1.4.2 a ver si me resuelve un problema que tengo precisamente con
>>>> lazreport
>>>> el cual me da una ecepci�n si cierro todos los formulario abiertos
>>>> desde
>>>> un
>>>> modulo de datos y los vuelvo a abrir. Al volver abrir los formulario y
>>>> tratar de visualizar algo en lazreport este tira una ecepci�n y me
>>>> cierra
>>>> el
>>>> programa la rutina que tengo para cerrar los formularios es la
>>>> siguiente:
>>>>
>>>> procedure Tdm.IniSis();
>>>> var
>>>> f: Tforigen;
>>>> i: integer;
>>>> begin
>>>> DecimalSeparator:='.';
>>>> ThousandSeparator:=',';
>>>> ShortDateFormat := 'dd/mm/yyyy';
>>>> blnend := false;
>>>> intciclo := 0;
>>>> intfilas := 0;
>>>> intnivel := 0;
>>>> lngentidad := 0;
>>>> struser := '';
>>>> strerror := '';
>>>> for i := Screen.FormCount - 1 downto 0 do begin
>>>> if Screen.Forms[i].Name Self.Name then begin
>>>> if Screen.Forms[i].Name 'fconta' then Screen.Forms[i].Free;
>>>> end;
>>>> end;
>>>> for i := Screen.FormCount - 1 downto 0 do begin
>>>> if Screen.Forms[i].Name Self.Name then Screen.Forms[i].Free;
>>>> end;
>>>> Application.CreateForm(Tfconta, fconta);
>>>> Application.CreateForm(Tfsplash, fsplash);
>>>> fsplash.Show;
>>>> Application.ProcessMessages;
>>>> if datos() then
>>>> entrar()
>>>> else
>>>> begin
>>>> f:=Tforigen.Create(Self);
>>>> f.IniSystem:=true;
>>>> f.ShowModal;
>>>> f.Free;
>>>> if blnend then
>>>> cerrarme()
>>>> else if datos() then
>>>> begin
>>>> intciclo := intciclo + 1;
>>>> entrar()
>>>> end
>>>> else
>>>> cerrarme();
>>>> end;
>>>> end;
>>>>
>>>> El error que me da es el siguiente:
>>>> El proyecto XXXX ha lanzado una excepci�n de la clase �xternal:
>>>> SIGSEGV'
>>>> En
>>>> Archivo '.\include\control.inc'en linea 3260
>>>>
>>>> Pero no veo cual puede ser el error porque si no cierro los formularios
>>>> con
>>>> la rutina anterior nunca me da ese error, lo peor del caso es que a
>>>> veces
>>>> si
>>>> tengo que utilizar ese procedimiento.
>>>>
>>>> Por ese motivo voy a instalar la versi�n 1.4.2 a ver si persiste el
>>>> problema.
>>>>
>>>> Saludos Cordiales
>>>> ========
>>>> | ISMAEL |
>>>> ========
>>>
>>>
>>> Paso a otro hilo para que sirva despues.
>>>
>>> Creo que primero debes dejar al modulo de datos solo para datos, y
>>> hacer las creaciones y destrucciones mas controladas.
>>>
>>>> Application.CreateForm(Tfsplash, fsplash);
>>>> fsplash.Show;
>>>
>>>
>>> el splash lo creas en el proyecto
>>
>>
>> Ya esta creado en el proyecto el formulario. En esas lineas lo que hace
>> segun la filosof�a de microsoft es
>> 1.- crear una instancia del formulario
>> 2.- mostrar la intancia
>>
>> Yo en las propiedades del proyecto tengo a modulo de datos solamente para
>> que se cree el formulario automaticamente los dem�s no.
>>
>>>
>>>> Application.CreateForm(Tfconta, fconta);
>>>
>>>
>>> No usaria esto sino Tfconta.Create(self), aunque en tu caso usaria el
>>> envento occlose y le pondria caFree, que lo destruye al salir del
>>> form, con eso te olvidas de liberarlo y no usaria Self sino nil (sin
>>> pariente)
>>
>>
>> Si pongo:
>> Tfconta.Create(self);
>> o
>> Tfconta.Create(nil);
>>
>> Despues no puedo mostrar el formulario con:
>> fconta.Show;
>>
>> Ni tampoco puedo usar el siguiente procedimiento por ejemplo ''que lo uso
>> tal como est�" lo cual tengo en otro formulario.
>>
>> procedure Tflogin.mnuother(buser: boolean);
>> begin
>> with fconta do begin
>> mnuherod.Visible := buser;
>> mnuherbh.Visible := buser;
>> mnuhercs.Visible := buser;
>> mnuherbar2.Visible := buser;
>> mnuherec.Visible := buser;
>> mnuhercp.Visible := buser;
>> mnuherbar3.Visible := buser;
>> mnuherid.Visible := buser;
>> mnuhereh.Visible := buser;
>> mnuherbar4.Visible := buser;
>> end;
>> end;
>>
>> Ya que no encuentra a fconta
>>
>>>
>>> procedure TFormPrincipal.FormClose(Sender: TObject; var
>>> CloseAction:TCloseAction);
>>> begin
>>> CloseAction:=caFree;
>>> end;
>>>
>>
>> Puse la declaraci�n CloseAction:=caFree; en todo los FormClose y persiste
>> el
>> problema
>>
>>>
>>> Te ayudo si quieres
>>>
>>
>> No estar�a de m�s, por el contrario ser�a bien venida toda ayuda.
>>
>> As� como lo tengo todo funciona bien. Excepto los reportes que si se
>> visualizan bien la primera vez que se use el procedimiento procedure
>> Tdm.IniSis(); pero si lo ejecuto por segunda vez entonces es cuando me
>> dan
>> error los reportes.
>>
>> Ese procedimieto se ejecuta siempre al iniciar la apliaci�n y ahi todo
>> funciona bien, pero si mando a ejecutar ese procedimiento por segunda vez
>> los reportes dan error, pero el trabajo con los formularios no da error
>> alguno.
>>
>> Saludos Reiterados
>> ========
>> | ISMAEL |
>> ========
>> Only for the small landowners and Cubans companies
>> Website: www.sisconge.byethost15.com
>> www.sisconge.hol.es
_______________________________________________
Lazarus-es mailing list
Lazarus-es en lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus-esEste mensaje le ha llegado mediante el servicio de correo electronico que ofrece Infomed para respaldar el cumplimiento de las misiones del Sistema Nacional de Salud. La persona que envia este correo asume el compromiso de usar el servicio a tales fines y cumplir con las regulaciones establecidas
Infomed:
http://www.sld.cu/