Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Aplicacion Multiformulario (https://www.clubdelphi.com/foros/showthread.php?t=34228)

roman 02-08-2006 19:22:29

Las líneas al compilador le son indistintas. El punto es que hay un paso de más en la otra manera (Show después de Create). Claro que- como dije al principio -no afecta y seguro que en este caso concreto nadie notará un ciclo más del procesador, pero yo prefiero como norma evitar redundancias. Desde luego es más cuestión de gustos.

// Saludos

grone35 03-08-2006 00:49:19

Muy buen debate!! Pero compañeros, he tenido el mismo problema con cualquiera de los dos codigos!!! Despues de que cierro el formulario secundario no lo puedo volver a abrir.

saludos!!

kesu 24-08-2006 12:26:33

Un saludo a todos los foreros, quiza sea un poco tarde para este mensaje, pero espero que le sirva a alguno.

codigo para mostrar form hijas: ( procedimiento)

Código Delphi [-]
procedure mostrarHija(aHija: TFormClass);
var
auxForm: TForm;

begin
auxForm:= Application.FindComponent(Copy(aHija.ClassName,2,255)) as TForm;
if Assigned(auxForm) then
auxForm.Show
else
auxForm.Create(Application);

end;



luego ... si se decea destruir una ventana(form) hija al cerrarla y no solo
minimizarla, solo adicionamos una linea de codigo en el evento OnClose de
esta:

Código Delphi [-]
Action:= caFree;




de antemano pido disculpas si existe algun error en el codigo, lo escribo de
memoria, pero los que tienen el libro de Ian Marteens pueden consultarlo, pues fue en la "Cara Oculta" donde lo lei hace algun tiempo atras.

Lepe 24-08-2006 13:39:33

Parece que el compañero se quedó con el error, despues de 3 semanas supongo que lo habrá solucionado; tambien puede darse el caso de que lo haya "postpuesto".

Reuniendo todo lo dicho, sin entrar en más debates, una solución completa sería:
Código Delphi [-]
// En un toolbar del MDI abrimos la ventana.
procedure TFrmMDI.Toolbutton1Click(Sender:Tobject);
begin
  if not Assigned(FrmCliente) then
    FrmCliente := TfrmCliente.Create(Application)
  else
    FrmCliente.BringtoFront;
end;

// En el evento OnClose del propio FrmCliente añadimos:
procedure TFrmCliente.FormClose(...var action:TCloseaction);
begin
  action := cafree;
  FrmCliente := nil;
end;

Ventajas de este método:
- En la ventana de facturas se puede usar datos de Frmclientes de forma cómoda:
Código Delphi [-]
  if assigned(frmcliente) then
    ShowMessage(frmCliente.Loquesea);

- No necesitamos hacer un bucle para encontrar una ventana, porque tenemos sus referencias Frmclientes, FrmFacturas, etc.

- Solo permitimos una ventana abierta de cada tipo al mismo tiempo. En algunos casos es una desventaja, en otros una ventaja, depende de la filosofía que se quiera seguir.

El método de kesu si tiene un pequeño error, pero al haber sido escrito de memoria, demasiado bien está. Por otra parte, es "la otra filosofía" para trabajar con ventanas MDI, ese método si permite tener varias ventanas FrmClientes abiertas al mismo tiempo, pero tambien tiene sus inconvenientes. Si interesa ese método, pregunten.

Lo que sí es muy importante es no mezclar ambos métodos, porque tendríamos Access Violation, Abstract Error y otras muchas excepciones nada obvias de localizar

Saludos

grone35 25-08-2006 19:24:32

Aplicacion Multiformulario
 
Gracias Kesu y Lepe!!

La verdad no habia solucionado este inconveniente pero habia buscado otros caminos que solucionaban de manera diferente mi problema. Voy a probar lo que ustedes acosejan y espero dar parte positivo despues de esto.

Saludos!!

Delphius 07-01-2007 06:07:10

Pues lepe diste justo en el blanco...
 
Disculpen que habra este hilo desde hace tiempo... lo que pasa es que yo estaba buscando en los foros algo que me ayude a determinar un error.

Hace un tiempo dejé un hilo inconcluso. Pues, empecé a retomarlo... y estuve metiendo código.
Veran, estoy declarando un descendiente de TForm ,lo llamé TExpertForm. Pues en dicha forma se encapsulan procedimientos y propiedades que permitan realizar visualizaciones tanto en forma modales como no modales... y que funcionen tanto para aplicaciones MDI como SDI (es asi?:p)

Me leí todo y al llegar aqui:

Cita:

Empezado por Lepe
- Solo permitimos una ventana abierta de cada tipo al mismo tiempo. En algunos casos es una desventaja, en otros una ventaja, depende de la filosofía que se quiera seguir.

El método de kesu si tiene un pequeño error, pero al haber sido escrito de memoria, demasiado bien está. Por otra parte, es "la otra filosofía" para trabajar con ventanas MDI, ese método si permite tener varias ventanas FrmClientes abiertas al mismo tiempo, pero tambien tiene sus inconvenientes. Si interesa ese método, pregunten.

Lo que sí es muy importante es no mezclar ambos métodos, porque tendríamos Access Violation, Abstract Error y otras muchas excepciones nada obvias de localizar

¡Y eso es lo que me pasa!
Hasta ahora (todavia estoy viendo esto) el código que tengo es como sigue:

Código Delphi [-]
unit UExpertForm;

interface

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

const
  MAX_VARIABLES = 25;

type
  TStateModal = (smModal, smNotModal);
  TInstancePermits = (ipOnlyOne, ipMultiple);

  TVarDomain = (vdPublic, vdPrivate);
  TVarInfo = record
    Value: Variant;
    Domain: TVarDomain;
  end;

  TArrayVariables = array [0..MAX_VARIABLES - 1] of TvarInfo;

  TExpertForm = class(TForm)
  private
    { Private declarations }
    FVars: TArrayVariables;
    FInstancePermits: TInstancePermits;
    FState: TStateModal;
  protected
    { Protected declarations }
    FID: integer;
    FOptionView: integer;
    function GetID: integer; virtual; abstract;
    procedure SetID(const Value: integer); virtual; abstract;
    function GetOptionView: integer; virtual; abstract;
    procedure SetOptionView(const Value: integer); virtual; abstract;
    procedure VariableChange(Index: integer; Value, OldValue: Variant); virtual; abstract;
    procedure DomainChange(Index: integer; Domain, OldDomain: TVarDomain); virtual; abstract;
  public
    { Public declarations }
    property ID: integer read GetID;
    property OptionView: integer read GetOptionView;
    property InstancePermits: TInstancePermits read FInstancePermits write FInstancePermits;
    procedure SetVariable(const Index: integer; Value: Variant; Domain: TVarDomain);
    function GetVariable(Sender: TObject; Index: integer): Variant;
    procedure View(OptionView: integer; NewInstance: boolean);
    procedure ViewModal(OptionView: integer);
    procedure ViewNotModal(OptionView: integer; NewInstance: boolean);
  end;


implementation

{$R *.dfm}

procedure TExpertForm.SetVariable(const Index: integer; Value: Variant; Domain: TVarDomain);
var OldV: Variant;
    OldD: TVarDomain;
begin
  OldV := FVars[Index].Value;
  OldD := FVars[Index].Domain;
  if (Value <> OldV)
     then begin
            FVars[Index].Value := Value;
            VariableChange(Index, Value, OldV);
          end;
  if (Domain <> OldD)
     then begin
            FVars[Index].Domain := Domain;
            DomainChange(Index, Domain, OldD);
          end;
end;

function TExpertForm.GetVariable(Sender: TObject; Index: integer): Variant;
begin
  if (Sender <> Self) AND (FVars[Index].Domain = vdPrivate)
     then raise Exception.Create('Error. Variable is private')
          else result := FVars[Index].Value;
end;

procedure TExpertForm.View(OptionView: integer; NewInstance: boolean);
begin
 if FState = smModal
    then ViewModal(OptionView)
    else ViewNotModal(OptionView, NewInstance);
end;

procedure TExpertForm.ViewModal(OptionView: integer);
begin
 if (NOT Assigned(Self))
    then begin
           with Create(Application) do
             try
               SetOptionView(OptionView);
               FState := smModal;
               ModalResult := ShowModal;
             finally
               Free;
             end;
         end
    else begin
           SetOptionView(OptionView);
           FState := smModal;
           ModalResult := ShowModal;
         end;
end;

procedure TExpertForm.ViewNotModal(OptionView: integer; NewInstance: boolean);
var Frm: TExpertForm;
begin
  // si es de una sola instancia...
  LockWindowUpdate(Application.MainForm.Handle);
  try
    if NOT (Assigned(Self))
       then begin
             // no hay ventana... hacer una
             with Create(Application) do
               try
                 FState := smNotModal;
                 FOptionView := OptionView;
                 Show;
               finally
                 Free;
               end;
            end
       else begin
               FState := smNotModal;
               FOptionView := OptionView;
               if Self.WindowState = wsMinimized
                  then Self.WindowState := wsNormal;
               Self.BringToFront;
               Self.Show;
               Exit;
            end;
  finally
    LockWindowUpdate(0);
  end;
end;

end.

Me preguntaba si se podrá realizar lo que pretendo... se que tiene errores... y algunos los veo ahorita. Mi pregunta mas que nada pasa por el hecho de como controlar que se pueda operar tanto para una sola instancia como para varias.

Desde ya muchas gracias,

Saludos,

Delphius 07-01-2007 21:33:25

Aclaro algunas cosillas...
 
Me pareció oportuno aclarar algo sobre el código que expuse anteriormente. Mi intención (pues.. el código está en versión 0.0beta:D:p )no es simplemente contar con un form especializado en mostrarse modal o no, con o sin instancias multiples. Si se fijan bien... tiene en su estructura interna un array del tipo variant. El mismo está pensado para llevar en el cualquier variable que usualmente uno declararía en la unidad. Lo que evitaría tener que estar declarando variables... (eso pretendo yo). Sólo bastaría con asignarles valores a las posiciones que uno desea. Por ejemplo: que Vars[1] indique CantidadActualPedidos. No se si la idea es buena... tiene su defecto... al destruir la forma todo se pierde (por tanto la solución es usar variables globales) [en lo personal... no me gusta emplear demasiada variables globales].


Comento esto ya que para alguno tal vez le sirva... y le de una idea, y para que se me entienda mejor.

Entonces, la forma mantiene encapsulada funciones para manejar el vector y va a tener... (pues todavia falla) funciones para mostrarse adecuadamanete según sea necesario. Si alguien ya tiene algo parecido, o si creen que estoy inventando la rueda me avisan.

Saludos,

Lepe 08-01-2007 11:47:44

Sobre el Variant.... a ver si esto le ves alguna utilidad ;).


