При создании компонентов в Delphi разработчики часто сталкиваются с проблемой, когда размеры компонента (ширина и высота) не соответствуют ожиданиям при размещении на форме. Это особенно заметно при работе с высокоточными графическими элементами, такими как BGRABitmap, где каждый пиксель важен. Проблема усугубляется при использовании мониторов с высоким разрешением (4K) и масштабированием Windows (например, 150%).
Причина
Основная причина — автоматическое масштабирование, применяемое LCL (Lazarus Component Library). Метод GetControlClassDefaultSize возвращает базовые размеры, но они могут быть изменены в зависимости от настроек масштабирования системы. Например, если установлен масштаб 150%, компонент будет увеличен на 50% от исходного размера.
Решение 1: Отключение масштабирования
Для компонентов, где точные пиксельные размеры критичны, можно полностью отключить масштабирование. Для этого переопределите метод SetInitialBounds и игнорируйте системные настройки:
procedure TMyFixedSizeControl.SetInitialBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
// Игнорируем системные настройки, используем фиксированные размеры
inherited SetInitialBounds(ALeft, 100, 100, 100);
end;
Решение 2: Использование CalculatePreferredSize
Для более гибкого управления размерами переопределите метод CalculatePreferredSize:
procedure TMyFixedSizeControl.CalculatePreferredSize(var PreferredWidth, PreferredHeight: Integer);
begin
PreferredWidth := 100; // Фиксированная ширина
PreferredHeight := 100; // Фиксированная высота
end;
Решение 3: Отключение масштабирования для всей формы
Если компонент используется в контексте формы, где масштабирование не требуется, отключите его для формы:
Если требуется поддержка разных DPI, но с контролем над размерами, используйте текущий DPI для расчета:
function GetRealPixels(Value: Integer): Integer;
begin
Result := MulDiv(Value, Screen.PixelsPerInch, 96);
end;
procedure TMyControl.Create;
begin
inherited;
Width := GetRealPixels(100);
Height := GetRealPixels(100);
end;
Заключение
Выбор подхода зависит от требований к компоненту:
- Фиксированные размеры: Отключите масштабирование полностью.
- Гибкие размеры: Используйте CalculatePreferredSize или ручной расчет с учетом DPI.
- Графические компоненты: Убедитесь, что все элементы (шрифты, границы) масштабируются согласованно.
Для сложных графических компонентов (например, на базе BGRABitmap) рекомендуется тестирование на разных настройках DPI и масштабирования Windows.
Контекст описывает методы фиксации размеров компонентов в Delphi для предотвращения нежелательного масштабирования при изменении системных настроек DPI.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.