es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

FMX: Los formularios modales no permanecen en la parte superior (Windows)

Hay varios casos en los que los formularios o diálogos que deberían ser modales no se mantienen en la parte superior. Estoy creando para Windows utilizando la versión 10.4. Aquí hay un ejemplo sencillo que involucra dos formularios y un TSaveDialog.

Para replicar el problema:
– Ejecute la aplicación en Windows
– Haga clic en el botón “Mostrar ventana” (debería ver Form2)
– Haga clic en el botón “Mostrar cuadro de diálogo Guardar” (debería ver el cuadro de diálogo Guardar)
– Haga clic en otra ventana que no sea parte de la aplicación, como una ventana de explorador.
– Haga clic en Form2. Form1 ahora estará al frente.

Si repite esto pero maximiza Form1 primero, no será fácil para el usuario resolverlo sin cerrar el programa desde el Administrador de tareas o utilizando algún conocimiento experto de Windows.

Form1:

object Form1: TForm1
Left = 0
Top = 0
Caption = ‘Form1’
ClientHeight = 480
ClientWidth = 640
Position = ScreenCenter
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
DesignerMasterStyle = 0
object Button1: TButton
Position.X = 264.000000000000000000
Position.Y = 168.000000000000000000
Size.Width = 97.000000000000000000
Size.Height = 33.000000000000000000
Size.PlatformDefault = False
Text = ‘Mostrar ventana’
OnClick = Button1Click
end
end

Form2:

object Form2: TForm2
Left = 0
Top = 0
Caption = ‘Form2’
ClientHeight = 333
ClientWidth = 489
Position = ScreenCenter
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
DesignerMasterStyle = 0
object Button1: TButton
Position.X = 184.000000000000000000
Position.Y = 136.000000000000000000
Size.Width = 113.000000000000000000
Size.Height = 41.000000000000000000
Size.PlatformDefault = False
Text = ‘Mostrar cuadro de diálogo Guardar’
OnClick = Button1Click
end
object SaveDialog1: TSaveDialog
Left = 80
Top = 40
end
end

Unit1:
unit Unit1;

interface

uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, Unit2,
FMX.Controls.Presentation, FMX.StdCtrls;

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

var
Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.Show;
end;

end.

Unit2:
unit Unit2;

interface

uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.Controls.Presentation, FMX.StdCtrls;

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

var
Form2: TForm2;

implementation

{$R *.fmx}

procedure TForm2.Button1Click(Sender: TObject);
begin
SaveDialog1.Execute;
end;

end.

No he visto este comportamiento en aplicaciones VCL (las ventanas modales siempre se mantienen en la parte superior). También he visto el problema en aplicaciones FMX con formularios que se han mostrado usando ShowModal e incluso ventanas de mensaje creadas con ShowMessage. El uso de TDialogServiceSync.ShowMessage parece ayudar a prevenir esto, pero aún así algunos usuarios experimentan el mismo problema.

¿Por qué está sucediendo esto y hay algo que pueda hacer para solucionarlo?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Este problema puede estar ocurriendo porque los formularios no están configurados para estar siempre en primer plano. Para solucionarlo, puede establecer la propiedad FormStyle del formulario en fsStayOnTop. Puede hacer esto agregando la siguiente línea al evento FormCreate tanto de Form1 como de Form2:

    FormStyle := fsStayOnTop;
    

    Esto asegurará que los formularios siempre permanezcan en la parte superior incluso cuando se hace clic en otra ventana. Además, puede establecer la propiedad PopupMode del formulario en pmAuto para garantizar que el formulario permanezca en la parte superior solo cuando es una ventana activa.

    Otra solución es utilizar la API de Windows para establecer el ZOrder del formulario. Puede hacer esto agregando el siguiente código al evento Button1Click tanto de Form1 como de Form2:

    SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
    

    Este código establecerá el ZOrder del formulario como la ventana más superior, incluso cuando se hace clic en otra ventana.

    En general, asegurarse de que los formularios tengan las propiedades FormStyle y PopupMode correctas y utilizar SetWindowPos para establecer su ZOrder pueden ayudar a evitar que las ventanas modales pierdan el enfoque y permanezcan en la parte superior de otras ventanas.

Comments are closed.