cef3 clienthandler

.h

#pragma once

#include "include/cef_render_process_handler.h"
#include "include/cef_client.h"
#include "include/cef_v8.h"
#include "include/cef_browser.h"

class CCefClientHandler : public CefClient, public CefDisplayHandler, public CefLifeSpanHandler,
    public CefLoadHandler, public CefRequestHandler, public CefContextMenuHandler
{
public:
    CCefClientHandler();
    ~CCefClientHandler();

    // CefClient methods:
    virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() override;

    virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() override;

    virtual CefRefPtr<CefLoadHandler> GetLoadHandler() override;

    virtual CefRefPtr<CefRequestHandler> GetRequestHandler() override;

    virtual CefRefPtr<CefContextMenuHandler> GetContextMenuHandler() override{
        return this;
    }

    // ----------------CefDisplayHandler methods:-------------------
    virtual void OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString& title) override;

    //---------------- CefLifeSpanHandler methods:----------------------------
    virtual bool OnBeforePopup(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, const CefString& target_url, const CefString& target_frame_name,
        CefLifeSpanHandler::WindowOpenDisposition target_disposition, bool user_gesture, const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo, CefRefPtr<CefClient>& client, CefBrowserSettings& settings, bool* no_javascript_access) override;

    virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) override;
    virtual bool DoClose(CefRefPtr<CefBrowser> browser) override;
    virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) override;

    // ----------------CefLoadHandler methods:---------------------------
    virtual void OnLoadStart(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame);
    virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, int httpStatusCode) override;
    virtual void OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, ErrorCode errorCode, const CefString& errorText, const CefString& failedUrl) override;
    //-----------------

    //菜单处理  
    virtual void OnBeforeContextMenu(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefContextMenuParams> params, CefRefPtr<CefMenuModel> model) override;

    virtual bool OnContextMenuCommand(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefContextMenuParams> params, int command_id, EventFlags event_flags) override;

    void CloseHostBrowser(CefRefPtr<CefBrowser>browser, bool force_close);
    // Request that all existing browser windows close.
    void CloseAllBrowsers(bool force_close);

    bool IsClosing() const;


    void ShowDevelopTools(CefRefPtr<CefBrowser> browser, const CefPoint& inspect_element_at);
    void CloseDevelopTools(CefRefPtr<CefBrowser> browser);

public:
    //CefRefPtr<CefBrowser> browser_;

    HWND hWnd_; //接收消息的句柄
    CefString strTitle_; //网址标题

    // List of existing browser windows. Only accessed on the CEF UI thread.
    typedef std::vector<CefRefPtr<CefBrowser> > BrowserList;
    BrowserList browser_list_;

private:

    bool is_closing_;

    // Include the default reference counting implementation.
    IMPLEMENT_REFCOUNTING(CCefClientHandler);
    //由于CEF采用多线程架构,有必要使用锁和闭包来保证在多不同线程安全的传递数据。IMPLEMENT_LOCKING定义提供了Lock()Unlock()方法以及AutoLock对象来保证不同代码块同步访问
    IMPLEMENT_LOCKING(CCefClientHandler);
};

.cpp

/************************************************************************************************
*   Copyright (c) 2013 Álan Crístoffer
*
*   Permission is hereby granted, free of charge, to any person obtaining a copy
*   of this software and associated documentation files (the "Software"), to deal
*   in the Software without restriction, including without limitation the rights
*   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
*   of the Software, and to permit persons to whom the Software is furnished to do so,
*   subject to the following conditions:
*
*   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
*   INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
*   PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
*   FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
*   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
*   DEALINGS IN THE SOFTWARE.
************************************************************************************************/
#include "stdafx.h"
#include "CCefClientHandler.h"

#include "include/cef_app.h"
#include "include/cef_base.h"
#include "include/cef_client.h"
#include "include/cef_command_line.h"
#include "include/cef_frame.h"
#include "include/cef_web_plugin.h"



