Mega Search
23.2 Million


Sign Up

Make a donation  
Formstyle select: fsStayOnTop. Why click other any file,  
News Group: embarcadero.public.delphi.vcl.components.using

Formstyle   select: fsStayOnTop

Why click other any file, the form can't stay on top. How can I do?

XE7 VCL

thanks a lot!

Vote for best question.
Score: 0  # Vote:  0
Date Posted: 21-Dec-2014, at 12:20 AM EST
From: hots wally
 
Re: Formstyle select: fsStayOnTop. Why click other any file,  
News Group: embarcadero.public.delphi.vcl.components.using
hots wally wrote:

> Formstyle   select: fsStayOnTop
> 
> Why click other any file, the form can't stay on top. How can I do?
> 
> XE7 VCL
> 

When the application looses focus to another application the VCL
removes the topmost style and restores it when the application gets the
focus again. This is by design, the fsStayOnTop style is supposed to be
used to keep a form on top of the other application forms only.

To keep a form topmost even when the application looses focus you have
to detect when the focus moves to another application, wait until the
VCL has processed this event and removed the topmost style, then
restore it again.

For the first part you handle the Application.OnDeactivate event. To
delay your action you post a custom message to the form from the event
handler. And to restore the topmost state in the message handler you
use the SetWindowPos API function.

I found an old example on my snippets collection. I have not tested it
on XE7 but it should work:

{code: Delphi}
Making a secondary form stay topmost when the app looses focus

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
  Dialogs, StdCtrls;

const
  UM_SETTOPMOST = WM_USER + 1;
type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormHide(Sender: TObject);
  private
    FOldAppDeactivate: TNotifyEvent;
    Procedure AppDeactivate( sender: TObject );
    Procedure UMSetTopmost( var msg: TMessage ); message UM_SETTOPMOST;
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

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

procedure TForm2.FormShow(Sender: TObject);
begin
  clientheight := button1.Height + 8;
  setbounds( 0, 0, width, height );
  FOldAppDeactivate := Application.OnDeactivate;
  Application.OnDeactivate := AppDeactivate;
end;


procedure TForm2.FormHide(Sender: TObject);
begin
  Application.OnDeactivate := FOldAppDeactivate;
end;

procedure TForm2.AppDeactivate(sender: TObject);
begin
  if assigned( FOldAppDeactivate ) Then
    FOldAppDeactivate( sender );
  postmessage( handle, UM_SETTOPMOST, 0, 0 );
end;

procedure TForm2.UMSetTopmost(var msg: TMessage);
begin
  SetWindowPos( handle, HWND_TOPMOST, 0, 0, 0, 0,
                SWP_NOSIZE or SWP_NOMOVE or SWP_NOOWNERZORDER );
end;

end.
{code}

The form only contains a button and has handlers for the form's onShow
and onHide events. The rest is done in code.

-- 
Peter Below (TeamB)

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 21-Dec-2014, at 1:11 AM EST
From: Peter Below