使用CEF实现Windows下Webkit内核浏览器

1.开发工具

cmake, VS2010

 

2.参考文章

a.嵌入Chrome cef之完整版(本教程基于cef1)

b.在mfc中使用cef实现webkit的浏览器(一)到(四)

c.CEF3自研究笔记 一到四

d.cef ppapi专栏资料,http://blog.csdn.net/column/details/cef-ppapi.html

e.CEF JS与browser进程间的异步通信

f.CEF中Browser进程与Render进程间通信

g.CEF中JavaScript与C++交互

h.cef / JavaScriptIntegration

i.CEF3开发者系列之JS与C++交互之二

j.duilib + cef简单浏览器的demo,demo2

k.MFC使用CEF并实现js与C++交互功能,解决Render进程中OnContextCreated绑定与OnWebKitInitialized的js扩展无法回调问题

3.基本操作,这个不详细说了,百度可以解决。

首先下载CEF源文件,然后使用cmake工具编译成VS2010能够打开的工程。使用VS2010编译出CEF库文件。再VS2010新建工程,使用CEF库文件开始开发。

 

4.关键源码

a.MCefBrowser.cpp : 定义应用程序的类行为

// CMCefBrowserApp 构造


CMCefBrowserApp::CMCefBrowserApp()
{
// 支持重新启动管理器
m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
// TODO: 在此处添加构造代码,
// 将所有重要的初始化放置在 InitInstance 中
void* sandbox_info = NULL;
        CefMainArgs main_args(AfxGetApp()->m_hInstance);
CefRefPtr app(new SimpleApp);
        CefSettings settings;
        settings.no_sandbox = true;
settings.single_process = false;//使用多进程模式
        settings.multi_threaded_message_loop = true; //使用主程序消息循环
settings.ignore_certificate_errors = true; //忽略掉ssl证书验证错误
settings.command_line_args_disabled = false;
        CefInitialize(main_args, settings, app.get(), sandbox_info);

}

 

b.MCefBrowserDlg.cpp : 实现文件

BOOL CMCefBrowserDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();


// 将“关于...”菜单项添加到系统菜单中。


// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);


CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}


// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
//  执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标


// TODO: 在此添加额外的初始化代码


SetWindowText(L"MCefBrowser");


//读取配置文件
CStringA browserURL;
GetPrivateProfileStringA( "Main", "BrowserURL", "", browserURL.GetBuffer(MAX_PATH), MAX_PATH, ".\\config.ini" ) ;

CStringA IsFullScreen;
       GetPrivateProfileStringA( "Main", "IsFullScreen", "Y", IsFullScreen.GetBuffer(MAX_PATH), MAX_PATH, ".\\config.ini" ) ;


if(IsFullScreen.Compare("Y") == 0){
ShowWindow(SW_SHOWMAXIMIZED); //全屏
}
                      
int StartPosition_X = GetPrivateProfileIntA("Main","StartPosition_X",0,".\\config.ini");
int StartPosition_Y = GetPrivateProfileIntA("Main","StartPosition_Y",0,".\\config.ini");
int WindowHeight = GetPrivateProfileIntA("Main","WindowHeight",600,".\\config.ini");
int WindowWidth = GetPrivateProfileIntA("Main","WindowWidth",800,".\\config.ini");


//窗体信息

CefWindowInfo window_info;
        CRect rt;
GetClientRect(&rt);
rt.left = StartPosition_X;
rt.top = StartPosition_Y;
rt.bottom = WindowHeight;
rt.right = WindowWidth;




        window_info.SetAsChild(this->GetSafeHwnd(), rt);
CefRefPtr m_handler = new SimpleHandler();

        CefBrowserSettings browser_settings;
        std::string url;
url = browserURL;


CefBrowserHost::CreateBrowser(window_info, m_handler.get(), url, browser_settings, NULL);

m_hWndMain = AfxGetMainWnd()->m_hWnd;//全局变量窗体句柄获取

return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE

}

BOOL CMCefBrowserDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CString strRecievedText = (LPCWSTR) (pCopyDataStruct->lpData); 

CefString cef_str(strRecievedText);
cef_str = strRecievedText;

CefRefPtr msg = CefProcessMessage::Create("callback_driver");
CefRefPtr args = msg->GetArgumentList();
args->SetString(0, cef_str);
m_browser->SendProcessMessage(PID_RENDERER, msg);


return CDialogEx::OnCopyData(pWnd, pCopyDataStruct);

}

 

c.simple_app.cc文件

