The key issue here is that the first instance of TForm2
is created as window that is owned by the application window, Application.Handle
. And here I am referring to the Windows meaning of owner. In VCL language this is known as the popup parent.
Now, when you create that first TForm2
instance, the Application.MainForm
property is still nil
. And because you did not explicitly assign PopupParent
, the code in TCustomForm.CreateParams
sets the owner to be the application window.
You simply do not want your windows to be owned by the hidden application window. This is the reason why that first TForm2
instance sometimes appears behind all the other windows, in particular behind your main form. It has simply been created with the wrong owner.
The form that is owned by Application.Handle
gets shown in THintWindow.ActivateHint
. That happens due to the line that reads ParentWindow := Application.Handle
. This is followed by a call to SetWindowPos(Handle, ...)
which results in the incorrectly owned form coming to the front. Presumably that form comes to the front because it is also owned by Application.Handle
. Right now I don't have a clear explanation for the precise mechanism, but I don't find that terribly interesting because the form is clearly setup wrongly.
In any case, the fundamental problem is that you have created a window that is incorrectly owned. The solution therefore is to make sure that the window is owned correctly. Do that by assigning the PopupParent
. For example:
procedure TForm1.CreateForm2;
var
frm : TForm2;
begin
frm := TForm2.Create(Application); // (Could pass Self - makes no difference)
frm.PopupParent := Self;
frm.Show;
end;