CEF4Delphi

Description

CEF4Delphi is an open source project created by Salvador Díaz Fau to embed Chromium-based browsers in applications made with Delphi or Lazarus/FPC for Windows, Linux and MacOS.

Introduction

CEF4Delphi is based on DCEF3 and fpCEF3, which were using outdated branches of CEF. In order to have Chromium-based web browser tabs in BriskBard it's necessary to use the latest stable branch of CEF and have frequent updates. DCEF3 hasn't been updated for a long time so it was decided to create a new project.

The main goal of CEF4Delphi is to simplify, whenever is possible, the work necessary to upgrade it to the latest version of CEF. To achieve this goal it was necessary to take the following measures :

  • Some redundancies were removed. The OSR TChromium component was merged into TChromium.
  • The code comments copied from CEF were removed. The comments in CEF are updated as frequently as the code and they can be replaced by a reference to the CEF file where you can find them.
  • The code is now spread over many smaller units.
  • There are new comments with the equivalencies between classes and types of CEF4Delphi and CEF.

The latest version of CEF4Delphi uses the branch 4515 of CEF. More precisely, it uses CEF 92.0.20 which includes Chromium 92.0.4515.107

CEF4Delphi is developed on Delphi 10.4.2 and it has also been tested in Delphi 7, Delphi XE, Delphi 10, Delphi 10.2, Delphi 10.3 and Lazarus 2.0.12 with FPC 3.2.0. CEF4Delphi includes VCL, FireMonkey (FMX) and Lazarus components tested in 32 and 64 bits.

If you wish to test CEF4Delphi consider downloading the latest Delphi Community Edition from Embarcadero for free.

It's also possible to test CEF4Delphi downloading Lazarus/FPC for free.

Overview

Before using CEF4Delphi with an aplication made with Delphi or Lazarus it's necessary to understand that CEF4Delphi is a wrapper that uses CEF's C API and, in turn, CEF insulates the user from the underlying Chromium and Blink code complexity.

CEF4Delphi's overview

Stable releases

The master branch in the repository is considered a development branch and it may have issues. Use the latest released version if you need a stable component.

Links

CEF4Delphi project :

Chromium Embedded Framework (CEF) project :

CEF binaries used by CEF4Delphi :

OldCEF4Delphi project :

Compatibility

CEF4Delphi can be used in VCL, FMX and LCL applications with Delphi or Lazarus/FPC.

For more information about CEF4Delphi on Lazarus read this wiki page.

Windows

Google announced that they would drop Windows XP support for Chrome in 2015. The last CEF branch that was compatible with Windows XP was 2623, released in 2016.

Since CEF4Delphi uses the latest CEF branch, it's not compatible with Windows XP, Windows Vista, Windows Server 2003 and Windows Server 2008.

CEF4Delphi needs Windows 7, 8, 8.1, 10 or newer to make it work but if you need to test some other Windows version just download and try to run the CEF Sample Application from the CEF's downloads page.

If you need to support Windows XP and Vista in your app use OldCEF4Delphi.

Linux

Linux is fully supported by CEF4Delphi with Firemonkey and Lazarus/FPC in x86 and ARM CPUs.

In the case of Linux applications CEF requires Ubuntu 16.04 or newer.

MacOS

MacOS is also fully supported by CEF4Delphi with Firemonkey and Lazarus/FPC in x86 CPUs.

CEF4Delphi has not been tested in MacOS with ARM CPUs. CEF requires MacOS 10.11 or newer to run.

Installation

To build and install CEF4Delphi in the latest version of Delphi you need to follow these steps :

  1. Download the latest version of CEF4Delphi from GitHub.
  2. Decompress CEF4Delphi into a directory and make sure your user has write privileges in that directory.
  3. Run Delphi.
  4. Add the CEF4Delphi's source directory to the Library path in Delphi inside the Tools->Options menu. The Options window will show up and there you have to click on Environment Options→Delphi Options→Library, select the right platform (32 or 64 bits) and add directory in Library path.
  5. Open the file CEF4Delphi.dproj from Delphi if you only want the VCL components. If you want VCL and FireMonkey (FMX) components, open CEF4Delphi_FMX.dproj.
  6. Right-click on the CEF4Delphi.bpl icon inside the Project manager and select the Build option.
  7. Right-click on the CEF4Delphi.bpl icon inside the Project manager and select the Install option.

To compile and install CEF4Delphi in Delphi 7 you need to follow these steps :

  1. Download the latest version of CEF4Delphi from GitHub.
  2. Decompress CEF4Delphi into a directory and make sure your user has write privileges in that directory.
  3. Run Delphi.
  4. Add the CEF4Delphi's source directory to the Library path in Delphi inside the Tools→Environment options menu. The Environment Options window will show up and there you have to select the Library tab to modify the Library path.
  5. Open the file CEF4Delphi_D7.dpk from Delphi.
  6. Click on the Compile button.
  7. Click on the Install button.

To compile and install CEF4Delphi in Lazarus you need to install the DCPCrypt package first using the Online Package Manager. Then follow these steps :

  1. Download the latest version of CEF4Delphi from GitHub.
  2. Decompress CEF4Delphi into a directory and make sure your user has write privileges in that directory.
  3. Run Lazarus.
  4. Open the file cef4delphi_lazarus.lpk from the Package→Open Package File (*.lpk)... menu.
  5. Click on the Compile button in the package window.
  6. Click on the Use button and select the Install option.

