I noticed something very strange. I save the properties of the top, left, width and height of the form when it is closed and using this information to restore the last position of the form when it opens again, calling SetBounds using the previously saved information. This works well, but only if the Position form property is set to poDefault at design time. If something else is set, such as poDesigned, poScreenCenter or poMainFormCenter, SetBounds does not restore the previous position and size of the form.
Here is the weird part. Which, apparently, matters when the Position property is set at design time. I can change the value of this property at runtime to poDefault, and calling SetBounds is still not working correctly. I tried something like the following
if Self.Position <> poDefault then Self.Position := poDefault;
both in the OnCreate event handler and from the overridden constructor (and set Position to poDefault in the constructor and called SetBounds in the OnCreate event handler). In all cases, changing the Position property to poDefault at runtime does not fix the problem that I observed with SetBounds. The only consistent model I found is that SetBounds works as it should, only if the Position property was poDefault at design time.
There are other things that I noticed regarding how SetBounds works when the Position property of the form is not set to poDefault at design time. For example, a form whose Position property is set to poScreenCenter at design time will not necessarily be centered on the screen if you call SetBounds. However, it does not appear in the upper left location specified by SetBounds, and does not take into account the width and height specified in the SetBounds call. Let me repeat, however, that I set the Position property of the form to poDefault before calling SetBounds. I even ran an Application.ProcessMessages call between two operations, but this does not fix the problem.
I tested this with Delphi 10.1 Berlin running on Windows 10. I also tested it with Delphi XE6 on Windows 7. Same results.
If in doubt, create a VCL application with four forms. On the first form, place the three buttons and add something like the following OnClick to each button:
with TForm2.Create(nil) do try ShowModal; finally Release; end;
where the constructor creates TForm2, then TForm3 and TForm4.
In OnCreate Forms 2 through 4, add the following code:
if Self.Position <> poDefault then Self.Position := poDefault; Self.SetBounds(500,500,500,500);
In form2, set Position to poDefault, in form3 set Position to poScreenCenter and in form4 leave the default position, poDefaultPosOnly. Only form2 will appear at 500, 500, with a width of 500 and a height of 500.
Does anyone have a logical explanation for this result?