diff --git a/.gitignore b/.gitignore
index 974a315f..67dbf6fd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -66,6 +66,7 @@ __recovery/
*.stat
# Project specific
+bin/*.log
bin/*.pak
bin/locales
bin/*.bin
diff --git a/bin/app_view.html b/bin/app_view.html
new file mode 100644
index 00000000..c6a8c575
--- /dev/null
+++ b/bin/app_view.html
@@ -0,0 +1,168 @@
+
+
+
+
+
+
+
+ App View
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/Delphi_VCL/CustomTitleBar/00-DeleteDCUs.bat b/demos/Delphi_VCL/CustomTitleBar/00-DeleteDCUs.bat
new file mode 100644
index 00000000..a9a84095
--- /dev/null
+++ b/demos/Delphi_VCL/CustomTitleBar/00-DeleteDCUs.bat
@@ -0,0 +1,18 @@
+del /s /q *.dcu
+del /s /q *.exe
+del /s /q *.res
+del /s /q *.rsm
+del /s /q *.log
+del /s /q *.dsk
+del /s /q *.identcache
+del /s /q *.stat
+del /s /q *.local
+del /s /q *.~*
+rmdir Win32\Debug
+rmdir Win32\Release
+rmdir Win32
+rmdir Win64\Debug
+rmdir Win64\Release
+rmdir Win64
+rmdir __history
+rmdir __recovery
diff --git a/demos/Delphi_VCL/CustomTitleBar/CustomTitleBar.dpr b/demos/Delphi_VCL/CustomTitleBar/CustomTitleBar.dpr
new file mode 100644
index 00000000..2301f9ae
--- /dev/null
+++ b/demos/Delphi_VCL/CustomTitleBar/CustomTitleBar.dpr
@@ -0,0 +1,75 @@
+// ************************************************************************
+// ***************************** CEF4Delphi *******************************
+// ************************************************************************
+//
+// CEF4Delphi is based on DCEF3 which uses CEF3 to embed a chromium-based
+// browser in Delphi applications.
+//
+// The original license of DCEF3 still applies to CEF4Delphi.
+//
+// For more information about CEF4Delphi visit :
+// https://www.briskbard.com/index.php?lang=en&pageid=cef
+//
+// Copyright © 2017 Salvador Díaz Fau. All rights reserved.
+//
+// ************************************************************************
+// ************ vvvv Original license and comments below vvvv *************
+// ************************************************************************
+(*
+ * Delphi Chromium Embedded 3
+ *
+ * Usage allowed under the restrictions of the Lesser GNU General Public License
+ * or alternatively the restrictions of the Mozilla Public License 1.1
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+ * the specific language governing rights and limitations under the License.
+ *
+ * Unit owner : Henri Gourvest
+ * Web site : http://www.progdigy.com
+ * Repository : http://code.google.com/p/delphichromiumembedded/
+ * Group : http://groups.google.com/group/delphichromiumembedded
+ *
+ * Embarcadero Technologies, Inc is not permitted to use or redistribute
+ * this source code without explicit permission.
+ *
+*)
+
+program CustomTitleBar;
+
+{$I cef.inc}
+
+uses
+{$IFDEF DELPHI16_UP}
+ Vcl.Forms,
+ WinApi.Windows,
+{$ELSE}
+ Forms,
+ Windows,
+{$ENDIF }
+ uCEFApplication,
+ uCustomTitleBarExtension in 'uCustomTitleBarExtension.pas' {CTBForm} ,
+ uTestExtension in 'uTestExtension.pas';
+
+{$R *.res}
+// CEF3 needs to set the LARGEADDRESSAWARE flag which allows 32-bit processes to use up to 3GB of RAM.
+{$SETPEFLAGS IMAGE_FILE_LARGE_ADDRESS_AWARE}
+
+begin
+ // GlobalCEFApp creation and initialization moved to a different unit to fix the memory leak described in the bug #89
+ // https://github.com/salvadordf/CEF4Delphi/issues/89
+ CreateGlobalCEFApp;
+
+ if GlobalCEFApp.StartMainProcess then
+ begin
+ Application.Initialize;
+{$IFDEF DELPHI11_UP}
+ Application.MainFormOnTaskbar := True;
+{$ENDIF}
+ Application.CreateForm(TCTBForm, CTBForm);
+ Application.Run;
+ end;
+
+ DestroyGlobalCEFApp;
+
+end.
diff --git a/demos/Delphi_VCL/CustomTitleBar/CustomTitleBar.dproj b/demos/Delphi_VCL/CustomTitleBar/CustomTitleBar.dproj
new file mode 100644
index 00000000..5bdd47f9
--- /dev/null
+++ b/demos/Delphi_VCL/CustomTitleBar/CustomTitleBar.dproj
@@ -0,0 +1,591 @@
+
+
+ {7AA32B92-A408-42CB-A571-383721053FFA}
+ 18.5
+ VCL
+ CustomTitleBar.dpr
+ True
+ Debug
+ Win64
+ 3
+ Application
+
+
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Cfg_1
+ true
+ true
+
+
+ true
+ Cfg_1
+ true
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Cfg_2
+ true
+ true
+
+
+ true
+ Cfg_2
+ true
+ true
+
+
+ 3082
+ $(BDS)\bin\delphi_PROJECTICON.ico
+ CustomTitleBar
+ System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace)
+ CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=
+ .\$(Platform)\$(Config)
+ false
+ false
+ false
+ false
+ false
+ ..\..\..\..\bin
+
+
+ Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
+ DBXSqliteDriver;RESTComponents;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;frxe23;vclFireDAC;emsclientfiredac;DataSnapFireDAC;svnui;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;svn;Intraweb;DBXOracleDriver;inetdb;CEF4Delphi;FmxTeeUI;FireDACIBDriver;fmx;fmxdae;vclib;FireDACDBXDriver;dbexpress;IndyProtocols230;vclx;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;frxTee23;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;CloudService;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;vcl;DBXSybaseASEDriver;FireDACDb2Driver;GR32_DSGN_RSXE5;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;TeeDB;FireDAC;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;soaprtl;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;GR32_RSXE5;bindcomp;appanalytics;DBXInformixDriver;bindcompvcl;frxDB23;TeeUI;IndyCore230;vclribbon;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;IndySystem230;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;frx23;fmxase;$(DCC_UsePackage)
+ 1033
+ $(BDS)\bin\default_app.manifest
+ CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)
+ true
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
+
+
+ DBXSqliteDriver;RESTComponents;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;emsclientfiredac;DataSnapFireDAC;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;Intraweb;DBXOracleDriver;inetdb;FmxTeeUI;FireDACIBDriver;fmx;fmxdae;vclib;FireDACDBXDriver;dbexpress;IndyProtocols230;vclx;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;CloudService;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;vcl;DBXSybaseASEDriver;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;TeeDB;FireDAC;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;soaprtl;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;bindcompvcl;TeeUI;IndyCore230;vclribbon;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;IndySystem230;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;fmxase;$(DCC_UsePackage)
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
+ Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)
+ Debug
+ true
+ CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
+ 1033
+ $(BDS)\bin\default_app.manifest
+
+
+ DEBUG;$(DCC_Define)
+ true
+ false
+ true
+ true
+ true
+
+
+ true
+ 1033
+ true
+ false
+ Debug
+ CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)
+ PerMonitor
+
+
+ ..\..\..\bin
+ ..\..\..\source;$(DCC_UnitSearchPath)
+ true
+ CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
+ 1033
+ true
+ PerMonitorV2
+
+
+ false
+ RELEASE;$(DCC_Define)
+ 0
+ 0
+
+
+ true
+ PerMonitor
+
+
+ ..\..\..\bin
+ true
+ CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
+ 1033
+ true
+ PerMonitorV2
+
+
+
+ MainSource
+
+
+
+
+
+
+ Cfg_2
+ Base
+
+
+ Base
+
+
+ Cfg_1
+ Base
+
+
+
+ Delphi.Personality.12
+ Application
+
+
+
+
+ Embarcadero C++Builder Office 2000 Servers Package
+ Embarcadero C++Builder Office XP Servers Package
+ Microsoft Office 2000 Sample Automation Server Wrapper Components
+ Microsoft Office XP Sample Automation Server Wrapper Components
+
+
+
+
+
+ JSRTTIExtension.exe
+ true
+
+
+
+
+
+ res\drawable-normal
+ 1
+
+
+
+
+ 1
+ .dylib
+
+
+ 0
+ .dll;.bpl
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+
+
+ library\lib\mips
+ 1
+
+
+
+
+ library\lib\x86
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ res\drawable-xlarge
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
+
+
+ res\drawable-xhdpi
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ Contents\MacOS
+ 1
+
+
+ 1
+
+
+ 0
+
+
+
+
+ Contents\MacOS
+ 1
+ .framework
+
+
+ 0
+
+
+
+
+ res\drawable-small
+ 1
+
+
+
+
+ 1
+
+
+
+
+ Contents\MacOS
+ 1
+
+
+ 1
+
+
+ Contents\MacOS
+ 0
+
+
+
+
+ classes
+ 1
+
+
+
+
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+
+
+ 1
+
+
+
+
+ Contents\Resources
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ Contents\MacOS
+ 0
+
+
+ 0
+
+
+
+
+ res\drawable-ldpi
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ res\drawable-mdpi
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ 1
+ .dylib
+
+
+ 0
+ .bpl
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ Contents
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ Contents
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\values-v21
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ library\lib\armeabi
+ 1
+
+
+
+
+ 1
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+ 0
+
+
+ Contents\MacOS
+ 1
+
+
+ 1
+
+
+
+
+ res\drawable-large
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ res\values
+ 1
+
+
+
+
+ res\xml
+ 1
+
+
+
+
+ res\drawable-hdpi
+ 1
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ True
+
+
+ 12
+
+
+
+
+
diff --git a/demos/Delphi_VCL/CustomTitleBar/cef.inc b/demos/Delphi_VCL/CustomTitleBar/cef.inc
new file mode 100644
index 00000000..8334dc78
--- /dev/null
+++ b/demos/Delphi_VCL/CustomTitleBar/cef.inc
@@ -0,0 +1,409 @@
+// ************************************************************************
+// ***************************** CEF4Delphi *******************************
+// ************************************************************************
+//
+// CEF4Delphi is based on DCEF3 which uses CEF3 to embed a chromium-based
+// browser in Delphi applications.
+//
+// The original license of DCEF3 still applies to CEF4Delphi.
+//
+// For more information about CEF4Delphi visit :
+// https://www.briskbard.com/index.php?lang=en&pageid=cef
+//
+// Copyright © 2017 Salvador Diaz Fau. All rights reserved.
+//
+// ************************************************************************
+// ************ vvvv Original license and comments below vvvv *************
+// ************************************************************************
+(*
+ * Delphi Chromium Embedded 3
+ *
+ * Usage allowed under the restrictions of the Lesser GNU General Public License
+ * or alternatively the restrictions of the Mozilla Public License 1.1
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+ * the specific language governing rights and limitations under the License.
+ *
+ * Unit owner : Henri Gourvest
+ * Web site : http://www.progdigy.com
+ * Repository : http://code.google.com/p/delphichromiumembedded/
+ * Group : http://groups.google.com/group/delphichromiumembedded
+ *
+ * Embarcadero Technologies, Inc is not permitted to use or redistribute
+ * this source code without explicit permission.
+ *
+ *)
+
+ // The complete list of compiler versions is here :
+ // http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Compiler_Versions
+
+{$DEFINE DELPHI_VERSION_UNKNOW}
+
+// Delphi 5
+{$IFDEF VER130}
+ {$UNDEF DELPHI_VERSION_UNKNOW}
+ {$DEFINE DELPHI5_UP}
+{$ENDIF}
+
+// Delphi 6
+{$IFDEF VER140}
+ {$UNDEF DELPHI_VERSION_UNKNOW}
+ {$DEFINE DELPHI5_UP}
+ {$DEFINE DELPHI6_UP}
+{$ENDIF}
+
+// Delphi 7
+{$IFDEF VER150}
+ {$UNDEF DELPHI_VERSION_UNKNOW}
+ {$DEFINE DELPHI5_UP}
+ {$DEFINE DELPHI6_UP}
+ {$DEFINE DELPHI7_UP}
+{$ENDIF}
+
+// Delphi 8
+{$IFDEF VER160}
+ {$UNDEF DELPHI_VERSION_UNKNOW}
+ {$DEFINE DELPHI5_UP}
+ {$DEFINE DELPHI6_UP}
+ {$DEFINE DELPHI7_UP}
+ {$DEFINE DELPHI8_UP}
+{$ENDIF}
+
+// Delphi 2005
+{$IFDEF VER170}
+ {$UNDEF DELPHI_VERSION_UNKNOW}
+ {$DEFINE DELPHI5_UP}
+ {$DEFINE DELPHI6_UP}
+ {$DEFINE DELPHI7_UP}
+ {$DEFINE DELPHI8_UP}
+ {$DEFINE DELPHI9_UP}
+{$ENDIF}
+
+{$IFDEF VER180}
+ {$UNDEF DELPHI_VERSION_UNKNOW}
+ // Delphi 2007
+ {$IFDEF VER185}
+ {$DEFINE DELPHI5_UP}
+ {$DEFINE DELPHI6_UP}
+ {$DEFINE DELPHI7_UP}
+ {$DEFINE DELPHI8_UP}
+ {$DEFINE DELPHI9_UP}
+ {$DEFINE DELPHI10_UP}
+ {$DEFINE DELPHI11_UP}
+ // Delphi 2006
+ {$ELSE}
+ {$DEFINE DELPHI5_UP}
+ {$DEFINE DELPHI6_UP}
+ {$DEFINE DELPHI7_UP}
+ {$DEFINE DELPHI8_UP}
+ {$DEFINE DELPHI9_UP}
+ {$DEFINE DELPHI10_UP}
+ {$ENDIF}
+{$ENDIF}
+
+// Delphi 2009
+{$IFDEF VER200}
+ {$UNDEF DELPHI_VERSION_UNKNOW}
+ {$DEFINE DELPHI5_UP}
+ {$DEFINE DELPHI6_UP}
+ {$DEFINE DELPHI7_UP}
+ {$DEFINE DELPHI8_UP}
+ {$DEFINE DELPHI9_UP}
+ {$DEFINE DELPHI10_UP}
+ {$DEFINE DELPHI11_UP}
+ {$DEFINE DELPHI12_UP}
+{$ENDIF}
+
+//Delphi 2010
+{$IFDEF VER210}
+ {$UNDEF DELPHI_VERSION_UNKNOW}
+ {$DEFINE DELPHI5_UP}
+ {$DEFINE DELPHI6_UP}
+ {$DEFINE DELPHI7_UP}
+ {$DEFINE DELPHI8_UP}
+ {$DEFINE DELPHI9_UP}
+ {$DEFINE DELPHI10_UP}
+ {$DEFINE DELPHI11_UP}
+ {$DEFINE DELPHI12_UP}
+ {$DEFINE DELPHI14_UP}
+{$ENDIF}
+
+// Delphi XE
+{$IFDEF VER220}
+ {$UNDEF DELPHI_VERSION_UNKNOW}
+ {$DEFINE DELPHI5_UP}
+ {$DEFINE DELPHI6_UP}
+ {$DEFINE DELPHI7_UP}
+ {$DEFINE DELPHI8_UP}
+ {$DEFINE DELPHI9_UP}
+ {$DEFINE DELPHI10_UP}
+ {$DEFINE DELPHI11_UP}
+ {$DEFINE DELPHI12_UP}
+ {$DEFINE DELPHI14_UP}
+ {$DEFINE DELPHI15_UP}
+{$ENDIF}
+
+// Delphi XE2 (First FireMonkey and 64bit compiler)
+{$IFDEF VER230}
+ {$UNDEF DELPHI_VERSION_UNKNOW}
+ {$DEFINE DELPHI5_UP}
+ {$DEFINE DELPHI6_UP}
+ {$DEFINE DELPHI7_UP}
+ {$DEFINE DELPHI8_UP}
+ {$DEFINE DELPHI9_UP}
+ {$DEFINE DELPHI10_UP}
+ {$DEFINE DELPHI11_UP}
+ {$DEFINE DELPHI12_UP}
+ {$DEFINE DELPHI14_UP}
+ {$DEFINE DELPHI15_UP}
+ {$DEFINE DELPHI16_UP}
+{$ENDIF}
+
+// Delphi XE3
+{$IFDEF VER240}
+ {$UNDEF DELPHI_VERSION_UNKNOW}
+ {$DEFINE DELPHI5_UP}
+ {$DEFINE DELPHI6_UP}
+ {$DEFINE DELPHI7_UP}
+ {$DEFINE DELPHI8_UP}
+ {$DEFINE DELPHI9_UP}
+ {$DEFINE DELPHI10_UP}
+ {$DEFINE DELPHI11_UP}
+ {$DEFINE DELPHI12_UP}
+ {$DEFINE DELPHI14_UP}
+ {$DEFINE DELPHI15_UP}
+ {$DEFINE DELPHI16_UP}
+ {$DEFINE DELPHI17_UP}
+{$ENDIF}
+
+// Delphi XE4
+{$IFDEF VER250}
+ {$UNDEF DELPHI_VERSION_UNKNOW}
+ {$DEFINE DELPHI5_UP}
+ {$DEFINE DELPHI6_UP}
+ {$DEFINE DELPHI7_UP}
+ {$DEFINE DELPHI8_UP}
+ {$DEFINE DELPHI9_UP}
+ {$DEFINE DELPHI10_UP}
+ {$DEFINE DELPHI11_UP}
+ {$DEFINE DELPHI12_UP}
+ {$DEFINE DELPHI14_UP}
+ {$DEFINE DELPHI15_UP}
+ {$DEFINE DELPHI16_UP}
+ {$DEFINE DELPHI17_UP}
+ {$DEFINE DELPHI18_UP}
+{$ENDIF}
+
+// Delphi XE5
+{$IFDEF VER260}
+ {$UNDEF DELPHI_VERSION_UNKNOW}
+ {$DEFINE DELPHI5_UP}
+ {$DEFINE DELPHI6_UP}
+ {$DEFINE DELPHI7_UP}
+ {$DEFINE DELPHI8_UP}
+ {$DEFINE DELPHI9_UP}
+ {$DEFINE DELPHI10_UP}
+ {$DEFINE DELPHI11_UP}
+ {$DEFINE DELPHI12_UP}
+ {$DEFINE DELPHI14_UP}
+ {$DEFINE DELPHI15_UP}
+ {$DEFINE DELPHI16_UP}
+ {$DEFINE DELPHI17_UP}
+ {$DEFINE DELPHI18_UP}
+ {$DEFINE DELPHI19_UP}
+{$ENDIF}
+
+// Delphi XE6
+{$IFDEF VER270}
+ {$UNDEF DELPHI_VERSION_UNKNOW}
+ {$DEFINE DELPHI5_UP}
+ {$DEFINE DELPHI6_UP}
+ {$DEFINE DELPHI7_UP}
+ {$DEFINE DELPHI8_UP}
+ {$DEFINE DELPHI9_UP}
+ {$DEFINE DELPHI10_UP}
+ {$DEFINE DELPHI11_UP}
+ {$DEFINE DELPHI12_UP}
+ {$DEFINE DELPHI14_UP}
+ {$DEFINE DELPHI15_UP}
+ {$DEFINE DELPHI16_UP}
+ {$DEFINE DELPHI17_UP}
+ {$DEFINE DELPHI18_UP}
+ {$DEFINE DELPHI19_UP}
+ {$DEFINE DELPHI20_UP}
+{$ENDIF}
+
+// Delphi XE7
+{$IFDEF VER280}
+ {$UNDEF DELPHI_VERSION_UNKNOW}
+ {$DEFINE DELPHI5_UP}
+ {$DEFINE DELPHI6_UP}
+ {$DEFINE DELPHI7_UP}
+ {$DEFINE DELPHI8_UP}
+ {$DEFINE DELPHI9_UP}
+ {$DEFINE DELPHI10_UP}
+ {$DEFINE DELPHI11_UP}
+ {$DEFINE DELPHI12_UP}
+ {$DEFINE DELPHI14_UP}
+ {$DEFINE DELPHI15_UP}
+ {$DEFINE DELPHI16_UP}
+ {$DEFINE DELPHI17_UP}
+ {$DEFINE DELPHI18_UP}
+ {$DEFINE DELPHI19_UP}
+ {$DEFINE DELPHI20_UP}
+ {$DEFINE DELPHI21_UP}
+{$ENDIF}
+
+// Delphi XE8
+{$IFDEF VER290}
+ {$UNDEF DELPHI_VERSION_UNKNOW}
+ {$DEFINE DELPHI5_UP}
+ {$DEFINE DELPHI6_UP}
+ {$DEFINE DELPHI7_UP}
+ {$DEFINE DELPHI8_UP}
+ {$DEFINE DELPHI9_UP}
+ {$DEFINE DELPHI10_UP}
+ {$DEFINE DELPHI11_UP}
+ {$DEFINE DELPHI12_UP}
+ {$DEFINE DELPHI14_UP}
+ {$DEFINE DELPHI15_UP}
+ {$DEFINE DELPHI16_UP}
+ {$DEFINE DELPHI17_UP}
+ {$DEFINE DELPHI18_UP}
+ {$DEFINE DELPHI19_UP}
+ {$DEFINE DELPHI20_UP}
+ {$DEFINE DELPHI21_UP}
+ {$DEFINE DELPHI22_UP}
+{$ENDIF VER290}
+
+// Rad Studio 10 - Delphi Seattle
+{$IFDEF VER300}
+ {$UNDEF DELPHI_VERSION_UNKNOW}
+ {$DEFINE DELPHI5_UP}
+ {$DEFINE DELPHI6_UP}
+ {$DEFINE DELPHI7_UP}
+ {$DEFINE DELPHI8_UP}
+ {$DEFINE DELPHI9_UP}
+ {$DEFINE DELPHI10_UP}
+ {$DEFINE DELPHI11_UP}
+ {$DEFINE DELPHI12_UP}
+ {$DEFINE DELPHI14_UP}
+ {$DEFINE DELPHI15_UP}
+ {$DEFINE DELPHI16_UP}
+ {$DEFINE DELPHI17_UP}
+ {$DEFINE DELPHI18_UP}
+ {$DEFINE DELPHI19_UP}
+ {$DEFINE DELPHI20_UP}
+ {$DEFINE DELPHI21_UP}
+ {$DEFINE DELPHI22_UP}
+ {$DEFINE DELPHI23_UP}
+{$ENDIF}
+
+// Rad Studio 10.1 - Delphi Berlin
+{$IFDEF VER310}
+ {$UNDEF DELPHI_VERSION_UNKNOW}
+ {$DEFINE DELPHI5_UP}
+ {$DEFINE DELPHI6_UP}
+ {$DEFINE DELPHI7_UP}
+ {$DEFINE DELPHI8_UP}
+ {$DEFINE DELPHI9_UP}
+ {$DEFINE DELPHI10_UP}
+ {$DEFINE DELPHI11_UP}
+ {$DEFINE DELPHI12_UP}
+ {$DEFINE DELPHI14_UP}
+ {$DEFINE DELPHI15_UP}
+ {$DEFINE DELPHI16_UP}
+ {$DEFINE DELPHI17_UP}
+ {$DEFINE DELPHI18_UP}
+ {$DEFINE DELPHI19_UP}
+ {$DEFINE DELPHI20_UP}
+ {$DEFINE DELPHI21_UP}
+ {$DEFINE DELPHI22_UP}
+ {$DEFINE DELPHI23_UP}
+ {$DEFINE DELPHI24_UP}
+{$ENDIF}
+
+// Rad Studio 10.2 - Delphi Tokyo
+{$IFDEF VER320}
+ {$UNDEF DELPHI_VERSION_UNKNOW}
+ {$DEFINE DELPHI5_UP}
+ {$DEFINE DELPHI6_UP}
+ {$DEFINE DELPHI7_UP}
+ {$DEFINE DELPHI8_UP}
+ {$DEFINE DELPHI9_UP}
+ {$DEFINE DELPHI10_UP}
+ {$DEFINE DELPHI11_UP}
+ {$DEFINE DELPHI12_UP}
+ {$DEFINE DELPHI14_UP}
+ {$DEFINE DELPHI15_UP}
+ {$DEFINE DELPHI16_UP}
+ {$DEFINE DELPHI17_UP}
+ {$DEFINE DELPHI18_UP}
+ {$DEFINE DELPHI19_UP}
+ {$DEFINE DELPHI20_UP}
+ {$DEFINE DELPHI21_UP}
+ {$DEFINE DELPHI22_UP}
+ {$DEFINE DELPHI23_UP}
+ {$DEFINE DELPHI24_UP}
+ {$DEFINE DELPHI25_UP}
+{$ENDIF}
+
+// Rad Studio 10.3 - Delphi Rio
+{$IFDEF VER330}
+ {$UNDEF DELPHI_VERSION_UNKNOW}
+ {$DEFINE DELPHI5_UP}
+ {$DEFINE DELPHI6_UP}
+ {$DEFINE DELPHI7_UP}
+ {$DEFINE DELPHI8_UP}
+ {$DEFINE DELPHI9_UP}
+ {$DEFINE DELPHI10_UP}
+ {$DEFINE DELPHI11_UP}
+ {$DEFINE DELPHI12_UP}
+ {$DEFINE DELPHI14_UP}
+ {$DEFINE DELPHI15_UP}
+ {$DEFINE DELPHI16_UP}
+ {$DEFINE DELPHI17_UP}
+ {$DEFINE DELPHI18_UP}
+ {$DEFINE DELPHI19_UP}
+ {$DEFINE DELPHI20_UP}
+ {$DEFINE DELPHI21_UP}
+ {$DEFINE DELPHI22_UP}
+ {$DEFINE DELPHI23_UP}
+ {$DEFINE DELPHI24_UP}
+ {$DEFINE DELPHI25_UP}
+ {$DEFINE DELPHI26_UP}
+{$ENDIF}
+
+{$IFDEF FPC}
+ {$DEFINE SUPPORTS_INLINE}
+{$ELSE}
+ {$IFDEF DELPHI_VERSION_UNKNOW}
+ {$DEFINE DELPHI5_UP}
+ {$DEFINE DELPHI6_UP}
+ {$DEFINE DELPHI7_UP}
+ {$DEFINE DELPHI8_UP}
+ {$DEFINE DELPHI9_UP}
+ {$DEFINE DELPHI10_UP}
+ {$DEFINE DELPHI11_UP}
+ {$DEFINE DELPHI12_UP}
+ {$DEFINE DELPHI14_UP}
+ {$DEFINE DELPHI15_UP}
+ {$DEFINE DELPHI16_UP}
+ {$DEFINE DELPHI17_UP}
+ {$DEFINE DELPHI18_UP}
+ {$DEFINE DELPHI19_UP}
+ {$DEFINE DELPHI20_UP}
+ {$DEFINE DELPHI21_UP}
+ {$DEFINE DELPHI22_UP}
+ {$DEFINE DELPHI23_UP}
+ {$DEFINE DELPHI24_UP}
+ {$DEFINE DELPHI25_UP}
+ {$DEFINE DELPHI26_UP}
+ {$ENDIF}
+{$ENDIF}
+
+{$IFDEF DELPHI9_UP}
+ {$DEFINE SUPPORTS_INLINE}
+{$ENDIF}
+
diff --git a/demos/Delphi_VCL/CustomTitleBar/uCustomTitleBarExtension.dfm b/demos/Delphi_VCL/CustomTitleBar/uCustomTitleBarExtension.dfm
new file mode 100644
index 00000000..d1fcc8fb
--- /dev/null
+++ b/demos/Delphi_VCL/CustomTitleBar/uCustomTitleBarExtension.dfm
@@ -0,0 +1,63 @@
+object CTBForm: TCTBForm
+ Left = 0
+ Top = 0
+ BorderStyle = bsNone
+ Caption = 'CEF4 Custom Title Bar'
+ ClientHeight = 628
+ ClientWidth = 994
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ OldCreateOrder = False
+ Position = poScreenCenter
+ OnCloseQuery = FormCloseQuery
+ OnCreate = FormCreate
+ OnShow = FormShow
+ PixelsPerInch = 96
+ TextHeight = 13
+ object CEFWindowParent1: TCEFWindowParent
+ Left = 0
+ Top = 0
+ Width = 994
+ Height = 628
+ Align = alClient
+ TabOrder = 0
+ ExplicitTop = 30
+ ExplicitWidth = 978
+ ExplicitHeight = 540
+ end
+ object Chromium1: TChromium
+ OnProcessMessageReceived = Chromium1ProcessMessageReceived
+ OnLoadEnd = Chromium1LoadEnd
+ OnBeforeContextMenu = Chromium1BeforeContextMenu
+ OnContextMenuCommand = Chromium1ContextMenuCommand
+ OnBeforePopup = Chromium1BeforePopup
+ OnAfterCreated = Chromium1AfterCreated
+ OnBeforeClose = Chromium1BeforeClose
+ OnClose = Chromium1Close
+ Left = 32
+ Top = 224
+ end
+ object Timer1: TTimer
+ Enabled = False
+ Interval = 300
+ OnTimer = Timer1Timer
+ Left = 32
+ Top = 288
+ end
+ object CEFSentinel1: TCEFSentinel
+ OnClose = CEFSentinel1Close
+ Left = 32
+ Top = 352
+ end
+ object Timer2: TTimer
+ Enabled = False
+ Interval = 1
+ OnTimer = Timer2Timer
+ Left = 624
+ Top = 336
+ end
+end
diff --git a/demos/Delphi_VCL/CustomTitleBar/uCustomTitleBarExtension.pas b/demos/Delphi_VCL/CustomTitleBar/uCustomTitleBarExtension.pas
new file mode 100644
index 00000000..7c665aac
--- /dev/null
+++ b/demos/Delphi_VCL/CustomTitleBar/uCustomTitleBarExtension.pas
@@ -0,0 +1,521 @@
+// ************************************************************************
+// ***************************** CEF4Delphi *******************************
+// ************************************************************************
+//
+// CEF4Delphi is based on DCEF3 which uses CEF to embed a chromium-based
+// browser in Delphi applications.
+//
+// The original license of DCEF3 still applies to CEF4Delphi.
+//
+// For more information about CEF4Delphi visit :
+// https://www.briskbard.com/index.php?lang=en&pageid=cef
+//
+// Copyright © 2017 Salvador Diaz Fau. All rights reserved.
+//
+// ************************************************************************
+// ************ vvvv Original license and comments below vvvv *************
+// ************************************************************************
+(*
+ * Delphi Chromium Embedded 3
+ *
+ * Usage allowed under the restrictions of the Lesser GNU General Public License
+ * or alternatively the restrictions of the Mozilla Public License 1.1
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+ * the specific language governing rights and limitations under the License.
+ *
+ * Unit owner : Henri Gourvest
+ * Web site : http://www.progdigy.com
+ * Repository : http://code.google.com/p/delphichromiumembedded/
+ * Group : http://groups.google.com/group/delphichromiumembedded
+ *
+ * Embarcadero Technologies, Inc is not permitted to use or redistribute
+ * this source code without explicit permission.
+ *
+*)
+
+unit uCustomTitleBarExtension;
+
+{$I cef.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI16_UP}
+ Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
+ System.Classes, Vcl.Graphics,
+ Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls,
+ Vcl.ComCtrls,
+{$ELSE}
+ Windows, Messages, SysUtils, Variants, Classes, Graphics,
+ Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
+{$ENDIF}
+ uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes,
+ uCEFConstants,
+ uCEFWinControl, uCEFSentinel;
+
+const
+ MINIBROWSER_SHOWTEXTVIEWER = WM_APP + $100;
+ MINIBROWSER_JSBINPARAM = WM_APP + $103;
+
+ MINIBROWSER_CONTEXTMENU_SETJSEVENT = MENU_ID_USER_FIRST + 1;
+ MINIBROWSER_CONTEXTMENU_JSVISITDOM = MENU_ID_USER_FIRST + 2;
+ MINIBROWSER_CONTEXTMENU_MUTATIONOBSERVER = MENU_ID_USER_FIRST + 3;
+ MINIBROWSER_CONTEXTMENU_SHOWDEVTOOLS = MENU_ID_USER_FIRST + 4;
+
+ MOUSEOVER_MESSAGE_NAME = 'mousestate';
+ WINDOW_MINIMIZE_MESSAGE = 'minimize';
+ WINDOW_MAXIMIZE_MESSAGE = 'maximize';
+ WINDOW_CLOSE_MESSAGE = 'close';
+ BINARY_PARAM_JS = 'JSBinaryParameter';
+
+type
+ TCTBForm = class(TForm)
+ CEFWindowParent1: TCEFWindowParent;
+ Chromium1: TChromium;
+ Timer1: TTimer;
+ CEFSentinel1: TCEFSentinel;
+ Timer2: TTimer;
+ procedure FormShow(Sender: TObject);
+ procedure GoBtnClick(Sender: TObject);
+ procedure Chromium1BeforeContextMenu(Sender: TObject;
+ const browser: ICefBrowser; const frame: ICefFrame;
+ const params: ICefContextMenuParams; const model: ICefMenuModel);
+ procedure Chromium1ContextMenuCommand(Sender: TObject;
+ const browser: ICefBrowser; const frame: ICefFrame;
+ const params: ICefContextMenuParams; commandId: Integer;
+ eventFlags: Cardinal; out Result: Boolean);
+ procedure Chromium1ProcessMessageReceived(Sender: TObject;
+ const browser: ICefBrowser; const frame: ICefFrame;
+ sourceProcess: TCefProcessId; const message: ICefProcessMessage;
+ out Result: Boolean);
+ procedure Chromium1AfterCreated(Sender: TObject;
+ const browser: ICefBrowser);
+ procedure Timer1Timer(Sender: TObject);
+ procedure Chromium1BeforePopup(Sender: TObject; const browser: ICefBrowser;
+ const frame: ICefFrame; const targetUrl, targetFrameName: ustring;
+ targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean;
+ const popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo;
+ var client: ICefClient; var settings: TCefBrowserSettings;
+ var extra_info: ICefDictionaryValue; var noJavascriptAccess: Boolean;
+ var Result: Boolean);
+ procedure FormCreate(Sender: TObject);
+ procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
+ procedure Chromium1Close(Sender: TObject; const browser: ICefBrowser;
+ var aAction: TCefCloseBrowserAction);
+ procedure Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
+ procedure CEFSentinel1Close(Sender: TObject);
+
+ procedure executeJS(frame: ICefFrame);
+ procedure Timer2Timer(Sender: TObject);
+ procedure Button1Click(Sender: TObject);
+ procedure Chromium1LoadEnd(Sender: TObject; const browser: ICefBrowser;
+ const frame: ICefFrame; httpStatusCode: Integer);
+ protected
+
+ tp, tpc: TPoint;
+ mouseDrag: Boolean;
+
+ FText: string;
+ // Variables to control when can we destroy the form safely
+ FCanClose: Boolean; // Set to True in TChromium.OnBeforeClose
+ FClosing: Boolean; // Set to True in the CloseQuery event.
+
+ procedure BrowserCreatedMsg(var aMessage: TMessage);
+ message CEF_AFTERCREATED;
+ procedure BrowserDestroyMsg(var aMessage: TMessage); message CEF_DESTROY;
+ procedure ShowTextViewerMsg(var aMessage: TMessage);
+ message MINIBROWSER_SHOWTEXTVIEWER;
+ procedure EvalJSBinParamMsg(var aMessage: TMessage);
+ message MINIBROWSER_JSBINPARAM;
+ procedure WMMove(var aMessage: TWMMove); message WM_MOVE;
+ procedure WMMoving(var aMessage: TMessage); message WM_MOVING;
+ public
+ { Public declarations }
+ end;
+
+var
+ CTBForm: TCTBForm;
+
+procedure CreateGlobalCEFApp;
+
+implementation
+
+{$R *.dfm}
+
+uses
+ uCefBinaryValue, uCefProcessMessage, uCEFv8Handler, uTestExtension,
+ uCEFMiscFunctions;
+
+
+// Please, read the code comments in the JSExtension demo (uJSExtension.pas) before using this demo!
+
+// This demo is almost identical to JSExtension but it uses a slightly easier
+// way to register JavaScript extensions inherited from the DCEF3 project.
+
+// Instead of creating a custom class inherited from TCefv8HandlerOwn and calling the
+// CefRegisterExtension function, this demo uses the TCefRTTIExtension.Register
+// class procedure to register the TTestExtension class, which is a custom Delphi
+// class with 2 class procedures.
+
+// TCefRTTIExtension uses the RTTI from the TTestExtension class to generate the
+// JS code and the ICefv8Handler parameters needed by CefRegisterExtension.
+
+// You still need to call TCefRTTIExtension.Register in the GlobalCEFApp.OnWebKitInitialized event
+// and use process messages to send information between processes.
+
+// TTestExtension can send information back to the browser with a process message.
+// The TTestExtension.mouseover function do this by calling
+// TCefv8ContextRef.Current.Browser.MainFrame.SendProcessMessage(PID_BROWSER, msg);
+
+// That message is received in the TChromium.OnProcessMessageReceived event.
+
+
+// Destruction steps
+// =================
+// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
+// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
+// 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
+// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
+
+procedure GlobalCEFApp_OnWebKitInitialized;
+begin
+{$IFDEF DELPHI14_UP}
+ // Registering the extension. Read this document for more details :
+ // https://bitbucket.org/chromiumembedded/cef/wiki/JavaScriptIntegration.md
+ if TCefRTTIExtension.Register('myextension', TTestExtension) then
+{$IFDEF DEBUG}CefDebugLog('JavaScript extension registered successfully!'){$ENDIF}
+ else
+{$IFDEF DEBUG}CefDebugLog('There was an error registering the JavaScript extension!'){$ENDIF};
+{$ENDIF}
+end;
+
+procedure CreateGlobalCEFApp;
+begin
+ GlobalCEFApp := TCefApplication.Create;
+ GlobalCEFApp.OnWebKitInitialized := GlobalCEFApp_OnWebKitInitialized;
+{$IFDEF DEBUG}
+ GlobalCEFApp.LogFile := 'debug.log';
+ GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO;
+{$ENDIF}
+end;
+
+procedure TCTBForm.GoBtnClick(Sender: TObject);
+begin
+ Chromium1.LoadURL('file:///app_view.html');
+end;
+
+procedure TCTBForm.CEFSentinel1Close(Sender: TObject);
+begin
+ FCanClose := True;
+ PostMessage(Handle, WM_CLOSE, 0, 0);
+end;
+
+procedure TCTBForm.Chromium1AfterCreated(Sender: TObject;
+ const browser: ICefBrowser);
+begin
+ PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
+ CTBForm.executeJS(Chromium1.browser.MainFrame);
+end;
+
+procedure TCTBForm.Chromium1BeforeContextMenu(Sender: TObject;
+ const browser: ICefBrowser; const frame: ICefFrame;
+ const params: ICefContextMenuParams; const model: ICefMenuModel);
+begin
+ // Adding some custom context menu entries
+ model.AddSeparator;
+ model.AddItem(MINIBROWSER_CONTEXTMENU_SHOWDEVTOOLS, 'Show DevTools');
+end;
+
+procedure TCTBForm.Chromium1BeforePopup(Sender: TObject;
+ const browser: ICefBrowser; const frame: ICefFrame;
+ const targetUrl, targetFrameName: ustring;
+ targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean;
+ const popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo;
+ var client: ICefClient; var settings: TCefBrowserSettings;
+ var extra_info: ICefDictionaryValue; var noJavascriptAccess: Boolean;
+ var Result: Boolean);
+begin
+ // For simplicity, this demo blocks all popup windows and new tabs
+ Result := (targetDisposition in [WOD_NEW_FOREGROUND_TAB,
+ WOD_NEW_BACKGROUND_TAB, WOD_NEW_POPUP, WOD_NEW_WINDOW]);
+end;
+
+procedure TCTBForm.executeJS(frame: ICefFrame);
+var
+
+ TempJSCode: string;
+
+begin
+ if (frame <> nil) and frame.IsValid then
+ begin
+ TempJSCode := 'document.body.addEventListener("mousedown", function(evt){' +
+ 'myextension.mousestate(getComputedStyle(evt.target).webkitAppRegion)' +
+ '});' + chr(13);
+
+ TempJSCode := TempJSCode + ' setAppCaption("' + CTBForm.caption + '");';
+
+ frame.ExecuteJavaScript(TempJSCode, 'about:blank', 0);
+ end;
+end;
+
+procedure TCTBForm.Chromium1ContextMenuCommand(Sender: TObject;
+ const browser: ICefBrowser; const frame: ICefFrame;
+ const params: ICefContextMenuParams; commandId: Integer; eventFlags: Cardinal;
+ out Result: Boolean);
+const
+ ELEMENT_ID = 'keywords';
+ // ID attribute in the search box at https://www.briskbard.com/forum/
+var
+ TempPoint: TPoint;
+
+begin
+ Result := False;
+
+ // Here is the code executed for each custom context menu entry
+ case commandId of
+ MINIBROWSER_CONTEXTMENU_SETJSEVENT:
+ CTBForm.executeJS(frame);
+
+ MINIBROWSER_CONTEXTMENU_SHOWDEVTOOLS:
+ begin
+ TempPoint.x := params.XCoord;
+ TempPoint.y := params.YCoord;
+
+ Chromium1.ShowDevTools(TempPoint, nil);
+ end;
+ end;
+end;
+
+procedure TCTBForm.EvalJSBinParamMsg(var aMessage: TMessage);
+var
+ TempMsg: ICefProcessMessage;
+ TempOpenDialog: TOpenDialog;
+ TempStream: TFileStream;
+ TempBinValue: ICefBinaryValue;
+ TempBuffer: TBytes;
+ TempSize: NativeUInt;
+ TempPointer: pointer;
+begin
+ TempOpenDialog := nil;
+ TempStream := nil;
+
+ try
+ try
+ TempOpenDialog := TOpenDialog.Create(nil);
+ TempOpenDialog.Filter := 'JPEG files (*.jpg)|*.JPG';
+
+ if TempOpenDialog.Execute then
+ begin
+ TempStream := TFileStream.Create(TempOpenDialog.FileName, fmOpenRead);
+ TempSize := TempStream.Size;
+
+ if (TempSize > 0) then
+ begin
+ SetLength(TempBuffer, TempSize);
+ TempSize := TempStream.Read(TempBuffer, TempSize);
+
+ if (TempSize > 0) then
+ begin
+ TempPointer := @TempBuffer[0];
+ TempBinValue := TCefBinaryValueRef.New(TempPointer, TempSize);
+ TempMsg := TCefProcessMessageRef.New(BINARY_PARAM_JS);
+
+ if TempMsg.ArgumentList.SetBinary(0, TempBinValue) then
+ Chromium1.SendProcessMessage(PID_RENDERER, TempMsg);
+ end;
+ end;
+ end;
+ except
+ on e: exception do
+ if CustomExceptionHandler('TCTBForm.EvalJSBinParamMsg', e) then
+ raise;
+ end;
+ finally
+ if (TempOpenDialog <> nil) then
+ FreeAndNil(TempOpenDialog);
+ if (TempStream <> nil) then
+ FreeAndNil(TempStream);
+ SetLength(TempBuffer, 0);
+ end;
+end;
+
+procedure TCTBForm.Chromium1LoadEnd(Sender: TObject; const browser: ICefBrowser;
+ const frame: ICefFrame; httpStatusCode: Integer);
+begin
+ CTBForm.executeJS(Chromium1.browser.MainFrame);
+end;
+
+procedure TCTBForm.Chromium1ProcessMessageReceived(Sender: TObject;
+ const browser: ICefBrowser; const frame: ICefFrame;
+ sourceProcess: TCefProcessId; const message: ICefProcessMessage;
+ out Result: Boolean);
+begin
+ Result := False;
+
+ if (message = nil) or (message.ArgumentList = nil) then
+ exit;
+
+ // This function receives the messages with the JavaScript results
+
+ // Many of these events are received in different threads and the VCL
+ // doesn't like to create and destroy components in different threads.
+
+ // It's safer to store the results and send a message to the main thread to show them.
+
+ // The message names are defined in the extension or in JS code.
+
+ if (message.Name = MOUSEOVER_MESSAGE_NAME) then
+ begin
+
+ tp := Mouse.CursorPos;
+ tp := CTBForm.ScreenToClient(tp);
+ mouseDrag := False;
+ if message.ArgumentList.GetString(0) = 'drag' then
+ begin
+ mouseDrag := True;
+ Timer2.Enabled := True;
+ end;
+
+ Result := True;
+ end;
+
+ if (message.Name = WINDOW_MINIMIZE_MESSAGE) then
+ begin
+ CTBForm.WindowState := wsMinimized;
+ end;
+
+ if (message.Name = WINDOW_MAXIMIZE_MESSAGE) then
+ begin
+ if CTBForm.WindowState = wsNormal then
+ begin
+ CTBForm.WindowState := wsMaximized;
+ end
+ else if CTBForm.WindowState = wsMaximized then
+ CTBForm.WindowState := wsNormal;
+ end;
+
+ if (message.Name = WINDOW_CLOSE_MESSAGE) then
+ begin
+ CTBForm.close;
+ end;
+
+end;
+
+procedure TCTBForm.FormShow(Sender: TObject);
+begin
+
+ Chromium1.DefaultURL := 'file:///app_view.html';
+
+ // GlobalCEFApp.GlobalContextInitialized has to be TRUE before creating any browser
+ // If it's not initialized yet, we use a simple timer to create the browser later.
+ if not(Chromium1.CreateBrowser(CEFWindowParent1, '')) then
+ Timer1.Enabled := True;
+
+end;
+
+procedure TCTBForm.WMMove(var aMessage: TWMMove);
+begin
+ inherited;
+
+ if (Chromium1 <> nil) then
+ Chromium1.NotifyMoveOrResizeStarted;
+end;
+
+procedure TCTBForm.WMMoving(var aMessage: TMessage);
+begin
+ inherited;
+
+ if (Chromium1 <> nil) then
+ Chromium1.NotifyMoveOrResizeStarted;
+end;
+
+procedure TCTBForm.ShowTextViewerMsg(var aMessage: TMessage);
+begin
+
+end;
+
+procedure TCTBForm.Timer1Timer(Sender: TObject);
+begin
+ Timer1.Enabled := False;
+ if not(Chromium1.CreateBrowser(CEFWindowParent1, '')) and
+ not(Chromium1.Initialized) then
+ begin
+ Timer1.Enabled := True;
+ end;
+end;
+
+procedure TCTBForm.BrowserCreatedMsg(var aMessage: TMessage);
+begin
+
+ CEFWindowParent1.UpdateSize;
+
+end;
+
+procedure TCTBForm.Chromium1BeforeClose(Sender: TObject;
+ const browser: ICefBrowser);
+begin
+ CEFSentinel1.Start;
+end;
+
+procedure TCTBForm.Chromium1Close(Sender: TObject; const browser: ICefBrowser;
+ var aAction: TCefCloseBrowserAction);
+begin
+ PostMessage(Handle, CEF_DESTROY, 0, 0);
+ aAction := cbaDelay;
+end;
+
+procedure TCTBForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
+begin
+ CanClose := FCanClose;
+
+ if not(FClosing) then
+ begin
+ FClosing := True;
+ Visible := False;
+ Chromium1.CloseBrowser(True);
+ end;
+end;
+
+procedure TCTBForm.FormCreate(Sender: TObject);
+begin
+ FCanClose := False;
+ FClosing := False;
+end;
+
+procedure TCTBForm.BrowserDestroyMsg(var aMessage: TMessage);
+begin
+ CEFWindowParent1.Free;
+end;
+
+procedure TCTBForm.Button1Click(Sender: TObject);
+begin
+
+end;
+
+/// ////////////////////////////////////////////////////////////////////////////
+
+procedure TCTBForm.Timer2Timer(Sender: TObject);
+var
+ MouseLBtnDown: Boolean;
+begin
+ tpc := Mouse.CursorPos;
+
+ MouseLBtnDown := (GetKeyState(VK_LBUTTON) < 0);
+
+ if not MouseLBtnDown then
+ begin
+ mouseDrag := False;
+ Timer2.Enabled := False;
+ end;
+
+ if mouseDrag then
+ begin
+ CTBForm.Left := tpc.x - tp.x;
+ CTBForm.top := tpc.y - tp.y;
+ end;
+
+end;
+
+end.
diff --git a/demos/Delphi_VCL/CustomTitleBar/uTestExtension.pas b/demos/Delphi_VCL/CustomTitleBar/uTestExtension.pas
new file mode 100644
index 00000000..204f5559
--- /dev/null
+++ b/demos/Delphi_VCL/CustomTitleBar/uTestExtension.pas
@@ -0,0 +1,151 @@
+// ************************************************************************
+// ***************************** CEF4Delphi *******************************
+// ************************************************************************
+//
+// CEF4Delphi is based on DCEF3 which uses CEF to embed a chromium-based
+// browser in Delphi applications.
+//
+// The original license of DCEF3 still applies to CEF4Delphi.
+//
+// For more information about CEF4Delphi visit :
+// https://www.briskbard.com/index.php?lang=en&pageid=cef
+//
+// Copyright © 2017 Salvador Diaz Fau. All rights reserved.
+//
+// ************************************************************************
+// ************ vvvv Original license and comments below vvvv *************
+// ************************************************************************
+(*
+ * Delphi Chromium Embedded 3
+ *
+ * Usage allowed under the restrictions of the Lesser GNU General Public License
+ * or alternatively the restrictions of the Mozilla Public License 1.1
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+ * the specific language governing rights and limitations under the License.
+ *
+ * Unit owner : Henri Gourvest
+ * Web site : http://www.progdigy.com
+ * Repository : http://code.google.com/p/delphichromiumembedded/
+ * Group : http://groups.google.com/group/delphichromiumembedded
+ *
+ * Embarcadero Technologies, Inc is not permitted to use or redistribute
+ * this source code without explicit permission.
+ *
+ *)
+
+unit uTestExtension;
+
+{$I cef.inc}
+
+interface
+
+uses
+ {$IFDEF DELPHI16_UP}
+ Winapi.Windows,
+ {$ELSE}
+ Windows,
+ {$ENDIF}
+ uCEFRenderProcessHandler, uCEFBrowserProcessHandler, uCEFInterfaces, uCEFProcessMessage,
+ uCEFv8Context, uCEFTypes, uCEFv8Handler;
+
+type
+ TTestExtension = class
+ class procedure mousestate(const data: string);
+ class procedure minimize();
+ class procedure maximize();
+ class procedure close();
+ end;
+
+implementation
+
+uses
+ uCEFMiscFunctions, uCEFConstants, uCustomTitleBarExtension;
+
+class procedure TTestExtension.mousestate(const data: string);
+var
+ TempMessage : ICefProcessMessage;
+ TempFrame : ICefFrame;
+begin
+ try
+ TempMessage := TCefProcessMessageRef.New(MOUSEOVER_MESSAGE_NAME);
+ TempMessage.ArgumentList.SetString(0, data);
+
+ // Sending a message back to the browser. It'll be received in the TChromium.OnProcessMessageReceived event.
+ // TCefv8ContextRef.Current returns the v8 context for the frame that is currently executing Javascript.
+
+ TempFrame := TCefv8ContextRef.Current.Browser.MainFrame;
+
+ if (TempFrame <> nil) and TempFrame.IsValid then
+ TempFrame.SendProcessMessage(PID_BROWSER, TempMessage);
+ finally
+ TempMessage := nil;
+ end;
+end;
+
+class procedure TTestExtension.minimize();
+var
+ TempMessage : ICefProcessMessage;
+ TempFrame : ICefFrame;
+begin
+ try
+ TempMessage := TCefProcessMessageRef.New(WINDOW_MINIMIZE_MESSAGE);
+
+
+ // Sending a message back to the browser. It'll be received in the TChromium.OnProcessMessageReceived event.
+ // TCefv8ContextRef.Current returns the v8 context for the frame that is currently executing Javascript.
+
+ TempFrame := TCefv8ContextRef.Current.Browser.MainFrame;
+
+ if (TempFrame <> nil) and TempFrame.IsValid then
+ TempFrame.SendProcessMessage(PID_BROWSER, TempMessage);
+ finally
+ TempMessage := nil;
+ end;
+end;
+
+class procedure TTestExtension.maximize();
+var
+ TempMessage : ICefProcessMessage;
+ TempFrame : ICefFrame;
+begin
+ try
+ TempMessage := TCefProcessMessageRef.New(WINDOW_MAXIMIZE_MESSAGE);
+
+
+ // Sending a message back to the browser. It'll be received in the TChromium.OnProcessMessageReceived event.
+ // TCefv8ContextRef.Current returns the v8 context for the frame that is currently executing Javascript.
+
+ TempFrame := TCefv8ContextRef.Current.Browser.MainFrame;
+
+ if (TempFrame <> nil) and TempFrame.IsValid then
+ TempFrame.SendProcessMessage(PID_BROWSER, TempMessage);
+ finally
+ TempMessage := nil;
+ end;
+end;
+
+class procedure TTestExtension.close();
+var
+ TempMessage : ICefProcessMessage;
+ TempFrame : ICefFrame;
+begin
+ try
+ TempMessage := TCefProcessMessageRef.New(WINDOW_CLOSE_MESSAGE);
+
+
+ // Sending a message back to the browser. It'll be received in the TChromium.OnProcessMessageReceived event.
+ // TCefv8ContextRef.Current returns the v8 context for the frame that is currently executing Javascript.
+
+ TempFrame := TCefv8ContextRef.Current.Browser.MainFrame;
+
+ if (TempFrame <> nil) and TempFrame.IsValid then
+ TempFrame.SendProcessMessage(PID_BROWSER, TempMessage);
+ finally
+ TempMessage := nil;
+ end;
+end;
+
+
+end.