CEF:MFC的简单浏览器实现

        开发环境:win10+vs2015

    本Demo只在release下运行!!!

       我也是学习别的大佬的教程,我所用的cef版本文件都是这个大佬的,如果像学习怎样编译CEF3库,请见:这位大佬是如何编译的CEF的

       如果要跑起来这个Demo,需要把Demo源码和cef编译后的文件下载下来,把下图1,2中的圈出来的cef文件路径改为cef编译后的文件解压出来的实际存放路径,如果不想改项目属性配置想偷懒,就把编译后的文件放在D盘(根目录),就可以正常跑起来。

cef编译后的文件

Demo源码下载

项目属性设置

1.CEF:MFC的简单浏览器实现_第1张图片
2.CEF:MFC的简单浏览器实现_第2张图片
3.
CEF:MFC的简单浏览器实现_第3张图片

Demo源码代码

CefMfcDemoDlg.h


#pragma once

#include "SimpleClient.h"

// CCefMfcDemoDlg 对话框
class CCefMfcDemoDlg : public CDialogEx
{
// 构造
public:
	CCefMfcDemoDlg(CWnd* pParent = NULL);	// 标准构造函数

// 对话框数据
	enum { IDD = IDD_CEFMFCDEMO_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持

	CefRefPtr<CSimpleClient>  m_simpleClient;

// 实现
protected:
	HICON m_hIcon;
	bool sandbox_info;
	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnClose();
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg void OnBnClickedBtnGo();
	BOOL PreTranslateMessage(MSG * pMsg);//回车
	afx_msg void OnBnClickedBtnForward();
	afx_msg void OnBnClickedBtnBack();
};

CefMfcDemoDlg.cpp


// CefMfcDemoDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "CefMfcDemo.h"
#include "CefMfcDemoDlg.h"
#include "afxdialogex.h"

#include "include/cef_app.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CCefMfcDemoDlg 对话框



CCefMfcDemoDlg::CCefMfcDemoDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CCefMfcDemoDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CCefMfcDemoDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CCefMfcDemoDlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_CLOSE()
	ON_WM_SIZE()
	ON_BN_CLICKED(IDC_BTN_GO, &CCefMfcDemoDlg::OnBnClickedBtnGo)
	ON_BN_CLICKED(IDC_BTN_FORWARD, &CCefMfcDemoDlg::OnBnClickedBtnForward)
	ON_BN_CLICKED(IDC_BTN_BACK, &CCefMfcDemoDlg::OnBnClickedBtnBack)
END_MESSAGE_MAP()


// CCefMfcDemoDlg 消息处理程序

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

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

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

	CefRefPtr<CSimpleClient> client(new CSimpleClient());
	m_simpleClient = client;

	CefSettings settings;
	CefSettingsTraits::init(&settings);
	settings.multi_threaded_message_loop = true;

	CefMainArgs mainArgs;
	CefRefPtr<CefApp> cefApp;
	CefInitialize(mainArgs, settings, m_simpleClient, NULL);//实现代码加载flash
	CefInitialize(mainArgs, settings,cefApp,NULL);
	RECT rect;
	GetClientRect(&rect);
	RECT rectnew = rect;
	rectnew.top = rect.top + 50;
	rectnew.bottom = rect.bottom;
	rectnew.left = rect.left;
	rectnew.right = rect.right;

	CefWindowInfo winInfo;
	winInfo.SetAsChild(GetSafeHwnd(), rectnew);

	CefBrowserSettings browserSettings;
	CefBrowserHost::CreateBrowser(winInfo, client, _T("http://www.baidu.com"), browserSettings, NULL);

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

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CCefMfcDemoDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CCefMfcDemoDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



void CCefMfcDemoDlg::OnClose()
{
	// TODO:  在此添加消息处理程序代码和/或调用默认值
	CefShutdown();

	CDialogEx::OnClose();

}



void CCefMfcDemoDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialogEx::OnSize(nType, cx, cy);

	// TODO:  在此处添加消息处理程序代码
	RECT rect;
	GetClientRect(&rect);

	if (m_simpleClient.get())
	{
		CefRefPtr<CefBrowser> browser = m_simpleClient->GetBrowser();
		if (browser)
		{
			CefWindowHandle hwnd = browser->GetHost()->GetWindowHandle();
			::MoveWindow(hwnd, 0, 50, rect.right - rect.left, rect.bottom - 50, true);
		}
	}
}

//go按钮
void CCefMfcDemoDlg::OnBnClickedBtnGo()
{
	// TODO:  在此添加控件通知处理程序代码
	CString strUrl;
	GetDlgItem(IDC_EDIT_URL)->GetWindowText(strUrl);
	if (strUrl.Trim().IsEmpty())// Trim()去除头尾空格
	{
		AfxMessageBox(_T("请输入网址"));
		return;
	}
	const CefString cefStrUrl(strUrl);
	m_simpleClient->GetBrowser()->GetMainFrame()->LoadURL(cefStrUrl);
}
BOOL CCefMfcDemoDlg::PreTranslateMessage(MSG* pMsg)
{
	// TODO: 在此添加专用代码和/或调用基类
	if (pMsg->message == WM_KEYDOWN)
	{
		switch (pMsg->wParam)
		{
		case VK_RETURN:    // 回车
			OnBnClickedBtnGo();
			return TRUE;
		}
	}
	return CDialog::PreTranslateMessage(pMsg);
}

//前进按钮
void CCefMfcDemoDlg::OnBnClickedBtnForward()
{
	// TODO: 在此添加控件通知处理程序代码
	m_simpleClient->GetBrowser()->GoForward();
}

