PDA

Ver la Versión Completa : Directivas para realizar uses de formularios dependiendo de lo que requiera


Soa Pelaez
01-12-2015, 17:00:42
Buen día, tengo una inquietud tengo tres formularios que entre el formulario 1 y 2 tengo el uses del formulario 1
Entre el formulario 3 y formulario 2 el uses del formulario 2, pero lo que no quiero es tener que usar el formulario 1 porque lo contiene el formulario 2.

Quiero realizar el uses con directivas se que asi no tendré que usar el formulario 1 en el formulario 3, pero no se como implementarlo.

Alguna idea??

Gracias.

AgustinOrtu
01-12-2015, 17:17:50
Bienvenido Soa Pelaez,

La verdad no entendi nada, podrias explicarlo un poco mejor?

Soa Pelaez
01-12-2015, 17:28:02
Bienvenido Soa Pelaez,

La verdad no entendi nada, podrias explicarlo un poco mejor?

Tres Formularios.

El 1 necesita del 2
El 3 necesita del 2

Pero lo que no quiero es por querer usar el formulario dos tener que arrastrar el formulario 1 porque se encuentra entre los uses del formulario 2

Con directivas se puede hacer, pero necesito saber como.

AgustinOrtu
01-12-2015, 18:36:13
Ósea que tenés una referencia circular

El 1 necesita del 2
El 3 necesita del 2
El 2 necesita del 1

Eso obviamente es malo y no se soluciona con directivas de compilación.
Es malo por justamente la situación que se te presentó: necesitas tanto a 1 como a 2 en tu proyecto pero sólo te interesa usar uno

Si es posible pon el código en donde se genera la dependencia y vemos como ayudarte a refactorizar

Básicamente la parte que nos interesa de 2 es, que parte no compila si se elimina a 1 del uses

AgustinOrtu
01-12-2015, 19:05:38
Este es un ejemplo trivial, basicamente consiste de dos Forms, Form1 y Form2

El Form1 consiste de un memo y un boton, el cual en su evento OnClick, crea y visualiza de manera modal el Form2. Por lo tanto en su clausula uses encontramos la Unit2

El Form2 simplemente tiene un Edit y un boton; Form2 en su clausula uses contiene a Unit1, por lo tanto creamos una referencia circular

Unidad1 -> Usa a la Unidad2
Unidad2 -> Usa a la Unidad1

En el evento OnClick del Form2, se agrega al Memo del Form1 el contenido del Edit, y se cierra el formulario

El codigo seria el siguiente:

unit Unit1;

interface

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

type
TForm1 = class(TForm)
Memo1: TMemo;
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);
var
Form2: TForm2;
begin
Form2 := TForm2.Create(NIL);
try
Form2.ShowModal;
finally
Form2.Free;
end;
end;

end.


unit Unit2;

interface

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

type
TForm2 = class(TForm)
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

implementation

uses
Unit1;

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
Form1.Memo1.Lines.Add(Edit1.Text);
Close;
end;

end.


Y en efecto si lo ejecutamos, podria decirse que funciona bien. Pero obviamente, si a mi me interesa en otro proyecto usar solo uno de estos dos Form, no me queda otra alternativa que incluir a los dos

Una primera solucion podria ser, quitar del uses del Form2, a la Unit1; obviamente el codigo ahora no compilara ya que no se conoce a 'Form1'.

Asi que la unica alternativa es acceder desde el Form1 al valor del Edit, asi:


procedure TForm1.Button1Click(Sender: TObject);
var
Form2: TForm2;
begin
Form2 := TForm2.Create(NIL);
try
Form2.ShowModal;
Memo1.Lines.Add(Form2.Edit1.Text);
finally
Form2.Free;
end;
end;


Pero no seria mas lindo poder hacer algo como esto?:


procedure TForm1.Button1Click(Sender: TObject);
var
Form2: TForm2;
begin
Form2 := TForm2.Create(NIL);
try
Memo1.Lines.Add(Form2.GetString);
finally
Form2.Free;
end;
end;

function TForm2.GetString: string;
begin
ShowModal;
Result := Edit1.Text;
end;


Obviamente se puede ir mejorando mas y mas, pero eso te lo dejo para que experimentes vos mismo

Saludos

Soa Pelaez
01-12-2015, 21:43:39
Este es un ejemplo trivial, basicamente consiste de dos Forms, Form1 y Form2

El Form1 consiste de un memo y un boton, el cual en su evento OnClick, crea y visualiza de manera modal el Form2. Por lo tanto en su clausula uses encontramos la Unit2

El Form2 simplemente tiene un Edit y un boton; Form2 en su clausula uses contiene a Unit1, por lo tanto creamos una referencia circular

Unidad1 -> Usa a la Unidad2
Unidad2 -> Usa a la Unidad1

En el evento OnClick del Form2, se agrega al Memo del Form1 el contenido del Edit, y se cierra el formulario

El codigo seria el siguiente:

unit Unit1;

interface

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

type
TForm1 = class(TForm)
Memo1: TMemo;
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);
var
Form2: TForm2;
begin
Form2 := TForm2.Create(NIL);
try
Form2.ShowModal;
finally
Form2.Free;
end;
end;

end.


unit Unit2;

interface

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

type
TForm2 = class(TForm)
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

implementation

uses
Unit1;

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
Form1.Memo1.Lines.Add(Edit1.Text);
Close;
end;

