├── src ├── QCefWing │ ├── QCefWing.h │ ├── icon.ico │ ├── resource.h │ ├── QCefWing.rc │ ├── CMakeLists.txt │ ├── QCefWing.manifest │ ├── QCefWing.cpp │ └── CefViewRenderApp │ │ ├── RenderDelegates │ │ ├── QCefViewDefaultRenderDelegate.h │ │ ├── QCefViewDefaultRenderDelegate.cpp │ │ ├── QCefClient.h │ │ └── QCefClient.cpp │ │ ├── QCefViewRenderApp.cpp │ │ └── QCefViewRenderApp.h ├── QCefView │ ├── QCefView.rc │ ├── CefViewBrowserApp │ │ ├── BrowserDelegates │ │ │ ├── QCefViewDefaultBrowserDelegate.cpp │ │ │ └── QCefViewDefaultBrowserDelegate.h │ │ ├── QCefViewBrowserAppHelper.cpp │ │ ├── QCefViewDelegate.h │ │ ├── QCefQueryHandler.h │ │ ├── QCefQueryHandler.cpp │ │ ├── QCefViewBrowserApp.h │ │ ├── SchemeHandlers │ │ │ ├── QCefViewDefaultSchemeHandler.h │ │ │ └── QCefViewDefaultSchemeHandler.cpp │ │ ├── QCefViewBrowserApp.cpp │ │ ├── QCefViewBrowserHandler.h │ │ └── QCefViewBrowserHandler.cpp │ ├── QCefEvent.cpp │ ├── CCefSetting.cpp │ ├── Include │ │ ├── QCefEvent.h │ │ ├── QCefQuery.h │ │ ├── QCefSetting.h │ │ └── QCefView.h │ ├── CMakeLists.txt │ ├── CCefManager.h │ ├── QCefQuery.cpp │ ├── CCefSetting.h │ ├── CCefWindow.h │ ├── CCefManager.cpp │ ├── QCefSetting.cpp │ ├── CCefWindow.cpp │ └── QCefView.cpp └── QCefProto │ ├── QCefProtocol.cpp │ ├── CMakeLists.txt │ └── QCefProtocol.h ├── .gitignore ├── .clang-format ├── test └── QCefViewTest │ ├── qcefviewtest.qrc │ ├── main.cpp │ ├── qcefviewtest.h │ ├── customcefview.h │ ├── qcefviewtest.cpp │ ├── QCefViewTest.manifest │ ├── customcefview.cpp │ ├── CMakeLists.txt │ ├── QCefViewTestPage.html │ └── qcefviewtest.ui ├── .github └── FUNDING.yml ├── readme.md ├── dep └── README.md ├── config.cmake ├── CMakeLists.txt └── License /src/QCefWing/QCefWing.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build/* 2 | /dep/* 3 | *.aps 4 | .vs 5 | out -------------------------------------------------------------------------------- /src/QCefWing/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tishion/QCefView/HEAD/src/QCefWing/icon.ico -------------------------------------------------------------------------------- /src/QCefWing/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tishion/QCefView/HEAD/src/QCefWing/resource.h -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | BasedOnStyle: Mozilla 3 | SortIncludes: 'false' 4 | ColumnLimit: 120 5 | ... 6 | -------------------------------------------------------------------------------- /src/QCefView/QCefView.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tishion/QCefView/HEAD/src/QCefView/QCefView.rc -------------------------------------------------------------------------------- /src/QCefWing/QCefWing.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tishion/QCefView/HEAD/src/QCefWing/QCefWing.rc -------------------------------------------------------------------------------- /test/QCefViewTest/qcefviewtest.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/QCefProto/QCefProtocol.cpp: -------------------------------------------------------------------------------- 1 | #include "QCefProtocol.h" 2 | 3 | /// ////////////////////////////////////////////////////////////////////////// 4 | // 5 | // Just an empty file 6 | // 7 | -------------------------------------------------------------------------------- /src/QCefProto/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.4.1) 2 | project(QCefProto) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CXX_STANDARD_REQUIRED) 6 | 7 | add_library(${PROJECT_NAME} 8 | QCefProtocol.h 9 | QCefProtocol.cpp 10 | ) -------------------------------------------------------------------------------- /test/QCefViewTest/main.cpp: -------------------------------------------------------------------------------- 1 | #include "qcefviewtest.h" 2 | #include 3 | 4 | int 5 | main(int argc, char* argv[]) 6 | { 7 | QApplication a(argc, argv); 8 | QCefViewTest w; 9 | w.show(); 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: tishion 4 | patreon: tishion 5 | open_collective: # Replace with a single Open Collective username 6 | community_bridge:QCefView 7 | custom: ["https://www.paypal.me/octocat", octocat.com] 8 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # https://cefview.github.io/QCefView/ 2 | 3 | # QCefView已经升级为支持跨平台的全新版本,项目已经迁移到:https://github.com/cefview/qcefview 4 | 5 | # QCefView has been updated to brand new version with support of cross-platform, the new project:https://github.com/cefview/qcefview 6 | -------------------------------------------------------------------------------- /dep/README.md: -------------------------------------------------------------------------------- 1 | Current commit is built with: 2 | Build with CEF cef_binary_89.0.12+g2b76680+chromium-89.0.4389.90_windows64.tar.bz2 3 | 4 | If you need to use a cef distribution in different version, please download from: 5 | https://cef-builds.spotifycdn.com/index.html 6 | 7 | Version history used: 8 | -------------------------------------------------------------------------------- /test/QCefViewTest/qcefviewtest.h: -------------------------------------------------------------------------------- 1 | #ifndef QCEFVIEWTEST_H 2 | #define QCEFVIEWTEST_H 3 | 4 | #include 5 | #include "ui_qcefviewtest.h" 6 | #include "customcefview.h" 7 | 8 | class QCefViewTest : public QMainWindow 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | QCefViewTest(QWidget *parent = 0); 14 | ~QCefViewTest(); 15 | 16 | protected slots: 17 | void onBtnChangeColorClicked(); 18 | private: 19 | Ui::QCefViewTestClass ui; 20 | CustomCefView* cefview; 21 | }; 22 | 23 | #endif // QCEFVIEWTEST_H 24 | -------------------------------------------------------------------------------- /src/QCefView/CefViewBrowserApp/BrowserDelegates/QCefViewDefaultBrowserDelegate.cpp: -------------------------------------------------------------------------------- 1 | #include "QCefViewDefaultBrowserDelegate.h" 2 | 3 | namespace QCefViewDefaultBrowserDelegate { 4 | void 5 | CreateBrowserDelegate(QCefViewBrowserApp::BrowserDelegateSet& delegates) 6 | { 7 | delegates.insert(new BrowserDelegate()); 8 | } 9 | 10 | BrowserDelegate::BrowserDelegate() {} 11 | 12 | void 13 | BrowserDelegate::OnContextInitialized(CefRefPtr app) 14 | {} 15 | 16 | void 17 | BrowserDelegate::OnBeforeChildProcessLaunch(CefRefPtr app, CefRefPtr command_line) 18 | {} 19 | 20 | } 21 | -------------------------------------------------------------------------------- /test/QCefViewTest/customcefview.h: -------------------------------------------------------------------------------- 1 | #ifndef CUSTOMCEFVIEW_H 2 | #define CUSTOMCEFVIEW_H 3 | 4 | #include 5 | 6 | class CustomCefView : public QCefView 7 | { 8 | Q_OBJECT 9 | 10 | public: 11 | using QCefView::QCefView; 12 | ~CustomCefView(); 13 | 14 | void changeColor(); 15 | 16 | protected: 17 | virtual void onDraggableRegionChanged(const QRegion& region) override; 18 | 19 | virtual void onQCefUrlRequest(const QString& url) override; 20 | 21 | virtual void onQCefQueryRequest(const QCefQuery& query) override; 22 | 23 | virtual void onInvokeMethodNotify(int browserId, 24 | int frameId, 25 | const QString& method, 26 | const QVariantList& arguments) override; 27 | 28 | private: 29 | }; 30 | 31 | #endif // CUSTOMCEFVIEW_H 32 | -------------------------------------------------------------------------------- /src/QCefView/CefViewBrowserApp/BrowserDelegates/QCefViewDefaultBrowserDelegate.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #pragma region cef_headers 4 | #include 5 | #pragma endregion cef_headers 6 | 7 | #include "../QCefViewBrowserApp.h" 8 | 9 | namespace QCefViewDefaultBrowserDelegate { 10 | void 11 | CreateBrowserDelegate(QCefViewBrowserApp::BrowserDelegateSet& delegates); 12 | 13 | class BrowserDelegate : public QCefViewBrowserApp::BrowserDelegate 14 | { 15 | public: 16 | BrowserDelegate(); 17 | 18 | virtual void OnContextInitialized(CefRefPtr app) override; 19 | 20 | virtual void OnBeforeChildProcessLaunch(CefRefPtr app, 21 | CefRefPtr command_line) override; 22 | 23 | private: 24 | IMPLEMENT_REFCOUNTING(BrowserDelegate); 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /src/QCefView/CefViewBrowserApp/QCefViewBrowserAppHelper.cpp: -------------------------------------------------------------------------------- 1 | #pragma region std_headers 2 | #include 3 | #pragma endregion std_headers 4 | 5 | #pragma region cef_headers 6 | #include 7 | #include 8 | #pragma endregion cef_headers 9 | 10 | #include "QCefViewBrowserApp.h" 11 | #include "BrowserDelegates/QCefViewDefaultBrowserDelegate.h" 12 | #include "SchemeHandlers/QCefViewDefaultSchemeHandler.h" 13 | 14 | void 15 | QCefViewBrowserApp::CreateBrowserDelegates(BrowserDelegateSet& delegates) 16 | { 17 | QCefViewDefaultBrowserDelegate::CreateBrowserDelegate(delegates); 18 | // add more browser delegates here 19 | } 20 | 21 | void 22 | QCefViewBrowserApp::RegisterCustomSchemesHandlerFactories() 23 | { 24 | QCefViewDefaultSchemeHandler::RegisterSchemeHandlerFactory(); 25 | } 26 | 27 | void 28 | QCefViewBrowserApp::RegisterCustomSchemes(CefRawPtr registrar) 29 | { 30 | QCefViewDefaultSchemeHandler::RegisterScheme(registrar); 31 | } 32 | -------------------------------------------------------------------------------- /test/QCefViewTest/qcefviewtest.cpp: -------------------------------------------------------------------------------- 1 | #include "qcefviewtest.h" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | QCefViewTest::QCefViewTest(QWidget* parent) 10 | : QMainWindow(parent) 11 | { 12 | ui.setupUi(this); 13 | QHBoxLayout* layout = new QHBoxLayout(); 14 | layout->setContentsMargins(2, 2, 2, 2); 15 | layout->setSpacing(3); 16 | 17 | connect(ui.btn_changeColor, SIGNAL(clicked()), this, SLOT(onBtnChangeColorClicked())); 18 | layout->addWidget(ui.nativeContainer); 19 | 20 | QDir dir = QCoreApplication::applicationDirPath(); 21 | QString uri = QDir::toNativeSeparators(dir.filePath("QCefViewTestPage.html")); 22 | cefview = new CustomCefView(uri, this); 23 | // cefview = new CustomCefView("http://www.google.com/", this); 24 | ui.cefContainer->layout()->addWidget(cefview); 25 | layout->addWidget(ui.cefContainer); 26 | 27 | centralWidget()->setLayout(layout); 28 | } 29 | 30 | QCefViewTest::~QCefViewTest() {} 31 | 32 | void 33 | QCefViewTest::onBtnChangeColorClicked() 34 | { 35 | cefview->changeColor(); 36 | } 37 | -------------------------------------------------------------------------------- /src/QCefView/CefViewBrowserApp/QCefViewDelegate.h: -------------------------------------------------------------------------------- 1 | #ifndef QCEFVIEWDELEGATE_H_ 2 | #define QCEFVIEWDELEGATE_H_ 3 | #pragma once 4 | 5 | #pragma region cef_headers 6 | #include 7 | #pragma endregion cef_headers 8 | 9 | class QCefViewDelegate 10 | { 11 | public: 12 | virtual ~QCefViewDelegate(){}; 13 | 14 | virtual void setCefBrowserWindow(CefWindowHandle hwnd) = 0; 15 | 16 | virtual void onLoadingStateChanged(bool isLoading, bool canGoBack, bool canGoForward) = 0; 17 | 18 | virtual void onLoadStart() = 0; 19 | 20 | virtual void onLoadEnd(int httpStatusCode) = 0; 21 | 22 | virtual void onLoadError(int errorCode, const CefString& errorMsg, const CefString& failedUrl, bool& handled) = 0; 23 | 24 | virtual void onDraggableRegionChanged(const std::vector regions) = 0; 25 | 26 | virtual void onConsoleMessage(const CefString& message, int level) = 0; 27 | 28 | virtual void onTakeFocus(bool next) = 0; 29 | 30 | virtual void onQCefUrlRequest(const CefString& url) = 0; 31 | 32 | virtual void onQCefQueryRequest(const CefString& request, int64 query_id) = 0; 33 | 34 | virtual void onInvokeMethodNotify(int browserId, const CefRefPtr& arguments) = 0; 35 | }; 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/QCefWing/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.4.1) 2 | project(${QCEF_WING_EXE}) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CXX_STANDARD_REQUIRED) 6 | 7 | file(GLOB_RECURSE _SRC_FILES 8 | "*.cpp" 9 | "*.h" 10 | ) 11 | source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Source FILES ${_SRC_FILES}) 12 | 13 | if (OS_WINDOWS) 14 | file(GLOB_RECURSE _RES_FILES 15 | "*.ico" 16 | "*.rc" 17 | ) 18 | source_group("Resources" ${_RES_FILES}) 19 | endif() 20 | 21 | add_executable(${PROJECT_NAME} WIN32 22 | ${_SRC_FILES} 23 | ${_RES_FILES} 24 | ) 25 | 26 | if (OS_WINDOWS) 27 | target_compile_definitions(${PROJECT_NAME} PRIVATE 28 | UNICODE 29 | _UNICODE 30 | ) 31 | endif() 32 | 33 | target_link_libraries(${PROJECT_NAME} PRIVATE 34 | ${CEF_DLL_WRAPPER} 35 | ${CEF_LIB_FILE} 36 | ) 37 | 38 | # Embed the manifest file into the target 39 | if (MSVC) 40 | if (CMAKE_MAJOR_VERSION LESS 3) 41 | message(WARNING "CMake version 3.0 or newer is required use build variable TARGET_FILE") 42 | else() 43 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD 44 | COMMAND mt.exe -manifest \"${CMAKE_CURRENT_SOURCE_DIR}\\${PROJECT_NAME}.manifest\" -inputresource:\"$\" -outputresource:\"$\" 45 | ) 46 | endif() 47 | endif(MSVC) -------------------------------------------------------------------------------- /src/QCefWing/QCefWing.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | QCefView Auxiliary Process 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /test/QCefViewTest/QCefViewTest.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | QCefViewTest Applicatoin 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/QCefView/CefViewBrowserApp/QCefQueryHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef QCEFQUERYHANDLER_H_ 2 | #define QCEFQUERYHANDLER_H_ 3 | #pragma once 4 | #pragma region std_headers 5 | #include 6 | #include 7 | #pragma endregion std_headers 8 | 9 | #pragma region cef_headers 10 | #include 11 | #include 12 | #include 13 | #pragma endregion cef_headers 14 | 15 | #include "QCefViewDelegate.h" 16 | 17 | class QCefQueryHandler 18 | : public CefBaseRefCounted 19 | , public CefMessageRouterBrowserSide::Handler 20 | { 21 | public: 22 | QCefQueryHandler(QCefViewDelegate* pDelegate); 23 | ~QCefQueryHandler(); 24 | 25 | virtual bool OnQuery(CefRefPtr browser, 26 | CefRefPtr frame, 27 | int64 query_id, 28 | const CefString& request, 29 | bool persistent, 30 | CefRefPtr callback) override; 31 | 32 | virtual void OnQueryCanceled(CefRefPtr browser, CefRefPtr frame, int64 query_id) override; 33 | 34 | bool Response(int64_t query, bool success, const CefString& response, int error); 35 | 36 | private: 37 | QCefViewDelegate* pQcefViewDelegate_; 38 | std::map> mapCallback_; 39 | std::mutex mtxCallbackMap_; 40 | 41 | private: 42 | IMPLEMENT_REFCOUNTING(QCefQueryHandler); 43 | }; 44 | 45 | #endif -------------------------------------------------------------------------------- /src/QCefView/QCefEvent.cpp: -------------------------------------------------------------------------------- 1 | #pragma region qt_headers 2 | #include 3 | #pragma endregion qt_headers 4 | 5 | #pragma region cef_headers 6 | #include 7 | #include 8 | #pragma endregion cef_headers 9 | 10 | #include "Include/QCefEvent.h" 11 | 12 | QCefEvent::QCefEvent() 13 | : QObject(nullptr) 14 | {} 15 | 16 | QCefEvent::QCefEvent(const QString& name) 17 | : QObject() 18 | { 19 | setObjectName(name); 20 | } 21 | 22 | void 23 | QCefEvent::setEventName(const QString& name) 24 | { 25 | setObjectName(name); 26 | } 27 | 28 | void 29 | QCefEvent::setIntProperty(const QString& key, int value) 30 | { 31 | Q_ASSERT(0 != QString::compare(key, "name", Qt::CaseInsensitive)); 32 | setProperty(key.toUtf8().constData(), QVariant::fromValue(value)); 33 | } 34 | 35 | void 36 | QCefEvent::setDoubleProperty(const QString& key, double value) 37 | { 38 | Q_ASSERT(0 != QString::compare(key, "name", Qt::CaseInsensitive)); 39 | setProperty(key.toUtf8().constData(), QVariant::fromValue(value)); 40 | } 41 | 42 | void 43 | QCefEvent::setStringProperty(const QString& key, const QString& value) 44 | { 45 | Q_ASSERT(0 != QString::compare(key, "name", Qt::CaseInsensitive)); 46 | setProperty(key.toUtf8().constData(), QVariant::fromValue(value)); 47 | } 48 | 49 | void 50 | QCefEvent::setBoolProperty(const QString& key, bool value) 51 | { 52 | Q_ASSERT(0 != QString::compare(key, "name", Qt::CaseInsensitive)); 53 | setProperty(key.toUtf8().constData(), QVariant::fromValue(value)); 54 | } 55 | -------------------------------------------------------------------------------- /src/QCefView/CCefSetting.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | #include "CCefSetting.h" 7 | 8 | CefString CCefSetting::bridge_object_name; 9 | 10 | CefString CCefSetting::browser_sub_process_path; 11 | 12 | CefString CCefSetting::resource_directory_path; 13 | 14 | CefString CCefSetting::locales_directory_path; 15 | 16 | CefString CCefSetting::user_agent; 17 | 18 | CefString CCefSetting::cache_path; 19 | 20 | CefString CCefSetting::user_data_path; 21 | 22 | int CCefSetting::persist_session_cookies; 23 | 24 | int CCefSetting::persist_user_preferences; 25 | 26 | CefString CCefSetting::locale; 27 | 28 | int CCefSetting::remote_debugging_port; 29 | 30 | cef_color_t CCefSetting::background_color; 31 | 32 | CefString CCefSetting::accept_language_list; 33 | 34 | std::list CCefSetting::global_cookie_list; 35 | 36 | void 37 | CCefSetting::initializeInstance() 38 | { 39 | static CCefSetting s_instance; 40 | } 41 | 42 | CCefSetting::CCefSetting() 43 | { 44 | QDir ExeDir = qApp->applicationDirPath(); 45 | 46 | QString strExePath = ExeDir.filePath(RENDER_PROCESS_NAME); 47 | browser_sub_process_path.FromString(QDir::toNativeSeparators(strExePath).toStdString()); 48 | 49 | QString strResPath = ExeDir.filePath(RESOURCE_DIRECTORY_NAME); 50 | resource_directory_path.FromString(QDir::toNativeSeparators(strResPath).toStdString()); 51 | 52 | QDir ResPath(strResPath); 53 | locales_directory_path.FromString(QDir::toNativeSeparators(ResPath.filePath(LOCALES_DIRECTORY_NAME)).toStdString()); 54 | 55 | user_agent.FromString(QCEF_USER_AGENT); 56 | } 57 | -------------------------------------------------------------------------------- /src/QCefWing/QCefWing.cpp: -------------------------------------------------------------------------------- 1 | #ifdef _WIN32 2 | #pragma region windows_headers 3 | #include 4 | #include 5 | #pragma endregion windows_headers 6 | #endif 7 | 8 | #pragma region cef_headers 9 | #include 10 | #pragma endregion cef_headers 11 | 12 | #pragma region project_heasers 13 | #include 14 | #include "CefViewRenderApp/QCefViewRenderApp.h" 15 | #include "QCefWing.h" 16 | #pragma endregion project_heasers 17 | 18 | #ifdef _WIN32 19 | int APIENTRY 20 | _tWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPTSTR lpCmdLine, _In_ int nCmdShow) 21 | { 22 | UNREFERENCED_PARAMETER(hPrevInstance); 23 | UNREFERENCED_PARAMETER(lpCmdLine); 24 | 25 | CefEnableHighDPISupport(); 26 | 27 | CefString bridgeObjectName = QCEF_OBJECT_NAME; 28 | CefRefPtr command_line = CefCommandLine::CreateCommandLine(); 29 | command_line->InitFromString(lpCmdLine); 30 | if (command_line->HasSwitch(QCEF_BRIDGE_OBJ_NAME_KEY)) { 31 | bridgeObjectName = command_line->GetSwitchValue(QCEF_BRIDGE_OBJ_NAME_KEY); 32 | if (bridgeObjectName.empty()) 33 | bridgeObjectName = QCEF_OBJECT_NAME; 34 | } 35 | 36 | CefRefPtr app(new QCefViewRenderApp(bridgeObjectName)); 37 | CefMainArgs main_args(hInstance); 38 | void* sandboxInfo = nullptr; 39 | return CefExecuteProcess(main_args, app, sandboxInfo); 40 | } 41 | #else // _WIN32 42 | int 43 | main(int argc, char* argv[]) 44 | { 45 | CefEnableHighDPISupport(); 46 | 47 | CefRefPtr app(new QCefViewRenderApp); 48 | CefMainArgs main_args(); 49 | void* sandboxInfo = nullptr; 50 | return CefExecuteProcess(main_args, app.get(), sandboxInfo); 51 | } 52 | #endif // _WIN32 53 | -------------------------------------------------------------------------------- /src/QCefView/Include/QCefEvent.h: -------------------------------------------------------------------------------- 1 | #ifndef QCEFEVENT_H 2 | #define QCEFEVENT_H 3 | #pragma once 4 | 5 | #pragma region qt_headers 6 | #include 7 | #include 8 | #include 9 | #pragma endregion qt_headers 10 | 11 | #ifdef QCEFVIEW_LIB 12 | #define QCEFVIEW_EXPORT Q_DECL_EXPORT 13 | #else 14 | #define QCEFVIEW_EXPORT Q_DECL_IMPORT 15 | #if _WIN32 16 | #pragma comment(lib, "QCefView.lib") 17 | #endif 18 | #endif 19 | 20 | /// 21 | /// 22 | /// 23 | class QCEFVIEW_EXPORT QCefEvent : public QObject 24 | { 25 | Q_OBJECT 26 | 27 | public: 28 | /// 29 | /// 30 | /// 31 | QCefEvent(); 32 | 33 | /// 34 | /// 35 | /// 36 | /// 37 | QCefEvent(const QString& name); 38 | 39 | /// 40 | /// 41 | /// 42 | /// 43 | void setEventName(const QString& name); 44 | 45 | /// 46 | /// 47 | /// 48 | /// 49 | /// 50 | void setIntProperty(const QString& key, int value); 51 | 52 | /// 53 | /// 54 | /// 55 | /// 56 | /// 57 | void setDoubleProperty(const QString& key, double value); 58 | 59 | /// 60 | /// 61 | /// 62 | /// 63 | /// 64 | void setStringProperty(const QString& key, const QString& value); 65 | 66 | /// 67 | /// 68 | /// 69 | /// 70 | /// 71 | void setBoolProperty(const QString& key, bool value); 72 | }; 73 | 74 | #endif // QCEFEVENT_H 75 | -------------------------------------------------------------------------------- /src/QCefView/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.4.1) 2 | project(${QCEF_VIEW_DLL}) 3 | 4 | set_property(GLOBAL PROPERTY AUTOGEN_SOURCE_GROUP "Generated Files") 5 | set(CMAKE_AUTOMOC ON) 6 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 7 | find_package(Qt5 COMPONENTS Core GUI Widgets REQUIRED) 8 | 9 | SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${QCEF_VIEW_SDK_LIB_OUT}) 10 | SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${QCEF_VIEW_SDK_LIB_OUT}) 11 | 12 | file(GLOB_RECURSE _SRC_FILES 13 | "*.cpp" 14 | "*.h" 15 | ) 16 | source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Source FILES ${_SRC_FILES}) 17 | 18 | if (OS_WINDOWS) 19 | file(GLOB _RES_FILES 20 | "*.rc" 21 | ) 22 | source_group(Resource ${_RES_FILES}) 23 | endif() 24 | 25 | add_library(${PROJECT_NAME} SHARED 26 | ${_SRC_FILES} 27 | ${_RES_FILES} 28 | ) 29 | 30 | if (OS_WINDOWS) 31 | target_compile_definitions(${PROJECT_NAME} PRIVATE 32 | UNICODE 33 | _UNICODE 34 | QCEFVIEW_LIB 35 | ) 36 | endif() 37 | 38 | target_link_libraries(${PROJECT_NAME} PRIVATE 39 | Qt5::Core 40 | Qt5::Gui 41 | Qt5::Widgets 42 | ${CEF_DLL_WRAPPER} 43 | ${CEF_LIB_FILE} 44 | ) 45 | 46 | add_dependencies(${PROJECT_NAME} ${QCEF_WING_EXE}) 47 | 48 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD 49 | COMMAND ${CMAKE_COMMAND} -E copy_directory ${CEF_RESOURCE_DIR} $/resources 50 | COMMAND ${CMAKE_COMMAND} -E copy $/resources/icudtl.dat $ 51 | COMMAND ${CMAKE_COMMAND} -E remove $/resources/icudtl.dat 52 | COMMAND ${CMAKE_COMMAND} -E copy_directory ${CEF_BINARY_DIR} $ 53 | COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/Include ${QCEF_VIEW_SDK_INC_OUT} 54 | ) -------------------------------------------------------------------------------- /src/QCefView/CCefManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #pragma region std_headers 4 | #include 5 | #pragma endregion std_headers 6 | 7 | #pragma region qt_headers 8 | #include 9 | #include 10 | #include 11 | #include 12 | #pragma endregion qt_headers 13 | 14 | #include "CefViewBrowserApp/QCefViewBrowserApp.h" 15 | 16 | /// 17 | /// 18 | /// 19 | class CCefManager : public QObject 20 | { 21 | Q_OBJECT 22 | 23 | protected: 24 | /// 25 | /// 26 | /// 27 | CCefManager(); 28 | 29 | /// 30 | /// 31 | /// 32 | ~CCefManager(){}; 33 | 34 | public: 35 | /// 36 | /// 37 | /// 38 | /// 39 | static CCefManager& getInstance(); 40 | 41 | /// 42 | /// 43 | /// 44 | void initializeCef(); 45 | 46 | /// 47 | /// 48 | /// 49 | /// 50 | /// 51 | /// 52 | /// 53 | /// 54 | bool addCookie(const std::string& name, const std::string& value, const std::string& domain, const std::string& url); 55 | 56 | /// 57 | /// 58 | /// 59 | void uninitializeCef(); 60 | 61 | protected slots: 62 | /// 63 | /// 64 | /// 65 | void releaseCef(); 66 | 67 | private: 68 | /// 69 | /// 70 | /// 71 | CefRefPtr app_; 72 | 73 | /// 74 | /// 75 | /// 76 | CefSettings cef_settings_; 77 | 78 | /// 79 | /// 80 | /// 81 | int64_t nBrowserRefCount_; 82 | }; 83 | -------------------------------------------------------------------------------- /src/QCefView/CefViewBrowserApp/QCefQueryHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "QCefQueryHandler.h" 2 | 3 | #include "Include/QCefQuery.h" 4 | 5 | QCefQueryHandler::QCefQueryHandler(QCefViewDelegate* pDelegate) 6 | : pQcefViewDelegate_(pDelegate) 7 | {} 8 | 9 | QCefQueryHandler::~QCefQueryHandler() 10 | { 11 | pQcefViewDelegate_ = nullptr; 12 | } 13 | 14 | bool 15 | QCefQueryHandler::OnQuery(CefRefPtr browser, 16 | CefRefPtr frame, 17 | int64 query_id, 18 | const CefString& request, 19 | bool persistent, 20 | CefRefPtr callback) 21 | { 22 | if (pQcefViewDelegate_) { 23 | mtxCallbackMap_.lock(); 24 | mapCallback_[query_id] = callback; 25 | mtxCallbackMap_.unlock(); 26 | 27 | pQcefViewDelegate_->onQCefQueryRequest(request, query_id); 28 | 29 | return true; 30 | } 31 | 32 | return false; 33 | } 34 | 35 | void 36 | QCefQueryHandler::OnQueryCanceled(CefRefPtr browser, CefRefPtr frame, int64 query_id) 37 | { 38 | mtxCallbackMap_.lock(); 39 | auto it = mapCallback_.find(query_id); 40 | if (it != mapCallback_.end()) 41 | mapCallback_.erase(it); 42 | 43 | mtxCallbackMap_.unlock(); 44 | } 45 | 46 | bool 47 | QCefQueryHandler::Response(int64_t query, bool success, const CefString& response, int error) 48 | { 49 | CefRefPtr cb; 50 | mtxCallbackMap_.lock(); 51 | auto it = mapCallback_.find(query); 52 | if (it != mapCallback_.end()) { 53 | cb = it->second; 54 | mapCallback_.erase(it); 55 | } 56 | mtxCallbackMap_.unlock(); 57 | 58 | if (!cb) 59 | return false; 60 | 61 | if (success) 62 | cb->Success(response); 63 | else 64 | cb->Failure(error, response); 65 | 66 | return true; 67 | } 68 | -------------------------------------------------------------------------------- /src/QCefView/QCefQuery.cpp: -------------------------------------------------------------------------------- 1 | #pragma region qt_headers 2 | #pragma endregion qt_headers 3 | 4 | #pragma region cef_headers 5 | #include 6 | #include 7 | #pragma endregion cef_headers 8 | 9 | #include "Include/QCefQuery.h" 10 | #include "Include/QCefView.h" 11 | 12 | int QCefQuery::TYPEID = qRegisterMetaType("QCefQuery"); 13 | 14 | ////////////////////////////////////////////////////////////////////////// 15 | QCefQuery::QCefQuery(QString req, int64_t query) 16 | : reqeust_(req) 17 | , id_(query) 18 | , restult_(false) 19 | , error_(0) 20 | {} 21 | 22 | QCefQuery::QCefQuery() 23 | : id_(-1) 24 | , restult_(false) 25 | , error_(0) 26 | {} 27 | 28 | QCefQuery::QCefQuery(const QCefQuery& other) 29 | { 30 | reqeust_ = other.reqeust_; 31 | id_ = other.id_; 32 | restult_ = other.restult_; 33 | response_ = other.response_; 34 | } 35 | 36 | QCefQuery& 37 | QCefQuery::operator=(const QCefQuery& other) 38 | { 39 | reqeust_ = other.reqeust_; 40 | id_ = other.id_; 41 | restult_ = other.restult_; 42 | response_ = other.response_; 43 | return *this; 44 | } 45 | 46 | QCefQuery::~QCefQuery() {} 47 | 48 | const QString 49 | QCefQuery::reqeust() const 50 | { 51 | return reqeust_; 52 | } 53 | 54 | const int64_t 55 | QCefQuery::id() const 56 | { 57 | return id_; 58 | } 59 | 60 | const QString 61 | QCefQuery::response() const 62 | { 63 | return response_; 64 | } 65 | 66 | const bool 67 | QCefQuery::result() const 68 | { 69 | return restult_; 70 | } 71 | 72 | const int 73 | QCefQuery::error() const 74 | { 75 | return error_; 76 | } 77 | 78 | void 79 | QCefQuery::setResponseResult(bool success, const QString& response, int error /*= 0*/) const 80 | { 81 | restult_ = success; 82 | response_ = response; 83 | error_ = error; 84 | } 85 | -------------------------------------------------------------------------------- /config.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Build environment configuration file for QCefView 3 | # 4 | 5 | ################################################################################# 6 | # 7 | # The Qt SDK path 8 | # 9 | set(QT_SDK_DIR 10 | # Change this value to the Qt SDK path of your build environment 11 | "$ENV{QTDIR}" 12 | ) 13 | 14 | # 15 | # For CI system 16 | # 17 | if (DEFINED ENV{APPVEYOR}) 18 | set(QT_SDK_DIR 19 | # Change this value to the Qt SDK path of your build environment 20 | "C:\\Qt\\5.15.2\\msvc2019_64" 21 | ) 22 | endif() 23 | 24 | # 25 | # The link for downloading the CEF binary sdk 26 | # 27 | set(CEF_SDK_URL 28 | # Change this value to swith between different CEF versions. 29 | "https://cef-builds.spotifycdn.com/cef_binary_89.0.12%2Bg2b76680%2Bchromium-89.0.4389.90_windows64.tar.bz2" 30 | ) 31 | 32 | 33 | #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 34 | # Usually, there is NO NEED to modify the following config 35 | # 36 | # Download CEF binary package 37 | # 38 | set (CEF_SDK_PACKAGE "${CMAKE_CURRENT_SOURCE_DIR}/dep/cef_package.tar.bz2") 39 | if(NOT EXISTS "${CEF_SDK_PACKAGE}") 40 | file(DOWNLOAD 41 | "${CEF_SDK_URL}" # URL 42 | "${CEF_SDK_PACKAGE}" # Local Path 43 | SHOW_PROGRESS 44 | TLS_VERIFY ON) 45 | endif() 46 | 47 | # 48 | # Extact the CEF SDK dir 49 | # 50 | file(GLOB CEF_SDK_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dep/cef_binary_*") 51 | 52 | # 53 | # Extract CEF binary package 54 | # 55 | if (NOT EXISTS ${CEF_SDK_DIR}) 56 | message(STATUS "CEF SDK dir does not exist, extracting new one....") 57 | 58 | # Extract 59 | file(ARCHIVE_EXTRACT 60 | INPUT "${CEF_SDK_PACKAGE}" 61 | DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}/dep") 62 | 63 | # Capture the dir name 64 | file(GLOB CEF_SDK_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dep/cef_binary_*") 65 | endif() 66 | 67 | # output 68 | message(STATUS "CEF SDK dir: ${CEF_SDK_DIR}") 69 | -------------------------------------------------------------------------------- /src/QCefProto/QCefProtocol.h: -------------------------------------------------------------------------------- 1 | #ifndef QCEFCOMMON_H 2 | #define QCEFCOMMON_H 3 | #if defined(_MSVC_) && _MSC_VER > 1000 4 | #pragma once 5 | #endif // _MSC_VER > 1000 6 | 7 | /// 8 | /// 9 | /// 10 | #define QCEF_SCHEMA "qcef" 11 | 12 | /// 13 | /// 14 | /// 15 | #define QCEF_QUERY_NAME "QCefQuery" 16 | 17 | /// 18 | /// 19 | /// 20 | #define QCEF_QUERY_CANCEL_NAME "QCefQueryCancel" 21 | 22 | /// 23 | /// 24 | /// 25 | #define QCEF_OBJECT_NAME "QCefClient" 26 | 27 | /// 28 | /// 29 | /// 30 | #define QCEF_BRIDGE_OBJ_NAME_KEY "bridge-obj-name" 31 | 32 | /// 33 | /// QCefClient.invokeMethod("method_name", ...) 34 | /// 35 | #define QCEF_INVOKEMETHOD "invokeMethod" 36 | 37 | /// 38 | /// QCefClient.addEventListener(type, listener) 39 | /// 40 | #define QCEF_ADDEVENTLISTENER "addEventListener" 41 | 42 | /// 43 | /// QCefClient.removeEventListener(type, listener) 44 | /// 45 | #define QCEF_REMOVEEVENTLISTENER "removeEventListener" 46 | 47 | /// 48 | /// this message is sent from render process to browser process 49 | /// and is processed in the Qt UI thread 50 | /// 51 | /// format 52 | /// msg.name 53 | /// msg.arg[0]: frame id 54 | /// msg.arg[1]: function name 55 | /// msg.arg[2~...]: function parameters 56 | /// 57 | #define INVOKEMETHOD_NOTIFY_MESSAGE "QCefClient#InvokeMethodNotify" 58 | 59 | /// 60 | /// this message is sent from browser process to render process 61 | /// and is processed in the CefRenderer_Main thread 62 | /// 63 | /// format: 64 | /// msg.name: 65 | /// msg.arg[0]: frame id 66 | /// msg.arg[1]: function name 67 | /// msg.arg[2~...]: function parameters 68 | /// 69 | #define TRIGGEREVENT_NOTIFY_MESSAGE "QCefClient#TriggerEventNotify" 70 | 71 | /// 72 | /// 73 | /// 74 | #define RENDER_PROCESS_NAME "QCefWing.exe" 75 | 76 | /// 77 | /// 78 | /// 79 | #define RESOURCE_DIRECTORY_NAME "resources" 80 | 81 | /// 82 | /// 83 | /// 84 | #define LOCALES_DIRECTORY_NAME "locales" 85 | 86 | /// 87 | /// 88 | /// 89 | #define QCEF_USER_AGENT "START/1.0 (Windows; en-us)" 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /src/QCefView/CCefSetting.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #pragma region cef_headers 4 | #include 5 | #pragma endregion cef_headers 6 | 7 | /// 8 | /// 9 | /// 10 | class CCefSetting 11 | { 12 | protected: 13 | /// 14 | /// 15 | /// 16 | CCefSetting(); 17 | 18 | /// 19 | /// 20 | /// 21 | ~CCefSetting(){}; 22 | 23 | public: 24 | /// 25 | /// 26 | /// 27 | static void initializeInstance(); 28 | 29 | public: 30 | /// 31 | /// 32 | /// 33 | static CefString bridge_object_name; 34 | 35 | /// 36 | /// 37 | /// 38 | static CefString browser_sub_process_path; 39 | 40 | /// 41 | /// 42 | /// 43 | static CefString resource_directory_path; 44 | 45 | /// 46 | /// 47 | /// 48 | static CefString locales_directory_path; 49 | 50 | /// 51 | /// 52 | /// 53 | static CefString user_agent; 54 | 55 | /// 56 | /// 57 | /// 58 | static CefString cache_path; 59 | 60 | /// 61 | /// 62 | /// 63 | static CefString user_data_path; 64 | 65 | /// 66 | /// 67 | /// 68 | static int persist_session_cookies; 69 | 70 | /// 71 | /// 72 | /// 73 | static int persist_user_preferences; 74 | 75 | /// 76 | /// 77 | /// 78 | static CefString locale; 79 | 80 | /// 81 | /// 82 | /// 83 | static int remote_debugging_port; 84 | 85 | /// 86 | /// 87 | /// 88 | static cef_color_t background_color; 89 | 90 | /// 91 | /// 92 | /// 93 | static CefString accept_language_list; 94 | 95 | /// 96 | /// 97 | /// 98 | typedef struct CookieItem 99 | { 100 | std::string name; 101 | std::string value; 102 | std::string domain; 103 | std::string url; 104 | } CookieItem; 105 | static std::list global_cookie_list; 106 | }; 107 | -------------------------------------------------------------------------------- /test/QCefViewTest/customcefview.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "customcefview.h" 7 | 8 | CustomCefView::~CustomCefView() {} 9 | 10 | void 11 | CustomCefView::changeColor() 12 | { 13 | QColor color(QRandomGenerator::global()->generate()); 14 | 15 | QCefEvent event("colorChange"); 16 | event.setStringProperty("color", color.name()); 17 | broadcastEvent(event); 18 | } 19 | 20 | void 21 | CustomCefView::onDraggableRegionChanged(const QRegion& region) 22 | {} 23 | 24 | void 25 | CustomCefView::onQCefUrlRequest(const QString& url) 26 | { 27 | QString title("QCef Url Request"); 28 | QString text = QString("Current Thread: QT_UI\r\n" 29 | "Url: %1") 30 | .arg(url); 31 | 32 | QMetaObject::invokeMethod(this, [=]() { 33 | QMessageBox::information(this->window(), title, text); 34 | }, Qt::QueuedConnection); 35 | } 36 | 37 | void 38 | CustomCefView::onQCefQueryRequest(const QCefQuery& query) 39 | { 40 | QString title("QCef Query Request"); 41 | QString text = QString("Current Thread: QT_UI\r\n" 42 | "Query: %1") 43 | .arg(query.reqeust()); 44 | 45 | QMetaObject::invokeMethod(this, [=]() { 46 | QMessageBox::information(this->window(), title, text); 47 | }, Qt::QueuedConnection); 48 | 49 | QString response = query.reqeust().toUpper(); 50 | query.setResponseResult(true, response); 51 | responseQCefQuery(query); 52 | } 53 | 54 | void 55 | CustomCefView::onInvokeMethodNotify(int browserId, int frameId, const QString& method, const QVariantList& arguments) 56 | { 57 | if (0 == method.compare("onDragAreaMouseDown")) { 58 | HWND hWnd = ::GetAncestor((HWND)getCefWinId(), GA_ROOT); 59 | 60 | // get current mouse cursor position 61 | POINT pt; 62 | ::GetCursorPos(&pt); 63 | 64 | // in case the mouse is being captured, try to release it 65 | ::ReleaseCapture(); 66 | 67 | // simulate that the mouse left button is down on the title area 68 | ::SendMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, POINTTOPOINTS(pt)); 69 | return; 70 | } 71 | 72 | QString title("QCef InvokeMethod Notify"); 73 | QString text = QString("Current Thread: QT_UI\r\n" 74 | "Method: %1\r\n" 75 | "Arguments: ...") 76 | .arg(method); 77 | 78 | QMetaObject::invokeMethod(this, [=]() { 79 | QMessageBox::information(this->window(), title, text); 80 | }, Qt::QueuedConnection); 81 | } 82 | -------------------------------------------------------------------------------- /test/QCefViewTest/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.4.1) 2 | project(QCefViewTest) 3 | 4 | set_property(GLOBAL PROPERTY AUTOGEN_SOURCE_GROUP "Generated Files") 5 | set(CMAKE_AUTOMOC ON) 6 | set(CMAKE_AUTOUIC ON) 7 | set(CMAKE_AUTORCC ON) 8 | 9 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 10 | find_package(Qt5 COMPONENTS Core GUI Widgets REQUIRED) 11 | 12 | include_directories( 13 | ${CMAKE_SOURCE_DIR}/out/${QCEF_VIEW_DLL} 14 | ) 15 | 16 | file(GLOB_RECURSE _SRC_FILES 17 | "*.h" 18 | "*.cpp" 19 | ) 20 | 21 | file(GLOB_RECURSE _UI_FILES 22 | "*.ui" 23 | ) 24 | source_group("Form Files" ${_UI_FILES}) 25 | 26 | if (OS_WINDOWS) 27 | file(GLOB_RECURSE _RES_FILES 28 | "*.qrc" 29 | "*.rc" 30 | ) 31 | source_group("Resource Files" ${_RES_FILES}) 32 | endif() 33 | 34 | SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/out/${PROJECT_NAME}) 35 | 36 | add_executable(${PROJECT_NAME} WIN32 37 | ${_SRC_FILES} 38 | ${_UI_FILES} 39 | ${_RES_FILES} 40 | ) 41 | 42 | if (OS_WINDOWS) 43 | target_compile_definitions(${PROJECT_NAME} PRIVATE 44 | UNICODE 45 | _UNICODE 46 | ) 47 | set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER Test) 48 | set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME}) 49 | endif() 50 | 51 | target_link_libraries(${PROJECT_NAME} PUBLIC 52 | Qt5::Core 53 | Qt5::Gui 54 | Qt5::Widgets 55 | ${QCEF_VIEW_DLL} 56 | ) 57 | 58 | # Embed the manifest file into the target 59 | if (MSVC) 60 | if (CMAKE_MAJOR_VERSION LESS 3) 61 | message(WARNING "CMake version 3.0 or newer is required use build variable TARGET_FILE") 62 | else() 63 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD 64 | COMMAND mt.exe -manifest \"${CMAKE_CURRENT_SOURCE_DIR}\\${PROJECT_NAME}.manifest\" -inputresource:\"$\" -outputresource:\"$\" 65 | ) 66 | endif() 67 | endif(MSVC) 68 | 69 | if (OS_WINDOWS) 70 | find_program(DEPLOYQT_EXECUTABLE windeployqt HINTS "${_qt_bin_dir}") 71 | elseif (OS_MACOS) 72 | find_program(DEPLOYQT_EXECUTABLE macdeployqt HINTS "${_qt_bin_dir}") 73 | elseif (OS_LINUX) 74 | else () 75 | endif() 76 | 77 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD 78 | COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/QCefViewTestPage.html $ 79 | COMMAND ${CMAKE_COMMAND} -E copy_directory ${QCEF_VIEW_SDK_BIN_OUT}/$ $ 80 | # Deploy the Qt Application 81 | COMMAND ${DEPLOYQT_EXECUTABLE} 82 | --no-svg 83 | --no-translations 84 | --no-compiler-runtime 85 | $ 86 | ) -------------------------------------------------------------------------------- /src/QCefView/CCefWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #pragma region qt_headers 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #pragma endregion qt_headers 11 | 12 | #pragma region cef_headers 13 | #include 14 | #pragma endregion cef_headers 15 | 16 | #include 17 | #include "CefViewBrowserApp/QCefViewDelegate.h" 18 | 19 | #include "Include/QCefQuery.h" 20 | #include "Include/QCefView.h" 21 | 22 | /// 23 | /// 24 | /// 25 | class CCefWindow 26 | : public QWindow 27 | , public QCefViewDelegate 28 | { 29 | Q_OBJECT 30 | 31 | public: 32 | /// 33 | /// 34 | /// 35 | 36 | public: 37 | /// 38 | /// 39 | /// 40 | /// 41 | explicit CCefWindow(QCefView* view = 0); 42 | 43 | /// 44 | /// 45 | /// 46 | ~CCefWindow(); 47 | 48 | virtual void setCefBrowserWindow(CefWindowHandle hwnd) override; 49 | 50 | virtual void onLoadingStateChanged(bool isLoading, bool canGoBack, bool canGoForward) override; 51 | 52 | virtual void onLoadStart() override; 53 | 54 | virtual void onLoadEnd(int httpStatusCode) override; 55 | 56 | virtual void onLoadError(int errorCode, 57 | const CefString& errorMsg, 58 | const CefString& failedUrl, 59 | bool& handled) override; 60 | 61 | virtual void onDraggableRegionChanged(const std::vector regions) override; 62 | 63 | virtual void onConsoleMessage(const CefString& message, int level) override; 64 | 65 | virtual void onTakeFocus(bool next) override; 66 | 67 | virtual void onQCefUrlRequest(const CefString& url) override; 68 | 69 | virtual void onQCefQueryRequest(const CefString& request, int64 query_id) override; 70 | 71 | virtual void onInvokeMethodNotify(int browserId, const CefRefPtr& arguments) override; 72 | 73 | public: 74 | /// 75 | /// 76 | /// 77 | void syncCefBrowserWindow(); 78 | 79 | /// 80 | /// 81 | /// 82 | /// 83 | virtual void exposeEvent(QExposeEvent* e); 84 | 85 | /// 86 | /// 87 | /// 88 | /// 89 | virtual void resizeEvent(QResizeEvent* e); 90 | 91 | private: 92 | /// 93 | /// 94 | /// 95 | QCefView* view_; 96 | 97 | /// 98 | /// 99 | /// 100 | CefWindowHandle hwndCefBrowser_; 101 | }; 102 | -------------------------------------------------------------------------------- /src/QCefView/Include/QCefQuery.h: -------------------------------------------------------------------------------- 1 | #ifndef QCEFQUERY_H 2 | #define QCEFQUERY_H 3 | #pragma once 4 | 5 | #pragma region std_headers 6 | #include 7 | #pragma endregion std_headers 8 | 9 | #pragma region qt_headers 10 | #include 11 | #include 12 | #include 13 | #include 14 | #pragma endregion qt_headers 15 | 16 | #ifdef QCEFVIEW_LIB 17 | #define QCEFVIEW_EXPORT Q_DECL_EXPORT 18 | #else 19 | #define QCEFVIEW_EXPORT Q_DECL_IMPORT 20 | #if _WIN32 21 | #pragma comment(lib, "QCefView.lib") 22 | #endif 23 | #endif 24 | 25 | /// 26 | /// 27 | /// 28 | class QCEFVIEW_EXPORT QCefQuery 29 | { 30 | public: 31 | /// 32 | /// 33 | /// 34 | QCefQuery(); 35 | 36 | /// 37 | /// 38 | /// 39 | /// 40 | /// 41 | QCefQuery(QString req, int64_t query); 42 | 43 | /// 44 | /// 45 | /// 46 | /// 47 | QCefQuery(const QCefQuery& other); 48 | 49 | /// 50 | /// 51 | /// 52 | /// 53 | /// 54 | QCefQuery& operator=(const QCefQuery& other); 55 | 56 | /// 57 | /// 58 | /// 59 | ~QCefQuery(); 60 | 61 | /// 62 | /// 63 | /// 64 | /// 65 | const QString reqeust() const; 66 | 67 | /// 68 | /// 69 | /// 70 | /// 71 | const int64_t id() const; 72 | 73 | /// 74 | /// 75 | /// 76 | /// 77 | const QString response() const; 78 | 79 | /// 80 | /// 81 | /// 82 | /// 83 | const bool result() const; 84 | 85 | /// 86 | /// 87 | /// 88 | /// 89 | const int error() const; 90 | 91 | /// 92 | /// 93 | /// 94 | /// 95 | /// 96 | /// 97 | void setResponseResult(bool success, const QString& response, int error = 0) const; 98 | 99 | private: 100 | /// 101 | /// 102 | /// 103 | int64_t id_; 104 | 105 | /// 106 | /// 107 | /// 108 | QString reqeust_; 109 | 110 | /// 111 | /// 112 | /// 113 | mutable QString response_; 114 | 115 | /// 116 | /// 117 | /// 118 | mutable bool restult_; 119 | 120 | /// 121 | /// 122 | /// 123 | mutable int error_; 124 | 125 | /// 126 | /// 127 | /// 128 | static int TYPEID; 129 | }; 130 | Q_DECLARE_METATYPE(QCefQuery); 131 | #endif // QCEFQUERY_H 132 | -------------------------------------------------------------------------------- /src/QCefView/CefViewBrowserApp/QCefViewBrowserApp.h: -------------------------------------------------------------------------------- 1 | #ifndef QCEFVIEWBROWSERAPP_H_ 2 | #define QCEFVIEWBROWSERAPP_H_ 3 | #pragma once 4 | 5 | #pragma region std_headers 6 | #include 7 | #pragma endregion std_headers 8 | 9 | #pragma region cef_headers 10 | #include 11 | #pragma endregion cef_headers 12 | 13 | class QCefViewBrowserApp 14 | : public CefApp 15 | , public CefBrowserProcessHandler 16 | { 17 | public: 18 | QCefViewBrowserApp(const CefString& name); 19 | ~QCefViewBrowserApp(); 20 | 21 | class BrowserDelegate : public virtual CefBaseRefCounted 22 | { 23 | public: 24 | virtual void OnContextInitialized(CefRefPtr app) {} 25 | 26 | virtual void OnBeforeChildProcessLaunch(CefRefPtr app, CefRefPtr command_line) 27 | {} 28 | }; 29 | typedef std::set> BrowserDelegateSet; 30 | 31 | private: 32 | // Creates all of the BrowserDelegate objects. Implemented in 33 | // client_app_delegates. 34 | static void CreateBrowserDelegates(BrowserDelegateSet& delegates); 35 | 36 | // Rigster custom schemes handler factories 37 | static void RegisterCustomSchemesHandlerFactories(); 38 | 39 | // Registers custom schemes. Implemented in client_app_delegates. 40 | static void RegisterCustomSchemes(CefRawPtr registrar); 41 | 42 | #pragma region CefApp 43 | 44 | ////////////////////////////////////////////////////////////////////////// 45 | // CefApp methods: 46 | virtual void OnBeforeCommandLineProcessing(const CefString& process_type, 47 | CefRefPtr command_line) override; 48 | 49 | virtual void OnRegisterCustomSchemes(CefRawPtr registrar) override; 50 | 51 | virtual CefRefPtr GetResourceBundleHandler() override; 52 | 53 | virtual CefRefPtr GetBrowserProcessHandler() override; 54 | 55 | virtual CefRefPtr GetRenderProcessHandler() override; 56 | 57 | #pragma endregion CefApp 58 | 59 | #pragma region CefBrowserProcessHandler 60 | 61 | // CefBrowserProcessHandler methods: 62 | virtual void OnContextInitialized() override; 63 | 64 | virtual void OnBeforeChildProcessLaunch(CefRefPtr command_line) override; 65 | 66 | virtual CefRefPtr GetPrintHandler() override; 67 | 68 | virtual void OnScheduleMessagePumpWork(int64 delay_ms) override; 69 | 70 | #pragma endregion CefBrowserProcessHandler 71 | 72 | private: 73 | CefString bridge_object_name_; 74 | 75 | // Set of supported BrowserDelegates. Only used in the browser process. 76 | BrowserDelegateSet browser_delegates_; 77 | 78 | // Include the default reference counting implementation. 79 | IMPLEMENT_REFCOUNTING(QCefViewBrowserApp); 80 | }; 81 | 82 | #endif // QCEFVIEWBROWSERAPP_H_ 83 | -------------------------------------------------------------------------------- /src/QCefView/CefViewBrowserApp/SchemeHandlers/QCefViewDefaultSchemeHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #pragma region std_headers 4 | #include 5 | #include 6 | #include 7 | #pragma endregion std_headers 8 | 9 | #pragma region cef_headers 10 | #include 11 | #include 12 | #include 13 | #pragma endregion cef_headers 14 | 15 | #include 16 | 17 | #include "../QCefViewDelegate.h" 18 | 19 | namespace QCefViewDefaultSchemeHandler { 20 | static char* scheme_name = QCEF_SCHEMA; 21 | 22 | bool 23 | RegisterSchemeHandlerFactory(); 24 | 25 | bool 26 | RegisterScheme(CefRawPtr registrar); 27 | 28 | class SchemeHandler : public CefResourceHandler 29 | { 30 | public: 31 | SchemeHandler(QCefViewDelegate* pDelegate); 32 | 33 | virtual bool Open(CefRefPtr request, bool& handle_request, CefRefPtr callback) override; 34 | 35 | virtual bool ProcessRequest(CefRefPtr request, CefRefPtr callback) override; 36 | 37 | virtual void GetResponseHeaders(CefRefPtr response, 38 | int64& response_length, 39 | CefString& redirectUrl) override; 40 | 41 | virtual bool Skip(int64 bytes_to_skip, int64& bytes_skipped, CefRefPtr callback) override; 42 | 43 | virtual bool Read(void* data_out, 44 | int bytes_to_read, 45 | int& bytes_read, 46 | CefRefPtr callback) override; 47 | virtual bool ReadResponse(void* data_out, 48 | int bytes_to_read, 49 | int& bytes_read, 50 | CefRefPtr callback) override; 51 | 52 | virtual void Cancel() override; 53 | 54 | private: 55 | QCefViewDelegate* pQCefViewDelegate_; 56 | std::string data_; 57 | std::string mime_type_; 58 | int offset_; 59 | 60 | private: 61 | IMPLEMENT_REFCOUNTING(SchemeHandler); 62 | }; 63 | 64 | class SchemeHandlerFactory : public CefSchemeHandlerFactory 65 | { 66 | 67 | public: 68 | /// 69 | /// 70 | /// 71 | /// 72 | /// 73 | static void recordBrowserAndDelegate(CefRefPtr browser, QCefViewDelegate* pDelegate); 74 | 75 | /// 76 | /// 77 | /// 78 | /// 79 | static void removeBrowserAndDelegate(CefRefPtr browser); 80 | 81 | // Return a new scheme handler instance to handle the request. 82 | virtual CefRefPtr Create(CefRefPtr browser, 83 | CefRefPtr frame, 84 | const CefString& scheme_name, 85 | CefRefPtr request); 86 | 87 | private: 88 | static std::map mapBrowser2Delegate_; 89 | static std::mutex mtxMap_; 90 | 91 | private: 92 | IMPLEMENT_REFCOUNTING(SchemeHandlerFactory); 93 | }; 94 | } 95 | -------------------------------------------------------------------------------- /src/QCefView/CCefManager.cpp: -------------------------------------------------------------------------------- 1 | #pragma region cef_headers 2 | #include 3 | #pragma endregion cef_headers 4 | 5 | #include "CCefManager.h" 6 | #include "CCefSetting.h" 7 | 8 | CCefManager::CCefManager() 9 | { 10 | nBrowserRefCount_ = 0; 11 | } 12 | 13 | CCefManager& 14 | CCefManager::getInstance() 15 | { 16 | static CCefManager s_instance; 17 | return s_instance; 18 | } 19 | 20 | void 21 | CCefManager::initializeCef() 22 | { 23 | // This is not the first time initialization 24 | if (++nBrowserRefCount_ > 1) 25 | return; 26 | 27 | // Enable High-DPI support on Windows 7 or newer. 28 | CefEnableHighDPISupport(); 29 | 30 | // This is the first time initialization 31 | CCefSetting::initializeInstance(); 32 | 33 | CefString(&cef_settings_.browser_subprocess_path) = CCefSetting::browser_sub_process_path; 34 | CefString(&cef_settings_.resources_dir_path) = CCefSetting::resource_directory_path; 35 | CefString(&cef_settings_.locales_dir_path) = CCefSetting::locales_directory_path; 36 | CefString(&cef_settings_.user_agent) = CCefSetting::user_agent; 37 | CefString(&cef_settings_.cache_path) = CCefSetting::cache_path; 38 | CefString(&cef_settings_.user_data_path) = CCefSetting::user_data_path; 39 | CefString(&cef_settings_.locale) = CCefSetting::locale; 40 | CefString(&cef_settings_.accept_language_list) = CCefSetting::accept_language_list; 41 | 42 | cef_settings_.persist_session_cookies = CCefSetting::persist_session_cookies; 43 | cef_settings_.persist_user_preferences = CCefSetting::persist_user_preferences; 44 | cef_settings_.remote_debugging_port = CCefSetting::remote_debugging_port; 45 | cef_settings_.background_color = CCefSetting::background_color; 46 | cef_settings_.no_sandbox = true; 47 | cef_settings_.pack_loading_disabled = false; 48 | cef_settings_.multi_threaded_message_loop = true; 49 | 50 | #ifndef NDEBUG 51 | cef_settings_.log_severity = LOGSEVERITY_DEFAULT; 52 | cef_settings_.remote_debugging_port = CCefSetting::remote_debugging_port; 53 | #else 54 | cef_settings_.log_severity = LOGSEVERITY_DISABLE; 55 | #endif 56 | 57 | app_ = new QCefViewBrowserApp(CCefSetting::bridge_object_name); 58 | 59 | HINSTANCE hInstance = ::GetModuleHandle(nullptr); 60 | CefMainArgs main_args(hInstance); 61 | 62 | // Initialize CEF. 63 | void* sandboxInfo = nullptr; 64 | if (!CefInitialize(main_args, cef_settings_, app_, sandboxInfo)) 65 | assert(0); 66 | } 67 | 68 | bool 69 | CCefManager::addCookie(const std::string& name, 70 | const std::string& value, 71 | const std::string& domain, 72 | const std::string& url) 73 | { 74 | CefCookie cookie; 75 | CefString(&cookie.name).FromString(name); 76 | CefString(&cookie.value).FromString(value); 77 | CefString(&cookie.domain).FromString(domain); 78 | return CefCookieManager::GetGlobalManager(nullptr)->SetCookie(CefString(url), cookie, nullptr); 79 | } 80 | 81 | void 82 | CCefManager::uninitializeCef() 83 | { 84 | // This is not the last time release 85 | if (--nBrowserRefCount_ > 0) 86 | return; 87 | 88 | // Destroy the application 89 | app_ = nullptr; 90 | 91 | // The last time release 92 | // TO-DO (sheen) when we reach here, it is possible there are pending 93 | // IO requests, and they will fire the DCHECK when complete or aborted 94 | releaseCef(); 95 | } 96 | 97 | void 98 | CCefManager::releaseCef() 99 | { 100 | CefShutdown(); 101 | } 102 | -------------------------------------------------------------------------------- /src/QCefView/CefViewBrowserApp/QCefViewBrowserApp.cpp: -------------------------------------------------------------------------------- 1 | #pragma region std_headers 2 | #include 3 | #pragma endregion std_headers 4 | 5 | #pragma region cef_headers 6 | #include 7 | #include 8 | #include 9 | #pragma endregion cef_headers 10 | 11 | #include 12 | 13 | #include "QCefViewBrowserApp.h" 14 | 15 | QCefViewBrowserApp::QCefViewBrowserApp(const CefString& name) 16 | : bridge_object_name_(name) 17 | {} 18 | 19 | QCefViewBrowserApp::~QCefViewBrowserApp() {} 20 | 21 | ////////////////////////////////////////////////////////////////////////// 22 | void 23 | QCefViewBrowserApp::OnBeforeCommandLineProcessing(const CefString& process_type, CefRefPtr command_line) 24 | { 25 | command_line->AppendSwitch("disable-spell-checking"); 26 | command_line->AppendSwitch("disable-extensions"); 27 | command_line->AppendSwitch("disable-web-security"); 28 | command_line->AppendSwitch("disable-pdf-extension"); 29 | command_line->AppendSwitch("enable-direct-write"); 30 | command_line->AppendSwitch("allow-file-access-from-files"); 31 | command_line->AppendSwitch("no-proxy-server"); 32 | command_line->AppendSwitch("in-process-gpu"); 33 | command_line->AppendSwitch("disable-direct-composition"); 34 | command_line->AppendSwitchWithValue("disable-features", "NetworkService"); 35 | command_line->AppendSwitchWithValue("renderer-process-limit", "1"); 36 | command_line->AppendSwitchWithValue("disable-usb-keyboard-detect", "1"); 37 | } 38 | 39 | void 40 | QCefViewBrowserApp::OnRegisterCustomSchemes(CefRawPtr registrar) 41 | { 42 | RegisterCustomSchemes(registrar); 43 | } 44 | 45 | CefRefPtr 46 | QCefViewBrowserApp::GetResourceBundleHandler() 47 | { 48 | return nullptr; 49 | } 50 | 51 | CefRefPtr 52 | QCefViewBrowserApp::GetBrowserProcessHandler() 53 | { 54 | return this; 55 | } 56 | 57 | CefRefPtr 58 | QCefViewBrowserApp::GetRenderProcessHandler() 59 | { 60 | return nullptr; 61 | } 62 | 63 | ////////////////////////////////////////////////////////////////////////// 64 | void 65 | QCefViewBrowserApp::OnContextInitialized() 66 | { 67 | CEF_REQUIRE_UI_THREAD(); 68 | 69 | // create all browser delegates 70 | CreateBrowserDelegates(browser_delegates_); 71 | 72 | // Register cookieable schemes with the global cookie manager. 73 | CefRefPtr manager = CefCookieManager::GetGlobalManager(nullptr); 74 | DCHECK(manager.get()); 75 | typedef std::vector CookiableSchemeSet; 76 | CookiableSchemeSet cookieable_schemes_; 77 | manager->SetSupportedSchemes(cookieable_schemes_, true, nullptr); 78 | 79 | RegisterCustomSchemesHandlerFactories(); 80 | 81 | BrowserDelegateSet::iterator it = browser_delegates_.begin(); 82 | for (; it != browser_delegates_.end(); ++it) 83 | (*it)->OnContextInitialized(this); 84 | } 85 | 86 | void 87 | QCefViewBrowserApp::OnBeforeChildProcessLaunch(CefRefPtr command_line) 88 | { 89 | if (bridge_object_name_.empty()) 90 | bridge_object_name_ = QCEF_OBJECT_NAME; 91 | 92 | command_line->AppendSwitchWithValue(QCEF_BRIDGE_OBJ_NAME_KEY, bridge_object_name_); 93 | BrowserDelegateSet::iterator it = browser_delegates_.begin(); 94 | for (; it != browser_delegates_.end(); ++it) 95 | (*it)->OnBeforeChildProcessLaunch(this, command_line); 96 | } 97 | 98 | CefRefPtr 99 | QCefViewBrowserApp::GetPrintHandler() 100 | { 101 | return nullptr; 102 | } 103 | 104 | void 105 | QCefViewBrowserApp::OnScheduleMessagePumpWork(int64 delay_ms) 106 | {} 107 | -------------------------------------------------------------------------------- /src/QCefView/Include/QCefSetting.h: -------------------------------------------------------------------------------- 1 | #ifndef QCEFSETTINGS_H 2 | #define QCEFSETTINGS_H 3 | #pragma once 4 | 5 | #pragma region qt_headers 6 | #include 7 | #include 8 | #include 9 | #pragma endregion qt_headers 10 | 11 | #ifdef QCEFVIEW_LIB 12 | #define QCEFVIEW_EXPORT Q_DECL_EXPORT 13 | #else 14 | #define QCEFVIEW_EXPORT Q_DECL_IMPORT 15 | #if _WIN32 16 | #pragma comment(lib, "QCefView.lib") 17 | #endif 18 | #endif 19 | 20 | namespace QCefSetting { 21 | /// 22 | /// 23 | /// 24 | void QCEFVIEW_EXPORT 25 | setBrowserSubProcessPath(const QString& path); 26 | 27 | /// 28 | /// 29 | /// 30 | const QCEFVIEW_EXPORT QString 31 | browserSubProcessPath(); 32 | 33 | /// 34 | /// 35 | /// 36 | void QCEFVIEW_EXPORT 37 | setResourceDirectoryPath(const QString& path); 38 | 39 | /// 40 | /// 41 | /// 42 | const QCEFVIEW_EXPORT QString 43 | resourceDirectoryPath(); 44 | 45 | /// 46 | /// 47 | /// 48 | void QCEFVIEW_EXPORT 49 | setLocalesDirectoryPath(const QString& path); 50 | 51 | /// 52 | /// 53 | /// 54 | const QCEFVIEW_EXPORT QString 55 | localesDirectoryPath(); 56 | 57 | /// 58 | /// 59 | /// 60 | void QCEFVIEW_EXPORT 61 | setUserAgent(const QString& agent); 62 | 63 | /// 64 | /// 65 | /// 66 | const QCEFVIEW_EXPORT QString 67 | userAgent(); 68 | 69 | /// 70 | /// 71 | /// 72 | void QCEFVIEW_EXPORT 73 | setCachePath(const QString& path); 74 | 75 | /// 76 | /// 77 | /// 78 | const QCEFVIEW_EXPORT QString 79 | cachePath(); 80 | 81 | /// 82 | /// 83 | /// 84 | void QCEFVIEW_EXPORT 85 | setUserDataPath(const QString& path); 86 | 87 | /// 88 | /// 89 | /// 90 | const QCEFVIEW_EXPORT QString 91 | userDataPath(); 92 | 93 | /// 94 | /// 95 | /// 96 | void QCEFVIEW_EXPORT 97 | setBridgeObjectName(const QString& name); 98 | 99 | /// 100 | /// 101 | /// 102 | const QCEFVIEW_EXPORT QString 103 | bridgeObjectName(); 104 | 105 | /// 106 | /// 107 | /// 108 | void QCEFVIEW_EXPORT 109 | setPersistSessionCookies(bool enabled); 110 | 111 | /// 112 | /// 113 | /// 114 | const QCEFVIEW_EXPORT bool 115 | persistSessionCookies(); 116 | 117 | /// 118 | /// 119 | /// 120 | void QCEFVIEW_EXPORT 121 | setPersistUserPreferences(bool enabled); 122 | 123 | /// 124 | /// 125 | /// 126 | const QCEFVIEW_EXPORT bool 127 | persistUserPreferences(); 128 | 129 | /// 130 | /// 131 | /// 132 | void QCEFVIEW_EXPORT 133 | setLocale(const QString& locale); 134 | 135 | /// 136 | /// 137 | /// 138 | const QCEFVIEW_EXPORT QString 139 | locale(); 140 | 141 | /// 142 | /// 143 | /// 144 | void QCEFVIEW_EXPORT 145 | setRemoteDebuggingPort(int port); 146 | 147 | /// 148 | /// 149 | /// 150 | const QCEFVIEW_EXPORT int 151 | remoteDebuggingPort(); 152 | 153 | /// 154 | /// 155 | /// 156 | void QCEFVIEW_EXPORT 157 | setBackgroundColor(const QColor& color); 158 | 159 | /// 160 | /// 161 | /// 162 | const QCEFVIEW_EXPORT QColor 163 | backgroundColor(); 164 | 165 | /// 166 | /// 167 | /// 168 | void QCEFVIEW_EXPORT 169 | setAcceptLanguageList(const QString& languages); 170 | 171 | /// 172 | /// 173 | /// 174 | const QCEFVIEW_EXPORT QString 175 | acceptLanguageList(); 176 | 177 | /// 178 | /// 179 | /// 180 | void QCEFVIEW_EXPORT 181 | setGlobalCookie(const QString& name, const QString& value, const QString& domain, const QString& url); 182 | 183 | }; 184 | 185 | #endif 186 | -------------------------------------------------------------------------------- /test/QCefViewTest/QCefViewTestPage.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 78 | 79 | 80 | 81 |