//在创建完render的context后调用, 我们可以在这里去绑定一些js的函数, 变量
void SimpleApp::OnContextCreated(CefRefPtr browser,   
                              CefRefPtr frame,   
                              CefRefPtr context)   
{   
//::MessageBox(NULL, L"OnContextCreated",NULL,  MB_OK);
    CEF_REQUIRE_RENDERER_THREAD();   

    m_js_callback_context = NULL;   
    m_js_callback_func = NULL;   





    CefRefPtr object = context->GetGlobal();   
    CefRefPtr myhandler = this;   
   
    CefRefPtr func2 = CefV8Value::CreateFunction(L"driverhandler", myhandler);  

    object->SetValue(L"driverhandler", func2, V8_PROPERTY_ATTRIBUTE_NONE);   
 object->SetValue(L"registercb", CefV8Value::CreateFunction(L"registercb", myhandler), V8_PROPERTY_ATTRIBUTE_NONE);   

 

//用来接收处理传给render进程的消息
bool SimpleApp::OnProcessMessageReceived(CefRefPtr browser,
                                        CefProcessId source_process,
                                        CefRefPtr message)
{
if(message->GetName().compare(L"callback_driver") == 0)
{
if(m_js_callback_func)
{
CefV8ValueList args;
CefString str = message->GetArgumentList()->GetString(0);
args.push_back(CefV8Value::CreateString(str));
m_js_callback_func->ExecuteFunctionWithContext(m_js_callback_context, NULL, args);
}
return true;
}

return false;

}

 

//在OnContextCreated中绑定的js函数执行时, 会调用这个函数, 我们可以在这个函数中处理这些js函数
bool SimpleApp::Execute(const CefString& name,
                       CefRefPtr object,
                       const CefV8ValueList& arguments,
                       CefRefPtr& retval,
                       CefString& exception)
{

if(name.compare(L"driverhandler") ==0)
{
if(arguments.size() == 1 && arguments[0]->IsString() )
{
COPYDATASTRUCT cds;
std::wstring str;
str += arguments[0]->GetStringValue();
LPCWSTR lpData = str.c_str();
cds.lpData = (LPVOID)lpData;
cds.cbData = (wcslen(lpData) + 1)*sizeof(WCHAR);
HWND m_hWndMain;
        m_hWndMain = FindWindow(NULL, L"GGMsgService");
//m_hWndMain = FindWindow(NULL, L"TestBrowser");
::SendMessage(m_hWndMain, WM_COPYDATA, NULL, (LPARAM)&cds);
//retval = CefV8Value::CreateString("0");
retval = CefV8Value::CreateInt(0);


return true;
}
if(arguments.size() == 2 && arguments[0]->IsString() && arguments[1]->IsString())
{

COPYDATASTRUCT cds;
std::wstring str;

str += arguments[0]->GetStringValue();
str += L"|";
str += arguments[1]->GetStringValue();

LPCWSTR lpData = str.c_str();
//::MessageBox(NULL, lpData, NULL, MB_OK);
cds.lpData = (LPVOID)lpData;
cds.cbData = (wcslen(lpData) + 1)*sizeof(WCHAR);



HWND m_hWndMain;
        m_hWndMain = FindWindow(NULL, L"GGMsgService");
::SendMessage(m_hWndMain, WM_COPYDATA, NULL, (LPARAM)&cds);



retval = CefV8Value::CreateInt(0);
return true;
}
if(arguments.size() == 3 && arguments[0]->IsString() && arguments[1]->IsString() && arguments[2]->IsString())
{
COPYDATASTRUCT cds;
std::wstring str;
str += arguments[0]->GetStringValue();
str += L"|";
str += arguments[1]->GetStringValue();
str += L"|";
str += arguments[2]->GetStringValue();
LPCWSTR lpData = str.c_str();
cds.lpData = (LPVOID)lpData;
cds.cbData = (wcslen(lpData) + 1)*sizeof(WCHAR);
HWND m_hWndMain;
        m_hWndMain = FindWindow(NULL, L"GGMsgService");
//m_hWndMain = FindWindow(NULL, L"TestBrowser");
::SendMessage(m_hWndMain, WM_COPYDATA, NULL, (LPARAM)&cds);
//retval = CefV8Value::CreateString("0");
retval = CefV8Value::CreateInt(0);


return true;
}
}
else if(name.compare(L"registercb") == 0)
{
if(arguments.size() == 1 && arguments[0]->IsFunction())
{

m_js_callback_func = arguments[0].get();
m_js_callback_context = CefV8Context::GetCurrentContext();


//调用回调函数

retval = CefV8Value::CreateInt(0);
return true;
}

}
return false;
}

你可能感兴趣的:(浏览器封装)