「FireMonkey で poOwnerFormCenter – MASA Lab softlab」で、「Delphi XE5ではFireMonkey on WindowsではpoOwnerFormCenterが効かない」とありました。
Delphi XE7で試してみたらところ、上の記事と同じようにオーナーフォームの中央ではなく画面中央にフォームが表示されます。
var
Form: TForm1;
begin
Form := TForm1.Create(Self);
Form.Position := TFormPosition.OwnerFormCenter;
Form.ShowModal;
Form.Free;
end;
ソースコードを追いかけてみたところ、FMX.Formsユニットの2843行目以降の部分で、
LPosition := FPosition;
// update position
case LPosition of
…
TFormPosition.OwnerFormCenter:
if not(Assigned(ParentForm)) then
LPosition := TFormPosition.ScreenCenter;
となっていて、ParentFormがnilのためScreenCenterに変更されていました。
元記事の「なぜか ParentForm がアサインされていない場合は poScreenCenter に変えられてしまっている」というのは、このことを指摘していると思います。
試しにRTTIでFParentFormを設定してみます。
/// <summary>
/// AFormのFParentForm変数にParentFormを設定する
/// </summary>
procedure SetParentForm(AForm, ParentForm: TCommonCustomForm);
var
RttiType: TRttiType;
RttiField: TRttiField;
begin
RttiType := SharedContext.GetType(AForm.ClassType);
RttiField := RttiType.GetField('FParentForm');
RttiField.SetValue(AForm, ParentForm);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Form: TForm1;
begin
Form := TForm1.Create(Self);
Form.Position := TFormPosition.OwnerFormCenter;
SetParentForm(Form, Self); //ParentFormを設定する
Form.ShowModal;
Form.Free;
end;
オーナーフォームの中央に配置されるようになりました。
やはりParentForm変数が設定されていないことが原因のようです。
とりあえず、今回はここまで。