AnchorDocking — мощная библиотека для создания интерфейсов с докируемыми окнами в Lazarus и Delphi. Однако, как показывает практика, при работе с ней могут возникать неожиданные проблемы. В этой статье мы разберём распространённую ошибку, когда после закрытия последнего докированного окна система докинга перестаёт работать, и предложим несколько способов её решения.
Описание проблемы
Как отмечают пользователи на форумах (включая pebe и andrew_arprix), при использовании AnchorDocking возникает следующая ситуация:
Пользователь создаёт докируемые окна динамически во время работы программы
После закрытия последнего докированного окна (особенно через кнопку закрытия) система докинга перестаёт работать
Попытки заново закрепить новые окна не дают результата — DockMaster как бы "исчезает"
// Типичный код, который может вызывать проблему
procedure TMainForm.CreateDockableForm;
var
VForm: TForm;
begin
VForm := TForm.Create(Self);
DockMaster.MakeDockable(VForm, True, True); // Создаём докируемую форму
end;
Причины проблемы
Основная причина кроется в том, что при закрытии последнего докированного окна система AnchorDocking теряет "точку опоры" — контейнер, к которому можно пристыковывать новые окна. Это происходит потому, что:
При закрытии последнего окна закрывается и его хост-контейнер (TAnchorDockHostSite)
DockMaster не восстанавливает автоматически основной контейнер для докинга
Последующие попытки докинга не имеют целевого контейнера
Решения проблемы
1. Использование AnchorDockPanel (рекомендуемое решение)
Как отметил zamtmn, использование AnchorDockPanel решает проблему. Вот как это реализовать:
procedure TMainForm.FormCreate(Sender: TObject);
begin
// Создаём панель для докинга
AnchorDockPanel1 := TAnchorDockPanel.Create(Self);
AnchorDockPanel1.Parent := Self;
AnchorDockPanel1.Align := alClient;
// Настраиваем DockMaster
DockMaster.MakeDockPanel(AnchorDockPanel1, admrpChild);
end;
procedure TMainForm.CreateDockableForm;
var
VForm: TForm;
begin
VForm := TForm.Create(Self);
DockMaster.MakeDockable(VForm, False); // Не создаём плавающее окно автоматически
VForm.Show;
end;
andrew_arprix предложил модификацию исходного кода AnchorDocking:
procedure TAnchorDockHeader.CloseButtonClick(Sender: TObject);
var
HeaderParent: TAnchorDockHostSite;
begin
TWinControl(HeaderParent) := Parent;
if HeaderParent = TWinControl(DockMaster.FOverlappingForm) then
begin
HeaderParent := DockMaster.FOverlappingForm.AnchorDockHostSite;
HeaderParent.HideMinimizedControl;
end;
if HeaderParent is TAnchorDockHostSite then
begin
DockMaster.RestoreLayouts.Add(DockMaster.CreateRestoreLayout(HeaderParent), True);
HeaderParent.Undock(); // Критичное добавление
HeaderParent.CloseSite;
end;
end;
Это изменение гарантирует правильное освобождение ресурсов при закрытии окна.
3. Восстановление DockMaster при закрытии последнего окна
Если вы не хотите модифицировать исходный код, можно обрабатывать закрытие окон вручную:
procedure TMainForm.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
if DockMaster.AnchorDockHostSiteCount = 1 then // Если это последнее окно
begin
CloseAction := caNone;
// Восстанавливаем главную форму как докируемую
DockMaster.MakeDockable(MainForm);
// Теперь можно закрыть форму
CloseAction := caFree;
end;
end;
Практические рекомендации
Всегда используйте AnchorDockPanel как базовый контейнер для докинга
Избегайте закрытия всех докируемых окон — оставляйте хотя бы одно
Обрабатывайте событие OnClose для докируемых форм
Рассмотрите возможность использования TAnchorDockSplitter для более гибкого управления
Проблема с исчезновением функциональности докинга после закрытия последнего окна — известный недостаток AnchorDocking. Однако, как мы показали, существует несколько рабочих способов её решения. Наиболее стабильным вариантом является использование TAnchorDockPanel в качестве постоянного контейнера.
Если вы столкнулись с этой проблемой в своём проекте, попробуйте предложенные решения и выберите то, которое лучше всего подходит для вашего случая. Помните, что AnchorDocking — мощный инструмент, но требующий внимательного подхода к настройке и использованию.
Контекст описывает проблему сбоя системы докинга AnchorDocking в Lazarus при закрытии последнего окна и предлагает три способа её решения: использование AnchorDockPanel, модификацию исходного кода библиотеки и ручное восстановление функциональности DockM
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS