PDA

Ver la Versión Completa : Herencia visual y variables públicas


rarratia
05-11-2008, 19:30:52
Amigos, soy novato en Delphi y quisiera hacerles una pregunta, genero dos formularios base donde en cada uno de ellos pongo una programación base que utilizaré.
Luego de uno heredo visualmente los formularios modales y del otro heredo visualmente los formularios no modales.
El problema se suscita cuando quiero acceder a por ejemplo un objeto TEdit de un formulario desde otro formularios. Pongo el formulario que deseo acceder en el use de la unidad y luego cuando le asigno un valor al TEdit:

Form1.edit.text := valor

curiosamente este edit no recibe el valor que asigno, es como si no hubiese asignado nada. Cosa que no me sucede cuando trabajo con formularios no heredados.

¿Alguien me puede decir que estoy haciendo mal?

afxe
05-11-2008, 19:42:08
Necesitas dar un poco más de información, por ejemplo, ¿cómo creas los formularios? Si usas Form1 := TForm1.Create(Application) no sé de donde viene el problema pero si usuas TForm1.Create(Application).Show el problema es que Form1 es nil, no puedes referenciarlo mediante la variable pública.

mmmmhhh no sé si me he explicado.

maeyanes
05-11-2008, 19:43:43
Hola...

¿Estás seguro que Form1 es una variable que apunta al formulario que deseas?

Ahora, algo que yo hago cuando quiero usar formularios a los que les mando valores para mostrar es crear propiedades públicas que hagan esa función:


type
TForm1 = class(TForm)
// Componentes
private
function GetNombre: string;
procedure SetNombre(const Value: string);
public
property Nombre: string read GetNombre write SetNombre;
end;

implementation

function TForm1.GetNombre: string;
begin
Result := Edit1.Text
end;

procedure TForm1.SetNombre(const Value: string);
begin
Edit1.Text := Value
end;


Así ya puedo hacer algo como:


begin
with TForm1.Create(nil) do
try
Nombre := 'Filomeno';
if ShowModal = mrOk then
ShowMessage(Nombre)
finally
Free
end
end;


Espero te sirva...



Saludos...

rarratia
05-11-2008, 19:47:16
Es justamente lo que hago, ¿cómo puedo arreglar ese problema?

maeyanes
05-11-2008, 19:50:26
Hola...

Pues así como lo explicas, la verdad no se te puede ayudar mucho...

Si pones algo de código tal vez podramos ver mejor donde está tu problema...



Saludos...

rarratia
05-11-2008, 19:51:19
Esta es la forma como creo el formulario:

class procedure Tf_sName.MostrarVentana(ATag : Integer);
var
i : Integer;
f : TForm;
begin
LockWindowUpdate(Application.MainForm.Handle);
try
for i := Screen.FormCount - 1 downto 0 do begin
f := Screen.Forms[i];
if(f is Self) then begin
if(f.WindowState = wsMinimized) then
f.WindowState := wsNormal;
f.BringToFront;
Exit;
end;
end;
f := Create(Application);
f.Tag := ATag;
f.Show;
finally
LockWindowUpdate(0);
end;
end;

maeyanes
05-11-2008, 20:05:39
Hola...

Esta es la forma como creo el formulario:


class procedure Tf_sName.MostrarVentana(ATag : Integer);
var
i : Integer;
f : TForm;

begin
LockWindowUpdate(Application.MainForm.Handle);
try
for i := Screen.FormCount - 1 downto 0 do begin
f := Screen.Forms[i];
if (f is Self) then begin
if (f.WindowState = wsMinimized) then
f.WindowState := wsNormal;
f.BringToFront;
Exit;
end;
end;
f := Create(Application);
f.Tag := ATag;
f.Show;
finally
LockWindowUpdate(0);
end;
end;




Según tu código, solo creas y muestras la forma, pero en ningún momento la asignas a una variable de objeto que siga "viva" fuera del método...

Así que si haces algo como Form1.Edit1.Text := Valor, obviamente no va a pasar nada (bueno si, un error de violación de memoria :p)...


Por cierto, cuando pongas código usa las etiquetas [ DELPHI ] [ /DELPHI ] (sin los espacios en blanco) para que este se vea mejor, fijate en la diferencia entre el código en el quote de este mensaje y el que tu pusiste...

Saludos...

rarratia
06-11-2008, 13:35:33
Ahora entiendo, si la Class Function esta definida en los formularios padres de donde se heredan todos los demás debo en el evento create colocar lo siguiente:


Form1 := Self;

maeyanes
06-11-2008, 15:39:29
Hola...

