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

Проблема с фокусом ввода в TWebBrowser при использовании WindowsEngine.EdgeOnly в FMX

Delphi , Интернет и Сети , Браузер

 

В FMX-приложении при использовании компонента TWebBrowser с движком WindowsEngine.EdgeOnly возникает проблема с потерей фокуса у элемента <input> на веб-странице, отображаемой внутри браузера. При клике на поле ввода оно получает фокус, но немедленно его теряет, что делает невозможным ввод текста. Проблема проявляется на Windows и исчезает при подключении второго монитора или переключении на WindowsEngine.IEOnly.

Пример кода для воспроизведения проблемы:

procedure TForm1.FormCreate(Sender: TObject);
begin
  var browser := TWebBrowser.Create(Self);
  browser.WindowsEngine := TWindowsEngine.EdgeOnly;
  browser.Align := TAlignLayout.Client;
  browser.URL := 'http://localhost:8000/test.html';
  Self.AddObject(browser);
end;

Содержимое test.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Test</title>
  </head>
  <body>
    <input type="text" name="test">
  </body>
</html>

Решение:

Проблема заключается в ошибке в реализации FMX.WebBrowser.Win. В обработчике события GotFocus для WebView2 вызывается SetFocus, что приводит к нежелательной потере фокуса.

Предложенное решение:

Закомментировать вызов SetFocus в следующем коде:

FWebViewController.Add_GotFocus(
  Callback<ICoreWebView2, IUnknown>
    .CreateAs<ICoreWebView2FocusChangedEventHandler>(
      function(const WebView: ICoreWebView2; const Args: IUnknown): HResult; stdcall
      begin
        Result := S_OK;
        FWebViewFocusEventActive := True;
        //SetFocus;  // ЗАКОММЕНТИРОВАТЬ ЭТУ СТРОКУ
        FWebViewFocusEventActive := False;
      end
    ),
    FGotFocusToken);

В VCL версии компонента TEdgeBrowser используется другой подход:

FWebViewController.Add_GotFocus(
  Callback<ICoreWebView2, IUnknown>
    .CreateAs<ICoreWebView2FocusChangedEventHandler>(
      function(const WebView: ICoreWebView2; const Args: IUnknown): HResult; stdcall
      begin
        Result := S_OK;
        FWebViewFocusEventActive := True;
        DoEnter;
        FWebViewFocusEventActive := False;
      end
    ), FGotFocusToken);

где DoEnter вызывает WebViewController.MoveFocus(COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC), а FWebViewFocusEventActive используется для предотвращения рекурсивного изменения фокуса.

Альтернативное решение (предложенное в ответах):

Этот вариант предполагает поиск HWND рендера WebView и принудительную установку на него фокуса при клике мышью.

unit Unit13;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.WebBrowser,
  FMX.Platform,
  FMX.Platform.Win,
  Winapi.Windows,
  Winapi.Messages;

type
  TForm13 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FBrowser: TWebBrowser;
    FWebViewRenderHandle: HWND;
    procedure BrowserDidFinishLoad(ASender: TObject);
    procedure WMParentNotify(var Message: TWMParentNotify); message WM_PARENTNOTIFY;
  public
  end;

var
  Form13: TForm13;

implementation

{$R *.fmx}

procedure TForm13.FormCreate(Sender: TObject);
begin
  FBrowser := TWebBrowser.Create(Self);
  FBrowser.Parent := Self;
  FBrowser.Align := TAlignLayout.Client;
  FBrowser.OnDidFinishLoad := BrowserDidFinishLoad;
  FBrowser.URL := 'http://localhost:8000/test.html';
end;

procedure TForm13.BrowserDidFinishLoad(ASender: TObject);
var
  WinService: IFMXWindowService;
  ParentHandle: HWND;
begin
  if (FBrowser <> nil) and (FWebViewRenderHandle = 0) then
  begin
    if TPlatformServices.Current.SupportsPlatformService(IFMXWindowService, IInterface(WinService)) then
    begin
      ParentHandle := WindowHandleToPlatform(Self.Handle).Wnd;
      if ParentHandle <> 0 then
      begin
        FWebViewRenderHandle := FindWindowEx(ParentHandle, 0, 'Chrome_RenderWidgetHostHWND', nil);
      end;
    end;
  end;
end;

procedure TForm13.WMParentNotify(var Message: TWMParentNotify);
begin
  if (Message.Event = WM_LBUTTONDOWN) and (FWebViewRenderHandle <> 0) then
  begin
    Winapi.Windows.SetFocus(FWebViewRenderHandle);
  end;
  inherited;
end;

end.

Обсуждение:

Первое решение (закомментирование SetFocus) является более простым и, вероятно, более правильным, так как оно устраняет причину проблемы. Второе решение (принудительная установка фокуса) является обходным путем и может иметь нежелательные побочные эффекты.

Рекомендации:

  1. Попробуйте закомментировать SetFocus в исходном коде FMX.WebBrowser.Win.
  2. Если это не возможно, используйте второй вариант, но будьте готовы к возможным проблемам.
  3. Сообщите об этой ошибке разработчикам Embarcadero, чтобы они исправили ее в будущих версиях Delphi.

Дополнительные замечания:

  • Убедитесь, что HTML-код вашей веб-страницы валиден.
  • Рассмотрите возможность использования компонента WebView4Delphi, который, по словам автора вопроса, не имеет этой проблемы.

Эта статья предоставляет информацию о проблеме с фокусом ввода в TWebBrowser при использовании WindowsEngine.EdgeOnly в FMX, а также предлагает два возможных решения. Первое решение является более предпочтительным, так как оно устраняет причину проблемы. Не забудьте сообщить об этой ошибке разработчикам Embarcadero.

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

В FMX-приложении при использовании TWebBrowser с WindowsEngine.EdgeOnly возникает проблема с потерей фокуса ввода на веб-странице, вызванная ошибкой в FMX.WebBrowser.Win, которую можно решить, закомментировав вызов SetFocus или принудительно установив фо


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

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




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


:: Главная :: Браузер ::


реклама


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

Время компиляции файла: 2024-12-22 20:14:06
2025-09-21 13:35:38/0.005263090133667/0