/** @file browser_handler.h * @brief 实现CefClient接口,处理Cef浏览器对象发出的各个事件和消息,并与上层控件进行数据交互 * @copyright (c) 2016, NetEase Inc. All rights reserved * @author Redrain * @date 2016/7/19 */ #pragma once #include "include/cef_client.h" #include "include/cef_browser.h" #include "cef_control/util/auto_unregister.h" #include "cef_control/app/cef_js_bridge.h" namespace nim_comp { // BrowserHandler implements CefClient and a number of other interfaces. class BrowserHandler : public nbase::SupportWeakCallback, public CefClient, public CefLifeSpanHandler, public CefRenderHandler, public CefContextMenuHandler, public CefDisplayHandler, public CefDragHandler, public CefGeolocationHandler, public CefJSDialogHandler, public CefKeyboardHandler, public CefLoadHandler, public CefRequestHandler, public CefDownloadHandler, public CefDialogHandler { public: BrowserHandler(); /** @class HandlerDelegate * @brief BrowserHandler的消息委托类接口,BrowserHandler类会处理多数Cef浏览器对象的事件 * 其中一些需要与上层交互的事件接口封装到此类中,BrowserHandler把这些事件传递到委托接口中 * 可以根据需求来扩展此接口 */ class HandlerDelegate : public virtual nbase::SupportWeakCallback { public: // 在非UI线程中被调用 virtual void OnPaint(CefRefPtr browser, CefRenderHandler::PaintElementType type, const CefRenderHandler::RectList& dirtyRects, const std::string* buffer, int width, int height) = 0; virtual void OnPopupShow(CefRefPtr browser, bool show) = 0; virtual void OnPopupSize(CefRefPtr browser, const CefRect& rect) = 0; virtual void UpdateWindowPos() = 0; // 在非UI线程中被调用 virtual void OnBeforeContextMenu(CefRefPtr browser, CefRefPtr frame, CefRefPtr params, CefRefPtr model) = 0; // 在非UI线程中被调用 virtual bool OnContextMenuCommand(CefRefPtr browser, CefRefPtr frame, CefRefPtr params, int command_id, EventFlags event_flags) = 0; virtual void OnAddressChange(CefRefPtr browser, CefRefPtr frame, const CefString& url) = 0; virtual void OnTitleChange(CefRefPtr browser, const CefString& title) = 0; virtual void OnLoadingStateChange(CefRefPtr browser, bool isLoading, bool canGoBack, bool canGoForward) = 0; virtual void OnLoadStart(CefRefPtr browser, CefRefPtr frame) = 0; virtual void OnLoadEnd(CefRefPtr browser, CefRefPtr frame, int httpStatusCode) = 0; virtual void OnLoadError(CefRefPtr browser, CefRefPtr frame, ErrorCode errorCode, const CefString& errorText, const CefString& failedUrl) = 0; // 在非UI线程中被调用 virtual bool OnBeforePopup(CefRefPtr browser, CefRefPtr frame, const CefString& target_url, const CefString& target_frame_name, CefLifeSpanHandler::WindowOpenDisposition target_disposition, bool user_gesture, const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo, CefRefPtr& client, CefBrowserSettings& settings, bool* no_javascript_access) = 0; virtual bool OnAfterCreated(CefRefPtr browser) = 0; virtual void OnBeforeClose(CefRefPtr browser) = 0; // 在非UI线程中被调用 virtual bool OnBeforeBrowse(CefRefPtr browser, CefRefPtr frame, CefRefPtr request, bool is_redirect) = 0; virtual void OnProtocolExecution(CefRefPtr browser, const CefString& url, bool& allow_os_execution) = 0; // 在非UI线程中被调用 virtual ReturnValue OnBeforeResourceLoad( CefRefPtr browser, CefRefPtr frame, CefRefPtr request, CefRefPtr callback) = 0; virtual void OnRenderProcessTerminated(CefRefPtr browser, TerminationStatus status) = 0; // 文件下载相关 virtual void OnBeforeDownload( CefRefPtr browser, CefRefPtr download_item, const CefString& suggested_name, CefRefPtr callback) = 0; virtual void OnDownloadUpdated( CefRefPtr browser, CefRefPtr download_item, CefRefPtr callback) = 0; // 打开文件 Dialog virtual bool OnFileDialog( CefRefPtr browser, FileDialogMode mode, const CefString& title, const CefString& default_file_path, const std::vector& accept_filters, int selected_accept_filter, CefRefPtr callback) = 0; // 封装一些 JS 与 C++ 交互的功能 virtual bool OnExecuteCppFunc(const CefString& function_name, const CefString& params, int js_callback_id, CefRefPtr browser) = 0; virtual bool OnExecuteCppCallbackFunc(int cpp_callback_id, const CefString& json_string) = 0; }; public: // 设置Cef浏览器对象所属的窗体的句柄 void SetHostWindow(HWND hwnd){ hwnd_ = hwnd; } // 设置委托类指针,浏览器对象的一些事件会交给此指针对象来处理 // 当指针所指的对象不需要处理事件时,应该给参数传入NULL void SetHandlerDelegate(HandlerDelegate *handler){ handle_delegate_ = handler; } // 设置Cef渲染内容的大小 void SetViewRect(RECT rc); // 当前Web页面中获取焦点的元素是否可编辑 bool IsCurFieldEditable(){ return is_focus_oneditable_field_; } CefRefPtr GetBrowser(){ return browser_; } CefRefPtr GetBrowserHost(); // 添加一个任务到队列中,当Browser对象创建成功后,会依次触发任务 // 比如创建Browser后调用LoadUrl加载网页,但是这时Browser很可能还没有创建成功,就把LoadUrl任务添加到队列 UnregisterCallback AddAfterCreateTask(const StdClosure& cb); void CloseAllBrowser(); public: // CefClient methods. Important to return |this| for the handler callbacks. virtual CefRefPtr GetContextMenuHandler() OVERRIDE { return this; } virtual CefRefPtr GetRenderHandler() OVERRIDE { return this; } virtual CefRefPtr GetDisplayHandler() OVERRIDE{ return this; } virtual CefRefPtr GetDragHandler() OVERRIDE{ return this; } virtual CefRefPtr GetGeolocationHandler() OVERRIDE{ return this; } virtual CefRefPtr GetJSDialogHandler() { return this; } virtual CefRefPtr GetKeyboardHandler() OVERRIDE{ return this; } virtual CefRefPtr GetLifeSpanHandler() OVERRIDE{ return this; } virtual CefRefPtr GetLoadHandler() OVERRIDE{ return this; } virtual CefRefPtr GetRequestHandler() OVERRIDE{ return this; } virtual CefRefPtr GetDownloadHandler() OVERRIDE { return this; } virtual CefRefPtr GetDialogHandler() OVERRIDE { return this; } virtual bool OnProcessMessageReceived(CefRefPtr browser, CefProcessId source_process, CefRefPtr message) OVERRIDE; // CefLifeSpanHandler methods virtual bool OnBeforePopup(CefRefPtr browser, CefRefPtr frame, const CefString& target_url, const CefString& target_frame_name, CefLifeSpanHandler::WindowOpenDisposition target_disposition, bool user_gesture, const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo, CefRefPtr& client, CefBrowserSettings& settings, bool* no_javascript_access) OVERRIDE; virtual void OnAfterCreated(CefRefPtr browser) OVERRIDE; virtual bool DoClose(CefRefPtr browser) OVERRIDE; virtual void OnBeforeClose(CefRefPtr browser) OVERRIDE; // CefRenderHandler methods virtual bool GetRootScreenRect(CefRefPtr browser, CefRect& rect) OVERRIDE; virtual bool GetViewRect(CefRefPtr browser, CefRect& rect) OVERRIDE; virtual bool GetScreenPoint(CefRefPtr browser, int viewX, int viewY, int& screenX, int& screenY) OVERRIDE; virtual void OnPopupShow(CefRefPtr browser, bool show) OVERRIDE; virtual void OnPopupSize(CefRefPtr browser, const CefRect& rect) OVERRIDE; virtual void OnPaint(CefRefPtr browser, PaintElementType type, const RectList& dirtyRects, const void* buffer, int width, int height) OVERRIDE; virtual void OnCursorChange(CefRefPtr browser, CefCursorHandle cursor, CursorType type, const CefCursorInfo& custom_cursor_info) OVERRIDE; // CefContextMenuHandler methods virtual void OnBeforeContextMenu(CefRefPtr browser, CefRefPtr frame, CefRefPtr params, CefRefPtr model) OVERRIDE; virtual bool RunContextMenu(CefRefPtr browser, CefRefPtr frame, CefRefPtr params, CefRefPtr model, CefRefPtr callback) OVERRIDE; virtual bool OnContextMenuCommand(CefRefPtr browser, CefRefPtr frame, CefRefPtr params, int command_id, EventFlags event_flags) OVERRIDE; virtual void OnContextMenuDismissed(CefRefPtr browser, CefRefPtr frame) OVERRIDE; // CefDisplayHandler methods virtual void OnAddressChange(CefRefPtr browser, CefRefPtr frame, const CefString& url) OVERRIDE; virtual void OnTitleChange(CefRefPtr browser, const CefString& title) OVERRIDE; virtual bool OnConsoleMessage(CefRefPtr browser, const CefString& message, const CefString& source, int line) OVERRIDE; // CefLoadHandler methods virtual void OnLoadingStateChange(CefRefPtr browser, bool isLoading, bool canGoBack, bool canGoForward) OVERRIDE; virtual void OnLoadStart(CefRefPtr browser, CefRefPtr frame) OVERRIDE; virtual void OnLoadEnd(CefRefPtr browser, CefRefPtr frame, int httpStatusCode) OVERRIDE; virtual void OnLoadError(CefRefPtr browser, CefRefPtr frame, ErrorCode errorCode, const CefString& errorText, const CefString& failedUrl) OVERRIDE; // CefJSDialogHandler methods virtual bool OnJSDialog(CefRefPtr browser, const CefString& origin_url, const CefString& accept_lang, JSDialogType dialog_type, const CefString& message_text, const CefString& default_prompt_text, CefRefPtr callback, bool& suppress_message) OVERRIDE; // CefRequestHandler methods bool OnBeforeBrowse(CefRefPtr browser, CefRefPtr frame, CefRefPtr request, bool is_redirect) OVERRIDE; virtual void OnProtocolExecution(CefRefPtr browser, const CefString& url, bool& allow_os_execution); cef_return_value_t OnBeforeResourceLoad( CefRefPtr browser, CefRefPtr frame, CefRefPtr request, CefRefPtr callback) OVERRIDE; bool OnQuotaRequest(CefRefPtr browser, const CefString& origin_url, int64 new_size, CefRefPtr callback) OVERRIDE; void OnRenderProcessTerminated(CefRefPtr browser, TerminationStatus status) OVERRIDE; // CefDownloadHandler methods virtual void OnBeforeDownload( CefRefPtr browser, CefRefPtr download_item, const CefString& suggested_name, CefRefPtr callback) OVERRIDE; virtual void OnDownloadUpdated( CefRefPtr browser, CefRefPtr download_item, CefRefPtr callback) OVERRIDE; // CefDialogHandler methods virtual bool OnFileDialog(CefRefPtr browser, FileDialogMode mode, const CefString& title, const CefString& default_file_path, const std::vector& accept_filters, int selected_accept_filter, CefRefPtr callback) OVERRIDE; protected: CefRefPtr browser_; std::vector> browser_list_; HWND hwnd_; HandlerDelegate* handle_delegate_; RECT rect_cef_control_; std::string paint_buffer_; bool is_focus_oneditable_field_; UnregistedCallbackList task_list_after_created_; IMPLEMENT_REFCOUNTING(BrowserHandler); }; }