1

TFrameC++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;呼び出す前にも書いてみました。ただし、これにより他のバグが発生します。 ScaleByParentFont


バグは、 と を含む を含むフレームまたはフォームを呼び出すと、ラベルがウィンドウScaleByの本来よりもはるかに高い位置に表示されることです (ウィンドウの上部から離れている可能性もあります)。TLabelAutoSize=trueParentFont=falseAnchorsakBottom

私は問題を突き止めました: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(したがって、バグの影響を受けません)。

4

0 に答える 0