I built the code below using Delphi XE2. It creates Form1, and Form1 immediately creates an instance of Form2. When I press the button on Form2 a second Form2 is created.
Now if I hover the mouse over the button on this second, topmost, Form2 and wait for the tooltip to appear, the moment the tooltip appears, the first Form2 comes to the front, stealing focus.
The problem occurs only if Application.MainFormOnTaskbar
is True
. It also relies on the first Form2 being created from Form1's FormCreate
method. If I use PostMessage()
to delay the creation of the first Form2 until the application has finished initialising, the problem goes away.
I'd like to understand why this is happening. I have already learned that Delphi's Application object handles a lot of things including hint display, and I know that Delphi can recreate a window's handle during initialisation, but I haven't been able to follow this through to explain fully the behaviour described above (or indeed whether the above two facts are even relevant).
Project1.dpr
program Project1;
uses
Vcl.Forms,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True; // False makes problem go away
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Unit1.pas
unit Unit1;
interface
uses
Vcl.Forms, Unit2;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
public
procedure CreateForm2;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
CreateForm2;
end;
procedure TForm1.CreateForm2;
var
frm : TForm2;
begin
frm := TForm2.Create(Application); // (Could pass Self - makes no difference)
frm.Show;
end;
end.
Unit2.pas
unit Unit2;
interface
uses
Vcl.Forms, System.Classes, Vcl.Controls, Vcl.StdCtrls, WinApi.Windows;
type
TForm2 = class(TForm)
Button1: TButton; // This button has a hint
procedure Button1Click(Sender: TObject);
end;
var
Form2: TForm2;
implementation
uses
System.SysUtils, Unit1;
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
begin
Form1.CreateForm2;
end;
end.