Web Area

82 |
83 | you can drag this window in this area! 84 |
85 |
86 | 87 |
88 | 89 |
90 |
91 | 92 | 93 |
94 | 95 |
96 | 97 |
98 |
99 | 100 | 101 |
102 | qcef://test/a/b 103 | 104 |
105 |
106 | 107 |
108 | 109 | 110 | -------------------------------------------------------------------------------- /src/QCefWing/CefViewRenderApp/RenderDelegates/QCefViewDefaultRenderDelegate.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma region std_headers 3 | #include 4 | #pragma endregion 5 | 6 | #pragma region cef_headers 7 | #include 8 | #pragma endregion cef_headers 9 | 10 | #pragma region project_headers 11 | #include "../QCefViewRenderApp.h" 12 | #include "QCefClient.h" 13 | #pragma endregion project_headers 14 | 15 | namespace QCefViewDefaultRenderDelegate { 16 | /// 17 | /// 18 | /// 19 | void 20 | CreateBrowserDelegate(QCefViewRenderApp::RenderDelegateSet& delegates, const CefString& name); 21 | 22 | /// 23 | /// 24 | /// 25 | class RenderDelegate : public QCefViewRenderApp::RenderDelegate 26 | { 27 | /// 28 | /// 29 | /// 30 | typedef std::unordered_map> FrameID2QCefClientMap; 31 | 32 | public: 33 | /// 34 | /// 35 | /// 36 | RenderDelegate(const CefString& name); 37 | 38 | /// 39 | /// 40 | /// 41 | /// 42 | virtual void OnWebKitInitialized(CefRefPtr app); 43 | 44 | /// 45 | /// 46 | /// 47 | /// 48 | /// 49 | /// 50 | /// 51 | virtual void OnContextCreated(CefRefPtr app, 52 | CefRefPtr browser, 53 | CefRefPtr frame, 54 | CefRefPtr context); 55 | 56 | /// 57 | /// 58 | /// 59 | /// 60 | /// 61 | /// 62 | /// 63 | virtual void OnContextReleased(CefRefPtr app, 64 | CefRefPtr browser, 65 | CefRefPtr frame, 66 | CefRefPtr context); 67 | 68 | /// 69 | /// 70 | /// 71 | /// 72 | /// 73 | /// 74 | /// 75 | /// 76 | virtual bool OnProcessMessageReceived(CefRefPtr app, 77 | CefRefPtr browser, 78 | CefRefPtr frame, 79 | CefProcessId source_process, 80 | CefRefPtr message); 81 | 82 | protected: 83 | /// 84 | /// 85 | /// 86 | /// 87 | /// 88 | /// 89 | /// 90 | /// 91 | bool OnTriggerEventNotifyMessage(CefRefPtr browser, 92 | CefRefPtr frame, 93 | CefProcessId source_process, 94 | CefRefPtr message); 95 | 96 | /// 97 | /// 98 | /// 99 | /// 100 | /// 101 | /// 102 | /// 103 | void ExecuteEventListener(CefRefPtr browser, 104 | CefRefPtr frame, 105 | const CefString& name, 106 | CefRefPtr dict); 107 | 108 | private: 109 | /// 110 | /// 111 | /// 112 | CefString bridge_object_name_; 113 | 114 | /// 115 | /// 116 | /// 117 | CefRefPtr render_message_router_; 118 | 119 | /// 120 | /// 121 | /// 122 | FrameID2QCefClientMap frame_id_to_client_map_; 123 | 124 | private: 125 | IMPLEMENT_REFCOUNTING(RenderDelegate); 126 | }; 127 | 128 | } 129 | -------------------------------------------------------------------------------- /test/QCefViewTest/qcefviewtest.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | QCefViewTestClass 4 | 5 | 6 | 7 | 0 8 | 0 9 | 600 10 | 400 11 | 12 | 13 | 14 | QCefViewTest 15 | 16 | 17 | 18 | #centralWidget { 19 | background-color: rgb(0, 85, 0); 20 | } 21 | 22 | 23 | 24 | 25 | 20 26 | 19 27 | 120 28 | 361 29 | 30 | 31 | 32 | 33 | 0 34 | 0 35 | 36 | 37 | 38 | 39 | 120 40 | 0 41 | 42 | 43 | 44 | 45 | 120 46 | 16777215 47 | 48 | 49 | 50 | #nativeContainer { 51 | background-color: rgb(170, 255, 255); 52 | } 53 | 54 | 55 | 56 | 6 57 | 58 | 59 | 0 60 | 61 | 62 | 0 63 | 64 | 65 | 0 66 | 67 | 68 | 0 69 | 70 | 71 | 72 | 73 | #label{ 74 | font: 12pt "MS Shell Dlg 2"; 75 | } 76 | 77 | 78 | Native Area 79 | 80 | 81 | Qt::AlignCenter 82 | 83 | 84 | 85 | 86 | 87 | 88 | ChangeColor 89 | 90 | 91 | 92 | 93 | 94 | 95 | Qt::Vertical 96 | 97 | 98 | 99 | 20 100 | 40 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 230 111 | 20 112 | 331 113 | 351 114 | 115 | 116 | 117 | #cefContainer { 118 | background-color: rgb(85, 170, 255); 119 | } 120 | 121 | 122 | 123 | 0 124 | 125 | 126 | 0 127 | 128 | 129 | 0 130 | 131 | 132 | 0 133 | 134 | 135 | 0 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # The main config file for QCefView 3 | # NOTE: 4 | # Usually there is no need to change this file. 5 | # Change the config.cmake instead. 6 | # 7 | cmake_minimum_required(VERSION 3.18) 8 | project(QCefView) 9 | 10 | # Determine the platform. 11 | if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") 12 | set(OS_MACOSX 1) 13 | set(OS_POSIX 1) 14 | elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") 15 | set(OS_LINUX 1) 16 | set(OS_POSIX 1) 17 | elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows") 18 | set(OS_WINDOWS 1) 19 | endif() 20 | 21 | # Determine the project architecture. 22 | if(NOT DEFINED PROJECT_ARCH) 23 | if(CMAKE_SIZEOF_VOID_P MATCHES 8) 24 | set(PROJECT_ARCH "x86_64") 25 | else() 26 | set(PROJECT_ARCH "x86") 27 | endif() 28 | 29 | if(OS_MACOSX) 30 | # PROJECT_ARCH should be specified on Mac OS X. 31 | message(WARNING "No PROJECT_ARCH value specified, using ${PROJECT_ARCH}") 32 | endif() 33 | endif() 34 | 35 | # Set common configurations 36 | ############################################################### 37 | # Use solution folder 38 | set_property(GLOBAL PROPERTY USE_FOLDERS ON) 39 | set(CMAKE_CXX_STANDARD 11) 40 | set(CXX_STANDARD_REQUIRED) 41 | set(CMAKE_CONFIGURATION_TYPES Debug Release) 42 | set(QCEF_VIEW_SDK_OUT ${CMAKE_SOURCE_DIR}/out/${PROJECT_NAME}) 43 | set(QCEF_VIEW_SDK_BIN_OUT ${CMAKE_SOURCE_DIR}/out/${PROJECT_NAME}/bin) 44 | set(QCEF_VIEW_SDK_LIB_OUT ${CMAKE_SOURCE_DIR}/out/${PROJECT_NAME}/lib) 45 | set(QCEF_VIEW_SDK_INC_OUT ${CMAKE_SOURCE_DIR}/out/${PROJECT_NAME}/include) 46 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${QCEF_VIEW_SDK_BIN_OUT}) 47 | ############################################################### 48 | 49 | # Include the local config files 50 | ############################################################### 51 | include(config.cmake) 52 | ############################################################### 53 | 54 | # Append the QT dir to CMAKE_PREFIX_PATH 55 | ############################################################### 56 | set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${QT_SDK_DIR}) 57 | ############################################################### 58 | 59 | 60 | # Set CEF root dir and append it to CMAKE_MODULE_PATH 61 | ############################################################### 62 | set(CEF_ROOT "${CEF_SDK_DIR}") 63 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CEF_ROOT}/cmake") 64 | ############################################################### 65 | 66 | 67 | # Config the CEF 68 | ############################################################### 69 | cmake_policy(SET CMP0074 NEW) 70 | cmake_policy(SET CMP0077 NEW) 71 | 72 | # Set the runtime library type 73 | set(CEF_RUNTIME_LIBRARY_FLAG "/MD" CACHE STRING "Use dynamic runtime") 74 | 75 | # Disable the SANDBOX 76 | set(USE_SANDBOX OFF CACHE BOOL "Disable the Sandbox") 77 | 78 | # Disable the ATL 79 | set(USE_ATL OFF CACHE STRING "Disable the ATL") 80 | 81 | # Find the CEF package 82 | find_package(CEF REQUIRED) 83 | 84 | # Store the libcef.lib path and cef dll wrapper target name 85 | # NOTE: we set this just for simplify the following referring. 86 | set(CEF_LIB_FILE "${CEF_BINARY_DIR}/libcef.lib") 87 | set(CEF_DLL_WRAPPER "libcef_dll_wrapper") 88 | 89 | # Add build target 90 | add_subdirectory(${CEF_LIBCEF_DLL_WRAPPER_PATH}) 91 | PRINT_CEF_CONFIG() 92 | ############################################################### 93 | 94 | 95 | # Add all targets 96 | ############################################################### 97 | add_subdirectory(src/QCefProto) 98 | 99 | include_directories( 100 | src/QCefProto 101 | ${CEF_ROOT} 102 | ) 103 | 104 | set(QCEF_WING_EXE "QCefWing") 105 | add_subdirectory(src/QCefWing) 106 | 107 | set(QCEF_VIEW_DLL "QCefView") 108 | add_subdirectory(src/QCefView) 109 | ############################################################### 110 | 111 | 112 | # Config the Demo project 113 | ############################################################### 114 | if ((NOT DEFINED SKIP_BUILD_DEMO) OR (SKIP_BUILD_DEMO STREQUAL "") OR (${SKIP_BUILD_DEMO} MATCHES "(FALSE|false|0|OFF)")) 115 | option(SKIP_BUILD_DEMO "Skip building of demo" OFF) 116 | message(STATUS "FLAG SKIP_BUILD_DEMO is OFF") 117 | elseif(${SKIP_BUILD_DEMO} MATCHES "(TRUE|true|1|ON)") 118 | option(SKIP_BUILD_DEMO "Skip building of demo" ON) 119 | message(STATUS "FLAG SKIP_BUILD_DEMO is ON") 120 | else() 121 | message(FATAL_ERROR "++++++++++ INVALID FLAG SKIP_BUILD_DEMO=" ${SKIP_BUILD_DEMO}) 122 | endif() 123 | 124 | if (NOT SKIP_BUILD_DEMO) 125 | add_subdirectory(test/QCefViewTest) 126 | endif() 127 | ############################################################### 128 | -------------------------------------------------------------------------------- /src/QCefWing/CefViewRenderApp/RenderDelegates/QCefViewDefaultRenderDelegate.cpp: -------------------------------------------------------------------------------- 1 | #pragma region project_headers 2 | #include "QCefViewDefaultRenderDelegate.h" 3 | #include "QCefClient.h" 4 | #pragma endregion project_headers 5 | 6 | namespace QCefViewDefaultRenderDelegate { 7 | void 8 | CreateBrowserDelegate(QCefViewRenderApp::RenderDelegateSet& delegates, const CefString& name) 9 | { 10 | delegates.insert(new RenderDelegate(name)); 11 | } 12 | 13 | RenderDelegate::RenderDelegate(const CefString& name) 14 | : bridge_object_name_(name) 15 | {} 16 | 17 | void 18 | RenderDelegate::OnWebKitInitialized(CefRefPtr app) 19 | { 20 | CefMessageRouterConfig config; 21 | config.js_query_function = QCEF_QUERY_NAME; 22 | config.js_cancel_function = QCEF_QUERY_CANCEL_NAME; 23 | render_message_router_ = CefMessageRouterRendererSide::Create(config); 24 | } 25 | 26 | void 27 | RenderDelegate::OnContextCreated(CefRefPtr app, 28 | CefRefPtr browser, 29 | CefRefPtr frame, 30 | CefRefPtr context) 31 | { 32 | render_message_router_->OnContextCreated(browser, frame, context); 33 | 34 | int64 frameId = frame->GetIdentifier(); 35 | auto it = frame_id_to_client_map_.find(frameId); 36 | if (it == frame_id_to_client_map_.end()) { 37 | // create and insert the QCefClient Object into this frame.window object 38 | CefRefPtr objWindow = context->GetGlobal(); 39 | CefRefPtr objClient = new QCefClient(browser, frame); 40 | if (bridge_object_name_.empty()) 41 | bridge_object_name_ = QCEF_OBJECT_NAME; 42 | 43 | objWindow->SetValue(bridge_object_name_, objClient->GetObject(), V8_PROPERTY_ATTRIBUTE_READONLY); 44 | frame_id_to_client_map_[frameId] = objClient; 45 | } 46 | } 47 | 48 | void 49 | RenderDelegate::OnContextReleased(CefRefPtr app, 50 | CefRefPtr browser, 51 | CefRefPtr frame, 52 | CefRefPtr context) 53 | { 54 | render_message_router_->OnContextReleased(browser, frame, context); 55 | 56 | int64 frameId = frame->GetIdentifier(); 57 | auto it = frame_id_to_client_map_.find(frameId); 58 | if (it != frame_id_to_client_map_.end()) { 59 | frame_id_to_client_map_.erase(it); 60 | } 61 | } 62 | 63 | bool 64 | RenderDelegate::OnProcessMessageReceived(CefRefPtr app, 65 | CefRefPtr browser, 66 | CefRefPtr frame, 67 | CefProcessId source_process, 68 | CefRefPtr message) 69 | { 70 | if (render_message_router_->OnProcessMessageReceived(browser, frame, source_process, message)) { 71 | return true; 72 | } 73 | 74 | if (OnTriggerEventNotifyMessage(browser, frame, source_process, message)) { 75 | return true; 76 | } 77 | 78 | return false; 79 | } 80 | 81 | bool 82 | RenderDelegate::OnTriggerEventNotifyMessage(CefRefPtr browser, 83 | CefRefPtr frame, 84 | CefProcessId source_process, 85 | CefRefPtr message) 86 | { 87 | if (message->GetName() == TRIGGEREVENT_NOTIFY_MESSAGE) { 88 | CefRefPtr messageArguments = message->GetArgumentList(); 89 | if (messageArguments && (messageArguments->GetSize() >= 2)) { 90 | int idx = 0; 91 | if (CefValueType::VTYPE_STRING == messageArguments->GetType(idx)) { 92 | CefString eventName = messageArguments->GetString(idx++); 93 | 94 | if (CefValueType::VTYPE_DICTIONARY == messageArguments->GetType(idx)) { 95 | CefRefPtr dict = messageArguments->GetDictionary(idx++); 96 | 97 | ExecuteEventListener(browser, frame, eventName, dict); 98 | return true; 99 | } 100 | } 101 | } 102 | } 103 | 104 | return false; 105 | } 106 | 107 | void 108 | RenderDelegate::ExecuteEventListener(CefRefPtr browser, 109 | CefRefPtr frame, 110 | const CefString& name, 111 | CefRefPtr dict) 112 | { 113 | if (browser && frame) { 114 | int64 frameId = frame->GetIdentifier(); 115 | auto it = frame_id_to_client_map_.find(frameId); 116 | if (it != frame_id_to_client_map_.end()) { 117 | const CefRefPtr& objClient = it->second; 118 | objClient->ExecuteEventListener(name, dict); 119 | } 120 | } 121 | } 122 | 123 | } 124 | -------------------------------------------------------------------------------- /src/QCefView/CefViewBrowserApp/SchemeHandlers/QCefViewDefaultSchemeHandler.cpp: -------------------------------------------------------------------------------- 1 | #pragma region std_headers 2 | #include 3 | #include 4 | #pragma endregion std_headers 5 | 6 | #pragma region cef_headers 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #pragma endregion cef_headers 16 | 17 | #include "QCefViewDefaultSchemeHandler.h" 18 | 19 | namespace QCefViewDefaultSchemeHandler { 20 | ////////////////////////////////////////////////////////////////////////// 21 | // handler 22 | SchemeHandler::SchemeHandler(QCefViewDelegate* pDelegate) 23 | : pQCefViewDelegate_(pDelegate) 24 | , offset_(0) 25 | {} 26 | 27 | bool 28 | SchemeHandler::Open(CefRefPtr request, bool& handle_request, CefRefPtr callback) 29 | { 30 | handle_request = false; 31 | if (pQCefViewDelegate_) { 32 | CefString cefStrUrl = request->GetURL(); 33 | pQCefViewDelegate_->onQCefUrlRequest(cefStrUrl); 34 | } 35 | 36 | // no matter whether we have found the handler or not, 37 | // we don't response this request. 38 | return false; 39 | } 40 | 41 | bool 42 | SchemeHandler::ProcessRequest(CefRefPtr request, CefRefPtr callback) 43 | { 44 | if (pQCefViewDelegate_) { 45 | CefString cefStrUrl = request->GetURL(); 46 | pQCefViewDelegate_->onQCefUrlRequest(cefStrUrl); 47 | } 48 | 49 | return false; 50 | } 51 | 52 | void 53 | SchemeHandler::GetResponseHeaders(CefRefPtr response, int64& response_length, CefString& redirectUrl) 54 | { 55 | CEF_REQUIRE_IO_THREAD(); 56 | // DCHECK(!data_.empty()); 57 | // response->SetMimeType(mime_type_); 58 | // response->SetStatus(200); 59 | //// Set the resulting response length 60 | // response_length = data_.length(); 61 | } 62 | 63 | bool 64 | SchemeHandler::Skip(int64 bytes_to_skip, int64& bytes_skipped, CefRefPtr callback) 65 | { 66 | bytes_skipped = -2; 67 | return false; 68 | } 69 | 70 | bool 71 | SchemeHandler::Read(void* data_out, int bytes_to_read, int& bytes_read, CefRefPtr callback) 72 | { 73 | bytes_read = 0; 74 | if (offset_ < data_.length()) { 75 | // Copy the next block of data into the buffer. 76 | int transfer_size = min(bytes_to_read, static_cast(data_.length() - offset_)); 77 | memcpy(data_out, data_.c_str() + offset_, transfer_size); 78 | offset_ += transfer_size; 79 | bytes_read = transfer_size; 80 | } 81 | 82 | return bytes_read > 0; 83 | } 84 | 85 | bool 86 | SchemeHandler::ReadResponse(void* data_out, int bytes_to_read, int& bytes_read, CefRefPtr callback) 87 | { 88 | bytes_read = -2; 89 | return false; 90 | } 91 | 92 | void 93 | SchemeHandler::Cancel() 94 | {} 95 | 96 | std::map SchemeHandlerFactory::mapBrowser2Delegate_; 97 | 98 | std::mutex SchemeHandlerFactory::mtxMap_; 99 | 100 | void 101 | SchemeHandlerFactory::recordBrowserAndDelegate(CefRefPtr browser, QCefViewDelegate* pDelegate) 102 | { 103 | if (!browser) 104 | return; 105 | 106 | std::lock_guard lock(mtxMap_); 107 | mapBrowser2Delegate_[browser.get()] = pDelegate; 108 | } 109 | 110 | void 111 | SchemeHandlerFactory::removeBrowserAndDelegate(CefRefPtr browser) 112 | { 113 | std::lock_guard lock(mtxMap_); 114 | if (mapBrowser2Delegate_.count(browser.get())) 115 | mapBrowser2Delegate_.erase(browser.get()); 116 | } 117 | 118 | ////////////////////////////////////////////////////////////////////////// 119 | // handler factory 120 | // 121 | 122 | CefRefPtr 123 | SchemeHandlerFactory::Create(CefRefPtr browser, 124 | CefRefPtr frame, 125 | const CefString& scheme_name, 126 | CefRefPtr request) 127 | { 128 | QCefViewDelegate* pDelegate = nullptr; 129 | 130 | { 131 | std::lock_guard lock(mtxMap_); 132 | if (mapBrowser2Delegate_.count(browser.get())) 133 | pDelegate = mapBrowser2Delegate_[browser.get()]; 134 | } 135 | 136 | if (pDelegate) 137 | return new SchemeHandler(pDelegate); 138 | else 139 | return nullptr; 140 | } 141 | 142 | ////////////////////////////////////////////////////////////////////////// 143 | bool 144 | RegisterScheme(CefRawPtr registrar) 145 | { 146 | return registrar->AddCustomScheme(scheme_name, 0); 147 | } 148 | 149 | bool 150 | RegisterSchemeHandlerFactory() 151 | { 152 | return CefRegisterSchemeHandlerFactory(scheme_name, "", new SchemeHandlerFactory()); 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/QCefWing/CefViewRenderApp/QCefViewRenderApp.cpp: -------------------------------------------------------------------------------- 1 | #pragma region std_headers 2 | #include 3 | #pragma endregion std_headers 4 | 5 | #pragma region cef_headers 6 | #include 7 | #include 8 | #include 9 | #pragma endregion cef_headers 10 | 11 | #pragma region project_headers 12 | #include "QCefViewRenderApp.h" 13 | #include "RenderDelegates/QCefViewDefaultRenderDelegate.h" 14 | #pragma endregion project_headers 15 | 16 | QCefViewRenderApp::QCefViewRenderApp(const CefString& name) 17 | : bridge_object_name_(name) 18 | { 19 | QCefViewDefaultRenderDelegate::CreateBrowserDelegate(render_delegates_, bridge_object_name_); 20 | } 21 | 22 | QCefViewRenderApp::~QCefViewRenderApp() {} 23 | 24 | ////////////////////////////////////////////////////////////////////////// 25 | void 26 | QCefViewRenderApp::OnBeforeCommandLineProcessing(const CefString& process_type, CefRefPtr command_line) 27 | {} 28 | 29 | void 30 | QCefViewRenderApp::OnRegisterCustomSchemes(CefRawPtr registrar) 31 | {} 32 | 33 | CefRefPtr 34 | QCefViewRenderApp::GetRenderProcessHandler() 35 | { 36 | return this; 37 | } 38 | 39 | CefRefPtr 40 | QCefViewRenderApp::GetResourceBundleHandler() 41 | { 42 | return nullptr; 43 | } 44 | 45 | CefRefPtr 46 | QCefViewRenderApp::GetBrowserProcessHandler() 47 | { 48 | return nullptr; 49 | } 50 | 51 | ////////////////////////////////////////////////////////////////////////// 52 | void 53 | QCefViewRenderApp::OnWebKitInitialized() 54 | { 55 | CEF_REQUIRE_RENDERER_THREAD(); 56 | 57 | RenderDelegateSet::iterator it = render_delegates_.begin(); 58 | for (; it != render_delegates_.end(); ++it) 59 | (*it)->OnWebKitInitialized(this); 60 | } 61 | 62 | void 63 | QCefViewRenderApp::OnBrowserCreated(CefRefPtr browser, CefRefPtr extra_info) 64 | { 65 | CEF_REQUIRE_RENDERER_THREAD(); 66 | RenderDelegateSet::iterator it = render_delegates_.begin(); 67 | for (; it != render_delegates_.end(); ++it) 68 | (*it)->OnBrowserCreated(this, browser, extra_info); 69 | } 70 | 71 | void 72 | QCefViewRenderApp::OnBrowserDestroyed(CefRefPtr browser) 73 | { 74 | CEF_REQUIRE_RENDERER_THREAD(); 75 | RenderDelegateSet::iterator it = render_delegates_.begin(); 76 | for (; it != render_delegates_.end(); ++it) 77 | (*it)->OnBrowserDestroyed(this, browser); 78 | } 79 | 80 | CefRefPtr 81 | QCefViewRenderApp::GetLoadHandler() 82 | { 83 | CefRefPtr load_handler; 84 | RenderDelegateSet::iterator it = render_delegates_.begin(); 85 | for (; it != render_delegates_.end() && !load_handler.get(); ++it) 86 | load_handler = (*it)->GetLoadHandler(this); 87 | 88 | return load_handler; 89 | } 90 | 91 | void 92 | QCefViewRenderApp::OnContextCreated(CefRefPtr browser, 93 | CefRefPtr frame, 94 | CefRefPtr context) 95 | { 96 | CEF_REQUIRE_RENDERER_THREAD(); 97 | 98 | RenderDelegateSet::iterator it = render_delegates_.begin(); 99 | for (; it != render_delegates_.end(); ++it) 100 | (*it)->OnContextCreated(this, browser, frame, context); 101 | } 102 | 103 | void 104 | QCefViewRenderApp::OnContextReleased(CefRefPtr browser, 105 | CefRefPtr frame, 106 | CefRefPtr context) 107 | { 108 | CEF_REQUIRE_RENDERER_THREAD(); 109 | RenderDelegateSet::iterator it = render_delegates_.begin(); 110 | for (; it != render_delegates_.end(); ++it) 111 | (*it)->OnContextReleased(this, browser, frame, context); 112 | } 113 | 114 | void 115 | QCefViewRenderApp::OnUncaughtException(CefRefPtr browser, 116 | CefRefPtr frame, 117 | CefRefPtr context, 118 | CefRefPtr exception, 119 | CefRefPtr stackTrace) 120 | { 121 | CEF_REQUIRE_RENDERER_THREAD(); 122 | RenderDelegateSet::iterator it = render_delegates_.begin(); 123 | for (; it != render_delegates_.end(); ++it) 124 | (*it)->OnUncaughtException(this, browser, frame, context, exception, stackTrace); 125 | } 126 | 127 | void 128 | QCefViewRenderApp::OnFocusedNodeChanged(CefRefPtr browser, 129 | CefRefPtr frame, 130 | CefRefPtr node) 131 | { 132 | CEF_REQUIRE_RENDERER_THREAD(); 133 | RenderDelegateSet::iterator it = render_delegates_.begin(); 134 | for (; it != render_delegates_.end(); ++it) 135 | (*it)->OnFocusedNodeChanged(this, browser, frame, node); 136 | } 137 | 138 | bool 139 | QCefViewRenderApp::OnProcessMessageReceived(CefRefPtr browser, 140 | CefRefPtr frame, 141 | CefProcessId source_process, 142 | CefRefPtr message) 143 | { 144 | CEF_REQUIRE_RENDERER_THREAD(); 145 | DCHECK_EQ(source_process, PID_BROWSER); 146 | 147 | bool handled = false; 148 | 149 | RenderDelegateSet::iterator it = render_delegates_.begin(); 150 | for (; it != render_delegates_.end() && !handled; ++it) 151 | handled = (*it)->OnProcessMessageReceived(this, browser, frame, source_process, message); 152 | 153 | return handled; 154 | } 155 | -------------------------------------------------------------------------------- /src/QCefView/QCefSetting.cpp: -------------------------------------------------------------------------------- 1 | #include "Include/QCefSetting.h" 2 | #include "CCefSetting.h" 3 | 4 | #include 5 | 6 | void 7 | QCefSetting::setBrowserSubProcessPath(const QString& path) 8 | { 9 | CCefSetting::initializeInstance(); 10 | CCefSetting::browser_sub_process_path.FromString(path.toStdString()); 11 | } 12 | 13 | const QString 14 | QCefSetting::browserSubProcessPath() 15 | { 16 | CCefSetting::initializeInstance(); 17 | return QString::fromStdString(CCefSetting::browser_sub_process_path.ToString()); 18 | } 19 | 20 | void 21 | QCefSetting::setResourceDirectoryPath(const QString& path) 22 | { 23 | CCefSetting::initializeInstance(); 24 | CCefSetting::resource_directory_path.FromString(path.toStdString()); 25 | } 26 | 27 | const QString 28 | QCefSetting::resourceDirectoryPath() 29 | { 30 | CCefSetting::initializeInstance(); 31 | return QString::fromStdString(CCefSetting::resource_directory_path.ToString()); 32 | } 33 | 34 | void 35 | QCefSetting::setLocalesDirectoryPath(const QString& path) 36 | { 37 | CCefSetting::initializeInstance(); 38 | CCefSetting::locales_directory_path.FromString(path.toStdString()); 39 | } 40 | 41 | const QString 42 | QCefSetting::localesDirectoryPath() 43 | { 44 | CCefSetting::initializeInstance(); 45 | return QString::fromStdString(CCefSetting::locales_directory_path.ToString()); 46 | } 47 | 48 | void 49 | QCefSetting::setUserAgent(const QString& agent) 50 | { 51 | CCefSetting::initializeInstance(); 52 | CCefSetting::user_agent.FromString(agent.toStdString()); 53 | } 54 | 55 | const QString 56 | QCefSetting::userAgent() 57 | { 58 | CCefSetting::initializeInstance(); 59 | return QString::fromStdString(CCefSetting::user_agent.ToString()); 60 | } 61 | 62 | void 63 | QCefSetting::setCachePath(const QString& path) 64 | { 65 | CCefSetting::initializeInstance(); 66 | CCefSetting::cache_path.FromString(path.toStdString()); 67 | } 68 | 69 | const QString 70 | QCefSetting::cachePath() 71 | { 72 | CCefSetting::initializeInstance(); 73 | return QString::fromStdString(CCefSetting::cache_path.ToString()); 74 | } 75 | 76 | void 77 | QCefSetting::setUserDataPath(const QString& path) 78 | { 79 | CCefSetting::initializeInstance(); 80 | CCefSetting::user_data_path.FromString(path.toStdString()); 81 | } 82 | 83 | const QString 84 | QCefSetting::userDataPath() 85 | { 86 | CCefSetting::initializeInstance(); 87 | return QString::fromStdString(CCefSetting::user_data_path.ToString()); 88 | } 89 | 90 | void 91 | QCefSetting::setBridgeObjectName(const QString& name) 92 | { 93 | CCefSetting::initializeInstance(); 94 | CCefSetting::bridge_object_name.FromString(name.toStdString()); 95 | } 96 | 97 | const QString 98 | QCefSetting::bridgeObjectName() 99 | { 100 | CCefSetting::initializeInstance(); 101 | return QString::fromStdString(CCefSetting::bridge_object_name); 102 | } 103 | 104 | void 105 | QCefSetting::setPersistSessionCookies(bool enabled) 106 | { 107 | CCefSetting::initializeInstance(); 108 | CCefSetting::persist_session_cookies = enabled ? TRUE : FALSE; 109 | } 110 | 111 | const bool 112 | QCefSetting::persistSessionCookies() 113 | { 114 | CCefSetting::initializeInstance(); 115 | return CCefSetting::persist_session_cookies ? true : false; 116 | } 117 | 118 | void 119 | QCefSetting::setPersistUserPreferences(bool enabled) 120 | { 121 | CCefSetting::initializeInstance(); 122 | CCefSetting::persist_user_preferences = enabled ? TRUE : FALSE; 123 | } 124 | 125 | const bool 126 | QCefSetting::persistUserPreferences() 127 | { 128 | CCefSetting::initializeInstance(); 129 | return CCefSetting::persist_user_preferences ? true : false; 130 | } 131 | 132 | void 133 | QCefSetting::setLocale(const QString& locale) 134 | { 135 | CCefSetting::initializeInstance(); 136 | CCefSetting::locale.FromString(locale.toStdString()); 137 | } 138 | 139 | const QString 140 | QCefSetting::locale() 141 | { 142 | CCefSetting::initializeInstance(); 143 | return QString::fromStdString(CCefSetting::locale.ToString()); 144 | } 145 | 146 | void 147 | QCefSetting::setRemoteDebuggingPort(int port) 148 | { 149 | CCefSetting::initializeInstance(); 150 | CCefSetting::remote_debugging_port = port; 151 | } 152 | 153 | const int 154 | QCefSetting::remoteDebuggingPort() 155 | { 156 | CCefSetting::initializeInstance(); 157 | return CCefSetting::remote_debugging_port; 158 | } 159 | 160 | void 161 | QCefSetting::setBackgroundColor(const QColor& color) 162 | { 163 | CCefSetting::initializeInstance(); 164 | CCefSetting::background_color = static_cast(color.rgba()); 165 | } 166 | 167 | const QColor 168 | QCefSetting::backgroundColor() 169 | { 170 | CCefSetting::initializeInstance(); 171 | return QColor::fromRgba(static_cast(CCefSetting::background_color)); 172 | } 173 | 174 | void 175 | QCefSetting::setAcceptLanguageList(const QString& languages) 176 | { 177 | CCefSetting::initializeInstance(); 178 | CCefSetting::accept_language_list.FromString(languages.toStdString()); 179 | } 180 | 181 | const QString 182 | QCefSetting::acceptLanguageList() 183 | { 184 | CCefSetting::initializeInstance(); 185 | return QString::fromStdString(CCefSetting::accept_language_list.ToString()); 186 | } 187 | 188 | void QCEFVIEW_EXPORT 189 | QCefSetting::setGlobalCookie(const QString& name, const QString& value, const QString& domain, const QString& url) 190 | { 191 | CCefSetting::initializeInstance(); 192 | CCefSetting::global_cookie_list.push_back( 193 | { name.toStdString(), value.toStdString(), domain.toStdString(), url.toStdString() }); 194 | } 195 | -------------------------------------------------------------------------------- /src/QCefWing/CefViewRenderApp/RenderDelegates/QCefClient.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma region std_headers 3 | #include 4 | #include 5 | #pragma endregion 6 | 7 | #pragma region cef_headers 8 | #include 9 | #pragma endregion cef_headers 10 | 11 | #include 12 | 13 | /// 14 | /// 15 | /// 16 | class QCefClient : public CefBaseRefCounted 17 | { 18 | // class Accessor 19 | // : public CefV8Accessor 20 | //{ 21 | // public: 22 | // virtual bool Get(const CefString& name, 23 | // const CefRefPtr object, 24 | // CefRefPtr& retval, 25 | // CefString& exception) override; 26 | 27 | // virtual bool Set(const CefString& name, 28 | // const CefRefPtr object, 29 | // const CefRefPtr value, 30 | // CefString& exception) override; 31 | 32 | // private: 33 | // IMPLEMENT_REFCOUNTING(Accessor); 34 | //}; 35 | 36 | /// 37 | /// 38 | /// 39 | typedef struct _EventListener 40 | { 41 | CefRefPtr callback_; 42 | CefRefPtr context_; 43 | } EventListener; 44 | 45 | /// 46 | /// 47 | /// 48 | typedef std::list EventListenerList; 49 | 50 | /// 51 | /// 52 | /// 53 | typedef std::map> EventListenerListMap; 54 | 55 | /// 56 | /// 57 | /// 58 | class V8Handler : public CefV8Handler 59 | { 60 | public: 61 | /// 62 | /// 63 | /// 64 | /// 65 | /// 66 | /// 67 | V8Handler(CefRefPtr browser, 68 | CefRefPtr frame, 69 | QCefClient::EventListenerListMap& eventListenerListMap); 70 | 71 | /// 72 | /// 73 | /// 74 | /// 75 | /// 76 | /// 77 | /// 78 | /// 79 | /// 80 | virtual bool Execute(const CefString& function, 81 | CefRefPtr object, 82 | const CefV8ValueList& arguments, 83 | CefRefPtr& retval, 84 | CefString& exception) override; 85 | 86 | protected: 87 | /// 88 | /// 89 | /// 90 | /// 91 | /// 92 | /// 93 | /// 94 | /// 95 | void ExecuteInvokeMethod(const CefString& function, 96 | CefRefPtr object, 97 | const CefV8ValueList& arguments, 98 | CefRefPtr& retval, 99 | CefString& exception); 100 | 101 | /// 102 | /// 103 | /// 104 | /// 105 | /// 106 | /// 107 | /// 108 | /// 109 | void ExecuteAddEventListener(const CefString& function, 110 | CefRefPtr object, 111 | const CefV8ValueList& arguments, 112 | CefRefPtr& retval, 113 | CefString& exception); 114 | 115 | /// 116 | /// 117 | /// 118 | /// 119 | /// 120 | /// 121 | /// 122 | /// 123 | void ExecuteRemoveEventListener(const CefString& function, 124 | CefRefPtr object, 125 | const CefV8ValueList& arguments, 126 | CefRefPtr& retval, 127 | CefString& exception); 128 | 129 | private: 130 | /// 131 | /// 132 | /// 133 | CefRefPtr browser_; 134 | 135 | /// 136 | /// 137 | /// 138 | CefRefPtr frame_; 139 | 140 | /// 141 | /// 142 | /// 143 | QCefClient::EventListenerListMap& eventListenerListMap_; 144 | 145 | private: 146 | IMPLEMENT_REFCOUNTING(V8Handler); 147 | }; 148 | 149 | public: 150 | /// 151 | /// 152 | /// 153 | /// 154 | /// 155 | QCefClient(CefRefPtr browser, CefRefPtr frame); 156 | 157 | /// 158 | /// 159 | /// 160 | /// 161 | CefRefPtr GetObject(); 162 | 163 | /// 164 | /// 165 | /// 166 | /// 167 | /// 168 | void ExecuteEventListener(const CefString eventName, CefRefPtr dict); 169 | 170 | private: 171 | /// 172 | /// 173 | /// 174 | CefRefPtr object_; 175 | 176 | /// 177 | /// 178 | /// 179 | CefRefPtr browser_; 180 | 181 | /// 182 | /// 183 | /// 184 | CefRefPtr frame_; 185 | 186 | /// 187 | /// 188 | /// 189 | EventListenerListMap eventListenerListMap_; 190 | 191 | private: 192 | IMPLEMENT_REFCOUNTING(QCefClient); 193 | }; 194 | -------------------------------------------------------------------------------- /src/QCefView/CCefWindow.cpp: -------------------------------------------------------------------------------- 1 | #pragma region qt_headers 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #pragma endregion qt_headers 8 | 9 | #include "CCefWindow.h" 10 | #include "CCefManager.h" 11 | 12 | CCefWindow::CCefWindow(QCefView* view /*= 0*/) 13 | : QWindow(view->windowHandle()) 14 | , view_(view) 15 | , hwndCefBrowser_(nullptr) 16 | { 17 | setFlags(Qt::FramelessWindowHint); 18 | 19 | CCefManager::getInstance().initializeCef(); 20 | } 21 | 22 | CCefWindow::~CCefWindow() 23 | { 24 | if (hwndCefBrowser_) 25 | hwndCefBrowser_ = nullptr; 26 | 27 | CCefManager::getInstance().uninitializeCef(); 28 | } 29 | 30 | void 31 | CCefWindow::setCefBrowserWindow(CefWindowHandle hwnd) 32 | { 33 | hwndCefBrowser_ = hwnd; 34 | syncCefBrowserWindow(); 35 | } 36 | 37 | void 38 | CCefWindow::onLoadingStateChanged(bool isLoading, bool canGoBack, bool canGoForward) 39 | { 40 | if (view_) 41 | view_->onLoadingStateChanged(isLoading, canGoBack, canGoForward); 42 | } 43 | 44 | void 45 | CCefWindow::onLoadStart() 46 | { 47 | if (view_) 48 | view_->onLoadStart(); 49 | } 50 | 51 | void 52 | CCefWindow::onLoadEnd(int httpStatusCode) 53 | { 54 | if (view_) 55 | view_->onLoadEnd(httpStatusCode); 56 | } 57 | 58 | void 59 | CCefWindow::onLoadError(int errorCode, const CefString& errorMsg, const CefString& failedUrl, bool& handled) 60 | { 61 | if (view_) { 62 | auto msg = QString::fromStdString(errorMsg.ToString()); 63 | auto url = QString::fromStdString(failedUrl.ToString()); 64 | view_->onLoadError(errorCode, msg, url, handled); 65 | } 66 | } 67 | 68 | void 69 | CCefWindow::onDraggableRegionChanged(const std::vector regions) 70 | { 71 | if (view_) { 72 | // Determine new draggable region. 73 | QRegion region; 74 | std::vector::const_iterator it = regions.begin(); 75 | for (; it != regions.end(); ++it) { 76 | region += QRegion(it->bounds.x, it->bounds.y, it->bounds.width, it->bounds.height); 77 | } 78 | view_->onDraggableRegionChanged(region); 79 | } 80 | } 81 | 82 | void 83 | CCefWindow::onConsoleMessage(const CefString& message, int level) 84 | { 85 | if (view_) { 86 | auto msg = QString::fromStdString(message.ToString()); 87 | view_->onConsoleMessage(msg, level); 88 | } 89 | } 90 | 91 | void 92 | CCefWindow::onTakeFocus(bool next) 93 | { 94 | if (view_) 95 | view_->onTakeFocus(next); 96 | } 97 | 98 | void 99 | CCefWindow::onQCefUrlRequest(const CefString& url) 100 | { 101 | if (view_) { 102 | auto u = QString::fromStdString(url.ToString()); 103 | view_->onQCefUrlRequest(u); 104 | } 105 | } 106 | 107 | void 108 | CCefWindow::onQCefQueryRequest(const CefString& request, int64 query_id) 109 | { 110 | if (view_) { 111 | auto req = QString::fromStdString(request.ToString()); 112 | view_->onQCefQueryRequest(QCefQuery(req, query_id)); 113 | } 114 | } 115 | 116 | void 117 | CCefWindow::onInvokeMethodNotify(int browserId, const CefRefPtr& arguments) 118 | { 119 | if (!view_) 120 | return; 121 | 122 | if (arguments && (arguments->GetSize() >= 2)) { 123 | int idx = 0; 124 | if (CefValueType::VTYPE_INT == arguments->GetType(idx)) { 125 | int frameId = arguments->GetInt(idx++); 126 | 127 | if (CefValueType::VTYPE_STRING == arguments->GetType(idx)) { 128 | CefString functionName = arguments->GetString(idx++); 129 | if (functionName == QCEF_INVOKEMETHOD) { 130 | QString method; 131 | if (CefValueType::VTYPE_STRING == arguments->GetType(idx)) { 132 | #if defined(CEF_STRING_TYPE_UTF16) 133 | method = QString::fromWCharArray(arguments->GetString(idx++).c_str()); 134 | #elif defined(CEF_STRING_TYPE_UTF8) 135 | method = QString::fromUtf8(arguments->GetString(idx++).c_str()); 136 | #elif defined(CEF_STRING_TYPE_WIDE) 137 | method = QString::fromWCharArray(arguments->GetString(idx++).c_str()); 138 | #endif 139 | } 140 | 141 | QVariantList argumentList; 142 | QString qStr; 143 | for (idx; idx < arguments->GetSize(); idx++) { 144 | if (CefValueType::VTYPE_NULL == arguments->GetType(idx)) 145 | argumentList.push_back(0); 146 | else if (CefValueType::VTYPE_BOOL == arguments->GetType(idx)) 147 | argumentList.push_back(QVariant::fromValue(arguments->GetBool(idx))); 148 | else if (CefValueType::VTYPE_INT == arguments->GetType(idx)) 149 | argumentList.push_back(QVariant::fromValue(arguments->GetInt(idx))); 150 | else if (CefValueType::VTYPE_DOUBLE == arguments->GetType(idx)) 151 | argumentList.push_back(QVariant::fromValue(arguments->GetDouble(idx))); 152 | else if (CefValueType::VTYPE_STRING == arguments->GetType(idx)) { 153 | #if defined(CEF_STRING_TYPE_UTF16) 154 | qStr = QString::fromWCharArray(arguments->GetString(idx).c_str()); 155 | #elif defined(CEF_STRING_TYPE_UTF8) 156 | qStr = QString::fromUtf8(arguments->GetString(idx).c_str()); 157 | #elif defined(CEF_STRING_TYPE_WIDE) 158 | qStr = QString::fromWCharArray(arguments->GetString(idx).c_str()); 159 | #endif 160 | argumentList.push_back(qStr); 161 | } else { 162 | } 163 | } 164 | 165 | view_->onInvokeMethodNotify(browserId, frameId, method, argumentList); 166 | } 167 | } 168 | } 169 | } 170 | } 171 | 172 | void 173 | CCefWindow::syncCefBrowserWindow() 174 | { 175 | double w = width() * devicePixelRatio(); 176 | double h = height() * devicePixelRatio(); 177 | if (hwndCefBrowser_) 178 | ::SetWindowPos(hwndCefBrowser_, NULL, 0, 0, w, h, SWP_NOZORDER | SWP_NOSENDCHANGING | SWP_DEFERERASE); 179 | } 180 | 181 | void 182 | CCefWindow::exposeEvent(QExposeEvent* e) 183 | { 184 | syncCefBrowserWindow(); 185 | return __super::exposeEvent(e); 186 | } 187 | 188 | void 189 | CCefWindow::resizeEvent(QResizeEvent* e) 190 | { 191 | syncCefBrowserWindow(); 192 | __super::resizeEvent(e); 193 | 194 | return; 195 | } 196 | -------------------------------------------------------------------------------- /License: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /src/QCefView/Include/QCefView.h: -------------------------------------------------------------------------------- 1 | #ifndef QCEFVIEW_H 2 | #define QCEFVIEW_H 3 | #pragma once 4 | 5 | #pragma region std_headers 6 | #include 7 | #pragma endregion std_headers 8 | 9 | #pragma region qt_headers 10 | #include 11 | #include 12 | #include 13 | #pragma endregion qt_headers 14 | 15 | #include "QCefQuery.h" 16 | #include "QCefEvent.h" 17 | 18 | #ifdef QCEFVIEW_LIB 19 | #define QCEFVIEW_EXPORT Q_DECL_EXPORT 20 | #else 21 | #define QCEFVIEW_EXPORT Q_DECL_IMPORT 22 | #if _WIN32 23 | #pragma comment(lib, "QCefView.lib") 24 | #endif 25 | #endif 26 | 27 | /** Outline of QCefView: 28 | ** 29 | ** +--------------------------------------------------------------+ 30 | ** | QCefView(QWidget) | 31 | ** | | 32 | ** | +----------------------------------------------------+ | 33 | ** | | WindowWrapper(QWidget) | | 34 | ** | | | | 35 | ** | | +-------------------------------------------+ | | 36 | ** | | | CefWindow(QWindow) | | | 37 | ** | | | | | | 38 | ** | | | | | | 39 | ** | | | | | | 40 | ** | | +-------------------------------------------+ | | 41 | ** | | | | 42 | ** | +----------------------------------------------------+ | 43 | ** | | 44 | ** +--------------------------------------------------------------+ 45 | ** 46 | ** Remarks: 47 | ** The WindowWrapper and CefWindow are transparent to upper layer user. 48 | ** 49 | **/ 50 | 51 | class CefContextMenuHandler; 52 | class CefDialogHandler; 53 | class CefDisplayHandler; 54 | class CefDownloadHandler; 55 | class CefJSDialogHandler; 56 | class CefKeyboardHandler; 57 | 58 | /// 59 | /// 60 | /// 61 | class QCEFVIEW_EXPORT QCefView : public QWidget 62 | { 63 | /// 64 | /// 65 | /// 66 | Q_OBJECT 67 | 68 | public: 69 | /// 70 | /// 71 | /// 72 | QCefView(const QString url, QWidget* parent = 0); 73 | 74 | /// 75 | /// 76 | /// 77 | QCefView(QWidget* parent = 0); 78 | 79 | /// 80 | /// 81 | /// 82 | ~QCefView(); 83 | 84 | /// 85 | /// 86 | /// 87 | /// 88 | /// 89 | static void addLocalFolderResource(const QString& path, const QString& url, int priority = 0); 90 | 91 | /// 92 | /// 93 | /// 94 | /// 95 | /// 96 | /// 97 | static void addArchiveResource(const QString& path, const QString& url, const QString& password = ""); 98 | 99 | /// 100 | /// 101 | /// 102 | /// 103 | /// 104 | /// 105 | /// 106 | void addCookie(const QString& name, const QString& value, const QString& domain, const QString& url); 107 | 108 | /// 109 | /// 110 | /// 111 | /// 112 | WId getCefWinId(); 113 | 114 | /// 115 | /// Navigates to the content. 116 | /// 117 | /// 118 | void navigateToString(const QString& content); 119 | 120 | /// 121 | /// 122 | /// 123 | /// 124 | void navigateToUrl(const QString& url); 125 | 126 | /// 127 | /// 128 | /// 129 | /// 130 | bool browserCanGoBack(); 131 | 132 | /// 133 | /// 134 | /// 135 | /// 136 | bool browserCanGoForward(); 137 | 138 | /// 139 | /// 140 | /// 141 | void browserGoBack(); 142 | 143 | /// 144 | /// 145 | /// 146 | void browserGoForward(); 147 | 148 | /// 149 | /// 150 | /// 151 | /// 152 | bool browserIsLoading(); 153 | 154 | /// 155 | /// 156 | /// 157 | void browserReload(); 158 | 159 | /// 160 | /// 161 | /// 162 | void browserStopLoad(); 163 | 164 | /// 165 | /// 166 | /// 167 | /// 168 | /// 169 | /// 170 | /// 171 | bool triggerEvent(const QCefEvent& event); 172 | 173 | /// 174 | /// 175 | /// 176 | /// 177 | /// 178 | /// 179 | /// 180 | bool triggerEvent(const QCefEvent& event, int frameId); 181 | 182 | /// 183 | /// 184 | /// 185 | /// 186 | /// 187 | /// 188 | bool broadcastEvent(const QCefEvent& event); 189 | 190 | /// 191 | /// 192 | /// 193 | /// 194 | /// 195 | bool responseQCefQuery(const QCefQuery& query); 196 | 197 | /// 198 | /// 199 | /// 200 | /// 201 | void setContextMenuHandler(CefContextMenuHandler* handler); 202 | 203 | /// 204 | /// 205 | /// 206 | /// 207 | void setDialogHandler(CefDialogHandler* handler); 208 | 209 | /// 210 | /// 211 | /// 212 | /// 213 | void setDisplayHandler(CefDisplayHandler* handler); 214 | 215 | /// 216 | /// 217 | /// 218 | /// 219 | void setDownloadHandler(CefDownloadHandler* handler); 220 | 221 | /// 222 | /// 223 | /// 224 | /// 225 | void setJSDialogHandler(CefJSDialogHandler* handler); 226 | 227 | /// 228 | /// 229 | /// 230 | /// 231 | void setKeyboardHandler(CefKeyboardHandler* handler); 232 | 233 | /// 234 | /// 235 | /// 236 | /// 237 | /// 238 | /// 239 | virtual void onLoadingStateChanged(bool isLoading, bool canGoBack, bool canGoForward); 240 | 241 | /// 242 | /// 243 | /// 244 | virtual void onLoadStart(); 245 | 246 | /// 247 | /// 248 | /// 249 | /// 250 | virtual void onLoadEnd(int httpStatusCode); 251 | 252 | /// 253 | /// 254 | /// 255 | /// 256 | /// 257 | /// 258 | /// 259 | virtual void onLoadError(int errorCode, const QString& errorMsg, const QString& failedUrl, bool& handled); 260 | 261 | /// 262 | /// 263 | /// 264 | /// 265 | virtual void onDraggableRegionChanged(const QRegion& region); 266 | 267 | /// 268 | /// 269 | /// 270 | /// 271 | /// 272 | virtual void onConsoleMessage(const QString& message, int level); 273 | 274 | /// 275 | /// 276 | /// 277 | /// 278 | virtual void onTakeFocus(bool next); 279 | 280 | /// 281 | /// 282 | /// 283 | /// 284 | virtual void onQCefUrlRequest(const QString& url); 285 | 286 | /// 287 | /// 288 | /// 289 | /// 290 | virtual void onQCefQueryRequest(const QCefQuery& query); 291 | 292 | /// 293 | /// 294 | /// 295 | /// 296 | /// 297 | /// 298 | /// 299 | virtual void onInvokeMethodNotify(int browserId, int frameId, const QString& method, const QVariantList& arguments); 300 | 301 | protected: 302 | /// 303 | /// 304 | /// 305 | /// 306 | virtual void changeEvent(QEvent* event) override; 307 | 308 | /// 309 | /// 310 | /// 311 | /// 312 | /// 313 | /// 314 | virtual bool eventFilter(QObject* watched, QEvent* event) override; 315 | 316 | private: 317 | /// 318 | /// 319 | /// 320 | class Implementation; 321 | std::unique_ptr pImpl_; 322 | }; 323 | 324 | #endif // QCEFVIEW_H 325 | -------------------------------------------------------------------------------- /src/QCefWing/CefViewRenderApp/RenderDelegates/QCefClient.cpp: -------------------------------------------------------------------------------- 1 | #pragma region projet_headers 2 | #include "QCefClient.h" 3 | #pragma endregion projet_headers 4 | 5 | // bool QCefClient::Accessor::Get(const CefString& name, 6 | // const CefRefPtr object, 7 | // CefRefPtr& retval, 8 | // CefString& exception) 9 | //{ 10 | // return true; 11 | //} 12 | // 13 | // bool QCefClient::Accessor::Set(const CefString& name, 14 | // const CefRefPtr object, 15 | // const CefRefPtr value, 16 | // CefString& exception) 17 | //{ 18 | // return true; 19 | //} 20 | 21 | ////////////////////////////////////////////////////////////////////////// 22 | 23 | QCefClient::V8Handler::V8Handler(CefRefPtr browser, 24 | CefRefPtr frame, 25 | QCefClient::EventListenerListMap& eventListenerListMap) 26 | : browser_(browser) 27 | , frame_(frame) 28 | , eventListenerListMap_(eventListenerListMap) 29 | {} 30 | 31 | bool 32 | QCefClient::V8Handler::Execute(const CefString& function, 33 | CefRefPtr object, 34 | const CefV8ValueList& arguments, 35 | CefRefPtr& retval, 36 | CefString& exception) 37 | { 38 | if (function == QCEF_INVOKEMETHOD) 39 | ExecuteInvokeMethod(function, object, arguments, retval, exception); 40 | else if (function == QCEF_ADDEVENTLISTENER) 41 | ExecuteAddEventListener(function, object, arguments, retval, exception); 42 | else if (function == QCEF_REMOVEEVENTLISTENER) 43 | ExecuteRemoveEventListener(function, object, arguments, retval, exception); 44 | else 45 | return false; 46 | 47 | return true; 48 | } 49 | 50 | void 51 | QCefClient::V8Handler::ExecuteInvokeMethod(const CefString& function, 52 | CefRefPtr object, 53 | const CefV8ValueList& arguments, 54 | CefRefPtr& retval, 55 | CefString& exception) 56 | { 57 | CefRefPtr msg = CefProcessMessage::Create(INVOKEMETHOD_NOTIFY_MESSAGE); 58 | 59 | CefRefPtr args = msg->GetArgumentList(); 60 | int frameId = (int)frame_->GetIdentifier(); 61 | 62 | int idx = 0; 63 | args->SetInt(idx++, frameId); 64 | args->SetString(idx++, function); 65 | 66 | for (std::size_t i = 0; i < arguments.size(); i++) { 67 | if (arguments[i]->IsBool()) 68 | args->SetBool(idx++, arguments[i]->GetBoolValue()); 69 | else if (arguments[i]->IsInt()) 70 | args->SetInt(idx++, arguments[i]->GetIntValue()); 71 | else if (arguments[i]->IsDouble()) 72 | args->SetDouble(idx++, arguments[i]->GetDoubleValue()); 73 | else if (arguments[i]->IsString()) 74 | args->SetString(idx++, arguments[i]->GetStringValue()); 75 | else 76 | args->SetNull(idx++); 77 | } 78 | 79 | bool bRet = false; 80 | if (browser_) 81 | frame_->SendProcessMessage(PID_BROWSER, msg); 82 | 83 | retval = CefV8Value::CreateUndefined(); 84 | } 85 | 86 | void 87 | QCefClient::V8Handler::ExecuteAddEventListener(const CefString& function, 88 | CefRefPtr object, 89 | const CefV8ValueList& arguments, 90 | CefRefPtr& retval, 91 | CefString& exception) 92 | { 93 | bool bRet = false; 94 | 95 | if (arguments.size() == 2) { 96 | if (arguments[0]->IsString()) { 97 | if (arguments[1]->IsFunction()) { 98 | CefString eventName = arguments[0]->GetStringValue(); 99 | EventListener listener; 100 | listener.callback_ = arguments[1]; 101 | listener.context_ = CefV8Context::GetCurrentContext(); 102 | 103 | auto itListenerList = eventListenerListMap_.find(eventName); 104 | if (itListenerList == eventListenerListMap_.end()) { 105 | EventListenerList eventListenerList; 106 | eventListenerList.push_back(listener); 107 | eventListenerListMap_[eventName] = eventListenerList; 108 | } else { 109 | EventListenerList& eventListenerList = itListenerList->second; 110 | // does this listener exist? 111 | bool found = false; 112 | for (auto item : eventListenerList) { 113 | if (item.callback_->IsSame(listener.callback_)) { 114 | found = true; 115 | break; 116 | } 117 | } 118 | 119 | if (!found) 120 | eventListenerList.push_back(listener); 121 | } 122 | bRet = true; 123 | } else 124 | exception = "Invalid parameters; parameter 2 is expecting a function"; 125 | } else 126 | exception = "Invalid parameters; parameter 1 is expecting a string"; 127 | } else 128 | exception = "Invalid parameters; expecting 2 parameters"; 129 | 130 | retval = CefV8Value::CreateBool(bRet); 131 | } 132 | 133 | void 134 | QCefClient::V8Handler::ExecuteRemoveEventListener(const CefString& function, 135 | CefRefPtr object, 136 | const CefV8ValueList& arguments, 137 | CefRefPtr& retval, 138 | CefString& exception) 139 | { 140 | bool bRet = false; 141 | 142 | if (arguments.size() == 2) { 143 | if (arguments[0]->IsString()) { 144 | if (arguments[1]->IsFunction()) { 145 | CefString eventName = arguments[0]->GetStringValue(); 146 | EventListener listener; 147 | listener.callback_ = arguments[1]; 148 | listener.context_ = CefV8Context::GetCurrentContext(); 149 | 150 | auto itListenerList = eventListenerListMap_.find(eventName); 151 | if (itListenerList != eventListenerListMap_.end()) { 152 | EventListenerList& eventListenerList = itListenerList->second; 153 | for (auto itListener = eventListenerList.begin(); itListener != eventListenerList.end(); itListener++) { 154 | if (itListener->callback_->IsSame(listener.callback_)) 155 | eventListenerList.erase(itListener); 156 | } 157 | } 158 | } else 159 | exception = "Invalid parameters; parameter 2 is expecting a function"; 160 | } else 161 | exception = "Invalid parameters; parameter 1 is expecting a string"; 162 | } else 163 | exception = "Invalid parameters; expecting 2 parameters"; 164 | 165 | retval = CefV8Value::CreateBool(bRet); 166 | } 167 | 168 | ////////////////////////////////////////////////////////////////////////// 169 | 170 | QCefClient::QCefClient(CefRefPtr browser, CefRefPtr frame) 171 | : object_(CefV8Value::CreateObject(nullptr, nullptr)) 172 | , browser_(browser) 173 | , frame_(frame) 174 | { 175 | // create function handler 176 | CefRefPtr handler = new V8Handler(browser_, frame_, eventListenerListMap_); 177 | 178 | // create function function 179 | CefRefPtr funcInvokeMethod = CefV8Value::CreateFunction(QCEF_INVOKEMETHOD, handler); 180 | // add this function to window object 181 | object_->SetValue(QCEF_INVOKEMETHOD, funcInvokeMethod, V8_PROPERTY_ATTRIBUTE_READONLY); 182 | 183 | // create function function 184 | CefRefPtr funcAddEventListener = CefV8Value::CreateFunction(QCEF_ADDEVENTLISTENER, handler); 185 | // add this function to window object 186 | object_->SetValue(QCEF_ADDEVENTLISTENER, funcAddEventListener, V8_PROPERTY_ATTRIBUTE_READONLY); 187 | 188 | // create function function 189 | CefRefPtr funcRemoveEventListener = CefV8Value::CreateFunction(QCEF_REMOVEEVENTLISTENER, handler); 190 | // add this function to window object 191 | object_->SetValue(QCEF_REMOVEEVENTLISTENER, funcRemoveEventListener, V8_PROPERTY_ATTRIBUTE_READONLY); 192 | } 193 | 194 | CefRefPtr 195 | QCefClient::GetObject() 196 | { 197 | return object_; 198 | } 199 | 200 | void 201 | QCefClient::ExecuteEventListener(const CefString eventName, CefRefPtr dict) 202 | { 203 | auto itListenerList = eventListenerListMap_.find(eventName); 204 | if (itListenerList != eventListenerListMap_.end()) { 205 | EventListenerList& eventListenerList = itListenerList->second; 206 | for (auto listener : eventListenerList) { 207 | listener.context_->Enter(); 208 | 209 | CefRefPtr eventObject = CefV8Value::CreateObject(nullptr, nullptr); 210 | CefDictionaryValue::KeyList kyes; 211 | dict->GetKeys(kyes); 212 | CefRefPtr value; 213 | CefRefPtr v8Value; 214 | for (const CefString key : kyes) { 215 | value = dict->GetValue(key); 216 | if (VTYPE_BOOL == value->GetType()) 217 | v8Value = CefV8Value::CreateBool(value->GetBool()); 218 | else if (VTYPE_INT == value->GetType()) 219 | v8Value = CefV8Value::CreateInt(value->GetInt()); 220 | else if (VTYPE_DOUBLE == value->GetType()) 221 | v8Value = CefV8Value::CreateDouble(value->GetDouble()); 222 | else if (VTYPE_STRING == value->GetType()) 223 | v8Value = CefV8Value::CreateString(value->GetString()); 224 | else 225 | continue; 226 | 227 | eventObject->SetValue(key, v8Value, V8_PROPERTY_ATTRIBUTE_READONLY); 228 | } 229 | 230 | CefV8ValueList arguments; 231 | arguments.push_back(eventObject); 232 | 233 | listener.callback_->ExecuteFunction(object_, arguments); 234 | listener.context_->Exit(); 235 | } 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /src/QCefWing/CefViewRenderApp/QCefViewRenderApp.h: -------------------------------------------------------------------------------- 1 | #ifndef QCEFVIEWRENDERAPP_H_ 2 | #define QCEFVIEWRENDERAPP_H_ 3 | #pragma once 4 | 5 | #pragma region std_headers 6 | #include 7 | #pragma endregion std_headers 8 | 9 | #pragma region cef_headers 10 | #include 11 | #pragma endregion cef_headers 12 | 13 | /// 14 | /// 15 | /// 16 | class QCefViewRenderApp 17 | : public CefApp 18 | , public CefRenderProcessHandler 19 | { 20 | public: 21 | /// 22 | /// 23 | /// 24 | QCefViewRenderApp(const CefString& name); 25 | 26 | /// 27 | /// 28 | /// 29 | ~QCefViewRenderApp(); 30 | 31 | /// 32 | /// 33 | /// 34 | class RenderDelegate : public virtual CefBaseRefCounted 35 | { 36 | public: 37 | /// 38 | /// 39 | /// 40 | /// 41 | virtual void OnWebKitInitialized(CefRefPtr app) {} 42 | 43 | /// 44 | /// 45 | /// 46 | /// 47 | /// 48 | virtual void OnBrowserCreated(CefRefPtr app, 49 | CefRefPtr browser, 50 | CefRefPtr extra_info) 51 | {} 52 | 53 | /// 54 | /// 55 | /// 56 | /// 57 | /// 58 | virtual void OnBrowserDestroyed(CefRefPtr app, CefRefPtr browser) {} 59 | 60 | /// 61 | /// 62 | /// 63 | /// 64 | /// 65 | virtual CefRefPtr GetLoadHandler(CefRefPtr app) { return nullptr; } 66 | 67 | /// 68 | /// 69 | /// 70 | /// 71 | /// 72 | /// 73 | /// 74 | virtual void OnContextCreated(CefRefPtr app, 75 | CefRefPtr browser, 76 | CefRefPtr frame, 77 | CefRefPtr context) 78 | {} 79 | 80 | /// 81 | /// 82 | /// 83 | /// 84 | /// 85 | /// 86 | /// 87 | virtual void OnContextReleased(CefRefPtr app, 88 | CefRefPtr browser, 89 | CefRefPtr frame, 90 | CefRefPtr context) 91 | {} 92 | 93 | /// 94 | /// 95 | /// 96 | /// 97 | /// 98 | /// 99 | /// 100 | /// 101 | /// 102 | virtual void OnUncaughtException(CefRefPtr app, 103 | CefRefPtr browser, 104 | CefRefPtr frame, 105 | CefRefPtr context, 106 | CefRefPtr exception, 107 | CefRefPtr stackTrace) 108 | {} 109 | 110 | /// 111 | /// 112 | /// 113 | /// 114 | /// 115 | /// 116 | /// 117 | virtual void OnFocusedNodeChanged(CefRefPtr app, 118 | CefRefPtr browser, 119 | CefRefPtr frame, 120 | CefRefPtr node) 121 | {} 122 | 123 | // Called when a process message is received. Return true if the message was 124 | // handled and should not be passed on to other handlers. RenderDelegates 125 | // should check for unique message names to avoid interfering with each 126 | // other. 127 | /// 128 | /// 129 | /// 130 | /// 131 | /// 132 | /// 133 | /// 134 | /// 135 | virtual bool OnProcessMessageReceived(CefRefPtr app, 136 | CefRefPtr browser, 137 | CefRefPtr frame, 138 | CefProcessId source_process, 139 | CefRefPtr message) 140 | { 141 | return false; 142 | } 143 | }; 144 | 145 | /// 146 | /// 147 | /// 148 | typedef std::set> RenderDelegateSet; 149 | 150 | private: 151 | 152 | #pragma region CefApp 153 | 154 | ////////////////////////////////////////////////////////////////////////// 155 | // CefApp methods: 156 | /// 157 | /// 158 | /// 159 | /// 160 | /// 161 | virtual void OnBeforeCommandLineProcessing(const CefString& process_type, 162 | CefRefPtr command_line) override; 163 | 164 | /// 165 | /// 166 | /// 167 | /// 168 | virtual void OnRegisterCustomSchemes(CefRawPtr registrar) override; 169 | 170 | /// 171 | /// 172 | /// 173 | /// 174 | virtual CefRefPtr GetResourceBundleHandler() override; 175 | 176 | /// 177 | /// 178 | /// 179 | /// 180 | virtual CefRefPtr GetBrowserProcessHandler() override; 181 | 182 | /// 183 | /// 184 | /// 185 | /// 186 | virtual CefRefPtr GetRenderProcessHandler() override; 187 | 188 | #pragma endregion CefApp 189 | 190 | #pragma region CefRenderProcessHandler 191 | 192 | /// 193 | /// 194 | /// 195 | virtual void OnWebKitInitialized() override; 196 | 197 | /// 198 | /// 199 | /// 200 | /// 201 | /// 202 | virtual void OnBrowserCreated(CefRefPtr browser, CefRefPtr extra_info) override; 203 | 204 | /// 205 | /// 206 | /// 207 | /// 208 | virtual void OnBrowserDestroyed(CefRefPtr browser) override; 209 | 210 | /// 211 | /// 212 | /// 213 | /// 214 | virtual CefRefPtr GetLoadHandler() override; 215 | 216 | /// 217 | /// 218 | /// 219 | /// 220 | /// 221 | /// 222 | virtual void OnContextCreated(CefRefPtr browser, 223 | CefRefPtr frame, 224 | CefRefPtr context) override; 225 | 226 | /// 227 | /// 228 | /// 229 | /// 230 | /// 231 | /// 232 | virtual void OnContextReleased(CefRefPtr browser, 233 | CefRefPtr frame, 234 | CefRefPtr context) override; 235 | 236 | /// 237 | /// 238 | /// 239 | /// 240 | /// 241 | /// 242 | /// 243 | /// 244 | virtual void OnUncaughtException(CefRefPtr browser, 245 | CefRefPtr frame, 246 | CefRefPtr context, 247 | CefRefPtr exception, 248 | CefRefPtr stackTrace) override; 249 | 250 | /// 251 | /// 252 | /// 253 | /// 254 | /// 255 | /// 256 | virtual void OnFocusedNodeChanged(CefRefPtr browser, 257 | CefRefPtr frame, 258 | CefRefPtr node) override; 259 | 260 | /// 261 | /// 262 | /// 263 | /// 264 | /// 265 | /// 266 | /// 267 | /// 268 | virtual bool OnProcessMessageReceived(CefRefPtr browser, 269 | CefRefPtr frame, 270 | CefProcessId source_process, 271 | CefRefPtr message) override; 272 | 273 | #pragma endregion CefRenderProcessHandler 274 | 275 | private: 276 | /// 277 | /// 278 | /// 279 | CefString bridge_object_name_; 280 | 281 | // Set of supported RenderDelegates. Only used in the renderer process. 282 | /// 283 | /// 284 | /// 285 | RenderDelegateSet render_delegates_; 286 | 287 | // Include the default reference counting implementation. 288 | IMPLEMENT_REFCOUNTING(QCefViewRenderApp); 289 | }; 290 | 291 | #endif // QCEFVIEWRENDERAPP_H_ 292 | -------------------------------------------------------------------------------- /src/QCefView/CefViewBrowserApp/QCefViewBrowserHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef QCEFVIEWHANDLER_H_ 2 | #define QCEFVIEWHANDLER_H_ 3 | #pragma once 4 | 5 | #pragma region std_headers 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #pragma endregion std_headers 12 | 13 | #pragma region cef_headers 14 | #include 15 | #include 16 | #include 17 | #pragma endregion cef_headers 18 | 19 | #include "../CCefWindow.h" 20 | #include "QCefQueryHandler.h" 21 | #include "QCefViewDelegate.h" 22 | 23 | class QCefViewBrowserHandler 24 | : public CefClient 25 | , public CefContextMenuHandler 26 | , public CefDisplayHandler 27 | , public CefDragHandler 28 | , public CefFocusHandler 29 | , public CefJSDialogHandler 30 | , public CefKeyboardHandler 31 | , public CefLifeSpanHandler 32 | , public CefLoadHandler 33 | , public CefRequestHandler 34 | , public CefResourceRequestHandler 35 | { 36 | public: 37 | /// 38 | /// 39 | /// 40 | enum 41 | { 42 | MAIN_FRAME = (int64_t)0, 43 | ALL_FRAMES = (int64_t)-1, 44 | }; 45 | 46 | /// /// 47 | /// 48 | /// 49 | /// 50 | QCefViewBrowserHandler(QCefViewDelegate* pDelegate); 51 | 52 | /// 53 | /// 54 | /// 55 | ~QCefViewBrowserHandler(); 56 | 57 | #pragma region CefClient 58 | 59 | ////////////////////////////////////////////////////////////////////////// 60 | // CefClient methods: 61 | virtual CefRefPtr GetContextMenuHandler() override 62 | { 63 | return pContextMenuHandler_ ? pContextMenuHandler_ : this; 64 | } 65 | virtual CefRefPtr GetDialogHandler() override { return pDialogHandler_; } 66 | virtual CefRefPtr GetDisplayHandler() override 67 | { 68 | return pDisplayHandler_ ? pDisplayHandler_ : this; 69 | } 70 | virtual CefRefPtr GetDownloadHandler() override { return pDownloadHandler_; } 71 | virtual CefRefPtr GetDragHandler() override { return this; } 72 | virtual CefRefPtr GetJSDialogHandler() override 73 | { 74 | return pJSDialogHandler_ ? pJSDialogHandler_ : this; 75 | } 76 | virtual CefRefPtr GetKeyboardHandler() override 77 | { 78 | return pKeyboardHandler_ ? pKeyboardHandler_ : this; 79 | } 80 | virtual CefRefPtr GetFocusHandler() override { return this; } 81 | virtual CefRefPtr GetLifeSpanHandler() override { return this; } 82 | virtual CefRefPtr GetLoadHandler() override { return this; } 83 | virtual CefRefPtr GetRequestHandler() override { return this; } 84 | 85 | virtual bool OnProcessMessageReceived(CefRefPtr browser, 86 | CefRefPtr frame, 87 | CefProcessId source_process, 88 | CefRefPtr message) override; 89 | 90 | #pragma endregion CefClient 91 | 92 | #pragma region CefContextMenuHandler 93 | 94 | // CefContextMenuHandler methods 95 | virtual void OnBeforeContextMenu(CefRefPtr browser, 96 | CefRefPtr frame, 97 | CefRefPtr params, 98 | CefRefPtr model) override; 99 | virtual bool OnContextMenuCommand(CefRefPtr browser, 100 | CefRefPtr frame, 101 | CefRefPtr params, 102 | int command_id, 103 | EventFlags event_flags) override; 104 | 105 | #pragma endregion CefContextMenuHandler 106 | 107 | #pragma region CefDisplayHandler 108 | 109 | // CefDisplayHandler methods 110 | virtual void OnAddressChange(CefRefPtr browser, CefRefPtr frame, const CefString& url) override; 111 | virtual void OnTitleChange(CefRefPtr browser, const CefString& title) override; 112 | virtual bool OnConsoleMessage(CefRefPtr browser, 113 | cef_log_severity_t level, 114 | const CefString& message, 115 | const CefString& source, 116 | int line) override; 117 | 118 | #pragma endregion CefDisplayHandler 119 | 120 | #pragma region CefDragHandler 121 | 122 | // CefDragHandler methods 123 | virtual bool OnDragEnter(CefRefPtr browser, 124 | CefRefPtr dragData, 125 | CefDragHandler::DragOperationsMask mask) override; 126 | 127 | virtual void OnDraggableRegionsChanged(CefRefPtr browser, 128 | CefRefPtr frame, 129 | const std::vector& regions) override; 130 | 131 | #pragma endregion CefDragHandler 132 | 133 | #pragma region CefJSDialogHandler 134 | 135 | // CefJSDialogHandler methods 136 | virtual bool OnJSDialog(CefRefPtr browser, 137 | const CefString& origin_url, 138 | JSDialogType dialog_type, 139 | const CefString& message_text, 140 | const CefString& default_prompt_text, 141 | CefRefPtr callback, 142 | bool& suppress_message) override; 143 | 144 | virtual bool OnBeforeUnloadDialog(CefRefPtr browser, 145 | const CefString& message_text, 146 | bool is_reload, 147 | CefRefPtr callback) override; 148 | virtual void OnResetDialogState(CefRefPtr browser) override; 149 | 150 | #pragma endregion CefJSDialogHandler 151 | 152 | #pragma region CefFocusHandler 153 | 154 | // CefFocusHandler methods 155 | virtual void OnTakeFocus(CefRefPtr browser, bool next) override; 156 | 157 | virtual bool OnSetFocus(CefRefPtr browser, FocusSource source) override; 158 | 159 | virtual void OnGotFocus(CefRefPtr browser) override; 160 | 161 | #pragma endregion CefFocusHandler 162 | 163 | #pragma region CefKeyboardHandler 164 | 165 | // CefKeyboardHandler methods 166 | virtual bool OnPreKeyEvent(CefRefPtr browser, 167 | const CefKeyEvent& event, 168 | CefEventHandle os_event, 169 | bool* is_keyboard_shortcut) override; 170 | 171 | #pragma endregion CefKeyboardHandler 172 | 173 | #pragma region CefLifeSpanHandler 174 | 175 | // CefLifeSpanHandler methods: 176 | virtual bool OnBeforePopup(CefRefPtr browser, 177 | CefRefPtr frame, 178 | const CefString& target_url, 179 | const CefString& target_frame_name, 180 | CefLifeSpanHandler::WindowOpenDisposition target_disposition, 181 | bool user_gesture, 182 | const CefPopupFeatures& popupFeatures, 183 | CefWindowInfo& windowInfo, 184 | CefRefPtr& client, 185 | CefBrowserSettings& settings, 186 | CefRefPtr& extra_info, 187 | bool* no_javascript_access) override; 188 | virtual void OnAfterCreated(CefRefPtr browser) override; 189 | virtual bool DoClose(CefRefPtr browser) override; 190 | virtual void OnBeforeClose(CefRefPtr browser) override; 191 | 192 | #pragma endregion CefLifeSpanHandler 193 | 194 | #pragma region CefLoadHandler 195 | 196 | // CefLoadHandler methods 197 | virtual void OnLoadingStateChange(CefRefPtr browser, 198 | bool isLoading, 199 | bool canGoBack, 200 | bool canGoForward) override; 201 | virtual void OnLoadStart(CefRefPtr browser, 202 | CefRefPtr frame, 203 | TransitionType transition_type) override; 204 | virtual void OnLoadEnd(CefRefPtr browser, CefRefPtr frame, int httpStatusCode) override; 205 | virtual void OnLoadError(CefRefPtr browser, 206 | CefRefPtr frame, 207 | ErrorCode errorCode, 208 | const CefString& errorText, 209 | const CefString& failedUrl) override; 210 | 211 | #pragma endregion CefLoadHandler 212 | 213 | #pragma region CefRequestHandler 214 | 215 | // CefRequestHandler methods 216 | virtual bool OnBeforeBrowse(CefRefPtr browser, 217 | CefRefPtr frame, 218 | CefRefPtr request, 219 | bool user_gesture, 220 | bool is_redirect) override; 221 | 222 | virtual bool OnOpenURLFromTab(CefRefPtr browser, 223 | CefRefPtr frame, 224 | const CefString& target_url, 225 | CefRequestHandler::WindowOpenDisposition target_disposition, 226 | bool user_gesture) override; 227 | 228 | virtual CefRefPtr GetResourceRequestHandler(CefRefPtr browser, 229 | CefRefPtr frame, 230 | CefRefPtr request, 231 | bool is_navigation, 232 | bool is_download, 233 | const CefString& request_initiator, 234 | bool& disable_default_handling) override; 235 | 236 | virtual bool OnQuotaRequest(CefRefPtr browser, 237 | const CefString& origin_url, 238 | int64 new_size, 239 | CefRefPtr callback) override; 240 | 241 | virtual void OnRenderProcessTerminated(CefRefPtr browser, TerminationStatus status) override; 242 | 243 | #pragma endregion CefRequestHandler 244 | 245 | #pragma region CefResourceRequestHandler 246 | 247 | virtual ReturnValue OnBeforeResourceLoad(CefRefPtr browser, 248 | CefRefPtr frame, 249 | CefRefPtr request, 250 | CefRefPtr callback) override; 251 | 252 | virtual CefRefPtr GetResourceHandler(CefRefPtr browser, 253 | CefRefPtr frame, 254 | CefRefPtr request) override; 255 | 256 | virtual void OnProtocolExecution(CefRefPtr browser, 257 | CefRefPtr frame, 258 | CefRefPtr request, 259 | bool& allow_os_execution) override; 260 | 261 | #pragma endregion CefResourceRequestHandler 262 | 263 | ////////////////////////////////////////////////////////////////////////// 264 | 265 | CefRefPtr GetBrowser() const; 266 | 267 | void AddLocalDirectoryResourceProvider(const std::string& dir_path, const std::string& url, int priority = 0); 268 | 269 | void AddArchiveResourceProvider(const std::string& archive_path, 270 | const std::string& url, 271 | const std::string& password, 272 | int priority = 0); 273 | 274 | // Request that all existing browser windows close. 275 | void CloseAllBrowsers(bool force_close); 276 | 277 | bool TriggerEvent(const int64_t frame_id, const CefRefPtr msg); 278 | 279 | bool ResponseQuery(const int64_t query, bool success, const CefString& response, int error); 280 | 281 | bool DispatchNotifyRequest(CefRefPtr browser, 282 | CefProcessId source_process, 283 | CefRefPtr message); 284 | 285 | void NotifyTakeFocus(bool next); 286 | 287 | void NotifyDragRegion(const std::vector regions); 288 | 289 | void SetContextMenuHandler(CefRefPtr handler) { pContextMenuHandler_ = handler; } 290 | 291 | void SetDialogHandler(CefRefPtr handler) { pDialogHandler_ = handler; } 292 | 293 | void SetDisplayHandler(CefRefPtr handler) { pDisplayHandler_ = handler; } 294 | 295 | void SetDownloadHandler(CefRefPtr handler) { pDownloadHandler_ = handler; } 296 | 297 | void SetJSDialogHandler(CefRefPtr handler) { pJSDialogHandler_ = handler; } 298 | 299 | void SetKeyboardHandler(CefRefPtr handler) { pKeyboardHandler_ = handler; } 300 | 301 | private: 302 | /// 303 | /// 304 | /// 305 | QCefViewDelegate* pQCefViewDelegate_; 306 | 307 | /// 308 | /// 309 | /// 310 | int browser_count_; 311 | 312 | /// 313 | /// 314 | /// 315 | bool is_closing_; 316 | 317 | /// 318 | /// 319 | /// 320 | bool initial_navigation_; 321 | 322 | /// 323 | /// 324 | /// 325 | mutable std::mutex mtx_; 326 | 327 | /// 328 | /// 329 | /// 330 | mutable std::condition_variable close_cv_; 331 | 332 | /// 333 | /// 334 | /// 335 | CefRefPtr main_browser_; 336 | 337 | /// 338 | /// List of existing browser windows. Only accessed on the CEF UI thread. 339 | /// 340 | std::list> popup_browser_list_; 341 | 342 | /// 343 | /// 344 | /// 345 | CefRefPtr resource_manager_; 346 | 347 | /// 348 | /// 349 | /// 350 | CefRefPtr message_router_; 351 | 352 | /// 353 | /// 354 | /// 355 | CefRefPtr cefquery_handler_; 356 | 357 | CefRefPtr pContextMenuHandler_; 358 | CefRefPtr pDialogHandler_; 359 | CefRefPtr pDisplayHandler_; 360 | CefRefPtr pDownloadHandler_; 361 | CefRefPtr pJSDialogHandler_; 362 | CefRefPtr pKeyboardHandler_; 363 | 364 | // Include the default reference counting implementation. 365 | IMPLEMENT_REFCOUNTING(QCefViewBrowserHandler); 366 | }; 367 | #endif 368 | -------------------------------------------------------------------------------- /src/QCefView/QCefView.cpp: -------------------------------------------------------------------------------- 1 | #pragma region qt_headers 2 | #include 3 | #include 4 | #include 5 | #include 6 | #pragma endregion qt_headers 7 | 8 | #pragma region cef_headers 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #pragma endregion cef_headers 15 | 16 | #include 17 | 18 | #include "Include/QCefQuery.h" 19 | #include "Include/QCefView.h" 20 | #include "Include/QCefEvent.h" 21 | #include "CCefManager.h" 22 | #include "CCefWindow.h" 23 | #include "CCefSetting.h" 24 | #include "CefViewBrowserApp/QCefViewBrowserHandler.h" 25 | 26 | ////////////////////////////////////////////////////////////////////////// 27 | class QCefView::Implementation 28 | { 29 | public: 30 | explicit Implementation(const QString& url, QCefView* view) 31 | : pCefWindow_(nullptr) 32 | , pQCefViewHandler_(nullptr) 33 | { 34 | // Here we must create a QWidget as a wrapper to encapsulate the QWindow 35 | pCefWindow_ = new CCefWindow(view); 36 | pCefWindow_->create(); 37 | 38 | // Set window info 39 | CefWindowInfo window_info; 40 | RECT rc = { 0 }; 41 | window_info.SetAsChild((HWND)pCefWindow_->winId(), rc); 42 | 43 | for (auto cookieItem : CCefSetting::global_cookie_list) { 44 | CCefManager::getInstance().addCookie(cookieItem.name, cookieItem.value, cookieItem.domain, cookieItem.url); 45 | } 46 | 47 | CefBrowserSettings browserSettings; 48 | browserSettings.plugins = STATE_DISABLED; // disable all plugins 49 | 50 | // Create the browser 51 | pQCefViewHandler_ = new QCefViewBrowserHandler(pCefWindow_); 52 | 53 | // add archive mapping 54 | for (auto archiveMapping : archiveMappingList_) { 55 | pQCefViewHandler_->AddArchiveResourceProvider( 56 | archiveMapping.path.toStdString(), archiveMapping.url.toStdString(), archiveMapping.psw.toStdString()); 57 | } 58 | 59 | // add local folder mapping 60 | for (auto folderMapping : folderMappingList_) { 61 | pQCefViewHandler_->AddLocalDirectoryResourceProvider( 62 | folderMapping.path.toStdString(), folderMapping.url.toStdString(), folderMapping.priority); 63 | } 64 | 65 | // Create the main browser window. 66 | if (!CefBrowserHost::CreateBrowser(window_info, // window info 67 | pQCefViewHandler_, // handler 68 | url.toStdString(), // url 69 | browserSettings, // settings 70 | nullptr, 71 | CefRequestContext::GetGlobalContext())) { 72 | throw std::exception("Failed to create browser."); 73 | } 74 | } 75 | 76 | ~Implementation() 77 | { 78 | if (pQCefViewHandler_) { 79 | pQCefViewHandler_->CloseAllBrowsers(true); 80 | pQCefViewHandler_ = nullptr; 81 | } 82 | } 83 | 84 | void closeAllBrowsers() 85 | { 86 | if (pQCefViewHandler_) { 87 | pQCefViewHandler_->CloseAllBrowsers(true); 88 | } 89 | } 90 | 91 | CCefWindow* cefWindow() { return pCefWindow_; } 92 | 93 | WId getCefWinId() 94 | { 95 | if (pCefWindow_) 96 | return pCefWindow_->winId(); 97 | 98 | return 0; 99 | } 100 | 101 | void addLocalFolderResource(const QString& path, const QString& url) 102 | { 103 | if (pQCefViewHandler_) { 104 | pQCefViewHandler_->AddLocalDirectoryResourceProvider(path.toStdString(), url.toStdString()); 105 | } 106 | } 107 | 108 | void addArchiveResource(const QString& path, const QString& url, const QString& password) 109 | { 110 | if (pQCefViewHandler_) { 111 | pQCefViewHandler_->AddArchiveResourceProvider(path.toStdString(), url.toStdString(), password.toStdString()); 112 | } 113 | } 114 | 115 | void navigateToString(const QString& content) 116 | { 117 | if (pQCefViewHandler_) { 118 | std::string data = content.toStdString(); 119 | data = CefURIEncode(CefBase64Encode(data.c_str(), data.size()), false).ToString(); 120 | data = "data:text/html;base64," + data; 121 | pQCefViewHandler_->GetBrowser()->GetMainFrame()->LoadURL(data); 122 | } 123 | } 124 | 125 | void navigateToUrl(const QString& url) 126 | { 127 | if (pQCefViewHandler_) { 128 | CefString strUrl; 129 | strUrl.FromString(url.toStdString()); 130 | pQCefViewHandler_->GetBrowser()->GetMainFrame()->LoadURL(strUrl); 131 | } 132 | } 133 | 134 | bool browserCanGoBack() 135 | { 136 | if (pQCefViewHandler_) 137 | return pQCefViewHandler_->GetBrowser()->CanGoBack(); 138 | 139 | return false; 140 | } 141 | 142 | bool browserCanGoForward() 143 | { 144 | if (pQCefViewHandler_) 145 | return pQCefViewHandler_->GetBrowser()->CanGoForward(); 146 | 147 | return false; 148 | } 149 | 150 | void browserGoBack() 151 | { 152 | if (pQCefViewHandler_) 153 | pQCefViewHandler_->GetBrowser()->GoBack(); 154 | } 155 | 156 | void browserGoForward() 157 | { 158 | if (pQCefViewHandler_) 159 | pQCefViewHandler_->GetBrowser()->GoForward(); 160 | } 161 | 162 | bool browserIsLoading() 163 | { 164 | if (pQCefViewHandler_) 165 | return pQCefViewHandler_->GetBrowser()->IsLoading(); 166 | 167 | return false; 168 | } 169 | 170 | void browserReload() 171 | { 172 | if (pQCefViewHandler_) 173 | pQCefViewHandler_->GetBrowser()->Reload(); 174 | } 175 | 176 | void browserStopLoad() 177 | { 178 | if (pQCefViewHandler_) 179 | pQCefViewHandler_->GetBrowser()->StopLoad(); 180 | } 181 | 182 | bool triggerEvent(const QString& name, const QCefEvent& event, int frameId = QCefViewBrowserHandler::MAIN_FRAME) 183 | { 184 | if (!name.isEmpty()) { 185 | return sendEventNotifyMessage(frameId, name, event); 186 | } 187 | 188 | return false; 189 | } 190 | 191 | bool responseQCefQuery(const QCefQuery& query) 192 | { 193 | if (pQCefViewHandler_) { 194 | CefString res; 195 | res.FromString(query.response().toStdString()); 196 | return pQCefViewHandler_->ResponseQuery(query.id(), query.result(), res, query.error()); 197 | } 198 | return false; 199 | } 200 | 201 | void notifyMoveOrResizeStarted() 202 | { 203 | if (pQCefViewHandler_) { 204 | CefRefPtr browser = pQCefViewHandler_->GetBrowser(); 205 | if (browser) { 206 | CefRefPtr host = browser->GetHost(); 207 | if (host) 208 | host->NotifyMoveOrResizeStarted(); 209 | } 210 | } 211 | } 212 | 213 | bool sendEventNotifyMessage(int frameId, const QString& name, const QCefEvent& event) 214 | { 215 | CefRefPtr msg = CefProcessMessage::Create(TRIGGEREVENT_NOTIFY_MESSAGE); 216 | CefRefPtr arguments = msg->GetArgumentList(); 217 | 218 | int idx = 0; 219 | CefString eventName = name.toStdString(); 220 | arguments->SetString(idx++, eventName); 221 | 222 | CefRefPtr dict = CefDictionaryValue::Create(); 223 | 224 | CefString cefStr; 225 | cefStr.FromString(event.objectName().toUtf8().constData()); 226 | dict->SetString("name", cefStr); 227 | 228 | QList keys = event.dynamicPropertyNames(); 229 | for (QByteArray key : keys) { 230 | QVariant value = event.property(key.data()); 231 | if (value.type() == QMetaType::Bool) 232 | dict->SetBool(key.data(), value.toBool()); 233 | else if (value.type() == QMetaType::Int || value.type() == QMetaType::UInt) 234 | dict->SetInt(key.data(), value.toInt()); 235 | else if (value.type() == QMetaType::Double) 236 | dict->SetDouble(key.data(), value.toDouble()); 237 | else if (value.type() == QMetaType::QString) { 238 | cefStr.FromString(value.toString().toUtf8().constData()); 239 | dict->SetString(key.data(), cefStr); 240 | } else { 241 | } 242 | } 243 | 244 | arguments->SetDictionary(idx++, dict); 245 | 246 | return pQCefViewHandler_->TriggerEvent(frameId, msg); 247 | } 248 | 249 | void onToplevelWidgetMoveOrResize() { notifyMoveOrResizeStarted(); } 250 | 251 | void setContextMenuHandler(CefContextMenuHandler* handler) 252 | { 253 | if (pQCefViewHandler_) 254 | pQCefViewHandler_->SetContextMenuHandler(handler); 255 | } 256 | 257 | void setDialogHandler(CefDialogHandler* handler) 258 | { 259 | if (pQCefViewHandler_) 260 | pQCefViewHandler_->SetDialogHandler(handler); 261 | } 262 | 263 | void setDisplayHandler(CefDisplayHandler* handler) 264 | { 265 | if (pQCefViewHandler_) 266 | pQCefViewHandler_->SetDisplayHandler(handler); 267 | } 268 | 269 | void setDownloadHandler(CefDownloadHandler* handler) 270 | { 271 | if (pQCefViewHandler_) 272 | pQCefViewHandler_->SetDownloadHandler(handler); 273 | } 274 | 275 | void setJSDialogHandler(CefJSDialogHandler* handler) 276 | { 277 | if (pQCefViewHandler_) 278 | pQCefViewHandler_->SetJSDialogHandler(handler); 279 | } 280 | 281 | void setKeyboardHandler(CefKeyboardHandler* handler) 282 | { 283 | if (pQCefViewHandler_) 284 | pQCefViewHandler_->SetKeyboardHandler(handler); 285 | } 286 | 287 | public: 288 | /// 289 | /// 290 | /// 291 | typedef struct FolderMapping 292 | { 293 | QString path; 294 | QString url; 295 | int priority; 296 | } FolderMapping; 297 | static QList folderMappingList_; 298 | 299 | /// 300 | /// 301 | /// 302 | typedef struct ArchiveMapping 303 | { 304 | QString path; 305 | QString url; 306 | QString psw; 307 | } ArchiveMapping; 308 | static QList archiveMappingList_; 309 | 310 | private: 311 | /// 312 | /// 313 | /// 314 | QPointer pCefWindow_; 315 | 316 | /// 317 | /// 318 | /// 319 | CefRefPtr pQCefViewHandler_; 320 | }; 321 | 322 | QList QCefView::Implementation::folderMappingList_; 323 | QList QCefView::Implementation::archiveMappingList_; 324 | 325 | QCefView::QCefView(const QString url, QWidget* parent /*= 0*/) 326 | : QWidget(parent) 327 | , pImpl_(nullptr) 328 | { 329 | pImpl_ = std::make_unique(url, this); 330 | 331 | QVBoxLayout* layout = new QVBoxLayout(this); 332 | layout->setContentsMargins(0, 0, 0, 0); 333 | setLayout(layout); 334 | 335 | QWidget* windowContainer = createWindowContainer(pImpl_->cefWindow(), this); 336 | layout->addWidget(windowContainer); 337 | 338 | // If we're already part of a window, we'll install our event handler 339 | // If our parent changes later, this will be handled in QCefView::changeEvent() 340 | if (this->window()) 341 | this->window()->installEventFilter(this); 342 | } 343 | 344 | QCefView::QCefView(QWidget* parent /*= 0*/) 345 | : QCefView("about:blank", parent) 346 | {} 347 | 348 | QCefView::~QCefView() 349 | { 350 | disconnect(); 351 | 352 | if (pImpl_) 353 | pImpl_.reset(); 354 | } 355 | 356 | void 357 | QCefView::addLocalFolderResource(const QString& path, const QString& url, int priority /* = 0*/) 358 | { 359 | Implementation::folderMappingList_.push_back({ path, url, priority }); 360 | } 361 | 362 | void 363 | QCefView::addArchiveResource(const QString& path, const QString& url, const QString& password /* = ""*/) 364 | { 365 | Implementation::archiveMappingList_.push_back({ path, url, password }); 366 | } 367 | 368 | void 369 | QCefView::addCookie(const QString& name, const QString& value, const QString& domain, const QString& url) 370 | { 371 | CCefManager::getInstance().addCookie( 372 | name.toStdString(), value.toStdString(), domain.toStdString(), url.toStdString()); 373 | } 374 | 375 | WId 376 | QCefView::getCefWinId() 377 | { 378 | if (pImpl_) 379 | return pImpl_->getCefWinId(); 380 | 381 | return 0; 382 | } 383 | 384 | void 385 | QCefView::navigateToString(const QString& content) 386 | { 387 | if (pImpl_) 388 | pImpl_->navigateToString(content); 389 | } 390 | 391 | void 392 | QCefView::navigateToUrl(const QString& url) 393 | { 394 | if (pImpl_) 395 | pImpl_->navigateToUrl(url); 396 | } 397 | 398 | bool 399 | QCefView::browserCanGoBack() 400 | { 401 | if (pImpl_) 402 | return pImpl_->browserCanGoBack(); 403 | 404 | return false; 405 | } 406 | 407 | bool 408 | QCefView::browserCanGoForward() 409 | { 410 | if (pImpl_) 411 | return pImpl_->browserCanGoForward(); 412 | 413 | return false; 414 | } 415 | 416 | void 417 | QCefView::browserGoBack() 418 | { 419 | if (pImpl_) 420 | pImpl_->browserGoBack(); 421 | } 422 | 423 | void 424 | QCefView::browserGoForward() 425 | { 426 | if (pImpl_) 427 | pImpl_->browserGoForward(); 428 | } 429 | 430 | bool 431 | QCefView::browserIsLoading() 432 | { 433 | if (pImpl_) 434 | return pImpl_->browserIsLoading(); 435 | 436 | return false; 437 | } 438 | 439 | void 440 | QCefView::browserReload() 441 | { 442 | if (pImpl_) 443 | pImpl_->browserReload(); 444 | } 445 | 446 | void 447 | QCefView::browserStopLoad() 448 | { 449 | if (pImpl_) 450 | pImpl_->browserStopLoad(); 451 | } 452 | 453 | bool 454 | QCefView::triggerEvent(const QCefEvent& event) 455 | { 456 | if (pImpl_) 457 | return pImpl_->triggerEvent(event.objectName(), event, QCefViewBrowserHandler::MAIN_FRAME); 458 | 459 | return false; 460 | } 461 | 462 | bool 463 | QCefView::triggerEvent(const QCefEvent& event, int frameId) 464 | { 465 | if (pImpl_) 466 | return pImpl_->triggerEvent(event.objectName(), event, frameId); 467 | 468 | return false; 469 | } 470 | 471 | bool 472 | QCefView::broadcastEvent(const QCefEvent& event) 473 | { 474 | if (pImpl_) 475 | return pImpl_->triggerEvent(event.objectName(), event, QCefViewBrowserHandler::ALL_FRAMES); 476 | 477 | return false; 478 | } 479 | 480 | bool 481 | QCefView::responseQCefQuery(const QCefQuery& query) 482 | { 483 | if (pImpl_) 484 | return pImpl_->responseQCefQuery(query); 485 | 486 | return false; 487 | } 488 | 489 | void 490 | QCefView::setContextMenuHandler(CefContextMenuHandler* handler) 491 | { 492 | if (pImpl_) 493 | return pImpl_->setContextMenuHandler(handler); 494 | } 495 | 496 | void 497 | QCefView::setDialogHandler(CefDialogHandler* handler) 498 | { 499 | if (pImpl_) 500 | return pImpl_->setDialogHandler(handler); 501 | } 502 | 503 | void 504 | QCefView::setDisplayHandler(CefDisplayHandler* handler) 505 | { 506 | if (pImpl_) 507 | return pImpl_->setDisplayHandler(handler); 508 | } 509 | 510 | void 511 | QCefView::setDownloadHandler(CefDownloadHandler* handler) 512 | { 513 | if (pImpl_) 514 | return pImpl_->setDownloadHandler(handler); 515 | } 516 | 517 | void 518 | QCefView::setJSDialogHandler(CefJSDialogHandler* handler) 519 | { 520 | if (pImpl_) 521 | return pImpl_->setJSDialogHandler(handler); 522 | } 523 | 524 | void 525 | QCefView::setKeyboardHandler(CefKeyboardHandler* handler) 526 | { 527 | if (pImpl_) 528 | return pImpl_->setKeyboardHandler(handler); 529 | } 530 | 531 | void 532 | QCefView::onLoadingStateChanged(bool isLoading, bool canGoBack, bool canGoForward) 533 | {} 534 | 535 | void 536 | QCefView::onLoadStart() 537 | {} 538 | 539 | void 540 | QCefView::onLoadEnd(int httpStatusCode) 541 | {} 542 | 543 | void 544 | QCefView::onLoadError(int errorCode, const QString& errorMsg, const QString& failedUrl, bool& handled) 545 | {} 546 | 547 | void 548 | QCefView::onDraggableRegionChanged(const QRegion& region) 549 | {} 550 | 551 | void 552 | QCefView::onConsoleMessage(const QString& message, int level) 553 | {} 554 | 555 | void 556 | QCefView::onTakeFocus(bool next) 557 | {} 558 | 559 | void 560 | QCefView::onQCefUrlRequest(const QString& url) 561 | {} 562 | 563 | void 564 | QCefView::onQCefQueryRequest(const QCefQuery& query) 565 | {} 566 | 567 | void 568 | QCefView::onInvokeMethodNotify(int browserId, int frameId, const QString& method, const QVariantList& arguments) 569 | {} 570 | 571 | void 572 | QCefView::changeEvent(QEvent* event) 573 | { 574 | if (QEvent::ParentAboutToChange == event->type()) { 575 | if (this->window()) 576 | this->window()->removeEventFilter(this); 577 | } else if (QEvent::ParentChange == event->type()) { 578 | if (this->window()) 579 | this->window()->installEventFilter(this); 580 | } 581 | QWidget::changeEvent(event); 582 | } 583 | 584 | bool 585 | QCefView::eventFilter(QObject* watched, QEvent* event) 586 | { 587 | if (pImpl_ && watched == this->window()) { 588 | if (QEvent::Resize == event->type() || QEvent::Move == event->type()) 589 | pImpl_->onToplevelWidgetMoveOrResize(); 590 | } 591 | return QWidget::eventFilter(watched, event); 592 | } -------------------------------------------------------------------------------- /src/QCefView/CefViewBrowserApp/QCefViewBrowserHandler.cpp: -------------------------------------------------------------------------------- 1 | #pragma region std_headers 2 | #include 3 | #include 4 | #pragma endregion std_headers 5 | 6 | #pragma region cef_headers 7 | #include 8 | #include 9 | #include 10 | #include 11 | #pragma endregion cef_headers 12 | 13 | #include 14 | 15 | #include "QCefViewBrowserHandler.h" 16 | #include "SchemeHandlers/QCefViewDefaultSchemeHandler.h" 17 | 18 | QCefViewBrowserHandler::QCefViewBrowserHandler(QCefViewDelegate* pDelegate) 19 | : is_closing_(false) 20 | , initial_navigation_(false) 21 | , pQCefViewDelegate_(pDelegate) 22 | , cefquery_handler_(new QCefQueryHandler(pDelegate)) 23 | , resource_manager_(new CefResourceManager()) 24 | , message_router_(nullptr) 25 | , browser_count_(0) 26 | {} 27 | 28 | QCefViewBrowserHandler::~QCefViewBrowserHandler() {} 29 | 30 | bool 31 | QCefViewBrowserHandler::OnProcessMessageReceived(CefRefPtr browser, 32 | CefRefPtr frame, 33 | CefProcessId source_process, 34 | CefRefPtr message) 35 | { 36 | CEF_REQUIRE_UI_THREAD(); 37 | if (message_router_->OnProcessMessageReceived(browser, frame, source_process, message)) 38 | return true; 39 | 40 | if (DispatchNotifyRequest(browser, source_process, message)) 41 | return true; 42 | 43 | return false; 44 | } 45 | 46 | void 47 | QCefViewBrowserHandler::OnBeforeContextMenu(CefRefPtr browser, 48 | CefRefPtr frame, 49 | CefRefPtr params, 50 | CefRefPtr model) 51 | { 52 | CEF_REQUIRE_UI_THREAD(); 53 | 54 | model->Clear(); 55 | } 56 | 57 | bool 58 | QCefViewBrowserHandler::OnContextMenuCommand(CefRefPtr browser, 59 | CefRefPtr frame, 60 | CefRefPtr params, 61 | int command_id, 62 | EventFlags event_flags) 63 | { 64 | CEF_REQUIRE_UI_THREAD(); 65 | 66 | return false; 67 | } 68 | 69 | void 70 | QCefViewBrowserHandler::OnAddressChange(CefRefPtr browser, CefRefPtr frame, const CefString& url) 71 | { 72 | CEF_REQUIRE_UI_THREAD(); 73 | } 74 | 75 | void 76 | QCefViewBrowserHandler::OnTitleChange(CefRefPtr browser, const CefString& title) 77 | { 78 | CEF_REQUIRE_UI_THREAD(); 79 | } 80 | 81 | bool 82 | QCefViewBrowserHandler::OnConsoleMessage(CefRefPtr browser, 83 | cef_log_severity_t level, 84 | const CefString& message, 85 | const CefString& source, 86 | int line) 87 | { 88 | CEF_REQUIRE_UI_THREAD(); 89 | 90 | if (pQCefViewDelegate_) 91 | pQCefViewDelegate_->onConsoleMessage(message, level); 92 | 93 | #if (defined(DEBUG) || defined(_DEBUG) || !defined(NDEBUG)) 94 | return false; 95 | #else 96 | return true; 97 | #endif 98 | } 99 | 100 | bool 101 | QCefViewBrowserHandler::OnDragEnter(CefRefPtr browser, 102 | CefRefPtr dragData, 103 | CefDragHandler::DragOperationsMask mask) 104 | { 105 | CEF_REQUIRE_UI_THREAD(); 106 | 107 | return true; 108 | } 109 | 110 | void 111 | QCefViewBrowserHandler::OnDraggableRegionsChanged(CefRefPtr browser, 112 | CefRefPtr frame, 113 | const std::vector& regions) 114 | { 115 | CEF_REQUIRE_UI_THREAD(); 116 | 117 | NotifyDragRegion(regions); 118 | 119 | return; 120 | } 121 | 122 | bool 123 | QCefViewBrowserHandler::OnJSDialog(CefRefPtr browser, 124 | const CefString& origin_url, 125 | JSDialogType dialog_type, 126 | const CefString& message_text, 127 | const CefString& default_prompt_text, 128 | CefRefPtr callback, 129 | bool& suppress_message) 130 | { 131 | CEF_REQUIRE_UI_THREAD(); 132 | 133 | return false; 134 | } 135 | 136 | bool 137 | QCefViewBrowserHandler::OnBeforeUnloadDialog(CefRefPtr browser, 138 | const CefString& message_text, 139 | bool is_reload, 140 | CefRefPtr callback) 141 | { 142 | CEF_REQUIRE_UI_THREAD(); 143 | 144 | return false; 145 | } 146 | 147 | void 148 | QCefViewBrowserHandler::OnResetDialogState(CefRefPtr browser) 149 | { 150 | CEF_REQUIRE_UI_THREAD(); 151 | } 152 | 153 | void 154 | QCefViewBrowserHandler::OnTakeFocus(CefRefPtr browser, bool next) 155 | { 156 | CEF_REQUIRE_UI_THREAD(); 157 | 158 | NotifyTakeFocus(next); 159 | } 160 | 161 | bool 162 | QCefViewBrowserHandler::OnSetFocus(CefRefPtr browser, FocusSource source) 163 | { 164 | CEF_REQUIRE_UI_THREAD(); 165 | 166 | if (initial_navigation_) { 167 | return true; 168 | } 169 | 170 | return false; 171 | } 172 | 173 | void 174 | QCefViewBrowserHandler::OnGotFocus(CefRefPtr browser) 175 | { 176 | CEF_REQUIRE_UI_THREAD(); 177 | 178 | auto host = main_browser_->GetHost(); 179 | if (host != nullptr) { 180 | host->SetFocus(true); 181 | } 182 | } 183 | 184 | bool 185 | QCefViewBrowserHandler::OnPreKeyEvent(CefRefPtr browser, 186 | const CefKeyEvent& event, 187 | CefEventHandle os_event, 188 | bool* is_keyboard_shortcut) 189 | { 190 | CEF_REQUIRE_UI_THREAD(); 191 | 192 | return false; 193 | } 194 | 195 | bool 196 | QCefViewBrowserHandler::OnBeforePopup(CefRefPtr browser, 197 | CefRefPtr frame, 198 | const CefString& target_url, 199 | const CefString& target_frame_name, 200 | CefLifeSpanHandler::WindowOpenDisposition target_disposition, 201 | bool user_gesture, 202 | const CefPopupFeatures& popupFeatures, 203 | CefWindowInfo& windowInfo, 204 | CefRefPtr& client, 205 | CefBrowserSettings& settings, 206 | CefRefPtr& extra_info, 207 | bool* no_javascript_access) 208 | { 209 | CEF_REQUIRE_UI_THREAD(); 210 | 211 | // cancel all popup 212 | return true; 213 | 214 | // If the browser is closing, block the popup 215 | if (is_closing_) 216 | return true; 217 | 218 | // Redirect all popup page into the source frame forcefully 219 | frame->LoadURL(target_url); 220 | // Don't allow new window or tab 221 | return true; 222 | } 223 | 224 | void 225 | QCefViewBrowserHandler::OnAfterCreated(CefRefPtr browser) 226 | { 227 | CEF_REQUIRE_UI_THREAD(); 228 | 229 | // If the browser is closing, return immediately to release the new created browser 230 | if (is_closing_) 231 | return; 232 | 233 | if (!message_router_) { 234 | // Create the browser-side router for query handling. 235 | CefMessageRouterConfig config; 236 | config.js_query_function = QCEF_QUERY_NAME; 237 | config.js_cancel_function = QCEF_QUERY_CANCEL_NAME; 238 | 239 | // Register handlers with the router. 240 | message_router_ = CefMessageRouterBrowserSide::Create(config); 241 | message_router_->AddHandler(cefquery_handler_.get(), false); 242 | } 243 | 244 | if (!main_browser_) { 245 | // If this is the main browser then keep it 246 | { 247 | std::unique_lock lock(mtx_); 248 | // We need to keep the main child window, but not popup windows 249 | main_browser_ = browser; 250 | } 251 | 252 | // Set the cef window handle to the QcefWindow 253 | if (pQCefViewDelegate_) 254 | pQCefViewDelegate_->setCefBrowserWindow(browser->GetHost()->GetWindowHandle()); 255 | } else if (browser->IsPopup()) { 256 | // Add to the list of popup browsers. 257 | popup_browser_list_.push_back(browser); 258 | 259 | // Give focus to the popup browser. Perform asynchronously because the 260 | // parent window may attempt to keep focus after launching the popup. 261 | CefPostTask(TID_UI, CefCreateClosureTask(base::Bind(&CefBrowserHost::SetFocus, browser->GetHost().get(), true))); 262 | } 263 | 264 | QCefViewDefaultSchemeHandler::SchemeHandlerFactory::recordBrowserAndDelegate(browser, pQCefViewDelegate_); 265 | 266 | // Increase the browser count 267 | { 268 | std::unique_lock lock(mtx_); 269 | browser_count_++; 270 | } 271 | } 272 | 273 | bool 274 | QCefViewBrowserHandler::DoClose(CefRefPtr browser) 275 | { 276 | CEF_REQUIRE_UI_THREAD(); 277 | 278 | // Closing the main window requires special handling. See the DoClose() 279 | // documentation in the CEF header for a detailed description of this 280 | // process. 281 | if (main_browser_ && main_browser_->IsSame(browser)) 282 | // Set a flag to indicate that the window close should be allowed. 283 | is_closing_ = true; 284 | 285 | // Allow the close. For windowed browsers this will result in the OS close 286 | // event being sent. 287 | return false; 288 | } 289 | 290 | void 291 | QCefViewBrowserHandler::OnBeforeClose(CefRefPtr browser) 292 | { 293 | CEF_REQUIRE_UI_THREAD(); 294 | 295 | message_router_->OnBeforeClose(browser); 296 | 297 | if (main_browser_ && main_browser_->IsSame(browser)) { 298 | // if the main browser is closing, we need to close all the pop up browsers. 299 | if (!popup_browser_list_.empty()) { 300 | for (auto& popup : popup_browser_list_) { 301 | if (popup) { 302 | popup->StopLoad(); 303 | popup->GetHost()->CloseBrowser(true); 304 | } 305 | } 306 | } 307 | 308 | main_browser_->StopLoad(); 309 | main_browser_ = nullptr; 310 | } else if (browser->IsPopup()) { 311 | // Remove from the browser popup list. 312 | for (auto it = popup_browser_list_.begin(); it != popup_browser_list_.end(); ++it) { 313 | if ((*it)->IsSame(browser)) { 314 | popup_browser_list_.erase(it); 315 | break; 316 | } 317 | } 318 | } 319 | 320 | QCefViewDefaultSchemeHandler::SchemeHandlerFactory::removeBrowserAndDelegate(browser); 321 | 322 | // Decrease the browser count 323 | { 324 | std::unique_lock lock(mtx_); 325 | if (--browser_count_ == 0) { 326 | message_router_->RemoveHandler(cefquery_handler_.get()); 327 | cefquery_handler_ = nullptr; 328 | message_router_ = nullptr; 329 | 330 | // Notify the waiting thread if any 331 | close_cv_.notify_all(); 332 | } 333 | } 334 | } 335 | 336 | void 337 | QCefViewBrowserHandler::OnLoadingStateChange(CefRefPtr browser, 338 | bool isLoading, 339 | bool canGoBack, 340 | bool canGoForward) 341 | { 342 | CEF_REQUIRE_UI_THREAD(); 343 | 344 | if (!isLoading && initial_navigation_) { 345 | initial_navigation_ = false; 346 | } 347 | 348 | if (pQCefViewDelegate_) 349 | pQCefViewDelegate_->onLoadingStateChanged(isLoading, canGoBack, canGoForward); 350 | } 351 | 352 | void 353 | QCefViewBrowserHandler::OnLoadStart(CefRefPtr browser, 354 | CefRefPtr frame, 355 | TransitionType transition_type) 356 | { 357 | CEF_REQUIRE_UI_THREAD(); 358 | if (pQCefViewDelegate_) { 359 | pQCefViewDelegate_->onLoadStart(); 360 | } 361 | } 362 | 363 | void 364 | QCefViewBrowserHandler::OnLoadEnd(CefRefPtr browser, CefRefPtr frame, int httpStatusCode) 365 | { 366 | CEF_REQUIRE_UI_THREAD(); 367 | if (pQCefViewDelegate_) 368 | pQCefViewDelegate_->onLoadEnd(httpStatusCode); 369 | } 370 | 371 | void 372 | QCefViewBrowserHandler::OnLoadError(CefRefPtr browser, 373 | CefRefPtr frame, 374 | ErrorCode errorCode, 375 | const CefString& errorText, 376 | const CefString& failedUrl) 377 | { 378 | CEF_REQUIRE_UI_THREAD(); 379 | if (errorCode == ERR_ABORTED) 380 | return; 381 | 382 | bool handled = false; 383 | if (pQCefViewDelegate_) 384 | pQCefViewDelegate_->onLoadError(errorCode, errorText, failedUrl, handled); 385 | 386 | if (handled) 387 | return; 388 | 389 | std::ostringstream oss; 390 | oss << "" 391 | << "

