PDA

Ver la Versión Completa : Como ejecutar un procedimiento en mis forms mostrados, cuando ocurra un evento??


jcapitan
19-06-2007, 04:14:57
Hola amigos, de nuevo por aqui.

Quiro que mis ventanas abiertas (mostradas con show) refresquen sus tablas cuando estas sufran una modificación.

El codigo del evento lo tengo asi:

procedure TDM.EventosEventAlert(Sender: TObject; EventName: string;
EventCount: Integer);

begin

If EventName='mod_regs_detalles' then
If frmPapeleta.tblDetalles.Active then
frmPapeleta.tblDetalles.FullRefresh;
end;

esto solo actualiza la ultima generada.

Como hacerle para que refresque todas?? o como puedo ejecutar un procedimiento en todas las ventanas.

Pense en barrer todos los forms y ejecutar un procedimiento pero como hago esto?

el barrido de los forms para detectar cuales quiero actualizar me quedaría asi, y suponiendo que el procedimiento con el que cuenta el form es "procedure actualiza(sender: TObject)";

for i := 0 to Screen.FormCount-1 do
begin
if Pos('Papeleta',Screen.Forms[i].Caption)>0 then
begin
//¿¿¿¿¿¿Aqui como me enlazo a este form y le digo que ejecute el procedimiento "actualiza"???? se puede???
end;
end



Gracias de antemano!!

Lepe
19-06-2007, 10:13:08
En principio, puedes usar un EventAlert por cada Form que quiera recibir mensajes. Así cada ventana registra sus propios mensajes y al cerrar la ventana, elimina la notificación.

Otra forma es usando herencia, por ejemplo. Defines una ventana maestra que tenga el procedimiento actualiza, después todas las ventanas sobreescriben ese método y hace su tarea.


TBase = Class(TForm)

public
procedure Actualiza (const msg:String);virtual;
end;

TForm1 = Class(TBase)

public
procedure Actualiza (const msg:String);override;
end;



TForm2 = Class(TBase)

public
procedure Actualiza (const msg:String);override;
end;

....
Ahora si puedes hacer esto:
for i := 0 to Screen.FormCount-1 do
begin
if Pos('Papeleta',Screen.Forms[i].Caption)>0 then
begin
TBase(Screen.Forms[i]).Actualiza('yo yo yo');
end;
end


Saludo

jcapitan
19-06-2007, 16:15:07
Gracias, intentaré lo segundo, lo primero que mencionas, de poner un eventalert en cada form, ya lo hice pero no se porque motivo no se activan los eventos, solo funciona si lo pongo en el DataModule, estos form que menciono, los llamo de la siguiente manera:


frmPapeleta:=TfrmPapeleta.Create(Self);
frmPapeleta.Show;

de esta forma puedo moverme de uno a otro, pero claro todos tienen el mismo nombre, y este form (frmPapeleta) tiene tablas, las cuales son las que quiero se actualizen (tantos como tenga en panatalla) cuando sufran cambios.



Gracias.

jcapitan
21-06-2007, 02:39:07
No he logrado que funcione el componente eventalert colocado en las forms generados desde ell form principal.

El codigo del proyecto es este.

program MiApp;

uses
Forms,
MDatos in 'MDatos.pas' {DM: TDataModule},
Papeleta in 'Papeleta.pas' {frmPapeleta},
Main in 'Main.pas' {frmMain},
{$R *.res}

begin
Application.Initialize;
Application.CreateForm(TDM, DM);
Application.CreateForm(TfrmMain, frmMain);
Application.Run;
end.

cuando ejecuto la aplicacion me muestra el form pricipal (Main), desde el cual metiendo un comando en un edit ejecuto la accion, en este caso generar un nuevo form

procedure TfrmMain.ProcesaComando(ComandoAProcesar : String);
var
NewFolio : Integer;
begin

if Comandos.Text='NP' then
begin
frmPapeleta:=TfrmPapeleta.Create(Self);
frmPapeleta.Show;
end;
end;

de esta manera cuantas veces ponga el comando "NP" se generara un nuevo form y los tendre en pantalla, y podre moverme de uno a otro para meter datos correspondientes.
Bien, este form (frmPapeleta) contiene un FIBDataset, con su respectivo datasource, y con un eventalert. El codigo al meter datos y el del eventalert es:

procedure TfrmPapeleta.Button1Click(Sender: TObject);
begin
tblDetalles.Insert;
....
....
....
tblDetalles.Post;
end;

procedure TfrmPapeleta.SIBfibEventAlerter1EventAlert(Sender: TObject;
EventName: string; EventCount: Integer);
begin
If EventName='mod_regs_detalles' then
begin
if tblDetalles.Active then tblDetalles.FullRefresh;
ShowMessage('Refresco tabla detalles'); //para fines de prueba
end;
end;


sin embargo cuando hay modificaciones en la tabla a la que esta enlazada el FIBDataset, el evento no se dispara en los forms (frmPapeleta) que tengo en pantalla, sin embargo si el eventalert lo coloco en el form principal (frmMain) funciona perfectamente. Cual es el problema??? o que estoy haciendo mal??? porque no se dispara en estos forms????

Lepe
21-06-2007, 11:33:08
No te puedo dar una respuesta clara, ya que ahora mismo uso FB 2.1 alpha y los componentes MDOLIB (veo que tu usas los IBX).

No sé si lo tienes en cuenta o no, de todas formas lo comento:

Debido a estas líneas:
if Comandos.Text='NP' then
begin
frmPapeleta:=TfrmPapeleta.Create(Self);
frmPapeleta.Show;
end;

Dentro de la ventana TFrmPapeleta, jamás debes usar "frmpapeleta.LoqueSea", porque esa variable frmpapeleta, solo apuntará al último Form Creado, y podrás tener Violaciones de memoria o resultados que no esperes (por ejemplo, el form que se actualiza es el último creado, no donde tú realizas la inserción).

Acabo de hacer la prueba y al tener dos MDOEventsAlert (uno en el datamodule principal y otro en una ventana hija mdiChild) obtengo una excepción "error reading connection" al abrir la ventana mdiChild :eek:.

La verdad es que uso 1 solo MDOEventAlert en el datamodule, y después, con una clase desarrollada por mí (http://www.clubdelphi.com/foros/showthread.php?t=37679&highlight=teventalerter)(y bastante sucia en código :D) encolo a todos los forms o unidades que quieren ser informados.


Saludos

jcapitan
21-06-2007, 18:16:56
Pues UN MILLON DE GRACIAS!!!! Ya está solucionado, utilizando sus grandes conocimientos. de nuevo mil gracias.

:)