//回退按钮
void CCefMfcDemoDlg::OnBnClickedBtnBack()
{
	// TODO: 在此添加控件通知处理程序代码
	m_simpleClient->GetBrowser()->GoBack();
}

SimpleClient.h

#pragma once

#include "include/cef_client.h"
#include "include/cef_app.h"
#include "include/cef_download_handler.h" 
class CSimpleClient : public CefClient, public CefLifeSpanHandler, public CefKeyboardHandler, public CefContextMenuHandler, public CefBrowserProcessHandler, public CefApp, public CefDownloadHandler
{
public:
	CSimpleClient();
	~CSimpleClient();
	
	
	virtual bool OnBeforePopup(CefRefPtr<CefBrowser> browser,//不弹对话框
		CefRefPtr<CefFrame> frame,
		const CefString& target_url,
		const CefString& target_frame_name,
		WindowOpenDisposition target_disposition,
		bool user_gesture,
		const CefPopupFeatures& popupFeatures,
		CefWindowInfo& windowInfo,
		CefRefPtr<CefClient>& client,
		CefBrowserSettings& settings,
		bool* no_javascript_access) override;

	void OnBeforeCommandLineProcessing(const CefString & process_type, CefRefPtr<CefCommandLine> command_line);
	
	virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE
	{ return this; }
	/*
	download
	*/
	virtual CefRefPtr<CefDownloadHandler> GetDownloadHandler() { return this; }
	virtual void OnBeforeDownload(
		CefRefPtr<CefBrowser> browser,
		CefRefPtr<CefDownloadItem> download_item,
		const CefString& suggested_name,
		CefRefPtr<CefBeforeDownloadCallback> callback) OVERRIDE;
	virtual void OnDownloadUpdated(
		CefRefPtr<CefBrowser> browser,
		CefRefPtr<CefDownloadItem> download_item,
		CefRefPtr<CefDownloadItemCallback> callback) OVERRIDE;
		
	// CefLifeSpanHandler methods:
	virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;

	CefRefPtr<CefBrowser> GetBrowser() { return m_cefBrowser; }

private:
	CefRefPtr<CefBrowser> m_cefBrowser;
	IMPLEMENT_REFCOUNTING(CSimpleClient);
};

SimpleClient.cpp

#include "afxwin.h"
#include "SimpleClient.h"

void OnBeforeDownload(
	CefRefPtr<CefBrowser> browser,
	CefRefPtr<CefDownloadItem> download_item,
	const CefString& suggested_name,
	CefRefPtr<CefBeforeDownloadCallback> callback);
void OnDownloadUpdated(
	CefRefPtr<CefBrowser> browser,
	CefRefPtr<CefDownloadItem> download_item,
	CefRefPtr<CefDownloadItemCallback> callback);

CSimpleClient::CSimpleClient()
{
}


CSimpleClient::~CSimpleClient()
{
}

void CSimpleClient::OnAfterCreated(CefRefPtr<CefBrowser> browser)
{
	m_cefBrowser = browser;
}

//不弹新对话框
bool CSimpleClient::OnBeforePopup(CefRefPtr<CefBrowser> browser,
	CefRefPtr<CefFrame> frame,
	const CefString& target_url,
	const CefString& target_frame_name,
	WindowOpenDisposition target_disposition,
	bool user_gesture,
	const CefPopupFeatures& popupFeatures,
	CefWindowInfo& windowInfo,
	CefRefPtr<CefClient>& client,
	CefBrowserSettings& settings,
	bool* no_javascript_access)
{
	switch (target_disposition)
	{
	case WOD_NEW_FOREGROUND_TAB:
	case WOD_NEW_BACKGROUND_TAB:
	case WOD_NEW_POPUP:
	case WOD_NEW_WINDOW:
		browser->GetMainFrame()->LoadURL(target_url);
		return true; //cancel create
	}

	return false;
}

//下载功能
void CSimpleClient::OnBeforeDownload(
	CefRefPtr<CefBrowser> browser,
	CefRefPtr<CefDownloadItem> download_item,
	const CefString& suggested_name,
	CefRefPtr<CefBeforeDownloadCallback> callback)
{
	callback->Continue(download_item->GetURL(), true);
}

void CSimpleClient::OnDownloadUpdated(
	CefRefPtr<CefBrowser> browser,
	CefRefPtr<CefDownloadItem> download_item,
	CefRefPtr<CefDownloadItemCallback> callback)
{
	if (download_item->IsComplete())
	{
		AfxMessageBox(_T("下载成功!!!"));
		if (browser->IsPopup() && !browser->HasDocument())
		{
			browser->GetHost()->CloseBrowser(true);
		}
	}
	
}

void CSimpleClient::OnBeforeCommandLineProcessing(const CefString& process_type, CefRefPtr<CefCommandLine> command_line)
{

	

	//manifest.json中的version
	command_line->AppendSwitchWithValue("ppapi-flash-version", "20.0.0.228");

	//加载flash插件
	command_line->AppendSwitchWithValue("ppapi-flash-path", "PepperFlash\\pepflashplayer.dll");

}


编译、运行、效果如下:
CEF:MFC的简单浏览器实现_第4张图片


参考教程:
CEF:MFC 对话框 Demo(VS2013)
CEF 下载文件扩展
CEF 加载flash 插件
CEF中禁止弹出浏览器窗口

你可能感兴趣的:(CEF,cef,mfc,cef,简单浏览器,mfc,简单浏览器,mfc,cef内核简单浏览器)