В интернет-браузере клик по ссылке с атрибутом "target="_blank"", или клик по ссылке левой кнопкой мыши с нажатой на клавиатуре клавишей ctrl или shift инициируют создание в интернет-браузере новой вкладки или нового окна. В WebView2 нет встроенной поддержки вкладок, поэтому в этой ситуации всегда открывается новое окно браузера. Например, в программе на Delphi первый клик по ссылке в TEdgeBrowser откроет окно браузера, второй клик в этом окне откроет второе окно и так до бесконечности. Самое плохое то, что эти новые окна мы уже не контролируем. Они живут своей жизнью даже после закрытия программы.
На скриншоте в логе программы видно, что открытие первой ссылки программа перехватила, а открытие второй ссылки, которое инициировано в окне браузера, программа не видит.
Помочь в решении этой проблемы у TEdgeBrowser может обработчик события OnNewWindowRequested. Это событие вызывается, когда WebView2 для перехода по ссылке запрашивает открытие нового окна. Свое решение на этот запрос программа может сообщить через параметр "Args" типа TNewWindowRequestedEventArgs, который реализует интерфейс ICoreWebView2NewWindowRequestedEventArgs:
Для начала, посмотреть, какую ссылку WebView2 пытается открыть:
Помочь в решении этой проблемы у TEdgeBrowser может обработчик события OnNewWindowRequested. Это событие вызывается, когда WebView2 для перехода по ссылке запрашивает открытие нового окна. Свое решение на этот запрос программа может сообщить через параметр "Args" типа TNewWindowRequestedEventArgs, который реализует интерфейс ICoreWebView2NewWindowRequestedEventArgs:
ICoreWebView2NewWindowRequestedEventArgs = interface(IUnknown) ['{9EDC7F5F-C6EA-4F3C-827B-A8880794C0A9}'] function Get_uri(out uri: PWideChar): HResult; stdcall; function Set_NewWindow(const NewWindow: ICoreWebView2): HResult; stdcall; function Get_NewWindow(out NewWindow: ICoreWebView2): HResult; stdcall; function Set_Handled(Handled: Integer): HResult; stdcall; function Get_Handled(out Handled: Integer): HResult; stdcall; function Get_IsUserInitiated(out IsUserInitiated: Integer): HResult; stdcall; function GetDeferral(out deferral: ICoreWebView2Deferral): HResult; stdcall; end;Итак, что мы можем сделать в обработчике OnNewWindowRequested?
Для начала, посмотреть, какую ссылку WebView2 пытается открыть:
procedure TEdgeMain.EdgeBrowserNewWindowRequested(Sender: TCustomEdgeBrowser; Args: TNewWindowRequestedEventArgs); var wcUri: PWideChar; begin mLog.Lines.Add(Sender.Name + ' NewWindowRequested'); Args.ArgsInterface.Get_uri(wcUri); mLog.Lines.Add(wcUri); CoTaskMemFree(wcUri); end;А дальше принять решение, что делать с этой ссылкой:
- Запретить переход по ссылке. Для этого просто сообщим WebView2, что мы уже обработали его запрос на открытие нового окна:
procedure TEdgeMain.EdgeBrowserNewWindowRequested(Sender: TCustomEdgeBrowser; Args: TNewWindowRequestedEventArgs); begin Args.ArgsInterface.Set_Handled(1); end;
- Открыть ссылку в текущем WebView2:
procedure TEdgeMain.EdgeBrowserNewWindowRequested(Sender: TCustomEdgeBrowser; Args: TNewWindowRequestedEventArgs); begin Args.ArgsInterface.Set_NewWindow(Sender.DefaultInterface); end;
- Открыть ссылку в другом WebView2 (новой вкладке):
procedure TEdgeMain.EdgeBrowserNewWindowRequested(Sender: TCustomEdgeBrowser; Args: TNewWindowRequestedEventArgs); begin // тут должен быть код создания новой вкладки с новым TEdgeBrowser pcEdgeBrowser.ActivePageIndex := 1; Args.ArgsInterface.Set_NewWindow(EdgeBrowser1.DefaultInterface); end;
procedure TEdgeMain.EdgeBrowserNewWindowRequested(Sender: TCustomEdgeBrowser; Args: TNewWindowRequestedEventArgs); var wcUri: PWideChar; begin Args.ArgsInterface.Get_uri(wcUri); // тут должен быть код создания новой вкладки с новым TEdgeBrowser pcEdgeBrowser.ActivePageIndex := 1; EdgeBrowser1.Navigate(wcUri); CoTaskMemFree(wcUri); Args.ArgsInterface.Set_Handled(1); end;
Комментариев нет:
Отправить комментарий