#include"stdafx.h"#include"etradeclient/browser/main_view_browser_handler.h"#include<stdio.h>#include<algorithm>#include<set>#include<sstream>#include<string>#include<vector>#include"include/cef_browser.h"#include"include/cef_frame.h"#include"include/cef_path_util.h"#include"include/cef_process_util.h"#include"include/cef_runnable.h"#include"include/cef_trace.h"#include"include/base/cef_lock.h"#include"include/wrapper/cef_helpers.h"#include"etradeclient/browser/browser_util.h"#include"etradeclient/browser/render_delegate.h"#include"etradeclient/browser/session.h"#include"etradeclient/browser/error_page.h"#include"etradeclient/browser/async_js_callback_handler.h"#include"etradeclient/utility/win_msg_define.h"#include"etradeclient/utility/string_converter.h"MainViewBrowserHandler::MainViewBrowserHandler(){}MainViewBrowserHandler::~MainViewBrowserHandler(){}//@{CefClientmethodsboolMainViewBrowserHandler::OnProcessMessageReceived(CefRefPtr<CefBrowser>browser,CefProcessIdsource_process,CefRefPtr<CefProcessMessage>message){CEF_REQUIRE_UI_THREAD();if(m_browser_msg_router->OnProcessMessageReceived(browser,source_process,message))returntrue;returnfalse;}//@}//@{CefLifeSpanHandlermethodsvoidMainViewBrowserHandler::OnAfterCreated(CefRefPtr<CefBrowser>browser){CEF_REQUIRE_UI_THREAD();if(!m_browser_msg_router){//Createthebrowser-siderouterforqueryhandling.CefMessageRouterConfigconfig;m_browser_msg_router=CefMessageRouterBrowserSide::Create(config);//Createothermessagehandlershere.AsyncJSCallbackHandler::HW_Create(m_msg_handlers);//Registerhandlerswiththerouter.for(constauto&handler:m_msg_handlers)m_browser_msg_router->AddHandler(handler,false);}autois_popup=browser->IsPopup();//@todoremove//getbrowserIDINTnBrowserId=browser->GetIdentifier();//TheframewindowwillbetheparentofthebrowserwindowHWNDhWindow=GetParent(browser->GetHost()->GetWindowHandle());//SendmsgtoViewtoholdreferencetothisbrowser::SendMessage(hWindow,WM_CEF_NEW_BROWSER,(WPARAM)nBrowserId,(LPARAM)browser.get());//callparentCefLifeSpanHandler::OnAfterCreated(browser);}boolMainViewBrowserHandler::DoClose(CefRefPtr<CefBrowser>browser){CEF_REQUIRE_UI_THREAD();HWNDhwnd=GetParent(browser->GetHost()->GetWindowHandle());//Theframewindowwillbetheparentofthebrowserwindow::SendMessage(hwnd,WM_CEF_CLOSE_BROWSER,(WPARAM)browser.get(),(LPARAM)NULL);//sendclosebrowsernotification.//Allowtheclose.ForwindowedbrowsersthiswillresultintheOSclose//eventbeingsent.returnfalse;}voidMainViewBrowserHandler::OnBeforeClose(CefRefPtr<CefBrowser>browser){CEF_REQUIRE_UI_THREAD();m_browser_msg_router->OnBeforeClose(browser);//Allbrowserwindowshaveclosed.//Removeanddeletemessagerouterhandlers.for(constauto&handler:m_msg_handlers)m_browser_msg_router->RemoveHandler(handler);m_msg_handlers.clear();m_browser_msg_router=NULL;CefLifeSpanHandler::OnBeforeClose(browser);//callparent}boolMainViewBrowserHandler::OnBeforePopup(CefRefPtr<CefBrowser>browser,CefRefPtr<CefFrame>frame,constCefString&target_url,constCefString&target_frame_name,cef_window_open_disposition_ttarget_disposition,booluser_gesture,constCefPopupFeatures&popupFeatures,CefWindowInfo&windowInfo,CefRefPtr<CefClient>&client,CefBrowserSettings&settings,bool*no_javascript_access){CEF_REQUIRE_IO_THREAD();if(browser->GetHost()->IsWindowRenderingDisabled())returntrue;//Cancelpopupsinoff-screenrenderingmode.//TheframewindowwillbetheparentofthebrowserwindowHWNDhWindow=GetParent(browser->GetHost()->GetWindowHandle());//sendmessageLPCTSTRlpszURL(target_url.c_str());if(::SendMessage(hWindow,WM_CEF_WINDOW_CHECK,(WPARAM)&popupFeatures,(LPARAM)lpszURL)==S_FALSE)returntrue;//sendmessageif(::SendMessage(hWindow,WM_CEF_NEW_WINDOW,(WPARAM)&popupFeatures,(LPARAM)&windowInfo)==S_FALSE)returntrue;//callparent,The|client|and|settings|valueswilldefaulttothesourcebrowser'svalues.returnCefLifeSpanHandler::OnBeforePopup(browser,frame,target_url,target_frame_name,target_disposition,user_gesture,popupFeatures,windowInfo,client,settings,no_javascript_access);}//@}//@{CefContextMenuHandlermethodsvoidMainViewBrowserHandler::OnBeforeContextMenu(CefRefPtr<CefBrowser>browser,CefRefPtr<CefFrame>frame,CefRefPtr<CefContextMenuParams>params,CefRefPtr<CefMenuModel>model){#ifndef_DEBUG//Blockthecontextmenuforsafetyconsideration.!!!BUTweshouldstillallowcontextmenufor"selection"&"editable"items.if((params->GetTypeFlags()&(CM_TYPEFLAG_SELECTION|CM_TYPEFLAG_EDITABLE))==0){model->Clear();return;}#endif//callparenttogetthedefaultbehavior.CefContextMenuHandler::OnBeforeContextMenu(browser,frame,params,model);}boolMainViewBrowserHandler::OnContextMenuCommand(CefRefPtr<CefBrowser>browser,CefRefPtr<CefFrame>frame,CefRefPtr<CefContextMenuParams>params,intcommand_id,EventFlagsevent_flags){//callparenttogetthedefaultbehavior.returnCefContextMenuHandler::OnContextMenuCommand(browser,frame,params,command_id,event_flags);}//@}//@{CefLoadHandlermethodsvoidMainViewBrowserHandler::OnLoadingStateChange(CefRefPtr<CefBrowser>browser,boolis_loading,boolcan_go_back,boolcan_go_forward){CEF_REQUIRE_UI_THREAD();INTstate=0;//setstateif(is_loading)state|=CEF_BIT_IS_LOADING;if(can_go_back)state|=CEF_BIT_CAN_GO_BACK;if(can_go_forward)state|=CEF_BIT_CAN_GO_FORWARD;HWNDhWindow=GetParent(browser->GetHost()->GetWindowHandle());//Theframewindowwillbetheparentofthebrowserwindow.::SendMessage(hWindow,WM_CEF_STATE_CHANGE,(WPARAM)state,NULL);//sendmessage.CefLoadHandler::OnLoadingStateChange(browser,is_loading,can_go_back,can_go_forward);//callparent.}//@}//@{CefDisplayHandlermethodsvoidMainViewBrowserHandler::OnAddressChange(CefRefPtr<CefBrowser>browser,CefRefPtr<CefFrame>frame,constCefString&url){CEF_REQUIRE_UI_THREAD();HWNDhWindow=GetParent(browser->GetHost()->GetWindowHandle());//Theframewindowwillbetheparentofthebrowserwindow.LPCTSTRpszURL(url.c_str());::SendMessage(hWindow,WM_CEF_ADDRESS_CHANGE,(WPARAM)pszURL,NULL);CefDisplayHandler::OnAddressChange(browser,frame,url);//callparent.}voidMainViewBrowserHandler::OnTitleChange(CefRefPtr<CefBrowser>browser,constCefString&title){CEF_REQUIRE_UI_THREAD();HWNDhWindow=GetParent(browser->GetHost()->GetWindowHandle());//Theframewindowwillbetheparentofthebrowserwindow.LPCTSTRpszTitle(title.c_str());::SendMessage(hWindow,WM_CEF_TITLE_CHANGE,(WPARAM)pszTitle,NULL);CefDisplayHandler::OnTitleChange(browser,title);//callparent.}voidMainViewBrowserHandler::OnStatusMessage(CefRefPtr<CefBrowser>browser,constCefString&value){CEF_REQUIRE_UI_THREAD();#if_DEBUGSendStatusToMainWnd(browser,value);#endif//_DEBUGCefDisplayHandler::OnStatusMessage(browser,value);//callparent.}boolMainViewBrowserHandler::OnConsoleMessage(CefRefPtr<CefBrowser>browser,constCefString&message,constCefString&source,intline){CEF_REQUIRE_UI_THREAD();returnTRUE;}//@}//@{CefDownloadHandlermethodsvoidMainViewBrowserHandler::OnBeforeDownload(CefRefPtr<CefBrowser>browser,CefRefPtr<CefDownloadItem>download_item,constCefString&suggested_name,CefRefPtr<CefBeforeDownloadCallback>callback){CEF_REQUIRE_UI_THREAD();//Continuethedownloadandshowthe"Save As"dialog.callback->Continue(GetDownloadPath(suggested_name),true);}voidMainViewBrowserHandler::OnDownloadUpdated(CefRefPtr<CefBrowser>browser,CefRefPtr<CefDownloadItem>download_item,CefRefPtr<CefDownloadItemCallback>callback){CEF_REQUIRE_UI_THREAD();CEFDownloadItemValuesvalues;values.bIsValid=download_item->IsValid();values.bIsInProgress=download_item->IsInProgress();values.bIsComplete=download_item->IsComplete();values.bIsCanceled=download_item->IsCanceled();values.nProgress=download_item->GetPercentComplete();values.nSpeed=download_item->GetCurrentSpeed();values.nReceived=download_item->GetReceivedBytes();values.nTotal=download_item->GetTotalBytes();CefString&szDispo=download_item->GetContentDisposition();//TheframewindowwillbetheparentofthebrowserwindowHWNDhWindow=GetParent(browser->GetHost()->GetWindowHandle());//sendmessage::SendMessage(hWindow,WM_CEF_DOWNLOAD_UPDATE,(WPARAM)&values,NULL);}//@}//@{CefLoadHandlermethodsvoidMainViewBrowserHandler::OnLoadStart(CefRefPtr<CefBrowser>browser,CefRefPtr<CefFrame>frame){CEF_REQUIRE_UI_THREAD();//TheframewindowwillbetheparentofthebrowserwindowHWNDhWindow=GetParent(browser->GetHost()->GetWindowHandle());::SendMessage(hWindow,WM_CEF_LOAD_START,NULL,NULL);SendStatusToMainWnd(browser,L"页面加载中...");CefLoadHandler::OnLoadStart(browser,frame);//callparent}voidMainViewBrowserHandler::OnLoadEnd(CefRefPtr<CefBrowser>browser,CefRefPtr<CefFrame>frame,inthttp_status_code){CEF_REQUIRE_UI_THREAD();staticconstintkHttpCode_OK=200;//@TODO统一定义这些值staticconstintkFileCode_OK=0;//codeofloadinglocalfile//TheframewindowwillbetheparentofthebrowserwindowHWNDhWindow=GetParent(browser->GetHost()->GetWindowHandle());CefStringurl=frame->GetURL();LPCTSTRurl_(url.c_str());//WARNNING:LPCTSTRurl_(frame->GetURL().c_str())willgetanincorrectstring,don'tdothisway!::SendMessage(hWindow,WM_CEF_LOAD_END,http_status_code,(LPARAM)url_);if(kHttpCode_OK==http_status_code||kFileCode_OK==http_status_code)SendStatusToMainWnd(browser,L"页面加载完成!");elseSendStatusToMainWnd(browser,L"页面加载出错!");CefLoadHandler::OnLoadEnd(browser,frame,http_status_code);//callparent}voidMainViewBrowserHandler::OnLoadError(CefRefPtr<CefBrowser>browser,CefRefPtr<CefFrame>frame,ErrorCodeerror_code,constCefString&error_text,constCefString&failed_url){CEF_REQUIRE_UI_THREAD();SendStatusToMainWnd(browser,L"页面加载结束!");//Don'tdisplayanerrorforifrequestaborted.if(error_code==ERR_ABORTED)return;//TheframewindowwillbetheparentofthebrowserwindowHWNDhWindow=GetParent(browser->GetHost()->GetWindowHandle());LPCTSTRfailed_url_(failed_url.c_str());CefStringerror_code_str=ErrorPage::ToErrorString(error_code);::SendMessage(hWindow,WM_CEF_LOAD_ERROR,(WPARAM)failed_url_,(LPARAM)error_code_str.c_str());//Don'tdisplayanerrorforexternalprotocolsthatweallowtheOStohandle.SeeOnProtocolExecution().if(error_code==ERR_UNKNOWN_URL_SCHEME){std::stringurlStr=frame->GetURL();if(urlStr.find("spotify:")==0)return;}frame->LoadURL(ErrorPage::Url(failed_url,error_code,error_text));//Loadtheerrorpage.}//@}//@{CefRequestHandlermethodsCefRefPtr<CefResourceHandler>MainViewBrowserHandler::GetResourceHandler(CefRefPtr<CefBrowser>browser,CefRefPtr<CefFrame>frame,CefRefPtr<CefRequest>request){CEF_REQUIRE_IO_THREAD();returnNULL;}boolMainViewBrowserHandler::GetAuthCredentials(CefRefPtr<CefBrowser>browser,CefRefPtr<CefFrame>frame,boolisProxy,constCefString&host,intport,constCefString&realm,constCefString&scheme,CefRefPtr<CefAuthCallback>callback){//TheframewindowwillbetheparentofthebrowserwindowHWNDhWindow=GetParent(browser->GetHost()->GetWindowHandle());CEFAuthenticationValuesvalues;values.lpszHost=host.c_str();values.lpszRealm=realm.c_str();//sendinfoif(::SendMessage(hWindow,WM_CEF_AUTHENTICATE,(WPARAM)&values,(LPARAM)NULL)==S_OK){callback->Continue(values.szUserName,values.szUserPass);returnTRUE;}//canceledreturnFALSE;}boolMainViewBrowserHandler::OnQuotaRequest(CefRefPtr<CefBrowser>browser,constCefString&origin_url,int64new_size,CefRefPtr<CefRequestCallback>callback){staticconstint64max_size=1024*1024*20;//20mb.//Grantthequotarequestifthesizeisreasonable.callback->Continue(new_size<=max_size);//callparentreturnCefRequestHandler::OnQuotaRequest(browser,origin_url,new_size,callback);}voidMainViewBrowserHandler::OnProtocolExecution(CefRefPtr<CefBrowser>browser,constCefString&url,bool&allow_os_execution){//dodefaultCefRequestHandler::OnProtocolExecution(browser,url,allow_os_execution);}boolMainViewBrowserHandler::OnBeforeBrowse(CefRefPtr<CefBrowser>browser,CefRefPtr<CefFrame>frame,CefRefPtr<CefRequest>request,boolis_redirect){CEF_REQUIRE_UI_THREAD();if(Session::Instance().IsExpired())//Returntruetocancelthenavigationifthesessionisalreadyexpired.returntrue;m_browser_msg_router->OnBeforeBrowse(browser,frame);CefStringurl=request->GetURL();//getURLrequestedLPCTSTRurl_(url.c_str());//WARNNING:LPCTSTRurl_(frame->GetURL().c_str())willgetanincorrectstring,don'tdothisway!HWNDhWindow=GetParent(browser->GetHost()->GetWindowHandle());//Theframewindowwillbetheparentofthebrowserwindow。if(::SendMessage(hWindow,WM_CEF_BEFORE_BROWSE,(WPARAM)url_,(LPARAM)is_redirect)==S_FALSE){//cancelnavigationreturntrue;}SendStatusToMainWnd(browser,L"开始加载页面...");returnCefRequestHandler::OnBeforeBrowse(browser,frame,request,is_redirect);//callparent}boolMainViewBrowserHandler::OnCertificateError(CefRefPtr<CefBrowser>browser,cef_errorcode_tcert_error,constCefString&request_url,CefRefPtr<CefSSLInfo>ssl_info,CefRefPtr<CefRequestCallback>callback){std::wstringstreamtext;//nofile,orempty,showthedefaulttext<<"The site's security certificate is not trusted!\n\n";text<<"You attempted to reach: "<<request_url.c_str()<<" \n";text<<"But the server presented a certificate issued by an entity that is not trusted by your computer's operating system.";text<<"This may mean that the server has generated its own security credentials, ";text<<"which Chrome cannot rely on for identity information, or an attacker may be ";text<<"trying to intercept your communications.\n\n";text<<"You should not proceed, especially if you have never seen this warning before for this site.";if(MessageBox(NULL,text.str().c_str(),L"The site's security certificate is not trusted:",MB_YESNO)==IDNO)returnFALSE;//continuecallback->Continue(true);returnTRUE;}CefRequestHandler::ReturnValueMainViewBrowserHandler::OnBeforeResourceLoad(CefRefPtr<CefBrowser>browser,CefRefPtr<CefFrame>frame,CefRefPtr<CefRequest>request,CefRefPtr<CefRequestCallback>callback){//dodefulatreturnCefRequestHandler::OnBeforeResourceLoad(browser,frame,request,callback);}boolMainViewBrowserHandler::OnResourceResponse(CefRefPtr<CefBrowser>browser,CefRefPtr<CefFrame>frame,CefRefPtr<CefRequest>request,CefRefPtr<CefResponse>response){CEF_REQUIRE_IO_THREAD();constCefStringkTimeoutHeader("sessionStatus");