Have an amazing solution built in RAD Studio? Let us know. Looking for discounts? Visit our Special Offers page!
Новости

Странный случай с VCL Forms ClientWidth и флагами PE версий Windows

2022 vcl clientwidth winversion

Лишь немногие разработчики знают, что приложения Windows ведут себя по-разному в зависимости от версии Windows, объявленной в их PE-заголовках в EXE-файле. Это имеет некоторые неожиданные последствия, о которых сообщают клиенты Delphi, из-за изменения базовой конфигурации в Delphi 11, которое осталось незамеченным большинством.


Приложение Windows хранится в EXE-файле в формате PE, который включает ряд PE-флагов, определяющих поведение приложения во многих областях. Одним из таких флагов является версия Windows . За последний год отдел исследований и разработок Embarcadero стал свидетелем того, что некоторые API-интерфейсы Windows (в частности, связанные с неклиентской областью Windows, а также с высоким DPI) работали некорректно в последних версиях операционной системы.

Это было связано с тем, что приложения Delphi по умолчанию использовали довольно старые версии Windows с флагами PE, несмотря на то, что официальная поддержка таких версий, как Windows XP, была прекращена. По этой причине, чтобы решить некоторые проблемы с реальным API, в Delphi 11 Alexandria Embarcadero изменила флаги PE для версий Windows на 6.0.

Хотя это изменение полезно во многих областях, оно может привести к значительным изменениям в поведении существующих приложений VCL. Одним из видимых примеров является размер границы окна в случае стиля границы формы bsDialog. Стиль границы становится больше, и поэтому меняется разница между шириной формы и шириной ее клиента. То же самое по высоте.

В качестве практического примера я создал очень простое приложение VCL с кнопкой и двумя метками. Обратите внимание, что основная форма имеет этот параметр:


Это простой код единственной кнопки:

Теперь, если вы запустите это приложение с Delphi 11 (слева) или с Delphi 10.4 (справа), вы получите разные результаты:

2022_vcl_clientwidth_winversion-5032507

При общей форме 1000 я получаю 974 клиентских пикселя в Delphi 11 по сравнению с 994 в более старых версиях. Это потому, что граница толще. Положительной стороной является то, что строка заголовка имеет более широкий интервал, а заголовок окна не забит до границы (что было одной из ошибок, о которых сообщалось в старых версиях Delphi). Другими словами, окно слева, построенное в Delphi 11, выглядит лучше с точки зрения неклиентской области.

Кстати, обратите внимание, что по умолчанию ширина клиента формы «выигрывает» над шириной формы. Без строки для установки ширины в обоих случаях у вас будет одинаковая ширина клиента и разная ширина формы. Таким образом, позиционирование ваших компонентов (в случае абсолютных значений) не будет затронуто. Только вручную установив ширину, ширина клиента устанавливается на значение, отличное от прошлого.

Теперь, если по какой-либо причине вы хотите сохранить старое поведение — может быть, просто потому, что ваше существующее приложение работает именно так — вам не нужно откатываться до Delphi 10.4. Флаги PE могут контролироваться компилятором и компоновщиком. На самом деле я получил изображение справа (старая версия), используя Delphi 11 и добавив в основной файл проекта следующие две директивы компилятора:

С помощью этого кода вы можете отменить изменение Embarcadero по умолчанию, примененное к Delphi 11, и продолжать использовать старые флаги PE версии Windows и старое поведение, как для хорошего, так и для плохого. Твой выбор.

See What's New in 12.2 Athens See What's New in 12.2 Athens Dev Days of Summer 2-24

Reduce development time and get to market faster with RAD Studio, Delphi, or C++Builder.
Design. Code. Compile. Deploy.
Start Free Trial   Upgrade Today

   Free Delphi Community Edition   Free C++Builder Community Edition

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

IN THE ARTICLES