Building the first demo

Before going into the coding details let’s take a moment to build one of the demos to see a working CEF browser.

Windows

Build this demo depending on the IDE you use :

  • Lazarus : Lazarus_Windows/MiniBrowser
  • Delphi : Delphi_VCL/MiniBrowser
  • Delphi 7 : Delphi_VCL/SimpleBrowser2

In a few seconds you’ll see a new executable inside the CEF4Delphi/bin directory called MiniBrowser.exe or SimpleBrowser2.exe but if you try to run the new EXE it will show an error message with a list of missing CEF binaries.

You need to copy the CEF binaries to the CEF4Delphi/bin directory and you can download them using these links :

Once you've downloaded and decompressed the package you must copy the contents of the Release and Resources directories to the CEF4Delphi/bin directory.

The final layout looks like this :

Final layout of the CEF binary distribution files with the application.
Notice how cef_sandbox.lib and libcef.lib can be omitted.

If everything is in place you should be able to run the demo.

Linux

Build this demo depending on the IDE you use :

  • Lazarus : Lazarus_Linux/MiniBrowser
  • Delphi : Delphi_FMX_Linux/FMXExternalPumpBrowser2

If you use Lazarus you will see a new MiniBrowser executable in the CEF4Delphi/bin directory but if you use Delphi you'll need to deploy the executables in order to copy them to a subdirectory inside paserver/scratch-dir/Username-ConnectionProfileName.

As with the Windows demos, you need to download the CEF binaries using these links :

Decompress the package and copy the contents of the Release and Resources directories to the CEF4Delphi/bin directory in case of Lazarus.

If you use Delphi you'll have decompress the package and copy the contents of the Release and Resources directories to the $HOME/cef directory. The FMXExternalPumpBrowser2_sp executable found in the paserver/scratch-dir/Username-ConnectionProfileName/FMXExternalPumpBrowser2_sp/ directory also needs to be copied to $HOME/cef.

The final layout looks like this :

Final layout of the CEF binary distribution files with the application.

Notice that the libcef.so file is huge because it includes the debug symbols. Running the demo with that libcef.so file will take a few seconds due to its size. In order to reduce the file size and improve the loading time you can remove the debug symbols with the following command :

strip libcef.so

If the CEF binaries are in the right place you should be able to run the demo now.

MacOS

If you use Lazarus build the Lazarus_Mac/ExternalPumpBrowser and the Lazarus_any_OS/AppHelper demo projects.

At this point you should see 2 new app bundles in the CEF4Delphi/bin directory corresponding to those 2 projects.

Download the CEF binaries package using this link : MacOS x86 (64 bit)

MacOS app bundles must have the right directory structure and contents. In this case you have to decompress the CEF binaries package and copy the contents of Release/Chromium Embedded Framework.framework directory into the ExternalPumpBrowser.app/Contents/Frameworks/Chromium Embedded Framework.framework/ directory.

The AppHelper app must be included inside the ExternalPumpBrowser app and to do that you need to execute the Lazarus_any_OS/AppHelper/create_mac_helper_apps.sh script with the complete path to ExternalPumpBrowser.app as the script argument.

The final layout looks like this :

ExternalPumpBrowser.app/ Contents/ Frameworks/ Chromium Embedded Framework.framework/ Chromium Embedded Framework Libraries/ libEGL.dylib libGLESv2.dylib libswiftshader_libEGL.dylib libswiftshader_libGLESv2.dylib libvk_swiftshader.dylib vk_swiftshader_icd.json Resources/ chrome_100_percent.pak chrome_200_percent.pak resources.pak.pak Info.plist icudtl.dat snapshot_blob.bin v8_context_snapshot.x86_64.bin en.lproj/ locale.pak es.lproj/ locale.pak ****.lproj/ locale.pak ExternalPumpBrowser Helper.app/ Contents/ Info.plist MacOS/ ExternalPumpBrowser Helper Pkginfo ExternalPumpBrowser Helper (GPU).app/ Contents/ Info.plist MacOS/ ExternalPumpBrowser Helper (GPU) Pkginfo ExternalPumpBrowser Helper (Plugin).app/ Contents/ Info.plist MacOS/ ExternalPumpBrowser Helper (Plugin) Pkginfo ExternalPumpBrowser Helper (Renderer).app/ Contents/ Info.plist MacOS/ ExternalPumpBrowser Helper (Renderer) Pkginfo Info.plist MacOS/ ExternalPumpBrowser Pkginfo Resources/ binding.html, ...

If the CEF binaries are correctly copied into the ExternalPumpBrowser app bundle and the create_mac_helper_apps.sh script run without errors then you should be able to run the demo.

In case you use Delphi open the Delphi_FMX_Mac/FMXExternalPumpBrowser/FMXExternalPumpBrowserGroup.groupproj file, build all the projects in that group and use the Deployment window for each project to copy the app bundle in the remote system.

Decompress the CEF binaries package and copy the contents of Release/Chromium Embedded Framework.framework directory into the paserver/scratch-dir/Username-ConnectionProfileName/Chromium Embedded Framework.framework directory.

