How can my Delphi 10.4.2 project detect that it is going into the background?
I've tried using TMainWindow.FormDeactivate() but this leaves the floating tool window staying on top of all other application windows as the project goes into the background.
To solve that I've also tried...
procedure TMainWindow.FormDeactivate(Sender: TObject);
begin
FloatingToolWindow.FormStyle := TFormStyle.Normal;
end;
...but this does not always work. For example, if the floating tool window has the focus (rather than the main window), then the main window's FormDeactivate() does not get called when the user clicks in another application - which leaves the tool window floating over all other application windows.
Here is a project that duplicates the problem. Run the project in Windows or in MacOS, click the button to show the tool window, click in the tool window (to give it focus), and finally click some other application's window to put this project in the background. The tool window continues to stay on top and the main window's FormDeactivate() is not called.
unit MainForm;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.Controls.Presentation, FMX.StdCtrls;
type
TMainWindow = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormDeactivate(Sender: TObject);
procedure FormActivate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
MainWindow: TMainWindow;
implementation
{$R *.fmx}
uses FloatingForm;
procedure TMainWindow.Button1Click(Sender: TObject);
begin
FloatingToolWindow.Show;
end;
procedure TMainWindow.FormActivate(Sender: TObject);
begin
FloatingToolWindow.FormStyle := TFormStyle.StayOnTop;
end;
procedure TMainWindow.FormDeactivate(Sender: TObject);
begin
FloatingToolWindow.FormStyle := TFormStyle.Normal;
end;
end.
The main form's DFM:
object MainWindow: TMainWindow
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 480
ClientWidth = 640
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
OnActivate = FormActivate
OnDeactivate = FormDeactivate
DesignerMasterStyle = 0
object Button1: TButton
Position.X = 280.000000000000000000
Position.Y = 232.000000000000000000
Size.Width = 137.000000000000000000
Size.Height = 22.000000000000000000
Size.PlatformDefault = False
TabOrder = 0
Text = 'Show Floater'
OnClick = Button1Click
end
end
The settings for the floating form:
object FloatingToolWindow: TFloatingToolWindow
Left = 0
Top = 0
BorderIcons = []
BorderStyle = ToolWindow
Caption = 'Form2'
ClientHeight = 316
ClientWidth = 491
FormStyle = StayOnTop
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
DesignerMasterStyle = 0
object Text1: TText
Position.X = 80.000000000000000000
Position.Y = 88.000000000000000000
Size.Width = 297.000000000000000000
Size.Height = 113.000000000000000000
Size.PlatformDefault = False
Text =
'Click on this tool window (to give it focus) and then click on a' +
'ny OTHER application'#39's window to send this project into the back' +
'ground. This window will continue to stay on top of the other ap' +
'plications.'
end
end
Source for the tool window:
unit FloatingForm;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.Controls.Presentation, FMX.StdCtrls, FMX.Objects;
type
TFloatingToolWindow = class(TForm)
Text1: TText;
private
{ Private declarations }
public
{ Public declarations }
end;
var
FloatingToolWindow: TFloatingToolWindow;
implementation
{$R *.fmx}
end.