Saludos

Delphius 09-01-2007 05:49:32

claro... es muy util
 
Cita:

Empezado por Lepe
Sobre el Variant.... a ver si esto le ves alguna utilidad ;).

Pues, lo lamento... no creo que me sirva:rolleyes:, jaja. La verdad que esta buena esa unidad. Estaba por ponerle métodos y funciones parecidas a la que tiene. Es que como nunca había utilizado Variant estuve viendo la ayuda sobre este tipo, para darme idea y note que habia funciones para conversiones...

Por ahora me estaba por concentrar en tratar de elaborar funciones para que la ventana se muestre modal, no modal, que permita una o mas instancias, MDI, etc... y como esto es algo más para el aspecto estetico de mis aplicaciones es algo que le dedico poco esfuerzo. Mi mayor concentración está por el momento en la lógica y diseño de unidades de bajo y medio nivel.

Si bien esta unidad (TExpertForm) me viene barbaro para el aspecto visual... si no me sale.., no hay drama. Lo que importa es que la lógica ande.

Si tengo novedades y problemas sobre este aspecto, estaré metiendo dudas.

Saludos,

Lepe 09-01-2007 12:50:08

Como bien dices, hay métodos para convertir el variant, pero al usar dichas conversiones en el programa final, se enrolla mucho el código, por eso mismo creé esa unidad, es más práctico.