When you run the main project of the project group it will copy the CEF binaries and all the other app bundles corresponding to the helper projects inside FMXExternalPumpBrowser.app/Contents/Frameworks/ automatically.

First steps

Before you use CEF4Delphi for the first time it's highly recommended to read all the information about CEF and the design documents of Chromium.

The CEF API documents are available at magpcss.org and there is extensive information about the CEF usage in its source code comments.

As you can see in the documentation, by default CEF uses multiple threads and processes to protect the overall application from bugs and glitches in the rendering engine.

In order to create the child processes, CEF can run the application's executable again or we can configure CEF to use a different executable.

By default, CEF will use the same executable but this can be problematic if the application has a complex initialization or the operating system has other requirements.

CEF4Delphi simplifies all CEF initialization thanks to GlobalCEFApp, which is an instance of the TCEFApplication class.

Windows

Windows applications can configure CEF to use one EXE file for all processes or a different EXE for the CEF subprocesses.

If you decide to use the same EXE for all processes then you need to modify the project file (*.DPR in Delphi and *.LPR in Lazarus) to create GlobalCEFApp, set its properties and call GlobalCEFApp.StartMainProcess before the Application.Initialize call.

Let's go into the details using a Delphi project file as an example, The Lazarus project files are almost identical.

Delphi applications use to have this code in the DPR file :

program Project1; uses Vcl.Forms, Unit1 in 'Unit1.pas' {Form1}; {$R *.res} begin Application.Initialize; Application.MainFormOnTaskbar := True; Application.CreateForm(TForm1, Form1); Application.Run; end.

To include CEF4Delphi you would need to modify it like this :

program Project1; uses Vcl.Forms, WinApi.Windows, uCEFApplication, Unit1 in 'Unit1.pas' {Form1}; {$R *.res} {$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE} begin GlobalCEFApp := TCefApplication.Create; if GlobalCEFApp.StartMainProcess then begin Application.Initialize; Application.MainFormOnTaskbar := True; Application.CreateForm(TForm1, Form1); Application.Run; end; GlobalCEFApp.Free; end.

The differences are these :

  • The uses clause has a reference to uCEFApplication.
  • In case your application is 32 bits then you need to add the SetPEFlags directive to set the IMAGE_FILE_LARGE_ADDRESS_AWARE flag which allows 32-bit processes to use up to 3GB of RAM. This is not necessary for 64 bits applications.
  • GlobalCEFApp is created at the beginning of the project file. Here you can set its properties before the GlobalCEFApp.StartMainProcess call.
  • The GlobalCEFApp.StartMainProcess call is the condition in an if..then clause before the Application instance is initialized and run.
  • GlobalCEFApp is destroyed in the last project file line.

The main process will execute the code in the project file following these steps :

  • The initialization sections in all the units declared in the uses clause are executed.
  • GlobalCEFApp is created.
  • GlobalCEFApp.StartMainProcess is executed and it returns TRUE quickly, which allows the Application to be initialized and run.
  • Application.Run is executed and the program execution stays inside it until the user closes the application.
  • GlobalCEFApp is destroyed.
  • The finalization sections in all the units declared in the uses clause are executed.

However, the CEF subprocesses will execute the code in the project file following these steps :

  • The initialization sections in all the units declared in the uses clause are executed.
  • GlobalCEFApp is created.
  • GlobalCEFApp.StartMainProcess is executed and the program execution remains inside it until Chromium decides to close this process.
  • GlobalCEFApp.StartMainProcess returns FALSE when Chromium closes this process, which avoids initializing and running Application.
  • GlobalCEFApp is destroyed.
  • The finalization sections in all the units declared in the uses clause are executed.

If you're adding a CEF browser to an existing application and you need to decide if you can use the same EXE or a different EXE for the CEF subprocesses then you have to check what code is already in the application's project file and the initialization and finalization sections because it will be executed once for each process.

If moving all the existing code out of the initialization and finalization sections and moving the existing code in the project file is too complicated or it's not allowed then you can use a different EXE for the CEF subprocesses.

In this case, you can create GlobalCEFApp at any moment in your application's lifetime.

Using a different EXE allows your application to initialize CEF only if the user needs to see a web browser but you have to remember that CEF can only be initialized once per process. This is a CEF feature and there's no workaround.

See these demos for all the details :

  • Delphi_VCL/SimpleBrowser2 : This is a Delphi demo using one EXE for all CEF processes.
  • Lazarus_Windows/SimpleBrowser2 : This is a Lazarus demo using one EXE for all CEF processes.
  • Delphi_VCL/Subprocess : This is a Delphi demo using a different EXE for the CEF subprocesses.
  • Lazarus_Windows/Subprocess : This is a Lazarus demo using a different EXE for the CEF subprocesses.
Linux

Using CEF4Delphi in Linux has a few differences with Windows and it can use almost the same code. Read the usage guidelines for Windows before reading this section.

Lazarus demos must add UseCthreads to the custom options in the project options window.

All the Lazarus demos use GTK 2 and the Delphi demo use GTK 3. QT is not supported at the moment.

Chromium should be initialized in a process with one thread and this can cause issues sometimes because GTK creates some threads when it's initialized.

Lazarus initializes GTK in the Initialization section of the Interfaces unit and Delphi initializes GTK in the Initialization section of the FMX.Platform unit.