CCefClientHandler::CCefClientHandler() :hWnd_(NULL), is_closing_(false)
{
}

CCefClientHandler::~CCefClientHandler()
{

}


// CefClient methods:
CefRefPtr<CefDisplayHandler> CCefClientHandler::GetDisplayHandler()
{
    return this;
}
CefRefPtr<CefLifeSpanHandler> CCefClientHandler::GetLifeSpanHandler()
{
    return this;
}
CefRefPtr<CefLoadHandler> CCefClientHandler::GetLoadHandler()
{
    return this;
}

CefRefPtr<CefRequestHandler> CCefClientHandler::GetRequestHandler()
{
    return this;
}

// 缓存一个指向browser的引用
void CCefClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser)
{
    int c = 3;
    c++;
    // Add to the list of existing browsers.
    browser_list_.push_back(browser);

    int nID = browser->GetIdentifier();

    ::PostMessage(hWnd_, UM_CEF_AFTERCREATED, nID, 0);

}


bool CCefClientHandler::DoClose(CefRefPtr<CefBrowser> browser)
{
    int c = 3;
    c++;
    //TID_UI 线程是浏览器的主线程。
    CEF_REQUIRE_UI_THREAD();
    //  AutoLock lock_scope(this);

    lock_.Acquire();


    // Remove from the list of existing browsers.
    BrowserList::iterator bit = browser_list_.begin();

    for (; bit != browser_list_.end(); bit++)
    {
        if ((*bit)->IsSame(browser))
        {
            browser_list_.erase(bit);
            browser = NULL;
            break;
        }
    }


    lock_.Release();

    if (browser_list_.size() == 0) {
        // Set a flag to indicate that the window close should be allowed.
        is_closing_ = true;

        ::PostMessage(hWnd_, UM_CEF_POSTQUITMESSAGE, 0, 0);
    }


    return false;
}


void CCefClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser)
{
    int c = 3;
    c++;
    CEF_REQUIRE_UI_THREAD();

    AutoLock lock_scope(this);
    //  lock_.Acquire();

    BrowserList::iterator bit = browser_list_.begin();

    for (; bit != browser_list_.end(); bit++)
    {
        if ((*bit)->IsSame(browser))
        {
            browser_list_.erase(bit);
            browser = NULL;
            break;
        }
    }


    if (browser_list_.empty())
    {
        is_closing_ = true;
        ::PostMessage(hWnd_, UM_CEF_POSTQUITMESSAGE, 0, 0);
        // All browser windows have closed. Quit the application message loop.
        //CefQuitMessageLoop();
        //PostQuitMessage(0l);
    }

    //  lock_.Release();
}

void CCefClientHandler::OnLoadStart(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame)
{
    int c = 3;
    c++;
    CEF_REQUIRE_UI_THREAD();

    CefString* strTmpURL = new CefString(browser->GetMainFrame()->GetURL());
    int nID = browser->GetIdentifier();
    ::PostMessage(hWnd_, UM_CEF_WEBLOADSTART, nID, (LPARAM)strTmpURL);

    //return __super::OnLoadStart(browser, frame);
}
void CCefClientHandler::OnLoadEnd(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, int httpStatusCode)
{
    int c = 3;
    c++;
    CEF_REQUIRE_UI_THREAD();

    CefString* strTmpURL = new CefString(browser->GetMainFrame()->GetURL());
    int nID = browser->GetIdentifier();
    ::PostMessage(hWnd_, UM_CEF_WEBLOADEND, nID, (LPARAM)strTmpURL);

}



void CCefClientHandler::OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, ErrorCode errorCode, const CefString& errorText, const CefString& failedUrl)
{
    int c = 3;
    c++;
    CEF_REQUIRE_UI_THREAD();

    // Don't display an error for downloaded files.
    if (errorCode == ERR_ABORTED)
        return;

    // Display a load error message.
    std::stringstream ss;
    ss << "<html><body bgcolor=\"white\">"
        "<h2>Failed to load URL " << std::string(failedUrl) <<
        " with error " << std::string(errorText) << " (" << errorCode <<
        ").</h2></body></html>";
    frame->LoadString(ss.str(), failedUrl);
}