Failed to load URL: " << failedUrl << "

" 392 | << "

Error: " << errorText << "(" << errorCode << ")

" 393 | << ""; 394 | 395 | std::string data = oss.str(); 396 | data = CefURIEncode(CefBase64Encode(data.c_str(), data.size()), false).ToString(); 397 | data = "data:text/html;base64," + data; 398 | frame->LoadURL(data); 399 | } 400 | 401 | bool 402 | QCefViewBrowserHandler::OnBeforeBrowse(CefRefPtr browser, 403 | CefRefPtr frame, 404 | CefRefPtr request, 405 | bool user_gesture, 406 | bool is_redirect) 407 | { 408 | CEF_REQUIRE_UI_THREAD(); 409 | 410 | message_router_->OnBeforeBrowse(browser, frame); 411 | return false; 412 | } 413 | 414 | bool 415 | QCefViewBrowserHandler::OnOpenURLFromTab(CefRefPtr browser, 416 | CefRefPtr frame, 417 | const CefString& target_url, 418 | CefRequestHandler::WindowOpenDisposition target_disposition, 419 | bool user_gesture) 420 | { 421 | CEF_REQUIRE_UI_THREAD(); 422 | 423 | return false; // return true to cancel this navigation. 424 | } 425 | 426 | CefRefPtr 427 | QCefViewBrowserHandler::GetResourceRequestHandler(CefRefPtr browser, 428 | CefRefPtr frame, 429 | CefRefPtr request, 430 | bool is_navigation, 431 | bool is_download, 432 | const CefString& request_initiator, 433 | bool& disable_default_handling) 434 | { 435 | CEF_REQUIRE_IO_THREAD(); 436 | return this; 437 | } 438 | 439 | bool 440 | QCefViewBrowserHandler::OnQuotaRequest(CefRefPtr browser, 441 | const CefString& origin_url, 442 | int64 new_size, 443 | CefRefPtr callback) 444 | { 445 | CEF_REQUIRE_IO_THREAD(); 446 | static const int maxSize = 10 * 1024 * 1024; 447 | callback->Continue(new_size <= maxSize); 448 | return true; 449 | } 450 | 451 | void 452 | QCefViewBrowserHandler::OnRenderProcessTerminated(CefRefPtr browser, TerminationStatus status) 453 | { 454 | CEF_REQUIRE_UI_THREAD(); 455 | 456 | message_router_->OnRenderProcessTerminated(browser); 457 | 458 | if (main_browser_) { 459 | CefString url = main_browser_->GetMainFrame()->GetURL(); 460 | if (!url.empty()) { 461 | main_browser_->GetMainFrame()->LoadURL(url); 462 | } 463 | } 464 | } 465 | 466 | CefResourceRequestHandler::ReturnValue 467 | QCefViewBrowserHandler::OnBeforeResourceLoad(CefRefPtr browser, 468 | CefRefPtr frame, 469 | CefRefPtr request, 470 | CefRefPtr callback) 471 | { 472 | return resource_manager_->OnBeforeResourceLoad(browser, frame, request, callback); 473 | } 474 | 475 | CefRefPtr 476 | QCefViewBrowserHandler::GetResourceHandler(CefRefPtr browser, 477 | CefRefPtr frame, 478 | CefRefPtr request) 479 | { 480 | return resource_manager_->GetResourceHandler(browser, frame, request); 481 | } 482 | 483 | void 484 | QCefViewBrowserHandler::OnProtocolExecution(CefRefPtr browser, 485 | CefRefPtr frame, 486 | CefRefPtr request, 487 | bool& allow_os_execution) 488 | {} 489 | 490 | CefRefPtr 491 | QCefViewBrowserHandler::GetBrowser() const 492 | { 493 | std::unique_lock lock(mtx_); 494 | return main_browser_; 495 | } 496 | 497 | void 498 | QCefViewBrowserHandler::AddLocalDirectoryResourceProvider(const std::string& dir_path, 499 | const std::string& url, 500 | int priority /* = 0*/) 501 | { 502 | if (dir_path.empty() || url.empty()) 503 | return; 504 | 505 | std::string identifier; 506 | resource_manager_->AddDirectoryProvider(url, dir_path, priority, identifier); 507 | } 508 | 509 | void 510 | QCefViewBrowserHandler::AddArchiveResourceProvider(const std::string& archive_path, 511 | const std::string& url, 512 | const std::string& password, 513 | int priority /* = 0*/) 514 | { 515 | if (archive_path.empty() || url.empty()) 516 | return; 517 | 518 | std::string identifier; 519 | resource_manager_->AddArchiveProvider(url, archive_path, password, 0, identifier); 520 | } 521 | 522 | void 523 | QCefViewBrowserHandler::CloseAllBrowsers(bool force_close) 524 | { 525 | // If all browsers had been closed, then return 526 | std::unique_lock lock(mtx_); 527 | if (!browser_count_) 528 | return; 529 | 530 | // Flip the closing flag 531 | is_closing_ = true; 532 | 533 | // Close all popup browsers if any 534 | if (!popup_browser_list_.empty()) { 535 | for (auto it = popup_browser_list_.begin(); it != popup_browser_list_.end(); ++it) { 536 | ::SetParent((*it)->GetHost()->GetWindowHandle(), NULL); 537 | (*it)->GetHost()->CloseBrowser(force_close); 538 | //::PostMessage((*it)->GetHost()->GetWindowHandle(), WM_CLOSE, 0, 0); 539 | } 540 | } 541 | 542 | if (main_browser_) { 543 | // Request that the main browser close. 544 | ::SetParent(main_browser_->GetHost()->GetWindowHandle(), NULL); 545 | main_browser_->GetHost()->CloseBrowser(force_close); 546 | //::PostMessage(main_browser_->GetHost()->GetWindowHandle(), WM_CLOSE, 0, 0); 547 | } 548 | 549 | // Wait for the browser to be closed 550 | close_cv_.wait(lock); 551 | } 552 | 553 | bool 554 | QCefViewBrowserHandler::TriggerEvent(const int64_t frame_id, const CefRefPtr msg) 555 | { 556 | if (msg->GetName().empty()) 557 | return false; 558 | 559 | CefRefPtr browser = GetBrowser(); 560 | if (browser) { 561 | std::vector frameIds; 562 | if (MAIN_FRAME == frame_id) { 563 | frameIds.push_back(browser->GetMainFrame()->GetIdentifier()); 564 | } else if (ALL_FRAMES == frame_id) { 565 | browser->GetFrameIdentifiers(frameIds); 566 | } else { 567 | frameIds.push_back(frame_id); 568 | } 569 | 570 | for (auto id : frameIds) { 571 | auto frame = browser->GetFrame(id); 572 | frame->SendProcessMessage(PID_RENDERER, msg); 573 | return true; 574 | } 575 | } 576 | 577 | return false; 578 | } 579 | 580 | bool 581 | QCefViewBrowserHandler::ResponseQuery(const int64_t query, bool success, const CefString& response, int error) 582 | { 583 | if (cefquery_handler_) 584 | return cefquery_handler_->Response(query, success, response, error); 585 | 586 | return false; 587 | } 588 | 589 | bool 590 | QCefViewBrowserHandler::DispatchNotifyRequest(CefRefPtr browser, 591 | CefProcessId source_process, 592 | CefRefPtr message) 593 | { 594 | if (pQCefViewDelegate_ && message->GetName() == INVOKEMETHOD_NOTIFY_MESSAGE) { 595 | int browserId = browser->GetIdentifier(); 596 | 597 | CefRefPtr messageArguments = message->GetArgumentList(); 598 | if (pQCefViewDelegate_) 599 | pQCefViewDelegate_->onInvokeMethodNotify(browserId, messageArguments); 600 | } 601 | 602 | return false; 603 | } 604 | 605 | void 606 | QCefViewBrowserHandler::NotifyTakeFocus(bool next) 607 | { 608 | if (!CefCurrentlyOn(TID_UI)) { 609 | // Execute this method on the main thread. 610 | CefPostTask(TID_UI, CefCreateClosureTask(base::Bind(&QCefViewBrowserHandler::NotifyTakeFocus, this, next))); 611 | return; 612 | } 613 | 614 | if (pQCefViewDelegate_) 615 | pQCefViewDelegate_->onTakeFocus(next); 616 | } 617 | 618 | void 619 | QCefViewBrowserHandler::NotifyDragRegion(const std::vector regions) 620 | { 621 | if (!CefCurrentlyOn(TID_UI)) { 622 | // Execute this method on the main thread. 623 | CefPostTask(TID_UI, CefCreateClosureTask(base::Bind(&QCefViewBrowserHandler::NotifyDragRegion, this, regions))); 624 | return; 625 | } 626 | 627 | if (pQCefViewDelegate_) 628 | pQCefViewDelegate_->onDraggableRegionChanged(regions); 629 | } 630 | --------------------------------------------------------------------------------