The Initialization sections are executed before the project file code and this may create problems with CEF.

Lazarus demos can avoid this problem in two ways :

  • Create a custom Interfaces unit that moves the GTK initialization away from the Initialization section.
  • Create a new unit that creates GlobalCEFApp in its Initialization section and add it to the uses clause of the project file before the Interfaces unit.

Delphi demos use FMXLinux and you need to create a custom unit that creates GlobalCEFApp in its Initialization section and then add it to the uses clause in the first place.

See these demos for all the details :

  • Lazarus_Linux/SimpleBrowser2 : This is a Lazarus demo using one executable for all CEF processes.
  • Lazarus_Linux/Subprocess : This is a Lazarus demo using a different executable for the CEF subprocesses.
  • Delphi_FMX_Linux/FMXExternalPumpBrowser2 : This is a Delphi demo using a different executable for the CEF subprocesses.
MacOS

Applications with CEF browsers in MacOS must contain 4 Helper app bundles for the subprocesses. Chromium searches for them internally when it needs to create a new subprocess. Read this for more information.

The Helper apps must be in the <appname>.app/Contents/Frameworks directory and they must have these names :

  • <appname> Helper.app
  • <appname> Helper (GPU).app
  • <appname> Helper (Plugin).app
  • <appname> Helper (Renderer).app

The 4 Helper applications are identical copies with different name and they only need to create GlobalCEFApp, call GlobalCEFApp.InitLibLocationFromArgs, call GlobalCEFApp.StartSubProcess and destroy GlobalCEFApp.

Read the code comments in the following demos for more details :

  • Delphi_FMX_Mac/FMXExternalPumpBrowser
  • Lazarus_Mac/ExternalPumpBrowser
  • Lazarus_any_OS/AppHelper

Browser configurations

CEF can be configured to create web browsers in several ways :

  • Browsers in normal mode (a.k.a. windowed mode) : CEF will create a child control to draw the web contents by itself and many other features and events are also handled internally by CEF.
  • Browsers in off screen rendering mode (a.k.a. OSR mode) : CEF will return a pixel buffer with the web contents. The application has to draw that buffer on a canvas and it also handles all events.

The normal mode requires a lot less code and it's much faster than the OSR mode but the OSR mode gives the application a much greater control of the browser.

You can compare these two modes with the SimpleBrowser2 and SimpleOSRBrowser demos.

CEF threads and the browser message loop

Another CEF configuration option worth mentioning is the use of a multithreaded message loop.

By default, CEF enables this setting and it will use a background thread to run the browser message loop in order to improve performance. As a result, all CEF events are executed in a CEF thread which is different than the main application thread.

Windows and Linux controls are not thread safe and you should avoid creating, destroying or modifying controls inside CEF events if it's configured to use a multithreaded message loop.

Some demos ignore this because they are oversimplified to keep the code as simple and easy to understand as possible but you should move the GUI handling code to a different procedure and execute it in the main application thread.

If CEF is configured to disable the multithreaded message loop then all CEF events are executed in the main application thread but the browser performance is not as good.

The CEF browsers in MacOS always have to disable the multithreaded message loop.

You can compare the code in the SimpleBrowser2 and ExternalPumpBrowser demos to know all the implementation differences between these two configuration options.

CEF4Delphi components

CEF4Delphi comes with many VCL, FMX and LCL components and classes to embed a web browser in all possible CEF configuration settings.

TCEFApplication

The main class used to simplify the CEF initialization and destruction is TCEFApplication and most of the demos create GlobalCEFApp as a TCEFApplication instance.

The SubProcess demos are an exception to this rule to avoid some issues with MS Office and they use TCEFApplicationCore instead.

TCEFApplication creates automatically some CEF handlers only if they are needed. Those handlers are CefApp, CefBrowserProcessHandler, CefRenderProcessHandler, CefResourceBundleHandler and CefLoadHandler.

Read this for more information about this class.

TChromium / TFMXChromium

This is the component that puts together all browser procedures, functions, properties and events in one place. It has all you need to create, modify and destroy a web browser.

VCL and LCL applications use TChromium but FireMonkey applications use TFMXChromium. Both components inherit from TChromiumCore which has most of the code but you'll see many references to TChromium in the forum to keep it simple.

TChromiumCore also creates many CEF handlers only if they are needed like CefClient, CefResourceRequestHandler, etc.

Read this for more information about this component.

TCEFWindowParent / TFMXWindowParent

The TCEFWindowParent component is used in VCL and LCL applications along with a TChromium component to embed a web browser in normal mode.

As commented previously, browsers in normal mode let CEF create some native child controls to show the web contents in them. TCEFWindowParent inherits from TCEFWinControl and it's used as the parent of those child controls. TCEFWindowParent also controls the size of those child controls automatically. See the SimpleBrowser2 demo for more details.

TFMXWindowParent is a FireMonkey component with the same purpose as TCEFWindowParent but due to FMX's code structure it has to inherit from TCommonCustomForm.

TFMXWindowParent is used with a TFMXChromium component and it has to be created at runtime. See the SimpleFMXBrowser demo for more details.

TCEFLinkedWindowParent

This component can be used by VCL and LCL applications. It has the same purpose as TCEFWindowParent but it has a Chromium property to link it directly to a TChromium component.

