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
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
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
CefRefPtr
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
CefRefPtr
CefRefPtr
{
//::MessageBox(NULL, L"OnContextCreated",NULL, MB_OK);
CEF_REQUIRE_RENDERER_THREAD();
m_js_callback_context = NULL;
m_js_callback_func = NULL;
CefRefPtr
CefRefPtr
CefRefPtr
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
CefProcessId source_process,
CefRefPtr
{
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
const CefV8ValueList& arguments,
CefRefPtr
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;
}