标签:
Tutorial
Tutorial explaining how to create a simple application using CEF3.
IntroductionThis tutorial explains how to create a simple application using CEF3. It references the cefsimple example project which is included with trunkrevision 1535 and newer. For complete CEF3 usage information visit the GeneralUsage Wiki page. Getting StartedBegin by downloading a binary distribution for your platform from http://cefbuilds.com. For the purposes of this tutorial download the 1750 branch or newer. Currently supported platforms include Windows, Linux and Mac OS X. Each binary distribution contains all files necessary to build a particular version of CEF3 on a particular platform. See the included README.txt file or the Getting Started section of the GeneralUsage Wiki page for a detailed description of binary distribution contents. Building the Included ProjectApplications based on CEF binary distributions can be built using standard platform build tools. This includes Visual Studio on Windows, Xcode on Mac OS X and gcc/make on Linux. Each platform has a slightly different build process and requirements. WindowsFollow these steps to build the cefsimple application on Windows:
LinuxFollow these steps to build the cefsimple application on Linux:
Mac OS XFollow these steps to build the cefsimple application on OS X:
Loading a Custom URLThe cefsimple application loads google.com by default but you can change it to load a custom URL instead. The easiest way to load a different URL is via the command-line. # Load the local file “c:\example\example.html” cefsimple.exe --url=file://c:/example/example.html You can also edit the source code in cefsimple/simple_app.cpp and recompile the application to load your custom URL by default. # Load the local file “c:\example\example.html” … if (url.empty()) url = "file://c:/example/example.html"; … Application ComponentsAll CEF applications have the following primary components:
The CEF dynamic library, support libraries and resources will be the same for every CEF-based application. They are included in the Debug/Release or Resources directory of the binary distribution. See the README.txt file included in the binary distribution for details on which of these files are required and which can be safely left out. See below for a detailed description of the required application layout on each platform. Architecture in 60 SecondsThe below list summarizes the items of primary importance for this tutorial:
Read the GeneralUsage Wiki page for complete discussion of the above points. Source CodeThe cefsimple application initializes CEF and creates a single popup browser window. The application terminates when all browser windows have been closed. Program flow is as follows:
Your binary distribution may include newer versions of the below files. However, the general concepts remain unchanged. Entry Point FunctionExecution begins in the browser process entry point function. This function is responsible for initializing CEF and any OS-related objects. For example, it initializes GTK on Linux and allocates the necessary Cocoa objects on OS X. OS X has a separate entry point function for helper processes (see the OS X section below). Windows#include <windows.h> #include "cefsimple/simple_app.h" #include "include/cef_sandbox_win.h" // Set to 0 to disable sandbox support. #define CEF_ENABLE_SANDBOX 1 #if CEF_ENABLE_SANDBOX // The cef_sandbox.lib static library is currently built with VS2010. It may not // link successfully with other VS versions. #pragma comment(lib, "cef_sandbox.lib") #endif // Entry point function for all processes. int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); void* sandbox_info = NULL; #if CEF_ENABLE_SANDBOX // Manage the life span of the sandbox information object. This is necessary // for sandbox support on Windows. See cef_sandbox_win.h for complete details. CefScopedSandboxInfo scoped_sandbox; sandbox_info = scoped_sandbox.sandbox_info(); #endif // Provide CEF with command-line arguments. CefMainArgs main_args(hInstance); // SimpleApp implements application-level callbacks. It will create the first // browser instance in OnContextInitialized() after CEF has initialized. CefRefPtr<SimpleApp> app(new SimpleApp); // 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, app.get(), sandbox_info); if (exit_code >= 0) { // The sub-process has completed so return here. return exit_code; } // Specify CEF global settings here. CefSettings settings; #if !CEF_ENABLE_SANDBOX settings.no_sandbox = true; #endif // Initialize CEF. CefInitialize(main_args, settings, app.get(), sandbox_info); // Run the CEF message loop. This will block until CefQuitMessageLoop() is // called. CefRunMessageLoop(); // Shut down CEF. CefShutdown(); return 0; } Linux// cefsimple_gtk.cpp #include <gtk/gtk.h> #include "cefsimple/simple_app.h" // Entry point function for all processes. int main(int argc, char* argv[]) { // Provide CEF with command-line arguments. CefMainArgs main_args(argc, argv); // SimpleApp implements application-level callbacks. It will create the first // browser instance in OnContextInitialized() after CEF has initialized. CefRefPtr<SimpleApp> app(new SimpleApp); // 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, app.get(), NULL); if (exit_code >= 0) { // The sub-process has completed so return here. return exit_code; } // Initialize GTK. gtk_init(&argc, &argv); // Specify CEF global settings here. CefSettings settings; // Initialize CEF for the browser process. CefInitialize(main_args, settings, app.get(), NULL); // Run the CEF message loop. This will block until CefQuitMessageLoop() is // called. CefRunMessageLoop(); // Shut down CEF. CefShutdown(); return 0; } Mac OS XBrowser process entry point: // cefsimple_mac.mm #import <Cocoa/Cocoa.h> #include "cefsimple/simple_app.h" #include "cefsimple/simple_handler.h" #include "cefsimple/util.h" #include "include/cef_application_mac.h" // Provide the CefAppProtocol implementation required by CEF. @interface SimpleApplication : NSApplication<CefAppProtocol> { @private BOOL handlingSendEvent_; } @end @implementation SimpleApplication - (BOOL)isHandlingSendEvent { return handlingSendEvent_; } - (void)setHandlingSendEvent:(BOOL)handlingSendEvent { handlingSendEvent_ = handlingSendEvent; } - (void)sendEvent:(NSEvent*)event { CefScopedSendingEvent sendingEventScoper; [super sendEvent:event]; } @end // Receives notifications from the application. @interface SimpleAppDelegate : NSObject - (void)createApp:(id)object; @end @implementation SimpleAppDelegate // Create the application on the UI thread. - (void)createApp:(id)object { [NSApplication sharedApplication]; [NSBundle loadNibNamed:@"MainMenu" owner:NSApp]; // Set the delegate for application events. [NSApp setDelegate:self]; } // Called when the application‘s Quit menu item is selected. - (NSApplicationTerminateReply)applicationShouldTerminate: (NSApplication *)sender { // Request that all browser windows close. if (SimpleHandler* handler = SimpleHandler::GetInstance()) handler->CloseAllBrowsers(false); // Cancel the termination. The application will exit after all windows have // closed. return NSTerminateCancel; } // Sent immediately before the application terminates. This signal should not // be called because we cancel the termination. - (void)applicationWillTerminate:(NSNotification *)aNotification { ASSERT(false); // Not reached. } @end // Entry point function for the browser process. int main(int argc, char* argv[]) { // Provide CEF with command-line arguments. CefMainArgs main_args(argc, argv); // SimpleApp implements application-level callbacks. It will create the first // browser instance in OnContextInitialized() after CEF has initialized. CefRefPtr<SimpleApp> app(new SimpleApp); // Initialize the AutoRelease pool. NSAutoreleasePool* autopool = [[NSAutoreleasePool alloc] init]; // Initialize the SimpleApplication instance. [SimpleApplication sharedApplication]; // Specify CEF global settings here. CefSettings settings; // Initialize CEF for the browser process. CefInitialize(main_args, settings, app.get(), NULL); // Create the application delegate. NSObject* delegate = [[SimpleAppDelegate alloc] init]; [delegate performSelectorOnMainThread:@selector(createApp:) withObject:nil waitUntilDone:NO]; // Run the CEF message loop. This will block until CefQuitMessageLoop() is // called. CefRunMessageLoop(); // Shut down CEF. CefShutdown(); // Release the delegate. [delegate release]; // Release the AutoRelease pool. [autopool release]; return 0; } Sub-process entry point: // process_helper_mac.cpp #include "include/cef_app.h" // Entry point function for sub-processes. int main(int argc, char* argv[]) { // Provide CEF with command-line arguments. CefMainArgs main_args(argc, argv); // Execute the sub-process. return CefExecuteProcess(main_args, NULL, NULL); } SimpleAppSimpleApp is responsible for handling process-level callbacks. It exposes some interfaces/methods that are shared by multiple processes and some that are only called in a particular process. The CefBrowserProcessHandler interface, for example, is only called in the browser process. There’s a separate CefRenderProcessHandler interface (not shown in this example) that is only called in the render process. Note that GetBrowserProcessHandler() must return |this| because SimpleApp implements both CefApp and CefBrowserProcessHandler. See theGeneralUsage Wiki page or API header files for additional information on CefApp and related interfaces. // simple_app.h #include "include/cef_app.h" class SimpleApp : public CefApp, public CefBrowserProcessHandler { public: SimpleApp(); // CefApp methods: virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler() OVERRIDE { return this; } // CefBrowserProcessHandler methods: virtual void OnContextInitialized() OVERRIDE; private: // Include the default reference counting implementation. IMPLEMENT_REFCOUNTING(SimpleApp); }; // simple_app.cpp #include "cefsimple/simple_app.h" #include <string> #include "cefsimple/simple_handler.h" #include "cefsimple/util.h" #include "include/cef_browser.h" #include "include/cef_command_line.h" SimpleApp::SimpleApp() { } void SimpleApp::OnContextInitialized() { REQUIRE_UI_THREAD(); // Information used when creating the native window. CefWindowInfo window_info; #if defined(OS_WIN) // On Windows we need to specify certain flags that will be passed to // CreateWindowEx(). window_info.SetAsPopup(NULL, "cefsimple"); #endif // SimpleHandler implements browser-level callbacks. CefRefPtr<SimpleHandler> handler(new SimpleHandler()); // Specify CEF browser settings here. CefBrowserSettings browser_settings; std::string url; // Check if a "--url=" value was provided via the command-line. If so, use // that instead of the default URL. CefRefPtr<CefCommandLine> command_line = CefCommandLine::GetGlobalCommandLine(); url = command_line->GetSwitchValue("url"); if (url.empty()) url = "http://www.google.com"; // Create the first browser window. CefBrowserHost::CreateBrowserSync(window_info, handler.get(), url, browser_settings, NULL); } SimpleHandlerSimpleHandler is responsible for handling browser-level callbacks. These callbacks are executed in the browser process. In this example we use the same CefClient instance for all browsers, but your application can use different CefClient instances as appropriate. See the GeneralUsageWiki page or API header files for additional information on CefClient and related interfaces. // simple_handler.h #include "include/cef_client.h" #include <list> class SimpleHandler : public CefClient, public CefDisplayHandler, public CefLifeSpanHandler, public CefLoadHandler { public: SimpleHandler(); ~SimpleHandler(); // Provide access to the single global instance of this object. static SimpleHandler* GetInstance(); // CefClient methods: virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE { return this; } virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE { return this; } virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE { return this; } // CefDisplayHandler methods: virtual void OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString& title) OVERRIDE; // CefLifeSpanHandler methods: virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE; virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE; // CefLoadHandler methods: virtual void OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, ErrorCode errorCode, const CefString& errorText, const CefString& failedUrl) OVERRIDE; // Request that all existing browser windows close. void CloseAllBrowsers(bool force_close); private: // List of existing browser windows. Only accessed on the CEF UI thread. typedef std::list<CefRefPtr<CefBrowser> > BrowserList; BrowserList browser_list_; // Include the default reference counting implementation. IMPLEMENT_REFCOUNTING(SimpleHandler); }; // simple_handler.cpp #include "cefsimple/simple_handler.h" #include <sstream> #include <string> #include "cefsimple/util.h" #include "include/cef_app.h" #include "include/cef_runnable.h" namespace { SimpleHandler* g_instance = NULL; } // namespace SimpleHandler::SimpleHandler() { ASSERT(!g_instance); g_instance = this; } SimpleHandler::~SimpleHandler() { g_instance = NULL; } // static SimpleHandler* SimpleHandler::GetInstance() { return g_instance; } void SimpleHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) { REQUIRE_UI_THREAD(); // Add to the list of existing browsers. browser_list_.push_back(browser); } void SimpleHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) { REQUIRE_UI_THREAD(); // Remove from the list of existing browsers. BrowserList::iterator bit = browser_list_.begin(); for (; bit != browser_list_.end(); ++bit) { if ((*bit)->IsSame(browser)) { browser_list_.erase(bit); break; } } if (browser_list_.empty()) { // All browser windows have closed. Quit the application message loop. CefQuitMessageLoop(); } } void SimpleHandler::OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, ErrorCode errorCode, const CefString& errorText, const CefString& failedUrl) { REQUIRE_UI_THREAD(); // Don‘t display an error for downloaded files. if (errorCode == ERR_ABORTED) return; // Display a load error message. std::stringstream ss; ss << "<html><body bgcolor=\"white\">" "<h2>Failed to load URL " << std::string(failedUrl) << " with error " << std::string(errorText) << " (" << errorCode << ").</h2></body></html>"; frame->LoadString(ss.str(), failedUrl); } void SimpleHandler::CloseAllBrowsers(bool force_close) { if (!CefCurrentlyOn(TID_UI)) { // Execute on the UI thread. CefPostTask(TID_UI, NewCefRunnableMethod(this, &SimpleHandler::CloseAllBrowsers, force_close)); return; } if (browser_list_.empty()) return; BrowserList::const_iterator it = browser_list_.begin(); for (; it != browser_list_.end(); ++it) (*it)->GetHost()->CloseBrowser(force_close); } // simple_handler_win.cpp -- Windows-specific code. #include "cefsimple/simple_handler.h" #include <string> #include <windows.h> #include "cefsimple/util.h" #include "include/cef_browser.h" void SimpleHandler::OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString& title) { REQUIRE_UI_THREAD(); CefWindowHandle hwnd = browser->GetHost()->GetWindowHandle(); SetWindowText(hwnd, std::wstring(title).c_str()); } // simple_handler_gtk.cc -- Linux-specific code. #include "cefsimple/simple_handler.h" #include <gtk/gtk.h> #include <string> #include "cefsimple/util.h" #include "include/cef_browser.h" void SimpleHandler::OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString& title) { REQUIRE_UI_THREAD(); GtkWidget* window = gtk_widget_get_ancestor( GTK_WIDGET(browser->GetHost()->GetWindowHandle()), GTK_TYPE_WINDOW); std::string titleStr(title); gtk_window_set_title(GTK_WINDOW(window), titleStr.c_str()); } // simple_handler_mac.mm -- OS X-specific code. #include "cefsimple/simple_handler.h" #import <Cocoa/Cocoa.h> #include "cefsimple/util.h" #include "include/cef_browser.h" void SimpleHandler::OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString& title) { REQUIRE_UI_THREAD(); NSView* view = (NSView*)browser->GetHost()->GetWindowHandle(); NSWindow* window = [view window]; std::string titleStr(title); NSString* str = [NSString stringWithUTF8String:titleStr.c_str()]; [window setTitle:str]; } Build StepsBuild steps vary depending on the platform. Explore the project files included with the binary distribution for a complete understanding of all required steps. The build steps common to all platforms can generally be summarized as follows:
Windows
The resulting directory structure looks like this: Application/ cefsimple.exe <= cefsimple application executable libcef.dll <= main CEF library icudt.dll <= ICU unicode support library ffmpegsumo.dll <= HTML5 audio/video support library libEGL.dll, libGLESv2.dll, … <= accelerated compositing support libraries cef.pak, devtools_resources.pak <= non-localized resources and strings locales/ en-US.pak, … <= locale-specific resources and strings Linux
The resulting directory structure looks like this: Application/ cefsimple <= cefsimple application executable chrome-sandbox <= sandbox support binary libcef.so <= main CEF library ffmpegsumo.so <-- HTML5 audio/video support library cef.pak, devtools_resources.pak <= non-localized resources and strings locales/ en-US.pak, … <= locale-specific resources and strings Mac OS X
The resulting directory structure looks like this: cefsimple.app/ Contents/ Frameworks/ Chromium Embedded Framework.framework/ Chromium Embedded Framework <= main application library Libraries/ ffmpegsumo.so <= HTML5 audio/video support library Resources/ cef.pak, devtools_resources.pak <= non-localized resources and strings crash_inspector, crash_report_sender <= breakpad support en.lproj/, ... <= locale-specific resources and strings Info.plist libplugin_carbon_interpose.dylib <= plugin support library cefsimple Helper.app/ Contents/ Info.plist MacOS/ cefsimple Helper <= helper executable Pkginfo cefsimple Helper EH.app/ Contents/ Info.plist MacOS/ cefsimple Helper EH <= helper executable Pkginfo cefsimple Helper NP.app/ Contents/ Info.plist MacOS/ cefsimple Helper NP <= helper executable Pkginfo Info.plist MacOS/ cefsimple <= cefsimple application executable Pkginfo Resources/ cefsimple.icns, ... <= cefsimple application resources |
标签:
原文地址:http://blog.csdn.net/hellochenlian/article/details/43562521