TCEFLinkedWindowParent resizes the child controls created by CEF for browsers in normal mode and sets the browser focus using the linked TChromium component.

TCEFWindowParent and TCEFLinkedWindowParent work fine in Windows and you can used any of them but you can't use TCEFWindowParent in Linux or MacOS.

TBufferPanel / TFMXBufferPanel

TBufferPanel is used by VCL and LCL applications with browsers in OSR mode to draw the browser contents. TFMXBufferPanel has the same purpose but it's used in FireMonkey applications.

See the SimpleOSRBrowser demo for more details.

TCEFWorkScheduler / TFMXWorkScheduler

TCEFWorkScheduler is used by VCL and LCL applications using CEF browsers with a disabled multithreaded message loop. TFMXWorkScheduler has the same purpose but it's used in FireMonkey applications.

These components handle the GlobalCEFApp.DoMessageLoopWork calls using the delayMs parameter in the GlobalCEFApp.OnScheduleMessagePumpWork event.

VCL and LCL applications must create GlobalCEFWorkScheduler as an instance of TCEFWorkScheduler before creating GlobalCEFApp.

FMX applications must create GlobalFMXWorkScheduler as an instance of TFMXWorkScheduler before creating GlobalCEFApp.

It's also necessary to destroy GlobalCEFApp before destroying GlobalCEFWorkScheduler or GlobalFMXWorkScheduler.

See the ExternalPumpBrowser and FMXExternalPumpBrowser demos for all the implementation details.

TChromiumWindow

TChromiumWindow was created to embed extremely simple web browsers in a slightly easier way than using a TChromium and a TCEFWindowParent pair.

TChromiumWindow can be used in VCL and LCL applications with browsers in normal mode but if you use many TChromium events and procedures you should consider using the other components.

See the SimpleBrowser demo for all the details.

TBrowserWindow / TOSRBrowserWindow

TBrowserWindow is a LCL component that simplifies the creation of multi-platform applications with embedded web browsers in normal mode. TOSRBrowserWindow has the same purpose but it uses browsers in OSR mode.

If you use the same source code to build a Windows, Linux and MacOS application with Lazarus then it's recommended to use these components.

TBrowserWindow and TOSRBrowserWindow were created by Martin_fr (a.k.a. User4martin), one of the Lazarus project administrators.

See all the demos in the Lazarus_any_OS directory for more details.

TCEFServerComponent

TCEFServerComponent allows you to create a small HTTP and WebSocket server in VCL, LCL and FMX applications.

It can be used to implement inter-process communication (IPC) between an application and a local host.

See the SimpleServer demo for more details.

TCEFURLRequestClientComponent

TCEFUrlRequestClientComponent allows you to make URL requests unrelated to any browser from a VCL, LCL or FMX application.

See the URLRequest demo for more details.

TCEFSentinel

TCEFSentinel is used as a timer that checks the number of running CEF processes when you close all browsers before shutdown.

This component is only used as a last resort when there's an unresolved shutdown issue in CEF or CEF4Delphi that generates exceptions when the application is closed.

Chromium Views Framework

All the components in the Chromium Views Framework tab allow you to use Views/Aura widgets and layout managers in VCL and LCL applications.

CEF uses this GUI framework internally on Windows, Linux and MacOS to create the browsers.

See the ToolBoxBrowser2 demo and read this document for more details about this framework.

Web browser creation

When GlobalCEFApp is configured with the default values CEF enables the multithreaded message loop and it's initialized in a background thread after the GlobalCEFApp.StartMainProcess call.

CEF browsers can only be created when the CEF initialization is complete and this can cause a race condition if an application tries to create a browser when the main application form is shown for the first time.

Most of the demos use a simple TTimer to retry the TChromium.CreateBrowser call after a few milliseconds but it's also possible to use the TCEFApplication.OnGlobalContextInitialized event to send a message to the main form and then create the browsers.

Lazarus applications handle this issue automatically if you use TBrowserWindow or TOSRBrowserWindow.

Application shutdown

Chromium requires that all the browsers in your application should be closed correctly before destroying GlobalCEFApp, which is the last step in the project file.

CEF browsers must follow these steps in order to close them correctly :

  1. Call TChromium.CloseBrowser.
  2. Wait for the TChromium.OnClose event.
  3. Wait for the TChromium.OnBeforeClose event.

Each demo has a more detailed destruction sequence in the code comments because each browser configuration can add a few more steps or skip some step but in general, your application should wait until all the TChromium.OnBeforeClose events are executed before closing the application.

Read the code comments in the demo you used as a template for your application to know more details.

CEF4Delphi and FireMonkey

FireMonkey is a very powerful framework capable of creating applications for Windows, MacOS, Linux, iOS and Android with the same code but that abstraction layer can make things a little more complicated because CEF needs access to some features at lower API levels.

For example, some Windows demos use a custom class that implements the IFMXApplicationService interface to access Windows messages. Some other demos use a custom WndProc procedure for the same reason. In MacOS the demo uses a custom class that implements the IFMXApplicationService interface to implement CrAppProtocol which is required by Chromium.

If you need to embed a CEF browser with CEF4Delphi in a FireMonkey application you need to add $(FrameworkType) as a conditional define in the project options.

