私は非常に奇妙なことに気づきました。フォームを閉じるときに上、左、幅、高さのプロパティを保持し、この情報を使用して、以前に保存された情報を使用して SetBounds を呼び出すことにより、フォームが再び開かれたときにフォームの最後の位置を復元します。これはうまく機能しますが、フォームの Position プロパティが設計時に poDefault に設定されている場合に限られます。poDesigned、poScreenCenter、poMainFormCenter などの別の値に設定した場合、SetBounds はフォームの以前の位置とサイズを復元しません。
ここが奇妙な部分です。問題のように見えるのは、設計時に Position プロパティが何に設定されているかです。実行時にこのプロパティの値を poDefault に変更できますが、SetBounds の呼び出しはまだ正しく機能しません。私は次のようなものを試しました
if Self.Position <> poDefault then
Self.Position := poDefault;
フォームの OnCreate イベント ハンドラーとオーバーライドされたコンストラクターの両方で (コンストラクターで Position を poDefault に設定し、OnCreate イベント ハンドラーで SetBounds を呼び出しました)。いずれの場合も、実行時にフォームの Position プロパティを poDefault に変更しても、SetBounds で確認した問題は修正されません。私が見つけた唯一の一貫したパターンは、フォームの Position プロパティが設計時に poDefault であった場合にのみ SetBounds が機能することです。
設計時にフォームの Position プロパティが poDefault に設定されていない場合に SetBounds がどのように機能するかに関して、私が気付いたことが他にもあります。たとえば、設計時に Position プロパティが poScreenCenter に設定されているフォームは、SetBounds を呼び出した場合、画面の中央に表示されるとは限りません。ただし、SetBounds で定義された左上の位置には表示されず、SetBounds の呼び出しで指定された幅と高さも考慮されません。ただし、SetBounds を呼び出す前に、フォームの Position プロパティを poDefault に設定していることを繰り返しましょう。2 つの操作の間に Application.ProcessMessages への呼び出しをスタックしましたが、それでも問題は解決しません。
Windows 10 で実行されている Delphi 10.1 Berlin でこれを広範囲にテストしました。また、Windows 7 で Delphi XE6 を使用してテストしました。同じ結果です。
疑問がある場合は、4 つのフォームを含む VCL アプリケーションを作成してください。最初のフォームに 3 つのボタンを配置し、各ボタンに次の OnClick のようなものを追加します。
with TForm2.Create(nil) do
try
ShowModal;
finally
Release;
end;
ここで、コンストラクターは TForm2 を作成し、次に TForm3 と TForm4 を作成します。
フォーム 2 ~ 4 の OnCreate で、次のコードを追加します。
if Self.Position <> poDefault then
Self.Position := poDefault;
Self.SetBounds(500,500,500,500);
form2 では Position を poDefault に設定し、form3 では Position を poScreenCenter に設定し、form4 では Position をデフォルトの poDefaultPosOnly に設定したままにします。form2 のみが 500, 500 に表示され、幅は 500、高さは 500 です。
誰かがこの結果の論理的な説明を持っていますか?