Tutorial :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.)


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...


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().


Here your goody

Create an global TApplicationEvents  Declare an global var to keep track of modal form count  Hookup the OnMessage    var    Ctrl: TControl;    if Msg.hwnd <> 0 then    case Msg.message of      CM_ACTIVATE,      CM_DEACTIVATE:      begin        Ctrl := FindControl(Msg.hwnd);        if Ctrl is TForm then          if fsModal in TForm(Ctrl).FormState then          begin              if Msg.message = CM_ACTIVATE then              Inc(Modal form count var)            else              Dec(Modal form count var);              add more logic based on Modal form count var          end;      end;    end;  

Have fun


procedure TForm1.ScreenOnActiveFormChange(Sender: TObject);  begin    if (Screen.ActiveForm <> nil) then    begin      if (Screen.ActiveForm.Handle <> Application.MainForm.Handle) then        with Screen.ActiveForm do          SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);      Windows.SetForeGroundWindow(Screen.ActiveForm.Handle);    end;  end;  

This should work.

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Next Post »