To do that, open the Project menu and click on Options.... Then select the Building→Delphi Compiler option to the left, select All configurations in the Target box and type $(FrameworkType) in the Conditional defines box.

You can also use FMX without quotes instead of $(FrameworkType) if the conditional define doesn't seem to work in that project.

CEF4Delphi demos

The CEF4Delphi\demos directory has multiple directories with demos for Delphi and Lazarus :

  1. Delphi_FMX_Linux
    • FMXExternalPumpBrowser2
      Browser in OSR mode that uses an external message pump with a different executable for the subprocesses.
  2. Delphi_FMX_Mac
    • FMXExternalPumpBrowser
      Browser in OSR mode that uses an external message pump with 4 app bundles for the subprocesses.
  3. Delphi_FMX_Windows
    • FMXExternalPumpBrowser
      Browser in OSR mode that uses an external message pump.
    • FMXTabbedBrowser
      Multiple browsers in tabs in normal mode.
    • FMXTabbedOSRBrowser
      Multiple browsers in tabs in OSR mode.
    • FMXToolBoxBrowser
      Browser in a child form in normal mode.
    • SimpleFMXBrowser
      Simple browser in normal mode.
  4. Delphi_VCL
    • ConsoleBrowser
      Browser in OSR mode created in a DLL which is loaded from a console application.
    • ConsoleBrowser2
      Console application that creates an OSR browser in a thread and takes a screenshot.
    • CookieVisitor
      Browser that uses TCefCookieManagerRef to read all the cookies.
    • CustomResourceBrowser
      A simple browser that shows customized resources and web pages instead of Internet websites.
    • DLLBrowser
      A web browser created from a DLL.
    • DOMVisitor
      A basic DOM visitor using the CEF classes. It includes node search and DOM iteration.
    • EditorBrowser
      HTML editor using TChromium and TCEFWindowParent.
    • Extensions
      • HelloWorldExt
        Loads a simple Hello World extension.
      • PageColorExt
        Loads the Set Page Color extension that allows you to change the page background color.
    • ExternalPumpBrowser
      Browser made with the TChromium and TCEFWindowParent components using an external message pump.
    • FullScreenBrowser
      Simple full screen browser that uses TChromium and TCEFWindowParent. It uses the ESC key to exit.
    • JavaScript
      • CustomTitleBar
        Browser using a JS extension that controls the Delphi form.
      • JSDialog
        Demo showing how to use cutom JS dialogs.
      • JSEval
        This demo evaluates JavaScript code using the V8Context.
      • JSExecutingFunctions
        This demo shows how to register and execute custom JS functions with native implementations.
      • JSExtension
        Demo showing how to register a basic JS extension with a function and how to send information between processes.
      • JSExtensionWithFunction
        Demo showing how to register a JS extension with a function that returns a value.
      • JSExtensionWithObjectParameter
        Demo showing how to register a JS extension with a function that has a parameter.
      • JSRTTIExtension
        This demo is similar to JSExtension but it uses RTTI to register the extension.
      • JSSimpleExtension
        This demo register a JS extension that sets a variable value.
      • JSSimpleWindowBinding
        Demo showing how to attach values to a frame's window object.
      • JSWindowBindingSubProcess
        This demo is similar to JSSimpleWindowBinding but it uses a different executable for the subprocesses.
      • JSWindowBindingWithArrayBuffer
        This demo is similar to JSSimpleWindowBinding but it attaches a value with an array buffer.
      • JSWindowBindingWithFunction
        Demo showing how to bind a function to the window object.
      • JSWindowBindingWithObject
        This demo is similar to JSSimpleWindowBinding but it attaches a value with an object.
    • KioskOSRBrowser
      Full screen Kiosk browser in OSR mode with a virtual keyboard that is shown automatically when the user clicks on an editable HTML element. The context menu also has an option to show/hide the keyboard. Press the ESC key to exit this demo.
    • MDIBrowser
      Multiple TChromium components in one MDI application.
    • MDIExternalPumpBrowser
      Multiple TChromium components in one MDI application using the external message pump configuration.
    • MediaRouter
      Demo showing how to use the media device discovery and messaging.
    • MiniBrowser
      A web browser using a TChromium and a TCEFWindowParent. It has custom context menus, basic web browser interface, developer tools, zoom, printing, proxy settings and some extra functions to copy the HTML and JavaScript printing.
    • OAuth2Tester
      User authentication with OAuth 2.0 and REST API requests using TCEFServerComponent and TCEFUrlRequestClientComponent.
    • OSRExternalPumpBrowser
      Browser in OSR mode using an external message pump.
    • PopupBrowser
      This demo shows how to use custom forms with popup windows in OSR mode.
    • PopupBrowser2
      This demo shows how to use custom forms with popup windows in normal mode.
    • PostInspectorBrowser
      Web browser with a POST data inspector.
    • ResponseFilterBrowser
      A browser made with the TChromium and TCEFWindowParent components using a custom response filter.
    • SchemeRegistrationBrowser
      URL scheme registration that shows customized web pages.
    • SimpleBrowser
      The simplest web browser made with CEF4Delphi. It uses a TChromiumWindow component.
    • SimpleBrowser2
      The simplest web browser made with CEF4Delphi. It uses a combination of two components : TChromium and TCEFWindowParent.
    • SimpleExternalPumpBrowser
      Browser made with the TChromiumWindow component using the external message pump configuration.
    • SimpleOSRBrowser
      A web browser using TChromium in OSR mode in case you need offscreen rendering.
    • SimpleServer
      HTTP and websockets server made with the TCEFServerComponent component for communication between applications in localhost.
    • SubProcess
      Web browser that uses a different executable for the CEF subprocesses.
    • TabbedBrowser
      Multiple TChromium and TCEFWindowParent components in tab sheets.
    • TabbedBrowser2
      Multiple TChromium and TCEFWindowParent components inside a TFrame in tab sheets.
    • TinyBrowser
      A tiny web browser created with the Views Framework without VCL or FMX.
    • TinyBrowser2
      Extremely simple browser similar to the cefsimple demo in the CEF project.
    • ToolBoxBrowser
      Multiple TChromium components in one application using ToolBox forms.
    • ToolBoxBrowser2
      A simple browser in a child form created using the Views Framework.
    • ToolBoxSubProcessBrowser
      Demo similar to ToolBoxBrowser but using a different executable for the CEF subprocesses.
    • URLRequest
      Demo showing how to do URL requests with the TCEFUrlRequestClientComponent component.
    • WebpageSnapshot
      Desktop application that creates an OSR browser in a thread and takes a screenshot.
  5. Lazarus_any_OS
    • AppHelper
      Helper executable used by MacOS demos for the CEF subprocesses.
    • BrowserWindow
      Web browser demo using a TBrowserWindow component.
    • BrowserWindowDom
      Demo similar to BrowserWindow but including a DOM visitor.
    • BrowserWindowEx
      Multiple TBrowserWindow components in the same form.
    • BrowserWindowOsrDom
      Web browser using a TOsrBrowserWindow component in OSR mode with a DOM visitor.
    • ExternalPumpBrowser
      Demo using a TChromium and TCEFLinkedWindowParent for any OS with the external message pump configuration.
  6. Lazarus_Linux
    • ExternalPumpBrowser
      Browser made with the TChromium and TCEFLinkedWindowParent components using an external message pump.
    • MiniBrowser
      A web browser using a TChromium and a TCEFLinkedWindowParent in normal mode. It has custom context menus, basic web browser interface, developer tools, zoom, printing, etc.
    • OSRExternalPumpBrowser
      Browser in OSR mode using an external message pump.
    • PopupBrowser2
      This demo shows how to use custom forms with popup windows in normal mode.
    • SimpleBrowser
      The simplest web browser made with CEF4Delphi. It uses a TChromiumWindow component.
    • SimpleBrowser2
      The simplest web browser made with CEF4Delphi. It uses a combination of two components : TChromium and TCEFLinkedWindowParent.
    • SimpleOSRBrowser
      A web browser using TChromium in OSR mode in case you need offscreen rendering.
    • SubProcess
      Web browser that uses a different executable for the CEF subprocesses.
    • TabbedBrowser2
      Multiple TChromium and TCEFLinkedWindowParent components inside a TFrame in tab sheets.
    • TinyBrowser2
      Extremely simple browser similar to the cefsimple demo in the CEF project.
  7. Lazarus_Mac
    • ExternalPumpBrowser
      Browser made with the TChromium and TCEFLinkedWindowParent components using an external message pump.
  8. Lazarus_Windows
    • ConsoleBrowser2
      Console application that creates an OSR browser in a thread and takes a screenshot.
    • CookieVisitor
      Browser that uses TCefCookieManagerRef to read all the cookies.
    • CustomResourceBrowser
      A simple browser that shows customized resources and web pages instead of Internet websites.
    • DOMVisitor
      A basic DOM visitor using the CEF classes. It includes node search and DOM iteration.
    • EditorBrowser
      HTML editor using TChromium and TCEFWindowParent.
    • ExternalPumpBrowser
      Browser made with the TChromium and TCEFWindowParent components using an external message pump.
    • FullScreenBrowser
      Simple full screen browser that uses TChromium and TCEFWindowParent. It uses the ESC key to exit.
    • JavaScript
      • JSDialog
        Demo showing how to use cutom JS dialogs.
      • JSEval
        This demo evaluates JavaScript code using the V8Context.
      • JSExecutingFunctions
        This demo shows how to register and execute custom JS functions with native implementations.
      • JSExtension
        Demo showing how to register a basic JS extension with a function and how to send information between processes.
      • JSExtensionWithFunction
        Demo showing how to register a JS extension with a function that returns a value.
      • JSExtensionWithObjectParameter
        Demo showing how to register a JS extension with a function that has a parameter.
      • JSSimpleExtension
        This demo register a JS extension that sets a variable value.
      • JSSimpleWindowBinding
        Demo showing how to attach values to a frame's window object.
      • JSWindowBindingSubProcess
        This demo is similar to JSSimpleWindowBinding but it uses a different executable for the subprocesses.
      • JSWindowBindingWithArrayBuffer
        This demo is similar to JSSimpleWindowBinding but it attaches a value with an array buffer.
      • JSWindowBindingWithFunction
        Demo showing how to bind a function to the window object.
      • JSWindowBindingWithObject
        This demo is similar to JSSimpleWindowBinding but it attaches a value with an object.
    • MediaRouter
      Demo showing how to use the media device discovery and messaging.
    • MiniBrowser
      A web browser using a TChromium and a TCEFWindowParent. It has custom context menus, basic web browser interface, developer tools, zoom, printing, proxy settings and some extra functions to copy the HTML and JavaScript printing.
    • OAuth2Tester
      User authentication with OAuth 2.0 and REST API requests using TCEFServerComponent and TCEFUrlRequestClientComponent.
    • OSRExternalPumpBrowser
      Browser in OSR mode using an external message pump.
    • PopupBrowser
      This demo shows how to use custom forms with popup windows in OSR mode.
    • PopupBrowser2
      This demo shows how to use custom forms with popup windows in normal mode.
    • PostInspectorBrowser
      Web browser with a POST data inspector.
    • SchemeRegistrationBrowser
      URL scheme registration that shows customized web pages.
    • SimpleBrowser
      The simplest web browser made with CEF4Delphi. It uses a TChromiumWindow component.
    • SimpleBrowser2
      The simplest web browser made with CEF4Delphi. It uses a combination of two components : TChromium and TCEFWindowParent.
    • SimpleExternalPumpBrowser
      Browser made with the TChromiumWindow component using the external message pump configuration.
    • SimpleOSRBrowser
      A web browser using TChromium in OSR mode in case you need offscreen rendering.
    • SimpleServer
      HTTP and websockets server made with the TCEFServerComponent component for communication between applications in localhost.
    • SubProcess
      Web browser that uses a different executable for the CEF subprocesses.
    • TabbedBrowser
      Multiple TChromium and TCEFWindowParent components in tab sheets.
    • TabbedBrowser2
      Multiple TChromium and TCEFWindowParent components inside a TFrame in tab sheets.
    • TinyBrowser
      A tiny web browser created with the Views Framework without LCL.
    • TinyBrowser2
      Extremely simple browser similar to the cefsimple demo in the CEF project.
    • ToolBoxBrowser
      Multiple TChromium components in one application using ToolBox forms.
    • ToolBoxBrowser2
      A simple browser in a child form created using the Views Framework.
    • URLRequest
      Demo showing how to do URL requests with the TCEFUrlRequestClientComponent component.
    • WebpageSnapshot
      Desktop application that creates an OSR browser in a thread and takes a screenshot.

