Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Как настроить выравнивание дочерней формы рядом с основной в Delphi с использованием DwmApi

Delphi , Синтаксис , Справочник по API-функциям

Как настроить выравнивание дочерней формы рядом с основной в Delphi с использованием DwmApi

Вопрос, с которым сталкиваются разработчики, работающие с VCL-приложениями в Delphi, заключается в необходимости выравнивания дочерних форм рядом с основной. Это может быть связано с различными проблемами, в том числе из-за рамок и теней, добавляемых системой Windows. В данной статье мы рассмотрим, как решить эту проблему, используя API DwmApi.

Описание проблемы

При попытке выровнять дочернюю форму по отношению к основной "бок о бок" могут возникать трудности, связанные с неправильным позиционированием из-за рамок и теней окон. Это особенно заметно на системах Windows 7 и Windows 10, где использование прозрачности и анимаций окон (DwmCompositionEnabled) вносит свои коррективы.

Пример кода с проблемой

Для воспроизведения проблемы создается новое VCL-приложение с одной кнопкой на форме. При нажатии на кнопку создается новая форма, которая должна отображаться рядом с основной. Однако, из-за особенностей работы DwmApi, форма может отображаться некорректно.

procedure TForm1.Button1Click(Sender: TObject);
var
  Form: TForm1;
begin
  Application.CreateForm(TForm1, Form);
  Form.BorderStyle := bsSingle;
  Form.Left := Left + Width;
  Form.Top := Top;
  Form.Show;
end;

Решение проблемы с использованием DwmApi

Использование DwmApi позволяет получить информацию о размерах и границах окон, включая рамки и тени. Это необходимо для корректного позиционирования дочерних форм. Пример кода, который решает проблему:

DXR1 := 0;
DXL2 := 0;
if (Win32MajorVersion >= 6) and DwmCompositionEnabled then begin
  DwmGetWindowAttribute(Handle, DWMWA_EXTENDED_FRAME_BOUNDS, @R1, SizeOf(R1));
  Winapi.Windows.GetWindowRect(Handle, R2);
  DXR1 := R2.Right - R1.Right;
  DYT1 := R2.Top - R1.Top;
end;
FormJob.Left := Left + Width - DXR1;
FormJob.Top := Top - DYT1;
FormJob.Show;
if (Win32MajorVersion >= 6) and DwmCompositionEnabled then begin
  DwmGetWindowAttribute(FormJob.Handle, DWMWA_EXTENDED_FRAME_BOUNDS, @R1, SizeOf(R1));
  Winapi.Windows.GetWindowRect(FormJob.Handle, R2);
  DXL2 := R1.Left - R2.Left;
  DYT2 := R2.Top - R1.Top;
end;
FormJob.Left := FormJob.Left - DXL2;
FormJob.Top := FormJob.Top + DYT2;

Подтвержденное решение с использованием DWMWA_CLOAK

Для корректного выравнивания дочерней формы необходимо сначала показать форму, а затем использовать DWMWA_CLOAK для получения корректных значений рамок и теней.

var
  R1, R2: TRect;
  DXR1, DXL2, DYT1, DYT2: Integer;
  bCloak: BOOL;
begin
  Application.CreateForm(TFormJob, FormJob);
  if (Win32MajorVersion >= 6) and DwmCompositionEnabled then begin
    // ... (инициализация переменных)
    bCloak := True;
    DwmSetWindowAttribute(FormJob.Handle, DWMWA_CLOAK, @bCloak, SizeOf(bCloak));
    FormJob.Show;
    // ... (получение размеров и границ)
    FormJob.Left := Left + Width - DXR1 - DXL2;
    FormJob.Top := Top - DYT1 + DYT2;
    bCloak := False;
    DwmSetWindowAttribute(FormJob.Handle, DWMWA_CLOAK, @bCloak, SizeOf(bCloak));
  end
  else begin
    // ... (позиционирование без использования DwmApi)
  end;
end;

Альтернативный ответ и дополнительные замечания

В некоторых случаях, если дочерняя форма не выравнивается корректно, стоит проверить следующие моменты:

  • Убедитесь, что темы оформления (themes) включены в системе.
  • Проверьте, что вы используете bsSingle для BorderStyle дочерней формы.
  • Убедитесь, что код для воспроизведения проблемы запускается в новом проекте.

Заключение

В данной статье мы рассмотрели, как с помощью DwmApi настроить выравнивание дочерней формы рядом с основной в Delphi. Использование DWMWA_CLOAK позволяет получить необходимые размеры и границы формы после ее показа, что обеспечивает корректное позиционирование. Следуя приведенным шагам, разработчики смогут избежать распространенных ошибок при работе с VCL-формами и добиться желаемого результата.

Создано по материалам из источника по ссылке.

Вопрос связан с настройкой выравнивания дочерних форм в Delphi с использованием DwmApi для корректного размещения их рядом с основной формой, учитывая рамки и тени окон.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Справочник по API-функциям ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2024-12-26 14:01:54/0.0034079551696777/0