zoukankan      html  css  js  c++  java
  • mfc cef<转>

    在mfc单文档程序中加入cef:
    1.在BOOL CtestCEFApp::InitInstance()中初始化cef
    HINSTANCE hInst = GetModuleHandle(NULL);
    CefMainArgs main_args(hInst);
    
    
    m_cefApp = new ClientApp();
    
    
    //cef默认启动四个进程,分别是浏览器主进程,渲染进程,GPU进程,插件进程,如果不是主进程则直接退出
    //AfxMessageBox(L"CefExecuteProcess");
    int exit_code = CefExecuteProcess(main_args, m_cefApp.get(), NULL);
    if (exit_code >= 0)
    return exit_code;
    
    
    //设置cef参数
    CString szCEFCache;
    CString szPath;
    INT nLen = GetTempPath( 0, NULL ) + 1;
    GetTempPath( nLen, szPath.GetBuffer( nLen ));
    szCEFCache.Format( _T("%scache"), szPath );
    
    
    CefSettings settings;
    //settings.no_sandbox = TRUE;
    //settings.multi_threaded_message_loop = FALSE;
    CefString(&settings.cache_path) = szCEFCache;
    
    
    //CefSettingsTraits::init( &cSettings);
    //cSettings.multi_threaded_message_loop = false;
    
    
    m_bCEFInitialized = CefInitialize(main_args, settings,m_cefApp.get(), NULL);
    
    
    //初始化自定义协议
    scheme_test::InitTest();
    2.创建浏览器窗口
    BOOL ClientApp::CreateBrowser(HWND hWnd, CRect rect, LPCTSTR pszURL)
    {
    CefBrowserSettings settings;
    CefWindowInfo info;
    
    
    info.SetAsChild( hWnd, rect );
    std::string url = "test://test/html1.html";
    
    
    return CefBrowserHost::CreateBrowser( info, m_cefHandler.get(), url, settings, NULL );
    }
    3.资源文件加载
    namespace scheme_test {
    
    
    // Implementation of the factory for for creating schema handlers.
    class ClientSchemeHandlerFactory : public CefSchemeHandlerFactory {
    public:
    // Return a new scheme handler instance to handle the request.
    virtual CefRefPtr<CefResourceHandler> Create(CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame,
    const CefString& scheme_name,
    CefRefPtr<CefRequest> request)
    OVERRIDE {
    return NULL;
    }
    
    
    IMPLEMENT_REFCOUNTING(ClientSchemeHandlerFactory);
    };
    
    
    //此方法在ClientApp的虚函数中被调用
    void RegisterCustomSchemes(CefRefPtr<CefSchemeRegistrar> registrar,
    std::vector<CefString>& cookiable_schemes) {
    registrar->AddCustomScheme("test", true, false, false);//注册一个新的协议test
    }
    
    
    //初始化时调用
    void InitTest() {
    CefRegisterSchemeHandlerFactory("test", "test", new ClientSchemeHandlerFactory());//注册一个新的域名,并且新建一个可以处理此域名请求的类
    }
    
    
    }  // namespace scheme_test
    4.两个关键的类
    class CWebClient
    : public CefClient
    , public CefLifeSpanHandler
    , public CefRequestHandler
    {
    
    
    public:
    CMyWebBrowser m_wndBrowser;
    public:
    CWebClient(void){}
    virtual ~CWebClient(void){}
    
    
    virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() { return this; }
    virtual CefRefPtr<CefRequestHandler> GetRequestHandler() { return this; }
    
    
    //virtual bool DoClose( CefRefPtr<CefBrowser> browser );
    //virtual void OnBeforeClose( CefRefPtr<CefBrowser> browser );
    virtual void OnAfterCreated( CefRefPtr<CefBrowser> browser );
    
    
    //此处处理接收到的message
    virtual bool OnProcessMessageReceived( CefRefPtr<CefBrowser> browser, CefProcessId source_process, CefRefPtr<CefProcessMessage> message );
    //此处加载本地html资源
    virtual CefRefPtr<CefResourceHandler> GetResourceHandler( CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request );
    
    
    private:
    bool ParseTestUrl(const std::string& url, std::string* file_name, std::string* mime_type);
    
    
    public:
    
    
    IMPLEMENT_REFCOUNTING(CWebClient);
    IMPLEMENT_LOCKING(CWebClient);
    };
    class ClientApp: public CefApp
    ,public CefBrowserProcessHandler
    ,public CefRenderProcessHandler
    {
    public:
    ClientApp(void);
    ClientApp(HWND hWnd);
    ~ClientApp(void);
    
    
    virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler() OVERRIDE { return this; }
    virtual CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler()OVERRIDE { return this; }
    //此处处理js和c++调用
    virtual void OnContextCreated( CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context );
    
    
    virtual void OnContextInitialized() OVERRIDE;
    
    
    //此处要<span style="font-family: Arial, Helvetica, sans-serif;">注册一个新的协议test</span>
    virtual void OnRegisterCustomSchemes( CefRefPtr<CefSchemeRegistrar> registrar );
    
    
    BOOL CreateBrowser(HWND hWnd, CRect rect, LPCTSTR pszURL);
    
    
    public:
    CefRefPtr<CWebClient> m_cefHandler;
    
    
    private:
    IMPLEMENT_REFCOUNTING(ClientApp);
    
    
    };
    5.c++和js相互调用
    第一种:
    class CefV8ExtensionHandler : public CefV8Handler
    {
    public:
    CefV8ExtensionHandler(){}
    ~CefV8ExtensionHandler(){}
    
    
    virtual bool Execute( const CefString& name, CefRefPtr<CefV8Value> object, const CefV8ValueList& arguments, CefRefPtr<CefV8Value>& retval, CefString& exception );
    
    
    IMPLEMENT_REFCOUNTING(CefV8ExtensionHandler);
    };
    void ClientApp::OnContextCreated( CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context )
    {
    CefRefPtr<CefV8Value> obj = context->GetGlobal();
    
    
    CefRefPtr<CefV8Handler> handler = new CefV8ExtensionHandler();
    
    
    obj->SetValue("test", CefV8Value::CreateFunction("test", handler), V8_PROPERTY_ATTRIBUTE_READONLY);
    
    
    }
    bool CefV8ExtensionHandler::Execute( const CefString& name, CefRefPtr<CefV8Value> object, const CefV8ValueList& arguments, CefRefPtr<CefV8Value>& retval, CefString& exception )
    {
    if (name == "test")
    {
    std::string arg1 = arguments[0]->GetStringValue();
    
    
    //MessageBoxA(NULL, arg1.c_str(), NULL, NULL);
    
    
    retval = CefV8Value::CreateString(arg1);
    
    
    CefRefPtr<CefBrowser> browser = CefV8Context::GetCurrentContext()->GetBrowser();
    ASSERT(browser.get());
    
    
    CefRefPtr<CefProcessMessage> message = CefProcessMessage::Create("test");
    
    
    browser->SendProcessMessage(PID_BROWSER, message);
    
    
    return true;
    }
    
    
    return false;
    }
    第二种:
    std::string app_code =
    "var app;"
    "if (!app)"
    "  app = {};"
    "(function() {"
    "  app.sendMessage = function(name, arguments) {"
    "    native function sendMessage();"
    "    return sendMessage(name, arguments);"
    "  };"
    "  app.setMessageCallback = function(name, callback) {"
    "    native function setMessageCallback();"
    "    return setMessageCallback(name, callback);"
    "  };"
    "  app.removeMessageCallback = function(name) {"
    "    native function removeMessageCallback();"
    "    return removeMessageCallback(name);"
    "  };"
    "})();";
    CefRegisterExtension("v8/app", app_code,
    new ClientAppExtensionHandler(this));
    6.自定义标题栏需要子类化浏览器窗口方能接收到消息
    class CMyWebBrowser : public CWnd
    {
    DECLARE_DYNCREATE(CMyWebBrowser)
    
    
    public:
    CMyWebBrowser(void);
    virtual ~CMyWebBrowser(void);
    
    
    protected:
    DECLARE_MESSAGE_MAP()
    
    
    public:
    afx_msg LRESULT OnNcHitTest(CPoint point);
    };
    LRESULT CMyWebBrowser::OnNcHitTest(CPoint point)
    {
    CRect rc;
    GetClientRect(&rc);
    rc.top = rc.top;
    rc.left = rc.left;
    rc.right = rc.right;
    rc.bottom = 20;
    ClientToScreen(&rc);
    
    
    CPoint screenpoint(point);
    ScreenToClient(&screenpoint);
    
    
    if (rc.PtInRect(point))
    {
    AfxGetApp()->GetMainWnd()->PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(screenpoint.x, screenpoint.y));
    
    
    return 0;
    }
    else
    return CWnd::OnNcHitTest(point);
    }
    void CWebClient::OnAfterCreated( CefRefPtr<CefBrowser> browser )
    {
    HWND hWnd = browser->GetHost()->GetWindowHandle();
    HWND hChildWnd = ::GetNextWindow(hWnd, GW_CHILD );
    m_wndBrowser.SubclassWindow(hChildWnd);
    
    
    CefLifeSpanHandler::OnAfterCreated(browser);
    }
    7.消息循环
    int CtestCEFApp::ExitInstance()
    {
    if( m_bCEFInitialized )
    {
    m_bCEFInitialized = false;
    
    
    m_cefApp = NULL;
    
    
    CefShutdown();
    }
    
    
    return CWinAppEx::ExitInstance();
    }
    
    
    BOOL CtestCEFApp::PumpMessage()
    {
    if( m_bCEFInitialized )
    CefDoMessageLoopWork();
    
    
    return CWinAppEx::PumpMessage();
    }
    
    ---------------------
    
    本文来自 lls2012 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/lls2012/article/details/47976101?utm_source=copy 

    https://blog.csdn.net/lls2012/article/details/47976101

    在mfc单文档程序中加入cef: 1.在BOOL CtestCEFApp::InitInstance()中初始化cef HINSTANCE hInst = GetModuleHandle(NULL); CefMainArgs main_args(hInst); m_cefApp = new ClientApp(); //cef默认启动四个进程,分别是浏览器主进程,渲染进程,GPU进程,插件进程,如果不是主进程则直接退出 //AfxMessageBox(L"CefExecuteProcess"); int exit_code = CefExecuteProcess(main_args, m_cefApp.get(), NULL); if (exit_code >= 0) return exit_code; //设置cef参数 CString szCEFCache; CString szPath; INT nLen = GetTempPath( 0, NULL ) + 1; GetTempPath( nLen, szPath.GetBuffer( nLen )); szCEFCache.Format( _T("%scache"), szPath ); CefSettings settings; //settings.no_sandbox = TRUE; //settings.multi_threaded_message_loop = FALSE; CefString(&settings.cache_path) = szCEFCache; //CefSettingsTraits::init( &cSettings); //cSettings.multi_threaded_message_loop = false; m_bCEFInitialized = CefInitialize(main_args, settings,m_cefApp.get(), NULL); //初始化自定义协议 scheme_test::InitTest(); 2.创建浏览器窗口 BOOL ClientApp::CreateBrowser(HWND hWnd, CRect rect, LPCTSTR pszURL) { CefBrowserSettings settings; CefWindowInfo info; info.SetAsChild( hWnd, rect ); std::string url = "test://test/html1.html"; return CefBrowserHost::CreateBrowser( info, m_cefHandler.get(), url, settings, NULL ); } 3.资源文件加载 namespace scheme_test { // Implementation of the factory for for creating schema handlers. class ClientSchemeHandlerFactory : public CefSchemeHandlerFactory { public: // Return a new scheme handler instance to handle the request. virtual CefRefPtr Create(CefRefPtr browser, CefRefPtr frame, const CefString& scheme_name, CefRefPtr request) OVERRIDE { return NULL; } IMPLEMENT_REFCOUNTING(ClientSchemeHandlerFactory); }; //此方法在ClientApp的虚函数中被调用 void RegisterCustomSchemes(CefRefPtr registrar, std::vector& cookiable_schemes) { registrar->AddCustomScheme("test", true, false, false);//注册一个新的协议test } //初始化时调用 void InitTest() { CefRegisterSchemeHandlerFactory("test", "test", new ClientSchemeHandlerFactory());//注册一个新的域名,并且新建一个可以处理此域名请求的类 } }  // namespace scheme_test 4.两个关键的类 class CWebClient : public CefClient , public CefLifeSpanHandler , public CefRequestHandler { public: CMyWebBrowser m_wndBrowser; public: CWebClient(void){} virtual ~CWebClient(void){} virtual CefRefPtr GetLifeSpanHandler() { return this; } virtual CefRefPtr GetRequestHandler() { return this; } //virtual bool DoClose( CefRefPtr browser ); //virtual void OnBeforeClose( CefRefPtr browser ); virtual void OnAfterCreated( CefRefPtr browser ); //此处处理接收到的message virtual bool OnProcessMessageReceived( CefRefPtr browser, CefProcessId source_process, CefRefPtr message ); //此处加载本地html资源 virtual CefRefPtr GetResourceHandler( CefRefPtr browser, CefRefPtr frame, CefRefPtr request ); private: bool ParseTestUrl(const std::string& url, std::string* file_name, std::string* mime_type); public: IMPLEMENT_REFCOUNTING(CWebClient); IMPLEMENT_LOCKING(CWebClient); }; class ClientApp: public CefApp ,public CefBrowserProcessHandler ,public CefRenderProcessHandler { public: ClientApp(void); ClientApp(HWND hWnd); ~ClientApp(void); virtual CefRefPtr GetBrowserProcessHandler() OVERRIDE { return this; } virtual CefRefPtr GetRenderProcessHandler()OVERRIDE { return this; } //此处处理js和c++调用 virtual void OnContextCreated( CefRefPtr browser, CefRefPtr frame, CefRefPtr context ); virtual void OnContextInitialized() OVERRIDE; //此处要注册一个新的协议test virtual void OnRegisterCustomSchemes( CefRefPtr registrar ); BOOL CreateBrowser(HWND hWnd, CRect rect, LPCTSTR pszURL); public: CefRefPtr m_cefHandler; private: IMPLEMENT_REFCOUNTING(ClientApp); }; 5.c++和js相互调用 第一种: class CefV8ExtensionHandler : public CefV8Handler { public: CefV8ExtensionHandler(){} ~CefV8ExtensionHandler(){} virtual bool Execute( const CefString& name, CefRefPtr object, const CefV8ValueList& arguments, CefRefPtr& retval, CefString& exception ); IMPLEMENT_REFCOUNTING(CefV8ExtensionHandler); }; void ClientApp::OnContextCreated( CefRefPtr browser, CefRefPtr frame, CefRefPtr context ) { CefRefPtr obj = context->GetGlobal(); CefRefPtr handler = new CefV8ExtensionHandler(); obj->SetValue("test", CefV8Value::CreateFunction("test", handler), V8_PROPERTY_ATTRIBUTE_READONLY); } bool CefV8ExtensionHandler::Execute( const CefString& name, CefRefPtr object, const CefV8ValueList& arguments, CefRefPtr& retval, CefString& exception ) { if (name == "test") { std::string arg1 = arguments[0]->GetStringValue(); //MessageBoxA(NULL, arg1.c_str(), NULL, NULL); retval = CefV8Value::CreateString(arg1); CefRefPtr browser = CefV8Context::GetCurrentContext()->GetBrowser(); ASSERT(browser.get()); CefRefPtr message = CefProcessMessage::Create("test"); browser->SendProcessMessage(PID_BROWSER, message); return true; } return false; } 第二种: std::string app_code = "var app;" "if (!app)" "  app = {};" "(function() {" "  app.sendMessage = function(name, arguments) {" "    native function sendMessage();" "    return sendMessage(name, arguments);" "  };" "  app.setMessageCallback = function(name, callback) {" "    native function setMessageCallback();" "    return setMessageCallback(name, callback);" "  };" "  app.removeMessageCallback = function(name) {" "    native function removeMessageCallback();" "    return removeMessageCallback(name);" "  };" "})();"; CefRegisterExtension("v8/app", app_code, new ClientAppExtensionHandler(this)); 6.自定义标题栏需要子类化浏览器窗口方能接收到消息 class CMyWebBrowser : public CWnd { DECLARE_DYNCREATE(CMyWebBrowser) public: CMyWebBrowser(void); virtual ~CMyWebBrowser(void); protected: DECLARE_MESSAGE_MAP() public: afx_msg LRESULT OnNcHitTest(CPoint point); }; LRESULT CMyWebBrowser::OnNcHitTest(CPoint point) { CRect rc; GetClientRect(&rc); rc.top = rc.top; rc.left = rc.left; rc.right = rc.right; rc.bottom = 20; ClientToScreen(&rc); CPoint screenpoint(point); ScreenToClient(&screenpoint); if (rc.PtInRect(point)) { AfxGetApp()->GetMainWnd()->PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(screenpoint.x, screenpoint.y)); return 0; } else return CWnd::OnNcHitTest(point); } void CWebClient::OnAfterCreated( CefRefPtr browser ) { HWND hWnd = browser->GetHost()->GetWindowHandle(); HWND hChildWnd = ::GetNextWindow(hWnd, GW_CHILD ); m_wndBrowser.SubclassWindow(hChildWnd); CefLifeSpanHandler::OnAfterCreated(browser); } 7.消息循环 int CtestCEFApp::ExitInstance() { if( m_bCEFInitialized ) { m_bCEFInitialized = false; m_cefApp = NULL; CefShutdown(); } return CWinAppEx::ExitInstance(); } BOOL CtestCEFApp::PumpMessage() { if( m_bCEFInitialized ) CefDoMessageLoopWork(); return CWinAppEx::PumpMessage(); } --------------------- 本文来自 lls2012 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/lls2012/article/details/47976101?utm_source=copy 

  • 相关阅读:
    go案例:客户管理系统流程 mvc模式 分层设计
    珠峰2016,第9期 vue.js 笔记部份
    前后端分离电商,业务逻辑部份
    'Specifying a namespace in include() without providing an app_name '报错解决
    vue2.0 前端框架
    vue项目实战
    电商网前后端分离数据表设计部份
    djang2.1教育平台02
    django框架开发流程
    测试的艺术:测试用例的设计
  • 原文地址:https://www.cnblogs.com/wainiwann/p/9688067.html
Copyright © 2011-2022 走看看