Масштабирование TFrame
Какова правильная процедура для масштабирования TFrame
в C++Builder?
Я занимаюсь разработкой в 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);
Я тоже пробовал писать f->Parent = fMain->Panel1;
перед звонком ScaleBy
, основанный на теории, что Frame имеет элементы управления, использующие ParentFont
и так далее, поэтому может быть лучше, если эта информация будет доступна во время масштабирования; Однако это приводит к другим ошибкам.
Баг в том что при звонке ScaleBy
на раме или форме, которая имеет TLabel
у которого есть AutoSize=true
а также ParentFont=false
а также Anchors
в том числе akBottom
, затем метка отображается гораздо выше в окне, чем она должна быть (может быть, даже в верхней части окна).
Я выследил проблему: TControl.ChangeScale
функция включает в себя вызов ScaleMargins
, а свойство Margin имеет установленный триггер, который в конечном итоге вызывает AlignControls
для родительской формы, которая будет перемещать любые элементы управления с AutoSize=true
,
Шагая через Vcl.Controls.pas
, Я вижу, что мой Label сначала корректно масштабируется, однако, когда обрабатывается следующий элемент управления (радиогруппа) AlignControls
срабатывает, что меняет мой лейбл Top
,
AlignControls
функция, очевидно, не может справиться с TLabel
с параметрами, которые я только что описал, когда вызывается частично через операцию масштабирования.
Я не определил, почему, но я думаю, что это потому, что родительская форма или фрейм еще не были масштабированы (ScaleControls
функция масштабирует всех детей до масштабирования себя), поэтому она использует старую форму Height
рассчитать фактическую Top
это происходит в результате выравнивания по дну.
Этот эффект не срабатывает при первой загрузке формы, потому что код масштабирования проверяет csLoading
компонент состояния и отключает целый ряд реакционных эффектов, в том числе вызов AlignControls
,
Я не понял, почему ошибка возникает только тогда, когда ParentFont=false
,
Мой текущий обходной путь - включить в обработчик FormResize строку, которая вручную перераспределяет соответствующие метки с другой меткой, которая имеет ParentFont=true
(и, следовательно, не страдает от ошибки).