CEF3自研究筆記 三、將CEF嵌入到MFC對話框程序中去


        下載CEF包,我下的是cef_binary_3.2171.1979_windows32版本的,網上的朋友說這個版本比較穩定,具體怎麼個穩定法,新版本怎麼個不穩定法,也沒誰告訴我,只說新版本“坑多”。呵呵呵,由於項目的急需,我也沒辦法去研究了,同好們如果有興趣研究,把結果告訴我微笑

        一、用VS2013的嚮導創建一個對話框的程序。

        二、解壓後的cef_binary_3.2171.1979_windows32文件夾如下:

將include、cefclient文件夾拷貝到我們的MFC,在你的MFC程序文件夾裏面創建兩個文件夾ReleaseLib,DebugLib,將out\Release\Lib\libcef_dll_wrapper.lib、將out\Debug\Lib\libcef_dll_wrapper.lib分別拷入對應的這兩個文件夾中備用。將Release文件夾中的cef_sandbox.lib、libcef.lib拷入MFC程序文件夾中備用。

      三、設置MFC程序的屬性。

爲什麼要在靜態庫中使用MFC我也不知道,好象大家都那麼說,我就那麼做了。至於字符集,你可以使用多字節字符集也可以使用unicode字符集,網上大多說用unicode字符集,其實我試了用多字節字符集也沒事,只是向CEF傳遞中文時要轉一下碼,否則就是亂碼。

在VC++目錄中添加包含目錄$(ProjectDir)\cefclient\和$(ProjectDir)\include\,鏈接器-輸入-附加依賴項添加libcef.lib,$(Configuration)Lib\libcef_dll_wrapper.lib,
opengl32.lib,C/C++->預編譯頭->不使用預編譯頭。然後那麼因爲所以就差不多是這樣了。

      四、運行環境:將cef_binary_3.2171.1979_windows32\out中的Debug和Release中的所有文件複製到你的MFC程序對應的生成這兩個文件夾中,具體哪些有用哪些沒用,我也沒研究了。

     五、將include 和cefclient兩個文件夾包含到我們的工程項目中,注意cefclient中帶win的一些文件名是示例程序中的win32程序,可以刪除掉,編譯一下如果報錯,把報錯的那些代碼屏蔽掉,應該都是示例win32程序中的一些調用函數。

   六、初始化CEF:

  在cefclient\client_app.cpp中添加一個用於初始化的成員函數:

int ClientApp::Init(HINSTANCE instance)
{
	CefMainArgs main_args(instance);
	// CEF applications have multiple sub-processes (render, plugin, GPU, etc)
	// that share the same executable. This function checks the command-line and,
	// if this is a sub-process, executes the appropriate logic.
	int exit_code = CefExecuteProcess(main_args, this, NULL);
	if (exit_code >= 0) 
	{
		// The sub-process has completed so return here.
		return exit_code;
	}

	CefSettings settings;
	AppInitCommandLine(0, NULL);

	AppGetSettings(settings);

	settings.single_process = false;
	settings.multi_threaded_message_loop = true;
	settings.no_sandbox = true;
	// Initialize CEF.
	CefInitialize(main_args, settings, this, NULL);
	return exit_code;
}

再添加一個用於退出的函數:

void ClientApp::Exit()
{
	CefShutdown();
}


       在工程主程序APP類中創建一個成員變量CefRefPtr<ClientApp> m_cefApp;

  在InitInstance()中插入如下代碼初始化:

m_cefApp = new ClientApp();
	if (!(m_cefApp->Init(m_hInstance) < 0))
		return FALSE;
在ExitInstance()中插入退出代碼:


int CCEFBrowserApp::ExitInstance()
{
	// TODO:  在此添加專用代碼和/或調用基類
	AfxOleTerm(FALSE);
	m_cefApp->Exit();
	m_cefApp = NULL;
	

	return CWinApp::ExitInstance();
}

七、在對話框中嵌入CEF

       在響應對話框的WM_CREATE函數OnCreate(LPCREATESTRUCT lpCreateStruct)中添加將CEF嵌入到對話框中的代碼:

g_handler = new ClientHandler();
	CefWindowInfo window_info;
	CRect rect;
	GetWindowRect(&rect);
	rect.bottom -= 160;
	window_info.SetAsChild(m_hWnd, rect);
	CefBrowserSettings browser_settings;
	CefBrowserHost::CreateBrowser(window_info, g_handler.get(), "www.baidu.com", browser_settings, NULL);

       爲了讓嵌入的CEF跟窗口大小一致,我們還要響應對話框的WM_SIZE消息,對應函數OnSize(UINT nType, int cx, int cy)代碼:

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

	// TODO:  在此處添加消息處理程序代碼
	if (g_handler != NULL){
		CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
		if (browser){
			CefWindowHandle hwnd = browser->GetHost()->GetWindowHandle();
			::MoveWindow(hwnd, 0, 0, cx, cy - 160, TRUE);
		}
	}
}

        好了,基本上就是這樣了。如果一切順利的話,運行一下,一個打開度娘頁面的對話框就出現了。唉,分享成果喜悅固然開心,但真要寫文章還真是累啊。





發佈了35 篇原創文章 · 獲贊 21 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章