MFC使用谷歌内核
MFC调用cef
1、初始化
m_callBack 是为了将消息返回到主界面的回调类
1 int CCEFLibrary::InitCef(CCefCallback* callBack) 2 { 3 m_callBack = callBack; 4 CefRefPtr<ClientAppRender> app(new ClientAppRender()); 5 CefSettings settings; 6 //settings.command_line_args_disabled = TRUE; 7 settings.no_sandbox = 0; 8 CefSettingsTraits::init(&settings); 9 settings.multi_threaded_message_loop = true; 10 settings.remote_debugging_port = 8088;//如果不定义,则不能运行调试工具 11 //settings.single_process = true; 12 13 CefMainArgs mainArgs; 14 CefRefPtr<CefApp> cefApp; 15 cefApp = app; 16 17 CefInitialize(mainArgs, settings, cefApp, NULL); 18 return 0; 19 }
2、展示页面
函数的index 是为了项目需要额外添加的 索引,一般直接使用else里面的代码内容即可;
1 int CCEFLibrary::CreateBrowser(int index, RECT rect, HWND hWnd, const std::wstring & url) 2 { 3 std::map<int, CefRefPtr<CSimpleClient>>::iterator itr = m_MapSimpleClient.find(index); 4 if (itr != m_MapSimpleClient.end()) 5 { 6 itr->second->GetBrowser()->GetMainFrame()->LoadURL(url); 7 //m_simpleClient->GetBrowser()->GetMainFrame()->LoadURL(cefStrUrl); 8 } 9 else 10 { 11 CefRefPtr<CSimpleClient> client(new CSimpleClient()); 12 client->SetCallBack(m_callBack); 13 m_MapSimpleClient[index] = client; 14 15 CefWindowInfo winInfo; 16 winInfo.SetAsChild(hWnd, rect); 17 const CefString cefStrUrl(url); 18 CefBrowserSettings browserSettings; 19 browserSettings.web_security = STATE_DISABLED; 20 CefBrowserHost::CreateBrowser(winInfo, client, cefStrUrl, browserSettings, NULL, NULL); 21 22 23 } 24 return 0; 25 }
3、MFC调用js
test.html
1 <!DOCTYPE html> 2 <html> 3 <!-- 4 Copyright (c) 2016 foruok. All rights reserved. 5 欢迎关注foruok的微信订阅好“程序视界”。 6 --> 7 <head> 8 <script type="text/javascript"> 9 function Login(){ 10 window.NativeLogin(document.getElementById("userName").value, document.getElementById("password").value); 11 } 12 function GetId2(){ 13 GetId(2); 14 } 15 function GetId(i) 16 { 17 alert("get id from native by extensions i:" + i); 18 return "i"; 19 } 20 </script> 21 <title>CEF JS Integration</title> 22 </head> 23 24 <body> 25 <h3>Call into native by Window bindings:</h3> 26 <form> 27 UserName: <input type="text" id="userName" /> Password: 28 <input type="text" id="password" /> <input type="button" value="Login" onclick="Login()"/> 29 </form> 30 <hr> 31 <h3>Call into native by js extensions:</h3> 32 <input type="button" value="GetId2" onclick="GetId2()"/> 33 34 </html>
1 void CCEF_MFCDlg::OnBnClickedButton1() 2 { 3 // TODO: 在此添加控件通知处理程序代码 4 m_cef->ExecJsCode(1, L"GetId(33);"); 5 }
传多个参数:
CString str;
//str.Format(L"GetId(%d,%d);",3,7);
str.Format(L"Getstr('%s','%s');", L"600012", L"123");
m_cef->ExecJsCode(1, str.GetBuffer());
1 bool CCEFLibrary::ExecJsCode(int index, const std::wstring & strJsCode) 2 { 3 std::map<int, CefRefPtr<CSimpleClient>>::iterator itr = m_MapSimpleClient.find(index); 4 if (itr != m_MapSimpleClient.end()) 5 { 6 itr->second->ExecJsCode(strJsCode); 7 return true; 8 } 9 return 0; 10 }
1 void CSimpleClient::ExecJsCode(const std::wstring & strJsCode) 2 { 3 if (m_cefBrowser) 4 { 5 m_cefBrowser->GetMainFrame()->ExecuteJavaScript(strJsCode, m_cefBrowser->GetMainFrame()->GetURL(), 0); 6 } 7 }
4、js调用C++代码
window.NativeLogin(document.getElementById("userName").value, document.getElementById("password").value); 回调到cef库中:
1 bool CCefV8HandlerEx::Execute(const CefString& name, 2 CefRefPtr<CefV8Value> object, 3 const CefV8ValueList& arguments, 4 CefRefPtr<CefV8Value>& retval, 5 CefString& exception) 6 { 7 8 if (name == "NativeLogin") 9 { 10 if (arguments.size() == 2) 11 { 12 13 CefString strUser = arguments.at(0)->GetStringValue(); 14 CefString strPassword = arguments.at(1)->GetStringValue(); 15 16 CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("login_msg"); 17 // Retrieve the argument list object. 18 CefRefPtr<CefListValue> args = msg->GetArgumentList(); 19 // Populate the argument values. 20 args->SetSize(2); 21 args->SetString(0, strUser); 22 args->SetString(1, strPassword); 23 24 // Send the process message to the browser process. 25 CefV8Context::GetCurrentContext()->GetBrowser()->GetMainFrame()->SendProcessMessage(PID_BROWSER, msg); 26 } 27 else 28 { 29 retval = CefV8Value::CreateInt(1); 30 } 31 return true; 32 } 33 return false; 34 }
1 bool CSimpleClient::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, 2 CefRefPtr<CefFrame> frame, 3 CefProcessId source_process, 4 CefRefPtr<CefProcessMessage> message) 5 { 6 const std::string& messageName = message->GetName(); 7 if (messageName == "login_msg") 8 { 9 // extract message 10 CefRefPtr<CefListValue> args = message->GetArgumentList(); 11 CefString strUser = args->GetString(0); 12 CefString strPassword = args->GetString(1); 13 14 m_callBack->RelLogin(strUser, strPassword); 15 return true; 16 } 17 return false; 18 }
1 void CefCallBack::RelLogin(std::wstring user, std::wstring pwd) 2 { 3 //::PostMessage(m_phWnd, WM_LOGIN_CLICK, (WPARAM)strUser.c_str(), (LPARAM)strPassword.c_str()); 4 std::wstring* NUser = new std::wstring(user); 5 std::wstring* NPwd = new std::wstring(pwd); 6 ::PostMessage(m_hwnd, WM_LOGIN_CLICK, (WPARAM)NUser, (LPARAM)NPwd); 7 }
从这里回到MFC主界面;在WM_LOGIN_CLICK消息中处理收到js中点击按钮的消息;这里使用 PostMessage,一切正常;我使用 SendMessage 我在消息中 弹框 代码就会崩溃,不知道为啥?
完整代码下载路径 https://download.csdn.net/download/qq_32197003/12526553