Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Herencia visual y variables públicas (https://www.clubdelphi.com/foros/showthread.php?t=61382)

rarratia 05-11-2008 19:30:52

Herencia visual y variables públicas
 
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:

Código Delphi [-]
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:

Código Delphi [-]
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...

Cita:

Empezado por rarratia (Mensaje 324365)
Esta es la forma como creo el formulario:

Código Delphi [-]
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:

Código Delphi [-]
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:

Código Delphi [-]
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:

Código Delphi [-]
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í?
Código Delphi [-]
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:

Código Delphi [-]
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:

Código Delphi [-]
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.

Cita:

Empezado por Delphi Help
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:

Código Delphi [-]
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:

Código Delphi [-]
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.


La franja horaria es GMT +2. Ahora son las 22:40:51.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi