Перейти к содержанию
Fire Monkey от А до Я
  • 0

Вызов TPopup ломает поведение TWebBrowser


Вадим Смоленский

Вопрос

Этот вопрос сложился из двух, которые я здесь уже задавал, но ответов не получил. Первый касался странного поведения TWebBrowser. Второй - ненужного мелькания в виде белого квадрата при вызове TPopup и TPopupMenu. Теперь оказалось, что эти проблемы связаны. Мне удалось их воспроизвести в маленьком демонстрационном проекте (Windows), который прилагаю в виде зипа и скриншота.

TWebBrowserProblem.png.c4c8e1e28751c3a42c9aa3b986e34f83.png

Кнопка Hide/Show прячет и снова показывает TWebBrowser. Но если хоть один раз (когда TWebBrowser виден) вызвать TPopupMenu или TPopup, это перестает работать - TWebBrowser отказывается прятаться. Характерно еще то, что в момент вызова TPopupMenu или TPopup в левом верхнем углу формы на долю секунды появляется непрошенный белый квадрат, и на эту же долю секунды TWebBrowser пропадает.

Если минимизировать форму в трей и снова открыть (при условии, что TWebBrowser при этом как бы не виден, т.е. после нечетного числа щелчков по кнопке), то функциональность восстанавливается. Иными словами, проблема в отрисовке. Своими силами справиться не смог. Буду признателен за дельный совет. Побороть белый квадрат тоже очень хотелось бы, с ним некрасиво.

TWebBrowserProblem.zip

Ссылка на комментарий

Рекомендуемые сообщения

  • 0

хм. у меня описанная проблема не проявилась

Вин10 x64, Rad 10.2.1 Tokyo

Апд: а вот в Берлине действительно есть такая проблема

Изменено пользователем sinuke
Ссылка на комментарий
  • 0
11 час назад, Вадим Смоленский сказал:

У меня Win 7 x32, Rad 10.1 Berlin.

Исходный код TCustomWebBrowser.FormHandleCreated исправлен?

 

На всякий случай - привожу сам код исправления. Файл FMX.WebBrowser.pas необходимо скопировать из исходников студии себе в проект, положив его рядом с dpr.

И уже в нем сделать метод FormHandleCreated следующего вида (часть проверок 100% лишняя, но когда менял - подумал "пусть будет"):

procedure TCustomWebBrowser.FormHandleCreated(const Sender: TObject; const Msg: TMessage);
var
  WBService: IFMXWBService;
begin
  if not Assigned(Self) then
    Exit;
  if not Assigned(Self.Root) then
    Exit;
  if Sender <> Self.Root.GetObject then
    Exit;
  if not(csDesigning in ComponentState) and TPlatformServices.Current.SupportsPlatformService(IFMXWBService, WBService)
  then
    // if not Assigned(FWeb) then
    begin
      if FWeb <> nil then
        WBService.DestroyWebBrowser(FWeb);
      FWeb := nil; // possibly, this not needed...
      FWeb := WBService.CreateWebBrowser;
      FWeb.SetWebBrowserControl(Self);
      FWeb.UpdateContentFromControl;
      FWeb.URL := FURL;
      FWeb.Navigate;
    end;
end;

 

Изменено пользователем kami
Ссылка на комментарий
  • 0
7 минут назад, afors сказал:

Если интересно, то вот еще ссылка...

Код, который привел Равиль - не самый лучший (заточен на частный конкретный случай), не стоит его использовать.

Ссылка на комментарий
  • 0

Kami, огромное спасибо! Получается, белый квадрат как раз и возникал из-за TWebBrowser - вот почему у меня в первый раз не получилось воспроизвести проблему с квадратом на маленьком проекте. Теперь всё заработало. Низкий поклон!

Ссылка на комментарий
  • 0

Апну тему.
На этот раз - Tokio upd1, с патчем под iOS11.

Что требуется: скопировать в папку с проектом (рядом с dpr) файл FMX.WebBrowser.pas. В нем внести изменения в метод TCustomWebBrowser.FormHandleCreated, чтобы он выглядел следующим образом:
 

procedure TCustomWebBrowser.FormHandleCreated(const Sender: TObject; const Msg: TMessage);

  function GetParentForm(Control: TFmxObject): TCommonCustomForm;
  begin
    if (Control.Root <> nil) and (Control.Root.GetObject is TCommonCustomForm) then
      Result := TCommonCustomForm(Control.Root.GetObject)
    else
      Result := nil;
  end;

var
  WBService : IFMXWBService;
begin
  if not (csDesigning in ComponentState) and ((FWeb = nil) or (Sender = GetParentForm(self as TFmxObject))) and
    TPlatformServices.Current.SupportsPlatformService(IFMXWBService, WBService) then
  begin
    WBService.DestroyWebBrowser(FWeb); // добавлена эта строка.
    FWeb := WBService.CreateWebBrowser;
    FWeb.SetWebBrowserControl(Self);
    FWeb.UpdateContentFromControl;
    FWeb.URL := FURL;
    FWeb.Navigate;
  end;
end;

Что дает правка:

допустим, у вас есть WB на главной форме и на дочерней форме (или фрейме - без разницы), которая создается / уничтожается динамически. При создании вторичной формы метод FormHandleCreated вызывается дважды, при этом FWeb, созданный в первом вызове просто забывается, но не уничтожается (сильная ссылка в списке веббраузеров в WBService). Дальше вторичная форма уничтожается (захватывая с собой FWeb, созданный при втором вызове FormHandleCreated ), а в "забытом" FWeb остаются невалидные ссылки на родителя. Что при вызове метода TWBFactoryService.RealignBrowsers (активация / изменение размеров формы) приведет к AV.

Внесенное изменение удаляет FWeb из списка WBService, и в дальнейшем ничего не мешает его спокойному уничтожению.

Ссылка на комментарий
  • 0
В 9 ноября 2017 г. в 13:52, kami сказал:

if  ..((FWeb = nil).... then begin WBService.DestroyWebBrowser(FWeb);

Точно ни где ошибка не вкралась?

 

В общем не знаю про ios, но под win и android этот фикс не лечит. Всё те же падения под win и так же не убираемый фрейм под андроид. Так что пока tms единственный выход, хотя там тоже глюков вагон. :( 
 

Ссылка на комментарий
  • 0
11 час назад, Akad сказал:

Точно ни где ошибка не вкралась?

Точно. Полная копипаста из моего модуля.

Под Win - лечит, опробовано лично. Про Андроид - не скажу, не знаю.

11 час назад, Akad сказал:

Всё те же падения под win

Так разберитесь, где именно падает. Что за стек вызовов, с какими параметрами. Оттрассируйте и предложите фикс.

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...