Formstyle select: fsStayOnTop. Why click other any file, |
|
Re: Formstyle select: fsStayOnTop. Why click other any file, |
|
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)
|