TFrame
C++Builder でa をスケーリングするための正しい手順は何ですか?
PixelsPerInch=120 (別名、Windows フォント サイズ 125%) で開発していますが、フォームを PixelsPerInch=96 (別名、デフォルト) でも動作させたいと考えています。
私のメイン フォームは正常に読み込まれます。作成する VCL コードにTForm
は、デザイン PPI がランタイム PPI と異なるかどうかのチェックが含まれており、その時点ですべてが正しくスケーリングされます。
ただし、 をロードするTFrame
場合、自動スケーリングは行われません。私が発見した限りでは、手動で呼び出す必要がありますFrame1->ScaleBy(M, D);
。
これはほとんどの場合機能しますが、バグ (以下で説明します) があるため、正しくスケーリングされていないフレームが生成されます。
フレームを作成し、フォームのようにロード時にスケーリングする適切な方法は何ですか?
現在、次のものを使用しています。
// class member
TFrame *f;
// called just before Application->Run()
f = new TFrame(fMain);
int M = fMain->PixelsPerInch;
int D = 120; // Matt's development
if ( M != D )
{
f->ScaleBy(M, D);
}
フレームをアクティブにしたいときは、`f->Parent = fMain->Panel1; (*f)->ScaleBy(M, D);
Frame には などを使用するコントロールがあるという理論に基づいて、 をf->Parent = fMain->Panel1;
呼び出す前にも書いてみました。ただし、これにより他のバグが発生します。 ScaleBy
ParentFont
バグは、 と を含む を含むフレームまたはフォームを呼び出すと、ラベルがウィンドウScaleBy
の本来よりもはるかに高い位置に表示されることです (ウィンドウの上部から離れている可能性もあります)。TLabel
AutoSize=true
ParentFont=false
Anchors
akBottom
私は問題を突き止めました:TControl.ChangeScale
関数には への呼び出しが含まれてScaleMargins
おり、Margin プロパティにAlignControls
は親フォームを呼び出すオンセット トリガーがあり、 でコントロールを移動しますAutoSize=true
。
をステップ実行するVcl.Controls.pas
と、最初はラベルが正しくスケーリングされることがわかりますが、次のコントロール (たまたまラジオ グループ) が処理されると、AlignControls
がトリガーされ、ラベルの が変更されますTop
。
このAlignControls
関数はTLabel
、再スケーリング操作の途中で呼び出されたときに、先ほど説明したパラメーターで を処理できないようです。
理由をしっかりと突き止めていませんが、親のフォームまたはフレームがまだスケーリングされていないためだと思います(ScaleControls
関数は自己をスケーリングする前にすべての子をスケーリングします)ので、フォームの古いものを使用して実際の結果Height
を計算しますTop
下へのアライメントを行うことから。
csLoading
スケーリング コードがコンポーネントの状態をチェックし、 への呼び出しを含む多くの反応効果を無効にするため、この効果は Form を初めてロードするときにトリガーされませんAlignControls
。
の場合にのみバグがトリガーされる理由がわかりませんParentFont=false
。
私の現在の回避策は、問題のラベルを別のラベルに手動で再配置する行を FormResize ハンドラーに含めることですParentFont=true
(したがって、バグの影響を受けません)。