Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Application.Run VS Form1.Showmodal (https://www.clubdelphi.com/foros/showthread.php?t=34383)

mmusashi 08-08-2006 11:34:10

Application.Run VS Form1.Showmodal
 
Guenas!!

Tengo una duda existencial....

¿que diferencia hay entre poner en el .dpr Application.Run o poner Form1.ShowModal (siendo Form1 el formulario principal)?

¿Hay alguna diferencia a efectos practicos?

Gracias.

dec 08-08-2006 11:40:04

Hola,

Código Delphi [-]
function TCustomForm.ShowModal: Integer;
var
  WindowList: Pointer;
  SaveFocusCount: Integer;
  SaveCursor: TCursor;
  SaveCount: Integer;
  ActiveWindow: HWnd;
begin
  CancelDrag;
  if Visible or not Enabled or (fsModal in FFormState) or
    (FormStyle = fsMDIChild) then
    raise EInvalidOperation.Create(SCannotShowModal);
  if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
  ReleaseCapture;
  Application.ModalStarted;
  try
  Include(FFormState, fsModal);
  ActiveWindow := GetActiveWindow;
  SaveFocusCount := FocusCount;
  Screen.FSaveFocusedList.Insert(0, Screen.FFocusedForm);
  Screen.FFocusedForm := Self;
  SaveCursor := Screen.Cursor;
  Screen.Cursor := crDefault;
  SaveCount := Screen.FCursorCount;
  WindowList := DisableTaskWindows(0);
  try
    Show;
    try
      SendMessage(Handle, CM_ACTIVATE, 0, 0);
      ModalResult := 0;
      repeat
        Application.HandleMessage;
        if Application.FTerminate then ModalResult := mrCancel else
          if ModalResult <> 0 then CloseModal;
      until ModalResult <> 0;
      Result := ModalResult;
      SendMessage(Handle, CM_DEACTIVATE, 0, 0);
      if GetActiveWindow <> Handle then ActiveWindow := 0;
    finally
      Hide;
    end;
  finally
    if Screen.FCursorCount = SaveCount then
      Screen.Cursor := SaveCursor
    else Screen.Cursor := crDefault;
    EnableTaskWindows(WindowList);
    if Screen.FSaveFocusedList.Count > 0 then
    begin
      Screen.FFocusedForm := Screen.FSaveFocusedList.First;
      Screen.FSaveFocusedList.Remove(Screen.FFocusedForm);
    end else Screen.FFocusedForm := nil;
    if ActiveWindow <> 0 then SetActiveWindow(ActiveWindow);
    FocusCount := SaveFocusCount;
    Exclude(FFormState, fsModal);
  end;
  finally
    Application.ModalFinished;
  end;
end;

Código Delphi [-]
procedure TApplication.Run;
begin
  FRunning := True;
  try
    AddExitProc(DoneApplication);
    if FMainForm <> nil then
    begin
      case CmdShow of
        SW_SHOWMINNOACTIVE: FMainForm.FWindowState := wsMinimized;
        SW_SHOWMAXIMIZED: MainForm.WindowState := wsMaximized;
      end;
      if FShowMainForm then
        if FMainForm.FWindowState = wsMinimized then
          Minimize else
          FMainForm.Visible := True;
      repeat
        try
          HandleMessage;
        except
          HandleException(Self);
        end;
      until Terminated;
    end;
  finally
    FRunning := False;
  end;
end;

Neftali [Germán.Estévez] 08-08-2006 11:59:22

Cita:

Empezado por mmusashi
¿Hay alguna diferencia a efectos practicos?

Bueno, la que más, es que en un caso el formulario que muestres será modal y en el otro no. Mucha por cierto.

Haz pruebas con formularios modales y verás si es lo que necesitas para el formulario principal de tu aplicación o no.

Enan0 08-08-2006 15:50:36

Es decir cuando haces la llamada a un formulario modal. entra en el proceso del formulario actual y va a procesar todo lo que se pueda o quiera hacer dentro de ese formulario. luego cuando lo cierres o lo finalizes continuara con la carga del proceso que lo llamo.

Ejemplo
Código Delphi [-]
......
.....
miformulario.Showmodal;
Showmessage('salio del form modal');
......
....

En estes caso el mensaje solo sera mostrado cuando Cierres el formulario "miformulario"

Código Delphi [-]
......
......
miformulario.show;
Showmessage('salio del form no modal');
....
....

En este caso. luego de mostrar en pantalla tu formulario. a continuacion se mostrara el mensaje.
es decir
Cuando mostramos un formulario de manera Modal, se interumple el "Hilo del proceso" hasta que finalize la ejecucion del formulario. entonces se retorna al "hilo general del proceso" y continua su ejecucion.

Hilo del proceso: No estoy seguro que se llame asi. pero leamolos como, las instrucciones a ejecutar dentro de un proceso lineal.


roman 08-08-2006 17:41:00

A ver, yo voy a preguntar también lo mismo que mmusashi:

¿que diferencia hay entre poner en el .dpr Application.Run o poner Form1.ShowModal (siendo Form1 el formulario principal)?

¿Hay alguna diferencia a efectos practicos?

resaltando lo de efectos prácticos.

Yo mismo he tenido esa duda y no creo que estemos contestando eso. Poner el código de uno u otro caso, no nos dice nada a efectos prácticos. Por otra parte esto:

Cita:

Empezado por Neftali
en un caso el formulario que muestres será modal y en el otro no. Mucha por cierto.

Es que esto es cierto en general, pero no con el formulario principal. Quizá valga la pena aclarar lo que estamos preguntando. Podemos tener nuestro dpr así:

Código Delphi [-]
program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  //Application.CreateForm(TForm1, Form1);
  Form1 := TForm1.Create(Application);
  Form1.ShowModal;
  //Application.Run;
end.

¿Cuál es la diferencia aquí para efecto prácticos? Yo no veo ninguna. En ambos casos se interrumpe el proceso hasta que se cierra la ventana. ¿Cuál proceso? En este caso el flujo desde el begin al end. Quizá la hay- y fuerte -durante la vida de la aplicación, esto es, quizá haya algún efecto colateral importante; pero a simple vista yo no lo veo.

// Saludos

roman 08-08-2006 17:47:11

Fé de erratas
 
En lo que comento respecto a lo de Neftali, estoy equivocado. Ciertamente hay diferencia entre mostrar modal o no al formulario principal. Pero es que esa no fue la pregunta original. La pregunta fue: ¿qué diferencia hay entre Form1.ShowModal y Application.Run?

// Saludos

Enan0 08-08-2006 18:01:51

mi respuesta queda totalmente invalidada, ya que no interprete correctamente lo que pedia mmusashi.

Neftali [Germán.Estévez] 08-08-2006 18:27:44

Cita:

Empezado por roman
¿qué diferencia hay entre Form1.ShowModal y Application.Run?

Creo que lo mejor es un ejemplo.

Con este código resula este ejemplo:
Código Delphi [-]
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.CreateForm(TForm2, Form2);
  Form1.ShowModal;
//  Application.Run;

Y con este otro código resulta este otro:
Código Delphi [-]
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.CreateForm(TForm2, Form2);
//  Form1.ShowModal;
  Application.Run;

Ambos resultados son bastante diferentes, sobre todo si se intenta acceder al segundo formulario.

roman 08-08-2006 18:46:42

Les gusta rizar el rizo ¿verdad? Ok. Entonces repregunto:

Entre esto:

Código Delphi [-]
program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  //Application.CreateForm(TForm1, Form1);
  Form1 := TForm1.Create(Application);
  Form1.ShowModal;
  //Application.Run;
end.

y un dpr normal:

Código Delphi [-]
program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  //Form1 := TForm1.Create(Application);
  //Form1.ShowModal;
  Application.Run;
end.

¿cuál es la diferencia a efectos prácticos? Sigo sin ver ninguna.

// Saludos

roman 08-08-2006 19:31:27

Voy a ver si puedo aclarar un poco.

Normalmente, una aplicación en Windows consiste de un ciclo que procesa los mensajes y que no termina sino hasta que se recibe el mensaje de finalización. Esto es básicamente lo que hace Application.Run.

Por otra parte, una ventana modal es muy similar: entra a su propio ciclo de mensajes hasta que recibe el que la obliga a cerrarse.

En resumen, en ambos casos se tiene algo similar a:

Código:

REPEAT
  ObtenMensaje(Mensaje);
  ProcesaMensaje(Mensaje);
UNTIL Mensaje = TERMINAR;

En estos términos, podemos valernos del ciclo de mensajes del formulario principal para sustituir al de la aplicación. Claro que eso implica algunos cambios. En el ejemplo de Neftali, el segundo formulario debe tener su propiedad Visible en true de manera que se muestra aun antes de que decidamos si el principal se muestra normal o modalmente.

Pero si dejamos que únicamente el formulario principal se cree de entrada (cosa que normalmente hacemos de cualquier forma), y creamos los demás conforme los requerimos, entonces todo ello se puede hacer desde el ciclo de mensajes del formulario principal mostrado modalmente.

La pregunta es entonces, si el usar este ciclo de mensajes, el de un formulario en lugar del de la aplicación, tendrá algún efecto colateral.

// Saludos

dec 09-08-2006 08:01:08

Hola,

Cita:

Empezado por Román
Poner el código de uno u otro caso, no nos dice nada a efectos prácticos.

Vaya, y yo que pensaba que el código fuente tenía ciertos efectos prácticos... qué le voy a hacer, estaba equivocado.

Resulta que este código fuente:

Código Delphi [-]
function TCustomForm.ShowModal: Integer;
var
  WindowList: Pointer;
  SaveFocusCount: Integer;
  SaveCursor: TCursor;
  SaveCount: Integer;
  ActiveWindow: HWnd;
begin
  CancelDrag;
  if Visible or not Enabled or (fsModal in FFormState) or
    (FormStyle = fsMDIChild) then
    raise EInvalidOperation.Create(SCannotShowModal);
  if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
  ReleaseCapture;
  Application.ModalStarted;
  try
  Include(FFormState, fsModal);
  ActiveWindow := GetActiveWindow;
  SaveFocusCount := FocusCount;
  Screen.FSaveFocusedList.Insert(0, Screen.FFocusedForm);
  Screen.FFocusedForm := Self;
  SaveCursor := Screen.Cursor;
  Screen.Cursor := crDefault;
  SaveCount := Screen.FCursorCount;
  WindowList := DisableTaskWindows(0);
  try
    Show;
    try
      SendMessage(Handle, CM_ACTIVATE, 0, 0);
      ModalResult := 0;
      repeat
        Application.HandleMessage;
        if Application.FTerminate then ModalResult := mrCancel else
          if ModalResult <> 0 then CloseModal;
      until ModalResult <> 0;
      Result := ModalResult;
      SendMessage(Handle, CM_DEACTIVATE, 0, 0);
      if GetActiveWindow <> Handle then ActiveWindow := 0;
    finally
      Hide;
    end;
  finally
    if Screen.FCursorCount = SaveCount then
      Screen.Cursor := SaveCursor
    else Screen.Cursor := crDefault;
    EnableTaskWindows(WindowList);
    if Screen.FSaveFocusedList.Count > 0 then
    begin
      Screen.FFocusedForm := Screen.FSaveFocusedList.First;
      Screen.FSaveFocusedList.Remove(Screen.FFocusedForm);
    end else Screen.FFocusedForm := nil;
    if ActiveWindow <> 0 then SetActiveWindow(ActiveWindow);
    FocusCount := SaveFocusCount;
    Exclude(FFormState, fsModal);
  end;
  finally
    Application.ModalFinished;
  end;
end;

Es prácticamente igual que este otro:

Código Delphi [-]
procedure TApplication.Run;
begin
  FRunning := True;
  try
    AddExitProc(DoneApplication);
    if FMainForm <> nil then
    begin
      case CmdShow of
        SW_SHOWMINNOACTIVE: FMainForm.FWindowState := wsMinimized;
        SW_SHOWMAXIMIZED: MainForm.WindowState := wsMaximized;
      end;
      if FShowMainForm then
        if FMainForm.FWindowState = wsMinimized then
          Minimize else
          FMainForm.Visible := True;
      repeat
        try
          HandleMessage;
        except
          HandleException(Self);
        end;
      until Terminated;
    end;
  finally
    FRunning := False;
  end;
end;

Estos chicos de Borland... hay que ver lo que les gusta duplicar las cosas...

roman 09-08-2006 08:07:23

¿Has leido lo escrito?

Esa diferencia en el código es precisamente lo que lleva a uno a preguntarse qué pasa puesto que el efecto práctico parece ser el mismo según lo describí en el último mensaje.

// Saludos

dec 09-08-2006 08:19:32

Hola,

Cita:

Empezado por Román
¿Has leido lo escrito?

Sí.

Cita:

Esa diferencia en el código es precisamente lo que lleva a uno a preguntarse qué pasa puesto que el efecto práctico parece ser el mismo según lo describí en el último mensaje.
"Parece ser el mismo" no es una respuesta correcta. Yo no comprendo los dos métodos, es decir, qué se lleva a cabo exactamente en uno y en otro, pero, me parece a simple vista que no son iguales, que no hacen lo mismo, y que en la práctica se utiliza uno en lugar de otro, y que por algo será, aunque yo no sepa exactamente porqué. Si ambos fueran iguales,... ¿para qué entonces duplicar el asunto? Es evidente que hay diferencias y que estas tienen que tener "efectos prácticos" distintos.

Ahora bien, estúdiese el código fuente de ambos métodos y sus correspondientes implicaciones y, apuesto a que tienen que verse diferencias prácticas en caso de utilizar uno u otro método. A bote pronto diría lo más evidente: parece que en un caso ponemos en marcha la aplicación, y en otro ponemos en marcha un formulario de la aplicación. Estas cosas no parecen ser iguales grosso modo.

roman 09-08-2006 08:34:02

Cita:

Empezado por dec
"Parece ser el mismo" no es una respuesta correcta.

Disculpa maese, prometo estudiar más.

// Saludos

dec 09-08-2006 08:42:09

Hola,

Cita:

Empezado por Román
Disculpa maese, prometo estudiar más.

Estupendo. ;)

