#delphi #firemonkey #delphi-10.4-sydney
#delphi #firemonkey #delphi-10.4-Сидней
Вопрос:
Есть несколько случаев, когда формы или диалоговые окна, которые должны быть модальными, не остаются на вершине. Я создаю для Windows, используя 10.4. Вот простой пример, включающий две формы и TSaveDialog.
Чтобы воспроизвести проблему:
- Запустите приложение в Windows
- Нажмите кнопку Показать окно (вы должны увидеть Form2)
- Нажмите кнопку Показать диалоговое окно сохранения (вы должны увидеть диалоговое окно сохранения)
- Щелкните другое окно, которое не является частью приложения, например окно проводника
- Нажмите Form2. Form1 теперь будет впереди
Если вы повторите это, но сначала увеличите Form1, пользователю будет нелегко решить, не закрыв программу из диспетчера задач или не используя некоторые экспертные знания 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 = 'Show Window'
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 = 'Show Save Dialog'
OnClick = Button1Click
end
object SaveDialog1: TSaveDialog
Left = 80
Top = 40
end
end
Блок1:
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.
Блок2:
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.
Я не видел такого поведения в приложениях VCL (модальные окна всегда остаются на вершине). Я также видел проблему в приложениях FMX с формами, которые были показаны с помощью ShowModal и даже окон сообщений, созданных с помощью ShowMessage. Использование TDialogServiceSync.ShowMessage, похоже, помогает предотвратить это, но даже тогда некоторые пользователи сталкиваются с той же проблемой.
Почему это происходит и могу ли я что-нибудь сделать, чтобы это исправить?
Ответ №1:
Попробуйте установить родительский элемент.
Нравится :
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.parent := form1;
Form2.Show;
end;
Я получил хороший результат с этим, но в OSX это не работает.
Комментарии:
1. Спасибо. По крайней мере, это помогает в моем примере.
Ответ №2:
Вы могли бы установить FormStyle
Form2
значение StayOnTop
FormStyle — это одно из значений Normal, Popup или StayOnTop, определенных в TFormStyle.
Обычный: обычная форма. Такая форма может иметь активное состояние и поддерживать z-порядок.
Всплывающее окно: такая форма не может быть активной. Все формы этого типа принадлежат списку PopupForms.
StayOnTop: эта форма остается поверх рабочего стола и других форм в приложении, за исключением любой другой формы, для которой также установлен FormStyle в StayOnTop. Если одна форма StayOnTop запускает другую, ни одна из форм не будет постоянно оставаться на вершине.
https://docwiki.embarcadero.com/Libraries/Sydney/en/FMX.Types .TFormStyle
Комментарии:
1. Я согласен с Басом ван дер Линденом . Отображение формы модально не означает, что она останется на вершине. Вам нужно установить значение
FormStyle
бытьStayOnTop
первым. Теперь, поскольку диалоги также являются просто модальными формами, необязательно, чтобы диалоговая форма оставалась поверх другой модальной формы. В VCL вы можете передать дополнительный параметр в диалоговое окно, указав ему, какая из его родительских форм всегда остается над ним. Но, к сожалению, в FMX такой опции нет2. В этом проблема. TSaveDialog не имеет свойства FormStyle.
3. Проблема с этим ответом заключается в том, что я, возможно, не хочу, чтобы Form2 всегда оставался на вершине. Возможно, я захочу отобразить обе формы и переключаться между ними. Но когда отображается диалоговое окно сохранения, я ожидаю, что оно всегда будет оставаться на вершине. К сожалению, для TSaveDialog нет свойства FormStyle. Однако ответ Эдвардса решает эту проблему.