Tutorial :Modal forms hidden by fsStayOnTop forms



Question:

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


Solution:1

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


Solution:2

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


Solution:3

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


Solution:4

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
Previous
Next Post »