end.


Y en efecto si lo ejecutamos, podria decirse que funciona bien. Pero obviamente, si a mi me interesa en otro proyecto usar solo uno de estos dos Form, no me queda otra alternativa que incluir a los dos

Una primera solucion podria ser, quitar del uses del Form2, a la Unit1; obviamente el codigo ahora no compilara ya que no se conoce a 'Form1'.

Asi que la unica alternativa es acceder desde el Form1 al valor del Edit, asi:


procedure TForm1.Button1Click(Sender: TObject);
var
Form2: TForm2;
begin
Form2 := TForm2.Create(NIL);
try
Form2.ShowModal;
Memo1.Lines.Add(Form2.Edit1.Text);
finally
Form2.Free;
end;
end;


Pero no seria mas lindo poder hacer algo como esto?:


procedure TForm1.Button1Click(Sender: TObject);
var
Form2: TForm2;
begin
Form2 := TForm2.Create(NIL);
try
Memo1.Lines.Add(Form2.GetString);
finally
Form2.Free;
end;
end;

function TForm2.GetString: string;
begin
ShowModal;
Result := Edit1.Text;
end;


Obviamente se puede ir mejorando mas y mas, pero eso te lo dejo para que experimentes vos mismo

Saludos

Lo que quiero realmente es hacer algo similar a esto.

{$IFDEF CLR}
System.ComponentModel.Design.Serialization, System.Security.Permissions, System.Security, // Esto lo usa solamente si es un equipo que tiene S.O Windows

{$ENDIF}
{$IFDEF LINUX}
WinUtils, libc, // Esto lo usa solamente si es un equipo que tien S.O Linux
{$ENDIF}


Alguien tiene un ejemplo de algo asi, pero especificando uses de Unit, poniendo en contexto el ejemplo que cito en mi inquietud

ecfisa
01-12-2015, 23:41:17
Hola Soa Pelaez.

La verdad que no estoy seguro de haber comprendido tu consulta, ¿ Es algo parecido a lo que se trata aquí (http://stackoverflow.com/questions/26152305/delphi-conditional-compilation-in-uses-clause) ?

Saludos :)

Soa Pelaez
02-12-2015, 15:47:29
Hola ecfisa si asi lo quiero hacer, pero necesito un ejemplo en codigo, porque realmente no tengo idea de como llamar esto.

Alguien podria colaborarme con eso.

AgustinOrtu
02-12-2015, 17:08:24
Investiga sobre Define (http://www.delphibasics.co.uk/RTL.asp?Name=$Define), aunque sigo pensando que no das informacion suficiente de que es lo que realmente queres hacer

ecfisa
02-12-2015, 17:40:33
Hola de nuevo.

Yo tampoco entiendo cuál es la situación concreta a que vas a aplicarlo, pero te pongo unos casos básicos:

...
{$IFDEF VER150} uses uDelphi7; {$ENDIF} // uDelphi7 se incluye cuando compila en Delphi 7
{$IFDEF VER300} uses uDelphiSeattle; {$ENDIF} // uDelphiSeattle se incluye cuando compila en Delphi Seattle
{$IFDEF WIN32} uses uWin32; {$ENDIF} // uWin32 se incluye si el SO es Windows 32
{$IFDEF WIN64} uses uWin64; {$ENDIF} // uWin64 se incluye si el SO es Windows 64
...


Saludos :)

AgustinOrtu
02-12-2015, 18:21:55
Hay que entender que las directivas de compilacion son para el compilador, para generar el ejecutable binario final. No es informacion que se evalua en tiempo de ejecucion "si es el linux usa esto, si es windows usa esto"

Mas bien seria, "compila en windows usando estas unidades, compila en linux usando estas otras"

Soa Pelaez
02-12-2015, 18:42:45
Si eso lo se, pero también llegue a ver un ejemplo en donde creaban directivas para caso de Uses de Unit.

Que cuando estaba en tal formulario se usan solo las unidades que están dentro de la directiva.

En mi ejemplo necesito que reconozca que si llamo el formulario 2 desde mi formulario 3 solo realice el use Unit2, sin tener que usar la Unit1 que tengo implementada en el formulario 2, se que con directivas se puede, solo que no recuerdo bien como hacerlo.

AgustinOrtu
02-12-2015, 18:45:36
Yo sigo sin entender :D

Osea que Form3 llama a Form2 pero Form2 necesita Unit1. Y lo que se quiere es usar solamente la Unit3 y Unit2?

Soa Pelaez
02-12-2015, 18:49:48
Si lo ejecuto desde el formulario 2 quiero usar la Unit1
Si lo ejecuto desde el formulario 3 quiero que solo use Unit2(sin tener que usar Unit1).

Soa Pelaez
02-12-2015, 18:56:45
Yo sigo sin entender :D

Osea que Form3 llama a Form2 pero Form2 necesita Unit1. Y lo que se quiere es usar solamente la Unit3 y Unit2?

Lo que quiero hace es similar al enlace que coloco ecfisa.

Solo que aun no se como implementarlo por eso necesito un ejemplo practico en código.

Soa Pelaez
04-12-2015, 21:24:33
Lo que quiero hace es similar al enlace que coloco ecfisa.

Solo que aun no se como implementarlo por eso necesito un ejemplo practico en código.

Asi lo estoy haciendo pero aun no da lo que necesito.