Esto que comentas, si bien puede solucionar tu problema, no es muy recomendable hacerlo.

Lo mejor sería que el método de clase sea la que devuelva ese valor:


class procedure TParentForm.ShowWindow(ATag: Integer; var Reference);
var
i: Integer;
AForm: TForm;

begin
LockWindowUpdate(Application.MainForm.Handle);
try
for i := Screen.FormCount - 1 downto 0 do
begin
AForm := Screen.Forms[i];
if (AForm = Reference) then
begin
if (AForm.WindowState = wsMinimized) then
AForm.WindowState := wsNormal;
AForm.BringToFront;
Exit
end
end;
AForm := Create(Application);
AForm.Tag := ATag;
AForm.Show;
Reference := AForm
finally
LockWindowUpdate(0)
end
end;


De esta forma puedes hacer algo como:


var
Form1: TForm1;

begin
TForm1.ShowWindow(1, Form1)
end;



Saludos...

rarratia
07-11-2008, 13:24:45
Bien, entonces para formularios modales ¿podríamos tener algo así?

class function TParentForm.ShowWindow(ATag : Integer; var Reference) : TModalResult;
var
AForm : TForm;
begin
AForm := Create(Application);
AForm.Tag := ATag;
Try
Result := AForm.ShowModal;
finally
Free;
end;
end;

rarratia
07-11-2008, 13:27:03
Me faltó algo:


class function TParentForm.ShowWindow(ATag : Integer; var Reference) : TModalResult;
var
AForm : TForm;
begin
AForm := Create(Application);
Reference := AForm; // Esto había quedado en el tintero
AForm.Tag := ATag;
Try
Result := AForm.ShowModal;
finally
Free;
end;
end;

maeyanes
07-11-2008, 15:07:59
Hola...

En tu método de clase liberas la forma que creas, así que al salir de la función, Reference tendrá un valor no válido.

En este caso sería mejor solo hacer algo como:


class function TParentForm.ShowWindow: TModalResult;
begin
with Self.Create(nil) do
try
Result := ShowModal
finally
Free
end
end;


Si te fijas, el método de clase no recibe ningún parámetro y solo devuelve el resultado de ModalResult...



Saludos...

Lepe
07-11-2008, 16:25:01
maeyanes, ¿usas Self en un procedimiento de clase?, supongo que se te ha ido el dedo ¿no?

maeyanes
07-11-2008, 16:39:45
Hola...

Nop, no se me ha ido el dedo. En un método de clase, Self representa a la clase. Esto es Self = TParentForm y en una clase descendiente, por ejemplo TShowNombreForm, Self sería igual a TShowNombreForm.


In the defining declaration of a class method, the identifier Self represents the class where the method is called (which could be a descendant of the class in which it is defined). If the method is called in the class C, then Self is of the type class of C. Thus you cannot use the Self to access instance fields, instance properties, and normal (object) methods, but you can use it to call constructors and other class methods, or to access class properties and class fields.

A class method can be called through a class reference or an object reference. When it is called through an object reference, the class of the object becomes the value of Self.




Saludos...

rarratia
07-11-2008, 18:21:14
Pero si es necesario el ATag para poder decidir lo que hacer dentro del formulario ShowModal, cómo paso el ATag????

maeyanes
07-11-2008, 18:24:11
Hola...

Pues como un parámetro:


class function ShowWindow(ATag: Integer): TModalResult;




Saludos...

rarratia
07-11-2008, 18:39:47
pero es una función de clase y el objeto aún no se crea, ¿cómo consigo acceder al atributo Tag?

rarratia
07-11-2008, 18:41:16
No conseguiré acceder al tag desde el formulario ShowModal, vendrá en 0

maeyanes
07-11-2008, 18:44:46
Hola...

Claro que si podrás:


class function TParentForm.ShowWindow(ATag: Integer): TModalResult;
begin
with Self.Create(nil) do
try
// Aquí estamos asignando el valor a la propiedad Tag de la forma creada
Tag := ATag;
Result := ShowModal
finally
Free
end
end;



Saludos...

rarratia
07-11-2008, 18:52:30
recuerda que este código está en el formulario Padre y que heredo de él un formulario hijo, luego cuando ejecuto esta función de clase que es un método del padre, pero lo ejecuto del formulario visual hijo, me aparece tag=0
es raro.

maeyanes
07-11-2008, 19:00:07
Hola...

¿Y como llamas a este método de clase?

Por que no te debería estar pasando eso. Ya que si haces TFormHijo.ShowWindow(1), la forma que se crea debería tener en Tag el valor 1.



Saludos...