void CCefClientHandler::OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString& title)
{
    int c = 3;
    c++;
    CEF_REQUIRE_UI_THREAD();
    // globally unique identifier for this browser
    int nID = browser->GetIdentifier();

    CefString* strTitle = new CefString(title);
    ::PostMessage(hWnd_, UM_CEF_WEBTITLECHANGE, nID, (LPARAM)strTitle);
}



bool CCefClientHandler::OnBeforePopup(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, const CefString& target_url, const CefString& target_frame_name, CefLifeSpanHandler::WindowOpenDisposition target_disposition,
    bool user_gesture, const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo, CefRefPtr<CefClient>& client, CefBrowserSettings& settings, bool* no_javascript_access)
{
    //消息处理后记得delete分配的字符串资源
    CefString* strTargetURL = new CefString(target_url);
    ::PostMessage(hWnd_, UM_CEF_WEBLOADPOPUP, (WPARAM)0, (LPARAM)strTargetURL);
    return true;

}


enum MyEnum
{
    MENU_ID_USER_OPENLINK = MENU_ID_USER_FIRST + 200,
    MENU_ID_USER_COPYLINK,
    MENU_ID_USER_SHOWDEVTOOLS,
};


void CCefClientHandler::OnBeforeContextMenu(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefContextMenuParams> params, CefRefPtr<CefMenuModel> model)
{
    //在这里,我添加了自己想要的菜单  
    cef_context_menu_type_flags_t flag = params->GetTypeFlags();
    if (flag&CM_TYPEFLAG_LINK)
    {
        model->Clear(); //清除所有菜单项

        model->AddItem(MENU_ID_USER_OPENLINK, L"在新标签页中打开(&T)");//增加菜单项
        model->AddSeparator(); //加分隔线
        model->AddItem(MENU_ID_USER_COPYLINK, L"复制链接地址(&C)");//增加菜单项
        //model->SetEnabled(MENU_ID_USER_OPENLINK, false); //禁用菜单项。
        return;
    }
    if (flag & CM_TYPEFLAG_PAGE)
    {//普通页面的右键消息

        model->SetLabel(MENU_ID_BACK, L"后退");
        model->SetLabel(MENU_ID_FORWARD, L"前进");
        model->AddSeparator();
        model->AddItem(MENU_ID_RELOAD, L"刷新");
        model->AddItem(MENU_ID_RELOAD_NOCACHE, L"强制刷新");
        model->AddItem(MENU_ID_STOPLOAD, L"停止加载");

        model->AddSeparator();
        model->SetLabel(MENU_ID_PRINT, L"打印");
        model->SetLabel(MENU_ID_VIEW_SOURCE, L"查看源代码");
        model->AddItem(MENU_ID_USER_SHOWDEVTOOLS, L"开发者工具"); //"&Show DevTools");                         

    }
    if (flag & CM_TYPEFLAG_EDITABLE)
    {//编辑框的右键消息  
        model->SetLabel(MENU_ID_UNDO, L"撤销");
        model->SetLabel(MENU_ID_REDO, L"重做");
        model->SetLabel(MENU_ID_CUT, L"剪切");
        model->SetLabel(MENU_ID_COPY, L"复制");
        model->SetLabel(MENU_ID_PASTE, L"粘贴");
        model->SetLabel(MENU_ID_DELETE, L"删除");
        model->SetLabel(MENU_ID_SELECT_ALL, L"全选");
    }

}

