PDA

Ver la Versión Completa : Ayuda con crear un mismo Form varias veces + Thread


n03l
23-12-2013, 20:33:38
Saludos, necesito una ayudita con un problemita que no e podido resolver.

Tengo Un Form mdi principal y un Form hijo en el cual creo un thread para realizar una serie de procesos incluyendo manejo de bases de datos. de esta forma me funciona bien.

el problema que tengo esque quiero crear el Form hijo varias veces pero el problema esque desde e theread hago referencias apuntando al Form1, por ejemplo Form1.ProgressBar1.Position:=Form1.ProgressBar1.Position+1;

lo cual no me funciona para el segundo Form

espero me ayuden!!! saludos

Aca el Form mdi Principal

unit Unit3;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;

type
TFrmMain = class(TForm)
Panel1: TPanel;
BtnFrm1: TButton;
BtnFrm2: TButton;
procedure BtnFrm2Click(Sender: TObject);
procedure BtnFrm1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
FrmMain: TFrmMain;

implementation

uses Unit1;

{$R *.dfm}

procedure TFrmMain.BtnFrm1Click(Sender: TObject);
begin

Form1:= TForm1.Create(Application);
Form1.Label1.Caption:='Soy el Uno';
Form1.Caption:= 'Soy el Uno';
Form1.show;

end;

procedure TFrmMain.BtnFrm2Click(Sender: TObject);
var
F2: TForm1;
begin
F2:= TForm1.Create(Application);
F2.Label1.Caption:='Soy el Dos';
F2.Caption:= 'Soy el Dos';
F2.show;

end;

end.


Aca el Form1 que quiero crear varias veces

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, Buttons;

type
TForm1 = class(TForm)
BitBtn2: TBitBtn;
ProgressBar1: TProgressBar;
Label1: TLabel;
procedure BitBtn2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;



implementation
Uses Hilos;
var
Hilo:THilo;

{$R *.dfm}

procedure TForm1.BitBtn2Click(Sender: TObject);
begin
Hilo:=THilo.Create(True);
Hilo.FreeOnTerminate:=true;
Hilo.Resume;
end;

end.


y aca la unidad del Hilo

unit Hilos;

interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, Buttons;

type
THilo = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
end;


implementation

uses Unit1;

procedure THilo.Execute;
begin
Form1.ProgressBar1.Position:=0;
Form1.BitBtn2.Enabled:=false;
repeat

Form1.ProgressBar1.Position:=Form1.ProgressBar1.Position+1;
Sleep(500);
until Form1.ProgressBar1.Position=Form1.ProgressBar1.Max;

Form1.BitBtn2.Enabled:=true;
end;




end.


Claro esta no es mi aplicacion real, es solo un esquema para lograr mi objetivo

http://s2.subirimagenes.com/imagen/previo/thump_8748484mdi.png (http://www.subirimagenes.com/imagen-mdi-8748484.html)

Saludos y espero sugerencias.

Caminante
23-12-2013, 20:46:10
Bueno nunca he usado threads pero podrias probar creando un campo en el thread que haga referencia al formulario y al crear el thread la pasas Self que vendria a ser la referencia al formulario actual. Asi en el codigo del thread solo usarias el campo para hacer tus operaciones.

Espero se me haya entendido

Saludos

Neftali [Germán.Estévez]
26-12-2013, 20:40:41
Los accesos desde el thread hacia el formulario (componentes como el progressbar) debes hacerlos utilizando Synchronize, ya que la VCL no es thread-safe.

revisa el método synchronize en la ayuda o algunos de los ejemplos de thread que hay en el FTP del club (http://terawiki.clubdelphi.com/).

n03l
26-12-2013, 20:59:08
Ok Gracias, Lo tendre en cuenta!!!.

Aun no e podido lograr lo que quiero. Sin embargo utilizando el Componente JVThread de los JEDI si me funciona perfecto ya que queda todo encapsulado en la misma forma.

saludos

escafandra
27-12-2013, 13:14:35
Varias cosas:

1.- En las opciones configura TForm1 como no autocreado.
2.- En tu thread implementa un constructor en el que tengas que pasar una referencia a TForm1 y la guardas en una variable privada. El resto de las llamadas en las que intervenga TForm1, las haces con esa variable que apuntará al Form que te interesa en cada momento.
3.- Como dice Neftali, usa Synchronize, para las funciones que hagan uso de TForm1.

Saludos.

n03l
27-12-2013, 17:40:16
Ok Voy a investigar como es eso de los constructores ya que nunca lo e usado saludos...

Muchas Gracias de Verdad......

n03l
27-12-2013, 18:57:03
Ok, despues de tirar puñaladas al aire y haciendo uso del copy paste e hecho lo siguiente:

En el form
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, Buttons;

type
TForm1 = class(TForm)
BitBtn2: TBitBtn;
ProgressBar1: TProgressBar;
Label1: TLabel;
procedure BitBtn2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;



implementation
Uses Hilos;
var
Hilo:THilo;

{$R *.dfm}

procedure TForm1.BitBtn2Click(Sender: TObject);
begin

//Aqui no se como capturar el nombre del form sin utilizar Form1. ya
// que el nombre es dinamico
Hilo:=THilo.Create(Form1);
Hilo.FreeOnTerminate:=true;
Hilo.Resume;
end;

end.


y en el hilo me da el siguiente error al tratar de compilarlo
[DCC Error] Hilos.pas(39): E2003 Undeclared identifier: 'ProgressBar1'

el Hilo
unit Hilos;

interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, Buttons;

type
THilo = class(TThread)
private
FName: TForm;

{ Private declarations }
protected
procedure Execute; override;
public
constructor Create(Name: TForm);

end;


implementation

uses Unit1;


constructor THilo.Create(Name: TForm);
begin
inherited Create(True);
FName := Name;
FreeOnTerminate := True;
end;


procedure THilo.Execute;
begin


FName.ProgressBar1.Position:=0;
FName.BitBtn2.Enabled:=false;
repeat

FName.ProgressBar1.Position:=FName.ProgressBar1.Position+1;
Sleep(500);
until FName.ProgressBar1.Position=FName.ProgressBar1.Max;

FName.BitBtn2.Enabled:=true;
end;


end.

Caminante
27-12-2013, 19:12:33
FName es de tipo Tform y debe ser de tipo TForm1

Saludos

n03l
27-12-2013, 19:30:26
Hola Caminante, ya lo intente y me marca error
[DCC Error] Hilos.pas(11): E2003 Undeclared identifier: 'TForm1'

saludos

n03l
27-12-2013, 20:12:09
Tenias razon ya lo solucione poniendo TForm1. el problema era que yo tenenia la referencia a Form1

aqui:
implementation

//uses Unit1;


lo puse aqui y me funciono
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, Buttons,Unit1;

saludos y gracias a todos los que me colaboraron

Neftali [Germán.Estévez]
28-12-2013, 13:54:31
Sigues accediendo al formulario y al progressbar sin usar Synchronize.
Creo que antes o después acabará dándote problemas.

escafandra
28-12-2013, 17:42:57
Sigues accediendo al formulario y al progressbar sin usar Synchronize.
Creo que antes o después acabará dándote problemas.
n03l escucha la voz de los maestros.


Saludos.

n03l
29-12-2013, 16:54:19
Si amigo lo tendre en cuenta en mi aplicacion real