I thought it was time to give back to the community with some detail of how DCEF3 works in Delphi because although this project is great bringing Chromium to Delphi, there is very little documentation and Chromium works in a very different way to normal Delphi controls or the normal Delphi way of doing things.
To start with, to get the latest version you need to checkout Branch 2062 from here:
https://code.google.com/p/dcef3/source/browse/?name=2062. This might not be that obvious.
The latest version doesn't seem to allow CefSingleProcess := true; to work anymore. This prompted us to review our code and gave us an understanding of what is actually going on.
So to start, DCEF3 for Delphi is a wrapper around a set of Chromium/WebKit files compiled for Win32/Win64 which are found in the BIN folder of your source folder.
Chromium and Chrome should not be confused. Your Delphi app uses the WebKit build deployed with your application (the files in the BIN\Win32 or Bin\Win64 folder should normally be in the same folder as your .exe file unless you specify otherwise. It does not use 'the version of Chrome installed on the PC by the user'.
Secondly, you will see any a number of threads that you need to add this to your DPR file for DCEF3 to work
CefCache := 'cache';
CefSingleProcess := false;
if not CefLoadLibDefault then
Exit;
What I haven't seen anywhere is 'why' or what this actually does.
Chromium is 'interesting' in the way it sets up the browser process. In order to protect different parts of the page rendering process from crashing other parts, multiple copies of your execution are started to serve the request. As a basic understanding there is a separate process for the javascript engine, rendering engine, etc. You will often end up with at least 5 processes running.
The code above detects if the execution (based on command line parameters) of the current executable is the main launch of your application (i.e. you ran it from Delphi, ran it from the desktop) or whether the command line parameters match those of the internal separate processes chrome creates once your application starts. You can see this behavior by placing a showmessage( cmdline ); at the very first line of your .DPR and setting cefSingleProcess := true after this.
This behavior is problematic to Delphi developers as they often place code in initialization sections of units and finalization sections of units which often have assumptions that the .dpr code will run. These init/final sections still execute with each of the spawned WebKit sub-instances and can cause strange crashing behavior that is very hard to track down or debug. If you do get weird crashes at startup/first load when using DCEF3 in non-single process this is probably where your problem lies.
A way around this is to tell Chromium to use a different executable for the 'sub-processes'. This executable could be built with ceflib/cefvcl included with no forms and a simple DPR containing only the commands above. For example this .exe could be subWebKit.exe and would ship alongside your MainApp.exe.
To make this process work you would add this line after CefSingleProcess := false;
CefBrowserSubprocessPath := 'subWebKit.exe';
The second thing to note is that when running in non single process mode your 'process messages' and perhaps your javascript callbacks although I haven't tested this yet might not be running in the same application instance, let alone the same thread as your main application. This means you can't access anything - not even your global variables. There is a message callback service available which you need to use to pass data between the two processes. I will write a further topic on this soon if anyone is interested.
This does make tasks that were very simple in TWebBrowser i.e. getting access to the DOM, much more complex, but the design does have advantages as it stops the browser becoming locked up by code that isn't thread safe and prevents one operation blocking the usability of the page. Because of the separate process you need to re-think your design and pass information back and forward with callbacks rather than grabbing something from the DOM and 'storing it until you need it'.
I hope this helps someone get started with this excellent component. You will see much better rendering performance when switching to CefSingleProcess := false;