bool CCefClientHandler::OnContextMenuCommand(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefContextMenuParams> params, int command_id, EventFlags event_flags)
{
    //CefString strLinkURL;
    CefString strURLLink;
    CefString* strTargetURL = nullptr;
    HGLOBAL hglbCopy;
    LPTSTR  lptstrCopy;
    int nBuffLength = 0;


    switch (command_id)
    {

    case MENU_ID_USER_OPENLINK:

        strTargetURL = new CefString(params->GetLinkUrl());
        ::PostMessage(hWnd_, UM_CEF_WEBLOADPOPUP, (WPARAM)0, (LPARAM)strTargetURL);
        break;
    case MENU_ID_USER_COPYLINK:

        if (!OpenClipboard(frame->GetBrowser().get()->GetHost().get()->GetWindowHandle()))
        {
            return FALSE;
        }

        EmptyClipboard();

        strURLLink = params->GetUnfilteredLinkUrl();

        if (strURLLink.length() != 0)
        {
            nBuffLength = (strURLLink.length() + 1) * sizeof(TCHAR);

            hglbCopy = GlobalAlloc(GMEM_MOVEABLE, nBuffLength);

            if (hglbCopy == NULL)
            {
                CloseClipboard();
                return FALSE;
            }

            // Lock the handle and copy the text to the buffer. 

            lptstrCopy = (LPTSTR)::GlobalLock(hglbCopy);
            memset(lptstrCopy, '\0', nBuffLength);
            memcpy(lptstrCopy, strURLLink.c_str(), nBuffLength - sizeof(TCHAR));

            GlobalUnlock(hglbCopy); // 解除锁定剪贴板
            // Place the handle on the clipboard. 

            //SetClipboardData(CF_TEXT, hglbCopy);
            SetClipboardData(CF_UNICODETEXT, hglbCopy);// CF_UNICODETEXT为Unicode编码  

        }

        CloseClipboard();

        break;
    case MENU_ID_USER_SHOWDEVTOOLS:
        ShowDevelopTools(browser, CefPoint());
        return true;

    default:
        break;
    }


    return false;
}



void CCefClientHandler::CloseHostBrowser(CefRefPtr<CefBrowser>browser, bool force_close)
{

    if (!CefCurrentlyOn(TID_UI))
    {
        // Execute on the UI thread.
        CefPostTask(TID_UI, base::Bind(&CCefClientHandler::CloseHostBrowser, this, browser, force_close));
        return;
    }


    int nID = browser->GetIdentifier();

    ::PostMessage(hWnd_, UM_CEF_BROWSERCLOSE, nID, 0);
    browser->GetHost()->CloseBrowser(force_close);
}


void CCefClientHandler::CloseAllBrowsers(bool force_close)
{
    //if (!CefCurrentlyOn(TID_UI))
    //{
    //  // Execute on the UI thread.
    //  CefPostTask(TID_UI, base::Bind(&CCefClientHandler::CloseAllBrowsers, this, force_close));
    //  return;
    //}

    lock_.Acquire();
    if (browser_list_.empty()) {
        return;
    }
    BrowserList::const_iterator it = browser_list_.begin();
    for (; it != browser_list_.end(); ++it)
    {
        (*it)->GetHost()->CloseBrowser(force_close);

    }
    lock_.Release();
}


bool CCefClientHandler::IsClosing() const
{
    return is_closing_;
}



void CCefClientHandler::ShowDevelopTools(CefRefPtr<CefBrowser> browser, const CefPoint& inspect_element_at) {
    CefWindowInfo windowInfo; CefBrowserSettings settings;

#if defined(OS_WIN)
    //windowInfo.SetAsPopup(browser->GetHost()->GetWindowHandle(), "DevTools");
    RECT rc = { 0, 0, 800, 600 };
    windowInfo.SetAsChild(hWnd_, rc);
#endif

    browser->GetHost()->ShowDevTools(windowInfo, this, settings, inspect_element_at);
}

void CCefClientHandler::CloseDevelopTools(CefRefPtr<CefBrowser> browser)
{
    browser->GetHost()->CloseDevTools();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值