To test the Windows and Linux demos follow these instructions :

  1. Download the CEF binaries used by CEF4Delphi following this guide.
  2. Decompress the CEF binaries in a temporary directory.
  3. Copy the contents from the Release and Resources directories to the BIN directory in CEF4Delphi.
  4. Build the demo.
  5. Run the demo.

To test the MacOS demos follow the instructions given in the Building the first demo section for MacOS.

Debugging

CEF uses several processes and that can make your app difficult to debug in Delphi but in those situations you can use the following tools :

  • Set GlobalCEFApp.SingleProcess to True before the GlobalCEFApp.StartMainProcess call in the DPR file. That will force CEF to use only one process and Delphi can debug it without problems. This single process mode should only be used for debugging purposes.
  • Use several processes but select the option Run→Run Without Debugging... in Delphi. Then click on Run→Attach To Process... and select the process you wish to debug.
  • Use the debug.log file to log custom text messages with the CefLog function like the DOMVisitor demo does. It's necesary to set the GlobalCEFApp.LogFile and GlobalCEFApp.LogSeverity properties before the GlobalCEFApp.StartMainProcess call in the DPR file.
  • In case of using javascript you can use the DevTools to read the console messages and to debug the javascript code. The MiniBrowser demo has all you need to add the DevTools to your app.

