Chromium 嵌入式框架

chromium embedded framework

本文关键字:框架 嵌入式 Chromium      更新时间:2023-10-16

如何使用选项卡或简单的相同 cef 组件以相同的形式真正打开新选项卡或创建新选项卡,这不是重要的部分。 重要的是用什么

procedure OnBeforePopup ...
...
begin
Return:= true;
TChromium1.LoadURL(target_url);
end; 

在某些情况下不起作用,例如在真实浏览器中(我认为这不是真正发送到新选项卡(。

在TWebBrowser中我没有这样的问题,代码运行良好:

procedure TForm1.WebBrowser1NewWindow2(Sender: TObject;
var ppDisp: IDispatch; var Cancel: WordBool);
var NewWindow: TForm1;
begin
NewWindow := TForm1.Create(self);
NewWindow.Show;
ppDisp := NewWindow.Webbrowser1.DefaultDispatch;
end;

如何进行真正的调度?

在OnBeforePopup中存在常量target_disposition如何将其(target_disposition(更改为current tab

你为更好的浏览器付出的代价是更多的时间尝试将其嵌入到你的应用程序中。 通常,从开发人员的角度来看,TWebBrowser组件更容易使用,但您的用户将获得更糟糕的体验。

使用 CEF 以正确的方式打开新选项卡或表单是那些更复杂的功能之一。

这就是为什么我在CEF4Delphi和OldCEF4Delphi中添加了PopupBrowser2演示。

您无法更改 CONST 参数。我建议您按照 CEF3 关于此事件的说法来创建新的子浏览器。

OnBeforePopup 事件的 CEF3 代码注释如下:

///
// Called on the UI thread before a new popup browser is created. The
// |browser| and |frame| values represent the source of the popup request. The
// |target_url| and |target_frame_name| values indicate where the popup
// browser should navigate and may be NULL if not specified with the request.
// The |target_disposition| value indicates where the user intended to open
// the popup (e.g. current tab, new tab, etc). The |user_gesture| value will
// be true (1) if the popup was opened via explicit user gesture (e.g.
// clicking a link) or false (0) if the popup opened automatically (e.g. via
// the DomContentLoaded event). The |popupFeatures| structure contains
// additional information about the requested popup window. To allow creation
// of the popup browser optionally modify |windowInfo|, |client|, |settings|
// and |no_javascript_access| and return false (0). To cancel creation of the
// popup browser return true (1). The |client| and |settings| values will
// default to the source browser's values. If the |no_javascript_access| value
// is set to false (0) the new browser will not be scriptable and may not be
// hosted in the same renderer process as the source browser. Any
// modifications to |windowInfo| will be ignored if the parent browser is
// wrapped in a cef_browser_view_t. Popup browser creation will be canceled if
// the parent browser is destroyed before the popup browser creation completes
// (indicated by a call to OnAfterCreated for the popup browser).
///

此处的挑战是 CEF3 可能使用与主线程不同的线程来执行所有事件,并且您希望在触发此事件时创建 VCL 组件。

如果在 cef.inc 中设置CEF_MULTI_THREADED_MESSAGE_LOOP,DCEF3 将使用不同的线程。 如果 GlobalCEFApp.MultiThreadedMessageLoop 为 True,则 CEF4Delphi 使用不同的线程,这是默认值,因为它是 CEF3 对 Windows 应用程序的建议设置。

如您所知,如果您在不同的线程中创建和销毁 VCL 组件,您将遇到问题。

这会强制您创建一个隐藏的弹出表单,以防万一触发此事件。正如您在 PopupBrowser2 中看到的,在主线程和此事件外部创建了一个隐藏的 FChildForm。

稍后,当执行 OnBeforePopup 时,演示调用 CreateClientHandler 来设置 "windowInfo" 和 "client" 事件参数,其中包含 FChildForm 使用的 windowInfo 和客户端。

如果要使用选项卡,还需要创建隐藏选项卡。

您也可以尝试在DCEF3中取消设置CEF_MULTI_THREADED_MESSAGE_LOOP或在CEF4Delphi中将GlobalCEFApp.MultiThreadedMessageLoop设置为False,但随后需要使用"外部泵"。有关更多详细信息,请参阅 SimpleExternalPumpBrowser 演示。