При разработке на Delphi, иногда возникают ситуации, когда стандартные компоненты ведут себя не так, как ожидается. Одной из таких проблем является некорректное автоматическое изменение размера TPanel, содержащего TWebBrowser, в среде Delphi XE6.
Описание проблемы
Разработчик столкнулся с регрессией при использовании TPanel с автодimensioning в версиях от Delphi 5 до XE6. В частности, он обнаружил, что если в TPanel добавить другие компоненты, такие как TListView, то TPanel корректно изменяет свой размер под содержимое. Однако, если в качестве содержимого используется TWebBrowser или его аналоги, например TEmbeddedWB, то TPanel не изменяет свой размер автоматически.
Анализ проблемы
Предполагается, что проблема кроется в некорректной реализации внутреннего механизма автодimensioning для TWebBrowser. Это предположение основано на том, что с другими компонентами автодimensioning работает корректно, а значит проблема может быть в специфике реализации TWebBrowser или связанных с ним компонентов.
Альтернативный ответ
Пользователь user1611655 предложил обходное решение: поместить TPanel под TWebBrowser и выровнять TWebBrowser по клиенту, используя свойство Align с значением alClient. Однако, разработчик был заинтересован в поиске и устранении первопричины проблемы, а не в использовании обходных путей.
Подтвержденный ответ
Исследование показало, что проблема связана с двумя регрессиями в Delphi XE6:
Некорректное поведение функции AlignControls в TWinControl, которая не вызывает необходимый метод для корректировки размеров, если соответствующие флаги не установлены.
Изменения в методе SetBounds для TOleControl, которые приводят к неправильной обработке сообщений о изменении размеров окна.
Решения
Для первого регресса необходимо изменить метод AlignControls так, чтобы он всегда вызывал метод DoAdjustSize, вне зависимости от установленных флагов:
procedure TWinControl.AlignControls(AControl: TControl; var Rect: TRect);
begin
// ... (другие операции)
// QC125995: вызов DoAdjustSize вне зависимости от флагов
if Showing then
DoAdjustSize;
// ... (другие операции)
end;
Для второго регресса необходимо, чтобы обработчик сообщения WMWindowPosChanged также вызывал метод RequestAlign, который отвечает за корректировку размера родительского компонента:
procedure TWinControl.WMWindowPosChanged;
begin
UpdateBounds;
RequestAlign; // Вызов метода для корректировки размера родителя
end;
Или изменить метод UpdateBounds для вызова RequestAlign:
procedure TWinControl.UpdateBounds;
begin
UpdateAnchorRules;
RequestAlign; // Вызов метода для корректировки размера в ответ на сообщение WM_WindowPosChanged
end;
Для практического решения разработчик выбрал вариант, который позволяет использовать преимущества корректной обработки изменения размеров в методе SetBounds, перенеся вызов SetObjectRects на после вызова этого метода. Таким образом, обработчик WMWindowPosChanged не будет выполнять никаких действий, которые могли бы привести к ошибкам:
procedure TOleControl.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
// ... (другие операции)
inherited SetBounds(ALeft, ATop, AWidth, AHeight);
// Вызов SetObjectRects после SetBounds
if FOleInplaceObject <> nil then
begin
LRect := Rect(Left, Top, Left+AWidth, Top+AHeight);
FOleInplaceObject.SetObjectRects(LRect, LRect);
end;
end;
Заключение
Проблема с автоматической корректировкой размера TPanel с TWebBrowser в Delphi XE6 вызвана регрессиями в работе компонентов. Приведенные выше решения позволяют устранить эти проблемы, обеспечив корректное поведение компонентов в рамках автоматического размера.
Разработчик столкнулся с проблемой некорректного автоматического изменения размера `TPanel`, содержащего `TWebBrowser`, в среде Delphi XE6, что является регрессией по сравнению с предыдущими версиями Delphi.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.