はすべてを壊す機能がUpdateAnchorRules
であることが判明しました。 TControl
はFOriginalParentSize
を格納しており、それ自体の元のサイズはFAnchorRules
で、それを使用して親サイズとして自動サイズ変更されます。 UpdateAnchorRules()
は現在の親サイズと現在のコントロールWidth
とHeight
をとり、それらをFOriginalParentSize
とFAnchorRules
に保存します。
通常のサイズ変更時に効果がないすべてが正常に動作していれば、コントロールと親のサイズが一致します。
しかし、コントロールWidth
が固定のためにゼロよりも小さい場合、Windowsは、したがって、Delphiはまだそれを0
とみなします。その時点でUpdateAnchorRules
が呼び出された場合は、元の幅の値である0
の間違った値を保存します。この後、レイアウトは修理の余地がありません。
(それが呼び出されていない場合は、Width
が原因保存元のサイズに親Width
への適切な関係で更新され続けて)
は、ウィンドウハンドルを作成する必要が何かが二回UpdateAnchorRules
を呼び出し判明:それとしてWinAPIのCreateWindow
の最初の返される前にWM_SIZE
を送出します(ハンドラはハンドラが呼び出され、UpdateAnchorRules
が呼び出されます)。また、ハンドルの作成後にはCreateHandle
に明示的に送出されます。
CreateHandle
の間、UpdateAnchorRules
を無効にできる限り、私たちは成功すると思われます。しかし、UpdateAnchorRules
への明示的な呼び出しがCreateHandle
にあります。これは、ハンドルの作成後にアンカールールを調整するためにが必要であると考えていることを意味します。
おそらく私は何かが不足しているため、無効にすると何かが壊れますか?
いずれにしても、UpdateAnchorRules
を無効にする2つの方法があります。FAnchorMove
を設定するか、csLoading
に設定します。まず、RecreateWnd
の途中でクリアしてからUpdateAnchorRules
を再度呼び出すコードがあるため、最初は正しくありません。
2つ目の作品と、ここソリューションです:
type
TComponentHack = class helper for TComponent
public
procedure SetCsLoading(Value: boolean);
end;
procedure TComponentHack.SetCsLoading(Value: boolean);
var i: integer;
begin
if Value then
Self.FComponentState := Self.FComponentState + [csLoading]
else
Self.FComponentState := Self.FComponentState - [csLoading];
for i := 0 to Self.ComponentCount-1 do
if Self.Components[i] is TControl then
TControl(Self.Components[i]).SetCsLoading(Value);
end;
procedure SafeRecreateWnd();
begin
MyControl.SetCsLoading(true);
try
MyControl.RecreateWnd(); //or any operation which triggers it -- such as docking or making the window visible first time after RecreateWnd()
finally
MyControl.SetCsLoading(false);
end;
end;
免責事項:
私はcsLoadingセットでTControl
操作を実行することによって破壊される他に何見当がつかない。
より良い代替手段がUpdateAnchorRules
プロシージャをフックし、特にこの目的のために別のフラグチェックを追加することですが、それは(別の元UpdateAnchorRules
でのDelphiの異なるバージョンに破壊しやすい)完全UpdateAnchorRules
を再実装するかにいくつかの方法を発明のいずれかが必要ですと思います元のUpdateAnchorRules
を呼び出します。これは通常、フックで書き直すことで破壊されます。
"使えない"とは少し上にあると思います。フォームのハンドルが決して再作成されない多くのユースケース。 –
私はそうは思わない。たとえあなたが一度もやっていないような気がしても、一ヶ月後にあなたが作り直すようなことをすると、知らないうちにバグが発生しました。アンカーは予測できません。 – himself
ええええええええええええええ、確かに、彼らはあまりにも使用されている理由です...アンカーはかなり機能し、私と他の多くの年のためにそうしてきました。明らかにあなたの走行距離は異なりますが、それらを使用することができないことは、他の人のために使用することを不可能にしません。 –