roman 09-08-2006 08:58:13

Hola, quizá esto aclare un poco.

Abran el demo MastApp que viene con Delphi. Es un demo medianamente complejo en tanto que incluye muchos formularios además del principal. Algunos abren modalmente y otros no.

Este es el dpr del demo con el sólo cambio al final de omitir Application.Run y poner MainForm.ShowModal en su lugar.

Código Delphi [-]
begin
  Application.Initialize;
  SplashForm := TSplashForm.Create(Application);
  SplashForm.Show;
  SplashForm.Update;
  Application.Title := 'Marine Adventures Order Entry';
  Application.HelpFile := 'MASTAPP.HLP';
  Application.CreateForm(TMastData, MastData);
  Application.CreateForm(TMainForm, MainForm);
  Application.CreateForm(TBrPartsForm, BrPartsForm);
  Application.CreateForm(TQueryCustDlg, QueryCustDlg);
  Application.CreateForm(TEdPartsForm, EdPartsForm);
  Application.CreateForm(TBrCustOrdForm, BrCustOrdForm);
  Application.CreateForm(TEdCustForm, EdCustForm);
  Application.CreateForm(TEdOrderForm, EdOrderForm);
  Application.CreateForm(TSearchDlg, SearchDlg);
  Application.CreateForm(TBrDateForm, BrDateForm);
  Application.CreateForm(TAboutBox, AboutBox);
  Application.CreateForm(TPickRpt, PickRpt);
  Application.CreateForm(TCustomerByInvoiceReport, CustomerByInvoiceReport);
  Application.CreateForm(TOrdersByDateReport, OrdersByDateReport);
  Application.CreateForm(TInvoiceByOrderNoReport, InvoiceByOrderNoReport);
  Application.CreateForm(TPickOrderNoDlg, PickOrderNoDlg);
  SplashForm.Hide;
  SplashForm.Free;

  MainForm.ShowModal;
  //Application.Run;
end.

Compilen la aplicación y jueguen un rato con ella y díganme que diferencias ven en su ejecución.

// Saludos


La franja horaria es GMT +2. Ahora son las 20:21:11.

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