Yo lo veo usando un TObjectList con cada VariantElement, así quitaríamos el array que se crea siempre. Pero bueno, si de momento no te sirve... ahí queda para cualquiera.

En tu código hay algo que no entiendo muy bien:
Código Delphi [-]
procedure TExpertForm.ViewModal(OptionView: integer);
begin
 if (NOT Assigned(Self))
    then begin
           with Create(Application) do
             try
Assigned(Self) se refiere a la instancia de TEXpertForm; como siempre haremos algo así:
Código Delphi [-]
var EF :TExpertForm;
begin
 EF := TExpertForm.Create;
 EF.ViewModal(3);
El ExpertForm siempre estará creado, por tanto, jamás entrará en esa rama.

Si el ExpertForm no está creado previamente, delphi nos lanzará un access violation al intentar acceder al método ViewModal (o cualquier otro), antes de intentar ejecutarlo, por ende, tampoco le veo sentido a "With Create(Application)"

No entiendo muy bien la filosofía que sigues, ya que en principio debe existir una instancia de ese ExpertForm, quizás viendo el código del "programa de usuario" (el que usa el módulo ExpertForm), entendería la funcionalidad que quieres crear.

Saludos

Delphius 09-01-2007 17:33:45

Cita:

Empezado por Lepe
Yo lo veo usando un TObjectList con cada VariantElement, así quitaríamos el array que se crea siempre. Pero bueno, si de momento no te sirve... ahí queda para cualquiera.

