铬嵌入式框架

时间:2018-08-14 07:50:07

标签: c++ delphi chromium chromium-embedded

如何使用选项卡或仅使用相同的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

1 个答案:

答案 0 :(得分:3)

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

使用CEF正确打开新标签页或表单是其中更为复杂的功能之一。

这就是为什么我在PopupBrowser2CEF4Delphi中添加了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时,演示程序将调用CreateClientHandler,以使用FChildForm使用的windowInfo和client设置“ windowInfo”和“ client”事件参数。

如果要使用标签页,则还需要创建一个隐藏的标签页。

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

相关问题