Codecs

Due to licensing issues and the US patent law, the CEF binaries available at Spotify have the proprietary codecs disabled. If you use those binaries, any website that offers media using H264 won't work.

In case you need to use those codecs, you can build the CEF binaries yourself as described in this forum thread.

Building the CEF binaries requires a very powerful computer. It can take several hours even with an Intel I7 cpu with 16GB of RAM. It's recommended to have 32GB of RAM and to use an SSD drive.

Read the 'Quick Start', 'Branches And Building' and 'Automated Build Setup' articles in the CEF Wiki before building the binaries.

The CEF sources used to build the binaries must have exactly the same CEF version supported by CEF4Delphi at that moment.

Read this forum thread for a shorter guide to build the CEF binaries.

Browser plugins and extensions

The Adobe Flash PPAPI plugin is no longer supported. NaCl plugins, NPAPI plugins and browser extensions are partially supported.

Google dropped support of NPAPI plugins in Chromium 45 released in September 2015. Only the CEF branches older than 2454 support NPAPI plugins for Java, Silverlight or Facebook video.

About the name

CEF4Delphi is just a numeronym and it should be interpreted as CEF for Delphi. It doesn't mean that it's based in CEF4.

More information in other languages

How to help

If you wish to help in this project you can make a donation by clicking this button :

You can also use Patreon to help this project :

Patreon

Or sponsor this project on GitHub :

You can also help by telling your friends about this project, sharing the messages of this project on the social networks, writing articles about this project on your website, making suggestions, reporting issues, etc.

If you shop online you can also help by using these links for your purchases :




This article was updated on July 29th, 2021.


Copyright © 2021  All rights reserved.
Cookie usage

By browsing our site you agree to our use of cookies. You will only see this message once.
Find out more
Ok