На самом деле, вопрос не такой очевидный, и не имеет однозначного решения. По хорошему вместе с размерами контролов необходимо менять еще и размер шрифта, иначе при переходе, на большие разрешения он становится мелким. Шрифт также имеет ограничения по уменьшению, после которого он становится не плохо читабельным. Потому как мне кажется, самое надежное привязываться именно к размеру шрифта. А то ведь представьте уменьшите вы размер контрола не изменив размер шрифта, тогда есть все шансы обрезать текст не поместившийся в этой строке. Возможна и другая ситуация, когда не специфические контролы не поддаются масштабированию или эта операция для них не желательна, например скролбары. Масштабирование формы имеет свои ограничения, так что желательно при проектировании изначально форма не занимала весь экран, т.е. чтобы она не обрезалась при меньших разрешениях.
Я делал так при создании формы заносил параметры всех контролов MemoryStream.
| Код | procedure TForm1.FormCreate(Sender: TObject); var a, i : Integer; d : TDevMode; p : pansichar; b : boolean; begin OrigSize := TMemoryStream.Create; OrigSize.Seek(0, soFromBeginning);
if ComponentCount <> 0 then for i := 0 to ComponentCount - 1 do Begin if (Components[i].ClassType = TButton) or (Components[i].ClassType = TRadioGroup) then Begin OrigSize.Write(TButton(Components[i]).Left, 4); OrigSize.Write(TButton(Components[i]).Top , 4); OrigSize.Write(TButton(Components[i]).Width , 4); OrigSize.Write(TButton(Components[i]).Height , 4);
end;
if (Components[i].ClassType = TComboBox) or (Components[i].ClassType = TSpinEdit) or (Components[i].ClassType = TCheckBox) or (Components[i].ClassType = TLabel) then Begin OrigSize.Write(TButton(Components[i]).Left, 4); OrigSize.Write(TButton(Components[i]).Top , 4); OrigSize.Write(TButton(Components[i]).Width , 4); end; end;
|
А после при изменении разрешения или если оно просто отличалось от исходного пересчитывал их каждый раз сначала шрифт, который уже не может меняться при разрешении меньше 800х600 и кроме того меняется очень грубо. А уже после этого пересчитывал масштабный параметр. Таким образом текст всегда будет одинаково помещаться на контролах при любом разрешении экрана.
| Код | if Screen.Height < 600 then Font.Height := -9 else Font.Height := -Round(11 * Screen.Height / 768);
Scale := Font.Height / -11;
CanResize := True; CheckBox1.Checked := False; Form1.Width := Round(252 * Scale) + 8; Form1.Height := Round(201 * Scale) + 34; Form1.Top := Round((Screen.Height - Form1.Height) / 2); Form1.Left := Round((Screen.Width - Form1.Width) / 2); CanResize := False;
OrigSize.Seek(0, soFromBeginning);
if ComponentCount <> 0 then for i := 0 to ComponentCount - 1 do Begin if (Components[i].ClassType = TButton) or (Components[i].ClassType = TRadioGroup) then Begin OrigSize.Read(temp, 4); TButton(Components[i]).Left := Round(temp * Scale);
OrigSize.Read(temp , 4); TButton(Components[i]).Top := Round(temp * Scale);
OrigSize.Read(temp , 4); TButton(Components[i]).Width := Round(temp * Scale); OrigSize.Read(temp , 4); TButton(Components[i]).Height := Round(temp * Scale); end;
if (Components[i].ClassType = TComboBox) or (Components[i].ClassType = TSpinEdit) or (Components[i].ClassType = TCheckBox) or (Components[i].ClassType = TLabel) then Begin OrigSize.Read(temp, 4); TButton(Components[i]).Left := Round(temp * Scale);
OrigSize.Read(temp , 4); TButton(Components[i]).Top := Round(temp * Scale);
OrigSize.Read(temp , 4); TButton(Components[i]).Width := Round(temp * Scale);
TButton(Components[i]).Font.Height := Font.Height; end; end;
|
Данный метод имеет тот недостаток, что не позволяет удалять компоненты. Это можно исправить если вносить в поток еще и их имена. Если контролы будут создаваться во время работы, то их прийдется предварительно туда же в поток прописывать или после создания или до создания. |