铬嵌入式框架

chromium embedded framework

如何以相同的形式真正打开新的标签,使用标签或简单地使用相同的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 中存在 const target_disposition如何把它(target_disposition)改成current tab?

您为更好的浏览器付出的代价是花更多的时间尝试将其嵌入到您的应用程序中。 一般来说,从开发人员的角度来看,TWebBrowser 组件更易于使用,但您的用户的体验会更差。

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

这就是我添加 PopupBrowser2 demo in CEF4Delphi and OldCEF4Delphi 的原因。

您不能更改 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时,demo调用CreateClientHandler设置"windowInfo"和"client"事件参数为FChildForm使用的windowInfo和client

如果您想使用标签,您还需要创建一个隐藏标签。

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