Comunicación entre formulario

El problema es que quiero acceder a un objeto del formulario padre. Pongo un ejemplo.
Formularios:
FA(AutoCreate):Un botón
FB(Se crea desde FA):Un botón y un edit
FC(Se crea desde FB):Un botón y un edit
En este ejemplo la idea seria desde FA, botón(FA) crear FB, escribir texto en el edit(FB), y botón(FB) crear FC, pulsar botón(FC) y obtener el texto del edit(FB) en el edit(FC).
Esto lo consigo si tanto FA como FB son AutoCreate, pero no quisiera eso.
Consigo acceder al edit(FB) pero obtengo el text que hay en diseño, no en ejecución, esto lo consigo de la siguiente manera:
Código del botón fc:
FB := application.FindComponent('FormB') as TFormB;
if assigned(FB) then
edit1.Text:= TEdit(FB.Components[1]).Text;
Si se te ocurre algo te lo agradecería.
1

1 Respuesta

87.925 pts. Desarrollador de sistemas, delphi, SQL Interbase, Oracle
Ah ok, es muy sencillo accesar a componentes de un formulario a otro.
En tu Form1 debes agregar en uses Unit2 que es la unidad que hace referencia a tu form2 igualmente en tu form3 en Uses agregas Unit2 para también poder hacer referencia a tu form2 y así sucesivamente.
Entonces en tu botón de la form1 pones el siguiente código:
Para accesar al edit1 de tu form2 y ponerle por decir 'HOLA' sera:
Procedure TForm1.Button1OnClick(Sender:TObject);
begin
Form2.Edti1.Text :='HOLA';
end;
Y listo en tu edit1 de tu form2 aparecerá la palabra hola, ahora recuerda que primero creas la forma, ya que si no esta creada jamas te funcionara y marcara error.
Entonces en pocas palabras para accesar a componentes de una forma a otra solo necesitas agregar en uses la forma a la cual quieres accesar ok. Y listo.
Por Otro lado para dibujar Cells en un Grid utiliza en el evento OnDrawCell del Grid ahí podrás dibujar las celas del grid, esto no lo ves en diseño, solo hasta que este corriento tu programa.
A ver si entiendo:
Me dices que tu tienes 3 forms
- En la primera tienes un Botón
- En la segunda tienes un Botón y un edit
-En la tercera tienes un botón y un edit
¿Y tu quieres que desde el Botón de la primera Form crear un Botón y un edit en una segunda Form? ¿Y luego con ese botón creado en la segunda forma crear otro botón y otro edit en una tercera form?
¿Dime si entendí bien o dame más detalles?
Antes de nada gracias por leértelo.
Me explique mal. A ver ahora.
En tiempo de diseño,
El form1, solo tiene un botón.
El form2, solo tiene un botón y un edit.
El form3, solo tiene un botón y un edit.
El código del botón del FORM1, lo que hace es crear en tiempo de ejecución el FORM2 (el cual posee ya su botón y su edit).
El código del botón del FORM2, lo que hace es crear en tiempo de ejecución el FORM3 (el cual posee ya su botón y su edit).
El código del botón del FORM3, lo que QUIERO que haga, es que me obtenga el texto que tiene el edit del FORM2 y me lo vuelque al edit del FORM3.
Es decir, arranco la aplicación, me sale un form1 con un botón, lo pulso, y me crea un form2 (el cual lleva un botón y un edit), en el edit escribo, "patata", doy al botón del form2 y me crea el form3 (el cual lleva un botón y un edit) y al dar a este botón, me sale en el edit del form3 la cadena "patata" que escribí antes en el edit del form2.
uisss no se si he liado más la cosa.
Realmente el problema esta en acceder a los objetos del formulario padre, que solo he conseguido hacerlo cuando el formulario padre es un AutoCreate. Pero yo no quiero que el FORM1 y FORM2 sean AutoCreate, solo quiero que sea el FORM1.
Espero haberlo aclarado, Muchas gracias Manuel.
Saludos.
PD: Perdona que aproveche la ocasión, pero esta tarde me ha salido un problemilla.Se como colorear filas y columnas de un grid, ¿pero y celdas? ¿Se pueden colorear celdas?, yo lo he hecho en visual basic, pero no consigo hacerlo en Delphi. Muchas gracias.
Ok, como no tienes al autocreate de tu form, tienes que crearla bajo código en runtime la cual seria así:
try
Form2 := TForm2.Create(self);
Form2.Edit1.Text := 'HOLA';
Form2.ShowModal;
finally
Form2.Free;
end;
De esta manera primero la creas, luego ya puedes accesar a cualquiera de sus componentes como el edit luego muestras la forma y por ultimo al cerrar la forma esta se vuelve a liberar.
En cuanto a dibujar una celda del stringGrid tienes que usar el canvas del stringGrid así más o menos
procedure TForm1.StringGrid1DrawCell(Sender: TObject; Col, Row: Integer;
Rect: TRect; State: TGridDrawState);
begin
if (Row=2) and (Col=3) then
with StringGrid1.Canvas do
Draw(Rect.Left, Rect.Top, Image1.Picture.Graphic);
end;
En el evento del OnDrawCell pones este código, lógicamente tienes que tener una TImage cargada un imagen, y esta imagen debe dibujarse en una celda, pero si en esa celda tienes letras estas se borran, es decir no puedes dibujar una celda y escribir datos en la misma, ahora yo te pregunto porque estas utilizando un StringGrid, quiero suponer que estas mostrando información que la obtienes de un query, ¿o no?
Hola Manuel, antes de nada disculpa por mi retraso pero he tenido mucho trabajo.
Bien, se me olvido decirte que los uses ya los tenia puestos, más que nada porque sino no podría ni compilar.
El ejemplo que tu me pones, es válido, pero no tiene nada que ver con lo que yo te digo. En el ejemplo que tu me pones introduces texto en el edit del form2 (del hijo), ademas que lo haces desde el form1 (el padre) el cual tiene el AutoCreate. Pero no es esto lo que quiero.
Es importante que tengas en cuenta que son 3 Forms (que solo el primero tiene el AutoCreate), y que es desde el tercer form, donde intento acceder al texto del edit del segundo form.
Por favor, intenta comprender el ejemplo que te puse, y si no te aclaras te mando yo en un zip el ejemplo a la dirección de correo que tu me digas.El ejemplo es muy simple.
Respecto a los grids, lo que necesito saber es que propiedad del grid me permite cambiar el color de una sola celda, NI de una fila, NI de una columna, SOLO de una celda. Si puedes ponme un ejemplo, suponiendo que fuera así ...
grid.cells[ACol,ARow].color := clred;
(Se que así no es, pero si me puedes poner un ejemplo mejor)
Muchas gracias Manuel y perdona por el tiempo que te estoy haciendo perder. Gracias.
Un Saludo.
Jose.
Hola Manuel, parece que no nos entendemos.
Sigues sin tener en cuenta que son 3 forms. Evidentemente en el botón del form1, está el código que me dices para crear el form2, y en el botón del form2, otro código parecido para crear el form3.
El texto del edit del form2 se mete en tiempo de ejecución. No quiero meterlo en diseño.
Al pulsar el botón del form3, es donde quiero cargar el texto del edit del form2 en el texto del edit del form3. Es muy importante que tengas en cuenta que son 3 FORMS y SOLO el PRIMERO esta en el AUTOCREATE, que SOLO el PRIMERO crea en tiempo de ejecución el SEGUNDO form, y el SEGUNDO crea en tiempo de ejecución el TERCER form.
Creo que lo mejor es que te ponga el código.
//FORM1
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses Unit2;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
with TForm2.Create(application) do
begin
Visible:=True;
end;
end;
end.
//FORM2
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm2 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
uses Unit1, Unit3;
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
begin
with TForm3.Create(application) do
begin
Visible:=True;
end;
end;
end.
//FORM3
unit Unit3;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm3 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form3: TForm3;
implementation
uses Unit2;
{$R *.dfm}
procedure TForm3.Button1Click(Sender: TObject);
begin
Edit1.Text:=Form2.Edit1.Text; <-- AQUI TENGO EL PROBLEMA
end;
end.
//-------------------------------------
Respecto a lo del grid, que yo recuerde en ningún momento te dije que fuera un StringGrid, solo dije Grid. Y lo único que me interesa es cambiar el COLOR, NO quiero meter una imagen. Mi pregunta es ¿Se puede cambiar el color de una celda de un grid?, me da igual el tipo de grid que sea, si se puede, ¿cómo?, un ejemplo por favor.
Muchas gracias Manuel.
Saludos.
Jose.
En cuanto a lo de las forms el código que me envías esta bien, la parte donde marcas que tienes el problema esta bien, lo que veo ahí es que intentas poner lo que tenga el Edit1 de tu Form2 ponérselo al Edit1 de tu Form3 y también veo que tienes el Uses Unit2, lo cual esta bien. ¿Dime cuál es el problema o que error te marca?
Por otro lado en cuanto al Grid, si correcto nunca mencionaste un StringGrid, entonces te aclaro.
Si lo intentas hacer en un StringGrid no se puede, ya lo intente y lo único que pude es dibujar una imagen como el código que te envíe, pero me eliminaba el posible texto que estuviera en la celda.
Ahora bien si usas un DBGrid en este si puedes, aquí te va el ejemplo:
procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;
Field: TField; State: TGridDrawState);
begin
{ NOMBRE es el nombre del campo a pintar de otro color }
{ NOMBRE this the field name to paint in a diferent color }
if Field.FieldName = 'NOMBRE' then
(Sender as TDBGrid).Canvas.Font.Color := clRed; { En rojo / in red }
(Sender as TDBGrid).Canvas.TextRect(Rect, Rect.Left + 2, Rect.Top + 2,
Field.AsString);
end;
¿Y dime cual problema tienes con lo de las forms dime que error te marca?
Ok mira creo que tu problema esta en la forma en creas tu forms en runtime, quiero comentarte que la mejor programación es que las formas no creen automáticamente, es decir así como lo estas haciendo es buena programación.
Ok intenta de esta manera para crear tu form y mostrarla
en el OnClick del Boton1 de tu form2 pon el siguiente código:
try
Form3 := TForm3.Create(self);
Form3.ShowModal;
finally
Form3.Free;
end;
Ok todo va en un try por si se genera algún error puedas liberar la creación de tu form, recuerda que ShowModal ya no te permite continuar con las siguientes lineas hasta que cierres la forma así que si usas solo Show no pongas el try finally ok, un tip no uses Visible := true para mostrar las formas mejor usa Show; o ShowModal; ok y listo
Tu codigo Edit1.Text := Form2. Edit1.Text; ya debe funcionar. Yo lo estoy calando aqui y si funciona bien. Checalo y avizame.
En cuando al Grid si te das cuenta dice Canvas.Font.Color por supuesto eso pinta el Font si eliminas el Font y pones Canvas.Color := clRed; esto te pintara la celda, ok.
¿Hola Manuel, como va?
Mira, el mensaje de error que me muestra cuando pulso el botón del form3 es:
Access violation at address 0044F710 in module 'PROJECT1.EXE'. Read of address FFFFFFFF.
este error es justo al ejecutar la linea de código:
Edit1.Text:=Form2.Edit1.Text;
Si yo pusiera el form2 como Autocreate (cosa que no quiero hacer), este problema no lo tendría.
------------------------------------
Respecto a lo del grid, lo que quiero pintar es la CELDA, NO EL TEXTO de la celda.
Muchas gracias Manuel.
Saludos.
Jose.
Hola Manuel,
Correcto, no entiendo porque motivo al crear el formulario de la manera que me dices si que puedo acceder al padre, pero bueno, funciona, muchas gracias.
Respecto al grid, el canvas no tiene la propiedad color, lo intente de esta manera con distintos grids pero tampoco lo conseguí:
(Sender as TDBGrid).Canvas.Brush.Color:=clred;
(Sender as TStringGrid).Canvas.Brush.Color:=clred;
(Sender as TDrawGrid).Canvas.Brush.Color:=clred;
He estado mirando otras propiedades sin profundizar y no encuentro nada.
Muchas gracias por todo, si ves que lo de colorear la celda de un grid no puede ser, pues que se le va hacer, me lo dices y cierro esta pregunta que te tiene que tener cansado, de nuevo, muchas gracias Manuel.
Saludos.
No claro que no, es un placer ayudarles a todos los que preguntan, y cuando necesites algo más preguntame si lo se te ayudare y si no pues ya veremos que hacemos.
En cuanto al grid, buscate unos componentes llamados InfoPower esos traen unos DBGrids muy buenos yo los uso y puedo hacer todo lo que intentas hacer hasta más, yo considero que son los mejores.
Pero ahora que recuerdo tengo un proyecto donde hice eso de dibujar columnas o celdas ahí te va el código:
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject;
const Rect: TRect; DataCol: Integer; Column: TColumn;
State: TGridDrawState);
begin
if Total = 10 then DBGrid1.Canvas.Brush.Color:=clGreen;
if DataCol = 1 then
DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;
Suponiendo que Total es uno de los campos el cual se encuentra en la columna 1, entonces los primero que preguntas es la condición para poder pintar la celda luego pintas con el Brush luego preguntas que columna esta pintando y vuelves a llamar la función DefaultDraw...
Entonces lo que te hará es lo siguiente: te pintara en la columna 1 todas la celdas donde el valor de Total = 10 y las pintara color verde...
Checalo a ver si te funciona, se que ya lo intentaste con el Brush. Color pero te falto la siguiente linea que aquí te pongo la del DefaultDrawColumnCell... ok

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas