Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modal forms hidden by fsStayOnTop forms

I have a form (TBigForm in the example below) which allows to manipulate some complex data and needs additional information to be shown. I put this info in a fsStayOnTop form (OnTopForm in the example) to ensure it's always visible but can be moved out of the way if necessary. Now when some user action in TBigForm shows a modal form this often gets hidden behind OnTopForm which makes the app look frozen. How can I avoid this? (Searching yields many, many hits but I wasn't able to distill a solution out of them.)

In my real app there are a lot of places where modal forms are shown, so I would like to avoid changing all of these calls.

Example: Create a new VCL application, drop a TButton on Form1, double-click the button and replace the generated Button1Click implementation stub with the following:

type
  TBigForm = class(TForm)
  strict private
    OnTopForm: TForm;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  protected
    procedure DoHide; override;
    procedure DoShow; override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

{ TBigForm }

procedure TBigForm.Button1Click(Sender: TObject);
begin
  ShowMessage('Test');
end;

constructor TBigForm.Create(AOwner: TComponent);
begin
  inherited CreateNew(AOwner);

  Caption := 'Big form';
  WindowState := wsMaximized;

  Button1 := TButton.Create(Self);
  Button1.Parent := Self;
  Button1.Caption := 'Freeze!';
  Button1.SetBounds(10, 10, 100, 100);
  Button1.OnClick := Button1Click;
end;

procedure TBigForm.DoHide;
begin
  OnTopForm.Free;
  inherited DoHide;
end;

procedure TBigForm.DoShow;
begin
  inherited DoShow;
  OnTopForm := TForm.Create(Self);
  OnTopForm.Caption := 'Important information';
  OnTopForm.BorderStyle := bsToolWindow;
  OnTopForm.FormStyle := fsStayOnTop;
  OnTopForm.Position := poScreenCenter;
  OnTopForm.Show;
end;

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
  f: TBigForm;
begin
  f := TBigForm.Create(nil);
  try
    f.ShowModal;
  finally
    f.Free;
  end;
end;

Start the app, click on "Button1" and then on "Freeze!".

(BTW: We use D2007.)

like image 566
Uli Gerhardt Avatar asked Oct 14 '22 02:10

Uli Gerhardt


2 Answers

Change temporarily the FormStyle of your OnTopform before displaying another Form as Modal:

procedure TBigForm.Button1Click(Sender: TObject);
begin
  OnTopForm.FormStyle := fsNormal;
  ShowMessage('Test');
  OnTopForm.FormStyle := fsStayOnTop;
end;

It should work for what you want...

like image 184
Francesca Avatar answered Oct 19 '22 09:10

Francesca


Try setting the modal Form's PopupParent property to be the StayOnTop Form, or set the Application.ModalPopupMode property to something other than pmNone, prior to calling ShowModal().

like image 41
Remy Lebeau Avatar answered Oct 19 '22 07:10

Remy Lebeau