您为更好的浏览器付出的代价是有更多时间尝试将其嵌入您的应用中。
一般来说,从开发人员的角度来看,TWebBrowser 组件更易于使用,但您的用户体验会更差。
使用 CEF 以正确方式打开新选项卡或表单是复杂得多的功能之一。
这就是我在CEF4Delphi 和OldCEF4Delphi 中添加PopupBrowser2 演示的原因。
您不能更改 CONST 参数。我建议您按照 CEF3 关于此事件的说明来创建新的子浏览器。
OnBeforePopup 事件的 CEF3 代码 cmets 如下:
///
// 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用FChildForm使用的windowInfo和client设置“windowInfo”和“client”事件参数。
如果你想使用标签,你还需要创建一个隐藏标签。
您也可以尝试在 DCEF3 中取消设置 CEF_MULTI_THREADED_MESSAGE_LOOP 或在 CEF4Delphi 中将 GlobalCEFApp.MultiThreadedMessageLoop 设置为 False,但是您需要使用“外部泵”。有关详细信息,请参阅 SimpleExternalPumpBrowser 演示。