Si tiene utilidad... yo dije a modo de broma:
Cita:

Empezado por Yo
no creo que me sirva:rolleyes:, jaja.

Con respecta a lo que comentas del código, si es verdad que tiene fallas... yo escribí el código asi para darme una idea de lo que debería hacer para ir refinandolo. Tengo que mejorarlo.

Cita:

Empezado por Lepe
No entiendo muy bien la filosofía que sigues, ya que en principio debe existir una instancia de ese ExpertForm, quizás viendo el código del "programa de usuario" (el que usa el módulo ExpertForm), entendería la funcionalidad que quieres crear.

Programa de usuario no hay todavía. Sólo esa unidad. Mi intensión es tener funciones o prodedimientos (a gustos) que permitan a dicha forma (mejor dicho a instancias, pues para ser usada debe ser heredada) mostrarse tanto en forma modal o no, seteando algunos valores en sus propiedades (y dependiendo de ellos). Yo había puesto:

Código Delphi [-]
procedure TExpertForm.ViewModal(OptionView: integer);
begin
 if (NOT Assigned(Self))
    then begin

Pues, el objetivo es determinar si ha sido creada una instancia
de la forma. Si la hay, mostrarla, si no la hay... primero
crearla. Y pruebas que hice, esta parte funciona. Haz la prueba:
1. Agrega al dpr la unidad.
2. Hereda la forma y desactivala de las auto-creadas.
3. Al form1 dale un código donde te guste:
Código Delphi [-]
TExpertForm2.ViewModal(1);
¡La forma se crea, y modal! Ha decir verdad... las pruebas que he realizado me han indicado que sólo funcionan (ViewModal y ViewNotModal) siempre y cuando no esté en auto create forms. Eso si... no recuerdo bien si hice cambios y luego verifique, mis disculpas. Ya me pongo a ver si es asì. Pero de las pruebas que hice, es como describo.

Utilidad que pretendo es encapsular todo y dejar que sea la misma forma decida como debe mostrarse (según las propiedades seteadas) y ofrecer publicamente sólo algunas de las propiedades y funciones. Por ejemplo: tanto ViewModal como ViewNotModal deben ser declaradas en forma privada y sólo dejar View.
El hecho de tener ese array de variables, es para permitir el flujo de datos entre unidades.


La franja horaria es GMT +2. Ahora son las 17:33:55.

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