diff --git a/demos/DOMVisitor/DOMVisitor.dproj b/demos/DOMVisitor/DOMVisitor.dproj
index 2d4e48bb..5dc06c54 100644
--- a/demos/DOMVisitor/DOMVisitor.dproj
+++ b/demos/DOMVisitor/DOMVisitor.dproj
@@ -107,7 +107,6 @@
- dfm
Cfg_2
diff --git a/demos/DOMVisitor/uDOMVisitor.dfm b/demos/DOMVisitor/uDOMVisitor.dfm
index dcf2bafc..7d5a4f9c 100644
--- a/demos/DOMVisitor/uDOMVisitor.dfm
+++ b/demos/DOMVisitor/uDOMVisitor.dfm
@@ -67,8 +67,6 @@ object DOMVisitorFrm: TDOMVisitorFrm
Caption = 'Go'
TabOrder = 0
OnClick = GoBtnClick
- ExplicitLeft = 98
- ExplicitTop = 5
end
object VisitDOMBtn: TButton
Left = 39
@@ -79,7 +77,6 @@ object DOMVisitorFrm: TDOMVisitorFrm
Caption = 'Visit DOM'
TabOrder = 1
OnClick = VisitDOMBtnClick
- ExplicitLeft = 42
end
end
end
diff --git a/demos/DOMVisitor/uDOMVisitor.pas b/demos/DOMVisitor/uDOMVisitor.pas
index 2c2c2d8a..0c8cc09a 100644
--- a/demos/DOMVisitor/uDOMVisitor.pas
+++ b/demos/DOMVisitor/uDOMVisitor.pas
@@ -160,7 +160,7 @@ end;
procedure SimpleNodeSearch(const aDocument: ICefDomDocument);
const
- NODE_ID = 'lst-ib'; // node found in google.com homepage
+ NODE_ID = 'lst-ib'; // input box node found in google.com homepage
var
TempNode : ICefDomNode;
begin
@@ -170,12 +170,18 @@ begin
TempNode := aDocument.GetElementById(NODE_ID);
if (TempNode <> nil) then
- CefLog('CEF4Delphi', 1, CEF_LOG_SEVERITY_ERROR, NODE_ID + ' element name : ' + TempNode.Name);
+ begin
+ CefLog('CEF4Delphi', 1, CEF_LOG_SEVERITY_ERROR, NODE_ID + ' element name : ' + TempNode.Name);
+ CefLog('CEF4Delphi', 1, CEF_LOG_SEVERITY_ERROR, NODE_ID + ' element value : ' + TempNode.GetValue);
+ end;
TempNode := aDocument.GetFocusedNode;
if (TempNode <> nil) then
- CefLog('CEF4Delphi', 1, CEF_LOG_SEVERITY_ERROR, 'Focused element name : ' + TempNode.Name);
+ begin
+ CefLog('CEF4Delphi', 1, CEF_LOG_SEVERITY_ERROR, 'Focused element name : ' + TempNode.Name);
+ CefLog('CEF4Delphi', 1, CEF_LOG_SEVERITY_ERROR, 'Focused element inner text : ' + TempNode.ElementInnerText);
+ end;
end;
except
on e : exception do
diff --git a/demos/FMXExternalPumpBrowser/00-DeleteDCUs.bat b/demos/FMXExternalPumpBrowser/00-DeleteDCUs.bat
new file mode 100644
index 00000000..dbd008bc
--- /dev/null
+++ b/demos/FMXExternalPumpBrowser/00-DeleteDCUs.bat
@@ -0,0 +1,14 @@
+del /s /q *.dcu
+del /s /q *.exe
+del /s /q *.res
+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 __history
+rmdir __recovery
diff --git a/demos/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dpr b/demos/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dpr
new file mode 100644
index 00000000..7d81bf17
--- /dev/null
+++ b/demos/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dpr
@@ -0,0 +1,92 @@
+// ************************************************************************
+// ***************************** 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 © 2018 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 FMXExternalPumpBrowser;
+
+uses
+ {$IFDEF DELPHI17_UP}
+ System.StartUpCopy,
+ {$ENDIF}
+ FMX.Forms,
+ {$IFDEF MSWINDOWS}
+ WinApi.Windows,
+ {$ENDIF}
+ System.SysUtils,
+ uCEFApplication,
+ uFMXWorkScheduler,
+ uFMXExternalPumpBrowser in 'uFMXExternalPumpBrowser.pas' {FMXExternalPumpBrowserFrm},
+ uFMXApplicationService in 'uFMXApplicationService.pas';
+
+{$R *.res}
+
+{$IFDEF MSWINDOWS}
+// 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}
+{$ENDIF}
+
+begin
+ // TCEFWorkScheduler will call cef_do_message_loop_work when
+ // it's told in the GlobalCEFApp.OnScheduleMessagePumpWork event.
+ // GlobalCEFWorkScheduler needs to be created before the
+ // GlobalCEFApp.StartMainProcess call.
+ GlobalCEFWorkScheduler := TFMXWorkScheduler.Create(nil);
+
+ GlobalCEFApp := TCefApplication.Create;
+ GlobalCEFApp.WindowlessRenderingEnabled := True;
+ GlobalCEFApp.EnableHighDPISupport := True;
+ GlobalCEFApp.FastUnload := True;
+ GlobalCEFApp.FlashEnabled := False;
+ GlobalCEFApp.ExternalMessagePump := True;
+ GlobalCEFApp.MultiThreadedMessageLoop := False;
+ GlobalCEFApp.SitePerProcess := False;
+ GlobalCEFApp.OnScheduleMessagePumpWork := GlobalCEFApp_OnScheduleMessagePumpWork;
+
+ if GlobalCEFApp.StartMainProcess then
+ begin
+ Application.Initialize;
+ Application.CreateForm(TFMXExternalPumpBrowserFrm, FMXExternalPumpBrowserFrm);
+ Application.Run;
+
+ // The form needs to be destroyed *BEFORE* stopping the scheduler.
+ FMXExternalPumpBrowserFrm.Free;
+
+ GlobalCEFWorkScheduler.StopScheduler;
+ end;
+
+ FreeAndNil(GlobalCEFApp);
+ FreeAndNil(GlobalCEFWorkScheduler);
+end.
diff --git a/demos/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dproj b/demos/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dproj
new file mode 100644
index 00000000..6faa38e6
--- /dev/null
+++ b/demos/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dproj
@@ -0,0 +1,617 @@
+
+
+ {BE24D13B-2634-4064-8746-AB331419C5FA}
+ 18.2
+ FMX
+ FMXExternalPumpBrowser.dpr
+ True
+ Debug
+ Win32
+ 1
+ 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
+
+
+ .\$(Platform)\$(Config)
+ ..\..\bin
+ false
+ false
+ false
+ false
+ false
+ RESTComponents;emsclientfiredac;FireDAC;FireDACSqliteDriver;soaprtl;FireDACIBDriver;soapmidas;FireDACCommon;emsclient;RESTBackendComponents;soapserver;FireDACCommonDriver;CloudService;inet;$(DCC_UsePackage)
+ System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)
+ $(BDS)\bin\delphi_PROJECTICON.ico
+ $(BDS)\bin\delphi_PROJECTICNS.icns
+ FMXExternalPumpBrowser
+ 3082
+ CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
+
+
+ DBXSqliteDriver;bindcompdbx;fmxase;DBXDb2Driver;DBXInterBaseDriver;vcl;DBXSybaseASEDriver;vclactnband;vclFireDAC;FireDACDb2Driver;DataSnapFireDAC;svnui;tethering;dsnapcon;FireDACADSDriver;FireDACMSAccDriver;fmxFireDAC;DBXMSSQLDriver;vclimg;FireDACInfxDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;Componentes_UI;vcldb;bindcompfmx;svn;FireDACPgDriver;DBXOracleDriver;inetdb;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;CEF4Delphi;DbxCommonDriver;IndyProtocols240;IndySystem240;fmx;DataSnapServer;xmlrtl;DataSnapNativeClient;fmxobj;fmxdae;vclwinx;rtl;FireDACDSDriver;DbxClientDriver;IndyCore240;DBXSybaseASADriver;CustomIPTransport;vcldsnap;dbexpress;FireDACDBXDriver;vclx;bindcomp;appanalytics;dsnap;DataSnapCommon;DBXInformixDriver;bindcompvcl;DataSnapConnectors;VCLRESTComponents;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;dsnapxml;FireDACMySQLDriver;dbrtl;inetdbxpress;DBXFirebirdDriver;DataSnapProviderClient;FireDACMongoDBDriver;FireDACCommonODBC;DataSnapClient;DataSnapServerMidas;$(DCC_UsePackage)
+ Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(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
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
+
+
+ DBXSqliteDriver;bindcompdbx;fmxase;DBXDb2Driver;DBXInterBaseDriver;vcl;DBXSybaseASEDriver;vclactnband;vclFireDAC;FireDACDb2Driver;DataSnapFireDAC;tethering;dsnapcon;FireDACADSDriver;FireDACMSAccDriver;fmxFireDAC;DBXMSSQLDriver;vclimg;FireDACInfxDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;FireDACPgDriver;DBXOracleDriver;inetdb;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;DbxCommonDriver;IndyProtocols240;IndySystem240;fmx;DataSnapServer;xmlrtl;DataSnapNativeClient;fmxobj;fmxdae;vclwinx;rtl;FireDACDSDriver;DbxClientDriver;IndyCore240;DBXSybaseASADriver;CustomIPTransport;vcldsnap;dbexpress;FireDACDBXDriver;vclx;bindcomp;appanalytics;dsnap;DataSnapCommon;DBXInformixDriver;bindcompvcl;DataSnapConnectors;VCLRESTComponents;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;dsnapxml;FireDACMySQLDriver;dbrtl;inetdbxpress;DBXFirebirdDriver;DataSnapProviderClient;FireDACMongoDBDriver;FireDACCommonODBC;DataSnapClient;DataSnapServerMidas;$(DCC_UsePackage)
+ 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
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
+
+
+ DEBUG;$(DCC_Define)
+ true
+ false
+ true
+ true
+ true
+
+
+ false
+ true
+ true
+ 1033
+
+
+ true
+ true
+
+
+ false
+ RELEASE;$(DCC_Define)
+ 0
+ 0
+
+
+ true
+ true
+
+
+ true
+ true
+
+
+
+ MainSource
+
+
+
+
+
+
+ Cfg_2
+ Base
+
+
+ Base
+
+
+ Cfg_1
+ Base
+
+
+
+ Delphi.Personality.12
+ Application
+
+
+
+ FMXExternalPumpBrowser.dpr
+
+
+ IP Abstraction Indy Implementation Design Time
+ Microsoft Office 2000 Sample Automation Server Wrapper Components
+ Microsoft Office XP Sample Automation Server Wrapper Components
+
+
+
+
+
+ true
+
+
+
+
+ true
+
+
+
+
+ true
+
+
+
+
+ true
+
+
+
+
+ FMXExternalPumpBrowser.exe
+ true
+
+
+
+
+ 1
+
+
+ Contents\MacOS
+ 1
+
+
+ Contents\MacOS
+ 0
+
+
+
+
+ classes
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ library\lib\armeabi
+ 1
+
+
+
+
+ library\lib\mips
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\values
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+
+
+ res\drawable-ldpi
+ 1
+
+
+
+
+ res\drawable-mdpi
+ 1
+
+
+
+
+ res\drawable-hdpi
+ 1
+
+
+
+
+ res\drawable-xhdpi
+ 1
+
+
+
+
+ res\drawable-small
+ 1
+
+
+
+
+ res\drawable-normal
+ 1
+
+
+
+
+ res\drawable-large
+ 1
+
+
+
+
+ res\drawable-xlarge
+ 1
+
+
+
+
+ 1
+
+
+ Contents\MacOS
+ 1
+
+
+ 0
+
+
+
+
+ Contents\MacOS
+ 1
+ .framework
+
+
+ 0
+
+
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ 0
+ .dll;.bpl
+
+
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ 0
+ .bpl
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ Contents\Resources\StartUp\
+ 0
+
+
+ 0
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ ..\
+ 1
+
+
+ ..\
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ ..\
+ 1
+
+
+
+
+ Contents
+ 1
+
+
+
+
+ Contents\Resources
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ Contents\MacOS
+ 1
+
+
+ 0
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ False
+
+
+ 12
+
+
+
+
+
diff --git a/demos/FMXExternalPumpBrowser/cef.inc b/demos/FMXExternalPumpBrowser/cef.inc
new file mode 100644
index 00000000..984ae795
--- /dev/null
+++ b/demos/FMXExternalPumpBrowser/cef.inc
@@ -0,0 +1,384 @@
+// ************************************************************************
+// ***************************** 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.
+ *
+ *)
+
+ // The complete list of compiler versions is here :
+ // http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Compiler_Versions
+
+{$DEFINE DELPHI_VERSION_UNKNOW}
+
+{$IFDEF FPC}
+ {$DEFINE CEF_MULTI_THREADED_MESSAGE_LOOP}
+ {$DEFINE SUPPORTS_INLINE}
+{$ENDIF}
+
+// 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
+{$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}
+
+
+{$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}
+{$ENDIF}
+
+{$IFDEF DELPHI9_UP}
+ {$DEFINE SUPPORTS_INLINE}
+{$ENDIF}
+
diff --git a/demos/FMXExternalPumpBrowser/uFMXApplicationService.pas b/demos/FMXExternalPumpBrowser/uFMXApplicationService.pas
new file mode 100644
index 00000000..9d3bfe03
--- /dev/null
+++ b/demos/FMXExternalPumpBrowser/uFMXApplicationService.pas
@@ -0,0 +1,204 @@
+// ************************************************************************
+// ***************************** 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 © 2018 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.
+ *
+ *)
+
+unit uFMXApplicationService;
+
+{$I cef.inc}
+
+// This unit is based in the TFMXApplicationService class created by Takashi Yamamoto
+// https://www.gesource.jp/weblog/?p=7367
+
+interface
+
+uses
+ FMX.Platform;
+
+type
+ TFMXApplicationService = class(TInterfacedObject, IFMXApplicationService)
+ protected
+ class var OldFMXApplicationService: IFMXApplicationService;
+ class var NewFMXApplicationService: IFMXApplicationService;
+
+ public
+ procedure Run;
+ function HandleMessage: Boolean;
+ procedure WaitMessage;
+ function GetDefaultTitle: string;
+ function GetTitle: string;
+ procedure SetTitle(const Value: string);
+ function GetVersionString: string;
+ procedure Terminate;
+ function Terminating: Boolean;
+ function Running: Boolean;
+
+ class procedure AddPlatformService;
+
+ property DefaultTitle : string read GetDefaultTitle;
+ property Title : string read GetTitle write SetTitle;
+ property AppVersion : string read GetVersionString;
+ end;
+
+implementation
+
+uses
+ FMX.Forms,
+ uFMXExternalPumpBrowser,
+ {$IFDEF MSWINDOWS}
+ Winapi.Messages, Winapi.Windows,
+ {$ENDIF}
+ uCEFConstants;
+
+class procedure TFMXApplicationService.AddPlatformService;
+begin
+ if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationService, IInterface(OldFMXApplicationService)) then
+ begin
+ TPlatformServices.Current.RemovePlatformService(IFMXApplicationService);
+
+ NewFMXApplicationService := TFMXApplicationService.Create;
+ TPlatformServices.Current.AddPlatformService(IFMXApplicationService, NewFMXApplicationService);
+ end;
+end;
+
+function TFMXApplicationService.GetDefaultTitle: string;
+begin
+ Result := OldFMXApplicationService.GetDefaultTitle;
+end;
+
+function TFMXApplicationService.GetTitle: string;
+begin
+ Result := OldFMXApplicationService.GetTitle;
+end;
+
+function TFMXApplicationService.GetVersionString: string;
+begin
+ Result := OldFMXApplicationService.GetVersionString;
+end;
+
+procedure TFMXApplicationService.Run;
+begin
+ OldFMXApplicationService.Run;
+end;
+
+procedure TFMXApplicationService.SetTitle(const Value: string);
+begin
+ OldFMXApplicationService.SetTitle(Value);
+end;
+
+procedure TFMXApplicationService.Terminate;
+begin
+ OldFMXApplicationService.Terminate;
+end;
+
+function TFMXApplicationService.Terminating: Boolean;
+begin
+ Result := OldFMXApplicationService.Terminating;
+end;
+
+procedure TFMXApplicationService.WaitMessage;
+begin
+ OldFMXApplicationService.WaitMessage;
+end;
+
+function TFMXApplicationService.Running: Boolean;
+begin
+ Result := OldFMXApplicationService.Running;
+end;
+
+function TFMXApplicationService.HandleMessage: Boolean;
+{$IFDEF MSWINDOWS}
+var
+ TempMsg : TMsg;
+{$ENDIF}
+begin
+ {$IFDEF MSWINDOWS}
+ if PeekMessage(TempMsg, 0, 0, 0, PM_NOREMOVE) then
+ case TempMsg.Message of
+ WM_MOVE,
+ WM_MOVING :
+ if not(Application.Terminated) and
+ (Application.MainForm <> nil) and
+ (Application.MainForm is TFMXExternalPumpBrowserFrm) then
+ TFMXExternalPumpBrowserFrm(Application.MainForm).NotifyMoveOrResizeStarted;
+
+ WM_CAPTURECHANGED,
+ WM_CANCELMODE :
+ if not(Application.Terminated) and
+ (Application.MainForm <> nil) and
+ (Application.MainForm is TFMXExternalPumpBrowserFrm) then
+ TFMXExternalPumpBrowserFrm(Application.MainForm).SendCaptureLostEvent;
+
+ WM_SYSCHAR :
+ if not(Application.Terminated) and
+ (Application.MainForm <> nil) and
+ (Application.MainForm is TFMXExternalPumpBrowserFrm) then
+ TFMXExternalPumpBrowserFrm(Application.MainForm).HandleSYSCHAR(TempMsg);
+
+ WM_SYSKEYDOWN :
+ if not(Application.Terminated) and
+ (Application.MainForm <> nil) and
+ (Application.MainForm is TFMXExternalPumpBrowserFrm) then
+ TFMXExternalPumpBrowserFrm(Application.MainForm).HandleSYSKEYDOWN(TempMsg);
+
+ WM_SYSKEYUP :
+ if not(Application.Terminated) and
+ (Application.MainForm <> nil) and
+ (Application.MainForm is TFMXExternalPumpBrowserFrm) then
+ TFMXExternalPumpBrowserFrm(Application.MainForm).HandleSYSKEYUP(TempMsg);
+
+ CEF_AFTERCREATED :
+ if not(Application.Terminated) and
+ (Application.MainForm <> nil) and
+ (Application.MainForm is TFMXExternalPumpBrowserFrm) then
+ TFMXExternalPumpBrowserFrm(Application.MainForm).DoBrowserCreated;
+
+ CEF_PENDINGRESIZE :
+ if not(Application.Terminated) and
+ (Application.MainForm <> nil) and
+ (Application.MainForm is TFMXExternalPumpBrowserFrm) then
+ TFMXExternalPumpBrowserFrm(Application.MainForm).DoResize;
+
+ CEF_PUMPHAVEWORK :
+ if not(Application.Terminated) and
+ (GlobalCEFWorkScheduler <> nil) then
+ GlobalCEFWorkScheduler.ScheduleWork(TempMsg.lParam);
+ end;
+ {$ENDIF}
+
+ Result := OldFMXApplicationService.HandleMessage;
+end;
+
+end.
diff --git a/demos/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.fmx b/demos/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.fmx
new file mode 100644
index 00000000..f50fb395
--- /dev/null
+++ b/demos/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.fmx
@@ -0,0 +1,91 @@
+object FMXExternalPumpBrowserFrm: TFMXExternalPumpBrowserFrm
+ Left = 0
+ Top = 0
+ Caption = 'Initializing browser. Please wait...'
+ ClientHeight = 534
+ ClientWidth = 800
+ Position = ScreenCenter
+ FormFactor.Width = 320
+ FormFactor.Height = 480
+ FormFactor.Devices = [Desktop]
+ OnCreate = FormCreate
+ OnCloseQuery = FormCloseQuery
+ OnDestroy = FormDestroy
+ OnShow = FormShow
+ OnHide = FormHide
+ DesignerMasterStyle = 0
+ object AddressPnl: TPanel
+ Align = Top
+ Padding.Left = 5.000000000000000000
+ Padding.Top = 5.000000000000000000
+ Padding.Right = 5.000000000000000000
+ Padding.Bottom = 5.000000000000000000
+ Size.Width = 800.000000000000000000
+ Size.Height = 33.000000000000000000
+ Size.PlatformDefault = False
+ TabOrder = 1
+ object GoBtn: TButton
+ Align = Right
+ Position.X = 759.000000000000000000
+ Position.Y = 5.000000000000000000
+ Size.Width = 36.000000000000000000
+ Size.Height = 23.000000000000000000
+ Size.PlatformDefault = False
+ TabOrder = 1
+ Text = 'Go'
+ OnClick = GoBtnClick
+ OnEnter = GoBtnEnter
+ end
+ object AddressEdt: TEdit
+ Touch.InteractiveGestures = [LongTap, DoubleTap]
+ Align = Client
+ TabOrder = 0
+ Text = 'https://www.google.com'
+ Size.Width = 754.000000000000000000
+ Size.Height = 23.000000000000000000
+ Size.PlatformDefault = False
+ OnEnter = AddressEdtEnter
+ end
+ end
+ object Panel1: TFMXBufferPanel
+ Align = Client
+ TabOrder = 0
+ Color = claTomato
+ CanFocus = True
+ Size.Width = 800.000000000000000000
+ Size.Height = 501.000000000000000000
+ Size.PlatformDefault = False
+ OnEnter = Panel1Enter
+ OnExit = Panel1Exit
+ OnResize = Panel1Resize
+ OnClick = Panel1Click
+ OnMouseDown = Panel1MouseDown
+ OnMouseMove = Panel1MouseMove
+ OnMouseUp = Panel1MouseUp
+ OnMouseLeave = Panel1MouseLeave
+ OnMouseWheel = Panel1MouseWheel
+ OnKeyUp = Panel1KeyUp
+ OnKeyDown = Panel1KeyDown
+ end
+ object Timer1: TTimer
+ Enabled = False
+ Interval = 300
+ OnTimer = Timer1Timer
+ Left = 384
+ Top = 313
+ end
+ object chrmosr: TFMXChromium
+ OnAfterCreated = chrmosrAfterCreated
+ OnBeforeClose = chrmosrBeforeClose
+ OnClose = chrmosrClose
+ OnGetViewRect = chrmosrGetViewRect
+ OnGetScreenPoint = chrmosrGetScreenPoint
+ OnGetScreenInfo = chrmosrGetScreenInfo
+ OnPopupShow = chrmosrPopupShow
+ OnPopupSize = chrmosrPopupSize
+ OnPaint = chrmosrPaint
+ OnCursorChange = chrmosrCursorChange
+ Left = 272
+ Top = 313
+ end
+end
diff --git a/demos/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.pas b/demos/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.pas
new file mode 100644
index 00000000..5f2e2446
--- /dev/null
+++ b/demos/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.pas
@@ -0,0 +1,806 @@
+// ************************************************************************
+// ***************************** 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 © 2018 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.
+ *
+ *)
+
+unit uFMXExternalPumpBrowser;
+
+{$I cef.inc}
+
+interface
+
+uses
+ {$IFDEF MSWINDOWS}
+ Winapi.Messages, Winapi.Windows,
+ {$ENDIF}
+ System.Types, System.UITypes, System.Classes, System.SyncObjs,
+ FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs,
+ FMX.Edit, FMX.StdCtrls, FMX.Controls.Presentation,
+ {$IFDEF DELPHI17_UP}
+ FMX.Graphics,
+ {$ENDIF}
+ uFMXChromium, uFMXBufferPanel, uFMXWorkScheduler,
+ uCEFInterfaces, uCEFTypes, uCEFConstants;
+
+type
+ TFMXExternalPumpBrowserFrm = class(TForm)
+ AddressPnl: TPanel;
+ AddressEdt: TEdit;
+ GoBtn: TButton;
+ Panel1: TFMXBufferPanel;
+ chrmosr: TFMXChromium;
+ Timer1: TTimer;
+
+ procedure GoBtnClick(Sender: TObject);
+ procedure GoBtnEnter(Sender: TObject);
+
+ procedure Panel1Enter(Sender: TObject);
+ procedure Panel1Exit(Sender: TObject);
+ procedure Panel1Resize(Sender: TObject);
+ procedure Panel1Click(Sender: TObject);
+ procedure Panel1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
+ procedure Panel1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
+ procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single);
+ procedure Panel1MouseLeave(Sender: TObject);
+ procedure Panel1MouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; var Handled: Boolean);
+ procedure Panel1KeyUp(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
+ procedure Panel1KeyDown(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
+
+ procedure FormCreate(Sender: TObject);
+ procedure FormDestroy(Sender: TObject);
+ procedure FormShow(Sender: TObject);
+ procedure FormHide(Sender: TObject);
+ procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
+
+ procedure chrmosrPaint(Sender: TObject; const browser: ICefBrowser; kind: TCefPaintElementType; dirtyRectsCount: NativeUInt; const dirtyRects: PCefRectArray; const buffer: Pointer; width, height: Integer);
+ procedure chrmosrCursorChange(Sender: TObject; const browser: ICefBrowser; cursor: HICON; cursorType: TCefCursorType; const customCursorInfo: PCefCursorInfo);
+ procedure chrmosrGetViewRect(Sender: TObject; const browser: ICefBrowser; var rect: TCefRect; out Result: Boolean);
+ procedure chrmosrGetScreenPoint(Sender: TObject; const browser: ICefBrowser; viewX, viewY: Integer; var screenX, screenY: Integer; out Result: Boolean);
+ procedure chrmosrGetScreenInfo(Sender: TObject; const browser: ICefBrowser; var screenInfo: TCefScreenInfo; out Result: Boolean);
+ procedure chrmosrPopupShow(Sender: TObject; const browser: ICefBrowser; show: Boolean);
+ procedure chrmosrPopupSize(Sender: TObject; const browser: ICefBrowser; const rect: PCefRect);
+ procedure chrmosrAfterCreated(Sender: TObject; const browser: ICefBrowser);
+ procedure chrmosrClose(Sender: TObject; const browser: ICefBrowser; out Result: Boolean);
+ procedure chrmosrBeforeClose(Sender: TObject; const browser: ICefBrowser);
+
+ procedure Timer1Timer(Sender: TObject);
+ procedure AddressEdtEnter(Sender: TObject);
+
+ protected
+ FPopUpBitmap : TBitmap;
+ FPopUpRect : TRect;
+ FShowPopUp : boolean;
+ FResizing : boolean;
+ FPendingResize : boolean;
+ FCanClose : boolean;
+ FClosing : boolean;
+ FResizeCS : TCriticalSection;
+ {$IFDEF DELPHI17_UP}
+ FMouseWheelService : IFMXMouseService;
+ {$ENDIF}
+
+ procedure LoadURL;
+ function getModifiers(Shift: TShiftState): TCefEventFlags;
+ function GetButton(Button: TMouseButton): TCefMouseButtonType;
+ function SendCompMessage(aMsg : cardinal; wParam : cardinal = 0; lParam : integer = 0) : boolean;
+
+ public
+ procedure DoResize;
+ procedure DoBrowserCreated;
+ procedure NotifyMoveOrResizeStarted;
+ procedure SendCaptureLostEvent;
+ procedure HandleSYSCHAR(const aMessage : TMsg);
+ procedure HandleSYSKEYDOWN(const aMessage : TMsg);
+ procedure HandleSYSKEYUP(const aMessage : TMsg);
+ end;
+
+var
+ FMXExternalPumpBrowserFrm : TFMXExternalPumpBrowserFrm;
+ GlobalCEFWorkScheduler : TFMXWorkScheduler = nil;
+
+// This is a simple browser using FireMonkey components in OSR mode (off-screen rendering)
+// and a external message pump.
+
+// It's recomemded to understand the code in the SimpleOSRBrowser and OSRExternalPumpBrowser demos before
+// reading the code in this demo.
+
+// Due to the Firemonkey code structure, this demo uses a IFMXApplicationService interface implemented in
+// uFMXApplicationService.pas to intercept some windows messages needed to make a CEF browser work.
+
+// The TFMXApplicationService.HandleMessages function receives many of the messages that the
+// OSRExternalPumpBrowser demo hadled in the main form or in the GlobalCEFWorkScheduler.
+
+// It was necessary to destroy the browser following the destruction sequence described in
+// the MDIBrowser demo but in OSR mode there are some modifications.
+
+// This is the destruction sequence in OSR mode :
+// 1- FormCloseQuery sets CanClose to the initial FCanClose value (False) and calls chrmosr.CloseBrowser(True).
+// 2- chrmosr.CloseBrowser(True) will trigger chrmosr.OnClose and we have to
+// set "Result" to false and CEF3 will destroy the internal browser immediately.
+// 3- chrmosr.OnBeforeClose is triggered because the internal browser was destroyed.
+// Now we set FCanClose to True and send WM_CLOSE to the form.
+
+procedure GlobalCEFApp_OnScheduleMessagePumpWork(const aDelayMS : int64);
+
+implementation
+
+{$R *.fmx}
+
+uses
+ System.SysUtils, System.Math, FMX.Platform, FMX.Platform.Win,
+ uCEFMiscFunctions, uCEFApplication, uFMXApplicationService;
+
+procedure GlobalCEFApp_OnScheduleMessagePumpWork(const aDelayMS : int64);
+begin
+ if (GlobalCEFWorkScheduler <> nil) then GlobalCEFWorkScheduler.ScheduleMessagePumpWork(aDelayMS);
+end;
+
+procedure TFMXExternalPumpBrowserFrm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
+begin
+ CanClose := FCanClose;
+
+ if not(FClosing) then
+ begin
+ FClosing := True;
+ Visible := False;
+ AddressPnl.Enabled := False;
+ chrmosr.CloseBrowser(True);
+ end;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.FormCreate(Sender: TObject);
+begin
+ TFMXApplicationService.AddPlatformService;
+
+ FPopUpBitmap := nil;
+ FPopUpRect := rect(0, 0, 0, 0);
+ FShowPopUp := False;
+ FResizing := False;
+ FPendingResize := False;
+ FCanClose := False;
+ FClosing := False;
+ FResizeCS := TCriticalSection.Create;
+
+ {$IFDEF DELPHI17_UP}
+ if TPlatformServices.Current.SupportsPlatformService(IFMXMouseService) then
+ FMouseWheelService := TPlatformServices.Current.GetPlatformService(IFMXMouseService) as IFMXMouseService;
+ {$ENDIF}
+end;
+
+procedure TFMXExternalPumpBrowserFrm.FormDestroy(Sender: TObject);
+begin
+ if (FPopUpBitmap <> nil) then FreeAndNil(FPopUpBitmap);
+end;
+
+procedure TFMXExternalPumpBrowserFrm.FormHide(Sender: TObject);
+begin
+ chrmosr.SendFocusEvent(False);
+ chrmosr.WasHidden(True);
+end;
+
+procedure TFMXExternalPumpBrowserFrm.FormShow(Sender: TObject);
+begin
+ if chrmosr.Initialized then
+ begin
+ chrmosr.WasHidden(False);
+ chrmosr.SendFocusEvent(True);
+ end
+ else
+ begin
+ // opaque white background color
+ chrmosr.Options.BackgroundColor := CefColorSetARGB($FF, $FF, $FF, $FF);
+
+ if not(chrmosr.CreateBrowser) then Timer1.Enabled := True;
+ end;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.GoBtnClick(Sender: TObject);
+begin
+ LoadURL;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.LoadURL;
+begin
+ FResizeCS.Acquire;
+ FResizing := False;
+ FPendingResize := False;
+ FResizeCS.Release;
+
+ chrmosr.LoadURL(AddressEdt.Text);
+end;
+
+procedure TFMXExternalPumpBrowserFrm.GoBtnEnter(Sender: TObject);
+begin
+ chrmosr.SendFocusEvent(False);
+end;
+
+procedure TFMXExternalPumpBrowserFrm.Panel1Click(Sender: TObject);
+begin
+ Panel1.SetFocus;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.Panel1Enter(Sender: TObject);
+begin
+ chrmosr.SendFocusEvent(True);
+end;
+
+procedure TFMXExternalPumpBrowserFrm.Panel1Exit(Sender: TObject);
+begin
+ chrmosr.SendFocusEvent(False);
+end;
+
+procedure TFMXExternalPumpBrowserFrm.Panel1KeyDown(Sender : TObject;
+ var Key : Word;
+ var KeyChar : Char;
+ Shift : TShiftState);
+var
+ TempKeyEvent : TCefKeyEvent;
+begin
+ if not(Panel1.IsFocused) or (chrmosr = nil) then exit;
+
+ if (Key in [VK_BACK..VK_HELP]) and (KeyChar = #0) then
+ begin
+ TempKeyEvent.kind := KEYEVENT_RAWKEYDOWN;
+ TempKeyEvent.modifiers := getModifiers(Shift);
+ TempKeyEvent.windows_key_code := Key;
+ TempKeyEvent.native_key_code := 0;
+ TempKeyEvent.is_system_key := ord(False);
+ TempKeyEvent.character := #0;
+ TempKeyEvent.unmodified_character := #0;
+ TempKeyEvent.focus_on_editable_field := ord(False);
+
+ chrmosr.SendKeyEvent(@TempKeyEvent);
+ end;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.Panel1KeyUp(Sender : TObject;
+ var Key : Word;
+ var KeyChar : Char;
+ Shift : TShiftState);
+var
+ TempKeyEvent : TCefKeyEvent;
+begin
+ if not(Panel1.IsFocused) or (chrmosr = nil) then exit;
+
+ if (Key = 0) and (KeyChar <> #0) then
+ begin
+ TempKeyEvent.kind := KEYEVENT_CHAR;
+ TempKeyEvent.modifiers := getModifiers(Shift);
+ TempKeyEvent.windows_key_code := ord(KeyChar);
+ TempKeyEvent.native_key_code := 0;
+ TempKeyEvent.is_system_key := ord(False);
+ TempKeyEvent.character := #0;
+ TempKeyEvent.unmodified_character := #0;
+ TempKeyEvent.focus_on_editable_field := ord(False);
+
+ chrmosr.SendKeyEvent(@TempKeyEvent);
+ end
+ else
+ if (Key in [VK_BACK..VK_HELP]) and (KeyChar = #0) then
+ begin
+ TempKeyEvent.kind := KEYEVENT_KEYUP;
+ TempKeyEvent.modifiers := getModifiers(Shift);
+ TempKeyEvent.windows_key_code := Key;
+ TempKeyEvent.native_key_code := 0;
+ TempKeyEvent.is_system_key := ord(False);
+ TempKeyEvent.character := #0;
+ TempKeyEvent.unmodified_character := #0;
+ TempKeyEvent.focus_on_editable_field := ord(False);
+
+ chrmosr.SendKeyEvent(@TempKeyEvent);
+ end;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.Panel1MouseDown(Sender : TObject;
+ Button : TMouseButton;
+ Shift : TShiftState;
+ X, Y : Single);
+var
+ TempEvent : TCefMouseEvent;
+begin
+ if (GlobalCEFApp <> nil) and (chrmosr <> nil) then
+ begin
+ Panel1.SetFocus;
+
+ TempEvent.x := round(X);
+ TempEvent.y := round(Y);
+ TempEvent.modifiers := getModifiers(Shift);
+ chrmosr.SendMouseClickEvent(@TempEvent, GetButton(Button), False, 1);
+ end;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.Panel1MouseLeave(Sender: TObject);
+var
+ TempEvent : TCefMouseEvent;
+ TempPoint : TPoint;
+begin
+ if (GlobalCEFApp <> nil) and (chrmosr <> nil) then
+ begin
+ GetCursorPos(TempPoint);
+ TempPoint := Panel1.ScreenToclient(TempPoint);
+ TempEvent.x := TempPoint.x;
+ TempEvent.y := TempPoint.y;
+ TempEvent.modifiers := GetCefMouseModifiers;
+ chrmosr.SendMouseMoveEvent(@TempEvent, True);
+ end;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.Panel1MouseMove(Sender : TObject;
+ Shift : TShiftState;
+ X, Y : Single);
+var
+ TempEvent : TCefMouseEvent;
+begin
+ if (GlobalCEFApp <> nil) and (chrmosr <> nil) then
+ begin
+ TempEvent.x := round(X);
+ TempEvent.y := round(Y);
+ TempEvent.modifiers := getModifiers(Shift);
+ chrmosr.SendMouseMoveEvent(@TempEvent, False);
+ end;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.Panel1MouseUp(Sender : TObject;
+ Button : TMouseButton;
+ Shift : TShiftState;
+ X, Y : Single);
+var
+ TempEvent : TCefMouseEvent;
+begin
+ if (GlobalCEFApp <> nil) and (chrmosr <> nil) then
+ begin
+ TempEvent.x := round(X);
+ TempEvent.y := round(Y);
+ TempEvent.modifiers := getModifiers(Shift);
+ chrmosr.SendMouseClickEvent(@TempEvent, GetButton(Button), True, 1);
+ end;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.Panel1MouseWheel(Sender : TObject;
+ Shift : TShiftState;
+ WheelDelta : Integer;
+ var Handled : Boolean);
+var
+ TempEvent : TCefMouseEvent;
+ TempPointF : TPointF;
+begin
+ if Panel1.IsFocused and (GlobalCEFApp <> nil) and (chrmosr <> nil) then
+ begin
+ {$IFDEF DELPHI17_UP}
+ if (FMouseWheelService <> nil) then
+ TempPointF := FMouseWheelService.GetMousePos
+ else
+ exit;
+ {$ELSE}
+ TempPointF := Platform.GetMousePos;
+ {$ENDIF}
+
+ TempEvent.x := round(TempPointF.x);
+ TempEvent.y := round(TempPointF.y);
+ TempEvent.modifiers := getModifiers(Shift);
+ chrmosr.SendMouseWheelEvent(@TempEvent, 0, WheelDelta);
+ end;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.Panel1Resize(Sender: TObject);
+begin
+ DoResize;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.Timer1Timer(Sender: TObject);
+begin
+ Timer1.Enabled := False;
+
+ if not(chrmosr.CreateBrowser) and not(chrmosr.Initialized) then Timer1.Enabled := True;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.AddressEdtEnter(Sender: TObject);
+begin
+ chrmosr.SendFocusEvent(False);
+end;
+
+procedure TFMXExternalPumpBrowserFrm.chrmosrAfterCreated(Sender: TObject; const browser: ICefBrowser);
+begin
+ SendCompMessage(CEF_AFTERCREATED);
+end;
+
+procedure TFMXExternalPumpBrowserFrm.chrmosrBeforeClose(Sender: TObject; const browser: ICefBrowser);
+begin
+ FCanClose := True;
+ SendCompMessage(WM_CLOSE);
+end;
+
+procedure TFMXExternalPumpBrowserFrm.chrmosrClose(Sender: TObject; const browser: ICefBrowser; out Result: Boolean);
+begin
+ Result := False;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.chrmosrCursorChange(Sender : TObject;
+ const browser : ICefBrowser;
+ cursor : HICON;
+ cursorType : TCefCursorType;
+ const customCursorInfo : PCefCursorInfo);
+begin
+ Panel1.Cursor := GefCursorToWindowsCursor(cursorType);
+end;
+
+procedure TFMXExternalPumpBrowserFrm.chrmosrGetScreenInfo(Sender : TObject;
+ const browser : ICefBrowser;
+ var screenInfo : TCefScreenInfo;
+ out Result : Boolean);
+var
+ TempRect : TCEFRect;
+begin
+ if (GlobalCEFApp <> nil) then
+ begin
+ TempRect.x := 0;
+ TempRect.y := 0;
+ TempRect.width := round(Panel1.Width);
+ TempRect.height := round(Panel1.Height);
+
+ screenInfo.device_scale_factor := GlobalCEFApp.DeviceScaleFactor;
+ screenInfo.depth := 0;
+ screenInfo.depth_per_component := 0;
+ screenInfo.is_monochrome := Ord(False);
+ screenInfo.rect := TempRect;
+ screenInfo.available_rect := TempRect;
+
+ Result := True;
+ end
+ else
+ Result := False;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.chrmosrGetScreenPoint(Sender : TObject;
+ const browser : ICefBrowser;
+ viewX : Integer;
+ viewY : Integer;
+ var screenX : Integer;
+ var screenY : Integer;
+ out Result : Boolean);
+var
+ TempScreenPt, TempViewPt : TPoint;
+begin
+ if (GlobalCEFApp <> nil) then
+ begin
+ TempViewPt.x := LogicalToDevice(viewX, GlobalCEFApp.DeviceScaleFactor);
+ TempViewPt.y := LogicalToDevice(viewY, GlobalCEFApp.DeviceScaleFactor);
+ TempScreenPt := Panel1.ClientToScreen(TempViewPt);
+ screenX := TempScreenPt.x;
+ screenY := TempScreenPt.y;
+ Result := True;
+ end
+ else
+ Result := False;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.chrmosrGetViewRect(Sender : TObject;
+ const browser : ICefBrowser;
+ var rect : TCefRect;
+ out Result : Boolean);
+begin
+ if (GlobalCEFApp <> nil) then
+ begin
+ rect.x := 0;
+ rect.y := 0;
+ rect.width := round(Panel1.Width);
+ rect.height := round(Panel1.Height);
+ Result := True;
+ end
+ else
+ Result := False;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.chrmosrPaint(Sender : TObject;
+ const browser : ICefBrowser;
+ kind : TCefPaintElementType;
+ dirtyRectsCount : NativeUInt;
+ const dirtyRects : PCefRectArray;
+ const buffer : Pointer;
+ width : Integer;
+ height : Integer);
+var
+ src, dst: PByte;
+ i, j, TempLineSize, TempSrcOffset, TempDstOffset, SrcStride, DstStride : Integer;
+ n : NativeUInt;
+ TempWidth, TempHeight, TempScanlineSize : integer;
+ TempBufferBits : Pointer;
+ TempForcedResize : boolean;
+ TempBitmapData : TBitmapData;
+ TempBitmap : TBitmap;
+begin
+ try
+ FResizeCS.Acquire;
+ TempForcedResize := False;
+
+ if Panel1.BeginBufferDraw then
+ try
+ if (kind = PET_POPUP) then
+ begin
+ if (FPopUpBitmap = nil) or
+ (width <> FPopUpBitmap.Width) or
+ (height <> FPopUpBitmap.Height) then
+ begin
+ if (FPopUpBitmap <> nil) then FPopUpBitmap.Free;
+
+ FPopUpBitmap := TBitmap.Create(width, height);
+ {$IFDEF DELPHI17_UP}
+ FPopUpBitmap.BitmapScale := Panel1.ScreenScale;
+ {$ENDIF}
+ end;
+
+ TempWidth := FPopUpBitmap.Width;
+ TempHeight := FPopUpBitmap.Height;
+ TempScanlineSize := FPopUpBitmap.BytesPerLine;
+ TempBitmap := FPopUpBitmap;
+ end
+ else
+ begin
+ TempForcedResize := Panel1.UpdateBufferDimensions(Width, Height) or not(Panel1.BufferIsResized(False));
+ TempWidth := Panel1.BufferWidth;
+ TempHeight := Panel1.BufferHeight;
+ TempScanlineSize := Panel1.ScanlineSize;
+ TempBitmap := Panel1.Buffer;
+ end;
+
+
+ if (TempBitmap <> nil) {$IFDEF DELPHI17_UP}and TempBitmap.Map(TMapAccess.ReadWrite, TempBitmapData){$ENDIF} then
+ begin
+ try
+ {$IFDEF DELPHI17_UP}
+ TempBufferBits := TempBitmapData.Data;
+ {$ELSE}
+ TempBufferBits := TempBitmapData.StartLine;
+ {$ENDIF}
+ SrcStride := Width * SizeOf(TRGBQuad);
+ DstStride := TempScanlineSize;
+
+ n := 0;
+
+ while (n < dirtyRectsCount) do
+ begin
+ if (dirtyRects[n].x >= 0) and (dirtyRects[n].y >= 0) then
+ begin
+ TempLineSize := min(dirtyRects[n].width, TempWidth - dirtyRects[n].x) * SizeOf(TRGBQuad);
+
+ if (TempLineSize > 0) then
+ begin
+ TempSrcOffset := ((dirtyRects[n].y * Width) + dirtyRects[n].x) * SizeOf(TRGBQuad);
+ TempDstOffset := (dirtyRects[n].y * TempScanlineSize) + (dirtyRects[n].x * SizeOf(TRGBQuad));
+
+ src := @PByte(buffer)[TempSrcOffset];
+ dst := @PByte(TempBufferBits)[TempDstOffset];
+
+ i := 0;
+ j := min(dirtyRects[n].height, TempHeight - dirtyRects[n].y);
+
+ while (i < j) do
+ begin
+ Move(src^, dst^, TempLineSize);
+
+ inc(dst, DstStride);
+ inc(src, SrcStride);
+ inc(i);
+ end;
+ end;
+ end;
+
+ inc(n);
+ end;
+
+ Panel1.InvalidatePanel;
+ finally
+ {$IFDEF DELPHI17_UP}
+ TempBitmap.Unmap(TempBitmapData);
+ {$ENDIF}
+ end;
+
+ if FShowPopup and (FPopUpBitmap <> nil) then
+ Panel1.BufferDraw(FPopUpRect.Left, FPopUpRect.Top, FPopUpBitmap);
+ end;
+
+ if (kind = PET_VIEW) then
+ begin
+ if TempForcedResize or FPendingResize then SendCompMessage(CEF_PENDINGRESIZE);
+
+ FResizing := False;
+ FPendingResize := False;
+ end;
+ finally
+ Panel1.EndBufferDraw;
+ end;
+ finally
+ FResizeCS.Release;
+ end;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.chrmosrPopupShow(Sender: TObject; const browser: ICefBrowser; show: Boolean);
+begin
+ if show then
+ FShowPopUp := True
+ else
+ begin
+ FShowPopUp := False;
+ FPopUpRect := rect(0, 0, 0, 0);
+
+ if (chrmosr <> nil) then chrmosr.Invalidate(PET_VIEW);
+ end;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.chrmosrPopupSize(Sender: TObject; const browser: ICefBrowser; const rect: PCefRect);
+begin
+ if (GlobalCEFApp <> nil) then
+ begin
+ FPopUpRect.Left := rect.x;
+ FPopUpRect.Top := rect.y;
+ FPopUpRect.Right := rect.x + LogicalToDevice(rect.width, GlobalCEFApp.DeviceScaleFactor) - 1;
+ FPopUpRect.Bottom := rect.y + LogicalToDevice(rect.height, GlobalCEFApp.DeviceScaleFactor) - 1;
+ end;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.DoResize;
+begin
+ try
+ if (FResizeCS <> nil) then
+ begin
+ FResizeCS.Acquire;
+
+ if FResizing then
+ FPendingResize := True
+ else
+ if Panel1.BufferIsResized then
+ chrmosr.Invalidate(PET_VIEW)
+ else
+ begin
+ FResizing := True;
+ chrmosr.WasResized;
+ end;
+ end;
+ finally
+ if (FResizeCS <> nil) then FResizeCS.Release;
+ end;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.NotifyMoveOrResizeStarted;
+begin
+ if (chrmosr <> nil) then chrmosr.NotifyMoveOrResizeStarted;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.SendCaptureLostEvent;
+begin
+ if (chrmosr <> nil) then chrmosr.SendCaptureLostEvent;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.HandleSYSCHAR(const aMessage : TMsg);
+var
+ TempKeyEvent : TCefKeyEvent;
+begin
+ if Panel1.IsFocused and (aMessage.wParam in [VK_BACK..VK_HELP]) then
+ begin
+ TempKeyEvent.kind := KEYEVENT_CHAR;
+ TempKeyEvent.modifiers := GetCefKeyboardModifiers(aMessage.wParam, aMessage.lParam);
+ TempKeyEvent.windows_key_code := aMessage.wParam;
+ TempKeyEvent.native_key_code := aMessage.lParam;
+ TempKeyEvent.is_system_key := ord(True);
+ TempKeyEvent.character := #0;
+ TempKeyEvent.unmodified_character := #0;
+ TempKeyEvent.focus_on_editable_field := ord(False);
+
+ chrmosr.SendKeyEvent(@TempKeyEvent);
+ end;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.HandleSYSKEYDOWN(const aMessage : TMsg);
+var
+ TempKeyEvent : TCefKeyEvent;
+begin
+ if Panel1.IsFocused and (aMessage.wParam in [VK_BACK..VK_HELP]) then
+ begin
+ TempKeyEvent.kind := KEYEVENT_RAWKEYDOWN;
+ TempKeyEvent.modifiers := GetCefKeyboardModifiers(aMessage.wParam, aMessage.lParam);
+ TempKeyEvent.windows_key_code := aMessage.wParam;
+ TempKeyEvent.native_key_code := aMessage.lParam;
+ TempKeyEvent.is_system_key := ord(True);
+ TempKeyEvent.character := #0;
+ TempKeyEvent.unmodified_character := #0;
+ TempKeyEvent.focus_on_editable_field := ord(False);
+
+ chrmosr.SendKeyEvent(@TempKeyEvent);
+ end;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.HandleSYSKEYUP(const aMessage : TMsg);
+var
+ TempKeyEvent : TCefKeyEvent;
+begin
+ if Panel1.IsFocused and (aMessage.wParam in [VK_BACK..VK_HELP]) then
+ begin
+ TempKeyEvent.kind := KEYEVENT_KEYUP;
+ TempKeyEvent.modifiers := GetCefKeyboardModifiers(aMessage.wParam, aMessage.lParam);
+ TempKeyEvent.windows_key_code := aMessage.wParam;
+ TempKeyEvent.native_key_code := aMessage.lParam;
+ TempKeyEvent.is_system_key := ord(True);
+ TempKeyEvent.character := #0;
+ TempKeyEvent.unmodified_character := #0;
+ TempKeyEvent.focus_on_editable_field := ord(False);
+
+ chrmosr.SendKeyEvent(@TempKeyEvent);
+ end;
+end;
+
+procedure TFMXExternalPumpBrowserFrm.DoBrowserCreated;
+begin
+ Caption := 'FMX External Pump Browser';
+ AddressPnl.Enabled := True;
+ Panel1.SetFocus;
+ LoadURL;
+end;
+
+function TFMXExternalPumpBrowserFrm.getModifiers(Shift: TShiftState): TCefEventFlags;
+begin
+ Result := EVENTFLAG_NONE;
+
+ if (ssShift in Shift) then Result := Result or EVENTFLAG_SHIFT_DOWN;
+ if (ssAlt in Shift) then Result := Result or EVENTFLAG_ALT_DOWN;
+ if (ssCtrl in Shift) then Result := Result or EVENTFLAG_CONTROL_DOWN;
+ if (ssLeft in Shift) then Result := Result or EVENTFLAG_LEFT_MOUSE_BUTTON;
+ if (ssRight in Shift) then Result := Result or EVENTFLAG_RIGHT_MOUSE_BUTTON;
+ if (ssMiddle in Shift) then Result := Result or EVENTFLAG_MIDDLE_MOUSE_BUTTON;
+end;
+
+function TFMXExternalPumpBrowserFrm.GetButton(Button: TMouseButton): TCefMouseButtonType;
+begin
+ case Button of
+ TMouseButton.mbRight : Result := MBT_RIGHT;
+ TMouseButton.mbMiddle : Result := MBT_MIDDLE;
+ else Result := MBT_LEFT;
+ end;
+end;
+
+function TFMXExternalPumpBrowserFrm.SendCompMessage(aMsg, wParam : cardinal; lParam : integer) : boolean;
+{$IFDEF MSWINDOWS}
+var
+ TempHandle : TWinWindowHandle;
+{$ENDIF}
+begin
+ {$IFDEF MSWINDOWS}
+ TempHandle := WindowHandleToPlatform(Handle);
+ Result := WinApi.Windows.PostMessage(TempHandle.Wnd, aMsg, wParam, lParam);
+ {$ELSE}
+ Result := False;
+ {$ENDIF}
+end;
+
+end.
diff --git a/demos/OSRExternalPumpBrowser/OSRExternalPumpBrowser.dpr b/demos/OSRExternalPumpBrowser/OSRExternalPumpBrowser.dpr
index d2454b26..b33495ec 100644
--- a/demos/OSRExternalPumpBrowser/OSRExternalPumpBrowser.dpr
+++ b/demos/OSRExternalPumpBrowser/OSRExternalPumpBrowser.dpr
@@ -72,6 +72,7 @@ begin
GlobalCEFApp.FlashEnabled := False;
GlobalCEFApp.ExternalMessagePump := True;
GlobalCEFApp.MultiThreadedMessageLoop := False;
+ GlobalCEFApp.SitePerProcess := False;
GlobalCEFApp.OnScheduleMessagePumpWork := GlobalCEFApp_OnScheduleMessagePumpWork;
if GlobalCEFApp.StartMainProcess then
diff --git a/demos/SimpleOSRBrowser/SimpleOSRBrowser.dpr b/demos/SimpleOSRBrowser/SimpleOSRBrowser.dpr
index ef40a62b..c87c85c7 100644
--- a/demos/SimpleOSRBrowser/SimpleOSRBrowser.dpr
+++ b/demos/SimpleOSRBrowser/SimpleOSRBrowser.dpr
@@ -59,6 +59,7 @@ begin
GlobalCEFApp.WindowlessRenderingEnabled := True;
GlobalCEFApp.EnableHighDPISupport := True;
GlobalCEFApp.FastUnload := True;
+ GlobalCEFApp.SitePerProcess := False;
if GlobalCEFApp.StartMainProcess then
begin
diff --git a/demos/SimpleOSRBrowser/uSimpleOSRBrowser.dfm b/demos/SimpleOSRBrowser/uSimpleOSRBrowser.dfm
index 2e530124..d57a54d3 100644
--- a/demos/SimpleOSRBrowser/uSimpleOSRBrowser.dfm
+++ b/demos/SimpleOSRBrowser/uSimpleOSRBrowser.dfm
@@ -2,7 +2,7 @@ object Form1: TForm1
Left = 0
Top = 0
Caption = 'Simple OSR Browser - Initializing browser. Please wait...'
- ClientHeight = 510
+ ClientHeight = 530
ClientWidth = 800
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
@@ -105,7 +105,7 @@ object Form1: TForm1
Left = 0
Top = 30
Width = 800
- Height = 480
+ Height = 500
Align = alClient
Caption = 'Panel1'
TabOrder = 1
diff --git a/demos/SimpleOSRBrowser/uSimpleOSRBrowser.pas b/demos/SimpleOSRBrowser/uSimpleOSRBrowser.pas
index 72b00b6b..c7a420e0 100644
--- a/demos/SimpleOSRBrowser/uSimpleOSRBrowser.pas
+++ b/demos/SimpleOSRBrowser/uSimpleOSRBrowser.pas
@@ -633,7 +633,7 @@ procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton; Shift: T
var
TempEvent : TCefMouseEvent;
begin
- if (GlobalCEFApp <> nil) then
+ if (GlobalCEFApp <> nil) and (chrmosr <> nil) then
begin
Panel1.SetFocus;
@@ -650,7 +650,7 @@ var
TempEvent : TCefMouseEvent;
TempPoint : TPoint;
begin
- if (GlobalCEFApp <> nil) then
+ if (GlobalCEFApp <> nil) and (chrmosr <> nil) then
begin
GetCursorPos(TempPoint);
TempPoint := Panel1.ScreenToclient(TempPoint);
@@ -666,7 +666,7 @@ procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Inte
var
TempEvent : TCefMouseEvent;
begin
- if (GlobalCEFApp <> nil) then
+ if (GlobalCEFApp <> nil) and (chrmosr <> nil) then
begin
TempEvent.x := X;
TempEvent.y := Y;
@@ -680,7 +680,7 @@ procedure TForm1.Panel1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TSh
var
TempEvent : TCefMouseEvent;
begin
- if (GlobalCEFApp <> nil) then
+ if (GlobalCEFApp <> nil) and (chrmosr <> nil) then
begin
TempEvent.x := X;
TempEvent.y := Y;
diff --git a/source/00-CreateResources.bat b/packages/00-CreateResources.bat
similarity index 100%
rename from source/00-CreateResources.bat
rename to packages/00-CreateResources.bat
diff --git a/packages/00-DeleteDCUs.bat b/packages/00-DeleteDCUs.bat
new file mode 100644
index 00000000..9ab8921e
--- /dev/null
+++ b/packages/00-DeleteDCUs.bat
@@ -0,0 +1,13 @@
+del /s /q *.dcu
+del /s /q *.exe
+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 __history
+rmdir __recovery
diff --git a/packages/CEF4Delphi.dpk b/packages/CEF4Delphi.dpk
new file mode 100644
index 00000000..a24dc5ad
--- /dev/null
+++ b/packages/CEF4Delphi.dpk
@@ -0,0 +1,170 @@
+package CEF4Delphi;
+
+{$R *.res}
+{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
+{$ALIGN 8}
+{$ASSERTIONS ON}
+{$BOOLEVAL OFF}
+{$DEBUGINFO OFF}
+{$EXTENDEDSYNTAX ON}
+{$IMPORTEDDATA ON}
+{$IOCHECKS ON}
+{$LOCALSYMBOLS ON}
+{$LONGSTRINGS ON}
+{$OPENSTRINGS ON}
+{$OPTIMIZATION OFF}
+{$OVERFLOWCHECKS OFF}
+{$RANGECHECKS OFF}
+{$REFERENCEINFO ON}
+{$SAFEDIVIDE OFF}
+{$STACKFRAMES ON}
+{$TYPEDADDRESS OFF}
+{$VARSTRINGCHECKS ON}
+{$WRITEABLECONST OFF}
+{$MINENUMSIZE 1}
+{$IMAGEBASE $400000}
+{$DEFINE DEBUG}
+{$ENDIF IMPLICITBUILDING}
+{$DESCRIPTION 'CEF4Delphi'}
+{$IMPLICITBUILD OFF}
+
+requires
+ rtl,
+ vcl;
+
+contains
+ CEF4Delphi_Register in 'CEF4Delphi_Register.pas',
+ uCEFFindHandler in '..\source\uCEFFindHandler.pas',
+ uCEFConstants in '..\source\uCEFConstants.pas',
+ uCEFTypes in '..\source\uCEFTypes.pas',
+ uCEFInterfaces in '..\source\uCEFInterfaces.pas',
+ uCEFMiscFunctions in '..\source\uCEFMiscFunctions.pas',
+ uCEFLibFunctions in '..\source\uCEFLibFunctions.pas',
+ uCEFApplication in '..\source\uCEFApplication.pas',
+ uCEFSchemeRegistrar in '..\source\uCEFSchemeRegistrar.pas',
+ uCEFCommandLine in '..\source\uCEFCommandLine.pas',
+ uCEFClient in '..\source\uCEFClient.pas',
+ uCEFProcessMessage in '..\source\uCEFProcessMessage.pas',
+ uCEFBrowser in '..\source\uCEFBrowser.pas',
+ uCEFListValue in '..\source\uCEFListValue.pas',
+ uCEFBinaryValue in '..\source\uCEFBinaryValue.pas',
+ uCEFValue in '..\source\uCEFValue.pas',
+ uCEFDictionaryValue in '..\source\uCEFDictionaryValue.pas',
+ uCEFDownloadImageCallBack in '..\source\uCEFDownloadImageCallBack.pas',
+ uCEFFrame in '..\source\uCEFFrame.pas',
+ uCEFPDFPrintCallback in '..\source\uCEFPDFPrintCallback.pas',
+ uCEFRunFileDialogCallback in '..\source\uCEFRunFileDialogCallback.pas',
+ uCEFRequestContext in '..\source\uCEFRequestContext.pas',
+ uCEFNavigationEntryVisitor in '..\source\uCEFNavigationEntryVisitor.pas',
+ uCEFStringVisitor in '..\source\uCEFStringVisitor.pas',
+ uCEFv8Context in '..\source\uCEFv8Context.pas',
+ uCEFDomVisitor in '..\source\uCEFDomVisitor.pas',
+ uCEFNavigationEntry in '..\source\uCEFNavigationEntry.pas',
+ uCEFCookieManager in '..\source\uCEFCookieManager.pas',
+ uCEFCompletionCallback in '..\source\uCEFCompletionCallback.pas',
+ uCEFRequestContextHandler in '..\source\uCEFRequestContextHandler.pas',
+ uCEFWebPluginInfo in '..\source\uCEFWebPluginInfo.pas',
+ uCEFDomDocument in '..\source\uCEFDomDocument.pas',
+ uCEFDomNode in '..\source\uCEFDomNode.pas',
+ uCEFv8Value in '..\source\uCEFv8Value.pas',
+ uCEFv8Accessor in '..\source\uCEFv8Accessor.pas',
+ uCEFLoadHandler in '..\source\uCEFLoadHandler.pas',
+ uCEFFocusHandler in '..\source\uCEFFocusHandler.pas',
+ uCEFContextMenuHandler in '..\source\uCEFContextMenuHandler.pas',
+ uCEFDialogHandler in '..\source\uCEFDialogHandler.pas',
+ uCEFKeyboardHandler in '..\source\uCEFKeyboardHandler.pas',
+ uCEFDisplayHandler in '..\source\uCEFDisplayHandler.pas',
+ uCEFDownloadHandler in '..\source\uCEFDownloadHandler.pas',
+ uCEFGeolocationHandler in '..\source\uCEFGeolocationHandler.pas',
+ uCEFJsDialogHandler in '..\source\uCEFJsDialogHandler.pas',
+ uCEFLifeSpanHandler in '..\source\uCEFLifeSpanHandler.pas',
+ uCEFRequestHandler in '..\source\uCEFRequestHandler.pas',
+ uCEFRenderHandler in '..\source\uCEFRenderHandler.pas',
+ uCEFDragHandler in '..\source\uCEFDragHandler.pas',
+ uCEFPostData in '..\source\uCEFPostData.pas',
+ uCEFPostDataElement in '..\source\uCEFPostDataElement.pas',
+ uCEFRequest in '..\source\uCEFRequest.pas',
+ uCEFStreamReader in '..\source\uCEFStreamReader.pas',
+ uCEFWriteHandler in '..\source\uCEFWriteHandler.pas',
+ uCEFStreamWriter in '..\source\uCEFStreamWriter.pas',
+ uCEFv8StackFrame in '..\source\uCEFv8StackFrame.pas',
+ uCEFv8StackTrace in '..\source\uCEFv8StackTrace.pas',
+ uCEFv8Handler in '..\source\uCEFv8Handler.pas',
+ uCEFRequestCallback in '..\source\uCEFRequestCallback.pas',
+ uCEFCustomStreamReader in '..\source\uCEFCustomStreamReader.pas',
+ uCEFCallback in '..\source\uCEFCallback.pas',
+ uCEFResourceHandler in '..\source\uCEFResourceHandler.pas',
+ uCEFSchemeHandlerFactory in '..\source\uCEFSchemeHandlerFactory.pas',
+ uCEFTask in '..\source\uCEFTask.pas',
+ uCEFTaskRunner in '..\source\uCEFTaskRunner.pas',
+ uCEFStringMap in '..\source\uCEFStringMap.pas',
+ uCEFStringMultimap in '..\source\uCEFStringMultimap.pas',
+ uCEFXmlReader in '..\source\uCEFXmlReader.pas',
+ uCEFZipReader in '..\source\uCEFZipReader.pas',
+ uCEFResponse in '..\source\uCEFResponse.pas',
+ uCEFCookieVisitor in '..\source\uCEFCookieVisitor.pas',
+ uCEFV8Exception in '..\source\uCEFV8Exception.pas',
+ uCEFResourceBundleHandler in '..\source\uCEFResourceBundleHandler.pas',
+ uCEFSetCookieCallback in '..\source\uCEFSetCookieCallback.pas',
+ uCEFDeleteCookiesCallback in '..\source\uCEFDeleteCookiesCallback.pas',
+ uCEFDownLoadItem in '..\source\uCEFDownLoadItem.pas',
+ uCEFBeforeDownloadCallback in '..\source\uCEFBeforeDownloadCallback.pas',
+ uCEFDownloadItemCallback in '..\source\uCEFDownloadItemCallback.pas',
+ uCEFAuthCallback in '..\source\uCEFAuthCallback.pas',
+ uCEFJsDialogCallback in '..\source\uCEFJsDialogCallback.pas',
+ uCEFGeolocationCallback in '..\source\uCEFGeolocationCallback.pas',
+ uCEFContextMenuParams in '..\source\uCEFContextMenuParams.pas',
+ uCEFMenuModel in '..\source\uCEFMenuModel.pas',
+ uCEFBrowserProcessHandler in '..\source\uCEFBrowserProcessHandler.pas',
+ uCEFRenderProcessHandler in '..\source\uCEFRenderProcessHandler.pas',
+ uCEFUrlrequestClient in '..\source\uCEFUrlrequestClient.pas',
+ uCEFUrlRequest in '..\source\uCEFUrlRequest.pas',
+ uCEFWebPluginInfoVisitor in '..\source\uCEFWebPluginInfoVisitor.pas',
+ uCEFWebPluginUnstableCallback in '..\source\uCEFWebPluginUnstableCallback.pas',
+ uCEFEndTracingCallback in '..\source\uCEFEndTracingCallback.pas',
+ uCEFGetGeolocationCallback in '..\source\uCEFGetGeolocationCallback.pas',
+ uCEFFileDialogCallback in '..\source\uCEFFileDialogCallback.pas',
+ uCEFDragData in '..\source\uCEFDragData.pas',
+ uCEFResolveCallback in '..\source\uCEFResolveCallback.pas',
+ uCEFPrintSettings in '..\source\uCEFPrintSettings.pas',
+ uCEFSslInfo in '..\source\uCEFSslInfo.pas',
+ uCEFRunContextMenuCallback in '..\source\uCEFRunContextMenuCallback.pas',
+ uCEFResourceBundle in '..\source\uCEFResourceBundle.pas',
+ uCEFResponseFilter in '..\source\uCEFResponseFilter.pas',
+ uCEFImage in '..\source\uCEFImage.pas',
+ uCEFMenuModelDelegate in '..\source\uCEFMenuModelDelegate.pas',
+ uCEFv8Types in '..\source\uCEFv8Types.pas',
+ uCEFWindowParent in '..\source\uCEFWindowParent.pas',
+ uCEFChromium in '..\source\uCEFChromium.pas',
+ uCEFChromiumEvents in '..\source\uCEFChromiumEvents.pas',
+ uCEFChromiumOptions in '..\source\uCEFChromiumOptions.pas',
+ uCEFChromiumFontOptions in '..\source\uCEFChromiumFontOptions.pas',
+ uCEFPDFPrintOptions in '..\source\uCEFPDFPrintOptions.pas',
+ uCEFRegisterCDMCallback in '..\source\uCEFRegisterCDMCallback.pas',
+ uCEFThread in '..\source\uCEFThread.pas',
+ uCEFv8Interceptor in '..\source\uCEFv8Interceptor.pas',
+ uCEFWaitableEvent in '..\source\uCEFWaitableEvent.pas',
+ uCEFX509CertPrincipal in '..\source\uCEFX509CertPrincipal.pas',
+ uCEFX509Certificate in '..\source\uCEFX509Certificate.pas',
+ uCEFSSLStatus in '..\source\uCEFSSLStatus.pas',
+ uCEFSelectClientCertificateCallback in '..\source\uCEFSelectClientCertificateCallback.pas',
+ uCEFChromiumWindow in '..\source\uCEFChromiumWindow.pas',
+ uCEFBaseRefCounted in '..\source\uCEFBaseRefCounted.pas',
+ uCEFBaseScopedWrapper in '..\source\uCEFBaseScopedWrapper.pas',
+ uCEFAccessibilityHandler in '..\source\uCEFAccessibilityHandler.pas',
+ uOLEDragAndDrop in '..\source\uOLEDragAndDrop.pas',
+ uCEFDragAndDropMgr in '..\source\uCEFDragAndDropMgr.pas',
+ uCEFGetExtensionResourceCallback in '..\source\uCEFGetExtensionResourceCallback.pas',
+ uCEFExtension in '..\source\uCEFExtension.pas',
+ uCEFExtensionHandler in '..\source\uCEFExtensionHandler.pas',
+ uBufferPanel in '..\source\uBufferPanel.pas',
+ uCEFApp in '..\source\uCEFApp.pas',
+ uCEFWorkScheduler in '..\source\uCEFWorkScheduler.pas',
+ uCEFWorkSchedulerThread in '..\source\uCEFWorkSchedulerThread.pas',
+ uCEFServer in '..\source\uCEFServer.pas',
+ uCEFServerHandler in '..\source\uCEFServerHandler.pas',
+ uCEFServerEvents in '..\source\uCEFServerEvents.pas',
+ uCEFServerComponent in '..\source\uCEFServerComponent.pas';
+
+end.
+
diff --git a/source/CEF4Delphi.dproj b/packages/CEF4Delphi.dproj
similarity index 74%
rename from source/CEF4Delphi.dproj
rename to packages/CEF4Delphi.dproj
index 2b18dc41..0626dac1 100644
--- a/source/CEF4Delphi.dproj
+++ b/packages/CEF4Delphi.dproj
@@ -72,14 +72,14 @@
false
- rtl;vcl;$(DCC_UsePackage)
+ rtl;vcl;fmx;$(DCC_UsePackage)
1033
Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
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
- rtl;vcl;$(DCC_UsePackage)
+ rtl;vcl;fmx;$(DCC_UsePackage)
Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)
Debug
true
@@ -124,137 +124,138 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Base
diff --git a/source/CEF4Delphi.res b/packages/CEF4Delphi.res
similarity index 100%
rename from source/CEF4Delphi.res
rename to packages/CEF4Delphi.res
diff --git a/source/CEF4Delphi_D7.cfg b/packages/CEF4Delphi_D7.cfg
similarity index 100%
rename from source/CEF4Delphi_D7.cfg
rename to packages/CEF4Delphi_D7.cfg
diff --git a/source/CEF4Delphi_D7.dof b/packages/CEF4Delphi_D7.dof
similarity index 100%
rename from source/CEF4Delphi_D7.dof
rename to packages/CEF4Delphi_D7.dof
diff --git a/packages/CEF4Delphi_D7.dpk b/packages/CEF4Delphi_D7.dpk
new file mode 100644
index 00000000..fdebff44
--- /dev/null
+++ b/packages/CEF4Delphi_D7.dpk
@@ -0,0 +1,166 @@
+package CEF4Delphi_D7;
+
+{$R *.res}
+{$ALIGN 8}
+{$ASSERTIONS ON}
+{$BOOLEVAL OFF}
+{$DEBUGINFO OFF}
+{$EXTENDEDSYNTAX ON}
+{$IMPORTEDDATA ON}
+{$IOCHECKS ON}
+{$LOCALSYMBOLS ON}
+{$LONGSTRINGS ON}
+{$OPENSTRINGS ON}
+{$OPTIMIZATION OFF}
+{$OVERFLOWCHECKS OFF}
+{$RANGECHECKS OFF}
+{$REFERENCEINFO ON}
+{$SAFEDIVIDE OFF}
+{$STACKFRAMES ON}
+{$TYPEDADDRESS OFF}
+{$VARSTRINGCHECKS ON}
+{$WRITEABLECONST OFF}
+{$MINENUMSIZE 1}
+{$IMAGEBASE $400000}
+{$DESCRIPTION 'CEF4Delphi'}
+{$IMPLICITBUILD OFF}
+{$DEFINE DEBUG}
+
+requires
+ rtl,
+ vcl;
+
+contains
+ CEF4Delphi_D7_Register in 'CEF4Delphi_D7_Register.pas',
+ uCEFFindHandler in '..\source\uCEFFindHandler.pas',
+ uCEFConstants in '..\source\uCEFConstants.pas',
+ uCEFTypes in '..\source\uCEFTypes.pas',
+ uCEFInterfaces in '..\source\uCEFInterfaces.pas',
+ uCEFMiscFunctions in '..\source\uCEFMiscFunctions.pas',
+ uCEFLibFunctions in '..\source\uCEFLibFunctions.pas',
+ uCEFApplication in '..\source\uCEFApplication.pas',
+ uCEFSchemeRegistrar in '..\source\uCEFSchemeRegistrar.pas',
+ uCEFCommandLine in '..\source\uCEFCommandLine.pas',
+ uCEFClient in '..\source\uCEFClient.pas',
+ uCEFProcessMessage in '..\source\uCEFProcessMessage.pas',
+ uCEFBrowser in '..\source\uCEFBrowser.pas',
+ uCEFListValue in '..\source\uCEFListValue.pas',
+ uCEFBinaryValue in '..\source\uCEFBinaryValue.pas',
+ uCEFValue in '..\source\uCEFValue.pas',
+ uCEFDictionaryValue in '..\source\uCEFDictionaryValue.pas',
+ uCEFDownloadImageCallBack in '..\source\uCEFDownloadImageCallBack.pas',
+ uCEFFrame in '..\source\uCEFFrame.pas',
+ uCEFPDFPrintCallback in '..\source\uCEFPDFPrintCallback.pas',
+ uCEFRunFileDialogCallback in '..\source\uCEFRunFileDialogCallback.pas',
+ uCEFRequestContext in '..\source\uCEFRequestContext.pas',
+ uCEFNavigationEntryVisitor in '..\source\uCEFNavigationEntryVisitor.pas',
+ uCEFStringVisitor in '..\source\uCEFStringVisitor.pas',
+ uCEFv8Context in '..\source\uCEFv8Context.pas',
+ uCEFDomVisitor in '..\source\uCEFDomVisitor.pas',
+ uCEFNavigationEntry in '..\source\uCEFNavigationEntry.pas',
+ uCEFCookieManager in '..\source\uCEFCookieManager.pas',
+ uCEFCompletionCallback in '..\source\uCEFCompletionCallback.pas',
+ uCEFRequestContextHandler in '..\source\uCEFRequestContextHandler.pas',
+ uCEFWebPluginInfo in '..\source\uCEFWebPluginInfo.pas',
+ uCEFDomDocument in '..\source\uCEFDomDocument.pas',
+ uCEFDomNode in '..\source\uCEFDomNode.pas',
+ uCEFv8Value in '..\source\uCEFv8Value.pas',
+ uCEFv8Accessor in '..\source\uCEFv8Accessor.pas',
+ uCEFLoadHandler in '..\source\uCEFLoadHandler.pas',
+ uCEFFocusHandler in '..\source\uCEFFocusHandler.pas',
+ uCEFContextMenuHandler in '..\source\uCEFContextMenuHandler.pas',
+ uCEFDialogHandler in '..\source\uCEFDialogHandler.pas',
+ uCEFKeyboardHandler in '..\source\uCEFKeyboardHandler.pas',
+ uCEFDisplayHandler in '..\source\uCEFDisplayHandler.pas',
+ uCEFDownloadHandler in '..\source\uCEFDownloadHandler.pas',
+ uCEFGeolocationHandler in '..\source\uCEFGeolocationHandler.pas',
+ uCEFJsDialogHandler in '..\source\uCEFJsDialogHandler.pas',
+ uCEFLifeSpanHandler in '..\source\uCEFLifeSpanHandler.pas',
+ uCEFRequestHandler in '..\source\uCEFRequestHandler.pas',
+ uCEFRenderHandler in '..\source\uCEFRenderHandler.pas',
+ uCEFDragHandler in '..\source\uCEFDragHandler.pas',
+ uCEFPostData in '..\source\uCEFPostData.pas',
+ uCEFPostDataElement in '..\source\uCEFPostDataElement.pas',
+ uCEFRequest in '..\source\uCEFRequest.pas',
+ uCEFStreamReader in '..\source\uCEFStreamReader.pas',
+ uCEFWriteHandler in '..\source\uCEFWriteHandler.pas',
+ uCEFStreamWriter in '..\source\uCEFStreamWriter.pas',
+ uCEFv8StackFrame in '..\source\uCEFv8StackFrame.pas',
+ uCEFv8StackTrace in '..\source\uCEFv8StackTrace.pas',
+ uCEFv8Handler in '..\source\uCEFv8Handler.pas',
+ uCEFRequestCallback in '..\source\uCEFRequestCallback.pas',
+ uCEFCustomStreamReader in '..\source\uCEFCustomStreamReader.pas',
+ uCEFCallback in '..\source\uCEFCallback.pas',
+ uCEFResourceHandler in '..\source\uCEFResourceHandler.pas',
+ uCEFSchemeHandlerFactory in '..\source\uCEFSchemeHandlerFactory.pas',
+ uCEFTask in '..\source\uCEFTask.pas',
+ uCEFTaskRunner in '..\source\uCEFTaskRunner.pas',
+ uCEFStringMap in '..\source\uCEFStringMap.pas',
+ uCEFStringMultimap in '..\source\uCEFStringMultimap.pas',
+ uCEFXmlReader in '..\source\uCEFXmlReader.pas',
+ uCEFZipReader in '..\source\uCEFZipReader.pas',
+ uCEFResponse in '..\source\uCEFResponse.pas',
+ uCEFCookieVisitor in '..\source\uCEFCookieVisitor.pas',
+ uCEFV8Exception in '..\source\uCEFV8Exception.pas',
+ uCEFResourceBundleHandler in '..\source\uCEFResourceBundleHandler.pas',
+ uCEFSetCookieCallback in '..\source\uCEFSetCookieCallback.pas',
+ uCEFDeleteCookiesCallback in '..\source\uCEFDeleteCookiesCallback.pas',
+ uCEFDownLoadItem in '..\source\uCEFDownLoadItem.pas',
+ uCEFBeforeDownloadCallback in '..\source\uCEFBeforeDownloadCallback.pas',
+ uCEFDownloadItemCallback in '..\source\uCEFDownloadItemCallback.pas',
+ uCEFAuthCallback in '..\source\uCEFAuthCallback.pas',
+ uCEFJsDialogCallback in '..\source\uCEFJsDialogCallback.pas',
+ uCEFGeolocationCallback in '..\source\uCEFGeolocationCallback.pas',
+ uCEFContextMenuParams in '..\source\uCEFContextMenuParams.pas',
+ uCEFMenuModel in '..\source\uCEFMenuModel.pas',
+ uCEFBrowserProcessHandler in '..\source\uCEFBrowserProcessHandler.pas',
+ uCEFRenderProcessHandler in '..\source\uCEFRenderProcessHandler.pas',
+ uCEFUrlrequestClient in '..\source\uCEFUrlrequestClient.pas',
+ uCEFUrlRequest in '..\source\uCEFUrlRequest.pas',
+ uCEFWebPluginInfoVisitor in '..\source\uCEFWebPluginInfoVisitor.pas',
+ uCEFWebPluginUnstableCallback in '..\source\uCEFWebPluginUnstableCallback.pas',
+ uCEFEndTracingCallback in '..\source\uCEFEndTracingCallback.pas',
+ uCEFGetGeolocationCallback in '..\source\uCEFGetGeolocationCallback.pas',
+ uCEFFileDialogCallback in '..\source\uCEFFileDialogCallback.pas',
+ uCEFDragData in '..\source\uCEFDragData.pas',
+ uCEFResolveCallback in '..\source\uCEFResolveCallback.pas',
+ uCEFPrintSettings in '..\source\uCEFPrintSettings.pas',
+ uCEFSslInfo in '..\source\uCEFSslInfo.pas',
+ uCEFRunContextMenuCallback in '..\source\uCEFRunContextMenuCallback.pas',
+ uCEFResourceBundle in '..\source\uCEFResourceBundle.pas',
+ uCEFResponseFilter in '..\source\uCEFResponseFilter.pas',
+ uCEFImage in '..\source\uCEFImage.pas',
+ uCEFMenuModelDelegate in '..\source\uCEFMenuModelDelegate.pas',
+ uCEFv8Types in '..\source\uCEFv8Types.pas',
+ uCEFWindowParent in '..\source\uCEFWindowParent.pas',
+ uCEFChromium in '..\source\uCEFChromium.pas',
+ uCEFChromiumEvents in '..\source\uCEFChromiumEvents.pas',
+ uCEFChromiumOptions in '..\source\uCEFChromiumOptions.pas',
+ uCEFChromiumFontOptions in '..\source\uCEFChromiumFontOptions.pas',
+ uCEFPDFPrintOptions in '..\source\uCEFPDFPrintOptions.pas',
+ uCEFRegisterCDMCallback in '..\source\uCEFRegisterCDMCallback.pas',
+ uCEFThread in '..\source\uCEFThread.pas',
+ uCEFv8Interceptor in '..\source\uCEFv8Interceptor.pas',
+ uCEFWaitableEvent in '..\source\uCEFWaitableEvent.pas',
+ uCEFX509CertPrincipal in '..\source\uCEFX509CertPrincipal.pas',
+ uCEFX509Certificate in '..\source\uCEFX509Certificate.pas',
+ uCEFSSLStatus in '..\source\uCEFSSLStatus.pas',
+ uCEFSelectClientCertificateCallback in '..\source\uCEFSelectClientCertificateCallback.pas',
+ uCEFChromiumWindow in '..\source\uCEFChromiumWindow.pas',
+ uCEFBaseRefCounted in '..\source\uCEFBaseRefCounted.pas',
+ uCEFBaseScopedWrapper in '..\source\uCEFBaseScopedWrapper.pas',
+ uCEFDragAndDropMgr in '..\source\uCEFDragAndDropMgr.pas',
+ uOLEDragAndDrop in '..\source\uOLEDragAndDrop.pas',
+ uCEFGetExtensionResourceCallback in '..\source\uCEFGetExtensionResourceCallback.pas',
+ uCEFExtension in '..\source\uCEFExtension.pas',
+ uCEFExtensionHandler in '..\source\uCEFExtensionHandler.pas',
+ uBufferPanel in '..\source\uBufferPanel.pas',
+ uCEFApp in '..\source\uCEFApp.pas',
+ uCEFWorkScheduler in '..\source\uCEFWorkScheduler.pas',
+ uCEFWorkSchedulerThread in '..\source\uCEFWorkSchedulerThread.pas',
+ uCEFServer in '..\source\uCEFServer.pas',
+ uCEFServerHandler in '..\source\uCEFServerHandler.pas',
+ uCEFServerEvents in '..\source\uCEFServerEvents.pas',
+ uCEFServerComponent in '..\source\uCEFServerComponent.pas';
+
+end.
diff --git a/source/CEF4Delphi_D7.skincfg b/packages/CEF4Delphi_D7.skincfg
similarity index 100%
rename from source/CEF4Delphi_D7.skincfg
rename to packages/CEF4Delphi_D7.skincfg
diff --git a/packages/CEF4Delphi_D7_Register.pas b/packages/CEF4Delphi_D7_Register.pas
new file mode 100644
index 00000000..c02a38ca
--- /dev/null
+++ b/packages/CEF4Delphi_D7_Register.pas
@@ -0,0 +1,60 @@
+// ************************************************************************
+// ***************************** 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 © 2018 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.
+ *
+ *)
+
+unit CEF4Delphi_D7_Register;
+
+{$R chromium.dcr}
+
+{$I cef.inc}
+
+interface
+
+procedure Register;
+
+implementation
+
+uses
+ Classes,
+ uCEFChromium, uCEFWindowParent, uCEFChromiumWindow, uBufferPanel, uCEFWorkScheduler, uCEFServerComponent;
+
+procedure Register;
+begin
+ RegisterComponents('Chromium', [TChromium, TCEFWindowParent, TChromiumWindow, TBufferPanel,
+ TCEFWorkScheduler, TCEFServerComponent]);
+end;
+
+end.
diff --git a/packages/CEF4Delphi_FMX.dpk b/packages/CEF4Delphi_FMX.dpk
new file mode 100644
index 00000000..eca7d01f
--- /dev/null
+++ b/packages/CEF4Delphi_FMX.dpk
@@ -0,0 +1,174 @@
+package CEF4Delphi_FMX;
+
+{$R *.res}
+{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
+{$ALIGN 8}
+{$ASSERTIONS ON}
+{$BOOLEVAL OFF}
+{$DEBUGINFO OFF}
+{$EXTENDEDSYNTAX ON}
+{$IMPORTEDDATA ON}
+{$IOCHECKS ON}
+{$LOCALSYMBOLS ON}
+{$LONGSTRINGS ON}
+{$OPENSTRINGS ON}
+{$OPTIMIZATION OFF}
+{$OVERFLOWCHECKS OFF}
+{$RANGECHECKS OFF}
+{$REFERENCEINFO ON}
+{$SAFEDIVIDE OFF}
+{$STACKFRAMES ON}
+{$TYPEDADDRESS OFF}
+{$VARSTRINGCHECKS ON}
+{$WRITEABLECONST OFF}
+{$MINENUMSIZE 1}
+{$IMAGEBASE $400000}
+{$DEFINE DEBUG}
+{$ENDIF IMPLICITBUILDING}
+{$DESCRIPTION 'CEF4Delphi'}
+{$IMPLICITBUILD OFF}
+
+requires
+ rtl,
+ vcl,
+ fmx;
+
+contains
+ CEF4Delphi_FMX_Register in 'CEF4Delphi_FMX_Register.pas',
+ uCEFFindHandler in '..\source\uCEFFindHandler.pas',
+ uCEFConstants in '..\source\uCEFConstants.pas',
+ uCEFTypes in '..\source\uCEFTypes.pas',
+ uCEFInterfaces in '..\source\uCEFInterfaces.pas',
+ uCEFMiscFunctions in '..\source\uCEFMiscFunctions.pas',
+ uCEFLibFunctions in '..\source\uCEFLibFunctions.pas',
+ uCEFApplication in '..\source\uCEFApplication.pas',
+ uCEFSchemeRegistrar in '..\source\uCEFSchemeRegistrar.pas',
+ uCEFCommandLine in '..\source\uCEFCommandLine.pas',
+ uCEFClient in '..\source\uCEFClient.pas',
+ uCEFProcessMessage in '..\source\uCEFProcessMessage.pas',
+ uCEFBrowser in '..\source\uCEFBrowser.pas',
+ uCEFListValue in '..\source\uCEFListValue.pas',
+ uCEFBinaryValue in '..\source\uCEFBinaryValue.pas',
+ uCEFValue in '..\source\uCEFValue.pas',
+ uCEFDictionaryValue in '..\source\uCEFDictionaryValue.pas',
+ uCEFDownloadImageCallBack in '..\source\uCEFDownloadImageCallBack.pas',
+ uCEFFrame in '..\source\uCEFFrame.pas',
+ uCEFPDFPrintCallback in '..\source\uCEFPDFPrintCallback.pas',
+ uCEFRunFileDialogCallback in '..\source\uCEFRunFileDialogCallback.pas',
+ uCEFRequestContext in '..\source\uCEFRequestContext.pas',
+ uCEFNavigationEntryVisitor in '..\source\uCEFNavigationEntryVisitor.pas',
+ uCEFStringVisitor in '..\source\uCEFStringVisitor.pas',
+ uCEFv8Context in '..\source\uCEFv8Context.pas',
+ uCEFDomVisitor in '..\source\uCEFDomVisitor.pas',
+ uCEFNavigationEntry in '..\source\uCEFNavigationEntry.pas',
+ uCEFCookieManager in '..\source\uCEFCookieManager.pas',
+ uCEFCompletionCallback in '..\source\uCEFCompletionCallback.pas',
+ uCEFRequestContextHandler in '..\source\uCEFRequestContextHandler.pas',
+ uCEFWebPluginInfo in '..\source\uCEFWebPluginInfo.pas',
+ uCEFDomDocument in '..\source\uCEFDomDocument.pas',
+ uCEFDomNode in '..\source\uCEFDomNode.pas',
+ uCEFv8Value in '..\source\uCEFv8Value.pas',
+ uCEFv8Accessor in '..\source\uCEFv8Accessor.pas',
+ uCEFLoadHandler in '..\source\uCEFLoadHandler.pas',
+ uCEFFocusHandler in '..\source\uCEFFocusHandler.pas',
+ uCEFContextMenuHandler in '..\source\uCEFContextMenuHandler.pas',
+ uCEFDialogHandler in '..\source\uCEFDialogHandler.pas',
+ uCEFKeyboardHandler in '..\source\uCEFKeyboardHandler.pas',
+ uCEFDisplayHandler in '..\source\uCEFDisplayHandler.pas',
+ uCEFDownloadHandler in '..\source\uCEFDownloadHandler.pas',
+ uCEFGeolocationHandler in '..\source\uCEFGeolocationHandler.pas',
+ uCEFJsDialogHandler in '..\source\uCEFJsDialogHandler.pas',
+ uCEFLifeSpanHandler in '..\source\uCEFLifeSpanHandler.pas',
+ uCEFRequestHandler in '..\source\uCEFRequestHandler.pas',
+ uCEFRenderHandler in '..\source\uCEFRenderHandler.pas',
+ uCEFDragHandler in '..\source\uCEFDragHandler.pas',
+ uCEFPostData in '..\source\uCEFPostData.pas',
+ uCEFPostDataElement in '..\source\uCEFPostDataElement.pas',
+ uCEFRequest in '..\source\uCEFRequest.pas',
+ uCEFStreamReader in '..\source\uCEFStreamReader.pas',
+ uCEFWriteHandler in '..\source\uCEFWriteHandler.pas',
+ uCEFStreamWriter in '..\source\uCEFStreamWriter.pas',
+ uCEFv8StackFrame in '..\source\uCEFv8StackFrame.pas',
+ uCEFv8StackTrace in '..\source\uCEFv8StackTrace.pas',
+ uCEFv8Handler in '..\source\uCEFv8Handler.pas',
+ uCEFRequestCallback in '..\source\uCEFRequestCallback.pas',
+ uCEFCustomStreamReader in '..\source\uCEFCustomStreamReader.pas',
+ uCEFCallback in '..\source\uCEFCallback.pas',
+ uCEFResourceHandler in '..\source\uCEFResourceHandler.pas',
+ uCEFSchemeHandlerFactory in '..\source\uCEFSchemeHandlerFactory.pas',
+ uCEFTask in '..\source\uCEFTask.pas',
+ uCEFTaskRunner in '..\source\uCEFTaskRunner.pas',
+ uCEFStringMap in '..\source\uCEFStringMap.pas',
+ uCEFStringMultimap in '..\source\uCEFStringMultimap.pas',
+ uCEFXmlReader in '..\source\uCEFXmlReader.pas',
+ uCEFZipReader in '..\source\uCEFZipReader.pas',
+ uCEFResponse in '..\source\uCEFResponse.pas',
+ uCEFCookieVisitor in '..\source\uCEFCookieVisitor.pas',
+ uCEFV8Exception in '..\source\uCEFV8Exception.pas',
+ uCEFResourceBundleHandler in '..\source\uCEFResourceBundleHandler.pas',
+ uCEFSetCookieCallback in '..\source\uCEFSetCookieCallback.pas',
+ uCEFDeleteCookiesCallback in '..\source\uCEFDeleteCookiesCallback.pas',
+ uCEFDownLoadItem in '..\source\uCEFDownLoadItem.pas',
+ uCEFBeforeDownloadCallback in '..\source\uCEFBeforeDownloadCallback.pas',
+ uCEFDownloadItemCallback in '..\source\uCEFDownloadItemCallback.pas',
+ uCEFAuthCallback in '..\source\uCEFAuthCallback.pas',
+ uCEFJsDialogCallback in '..\source\uCEFJsDialogCallback.pas',
+ uCEFGeolocationCallback in '..\source\uCEFGeolocationCallback.pas',
+ uCEFContextMenuParams in '..\source\uCEFContextMenuParams.pas',
+ uCEFMenuModel in '..\source\uCEFMenuModel.pas',
+ uCEFBrowserProcessHandler in '..\source\uCEFBrowserProcessHandler.pas',
+ uCEFRenderProcessHandler in '..\source\uCEFRenderProcessHandler.pas',
+ uCEFUrlrequestClient in '..\source\uCEFUrlrequestClient.pas',
+ uCEFUrlRequest in '..\source\uCEFUrlRequest.pas',
+ uCEFWebPluginInfoVisitor in '..\source\uCEFWebPluginInfoVisitor.pas',
+ uCEFWebPluginUnstableCallback in '..\source\uCEFWebPluginUnstableCallback.pas',
+ uCEFEndTracingCallback in '..\source\uCEFEndTracingCallback.pas',
+ uCEFGetGeolocationCallback in '..\source\uCEFGetGeolocationCallback.pas',
+ uCEFFileDialogCallback in '..\source\uCEFFileDialogCallback.pas',
+ uCEFDragData in '..\source\uCEFDragData.pas',
+ uCEFResolveCallback in '..\source\uCEFResolveCallback.pas',
+ uCEFPrintSettings in '..\source\uCEFPrintSettings.pas',
+ uCEFSslInfo in '..\source\uCEFSslInfo.pas',
+ uCEFRunContextMenuCallback in '..\source\uCEFRunContextMenuCallback.pas',
+ uCEFResourceBundle in '..\source\uCEFResourceBundle.pas',
+ uCEFResponseFilter in '..\source\uCEFResponseFilter.pas',
+ uCEFImage in '..\source\uCEFImage.pas',
+ uCEFMenuModelDelegate in '..\source\uCEFMenuModelDelegate.pas',
+ uCEFv8Types in '..\source\uCEFv8Types.pas',
+ uCEFWindowParent in '..\source\uCEFWindowParent.pas',
+ uCEFChromium in '..\source\uCEFChromium.pas',
+ uCEFChromiumEvents in '..\source\uCEFChromiumEvents.pas',
+ uCEFChromiumOptions in '..\source\uCEFChromiumOptions.pas',
+ uCEFChromiumFontOptions in '..\source\uCEFChromiumFontOptions.pas',
+ uCEFPDFPrintOptions in '..\source\uCEFPDFPrintOptions.pas',
+ uCEFRegisterCDMCallback in '..\source\uCEFRegisterCDMCallback.pas',
+ uCEFThread in '..\source\uCEFThread.pas',
+ uCEFv8Interceptor in '..\source\uCEFv8Interceptor.pas',
+ uCEFWaitableEvent in '..\source\uCEFWaitableEvent.pas',
+ uCEFX509CertPrincipal in '..\source\uCEFX509CertPrincipal.pas',
+ uCEFX509Certificate in '..\source\uCEFX509Certificate.pas',
+ uCEFSSLStatus in '..\source\uCEFSSLStatus.pas',
+ uCEFSelectClientCertificateCallback in '..\source\uCEFSelectClientCertificateCallback.pas',
+ uCEFChromiumWindow in '..\source\uCEFChromiumWindow.pas',
+ uCEFBaseRefCounted in '..\source\uCEFBaseRefCounted.pas',
+ uCEFBaseScopedWrapper in '..\source\uCEFBaseScopedWrapper.pas',
+ uCEFAccessibilityHandler in '..\source\uCEFAccessibilityHandler.pas',
+ uOLEDragAndDrop in '..\source\uOLEDragAndDrop.pas',
+ uCEFDragAndDropMgr in '..\source\uCEFDragAndDropMgr.pas',
+ uCEFGetExtensionResourceCallback in '..\source\uCEFGetExtensionResourceCallback.pas',
+ uCEFExtension in '..\source\uCEFExtension.pas',
+ uCEFExtensionHandler in '..\source\uCEFExtensionHandler.pas',
+ uBufferPanel in '..\source\uBufferPanel.pas',
+ uCEFApp in '..\source\uCEFApp.pas',
+ uCEFWorkScheduler in '..\source\uCEFWorkScheduler.pas',
+ uCEFWorkSchedulerThread in '..\source\uCEFWorkSchedulerThread.pas',
+ uCEFServer in '..\source\uCEFServer.pas',
+ uCEFServerHandler in '..\source\uCEFServerHandler.pas',
+ uCEFServerEvents in '..\source\uCEFServerEvents.pas',
+ uCEFServerComponent in '..\source\uCEFServerComponent.pas',
+ uFMXBufferPanel in '..\source\uFMXBufferPanel.pas',
+ uFMXChromium in '..\source\uFMXChromium.pas',
+ uFMXWorkScheduler in '..\source\uFMXWorkScheduler.pas';
+
+end.
+
diff --git a/packages/CEF4Delphi_FMX.dproj b/packages/CEF4Delphi_FMX.dproj
new file mode 100644
index 00000000..7d617909
--- /dev/null
+++ b/packages/CEF4Delphi_FMX.dproj
@@ -0,0 +1,672 @@
+
+
+ {2F51F1BD-0529-4B4A-BFD2-86FE96910A62}
+ CEF4Delphi_FMX.dpk
+ 18.2
+ VCL
+ True
+ Debug
+ Win32
+ 1
+ Package
+
+
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Cfg_1
+ true
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Cfg_2
+ true
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Cfg_3
+ true
+ true
+
+
+ All
+ true
+ System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace)
+ CEF4Delphi_FMX
+ true
+ true
+ .\$(Platform)\$(Config)
+ .\$(Platform)\$(Config)
+ false
+ false
+ false
+ false
+ false
+
+
+ rtl;vcl;fmx;$(DCC_UsePackage)
+ 1033
+ Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
+ 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
+
+
+ rtl;vcl;fmx;$(DCC_UsePackage)
+ 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
+
+
+ DEBUG;$(DCC_Define)
+ true
+ false
+ true
+ true
+ true
+
+
+ CompanyName=;FileVersion=1.0.0.0;InternalName=CEF4Delphi;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=CEF4Delphi;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName)
+ CEF4Delphi
+ 1033
+ true
+ false
+
+
+ false
+ RELEASE;$(DCC_Define)
+ 0
+ 0
+
+
+ true
+ 1033
+
+
+ true
+ true
+ 1033
+ true
+ true
+
+
+
+ MainSource
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Base
+
+
+ Cfg_2
+ Base
+
+
+ Cfg_1
+ Base
+
+
+ Cfg_3
+ Base
+
+
+
+ Delphi.Personality.12
+ Package
+
+
+
+ CEF4Delphi_FMX.dpk
+
+
+ IP Abstraction Indy Implementation Design Time
+ Microsoft Office 2000 Sample Automation Server Wrapper Components
+ Microsoft Office XP Sample Automation Server Wrapper Components
+
+
+
+
+
+
+
+
+ CEF4Delphi.bpl
+ true
+
+
+
+
+
+ 1
+
+
+ Contents\MacOS
+ 0
+
+
+
+
+ classes
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ library\lib\armeabi
+ 1
+
+
+
+
+ library\lib\mips
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\values
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+
+
+ res\drawable-ldpi
+ 1
+
+
+
+
+ res\drawable-mdpi
+ 1
+
+
+
+
+ res\drawable-hdpi
+ 1
+
+
+
+
+ res\drawable-xhdpi
+ 1
+
+
+
+
+ res\drawable-small
+ 1
+
+
+
+
+ res\drawable-normal
+ 1
+
+
+
+
+ res\drawable-large
+ 1
+
+
+
+
+ res\drawable-xlarge
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 0
+
+
+
+
+ 1
+ .framework
+
+
+ 0
+
+
+
+
+ 1
+ .dylib
+
+
+ 0
+ .dll;.bpl
+
+
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 0
+ .bpl
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+
+
+ Contents\Resources
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 0
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ False
+
+
+ 12
+
+
+
+
+
diff --git a/packages/CEF4Delphi_FMX.res b/packages/CEF4Delphi_FMX.res
new file mode 100644
index 00000000..0b1d7bfe
Binary files /dev/null and b/packages/CEF4Delphi_FMX.res differ
diff --git a/packages/CEF4Delphi_FMX_Register.pas b/packages/CEF4Delphi_FMX_Register.pas
new file mode 100644
index 00000000..70c4a9bc
--- /dev/null
+++ b/packages/CEF4Delphi_FMX_Register.pas
@@ -0,0 +1,62 @@
+// ************************************************************************
+// ***************************** 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 © 2018 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.
+ *
+ *)
+
+unit CEF4Delphi_FMX_Register;
+
+{$R chromium.dcr}
+
+{$I cef.inc}
+
+interface
+
+procedure Register;
+
+implementation
+
+uses
+ System.Classes,
+ uCEFChromium, uCEFWindowParent, uCEFChromiumWindow, uBufferPanel, uCEFWorkScheduler,
+ uFMXBufferPanel, uFMXChromium, uFMXWorkScheduler, uCEFServerComponent;
+
+procedure Register;
+begin
+ RegisterComponents('Chromium', [TChromium, TCEFWindowParent, TChromiumWindow, TBufferPanel,
+ TFMXBufferPanel, TFMXChromium, TFMXWorkScheduler,
+ TCEFWorkScheduler, TCEFServerComponent]);
+end;
+
+end.
diff --git a/source/uCEFRegisterComponents.pas b/packages/CEF4Delphi_Register.pas
similarity index 98%
rename from source/uCEFRegisterComponents.pas
rename to packages/CEF4Delphi_Register.pas
index 03f5a2d6..1caeb449 100644
--- a/source/uCEFRegisterComponents.pas
+++ b/packages/CEF4Delphi_Register.pas
@@ -35,7 +35,7 @@
*
*)
-unit uCEFRegisterComponents;
+unit CEF4Delphi_Register;
{$R chromium.dcr}
diff --git a/packages/bufferpanel.bmp b/packages/bufferpanel.bmp
new file mode 100644
index 00000000..46d51f4e
Binary files /dev/null and b/packages/bufferpanel.bmp differ
diff --git a/packages/cef.inc b/packages/cef.inc
new file mode 100644
index 00000000..984ae795
--- /dev/null
+++ b/packages/cef.inc
@@ -0,0 +1,384 @@
+// ************************************************************************
+// ***************************** 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.
+ *
+ *)
+
+ // The complete list of compiler versions is here :
+ // http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Compiler_Versions
+
+{$DEFINE DELPHI_VERSION_UNKNOW}
+
+{$IFDEF FPC}
+ {$DEFINE CEF_MULTI_THREADED_MESSAGE_LOOP}
+ {$DEFINE SUPPORTS_INLINE}
+{$ENDIF}
+
+// 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
+{$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}
+
+
+{$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}
+{$ENDIF}
+
+{$IFDEF DELPHI9_UP}
+ {$DEFINE SUPPORTS_INLINE}
+{$ENDIF}
+
diff --git a/source/chromium.bmp b/packages/chromium.bmp
similarity index 100%
rename from source/chromium.bmp
rename to packages/chromium.bmp
diff --git a/packages/chromium.dcr b/packages/chromium.dcr
new file mode 100644
index 00000000..9aadbeb3
Binary files /dev/null and b/packages/chromium.dcr differ
diff --git a/packages/chromium.rc b/packages/chromium.rc
new file mode 100644
index 00000000..ebd5fea0
--- /dev/null
+++ b/packages/chromium.rc
@@ -0,0 +1,9 @@
+TChromium BITMAP "chromium.bmp"
+TFMXChromium BITMAP "chromium.bmp"
+TCEFWindowParent BITMAP "windowparent.bmp"
+TChromiumWindow BITMAP "chromiumwindow.bmp"
+TBufferPanel BITMAP "bufferpanel.bmp"
+TFMXBufferPanel BITMAP "bufferpanel.bmp"
+TCEFWorkScheduler BITMAP "workscheduler.bmp"
+TFMXWorkScheduler BITMAP "workscheduler.bmp"
+TCEFServerComponent BITMAP "server.bmp"
\ No newline at end of file
diff --git a/packages/chromiumwindow.bmp b/packages/chromiumwindow.bmp
new file mode 100644
index 00000000..b3491459
Binary files /dev/null and b/packages/chromiumwindow.bmp differ
diff --git a/source/dcu/placeholder.txt b/packages/dcu/placeholder.txt
similarity index 100%
rename from source/dcu/placeholder.txt
rename to packages/dcu/placeholder.txt
diff --git a/packages/server.bmp b/packages/server.bmp
new file mode 100644
index 00000000..f19ceb46
Binary files /dev/null and b/packages/server.bmp differ
diff --git a/packages/windowparent.bmp b/packages/windowparent.bmp
new file mode 100644
index 00000000..0e45ae08
Binary files /dev/null and b/packages/windowparent.bmp differ
diff --git a/packages/workscheduler.bmp b/packages/workscheduler.bmp
new file mode 100644
index 00000000..d38ba709
Binary files /dev/null and b/packages/workscheduler.bmp differ
diff --git a/source/CEF4Delphi.dpk b/source/CEF4Delphi.dpk
deleted file mode 100644
index 978e18a0..00000000
--- a/source/CEF4Delphi.dpk
+++ /dev/null
@@ -1,169 +0,0 @@
-package CEF4Delphi;
-
-{$R *.res}
-{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
-{$ALIGN 8}
-{$ASSERTIONS ON}
-{$BOOLEVAL OFF}
-{$DEBUGINFO OFF}
-{$EXTENDEDSYNTAX ON}
-{$IMPORTEDDATA ON}
-{$IOCHECKS ON}
-{$LOCALSYMBOLS ON}
-{$LONGSTRINGS ON}
-{$OPENSTRINGS ON}
-{$OPTIMIZATION OFF}
-{$OVERFLOWCHECKS OFF}
-{$RANGECHECKS OFF}
-{$REFERENCEINFO ON}
-{$SAFEDIVIDE OFF}
-{$STACKFRAMES ON}
-{$TYPEDADDRESS OFF}
-{$VARSTRINGCHECKS ON}
-{$WRITEABLECONST OFF}
-{$MINENUMSIZE 1}
-{$IMAGEBASE $400000}
-{$DEFINE DEBUG}
-{$ENDIF IMPLICITBUILDING}
-{$DESCRIPTION 'CEF4Delphi'}
-{$IMPLICITBUILD OFF}
-
-requires
- rtl,
- vcl;
-
-contains
- uCEFRegisterComponents in 'uCEFRegisterComponents.pas',
- uCEFFindHandler in 'uCEFFindHandler.pas',
- uCEFConstants in 'uCEFConstants.pas',
- uCEFTypes in 'uCEFTypes.pas',
- uCEFInterfaces in 'uCEFInterfaces.pas',
- uCEFMiscFunctions in 'uCEFMiscFunctions.pas',
- uCEFLibFunctions in 'uCEFLibFunctions.pas',
- uCEFApplication in 'uCEFApplication.pas',
- uCEFSchemeRegistrar in 'uCEFSchemeRegistrar.pas',
- uCEFCommandLine in 'uCEFCommandLine.pas',
- uCEFClient in 'uCEFClient.pas',
- uCEFProcessMessage in 'uCEFProcessMessage.pas',
- uCEFBrowser in 'uCEFBrowser.pas',
- uCEFListValue in 'uCEFListValue.pas',
- uCEFBinaryValue in 'uCEFBinaryValue.pas',
- uCEFValue in 'uCEFValue.pas',
- uCEFDictionaryValue in 'uCEFDictionaryValue.pas',
- uCEFDownloadImageCallBack in 'uCEFDownloadImageCallBack.pas',
- uCEFFrame in 'uCEFFrame.pas',
- uCEFPDFPrintCallback in 'uCEFPDFPrintCallback.pas',
- uCEFRunFileDialogCallback in 'uCEFRunFileDialogCallback.pas',
- uCEFRequestContext in 'uCEFRequestContext.pas',
- uCEFNavigationEntryVisitor in 'uCEFNavigationEntryVisitor.pas',
- uCEFStringVisitor in 'uCEFStringVisitor.pas',
- uCEFv8Context in 'uCEFv8Context.pas',
- uCEFDomVisitor in 'uCEFDomVisitor.pas',
- uCEFNavigationEntry in 'uCEFNavigationEntry.pas',
- uCEFCookieManager in 'uCEFCookieManager.pas',
- uCEFCompletionCallback in 'uCEFCompletionCallback.pas',
- uCEFRequestContextHandler in 'uCEFRequestContextHandler.pas',
- uCEFWebPluginInfo in 'uCEFWebPluginInfo.pas',
- uCEFDomDocument in 'uCEFDomDocument.pas',
- uCEFDomNode in 'uCEFDomNode.pas',
- uCEFv8Value in 'uCEFv8Value.pas',
- uCEFv8Accessor in 'uCEFv8Accessor.pas',
- uCEFLoadHandler in 'uCEFLoadHandler.pas',
- uCEFFocusHandler in 'uCEFFocusHandler.pas',
- uCEFContextMenuHandler in 'uCEFContextMenuHandler.pas',
- uCEFDialogHandler in 'uCEFDialogHandler.pas',
- uCEFKeyboardHandler in 'uCEFKeyboardHandler.pas',
- uCEFDisplayHandler in 'uCEFDisplayHandler.pas',
- uCEFDownloadHandler in 'uCEFDownloadHandler.pas',
- uCEFGeolocationHandler in 'uCEFGeolocationHandler.pas',
- uCEFJsDialogHandler in 'uCEFJsDialogHandler.pas',
- uCEFLifeSpanHandler in 'uCEFLifeSpanHandler.pas',
- uCEFRequestHandler in 'uCEFRequestHandler.pas',
- uCEFRenderHandler in 'uCEFRenderHandler.pas',
- uCEFDragHandler in 'uCEFDragHandler.pas',
- uCEFPostData in 'uCEFPostData.pas',
- uCEFPostDataElement in 'uCEFPostDataElement.pas',
- uCEFRequest in 'uCEFRequest.pas',
- uCEFStreamReader in 'uCEFStreamReader.pas',
- uCEFWriteHandler in 'uCEFWriteHandler.pas',
- uCEFStreamWriter in 'uCEFStreamWriter.pas',
- uCEFv8StackFrame in 'uCEFv8StackFrame.pas',
- uCEFv8StackTrace in 'uCEFv8StackTrace.pas',
- uCEFv8Handler in 'uCEFv8Handler.pas',
- uCEFRequestCallback in 'uCEFRequestCallback.pas',
- uCEFCustomStreamReader in 'uCEFCustomStreamReader.pas',
- uCEFCallback in 'uCEFCallback.pas',
- uCEFResourceHandler in 'uCEFResourceHandler.pas',
- uCEFSchemeHandlerFactory in 'uCEFSchemeHandlerFactory.pas',
- uCEFTask in 'uCEFTask.pas',
- uCEFTaskRunner in 'uCEFTaskRunner.pas',
- uCEFStringMap in 'uCEFStringMap.pas',
- uCEFStringMultimap in 'uCEFStringMultimap.pas',
- uCEFXmlReader in 'uCEFXmlReader.pas',
- uCEFZipReader in 'uCEFZipReader.pas',
- uCEFResponse in 'uCEFResponse.pas',
- uCEFCookieVisitor in 'uCEFCookieVisitor.pas',
- uCEFV8Exception in 'uCEFV8Exception.pas',
- uCEFResourceBundleHandler in 'uCEFResourceBundleHandler.pas',
- uCEFSetCookieCallback in 'uCEFSetCookieCallback.pas',
- uCEFDeleteCookiesCallback in 'uCEFDeleteCookiesCallback.pas',
- uCEFDownLoadItem in 'uCEFDownLoadItem.pas',
- uCEFBeforeDownloadCallback in 'uCEFBeforeDownloadCallback.pas',
- uCEFDownloadItemCallback in 'uCEFDownloadItemCallback.pas',
- uCEFAuthCallback in 'uCEFAuthCallback.pas',
- uCEFJsDialogCallback in 'uCEFJsDialogCallback.pas',
- uCEFGeolocationCallback in 'uCEFGeolocationCallback.pas',
- uCEFContextMenuParams in 'uCEFContextMenuParams.pas',
- uCEFMenuModel in 'uCEFMenuModel.pas',
- uCEFBrowserProcessHandler in 'uCEFBrowserProcessHandler.pas',
- uCEFRenderProcessHandler in 'uCEFRenderProcessHandler.pas',
- uCEFUrlrequestClient in 'uCEFUrlrequestClient.pas',
- uCEFUrlRequest in 'uCEFUrlRequest.pas',
- uCEFWebPluginInfoVisitor in 'uCEFWebPluginInfoVisitor.pas',
- uCEFWebPluginUnstableCallback in 'uCEFWebPluginUnstableCallback.pas',
- uCEFEndTracingCallback in 'uCEFEndTracingCallback.pas',
- uCEFGetGeolocationCallback in 'uCEFGetGeolocationCallback.pas',
- uCEFFileDialogCallback in 'uCEFFileDialogCallback.pas',
- uCEFDragData in 'uCEFDragData.pas',
- uCEFResolveCallback in 'uCEFResolveCallback.pas',
- uCEFPrintSettings in 'uCEFPrintSettings.pas',
- uCEFSslInfo in 'uCEFSslInfo.pas',
- uCEFRunContextMenuCallback in 'uCEFRunContextMenuCallback.pas',
- uCEFResourceBundle in 'uCEFResourceBundle.pas',
- uCEFResponseFilter in 'uCEFResponseFilter.pas',
- uCEFImage in 'uCEFImage.pas',
- uCEFMenuModelDelegate in 'uCEFMenuModelDelegate.pas',
- uCEFv8Types in 'uCEFv8Types.pas',
- uCEFWindowParent in 'uCEFWindowParent.pas',
- uCEFChromium in 'uCEFChromium.pas',
- uCEFChromiumEvents in 'uCEFChromiumEvents.pas',
- uCEFChromiumOptions in 'uCEFChromiumOptions.pas',
- uCEFChromiumFontOptions in 'uCEFChromiumFontOptions.pas',
- uCEFPDFPrintOptions in 'uCEFPDFPrintOptions.pas',
- uCEFRegisterCDMCallback in 'uCEFRegisterCDMCallback.pas',
- uCEFThread in 'uCEFThread.pas',
- uCEFv8Interceptor in 'uCEFv8Interceptor.pas',
- uCEFWaitableEvent in 'uCEFWaitableEvent.pas',
- uCEFX509CertPrincipal in 'uCEFX509CertPrincipal.pas',
- uCEFX509Certificate in 'uCEFX509Certificate.pas',
- uCEFSSLStatus in 'uCEFSSLStatus.pas',
- uCEFSelectClientCertificateCallback in 'uCEFSelectClientCertificateCallback.pas',
- uCEFChromiumWindow in 'uCEFChromiumWindow.pas',
- uCEFBaseRefCounted in 'uCEFBaseRefCounted.pas',
- uCEFBaseScopedWrapper in 'uCEFBaseScopedWrapper.pas',
- uCEFAccessibilityHandler in 'uCEFAccessibilityHandler.pas',
- uOLEDragAndDrop in 'uOLEDragAndDrop.pas',
- uCEFDragAndDropMgr in 'uCEFDragAndDropMgr.pas',
- uCEFGetExtensionResourceCallback in 'uCEFGetExtensionResourceCallback.pas',
- uCEFExtension in 'uCEFExtension.pas',
- uCEFExtensionHandler in 'uCEFExtensionHandler.pas',
- uBufferPanel in 'uBufferPanel.pas',
- uCEFApp in 'uCEFApp.pas',
- uCEFWorkScheduler in 'uCEFWorkScheduler.pas',
- uCEFServer in 'uCEFServer.pas',
- uCEFServerHandler in 'uCEFServerHandler.pas',
- uCEFServerEvents in 'uCEFServerEvents.pas',
- uCEFServerComponent in 'uCEFServerComponent.pas';
-
-end.
-
diff --git a/source/CEF4Delphi_D7.dpk b/source/CEF4Delphi_D7.dpk
deleted file mode 100644
index b7c3f4a6..00000000
--- a/source/CEF4Delphi_D7.dpk
+++ /dev/null
@@ -1,165 +0,0 @@
-package CEF4Delphi_D7;
-
-{$R *.res}
-{$ALIGN 8}
-{$ASSERTIONS ON}
-{$BOOLEVAL OFF}
-{$DEBUGINFO OFF}
-{$EXTENDEDSYNTAX ON}
-{$IMPORTEDDATA ON}
-{$IOCHECKS ON}
-{$LOCALSYMBOLS ON}
-{$LONGSTRINGS ON}
-{$OPENSTRINGS ON}
-{$OPTIMIZATION OFF}
-{$OVERFLOWCHECKS OFF}
-{$RANGECHECKS OFF}
-{$REFERENCEINFO ON}
-{$SAFEDIVIDE OFF}
-{$STACKFRAMES ON}
-{$TYPEDADDRESS OFF}
-{$VARSTRINGCHECKS ON}
-{$WRITEABLECONST OFF}
-{$MINENUMSIZE 1}
-{$IMAGEBASE $400000}
-{$DESCRIPTION 'CEF4Delphi'}
-{$IMPLICITBUILD OFF}
-{$DEFINE DEBUG}
-
-requires
- rtl,
- vcl;
-
-contains
- uCEFRegisterComponents in 'uCEFRegisterComponents.pas',
- uCEFFindHandler in 'uCEFFindHandler.pas',
- uCEFConstants in 'uCEFConstants.pas',
- uCEFTypes in 'uCEFTypes.pas',
- uCEFInterfaces in 'uCEFInterfaces.pas',
- uCEFMiscFunctions in 'uCEFMiscFunctions.pas',
- uCEFLibFunctions in 'uCEFLibFunctions.pas',
- uCEFApplication in 'uCEFApplication.pas',
- uCEFSchemeRegistrar in 'uCEFSchemeRegistrar.pas',
- uCEFCommandLine in 'uCEFCommandLine.pas',
- uCEFClient in 'uCEFClient.pas',
- uCEFProcessMessage in 'uCEFProcessMessage.pas',
- uCEFBrowser in 'uCEFBrowser.pas',
- uCEFListValue in 'uCEFListValue.pas',
- uCEFBinaryValue in 'uCEFBinaryValue.pas',
- uCEFValue in 'uCEFValue.pas',
- uCEFDictionaryValue in 'uCEFDictionaryValue.pas',
- uCEFDownloadImageCallBack in 'uCEFDownloadImageCallBack.pas',
- uCEFFrame in 'uCEFFrame.pas',
- uCEFPDFPrintCallback in 'uCEFPDFPrintCallback.pas',
- uCEFRunFileDialogCallback in 'uCEFRunFileDialogCallback.pas',
- uCEFRequestContext in 'uCEFRequestContext.pas',
- uCEFNavigationEntryVisitor in 'uCEFNavigationEntryVisitor.pas',
- uCEFStringVisitor in 'uCEFStringVisitor.pas',
- uCEFv8Context in 'uCEFv8Context.pas',
- uCEFDomVisitor in 'uCEFDomVisitor.pas',
- uCEFNavigationEntry in 'uCEFNavigationEntry.pas',
- uCEFCookieManager in 'uCEFCookieManager.pas',
- uCEFCompletionCallback in 'uCEFCompletionCallback.pas',
- uCEFRequestContextHandler in 'uCEFRequestContextHandler.pas',
- uCEFWebPluginInfo in 'uCEFWebPluginInfo.pas',
- uCEFDomDocument in 'uCEFDomDocument.pas',
- uCEFDomNode in 'uCEFDomNode.pas',
- uCEFv8Value in 'uCEFv8Value.pas',
- uCEFv8Accessor in 'uCEFv8Accessor.pas',
- uCEFLoadHandler in 'uCEFLoadHandler.pas',
- uCEFFocusHandler in 'uCEFFocusHandler.pas',
- uCEFContextMenuHandler in 'uCEFContextMenuHandler.pas',
- uCEFDialogHandler in 'uCEFDialogHandler.pas',
- uCEFKeyboardHandler in 'uCEFKeyboardHandler.pas',
- uCEFDisplayHandler in 'uCEFDisplayHandler.pas',
- uCEFDownloadHandler in 'uCEFDownloadHandler.pas',
- uCEFGeolocationHandler in 'uCEFGeolocationHandler.pas',
- uCEFJsDialogHandler in 'uCEFJsDialogHandler.pas',
- uCEFLifeSpanHandler in 'uCEFLifeSpanHandler.pas',
- uCEFRequestHandler in 'uCEFRequestHandler.pas',
- uCEFRenderHandler in 'uCEFRenderHandler.pas',
- uCEFDragHandler in 'uCEFDragHandler.pas',
- uCEFPostData in 'uCEFPostData.pas',
- uCEFPostDataElement in 'uCEFPostDataElement.pas',
- uCEFRequest in 'uCEFRequest.pas',
- uCEFStreamReader in 'uCEFStreamReader.pas',
- uCEFWriteHandler in 'uCEFWriteHandler.pas',
- uCEFStreamWriter in 'uCEFStreamWriter.pas',
- uCEFv8StackFrame in 'uCEFv8StackFrame.pas',
- uCEFv8StackTrace in 'uCEFv8StackTrace.pas',
- uCEFv8Handler in 'uCEFv8Handler.pas',
- uCEFRequestCallback in 'uCEFRequestCallback.pas',
- uCEFCustomStreamReader in 'uCEFCustomStreamReader.pas',
- uCEFCallback in 'uCEFCallback.pas',
- uCEFResourceHandler in 'uCEFResourceHandler.pas',
- uCEFSchemeHandlerFactory in 'uCEFSchemeHandlerFactory.pas',
- uCEFTask in 'uCEFTask.pas',
- uCEFTaskRunner in 'uCEFTaskRunner.pas',
- uCEFStringMap in 'uCEFStringMap.pas',
- uCEFStringMultimap in 'uCEFStringMultimap.pas',
- uCEFXmlReader in 'uCEFXmlReader.pas',
- uCEFZipReader in 'uCEFZipReader.pas',
- uCEFResponse in 'uCEFResponse.pas',
- uCEFCookieVisitor in 'uCEFCookieVisitor.pas',
- uCEFV8Exception in 'uCEFV8Exception.pas',
- uCEFResourceBundleHandler in 'uCEFResourceBundleHandler.pas',
- uCEFSetCookieCallback in 'uCEFSetCookieCallback.pas',
- uCEFDeleteCookiesCallback in 'uCEFDeleteCookiesCallback.pas',
- uCEFDownLoadItem in 'uCEFDownLoadItem.pas',
- uCEFBeforeDownloadCallback in 'uCEFBeforeDownloadCallback.pas',
- uCEFDownloadItemCallback in 'uCEFDownloadItemCallback.pas',
- uCEFAuthCallback in 'uCEFAuthCallback.pas',
- uCEFJsDialogCallback in 'uCEFJsDialogCallback.pas',
- uCEFGeolocationCallback in 'uCEFGeolocationCallback.pas',
- uCEFContextMenuParams in 'uCEFContextMenuParams.pas',
- uCEFMenuModel in 'uCEFMenuModel.pas',
- uCEFBrowserProcessHandler in 'uCEFBrowserProcessHandler.pas',
- uCEFRenderProcessHandler in 'uCEFRenderProcessHandler.pas',
- uCEFUrlrequestClient in 'uCEFUrlrequestClient.pas',
- uCEFUrlRequest in 'uCEFUrlRequest.pas',
- uCEFWebPluginInfoVisitor in 'uCEFWebPluginInfoVisitor.pas',
- uCEFWebPluginUnstableCallback in 'uCEFWebPluginUnstableCallback.pas',
- uCEFEndTracingCallback in 'uCEFEndTracingCallback.pas',
- uCEFGetGeolocationCallback in 'uCEFGetGeolocationCallback.pas',
- uCEFFileDialogCallback in 'uCEFFileDialogCallback.pas',
- uCEFDragData in 'uCEFDragData.pas',
- uCEFResolveCallback in 'uCEFResolveCallback.pas',
- uCEFPrintSettings in 'uCEFPrintSettings.pas',
- uCEFSslInfo in 'uCEFSslInfo.pas',
- uCEFRunContextMenuCallback in 'uCEFRunContextMenuCallback.pas',
- uCEFResourceBundle in 'uCEFResourceBundle.pas',
- uCEFResponseFilter in 'uCEFResponseFilter.pas',
- uCEFImage in 'uCEFImage.pas',
- uCEFMenuModelDelegate in 'uCEFMenuModelDelegate.pas',
- uCEFv8Types in 'uCEFv8Types.pas',
- uCEFWindowParent in 'uCEFWindowParent.pas',
- uCEFChromium in 'uCEFChromium.pas',
- uCEFChromiumEvents in 'uCEFChromiumEvents.pas',
- uCEFChromiumOptions in 'uCEFChromiumOptions.pas',
- uCEFChromiumFontOptions in 'uCEFChromiumFontOptions.pas',
- uCEFPDFPrintOptions in 'uCEFPDFPrintOptions.pas',
- uCEFRegisterCDMCallback in 'uCEFRegisterCDMCallback.pas',
- uCEFThread in 'uCEFThread.pas',
- uCEFv8Interceptor in 'uCEFv8Interceptor.pas',
- uCEFWaitableEvent in 'uCEFWaitableEvent.pas',
- uCEFX509CertPrincipal in 'uCEFX509CertPrincipal.pas',
- uCEFX509Certificate in 'uCEFX509Certificate.pas',
- uCEFSSLStatus in 'uCEFSSLStatus.pas',
- uCEFSelectClientCertificateCallback in 'uCEFSelectClientCertificateCallback.pas',
- uCEFChromiumWindow in 'uCEFChromiumWindow.pas',
- uCEFBaseRefCounted in 'uCEFBaseRefCounted.pas',
- uCEFBaseScopedWrapper in 'uCEFBaseScopedWrapper.pas',
- uCEFDragAndDropMgr in 'uCEFDragAndDropMgr.pas',
- uOLEDragAndDrop in 'uOLEDragAndDrop.pas',
- uCEFGetExtensionResourceCallback in 'uCEFGetExtensionResourceCallback.pas',
- uCEFExtension in 'uCEFExtension.pas',
- uCEFExtensionHandler in 'uCEFExtensionHandler.pas',
- uBufferPanel in 'uBufferPanel.pas',
- uCEFApp in 'uCEFApp.pas',
- uCEFWorkScheduler in 'uCEFWorkScheduler.pas',
- uCEFServer in 'uCEFServer.pas',
- uCEFServerHandler in 'uCEFServerHandler.pas',
- uCEFServerEvents in 'uCEFServerEvents.pas',
- uCEFServerComponent in 'uCEFServerComponent.pas';
-
-end.
diff --git a/source/CEF4Delphi_D7.res b/source/CEF4Delphi_D7.res
deleted file mode 100644
index 7012acd9..00000000
Binary files a/source/CEF4Delphi_D7.res and /dev/null differ
diff --git a/source/chromium.dcr b/source/chromium.dcr
deleted file mode 100644
index f58c4ec9..00000000
Binary files a/source/chromium.dcr and /dev/null differ
diff --git a/source/chromium.rc b/source/chromium.rc
deleted file mode 100644
index 135b2d41..00000000
--- a/source/chromium.rc
+++ /dev/null
@@ -1,2 +0,0 @@
-TChromium BITMAP "chromium.bmp"
-TChromiumWindow BITMAP "chromium.bmp"
\ No newline at end of file
diff --git a/source/uBufferPanel.pas b/source/uBufferPanel.pas
index a7ec4125..2055aa28 100644
--- a/source/uBufferPanel.pas
+++ b/source/uBufferPanel.pas
@@ -57,9 +57,9 @@ type
FBuffer : TBitmap;
FScanlineSize : integer;
- procedure CreateBufferMutex;
+ procedure CreateSyncObj;
- procedure DestroyBufferMutex;
+ procedure DestroySyncObj;
procedure DestroyBuffer;
function GetBufferBits : pointer;
@@ -192,7 +192,7 @@ end;
destructor TBufferPanel.Destroy;
begin
DestroyBuffer;
- DestroyBufferMutex;
+ DestroySyncObj;
inherited Destroy;
end;
@@ -201,15 +201,15 @@ procedure TBufferPanel.AfterConstruction;
begin
inherited AfterConstruction;
- CreateBufferMutex;
+ CreateSyncObj;
end;
-procedure TBufferPanel.CreateBufferMutex;
+procedure TBufferPanel.CreateSyncObj;
begin
FMutex := CreateMutex(nil, False, nil);
end;
-procedure TBufferPanel.DestroyBufferMutex;
+procedure TBufferPanel.DestroySyncObj;
begin
if (FMutex <> 0) then
begin
@@ -359,18 +359,35 @@ begin
end;
function TBufferPanel.BufferIsResized(aUseMutex : boolean) : boolean;
+var
+ TempDevWidth, TempLogWidth, TempDevHeight, TempLogHeight : integer;
begin
Result := False;
if not(aUseMutex) or BeginBufferDraw then
begin
- // CEF and Chromium use 'floor' to round the float values in Device <-> Logical unit conversions
- // and Delphi uses MulDiv, which uses the bankers rounding, to resize the components in high DPI mode.
- // This is the cause of slight differences in size between the buffer and the panel in some occasions.
+ if (GlobalCEFApp.DeviceScaleFactor = 1) then
+ begin
+ Result := (FBuffer <> nil) and
+ (FBuffer.Width = Width) and
+ (FBuffer.Height = Height);
+ end
+ else
+ begin
+ // CEF and Chromium use 'floor' to round the float values in Device <-> Logical unit conversions
+ // and Delphi uses MulDiv, which uses the bankers rounding, to resize the components in high DPI mode.
+ // This is the cause of slight differences in size between the buffer and the panel in some occasions.
- Result := (FBuffer <> nil) and
- (FBuffer.Width = LogicalToDevice(DeviceToLogical(Width, GlobalCEFApp.DeviceScaleFactor), GlobalCEFApp.DeviceScaleFactor)) and
- (FBuffer.Height = LogicalToDevice(DeviceToLogical(Height, GlobalCEFApp.DeviceScaleFactor), GlobalCEFApp.DeviceScaleFactor));
+ TempLogWidth := DeviceToLogical(Width, GlobalCEFApp.DeviceScaleFactor);
+ TempLogHeight := DeviceToLogical(Height, GlobalCEFApp.DeviceScaleFactor);
+
+ TempDevWidth := LogicalToDevice(TempLogWidth, GlobalCEFApp.DeviceScaleFactor);
+ TempDevHeight := LogicalToDevice(TempLogHeight, GlobalCEFApp.DeviceScaleFactor);
+
+ Result := (FBuffer <> nil) and
+ (FBuffer.Width = TempDevWidth) and
+ (FBuffer.Height = TempDevHeight);
+ end;
if aUseMutex then EndBufferDraw;
end;
diff --git a/source/uCEFApplication.pas b/source/uCEFApplication.pas
index 79eb8adf..a24c16ae 100644
--- a/source/uCEFApplication.pas
+++ b/source/uCEFApplication.pas
@@ -124,6 +124,7 @@ type
FSetCurrentDir : boolean;
FGlobalContextInitialized : boolean;
FSitePerProcess : boolean;
+ FDisableWebSecurity : boolean;
FChromeVersionInfo : TFileVersionInfo;
FLibHandle : THandle;
FOnRegisterCustomSchemes : TOnRegisterCustomSchemes;
@@ -327,6 +328,7 @@ type
property EnableHighDPISupport : boolean read FEnableHighDPISupport write FEnableHighDPISupport;
property MuteAudio : boolean read FMuteAudio write FMuteAudio;
property SitePerProcess : boolean read FSitePerProcess write FSitePerProcess;
+ property DisableWebSecurity : boolean read FDisableWebSecurity write FDisableWebSecurity;
property ReRaiseExceptions : boolean read FReRaiseExceptions write FReRaiseExceptions;
property DeviceScaleFactor : single read FDeviceScaleFactor;
property CheckDevToolsResources : boolean read FCheckDevToolsResources write FCheckDevToolsResources;
@@ -380,9 +382,9 @@ implementation
uses
{$IFDEF DELPHI16_UP}
- System.Math, System.IOUtils, System.SysUtils, Vcl.Dialogs,
+ System.Math, System.IOUtils, System.SysUtils,
{$ELSE}
- Math, {$IFDEF DELPHI14_UP}IOUtils,{$ENDIF} SysUtils, Dialogs,
+ Math, {$IFDEF DELPHI14_UP}IOUtils,{$ENDIF} SysUtils,
{$ENDIF}
uCEFLibFunctions, uCEFMiscFunctions, uCEFCommandLine, uCEFConstants,
uCEFSchemeHandlerFactory, uCEFCookieManager, uCEFApp,
@@ -443,6 +445,7 @@ begin
FEnableHighDPISupport := False;
FMuteAudio := False;
FSitePerProcess := True;
+ FDisableWebSecurity := False;
FReRaiseExceptions := False;
FLibLoaded := False;
FShowMessageDlg := True;
@@ -960,7 +963,12 @@ procedure TCefApplication.ShowErrorMessageDlg(const aError : string);
begin
OutputDebugMessage(aError);
- if FShowMessageDlg then MessageDlg(aError, mtError, [mbOk], 0);
+ if FShowMessageDlg then
+ begin
+ {$IFDEF MSWINDOWS}
+ MessageBox(0, PChar(aError + #0), PChar('Error' + #0), MB_ICONERROR or MB_OK or MB_TOPMOST);
+ {$ENDIF}
+ end;
end;
function TCefApplication.ParseProcessType : TCefProcessType;
@@ -1163,6 +1171,9 @@ begin
if FMuteAudio then
commandLine.AppendSwitch('--mute-audio');
+ if FDisableWebSecurity then
+ commandLine.AppendSwitch('--disable-web-security');
+
if FSitePerProcess then
commandLine.AppendSwitch('--site-per-process');
diff --git a/source/uCEFChromium.pas b/source/uCEFChromium.pas
index 4da26436..5388a5db 100644
--- a/source/uCEFChromium.pas
+++ b/source/uCEFChromium.pas
@@ -419,10 +419,25 @@ type
// ICefFindHandler
procedure doOnFindResult(const browser: ICefBrowser; identifier, count: Integer; const selectionRect: PCefRect; activeMatchOrdinal: Integer; finalUpdate: Boolean); virtual;
+ // Custom
+ procedure doCookiesDeleted(numDeleted : integer); virtual;
+ procedure doGetHTML(const aFrameName : ustring); overload;
+ procedure doGetHTML(const aFrame : ICefFrame); overload;
+ procedure doGetHTML(const aFrameIdentifier : int64); overload;
+ procedure doGetText(const aFrameName : ustring); overload;
+ procedure doGetText(const aFrame : ICefFrame); overload;
+ procedure doGetText(const aFrameIdentifier : int64); overload;
+ procedure doPdfPrintFinished(aResultOK : boolean); virtual;
+ procedure doTextResultAvailable(const aText : string); virtual;
+ procedure doUpdatePreferences; virtual;
+ function doSavePreferences : boolean; virtual;
+ procedure doResolvedHostAvailable(result: TCefErrorCode; const resolvedIps: TStrings); virtual;
+
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure AfterConstruction; override;
+ procedure BeforeDestruction; override;
function CreateClientHandler(aIsOSR : boolean) : boolean; overload;
function CreateClientHandler(var aClient : ICefClient) : boolean; overload;
procedure CloseBrowser(aForceClose : boolean);
@@ -432,21 +447,6 @@ type
procedure InitializeDragAndDrop(const aDropTargetCtrl : TWinControl);
procedure ShutdownDragAndDrop;
- // Internal procedures.
- // Only tasks, visitors or callbacks should use them in the right thread/process.
- procedure Internal_CookiesDeleted(numDeleted : integer);
- procedure Internal_GetHTML(const aFrameName : ustring); overload;
- procedure Internal_GetHTML(const aFrame : ICefFrame); overload;
- procedure Internal_GetHTML(const aFrameIdentifier : int64); overload;
- procedure Internal_GetText(const aFrameName : ustring); overload;
- procedure Internal_GetText(const aFrame : ICefFrame); overload;
- procedure Internal_GetText(const aFrameIdentifier : int64); overload;
- procedure Internal_PdfPrintFinished(aResultOK : boolean);
- procedure Internal_TextResultAvailable(const aText : string);
- procedure Internal_UpdatePreferences; virtual;
- function Internal_SavePreferences : boolean;
- procedure Internal_ResolvedHostAvailable(result: TCefErrorCode; const resolvedIps: TStrings);
-
procedure LoadURL(const aURL : ustring);
procedure LoadString(const aString : ustring; const aURL : ustring = '');
procedure LoadRequest(const aRequest: ICefRequest);
@@ -774,12 +774,6 @@ begin
ClearBrowserReference;
- DestroyClientHandler;
- DestroyVisitor;
- DestroyPDFPrintcb;
- DestroyResolveHostcb;
- DestroyCookiDeletercb;
-
if (FFontOptions <> nil) then FreeAndNil(FFontOptions);
if (FOptions <> nil) then FreeAndNil(FOptions);
if (FPDFPrintOptions <> nil) then FreeAndNil(FPDFPrintOptions);
@@ -792,6 +786,17 @@ begin
end;
end;
+procedure TChromium.BeforeDestruction;
+begin
+ DestroyClientHandler;
+ DestroyVisitor;
+ DestroyPDFPrintcb;
+ DestroyResolveHostcb;
+ DestroyCookiDeletercb;
+
+ inherited BeforeDestruction;
+end;
+
procedure TChromium.ClearBrowserReference;
begin
FBrowser := nil;
@@ -800,47 +805,72 @@ end;
procedure TChromium.DestroyClientHandler;
begin
- if (FHandler <> nil) then
- begin
- FHandler.InitializeVars;
- FHandler := nil;
- end;
+ try
+ if (FHandler <> nil) then
+ begin
+ FHandler.InitializeVars;
+ FHandler := nil;
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TChromium.DestroyClientHandler', e) then raise;
+ end;
end;
procedure TChromium.DestroyVisitor;
begin
- if (FVisitor <> nil) then
- begin
- FVisitor.InitializeVars;
- FVisitor := nil;
- end;
+ try
+ if (FVisitor <> nil) then
+ begin
+ FVisitor.InitializeVars;
+ FVisitor := nil;
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TChromium.DestroyVisitor', e) then raise;
+ end;
end;
procedure TChromium.DestroyPDFPrintcb;
begin
- if (FPDFPrintcb <> nil) then
- begin
- FPDFPrintcb.InitializeVars;
- FPDFPrintcb := nil;
- end;
+ try
+ if (FPDFPrintcb <> nil) then
+ begin
+ FPDFPrintcb.InitializeVars;
+ FPDFPrintcb := nil;
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TChromium.DestroyPDFPrintcb', e) then raise;
+ end;
end;
procedure TChromium.DestroyResolveHostcb;
begin
- if (FResolveHostcb <> nil) then
- begin
- FResolveHostcb.InitializeVars;
- FResolveHostcb := nil;
- end;
+ try
+ if (FResolveHostcb <> nil) then
+ begin
+ FResolveHostcb.InitializeVars;
+ FResolveHostcb := nil;
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TChromium.DestroyResolveHostcb', e) then raise;
+ end;
end;
procedure TChromium.DestroyCookiDeletercb;
begin
- if (FCookiDeletercb <> nil) then
- begin
- FCookiDeletercb.InitializeVars;
- FCookiDeletercb := nil;
- end;
+ try
+ if (FCookiDeletercb <> nil) then
+ begin
+ FCookiDeletercb.InitializeVars;
+ FCookiDeletercb := nil;
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TChromium.DestroyCookiDeletercb', e) then raise;
+ end;
end;
procedure TChromium.AfterConstruction;
@@ -1897,7 +1927,7 @@ begin
end;
end;
-procedure TChromium.Internal_GetHTML(const aFrameName : ustring);
+procedure TChromium.doGetHTML(const aFrameName : ustring);
var
TempFrame : ICefFrame;
begin
@@ -1916,7 +1946,7 @@ begin
end;
end;
-procedure TChromium.Internal_GetHTML(const aFrame : ICefFrame);
+procedure TChromium.doGetHTML(const aFrame : ICefFrame);
begin
if Initialized and (aFrame <> nil) then
begin
@@ -1925,7 +1955,7 @@ begin
end;
end;
-procedure TChromium.Internal_GetHTML(const aFrameIdentifier : int64);
+procedure TChromium.doGetHTML(const aFrameIdentifier : int64);
var
TempFrame : ICefFrame;
begin
@@ -1944,7 +1974,7 @@ begin
end;
end;
-procedure TChromium.Internal_GetText(const aFrameName : ustring);
+procedure TChromium.doGetText(const aFrameName : ustring);
var
TempFrame : ICefFrame;
begin
@@ -1963,7 +1993,7 @@ begin
end;
end;
-procedure TChromium.Internal_GetText(const aFrame : ICefFrame);
+procedure TChromium.doGetText(const aFrame : ICefFrame);
begin
if Initialized and (aFrame <> nil) then
begin
@@ -1972,7 +2002,7 @@ begin
end;
end;
-procedure TChromium.Internal_GetText(const aFrameIdentifier : int64);
+procedure TChromium.doGetText(const aFrameIdentifier : int64);
var
TempFrame : ICefFrame;
begin
@@ -2189,7 +2219,7 @@ begin
end;
end;
-procedure TChromium.Internal_UpdatePreferences;
+procedure TChromium.doUpdatePreferences;
begin
FUpdatePreferences := False;
@@ -2609,7 +2639,7 @@ begin
end;
end;
-function TChromium.Internal_SavePreferences : boolean;
+function TChromium.doSavePreferences : boolean;
var
TempDict : ICefDictionaryValue;
TempPrefs : TStringList;
@@ -2637,7 +2667,7 @@ begin
end;
end;
-procedure TChromium.Internal_ResolvedHostAvailable(result: TCefErrorCode; const resolvedIps: TStrings);
+procedure TChromium.doResolvedHostAvailable(result: TCefErrorCode; const resolvedIps: TStrings);
begin
if assigned(FOnResolvedHostAvailable) then FOnResolvedHostAvailable(self, result, resolvedIps);
end;
@@ -2757,7 +2787,7 @@ begin
Result := (FCompHandle <> 0) and PostMessage(FCompHandle, aMsg, wParam, lParam);
end;
-procedure TChromium.Internal_TextResultAvailable(const aText : string);
+procedure TChromium.doTextResultAvailable(const aText : string);
begin
if assigned(FOnTextResultAvailable) then FOnTextResultAvailable(self, aText);
end;
@@ -2815,12 +2845,12 @@ begin
end;
end;
-procedure TChromium.Internal_CookiesDeleted(numDeleted : integer);
+procedure TChromium.doCookiesDeleted(numDeleted : integer);
begin
if assigned(FOnCookiesDeleted) then FOnCookiesDeleted(self, numDeleted);
end;
-procedure TChromium.Internal_PdfPrintFinished(aResultOK : boolean);
+procedure TChromium.doPdfPrintFinished(aResultOK : boolean);
begin
if assigned(FOnPdfPrintFinished) then FOnPdfPrintFinished(self, aResultOK);
end;
@@ -2912,7 +2942,7 @@ begin
if (FBrowser <> nil) then FBrowserId := FBrowser.Identifier;
end;
- Internal_UpdatePreferences;
+ doUpdatePreferences;
FInitialized := (FBrowser <> nil) and (FBrowserId <> 0);
@@ -2926,7 +2956,7 @@ function TChromium.doOnBeforeBrowse(const browser : ICefBrowser;
begin
Result := False;
- if FUpdatePreferences then Internal_UpdatePreferences;
+ if FUpdatePreferences then doUpdatePreferences;
if Assigned(FOnBeforeBrowse) then FOnBeforeBrowse(Self, browser, frame, request, isRedirect, Result);
end;
diff --git a/source/uCEFConstants.pas b/source/uCEFConstants.pas
index 759e09f9..02279d5d 100644
--- a/source/uCEFConstants.pas
+++ b/source/uCEFConstants.pas
@@ -366,10 +366,12 @@ const
CEF_DESTROY = WM_APP + $A06;
CEF_DOONBEFORECLOSE = WM_APP + $A07;
- CEF_TIMER_MINIMUM = $0000000A;
- CEF_TIMER_MAXIMUM = $7FFFFFFF;
- CEF_TIMER_MAXDELAY = 1000 div 30; // 30fps
- CEF_TIMER_DELAY_PLACEHOLDER = high(integer);
+ CEF_TIMER_FIRST_ID = high(cardinal) div 3; // A highly unlikely nIDEvent for our timers
+ CEF_TIMER_MINIMUM = $0000000A;
+ CEF_TIMER_MAXIMUM = $7FFFFFFF;
+ CEF_TIMER_MAXDELAY = 1000 div 30; // 30fps
+ CEF_TIMER_DEPLETEWORK_CYCLES = 10;
+ CEF_TIMER_DEPLETEWORK_DELAY = 50;
CEF4DELPHI_URL = 'https://github.com/salvadordf/CEF4Delphi';
CRLF = #13 + #10;
diff --git a/source/uCEFDeleteCookiesCallback.pas b/source/uCEFDeleteCookiesCallback.pas
index 6d931df0..d08e64a2 100644
--- a/source/uCEFDeleteCookiesCallback.pas
+++ b/source/uCEFDeleteCookiesCallback.pas
@@ -73,12 +73,12 @@ type
TCefCustomDeleteCookiesCallback = class(TCefDeleteCookiesCallbackOwn)
protected
- FChromiumBrowser : TObject;
+ FChromiumBrowser : IChromiumEvents;
procedure OnComplete(numDeleted: Integer); override;
public
- constructor Create(const aChromiumBrowser : TObject); reintroduce;
+ constructor Create(const aChromiumBrowser : IChromiumEvents); reintroduce;
destructor Destroy; override;
procedure InitializeVars; override;
end;
@@ -86,7 +86,7 @@ type
implementation
uses
- uCEFMiscFunctions, uCEFLibFunctions, uCEFChromium;
+ uCEFMiscFunctions, uCEFLibFunctions;
procedure cef_delete_cookie_callback_on_complete(self: PCefDeleteCookiesCallback; num_deleted: Integer); stdcall;
begin
@@ -130,7 +130,7 @@ end;
// TCefCustomDeleteCookiesCallback
-constructor TCefCustomDeleteCookiesCallback.Create(const aChromiumBrowser : TObject);
+constructor TCefCustomDeleteCookiesCallback.Create(const aChromiumBrowser : IChromiumEvents);
begin
inherited Create;
@@ -151,8 +151,7 @@ end;
procedure TCefCustomDeleteCookiesCallback.OnComplete(numDeleted: Integer);
begin
- if (FChromiumBrowser <> nil) and (FChromiumBrowser is TChromium) then
- TChromium(FChromiumBrowser).Internal_CookiesDeleted(numDeleted);
+ if (FChromiumBrowser <> nil) then FChromiumBrowser.doCookiesDeleted(numDeleted);
end;
end.
diff --git a/source/uCEFDomVisitor.pas b/source/uCEFDomVisitor.pas
index 4922a0e0..ea3c64cd 100644
--- a/source/uCEFDomVisitor.pas
+++ b/source/uCEFDomVisitor.pas
@@ -83,7 +83,7 @@ type
implementation
uses
- uCEFMiscFunctions, uCEFLibFunctions, uCEFTypes, uCEFDomDocument, uCEFChromium;
+ uCEFMiscFunctions, uCEFLibFunctions, uCEFTypes, uCEFDomDocument;
procedure cef_dom_visitor_visite(self: PCefDomVisitor; document: PCefDomDocument); stdcall;
begin
diff --git a/source/uCEFInterfaces.pas b/source/uCEFInterfaces.pas
index 8d9999de..ba37d5de 100644
--- a/source/uCEFInterfaces.pas
+++ b/source/uCEFInterfaces.pas
@@ -1809,6 +1809,20 @@ type
// ICefFindHandler
procedure doOnFindResult(const browser: ICefBrowser; identifier, count: Integer; const selectionRect: PCefRect; activeMatchOrdinal: Integer; finalUpdate: Boolean);
+
+ // Custom
+ procedure doCookiesDeleted(numDeleted : integer);
+ procedure doGetHTML(const aFrameName : ustring); overload;
+ procedure doGetHTML(const aFrame : ICefFrame); overload;
+ procedure doGetHTML(const aFrameIdentifier : int64); overload;
+ procedure doGetText(const aFrameName : ustring); overload;
+ procedure doGetText(const aFrame : ICefFrame); overload;
+ procedure doGetText(const aFrameIdentifier : int64); overload;
+ procedure doPdfPrintFinished(aResultOK : boolean);
+ procedure doTextResultAvailable(const aText : string);
+ procedure doUpdatePreferences;
+ function doSavePreferences : boolean;
+ procedure doResolvedHostAvailable(result: TCefErrorCode; const resolvedIps: TStrings);
end;
diff --git a/source/uCEFPDFPrintCallback.pas b/source/uCEFPDFPrintCallback.pas
index a622e44d..735421b9 100644
--- a/source/uCEFPDFPrintCallback.pas
+++ b/source/uCEFPDFPrintCallback.pas
@@ -74,12 +74,12 @@ type
TCefCustomPDFPrintCallBack = class(TCefPdfPrintCallbackOwn)
protected
- FChromiumBrowser : TObject;
+ FChromiumBrowser : IChromiumEvents;
procedure OnPdfPrintFinished(const path: ustring; aResultOK : Boolean); override;
public
- constructor Create(const aChromiumBrowser : TObject); reintroduce;
+ constructor Create(const aChromiumBrowser : IChromiumEvents); reintroduce;
destructor Destroy; override;
procedure InitializeVars; override;
end;
@@ -87,7 +87,7 @@ type
implementation
uses
- uCEFMiscFunctions, uCEFLibFunctions, uCEFChromium;
+ uCEFMiscFunctions, uCEFLibFunctions;
procedure cef_pdf_print_callback_on_pdf_print_finished(self: PCefPdfPrintCallback; const path: PCefString; ok: Integer); stdcall;
begin
@@ -128,7 +128,7 @@ end;
// TCefCustomPDFPrintCallBack
-constructor TCefCustomPDFPrintCallBack.Create(const aChromiumBrowser : TObject);
+constructor TCefCustomPDFPrintCallBack.Create(const aChromiumBrowser : IChromiumEvents);
begin
inherited Create;
@@ -149,8 +149,7 @@ end;
procedure TCefCustomPDFPrintCallBack.OnPdfPrintFinished(const path: ustring; aResultOK : Boolean);
begin
- if (FChromiumBrowser <> nil) and (FChromiumBrowser is TChromium) then
- TChromium(FChromiumBrowser).Internal_PdfPrintFinished(aResultOK);
+ if (FChromiumBrowser <> nil) then FChromiumBrowser.doPdfPrintFinished(aResultOK);
end;
end.
diff --git a/source/uCEFResolveCallback.pas b/source/uCEFResolveCallback.pas
index 721e8f92..5e1c1945 100644
--- a/source/uCEFResolveCallback.pas
+++ b/source/uCEFResolveCallback.pas
@@ -66,11 +66,11 @@ type
TCefCustomResolveCallback = class(TCefResolveCallbackOwn)
protected
- FChromiumBrowser : TObject;
+ FChromiumBrowser : IChromiumEvents;
procedure OnResolveCompleted(result: TCefErrorCode; const resolvedIps: TStrings); override;
public
- constructor Create(const aChromiumBrowser : TObject); reintroduce;
+ constructor Create(const aChromiumBrowser : IChromiumEvents); reintroduce;
destructor Destroy; override;
procedure InitializeVars; override;
end;
@@ -78,7 +78,7 @@ type
implementation
uses
- uCEFMiscFunctions, uCEFLibFunctions, uCEFChromium;
+ uCEFMiscFunctions, uCEFLibFunctions;
procedure cef_resolve_callback_on_resolve_completed(self: PCefResolveCallback;
result: TCefErrorCode;
@@ -126,7 +126,7 @@ end;
// TCefCustomResolveCallback
-constructor TCefCustomResolveCallback.Create(const aChromiumBrowser : TObject);
+constructor TCefCustomResolveCallback.Create(const aChromiumBrowser : IChromiumEvents);
begin
inherited Create;
@@ -147,8 +147,7 @@ end;
procedure TCefCustomResolveCallback.OnResolveCompleted(result: TCefErrorCode; const resolvedIps: TStrings);
begin
- if (FChromiumBrowser <> nil) and (FChromiumBrowser is TChromium) then
- TChromium(FChromiumBrowser).Internal_ResolvedHostAvailable(result, resolvedIps);
+ if (FChromiumBrowser <> nil) then FChromiumBrowser.doResolvedHostAvailable(result, resolvedIps);
end;
end.
diff --git a/source/uCEFStringVisitor.pas b/source/uCEFStringVisitor.pas
index a6493087..992061cc 100644
--- a/source/uCEFStringVisitor.pas
+++ b/source/uCEFStringVisitor.pas
@@ -71,12 +71,12 @@ type
TCustomCefStringVisitor = class(TCefStringVisitorOwn)
protected
- FChromiumBrowser : TObject;
+ FChromiumBrowser : IChromiumEvents;
procedure Visit(const str: ustring); override;
public
- constructor Create(const aChromiumBrowser : TObject); reintroduce;
+ constructor Create(const aChromiumBrowser : IChromiumEvents); reintroduce;
destructor Destroy; override;
procedure InitializeVars; override;
end;
@@ -84,7 +84,7 @@ type
implementation
uses
- uCEFMiscFunctions, uCEFLibFunctions, uCEFChromium;
+ uCEFMiscFunctions, uCEFLibFunctions;
procedure cef_string_visitor_visit(self: PCefStringVisitor; const str: PCefString); stdcall;
begin
@@ -126,7 +126,7 @@ end;
// TCustomCefStringVisitor
-constructor TCustomCefStringVisitor.Create(const aChromiumBrowser : TObject);
+constructor TCustomCefStringVisitor.Create(const aChromiumBrowser : IChromiumEvents);
begin
inherited Create;
@@ -147,8 +147,7 @@ end;
procedure TCustomCefStringVisitor.Visit(const str: ustring);
begin
- if (FChromiumBrowser <> nil) and (FChromiumBrowser is TChromium) then
- TChromium(FChromiumBrowser).Internal_TextResultAvailable(str);
+ if (FChromiumBrowser <> nil) then FChromiumBrowser.doTextResultAvailable(str);
end;
end.
diff --git a/source/uCEFTask.pas b/source/uCEFTask.pas
index 07d1bee7..d2d3eb52 100644
--- a/source/uCEFTask.pas
+++ b/source/uCEFTask.pas
@@ -82,7 +82,7 @@ type
TCefGetTextTask = class(TCefTaskOwn)
protected
- FChromiumBrowser : TObject;
+ FChromiumBrowser : IChromiumEvents;
FFrameName : ustring;
FFrame : ICefFrame;
FFrameIdentifier : int64;
@@ -90,9 +90,9 @@ type
procedure Execute; override;
public
- constructor Create(const aChromiumBrowser : TObject; const aFrameName : ustring); reintroduce; overload;
- constructor Create(const aChromiumBrowser : TObject; const aFrame : ICefFrame); reintroduce; overload;
- constructor Create(const aChromiumBrowser : TObject; const aFrameIdentifier : int64); reintroduce; overload;
+ constructor Create(const aChromiumBrowser : IChromiumEvents; const aFrameName : ustring); reintroduce; overload;
+ constructor Create(const aChromiumBrowser : IChromiumEvents; const aFrame : ICefFrame); reintroduce; overload;
+ constructor Create(const aChromiumBrowser : IChromiumEvents; const aFrameIdentifier : int64); reintroduce; overload;
destructor Destroy; override;
end;
@@ -103,28 +103,30 @@ type
TCefUpdatePrefsTask = class(TCefTaskOwn)
protected
- FChromiumBrowser : TObject;
+ FChromiumBrowser : IChromiumEvents;
procedure Execute; override;
public
- constructor Create(const aChromiumBrowser : TObject); reintroduce;
+ constructor Create(const aChromiumBrowser : IChromiumEvents); reintroduce;
+ destructor Destroy; override;
end;
TCefSavePrefsTask = class(TCefTaskOwn)
protected
- FChromiumBrowser : TObject;
+ FChromiumBrowser : IChromiumEvents;
procedure Execute; override;
public
- constructor Create(const aChromiumBrowser : TObject); reintroduce;
+ constructor Create(const aChromiumBrowser : IChromiumEvents); reintroduce;
+ destructor Destroy; override;
end;
implementation
uses
- uCEFMiscFunctions, uCEFLibFunctions, uCEFChromium, uCEFCookieManager;
+ uCEFMiscFunctions, uCEFLibFunctions, uCEFCookieManager;
procedure cef_task_execute(self: PCefTask); stdcall;
begin
@@ -189,7 +191,7 @@ end;
// TCefGetTextTask
-constructor TCefGetTextTask.Create(const aChromiumBrowser : TObject; const aFrameName : ustring);
+constructor TCefGetTextTask.Create(const aChromiumBrowser : IChromiumEvents; const aFrameName : ustring);
begin
inherited Create;
@@ -199,7 +201,7 @@ begin
FFrameIdentifier := 0;
end;
-constructor TCefGetTextTask.Create(const aChromiumBrowser : TObject; const aFrame : ICefFrame);
+constructor TCefGetTextTask.Create(const aChromiumBrowser : IChromiumEvents; const aFrame : ICefFrame);
begin
inherited Create;
@@ -209,7 +211,7 @@ begin
FFrameIdentifier := 0;
end;
-constructor TCefGetTextTask.Create(const aChromiumBrowser : TObject; const aFrameIdentifier : int64);
+constructor TCefGetTextTask.Create(const aChromiumBrowser : IChromiumEvents; const aFrameIdentifier : int64);
begin
inherited Create;
@@ -221,22 +223,23 @@ end;
destructor TCefGetTextTask.Destroy;
begin
- FFrame := nil;
+ FChromiumBrowser := nil;
+ FFrame := nil;
inherited Destroy;
end;
procedure TCefGetTextTask.Execute;
begin
- if (FChromiumBrowser <> nil) and (FChromiumBrowser is TChromium) then
+ if (FChromiumBrowser <> nil) then
begin
if (FFrame <> nil) then
- TChromium(FChromiumBrowser).Internal_GetText(FFrame)
+ FChromiumBrowser.doGetText(FFrame)
else
if (FFrameIdentifier <> 0) then
- TChromium(FChromiumBrowser).Internal_GetText(FFrameIdentifier)
+ FChromiumBrowser.doGetText(FFrameIdentifier)
else
- TChromium(FChromiumBrowser).Internal_GetText(FFrameName);
+ FChromiumBrowser.doGetText(FFrameName);
end;
end;
@@ -245,15 +248,15 @@ end;
procedure TCefGetHTMLTask.Execute;
begin
- if (FChromiumBrowser <> nil) and (FChromiumBrowser is TChromium) then
+ if (FChromiumBrowser <> nil) then
begin
if (FFrame <> nil) then
- TChromium(FChromiumBrowser).Internal_GetHTML(FFrame)
+ FChromiumBrowser.doGetHTML(FFrame)
else
if (FFrameIdentifier <> 0) then
- TChromium(FChromiumBrowser).Internal_GetHTML(FFrameIdentifier)
+ FChromiumBrowser.doGetHTML(FFrameIdentifier)
else
- TChromium(FChromiumBrowser).Internal_GetHTML(FFrameName);
+ FChromiumBrowser.doGetHTML(FFrameName);
end;
end;
@@ -261,34 +264,46 @@ end;
// TCefUpdatePrefsTask
-constructor TCefUpdatePrefsTask.Create(const aChromiumBrowser : TObject);
+constructor TCefUpdatePrefsTask.Create(const aChromiumBrowser : IChromiumEvents);
begin
inherited Create;
FChromiumBrowser := aChromiumBrowser;
end;
+destructor TCefUpdatePrefsTask.Destroy;
+begin
+ FChromiumBrowser := nil;
+
+ inherited Destroy;
+end;
+
procedure TCefUpdatePrefsTask.Execute;
begin
- if (FChromiumBrowser <> nil) and (FChromiumBrowser is TChromium) then
- TChromium(FChromiumBrowser).Internal_UpdatePreferences;
+ if (FChromiumBrowser <> nil) then FChromiumBrowser.doUpdatePreferences;
end;
// TCefSavePrefsTask
-constructor TCefSavePrefsTask.Create(const aChromiumBrowser : TObject);
+constructor TCefSavePrefsTask.Create(const aChromiumBrowser : IChromiumEvents);
begin
inherited Create;
FChromiumBrowser := aChromiumBrowser;
end;
+destructor TCefSavePrefsTask.Destroy;
+begin
+ FChromiumBrowser := nil;
+
+ inherited Destroy;
+end;
+
procedure TCefSavePrefsTask.Execute;
begin
- if (FChromiumBrowser <> nil) and (FChromiumBrowser is TChromium) then
- TChromium(FChromiumBrowser).Internal_SavePreferences;
+ if (FChromiumBrowser <> nil) then FChromiumBrowser.doSavePreferences;
end;
end.
diff --git a/source/uCEFWorkScheduler.pas b/source/uCEFWorkScheduler.pas
index 6e914b53..417716c5 100644
--- a/source/uCEFWorkScheduler.pas
+++ b/source/uCEFWorkScheduler.pas
@@ -52,35 +52,41 @@ uses
{$ELSE}
Windows, Messages, Classes, Controls, Graphics, Forms,
{$ENDIF}
- uCEFTypes, uCEFInterfaces, uCEFLibFunctions, uCEFMiscFunctions, uCEFConstants;
-
-const
- TIMER_NIDEVENT = 1;
- TIMER_DEPLETEWORK_CYCLES = 10;
- TIMER_DEPLETEWORK_DELAY = 50;
+ uCEFConstants, uCEFWorkSchedulerThread;
type
TCEFWorkScheduler = class(TComponent)
protected
FCompHandle : HWND;
+ FThread : TCEFWorkSchedulerThread;
FDepleteWorkCycles : cardinal;
FDepleteWorkDelay : cardinal;
- FTimerPending : boolean;
- FIsActive : boolean;
- FReentrancyDetected : boolean;
+ FDefaultInterval : integer;
FStopped : boolean;
+ {$IFDEF MSWINDOWS}
+ {$WARN SYMBOL_PLATFORM OFF}
+ FPriority : TThreadPriority;
+ {$WARN SYMBOL_PLATFORM ON}
+ {$ENDIF}
- procedure WndProc(var aMessage: TMessage);
- function SendCompMessage(aMsg, wParam : cardinal; lParam : integer) : boolean;
- procedure CreateTimer(const delay_ms : int64);
- procedure TimerTimeout;
- procedure DoWork;
- procedure ScheduleWork(const delay_ms : int64);
- procedure DoMessageLoopWork;
- function PerformMessageLoopWork : boolean;
- procedure DestroyTimer;
+ procedure CreateThread;
+ procedure DestroyThread;
procedure DeallocateWindowHandle;
procedure DepleteWork;
+ procedure WndProc(var aMessage: TMessage);
+ procedure NextPulse(aInterval : integer);
+ procedure ScheduleWork(const delay_ms : int64);
+ procedure DoWork;
+ procedure DoMessageLoopWork;
+
+ procedure SetDefaultInterval(aValue : integer);
+ {$IFDEF MSWINDOWS}
+ {$WARN SYMBOL_PLATFORM OFF}
+ procedure SetPriority(aValue : TThreadPriority);
+ {$WARN SYMBOL_PLATFORM ON}
+ {$ENDIF}
+
+ procedure Thread_OnPulse(Sender : TObject);
public
constructor Create(AOwner: TComponent); override;
@@ -89,11 +95,15 @@ type
procedure ScheduleMessagePumpWork(const delay_ms : int64);
procedure StopScheduler;
- property IsTimerPending : boolean read FTimerPending;
-
published
- property DepleteWorkCycles : cardinal read FDepleteWorkCycles write FDepleteWorkCycles default TIMER_DEPLETEWORK_CYCLES;
- property DepleteWorkDelay : cardinal read FDepleteWorkDelay write FDepleteWorkDelay default TIMER_DEPLETEWORK_DELAY;
+ {$IFDEF MSWINDOWS}
+ {$WARN SYMBOL_PLATFORM OFF}
+ property Priority : TThreadPriority read FPriority write SetPriority default tpNormal;
+ {$WARN SYMBOL_PLATFORM ON}
+ {$ENDIF}
+ property DefaultInterval : integer read FDefaultInterval write SetDefaultInterval default CEF_TIMER_MAXDELAY;
+ property DepleteWorkCycles : cardinal read FDepleteWorkCycles write FDepleteWorkCycles default CEF_TIMER_DEPLETEWORK_CYCLES;
+ property DepleteWorkDelay : cardinal read FDepleteWorkDelay write FDepleteWorkDelay default CEF_TIMER_DEPLETEWORK_DELAY;
end;
implementation
@@ -104,25 +114,29 @@ uses
{$ELSE}
SysUtils, Math,
{$ENDIF}
- uCEFApplication;
+ uCEFMiscFunctions, uCEFApplication;
constructor TCEFWorkScheduler.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
+ FThread := nil;
FCompHandle := 0;
- FTimerPending := False;
- FIsActive := False;
- FReentrancyDetected := False;
FStopped := False;
- FDepleteWorkCycles := TIMER_DEPLETEWORK_CYCLES;
- FDepleteWorkDelay := TIMER_DEPLETEWORK_DELAY;
+ {$IFDEF MSWINDOWS}
+ {$WARN SYMBOL_PLATFORM OFF}
+ FPriority := tpNormal;
+ {$WARN SYMBOL_PLATFORM ON}
+ {$ENDIF}
+ FDefaultInterval := CEF_TIMER_MAXDELAY;
+ FDepleteWorkCycles := CEF_TIMER_DEPLETEWORK_CYCLES;
+ FDepleteWorkDelay := CEF_TIMER_DEPLETEWORK_DELAY;
end;
destructor TCEFWorkScheduler.Destroy;
begin
- DestroyTimer;
+ DestroyThread;
DeallocateWindowHandle;
inherited Destroy;
@@ -133,35 +147,49 @@ begin
inherited AfterConstruction;
if not(csDesigning in ComponentState) then
- FCompHandle := AllocateHWnd(WndProc);
+ begin
+ FCompHandle := AllocateHWnd(WndProc);
+ CreateThread;
+ end;
+end;
+
+procedure TCEFWorkScheduler.CreateThread;
+begin
+ FThread := TCEFWorkSchedulerThread.Create;
+ {$IFDEF MSWINDOWS}
+ FThread.Priority := FPriority;
+ {$ENDIF}
+ FThread.DefaultInterval := FDefaultInterval;
+ FThread.OnPulse := Thread_OnPulse;
+ {$IFDEF DELPHI8_UP}
+ FThread.Start;
+ {$ELSE}
+ FThread.Resume;
+ {$ENDIF}
+end;
+
+procedure TCEFWorkScheduler.DestroyThread;
+begin
+ try
+ if (FThread <> nil) then
+ begin
+ FThread.Terminate;
+ FThread.NextPulse(0);
+ FThread.WaitFor;
+ FreeAndNil(FThread);
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TCEFWorkScheduler.DestroyThread', e) then raise;
+ end;
end;
procedure TCEFWorkScheduler.WndProc(var aMessage: TMessage);
begin
- case aMessage.Msg of
- WM_TIMER : TimerTimeout;
- CEF_PUMPHAVEWORK : ScheduleWork(aMessage.lParam);
- else aMessage.Result := DefWindowProc(FCompHandle, aMessage.Msg, aMessage.WParam, aMessage.LParam);
- end;
-end;
-
-function TCEFWorkScheduler.SendCompMessage(aMsg, wParam : cardinal; lParam : integer) : boolean;
-begin
- Result := not(FStopped) and (FCompHandle <> 0) and PostMessage(FCompHandle, aMsg, wParam, lParam);
-end;
-
-procedure TCEFWorkScheduler.CreateTimer(const delay_ms : int64);
-begin
- if not(FTimerPending) and
- not(FStopped) and
- (delay_ms > 0) and
- (SetTimer(FCompHandle, TIMER_NIDEVENT, cardinal(delay_ms), nil) <> 0) then
- FTimerPending := True;
-end;
-
-procedure TCEFWorkScheduler.DestroyTimer;
-begin
- if FTimerPending and KillTimer(FCompHandle, TIMER_NIDEVENT) then FTimerPending := False;
+ if (aMessage.Msg = CEF_PUMPHAVEWORK) then
+ ScheduleWork(aMessage.lParam)
+ else
+ aMessage.Result := DefWindowProc(FCompHandle, aMessage.Msg, aMessage.WParam, aMessage.LParam);
end;
procedure TCEFWorkScheduler.DeallocateWindowHandle;
@@ -173,6 +201,27 @@ begin
end;
end;
+procedure TCEFWorkScheduler.DoMessageLoopWork;
+begin
+ if (GlobalCEFApp <> nil) then GlobalCEFApp.DoMessageLoopWork;
+end;
+
+procedure TCEFWorkScheduler.SetDefaultInterval(aValue : integer);
+begin
+ FDefaultInterval := aValue;
+ if (FThread <> nil) then FThread.DefaultInterval := aValue;
+end;
+
+{$IFDEF MSWINDOWS}
+{$WARN SYMBOL_PLATFORM OFF}
+procedure TCEFWorkScheduler.SetPriority(aValue : TThreadPriority);
+begin
+ FPriority := aValue;
+ if (FThread <> nil) then FThread.Priority := aValue;
+end;
+{$WARN SYMBOL_PLATFORM ON}
+{$ENDIF}
+
procedure TCEFWorkScheduler.DepleteWork;
var
i : cardinal;
@@ -189,78 +238,43 @@ end;
procedure TCEFWorkScheduler.ScheduleMessagePumpWork(const delay_ms : int64);
begin
- SendCompMessage(CEF_PUMPHAVEWORK, 0, LPARAM(delay_ms));
+ if not(FStopped) and (FCompHandle <> 0) then
+ PostMessage(FCompHandle, CEF_PUMPHAVEWORK, 0, LPARAM(delay_ms));
end;
procedure TCEFWorkScheduler.StopScheduler;
begin
FStopped := True;
- DestroyTimer;
+ NextPulse(0);
DepleteWork;
DeallocateWindowHandle;
end;
-procedure TCEFWorkScheduler.TimerTimeout;
+procedure TCEFWorkScheduler.Thread_OnPulse(Sender: TObject);
begin
- if not(FStopped) then
- begin
- DestroyTimer;
- DoWork;
- end;
+ if not(FStopped) then DoMessageLoopWork;
end;
procedure TCEFWorkScheduler.DoWork;
-var
- TempWasReentrant : boolean;
begin
- TempWasReentrant := PerformMessageLoopWork;
-
- if TempWasReentrant then
- ScheduleMessagePumpWork(0)
- else
- if not(IsTimerPending) then
- ScheduleMessagePumpWork(CEF_TIMER_DELAY_PLACEHOLDER);
+ DoMessageLoopWork;
+ NextPulse(FDefaultInterval);
end;
procedure TCEFWorkScheduler.ScheduleWork(const delay_ms : int64);
begin
- if FStopped or
- ((delay_ms = CEF_TIMER_DELAY_PLACEHOLDER) and IsTimerPending) then
- exit;
-
- DestroyTimer;
-
- if (delay_ms <= 0) then
- DoWork
- else
- if (delay_ms > CEF_TIMER_MAXDELAY) then
- CreateTimer(CEF_TIMER_MAXDELAY)
- else
- CreateTimer(delay_ms);
-end;
-
-procedure TCEFWorkScheduler.DoMessageLoopWork;
-begin
- if (GlobalCEFApp <> nil) then GlobalCEFApp.DoMessageLoopWork;
-end;
-
-function TCEFWorkScheduler.PerformMessageLoopWork : boolean;
-begin
- Result := False;
-
- if FIsActive then
+ if not(FStopped) then
begin
- FReentrancyDetected := True;
- exit;
+ if (delay_ms <= 0) then
+ DoWork
+ else
+ NextPulse(delay_ms);
end;
+end;
- FReentrancyDetected := False;
-
- FIsActive := True;
- DoMessageLoopWork;
- FIsActive := False;
-
- Result := FReentrancyDetected;
+procedure TCEFWorkScheduler.NextPulse(aInterval : integer);
+begin
+ if (FThread <> nil) then FThread.NextPulse(aInterval);
end;
end.
diff --git a/source/uCEFWorkSchedulerThread.pas b/source/uCEFWorkSchedulerThread.pas
new file mode 100644
index 00000000..819270bd
--- /dev/null
+++ b/source/uCEFWorkSchedulerThread.pas
@@ -0,0 +1,222 @@
+// ************************************************************************
+// ***************************** 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 © 2018 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.
+ *
+ *)
+
+unit uCEFWorkSchedulerThread;
+
+{$IFNDEF CPUX64}
+ {$ALIGN ON}
+ {$MINENUMSIZE 4}
+{$ENDIF}
+
+{$I cef.inc}
+
+interface
+
+uses
+ {$IFDEF DELPHI16_UP}
+ System.Classes, System.SyncObjs,
+ {$ELSE}
+ Classes, SyncObjs,
+ {$ENDIF}
+ uCEFConstants;
+
+type
+ TCEFWorkSchedulerThread = class(TThread)
+ protected
+ FCritSect : TCriticalSection;
+ FInterval : integer;
+ FEvent : TEvent;
+ FOnPulse : TNotifyEvent;
+ FPulsing : boolean;
+ FMustReset : boolean;
+ FDefaultInterval : integer;
+
+ function Lock : boolean;
+ procedure Unlock;
+ function CanPulse(var aInterval : integer) : boolean;
+ procedure DoOnPulseEvent;
+ procedure EventTimeOut;
+ procedure SignaledEvent;
+ procedure Execute; override;
+
+ public
+ constructor Create;
+ destructor Destroy; override;
+ procedure AfterConstruction; override;
+ procedure NextPulse(aInterval : integer);
+
+ property DefaultInterval : integer read FDefaultInterval write FDefaultInterval default CEF_TIMER_MAXDELAY;
+ property OnPulse : TNotifyEvent read FOnPulse write FOnPulse;
+ end;
+
+implementation
+
+uses
+ {$IFDEF DELPHI16_UP}
+ System.SysUtils, System.Math,
+ {$ELSE}
+ SysUtils, Math,
+ {$ENDIF}
+ uCEFApplication;
+
+constructor TCEFWorkSchedulerThread.Create;
+begin
+ FOnPulse := nil;
+ FCritSect := nil;
+ FPulsing := False;
+ FEvent := nil;
+ FDefaultInterval := CEF_TIMER_MAXDELAY;
+ FInterval := FDefaultInterval;
+ FMustReset := False;
+
+ inherited Create(True);
+
+ FreeOnTerminate := False;
+end;
+
+destructor TCEFWorkSchedulerThread.Destroy;
+begin
+ if (FEvent <> nil) then FreeAndNil(FEvent);
+ if (FCritSect <> nil) then FreeAndNil(FCritSect);
+
+ inherited Destroy;
+end;
+
+procedure TCEFWorkSchedulerThread.AfterConstruction;
+begin
+ inherited AfterConstruction;
+
+ FEvent := TEvent.Create(nil, False, False, '');
+ FCritSect := TCriticalSection.Create;
+end;
+
+procedure TCEFWorkSchedulerThread.DoOnPulseEvent;
+begin
+ if assigned(FOnPulse) then FOnPulse(self);
+end;
+
+function TCEFWorkSchedulerThread.Lock : boolean;
+begin
+ if not(Terminated) and (FCritSect <> nil) then
+ begin
+ FCritSect.Acquire;
+ Result := True;
+ end
+ else
+ Result := False;
+end;
+
+procedure TCEFWorkSchedulerThread.Unlock;
+begin
+ if (FCritSect <> nil) then FCritSect.Release;
+end;
+
+procedure TCEFWorkSchedulerThread.NextPulse(aInterval : integer);
+begin
+ if Lock then
+ try
+ FInterval := min(aInterval, CEF_TIMER_MAXDELAY);
+ FMustReset := True;
+
+ if FPulsing then
+ begin
+ FPulsing := False;
+ FEvent.SetEvent;
+ end;
+ finally
+ Unlock;
+ end;
+end;
+
+procedure TCEFWorkSchedulerThread.EventTimeOut;
+begin
+ if Lock then
+ try
+ if FMustReset then
+ begin
+ FInterval := FDefaultInterval;
+ FMustReset := False;
+ end;
+
+ FPulsing := False;
+ finally
+ Unlock;
+ if not(Terminated) then Synchronize(DoOnPulseEvent);
+ end;
+end;
+
+procedure TCEFWorkSchedulerThread.SignaledEvent;
+begin
+ if Lock then
+ try
+ FPulsing := False;
+ finally
+ Unlock;
+ end;
+end;
+
+function TCEFWorkSchedulerThread.CanPulse(var aInterval : integer) : boolean;
+begin
+ Result := False;
+
+ if Lock then
+ try
+ aInterval := FInterval;
+
+ if (aInterval > 0) then
+ begin
+ Result := True;
+ FPulsing := True;
+ FEvent.ResetEvent;
+ end;
+ finally
+ Unlock;
+ end;
+end;
+
+procedure TCEFWorkSchedulerThread.Execute;
+var
+ TempInterval : integer;
+begin
+ while CanPulse(TempInterval) do
+ if (FEvent.WaitFor(TempInterval) = wrTimeout) then
+ EventTimeOut
+ else
+ SignaledEvent;
+end;
+
+end.
diff --git a/source/uFMXBufferPanel.pas b/source/uFMXBufferPanel.pas
new file mode 100644
index 00000000..86546985
--- /dev/null
+++ b/source/uFMXBufferPanel.pas
@@ -0,0 +1,426 @@
+// ************************************************************************
+// ***************************** 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 © 2018 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.
+ *
+ *)
+
+unit uFMXBufferPanel;
+
+{$I cef.inc}
+
+interface
+
+uses
+ {$IFDEF MSWINDOWS}
+ Winapi.Windows,
+ {$ELSE}
+ System.SyncObjs,
+ {$ENDIF}
+ System.Classes, System.UIConsts, System.Types, System.UITypes,
+ {$IFDEF DELPHI17_UP}
+ FMX.Graphics,
+ {$ENDIF}
+ FMX.Types, FMX.Controls;
+
+type
+ TDialogKeyEvent = procedure(Sender: TObject; var Key: Word; Shift: TShiftState) of object;
+
+ TFMXBufferPanel = class(TControl)
+ protected
+ {$IFDEF MSWINDOWS}
+ FMutex : THandle;
+ {$ELSE}
+ FBufferCS : TCriticalSection;
+ {$ENDIF}
+ FBuffer : TBitmap;
+ FScanlineSize : integer;
+ FColor : TAlphaColor;
+ FHighSpeedDrawing : boolean;
+ FOnDialogKey : TDialogKeyEvent;
+
+ procedure CreateSyncObj;
+
+ procedure DestroySyncObj;
+ procedure DestroyBuffer;
+
+ function GetScreenScale : Single;
+ function GetBufferWidth : integer;
+ function GetBufferHeight : integer;
+
+ function CopyBuffer : boolean;
+ function SaveBufferToFile(const aFilename : string) : boolean;
+
+ procedure Paint; override;
+ procedure DialogKey(var Key: Word; Shift: TShiftState); override;
+
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ procedure AfterConstruction; override;
+ function SaveToFile(const aFilename : string) : boolean;
+ procedure InvalidatePanel;
+ function BeginBufferDraw : boolean;
+ procedure EndBufferDraw;
+ procedure BufferDraw(x, y : integer; const aBitmap : TBitmap);
+ function UpdateBufferDimensions(aWidth, aHeight : integer) : boolean;
+ function BufferIsResized(aUseMutex : boolean = True) : boolean;
+ function ScreenToClient(aPoint : TPoint) : TPoint;
+ function ClientToScreen(aPoint : TPoint) : TPoint;
+
+ property Buffer : TBitmap read FBuffer;
+ property ScanlineSize : integer read FScanlineSize;
+ property BufferWidth : integer read GetBufferWidth;
+ property BufferHeight : integer read GetBufferHeight;
+ property ScreenScale : single read GetScreenScale;
+
+ published
+ property Align;
+ property Anchors;
+ property Visible;
+ property Enabled;
+ property TabOrder;
+ property Color : TAlphaColor read FColor write FColor default claWhite;
+ property HighSpeedDrawing : boolean read FHighSpeedDrawing write FHighSpeedDrawing default True;
+
+ {$IFDEF DELPHI17_UP}
+ property TabStop;
+ property CanFocus;
+ property CanParentFocus;
+ property Height;
+ property Width;
+ property Padding;
+ property Opacity;
+ property Margins;
+ property Position;
+ property RotationAngle;
+ property RotationCenter;
+ property Scale;
+ property Size;
+ {$ENDIF}
+
+ property OnEnter;
+ property OnExit;
+ property OnResize;
+ property OnClick;
+ property OnMouseDown;
+ property OnMouseMove;
+ property OnMouseUp;
+ property OnMouseEnter;
+ property OnMouseLeave;
+ property OnMouseWheel;
+ property OnKeyUp;
+ property OnKeyDown;
+ property OnDialogKey : TDialogKeyEvent read FOnDialogKey write FOnDialogKey;
+ end;
+
+implementation
+
+uses
+ System.SysUtils, System.Math,
+ FMX.Platform, uCEFMiscFunctions, uCEFApplication;
+
+constructor TFMXBufferPanel.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+
+ {$IFDEF MSWINDOWS}
+ FMutex := 0;
+ {$ELSE}
+ FBufferCS := nil;
+ {$ENDIF}
+ FBuffer := nil;
+ FScanlineSize := 0;
+ FColor := claWhite;
+ FOnDialogKey := nil;
+ FHighSpeedDrawing := True;
+end;
+
+destructor TFMXBufferPanel.Destroy;
+begin
+ DestroyBuffer;
+ DestroySyncObj;
+
+ inherited Destroy;
+end;
+
+procedure TFMXBufferPanel.AfterConstruction;
+begin
+ inherited AfterConstruction;
+
+ CreateSyncObj;
+end;
+
+procedure TFMXBufferPanel.CreateSyncObj;
+begin
+ {$IFDEF MSWINDOWS}
+ FMutex := CreateMutex(nil, False, nil);
+ {$ELSE}
+ FBufferCS := TCriticalSection.Create;
+ {$ENDIF}
+end;
+
+procedure TFMXBufferPanel.DestroySyncObj;
+begin
+ {$IFDEF MSWINDOWS}
+ if (FMutex <> 0) then
+ begin
+ CloseHandle(FMutex);
+ FMutex := 0;
+ end;
+ {$ELSE}
+ if (FBufferCS <> nil) then FreeAndNil(FBufferCS);
+ {$ENDIF}
+end;
+
+procedure TFMXBufferPanel.DestroyBuffer;
+begin
+ if BeginBufferDraw then
+ begin
+ if (FBuffer <> nil) then FreeAndNil(FBuffer);
+ EndBufferDraw;
+ end;
+end;
+
+function TFMXBufferPanel.SaveBufferToFile(const aFilename : string) : boolean;
+begin
+ Result := False;
+
+ try
+ if (FBuffer <> nil) then
+ begin
+ FBuffer.SaveToFile(aFilename);
+ Result := True;
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXBufferPanel.SaveBufferToFile', e) then raise;
+ end;
+end;
+
+function TFMXBufferPanel.SaveToFile(const aFilename : string) : boolean;
+begin
+ Result := False;
+
+ if BeginBufferDraw then
+ begin
+ Result := SaveBufferToFile(aFilename);
+ EndBufferDraw;
+ end;
+end;
+
+procedure TFMXBufferPanel.InvalidatePanel;
+begin
+ InvalidateRect(TRectF.Create(0, 0, Width, Height));
+end;
+
+function TFMXBufferPanel.BeginBufferDraw : boolean;
+begin
+ {$IFDEF MSWINDOWS}
+ Result := (FMutex <> 0) and (WaitForSingleObject(FMutex, 5000) = WAIT_OBJECT_0);
+ {$ELSE}
+ if (FBufferCS <> nil) then
+ begin
+ FBufferCS.Acquire;
+ Result := True;
+ end
+ else
+ Result := False;
+ {$ENDIF}
+end;
+
+procedure TFMXBufferPanel.EndBufferDraw;
+begin
+ {$IFDEF MSWINDOWS}
+ if (FMutex <> 0) then ReleaseMutex(FMutex);
+ {$ELSE}
+ if (FBufferCS <> nil) then FBufferCS.Release;
+ {$ENDIF}
+end;
+
+function TFMXBufferPanel.CopyBuffer : boolean;
+var
+ TempSrc, TempDst : TRectF;
+begin
+ Result := False;
+
+ if Canvas.BeginScene then
+ try
+ if BeginBufferDraw then
+ begin
+ if (FBuffer <> nil) then
+ begin
+ TempSrc := TRectF.Create(0, 0, FBuffer.Width, FBuffer.Height);
+ TempDst := TRectF.Create(0, 0, FBuffer.Width / ScreenScale, FBuffer.Height / ScreenScale);
+
+ Canvas.DrawBitmap(FBuffer, TempSrc, TempDst, 1, FHighSpeedDrawing);
+
+ Result := True;
+ end;
+
+ EndBufferDraw;
+ end;
+ finally
+ Canvas.EndScene;
+ end;
+end;
+
+procedure TFMXBufferPanel.DialogKey(var Key: Word; Shift: TShiftState);
+begin
+ if assigned(FOnDialogKey) then FOnDialogKey(self, Key, Shift);
+
+ inherited DialogKey(Key, Shift);
+end;
+
+procedure TFMXBufferPanel.Paint;
+var
+ TempRect : TRectF;
+begin
+ if (csDesigning in ComponentState) or not(CopyBuffer) then
+ begin
+ TempRect := TRectF.Create(0, 0, Width, Height);
+
+ if Canvas.BeginScene then
+ try
+ Canvas.ClearRect(TempRect, FColor);
+ finally
+ Canvas.EndScene;
+ end;
+ end;
+end;
+
+function TFMXBufferPanel.GetScreenScale : Single;
+begin
+ if (GlobalCEFApp <> nil) then
+ Result := GlobalCEFApp.DeviceScaleFactor
+ else
+ Result := 1;
+end;
+
+function TFMXBufferPanel.GetBufferWidth : integer;
+begin
+ if (FBuffer <> nil) then
+ Result := FBuffer.Width
+ else
+ Result := 0;
+end;
+
+function TFMXBufferPanel.GetBufferHeight : integer;
+begin
+ if (FBuffer <> nil) then
+ Result := FBuffer.Height
+ else
+ Result := 0;
+end;
+
+procedure TFMXBufferPanel.BufferDraw(x, y : integer; const aBitmap : TBitmap);
+var
+ TempSrc, TempDst : TRectF;
+begin
+ if (FBuffer <> nil) then
+ begin
+ TempSrc := TRectF.Create(0, 0, aBitmap.Width, aBitmap.Height);
+ TempDst := TRectF.Create(x, y, x + (aBitmap.Width / ScreenScale), y + (aBitmap.Height / ScreenScale));
+
+ if FBuffer.Canvas.BeginScene then
+ try
+ FBuffer.Canvas.DrawBitmap(aBitmap, TempSrc, TempDst, 1, FHighSpeedDrawing);
+ finally
+ FBuffer.Canvas.EndScene;
+ end;
+ end;
+end;
+
+function TFMXBufferPanel.UpdateBufferDimensions(aWidth, aHeight : integer) : boolean;
+begin
+ Result := False;
+
+ if ((FBuffer = nil) or
+ (FBuffer.Width <> aWidth) or
+ (FBuffer.Height <> aHeight)) then
+ begin
+ if (FBuffer <> nil) then FreeAndNil(FBuffer);
+
+ FBuffer := TBitmap.Create(aWidth, aHeight);
+ {$IFDEF DELPHI17_UP}
+ FBuffer.BitmapScale := ScreenScale;
+ FScanlineSize := FBuffer.BytesPerLine;
+ {$ELSE}
+ FScanlineSize := aWidth * SizeOf(TRGBQuad);
+ {$ENDIF}
+ Result := True;
+ end;
+end;
+
+function TFMXBufferPanel.BufferIsResized(aUseMutex : boolean) : boolean;
+var
+ TempWidth, TempHeight : integer;
+begin
+ Result := False;
+
+ if not(aUseMutex) or BeginBufferDraw then
+ begin
+ TempWidth := round(Width * GlobalCEFApp.DeviceScaleFactor);
+ TempHeight := round(Height * GlobalCEFApp.DeviceScaleFactor);
+
+ Result := (FBuffer <> nil) and
+ (FBuffer.Width = TempWidth) and
+ (FBuffer.Height = TempHeight);
+
+ if aUseMutex then EndBufferDraw;
+ end;
+end;
+
+function TFMXBufferPanel.ScreenToClient(aPoint : TPoint) : TPoint;
+var
+ TempPoint : TPointF;
+begin
+ TempPoint.x := aPoint.x;
+ TempPoint.y := aPoint.y;
+ TempPoint := ScreenToLocal(TempPoint);
+ Result.x := round(TempPoint.x);
+ Result.y := round(TempPoint.y);
+end;
+
+function TFMXBufferPanel.ClientToScreen(aPoint : TPoint) : TPoint;
+var
+ TempPoint : TPointF;
+begin
+ TempPoint.x := aPoint.x;
+ TempPoint.y := aPoint.y;
+ TempPoint := LocalToScreen(TempPoint);
+ Result.x := round(TempPoint.x);
+ Result.y := round(TempPoint.y);
+end;
+
+end.
diff --git a/source/uFMXChromium.pas b/source/uFMXChromium.pas
new file mode 100644
index 00000000..5e7f3055
--- /dev/null
+++ b/source/uFMXChromium.pas
@@ -0,0 +1,3435 @@
+// ************************************************************************
+// ***************************** 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 © 2018 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.
+ *
+ *)
+
+unit uFMXChromium;
+
+{$IFNDEF CPUX64}
+ {$ALIGN ON}
+ {$MINENUMSIZE 4}
+{$ENDIF}
+
+{$I cef.inc}
+
+interface
+
+uses
+ System.Classes, System.Types,
+ FMX.Types, FMX.Platform, FMX.Controls, FMX.Forms,
+ uCEFTypes, uCEFInterfaces, uCEFLibFunctions, uCEFMiscFunctions, uCEFClient,
+ uCEFPDFPrintCallback, uCEFStringVisitor, uCEFConstants, uCEFTask,
+ uCEFDeleteCookiesCallback, uCEFDomVisitor, uCEFChromiumEvents,
+ uCEFChromiumOptions, uCEFChromiumFontOptions, uCEFPDFPrintOptions;
+
+type
+ TFMXChromium = class(TComponent, IChromiumEvents)
+ protected
+ FVisitor : ICefStringVisitor;
+ FPDFPrintcb : ICefPdfPrintCallback;
+ FResolveHostcb : ICefResolveCallback;
+ FCookiDeletercb : ICefDeleteCookiesCallback;
+ FHandler : ICefClient;
+ FBrowser : ICefBrowser;
+ FBrowserId : Integer;
+ FDefaultUrl : ustring;
+ FOptions : TChromiumOptions;
+ FFontOptions : TChromiumFontOptions;
+ FPDFPrintOptions : TPDFPrintOptions;
+ FDefaultEncoding : ustring;
+ FProxyType : integer;
+ FProxyScheme : TCefProxyScheme;
+ FProxyServer : string;
+ FProxyPort : integer;
+ FProxyUsername : string;
+ FProxyPassword : string;
+ FProxyScriptURL : string;
+ FProxyByPassList : string;
+ FUpdatePreferences : boolean;
+ FCustomHeaderName : string;
+ FCustomHeaderValue : string;
+ FAddCustomHeader : boolean;
+ FDoNotTrack : boolean;
+ FSendReferrer : boolean;
+ FHyperlinkAuditing : boolean;
+ FCookiePrefs : integer;
+ FImagesPrefs : integer;
+ FZoomStep : byte;
+ FWindowName : string;
+ FPrefsFileName : string;
+ FInitialized : boolean;
+ FClosing : boolean;
+ FWindowInfo : TCefWindowInfo;
+ FBrowserSettings : TCefBrowserSettings;
+ FDevWindowInfo : TCefWindowInfo;
+ FDevBrowserSettings : TCefBrowserSettings;
+ FDragOperations : TCefDragOperations;
+ FDragAndDropInitialized : boolean;
+ FWebRTCIPHandlingPolicy : TCefWebRTCHandlingPolicy;
+ FWebRTCMultipleRoutes : TCefState;
+ FWebRTCNonProxiedUDP : TCefState;
+
+ // ICefClient
+ FOnProcessMessageReceived : TOnProcessMessageReceived;
+
+ // ICefLoadHandler
+ FOnLoadStart : TOnLoadStart;
+ FOnLoadEnd : TOnLoadEnd;
+ FOnLoadError : TOnLoadError;
+ FOnLoadingStateChange : TOnLoadingStateChange;
+
+ // ICefFocusHandler
+ FOnTakeFocus : TOnTakeFocus;
+ FOnSetFocus : TOnSetFocus;
+ FOnGotFocus : TOnGotFocus;
+
+ // ICefContextMenuHandler
+ FOnBeforeContextMenu : TOnBeforeContextMenu;
+ FOnRunContextMenu : TOnRunContextMenu;
+ FOnContextMenuCommand : TOnContextMenuCommand;
+ FOnContextMenuDismissed : TOnContextMenuDismissed;
+
+ // ICefKeyboardHandler
+ FOnPreKeyEvent : TOnPreKeyEvent;
+ FOnKeyEvent : TOnKeyEvent;
+
+ // ICefDisplayHandler
+ FOnAddressChange : TOnAddressChange;
+ FOnTitleChange : TOnTitleChange;
+ FOnFavIconUrlChange : TOnFavIconUrlChange;
+ FOnFullScreenModeChange : TOnFullScreenModeChange;
+ FOnTooltip : TOnTooltip;
+ FOnStatusMessage : TOnStatusMessage;
+ FOnConsoleMessage : TOnConsoleMessage;
+ FOnAutoResize : TOnAutoResize;
+
+ // ICefDownloadHandler
+ FOnBeforeDownload : TOnBeforeDownload;
+ FOnDownloadUpdated : TOnDownloadUpdated;
+
+ // ICefGeolocationHandler
+ FOnRequestGeolocationPermission : TOnRequestGeolocationPermission;
+ FOnCancelGeolocationPermission : TOnCancelGeolocationPermission;
+
+ // ICefJsDialogHandler
+ FOnJsdialog : TOnJsdialog;
+ FOnBeforeUnloadDialog : TOnBeforeUnloadDialog;
+ FOnResetDialogState : TOnResetDialogState;
+ FOnDialogClosed : TOnDialogClosed;
+
+ // ICefLifeSpanHandler
+ FOnBeforePopup : TOnBeforePopup;
+ FOnAfterCreated : TOnAfterCreated;
+ FOnBeforeClose : TOnBeforeClose;
+ FOnClose : TOnClose;
+
+ // ICefRequestHandler
+ FOnBeforeBrowse : TOnBeforeBrowse;
+ FOnOpenUrlFromTab : TOnOpenUrlFromTab;
+ FOnBeforeResourceLoad : TOnBeforeResourceLoad;
+ FOnGetResourceHandler : TOnGetResourceHandler;
+ FOnResourceRedirect : TOnResourceRedirect;
+ FOnResourceResponse : TOnResourceResponse;
+ FOnGetResourceResponseFilter : TOnGetResourceResponseFilter;
+ FOnResourceLoadComplete : TOnResourceLoadComplete;
+ FOnGetAuthCredentials : TOnGetAuthCredentials;
+ FOnQuotaRequest : TOnQuotaRequest;
+ FOnProtocolExecution : TOnProtocolExecution;
+ FOnCertificateError : TOnCertificateError;
+ FOnSelectClientCertificate : TOnSelectClientCertificate;
+ FOnPluginCrashed : TOnPluginCrashed;
+ FOnRenderViewReady : TOnRenderViewReady;
+ FOnRenderProcessTerminated : TOnRenderProcessTerminated;
+
+ // ICefDialogHandler
+ FOnFileDialog : TOnFileDialog;
+
+ // ICefRenderHandler
+ FOnGetAccessibilityHandler : TOnGetAccessibilityHandler;
+ FOnGetRootScreenRect : TOnGetRootScreenRect;
+ FOnGetViewRect : TOnGetViewRect;
+ FOnGetScreenPoint : TOnGetScreenPoint;
+ FOnGetScreenInfo : TOnGetScreenInfo;
+ FOnPopupShow : TOnPopupShow;
+ FOnPopupSize : TOnPopupSize;
+ FOnPaint : TOnPaint;
+ FOnCursorChange : TOnCursorChange;
+ FOnScrollOffsetChanged : TOnScrollOffsetChanged;
+ FOnIMECompositionRangeChanged : TOnIMECompositionRangeChanged;
+
+ // ICefDragHandler
+ FOnDragEnter : TOnDragEnter;
+ FOnDraggableRegionsChanged : TOnDraggableRegionsChanged;
+
+ // ICefFindHandler
+ FOnFindResult : TOnFindResult;
+
+ // Custom
+ FOnTextResultAvailable : TOnTextResultAvailableEvent;
+ FOnPdfPrintFinished : TOnPdfPrintFinishedEvent;
+ FOnCookiesDeleted : TOnCookiesDeletedEvent;
+ FOnResolvedHostAvailable : TOnResolvedIPsAvailableEvent;
+
+ function GetIsLoading : boolean;
+ function GetMultithreadApp : boolean;
+ function GetHasDocument : boolean;
+ function GetHasView : boolean;
+ function GetHasDevTools : boolean;
+ function GetHasClientHandler : boolean;
+ function GetHasBrowser : boolean;
+ function GetCanGoBack : boolean;
+ function GetCanGoForward : boolean;
+ function GetDocumentURL : string;
+ function GetZoomLevel : double;
+ function GetZoomPct : double;
+ function GetIsPopUp : boolean;
+ function GetWindowHandle : THandle;
+ function GetWindowlessFrameRate : integer;
+ function GetFrameIsFocused : boolean;
+ function GetInitialized : boolean;
+ function GetVisibleNavigationEntry : ICefNavigationEntry;
+ function GetHasValidMainFrame : boolean;
+ function GetFrameCount : NativeUInt;
+ function GetRequestContextCache : string;
+ function GetRequestContextIsGlobal : boolean;
+
+ procedure SetDoNotTrack(aValue : boolean);
+ procedure SetSendReferrer(aValue : boolean);
+ procedure SetHyperlinkAuditing(aValue : boolean);
+ procedure SetWebRTCIPHandlingPolicy(aValue : TCefWebRTCHandlingPolicy);
+ procedure SetWebRTCMultipleRoutes(aValue : TCefState);
+ procedure SetWebRTCNonProxiedUDP(aValue : TCefState);
+ procedure SetCookiePrefs(aValue : integer);
+ procedure SetImagesPrefs(aValue : integer);
+ procedure SetProxyType(aValue : integer);
+ procedure SetProxyScheme(aValue : TCefProxyScheme);
+ procedure SetProxyServer(const aValue : string);
+ procedure SetProxyPort(aValue : integer);
+ procedure SetProxyUsername(const aValue : string);
+ procedure SetProxyPassword(const aValue : string);
+ procedure SetProxyScriptURL(const aValue : string);
+ procedure SetProxyByPassList(const aValue : string);
+ procedure SetCustomHeaderName(const aValue : string);
+ procedure SetCustomHeaderValue(const aValue : string);
+ procedure SetZoomLevel(const aValue : double);
+ procedure SetZoomPct(const aValue : double);
+ procedure SetZoomStep(aValue : byte);
+ procedure SetWindowlessFrameRate(aValue : integer);
+
+
+ function CreateBrowserHost(aWindowInfo : PCefWindowInfo; const aURL : ustring; const aSettings : PCefBrowserSettings; const aContext : ICefRequestContext): Boolean;
+ function CreateBrowserHostSync(aWindowInfo : PCefWindowInfo; const aURL : ustring; const aSettings : PCefBrowserSettings; const aContext : ICefRequestContext): ICefBrowser;
+
+ procedure DestroyClientHandler;
+ procedure DestroyVisitor;
+ procedure DestroyPDFPrintcb;
+ procedure DestroyResolveHostcb;
+ procedure DestroyCookiDeletercb;
+
+ procedure ClearBrowserReference;
+
+ procedure InitializeEvents;
+ procedure InitializeSettings(var aSettings : TCefBrowserSettings);
+
+ procedure GetPrintPDFSettings(var aSettings : TCefPdfPrintSettings; const aTitle, aURL : string);
+
+ function UpdateProxyPrefs : boolean;
+ function UpdatePreference(const aName : string; aValue : boolean) : boolean; overload;
+ function UpdatePreference(const aName : string; aValue : integer) : boolean; overload;
+ function UpdatePreference(const aName : string; const aValue : double) : boolean; overload;
+ function UpdatePreference(const aName, aValue : string) : boolean; overload;
+
+ procedure HandleDictionary(const aDict : ICefDictionaryValue; var aResultSL : TStringList; const aRoot : string);
+ procedure HandleNull(const aValue : ICefValue; var aResultSL : TStringList; const aRoot, aKey : string);
+ procedure HandleBool(const aValue : ICefValue; var aResultSL : TStringList; const aRoot, aKey : string);
+ procedure HandleInteger(const aValue : ICefValue; var aResultSL : TStringList; const aRoot, aKey : string);
+ procedure HandleDouble(const aValue : ICefValue; var aResultSL : TStringList; const aRoot, aKey : string);
+ procedure HandleString(const aValue : ICefValue; var aResultSL : TStringList; const aRoot, aKey : string);
+ procedure HandleBinary(const aValue : ICefValue; var aResultSL : TStringList; const aRoot, aKey : string);
+ procedure HandleList(const aValue : ICefValue; var aResultSL : TStringList; const aRoot, aKey : string);
+ procedure HandleInvalid(const aValue : ICefValue; var aResultSL : TStringList; const aRoot, aKey : string);
+
+ function MustCreateLoadHandler : boolean; virtual;
+ function MustCreateFocusHandler : boolean; virtual;
+ function MustCreateContextMenuHandler : boolean; virtual;
+ function MustCreateDialogHandler : boolean; virtual;
+ function MustCreateKeyboardHandler : boolean; virtual;
+ function MustCreateDisplayHandler : boolean; virtual;
+ function MustCreateDownloadHandler : boolean; virtual;
+ function MustCreateGeolocationHandler : boolean; virtual;
+ function MustCreateJsDialogHandler : boolean; virtual;
+ function MustCreateLifeSpanHandler : boolean; virtual;
+ function MustCreateRequestHandler : boolean; virtual;
+ function MustCreateDragHandler : boolean; virtual;
+ function MustCreateFindHandler : boolean; virtual;
+
+ procedure ApplyZoomStep;
+ function GetParentForm : TCustomForm;
+
+ // IChromiumEvents
+ procedure GetSettings(var aSettings : TCefBrowserSettings);
+
+ // ICefClient
+ function doOnProcessMessageReceived(const browser: ICefBrowser; sourceProcess: TCefProcessId; const aMessage: ICefProcessMessage): Boolean; virtual;
+
+ // ICefLoadHandler
+ procedure doOnLoadStart(const browser: ICefBrowser; const frame: ICefFrame; transitionType: TCefTransitionType); virtual;
+ procedure doOnLoadEnd(const browser: ICefBrowser; const frame: ICefFrame; httpStatusCode: Integer); virtual;
+ procedure doOnLoadError(const browser: ICefBrowser; const frame: ICefFrame; errorCode: Integer; const errorText, failedUrl: ustring); virtual;
+ procedure doOnLoadingStateChange(const browser: ICefBrowser; isLoading, canGoBack, canGoForward: Boolean); virtual;
+
+ // ICefFocusHandler
+ procedure doOnTakeFocus(const browser: ICefBrowser; next: Boolean); virtual;
+ function doOnSetFocus(const browser: ICefBrowser; source: TCefFocusSource): Boolean; virtual;
+ procedure doOnGotFocus(const browser: ICefBrowser); virtual;
+
+ // ICefContextMenuHandler
+ procedure doOnBeforeContextMenu(const browser: ICefBrowser; const frame: ICefFrame; const params: ICefContextMenuParams; const model: ICefMenuModel); virtual;
+ function doRunContextMenu(const browser: ICefBrowser; const frame: ICefFrame; const params: ICefContextMenuParams; const model: ICefMenuModel; const callback: ICefRunContextMenuCallback): Boolean; virtual;
+ function doOnContextMenuCommand(const browser: ICefBrowser; const frame: ICefFrame; const params: ICefContextMenuParams; commandId: Integer; eventFlags: TCefEventFlags): Boolean; virtual;
+ procedure doOnContextMenuDismissed(const browser: ICefBrowser; const frame: ICefFrame); virtual;
+
+ // ICefKeyboardHandler
+ function doOnPreKeyEvent(const browser: ICefBrowser; const event: PCefKeyEvent; osEvent: TCefEventHandle; out isKeyboardShortcut: Boolean): Boolean; virtual;
+ function doOnKeyEvent(const browser: ICefBrowser; const event: PCefKeyEvent; osEvent: TCefEventHandle): Boolean; virtual;
+
+ // ICefDisplayHandler
+ procedure doOnAddressChange(const browser: ICefBrowser; const frame: ICefFrame; const url: ustring); virtual;
+ procedure doOnTitleChange(const browser: ICefBrowser; const title: ustring); virtual;
+ procedure doOnFaviconUrlChange(const browser: ICefBrowser; iconUrls: TStrings); virtual;
+ procedure doOnFullScreenModeChange(const browser: ICefBrowser; fullscreen: Boolean); virtual;
+ function doOnTooltip(const browser: ICefBrowser; var text: ustring): Boolean; virtual;
+ procedure doOnStatusMessage(const browser: ICefBrowser; const value: ustring); virtual;
+ function doOnConsoleMessage(const browser: ICefBrowser; const aMessage, source: ustring; line: Integer): Boolean; virtual;
+ function doOnAutoResize(const browser: ICefBrowser; const new_size: PCefSize): Boolean; virtual;
+
+ // ICefDownloadHandler
+ procedure doOnBeforeDownload(const browser: ICefBrowser; const downloadItem: ICefDownloadItem; const suggestedName: ustring; const callback: ICefBeforeDownloadCallback); virtual;
+ procedure doOnDownloadUpdated(const browser: ICefBrowser; const downloadItem: ICefDownloadItem; const callback: ICefDownloadItemCallback); virtual;
+
+ // ICefGeolocationHandler
+ function doOnRequestGeolocationPermission(const browser: ICefBrowser; const requestingUrl: ustring; requestId: Integer; const callback: ICefGeolocationCallback): Boolean; virtual;
+ procedure doOnCancelGeolocationPermission(const browser: ICefBrowser; requestId: Integer); virtual;
+
+ // ICefJsDialogHandler
+ function doOnJsdialog(const browser: ICefBrowser; const originUrl: ustring; dialogType: TCefJsDialogType; const messageText, defaultPromptText: ustring; const callback: ICefJsDialogCallback; out suppressMessage: Boolean): Boolean; virtual;
+ function doOnBeforeUnloadDialog(const browser: ICefBrowser; const messageText: ustring; isReload: Boolean; const callback: ICefJsDialogCallback): Boolean; virtual;
+ procedure doOnResetDialogState(const browser: ICefBrowser); virtual;
+ procedure doOnDialogClosed(const browser: ICefBrowser); virtual;
+
+ // ICefLifeSpanHandler
+ function doOnBeforePopup(const browser: ICefBrowser; const frame: ICefFrame; const targetUrl, targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; var popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo; var client: ICefClient; var settings: TCefBrowserSettings; var noJavascriptAccess: Boolean): Boolean; virtual;
+ procedure doOnAfterCreated(const browser: ICefBrowser); virtual;
+ procedure doOnBeforeClose(const browser: ICefBrowser); virtual;
+ function doOnClose(const browser: ICefBrowser): Boolean; virtual;
+
+ // ICefRequestHandler
+ function doOnBeforeBrowse(const browser: ICefBrowser; const frame: ICefFrame; const request: ICefRequest; isRedirect: Boolean): Boolean; virtual;
+ function doOnOpenUrlFromTab(const browser: ICefBrowser; const frame: ICefFrame; const targetUrl: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean): Boolean; virtual;
+ function doOnBeforeResourceLoad(const browser: ICefBrowser; const frame: ICefFrame; const request: ICefRequest; const callback: ICefRequestCallback): TCefReturnValue; virtual;
+ function doOnGetResourceHandler(const browser: ICefBrowser; const frame: ICefFrame; const request: ICefRequest): ICefResourceHandler; virtual;
+ procedure doOnResourceRedirect(const browser: ICefBrowser; const frame: ICefFrame; const request: ICefRequest; const response: ICefResponse; var newUrl: ustring); virtual;
+ function doOnResourceResponse(const browser: ICefBrowser; const frame: ICefFrame; const request: ICefRequest; const response: ICefResponse): Boolean; virtual;
+ function doOnGetResourceResponseFilter(const browser: ICefBrowser; const frame: ICefFrame; const request: ICefRequest; const response: ICefResponse): ICefResponseFilter; virtual;
+ procedure doOnResourceLoadComplete(const browser: ICefBrowser; const frame: ICefFrame; const request: ICefRequest; const response: ICefResponse; status: TCefUrlRequestStatus; receivedContentLength: Int64); virtual;
+ function doOnGetAuthCredentials(const browser: ICefBrowser; const frame: ICefFrame; isProxy: Boolean; const host: ustring; port: Integer; const realm, scheme: ustring; const callback: ICefAuthCallback): Boolean; virtual;
+ function doOnQuotaRequest(const browser: ICefBrowser; const originUrl: ustring; newSize: Int64; const callback: ICefRequestCallback): Boolean; virtual;
+ procedure doOnProtocolExecution(const browser: ICefBrowser; const url: ustring; out allowOsExecution: Boolean); virtual;
+ function doOnCertificateError(const browser: ICefBrowser; certError: TCefErrorcode; const requestUrl: ustring; const sslInfo: ICefSslInfo; const callback: ICefRequestCallback): Boolean; virtual;
+ function doOnSelectClientCertificate(const browser: ICefBrowser; isProxy: boolean; const host: ustring; port: integer; certificatesCount: NativeUInt; const certificates: TCefX509CertificateArray; const callback: ICefSelectClientCertificateCallback): boolean; virtual;
+ procedure doOnPluginCrashed(const browser: ICefBrowser; const pluginPath: ustring); virtual;
+ procedure doOnRenderViewReady(const browser: ICefBrowser); virtual;
+ procedure doOnRenderProcessTerminated(const browser: ICefBrowser; status: TCefTerminationStatus); virtual;
+
+ // ICefDialogHandler
+ function doOnFileDialog(const browser: ICefBrowser; mode: TCefFileDialogMode; const title, defaultFilePath: ustring; acceptFilters: TStrings; selectedAcceptFilter: Integer; const callback: ICefFileDialogCallback): Boolean; virtual;
+
+ // ICefRenderHandler
+ procedure doOnGetAccessibilityHandler(var aAccessibilityHandler : ICefAccessibilityHandler); virtual;
+ function doOnGetRootScreenRect(const browser: ICefBrowser; var rect: TCefRect): Boolean; virtual;
+ function doOnGetViewRect(const browser: ICefBrowser; var rect: TCefRect): Boolean; virtual;
+ function doOnGetScreenPoint(const browser: ICefBrowser; viewX, viewY: Integer; var screenX, screenY: Integer): Boolean; virtual;
+ function doOnGetScreenInfo(const browser: ICefBrowser; var screenInfo: TCefScreenInfo): Boolean; virtual;
+ procedure doOnPopupShow(const browser: ICefBrowser; show: Boolean); virtual;
+ procedure doOnPopupSize(const browser: ICefBrowser; const rect: PCefRect); virtual;
+ procedure doOnPaint(const browser: ICefBrowser; kind: TCefPaintElementType; dirtyRectsCount: NativeUInt; const dirtyRects: PCefRectArray; const buffer: Pointer; width, height: Integer); virtual;
+ procedure doOnCursorChange(const browser: ICefBrowser; cursor: TCefCursorHandle; cursorType: TCefCursorType; const customCursorInfo: PCefCursorInfo); virtual;
+ function doOnStartDragging(const browser: ICefBrowser; const dragData: ICefDragData; allowedOps: TCefDragOperations; x, y: Integer): Boolean; virtual;
+ procedure doOnUpdateDragCursor(const browser: ICefBrowser; operation: TCefDragOperation); virtual;
+ procedure doOnScrollOffsetChanged(const browser: ICefBrowser; x, y: Double); virtual;
+ procedure doOnIMECompositionRangeChanged(const browser: ICefBrowser; const selected_range: PCefRange; character_boundsCount: NativeUInt; const character_bounds: PCefRect); virtual;
+
+ // ICefDragHandler
+ function doOnDragEnter(const browser: ICefBrowser; const dragData: ICefDragData; mask: TCefDragOperations): Boolean; virtual;
+ procedure doOnDraggableRegionsChanged(const browser: ICefBrowser; regionsCount: NativeUInt; regions: PCefDraggableRegionArray); virtual;
+
+ // ICefFindHandler
+ procedure doOnFindResult(const browser: ICefBrowser; identifier, count: Integer; const selectionRect: PCefRect; activeMatchOrdinal: Integer; finalUpdate: Boolean); virtual;
+
+ // Custom
+ procedure doCookiesDeleted(numDeleted : integer); virtual;
+ procedure doGetHTML(const aFrameName : ustring); overload;
+ procedure doGetHTML(const aFrame : ICefFrame); overload;
+ procedure doGetHTML(const aFrameIdentifier : int64); overload;
+ procedure doGetText(const aFrameName : ustring); overload;
+ procedure doGetText(const aFrame : ICefFrame); overload;
+ procedure doGetText(const aFrameIdentifier : int64); overload;
+ procedure doPdfPrintFinished(aResultOK : boolean); virtual;
+ procedure doTextResultAvailable(const aText : string); virtual;
+ procedure doUpdatePreferences; virtual;
+ function doSavePreferences : boolean; virtual;
+ procedure doResolvedHostAvailable(result: TCefErrorCode; const resolvedIps: TStrings); virtual;
+
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ procedure AfterConstruction; override;
+ procedure BeforeDestruction; override;
+ function CreateClientHandler : boolean; overload;
+ function CreateClientHandler(var aClient : ICefClient) : boolean; overload;
+ procedure CloseBrowser(aForceClose : boolean);
+ function CreateBrowser(const aWindowName : string = ''; const aContext : ICefRequestContext = nil; const aCookiesPath : string = ''; aPersistSessionCookies : boolean = False) : boolean;
+ function ShareRequestContext(var aContext : ICefRequestContext; const aHandler : ICefRequestContextHandler = nil) : boolean;
+
+ procedure LoadURL(const aURL : ustring);
+ procedure LoadString(const aString : ustring; const aURL : ustring = '');
+ procedure LoadRequest(const aRequest: ICefRequest);
+
+ procedure GoBack;
+ procedure GoForward;
+ procedure Reload;
+ procedure ReloadIgnoreCache;
+ procedure StopLoad;
+ procedure StartDownload(const aURL : ustring);
+
+ procedure SimulateMouseWheel(aDeltaX, aDeltaY : integer);
+ function DeleteCookies : boolean;
+ procedure RetrieveHTML(const aFrameName : ustring = ''); overload;
+ procedure RetrieveHTML(const aFrame : ICefFrame); overload;
+ procedure RetrieveHTML(const aFrameIdentifier : int64); overload;
+ procedure RetrieveText(const aFrameName : ustring = ''); overload;
+ procedure RetrieveText(const aFrame : ICefFrame); overload;
+ procedure RetrieveText(const aFrameIdentifier : int64); overload;
+ function GetFrameNames(var aFrameNames : TStrings) : boolean;
+ function GetFrameIdentifiers(var aFrameCount : NativeUInt; var aFrameIdentifierArray : TCefFrameIdentifierArray) : boolean;
+ procedure ExecuteJavaScript(const aCode, aScriptURL : ustring; const aFrameName : ustring = ''; aStartLine : integer = 0); overload;
+ procedure ExecuteJavaScript(const aCode, aScriptURL : ustring; const aFrame : ICefFrame; aStartLine : integer = 0); overload;
+ procedure ExecuteJavaScript(const aCode, aScriptURL : ustring; const aFrameIdentifier : int64; aStartLine : integer = 0); overload;
+ procedure UpdatePreferences;
+ procedure SavePreferences(const aFileName : string);
+ procedure ResolveHost(const aURL : ustring);
+
+ procedure Find(aIdentifier : integer; const aSearchText : ustring; aForward, aMatchCase, aFindNext : Boolean);
+ procedure StopFinding(aClearSelection : Boolean);
+
+ procedure Print;
+ procedure PrintToPDF(const aFilePath, aTitle, aURL : ustring);
+
+ procedure ClipboardCopy;
+ procedure ClipboardPaste;
+ procedure ClipboardCut;
+ procedure ClipboardUndo;
+ procedure ClipboardRedo;
+ procedure ClipboardDel;
+ procedure SelectAll;
+
+ procedure IncZoomStep;
+ procedure DecZoomStep;
+ procedure ResetZoomStep;
+
+ procedure MoveFormTo(const x, y: Integer);
+ procedure MoveFormBy(const x, y: Integer);
+ procedure ResizeFormWidthTo(const x : Integer);
+ procedure ResizeFormHeightTo(const y : Integer);
+ procedure SetFormLeftTo(const x : Integer);
+ procedure SetFormTopTo(const y : Integer);
+
+ procedure WasResized;
+ procedure WasHidden(hidden: Boolean);
+ procedure NotifyScreenInfoChanged;
+ procedure NotifyMoveOrResizeStarted;
+ procedure Invalidate(kind: TCefPaintElementType = PET_VIEW);
+ procedure SendKeyEvent(const event: PCefKeyEvent);
+ procedure SendMouseClickEvent(const event: PCefMouseEvent; kind: TCefMouseButtonType; mouseUp: Boolean; clickCount: Integer);
+ procedure SendMouseMoveEvent(const event: PCefMouseEvent; mouseLeave: Boolean);
+ procedure SendMouseWheelEvent(const event: PCefMouseEvent; deltaX, deltaY: Integer);
+ procedure SendFocusEvent(setFocus: Boolean);
+ procedure SendCaptureLostEvent;
+ function SendProcessMessage(targetProcess: TCefProcessId; const ProcMessage: ICefProcessMessage): Boolean;
+ procedure SetFocus(focus: Boolean);
+ procedure SetAccessibilityState(accessibilityState: TCefState);
+
+ procedure DragTargetDragEnter(const dragData: ICefDragData; const event: PCefMouseEvent; allowedOps: TCefDragOperations);
+ procedure DragTargetDragOver(const event: PCefMouseEvent; allowedOps: TCefDragOperations);
+ procedure DragTargetDragLeave;
+ procedure DragTargetDrop(event: PCefMouseEvent);
+ procedure DragSourceEndedAt(x, y: Integer; op: TCefDragOperation);
+ procedure DragSourceSystemDragEnded;
+
+
+ property DefaultUrl : ustring read FDefaultUrl write FDefaultUrl;
+ property Options : TChromiumOptions read FOptions write FOptions;
+ property FontOptions : TChromiumFontOptions read FFontOptions write FFontOptions;
+ property PDFPrintOptions : TPDFPrintOptions read FPDFPrintOptions write FPDFPrintOptions;
+ property DefaultEncoding : ustring read FDefaultEncoding write FDefaultEncoding;
+ property BrowserId : integer read FBrowserId;
+ property Browser : ICefBrowser read FBrowser;
+ property CefClient : ICefClient read FHandler;
+ property VisibleNavigationEntry : ICefNavigationEntry read GetVisibleNavigationEntry;
+ property MultithreadApp : boolean read GetMultithreadApp;
+ property IsLoading : boolean read GetIsLoading;
+ property HasDocument : boolean read GetHasDocument;
+ property HasView : boolean read GetHasView;
+ property HasDevTools : boolean read GetHasDevTools;
+ property HasClientHandler : boolean read GetHasClientHandler;
+ property HasBrowser : boolean read GetHasBrowser;
+ property CanGoBack : boolean read GetCanGoBack;
+ property CanGoForward : boolean read GetCanGoForward;
+ property IsPopUp : boolean read GetIsPopUp;
+ property WindowHandle : THandle read GetWindowHandle;
+ property FrameIsFocused : boolean read GetFrameIsFocused;
+ property Initialized : boolean read GetInitialized;
+ property RequestContextCache : string read GetRequestContextCache;
+ property RequestContextIsGlobal : boolean read GetRequestContextIsGlobal;
+ property CookiePrefs : integer read FCookiePrefs write SetCookiePrefs;
+ property ImagesPrefs : integer read FImagesPrefs write SetImagesPrefs;
+ property DocumentURL : string read GetDocumentURL;
+ property WindowName : string read FWindowName write FWindowName;
+ property ZoomLevel : double read GetZoomLevel write SetZoomLevel;
+ property ZoomPct : double read GetZoomPct write SetZoomPct;
+ property ZoomStep : byte read FZoomStep write SetZoomStep;
+ property WindowlessFrameRate : integer read GetWindowlessFrameRate write SetWindowlessFrameRate;
+ property CustomHeaderName : string read FCustomHeaderName write SetCustomHeaderName;
+ property CustomHeaderValue : string read FCustomHeaderValue write SetCustomHeaderValue;
+ property DoNotTrack : boolean read FDoNotTrack write SetDoNotTrack;
+ property SendReferrer : boolean read FSendReferrer write SetSendReferrer;
+ property HyperlinkAuditing : boolean read FHyperlinkAuditing write SetHyperlinkAuditing;
+ property HasValidMainFrame : boolean read GetHasValidMainFrame;
+ property FrameCount : NativeUInt read GetFrameCount;
+ property DragOperations : TCefDragOperations read FDragOperations write FDragOperations;
+
+ property WebRTCIPHandlingPolicy : TCefWebRTCHandlingPolicy read FWebRTCIPHandlingPolicy write SetWebRTCIPHandlingPolicy;
+ property WebRTCMultipleRoutes : TCefState read FWebRTCMultipleRoutes write SetWebRTCMultipleRoutes;
+ property WebRTCNonproxiedUDP : TCefState read FWebRTCNonProxiedUDP write SetWebRTCNonProxiedUDP;
+
+ property ProxyType : integer read FProxyType write SetProxyType;
+ property ProxyScheme : TCefProxyScheme read FProxyScheme write SetProxyScheme;
+ property ProxyServer : string read FProxyServer write SetProxyServer;
+ property ProxyPort : integer read FProxyPort write SetProxyPort;
+ property ProxyUsername : string read FProxyUsername write SetProxyUsername;
+ property ProxyPassword : string read FProxyPassword write SetProxyPassword;
+ property ProxyScriptURL : string read FProxyScriptURL write SetProxyScriptURL;
+ property ProxyByPassList : string read FProxyByPassList write SetProxyByPassList;
+
+ published
+ property OnTextResultAvailable : TOnTextResultAvailableEvent read FOnTextResultAvailable write FOnTextResultAvailable;
+ property OnPdfPrintFinished : TOnPdfPrintFinishedEvent read FOnPdfPrintFinished write FOnPdfPrintFinished;
+ property OnCookiesDeleted : TOnCookiesDeletedEvent read FOnCookiesDeleted write FOnCookiesDeleted;
+ property OnResolvedHostAvailable : TOnResolvedIPsAvailableEvent read FOnResolvedHostAvailable write FOnResolvedHostAvailable;
+
+ // ICefClient
+ property OnProcessMessageReceived : TOnProcessMessageReceived read FOnProcessMessageReceived write FOnProcessMessageReceived;
+
+ // ICefLoadHandler
+ property OnLoadStart : TOnLoadStart read FOnLoadStart write FOnLoadStart;
+ property OnLoadEnd : TOnLoadEnd read FOnLoadEnd write FOnLoadEnd;
+ property OnLoadError : TOnLoadError read FOnLoadError write FOnLoadError;
+ property OnLoadingStateChange : TOnLoadingStateChange read FOnLoadingStateChange write FOnLoadingStateChange;
+
+ // ICefFocusHandler
+ property OnTakeFocus : TOnTakeFocus read FOnTakeFocus write FOnTakeFocus;
+ property OnSetFocus : TOnSetFocus read FOnSetFocus write FOnSetFocus;
+ property OnGotFocus : TOnGotFocus read FOnGotFocus write FOnGotFocus;
+
+ // ICefContextMenuHandler
+ property OnBeforeContextMenu : TOnBeforeContextMenu read FOnBeforeContextMenu write FOnBeforeContextMenu;
+ property OnRunContextMenu : TOnRunContextMenu read FOnRunContextMenu write FOnRunContextMenu;
+ property OnContextMenuCommand : TOnContextMenuCommand read FOnContextMenuCommand write FOnContextMenuCommand;
+ property OnContextMenuDismissed : TOnContextMenuDismissed read FOnContextMenuDismissed write FOnContextMenuDismissed;
+
+ // ICefKeyboardHandler
+ property OnPreKeyEvent : TOnPreKeyEvent read FOnPreKeyEvent write FOnPreKeyEvent;
+ property OnKeyEvent : TOnKeyEvent read FOnKeyEvent write FOnKeyEvent;
+
+ // ICefDisplayHandler
+ property OnAddressChange : TOnAddressChange read FOnAddressChange write FOnAddressChange;
+ property OnTitleChange : TOnTitleChange read FOnTitleChange write FOnTitleChange;
+ property OnFavIconUrlChange : TOnFavIconUrlChange read FOnFavIconUrlChange write FOnFavIconUrlChange;
+ property OnFullScreenModeChange : TOnFullScreenModeChange read FOnFullScreenModeChange write FOnFullScreenModeChange;
+ property OnTooltip : TOnTooltip read FOnTooltip write FOnTooltip;
+ property OnStatusMessage : TOnStatusMessage read FOnStatusMessage write FOnStatusMessage;
+ property OnConsoleMessage : TOnConsoleMessage read FOnConsoleMessage write FOnConsoleMessage;
+ property OnAutoResize : TOnAutoResize read FOnAutoResize write FOnAutoResize;
+
+ // ICefDownloadHandler
+ property OnBeforeDownload : TOnBeforeDownload read FOnBeforeDownload write FOnBeforeDownload;
+ property OnDownloadUpdated : TOnDownloadUpdated read FOnDownloadUpdated write FOnDownloadUpdated;
+
+ // ICefGeolocationHandler
+ property OnRequestGeolocationPermission : TOnRequestGeolocationPermission read FOnRequestGeolocationPermission write FOnRequestGeolocationPermission;
+ property OnCancelGeolocationPermission : TOnCancelGeolocationPermission read FOnCancelGeolocationPermission write FOnCancelGeolocationPermission;
+
+ // ICefJsDialogHandler
+ property OnJsdialog : TOnJsdialog read FOnJsdialog write FOnJsdialog;
+ property OnBeforeUnloadDialog : TOnBeforeUnloadDialog read FOnBeforeUnloadDialog write FOnBeforeUnloadDialog;
+ property OnResetDialogState : TOnResetDialogState read FOnResetDialogState write FOnResetDialogState;
+ property OnDialogClosed : TOnDialogClosed read FOnDialogClosed write FOnDialogClosed;
+
+ // ICefLifeSpanHandler
+ property OnBeforePopup : TOnBeforePopup read FOnBeforePopup write FOnBeforePopup;
+ property OnAfterCreated : TOnAfterCreated read FOnAfterCreated write FOnAfterCreated;
+ property OnBeforeClose : TOnBeforeClose read FOnBeforeClose write FOnBeforeClose;
+ property OnClose : TOnClose read FOnClose write FOnClose;
+
+ // ICefRequestHandler
+ property OnBeforeBrowse : TOnBeforeBrowse read FOnBeforeBrowse write FOnBeforeBrowse;
+ property OnOpenUrlFromTab : TOnOpenUrlFromTab read FOnOpenUrlFromTab write FOnOpenUrlFromTab;
+ property OnBeforeResourceLoad : TOnBeforeResourceLoad read FOnBeforeResourceLoad write FOnBeforeResourceLoad;
+ property OnGetResourceHandler : TOnGetResourceHandler read FOnGetResourceHandler write FOnGetResourceHandler;
+ property OnResourceRedirect : TOnResourceRedirect read FOnResourceRedirect write FOnResourceRedirect;
+ property OnResourceResponse : TOnResourceResponse read FOnResourceResponse write FOnResourceResponse;
+ property OnGetResourceResponseFilter : TOnGetResourceResponseFilter read FOnGetResourceResponseFilter write FOnGetResourceResponseFilter;
+ property OnResourceLoadComplete : TOnResourceLoadComplete read FOnResourceLoadComplete write FOnResourceLoadComplete;
+ property OnGetAuthCredentials : TOnGetAuthCredentials read FOnGetAuthCredentials write FOnGetAuthCredentials;
+ property OnQuotaRequest : TOnQuotaRequest read FOnQuotaRequest write FOnQuotaRequest;
+ property OnProtocolExecution : TOnProtocolExecution read FOnProtocolExecution write FOnProtocolExecution;
+ property OnCertificateError : TOnCertificateError read FOnCertificateError write FOnCertificateError;
+ property OnSelectClientCertificate : TOnSelectClientCertificate read FOnSelectClientCertificate write FOnSelectClientCertificate;
+ property OnPluginCrashed : TOnPluginCrashed read FOnPluginCrashed write FOnPluginCrashed;
+ property OnRenderViewReady : TOnRenderViewReady read FOnRenderViewReady write FOnRenderViewReady;
+ property OnRenderProcessTerminated : TOnRenderProcessTerminated read FOnRenderProcessTerminated write FOnRenderProcessTerminated;
+
+ // ICefDialogHandler
+ property OnFileDialog : TOnFileDialog read FOnFileDialog write FOnFileDialog;
+
+ // ICefRenderHandler
+ property OnGetAccessibilityHandler : TOnGetAccessibilityHandler read FOnGetAccessibilityHandler write FOnGetAccessibilityHandler;
+ property OnGetRootScreenRect : TOnGetRootScreenRect read FOnGetRootScreenRect write FOnGetRootScreenRect;
+ property OnGetViewRect : TOnGetViewRect read FOnGetViewRect write FOnGetViewRect;
+ property OnGetScreenPoint : TOnGetScreenPoint read FOnGetScreenPoint write FOnGetScreenPoint;
+ property OnGetScreenInfo : TOnGetScreenInfo read FOnGetScreenInfo write FOnGetScreenInfo;
+ property OnPopupShow : TOnPopupShow read FOnPopupShow write FOnPopupShow;
+ property OnPopupSize : TOnPopupSize read FOnPopupSize write FOnPopupSize;
+ property OnPaint : TOnPaint read FOnPaint write FOnPaint;
+ property OnCursorChange : TOnCursorChange read FOnCursorChange write FOnCursorChange;
+ property OnScrollOffsetChanged : TOnScrollOffsetChanged read FOnScrollOffsetChanged write FOnScrollOffsetChanged;
+ property OnIMECompositionRangeChanged : TOnIMECompositionRangeChanged read FOnIMECompositionRangeChanged write FOnIMECompositionRangeChanged;
+
+ // ICefDragHandler
+ property OnDragEnter : TOnDragEnter read FOnDragEnter write FOnDragEnter;
+ property OnDraggableRegionsChanged : TOnDraggableRegionsChanged read FOnDraggableRegionsChanged write FOnDraggableRegionsChanged;
+
+ // ICefFindHandler
+ property OnFindResult : TOnFindResult read FOnFindResult write FOnFindResult;
+
+ end;
+
+implementation
+
+uses
+ System.SysUtils, System.Math,
+ uCEFBrowser, uCEFValue, uCEFDictionaryValue, uCEFStringMultimap, uCEFFrame,
+ uCEFApplication, uCEFProcessMessage, uOLEDragAndDrop, uCEFRequestContext,
+ uCEFResolveCallback;
+
+constructor TFMXChromium.Create(AOwner: TComponent);
+begin
+ FBrowser := nil;
+ FBrowserId := 0;
+ FClosing := False;
+ FInitialized := False;
+ FDefaultUrl := 'about:blank';
+ FHandler := nil;
+ FOptions := nil;
+ FFontOptions := nil;
+ FDefaultEncoding := '';
+ FVisitor := nil;
+ FPDFPrintcb := nil;
+ FResolveHostcb := nil;
+ FCookiDeletercb := nil;
+ FPDFPrintOptions := nil;
+ FUpdatePreferences := False;
+ FCustomHeaderName := '';
+ FCustomHeaderValue := '';
+ FPrefsFileName := '';
+ FAddCustomHeader := False;
+ FDoNotTrack := True;
+ FSendReferrer := True;
+ FHyperlinkAuditing := False;
+ FCookiePrefs := CEF_CONTENT_SETTING_ALLOW;
+ FImagesPrefs := CEF_CONTENT_SETTING_ALLOW;
+ FZoomStep := ZOOM_STEP_DEF;
+ FWindowName := '';
+
+ FDragOperations := DRAG_OPERATION_NONE;
+ FDragAndDropInitialized := False;
+
+ FWebRTCIPHandlingPolicy := hpDefault;
+ FWebRTCMultipleRoutes := STATE_DEFAULT;
+ FWebRTCNonProxiedUDP := STATE_DEFAULT;
+
+ FProxyType := CEF_PROXYTYPE_DIRECT;
+ FProxyScheme := psHTTP;
+ FProxyServer := '';
+ FProxyPort := 80;
+ FProxyUsername := '';
+ FProxyPassword := '';
+ FProxyScriptURL := '';
+ FProxyByPassList := '';
+
+ FillChar(FWindowInfo, SizeOf(TCefWindowInfo), 0);
+ FillChar(FDevWindowInfo, SizeOf(TCefWindowInfo), 0);
+
+ InitializeSettings(FBrowserSettings);
+ InitializeSettings(FDevBrowserSettings);
+
+ InitializeEvents;
+
+ inherited Create(AOwner);
+end;
+
+destructor TFMXChromium.Destroy;
+begin
+ try
+ try
+ ClearBrowserReference;
+
+ if (FFontOptions <> nil) then FreeAndNil(FFontOptions);
+ if (FOptions <> nil) then FreeAndNil(FOptions);
+ if (FPDFPrintOptions <> nil) then FreeAndNil(FPDFPrintOptions);
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXChromium.Destroy', e) then raise;
+ end;
+ finally
+ inherited Destroy;
+ end;
+end;
+
+procedure TFMXChromium.BeforeDestruction;
+begin
+ DestroyClientHandler;
+ DestroyVisitor;
+ DestroyPDFPrintcb;
+ DestroyResolveHostcb;
+ DestroyCookiDeletercb;
+
+ inherited BeforeDestruction;
+end;
+
+procedure TFMXChromium.ClearBrowserReference;
+begin
+ FBrowser := nil;
+ FBrowserId := 0;
+end;
+
+procedure TFMXChromium.DestroyClientHandler;
+begin
+ try
+ if (FHandler <> nil) then
+ begin
+ FHandler.InitializeVars;
+ FHandler := nil;
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXChromium.DestroyClientHandler', e) then raise;
+ end;
+end;
+
+procedure TFMXChromium.DestroyVisitor;
+begin
+ try
+ if (FVisitor <> nil) then
+ begin
+ FVisitor.InitializeVars;
+ FVisitor := nil;
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXChromium.DestroyVisitor', e) then raise;
+ end;
+end;
+
+procedure TFMXChromium.DestroyPDFPrintcb;
+begin
+ try
+ if (FPDFPrintcb <> nil) then
+ begin
+ FPDFPrintcb.InitializeVars;
+ FPDFPrintcb := nil;
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXChromium.DestroyPDFPrintcb', e) then raise;
+ end;
+end;
+
+procedure TFMXChromium.DestroyResolveHostcb;
+begin
+ try
+ if (FResolveHostcb <> nil) then
+ begin
+ FResolveHostcb.InitializeVars;
+ FResolveHostcb := nil;
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXChromium.DestroyResolveHostcb', e) then raise;
+ end;
+end;
+
+procedure TFMXChromium.DestroyCookiDeletercb;
+begin
+ try
+ if (FCookiDeletercb <> nil) then
+ begin
+ FCookiDeletercb.InitializeVars;
+ FCookiDeletercb := nil;
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXChromium.DestroyCookiDeletercb', e) then raise;
+ end;
+end;
+
+procedure TFMXChromium.AfterConstruction;
+begin
+ inherited AfterConstruction;
+
+ try
+ if not(csDesigning in ComponentState) then
+ begin
+ FOptions := TChromiumOptions.Create;
+ FFontOptions := TChromiumFontOptions.Create;
+ FPDFPrintOptions := TPDFPrintOptions.Create;
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXChromium.AfterConstruction', e) then raise;
+ end;
+end;
+
+function TFMXChromium.CreateClientHandler : boolean;
+begin
+ Result := False;
+
+ try
+ if (FHandler = nil) then
+ begin
+ FHandler := TCustomClientHandler.Create(Self,
+ MustCreateLoadHandler,
+ MustCreateFocusHandler,
+ MustCreateContextMenuHandler,
+ MustCreateDialogHandler,
+ MustCreateKeyboardHandler,
+ MustCreateDisplayHandler,
+ MustCreateDownloadHandler,
+ MustCreateGeolocationHandler,
+ MustCreateJsDialogHandler,
+ MustCreateLifeSpanHandler,
+ True, // FMX always uses the OSR mode
+ MustCreateRequestHandler,
+ MustCreateDragHandler,
+ MustCreateFindHandler);
+
+ Result := True;
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXChromium.CreateClientHandler', e) then raise;
+ end;
+end;
+
+function TFMXChromium.CreateClientHandler(var aClient : ICefClient) : boolean;
+begin
+ if CreateClientHandler then
+ begin
+ aClient := FHandler;
+ Result := True;
+ end
+ else
+ Result := False;
+end;
+
+procedure TFMXChromium.InitializeEvents;
+begin
+ // ICefClient
+ FOnProcessMessageReceived := nil;
+
+ // ICefLoadHandler
+ FOnLoadStart := nil;
+ FOnLoadEnd := nil;
+ FOnLoadError := nil;
+ FOnLoadingStateChange := nil;
+
+ // ICefFocusHandler
+ FOnTakeFocus := nil;
+ FOnSetFocus := nil;
+ FOnGotFocus := nil;
+
+ // ICefContextMenuHandler
+ FOnBeforeContextMenu := nil;
+ FOnRunContextMenu := nil;
+ FOnContextMenuCommand := nil;
+ FOnContextMenuDismissed := nil;
+
+ // ICefKeyboardHandler
+ FOnPreKeyEvent := nil;
+ FOnKeyEvent := nil;
+
+ // ICefDisplayHandler
+ FOnAddressChange := nil;
+ FOnTitleChange := nil;
+ FOnFavIconUrlChange := nil;
+ FOnFullScreenModeChange := nil;
+ FOnTooltip := nil;
+ FOnStatusMessage := nil;
+ FOnConsoleMessage := nil;
+ FOnAutoResize := nil;
+
+ // ICefDownloadHandler
+ FOnBeforeDownload := nil;
+ FOnDownloadUpdated := nil;
+
+ // ICefGeolocationHandler
+ FOnRequestGeolocationPermission := nil;
+ FOnCancelGeolocationPermission := nil;
+
+ // ICefJsDialogHandler
+ FOnJsdialog := nil;
+ FOnBeforeUnloadDialog := nil;
+ FOnResetDialogState := nil;
+ FOnDialogClosed := nil;
+
+ // ICefLifeSpanHandler
+ FOnBeforePopup := nil;
+ FOnAfterCreated := nil;
+ FOnBeforeClose := nil;
+ FOnClose := nil;
+
+ // ICefRequestHandler
+ FOnBeforeBrowse := nil;
+ FOnOpenUrlFromTab := nil;
+ FOnBeforeResourceLoad := nil;
+ FOnGetResourceHandler := nil;
+ FOnResourceRedirect := nil;
+ FOnResourceResponse := nil;
+ FOnGetResourceResponseFilter := nil;
+ FOnResourceLoadComplete := nil;
+ FOnGetAuthCredentials := nil;
+ FOnQuotaRequest := nil;
+ FOnProtocolExecution := nil;
+ FOnCertificateError := nil;
+ FOnSelectClientCertificate := nil;
+ FOnPluginCrashed := nil;
+ FOnRenderViewReady := nil;
+ FOnRenderProcessTerminated := nil;
+
+ // ICefDialogHandler
+ FOnFileDialog := nil;
+
+ // ICefRenderHandler
+ FOnGetAccessibilityHandler := nil;
+ FOnGetRootScreenRect := nil;
+ FOnGetViewRect := nil;
+ FOnGetScreenPoint := nil;
+ FOnGetScreenInfo := nil;
+ FOnPopupShow := nil;
+ FOnPopupSize := nil;
+ FOnPaint := nil;
+ FOnCursorChange := nil;
+ FOnScrollOffsetChanged := nil;
+ FOnIMECompositionRangeChanged := nil;
+
+ // ICefDragHandler
+ FOnDragEnter := nil;
+ FOnDraggableRegionsChanged := nil;
+
+ // ICefFindHandler
+ FOnFindResult := nil;
+
+ // Custom
+ FOnTextResultAvailable := nil;
+ FOnPdfPrintFinished := nil;
+ FOnCookiesDeleted := nil;
+ FOnResolvedHostAvailable := nil;
+end;
+
+function TFMXChromium.CreateBrowser(const aWindowName : string;
+ const aContext : ICefRequestContext;
+ const aCookiesPath : string;
+ aPersistSessionCookies : boolean) : boolean;
+var
+ TempCookieManager : ICefCookieManager;
+begin
+ Result := False;
+
+ try
+ // GlobalCEFApp.GlobalContextInitialized has to be TRUE before creating any browser
+ // even if you use a custom request context.
+ // If you create a browser in the initialization of your app, make sure you call this
+ // function when GlobalCEFApp.GlobalContextInitialized is TRUE.
+ // Use the GlobalCEFApp.OnContextInitialized event to know when
+ // GlobalCEFApp.GlobalContextInitialized is set to TRUE.
+
+ if not(csDesigning in ComponentState) and
+ not(FClosing) and
+ (FBrowser = nil) and
+ (FBrowserId = 0) and
+ (GlobalCEFApp <> nil) and
+ GlobalCEFApp.GlobalContextInitialized and
+ CreateClientHandler then
+ begin
+ GetSettings(FBrowserSettings);
+ WindowInfoAsWindowless(FWindowInfo, 0, aWindowName);
+
+ if (aContext <> nil) and (length(aCookiesPath) > 0) then
+ begin
+ TempCookieManager := aContext.GetDefaultCookieManager(nil);
+
+ if (TempCookieManager = nil) or
+ not(TempCookieManager.SetStoragePath(aCookiesPath, aPersistSessionCookies, nil)) then
+ OutputDebugMessage('TFMXChromium.CreateBrowser error : cookies cannot be accessed');
+ end;
+
+
+ if MultithreadApp then
+ Result := CreateBrowserHost(@FWindowInfo, FDefaultUrl, @FBrowserSettings, aContext)
+ else
+ begin
+ FBrowser := CreateBrowserHostSync(@FWindowInfo, FDefaultUrl, @FBrowserSettings, aContext);
+
+ if (FBrowser <> nil) then
+ begin
+ FBrowserId := FBrowser.Identifier;
+ FInitialized := (FBrowserId <> 0);
+ Result := True;
+ end;
+ end;
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXChromium.CreateBrowser', e) then raise;
+ end;
+end;
+
+function TFMXChromium.ShareRequestContext(var aContext : ICefRequestContext;
+ const aHandler : ICefRequestContextHandler) : boolean;
+begin
+ Result := False;
+ aContext := nil;
+
+ if Initialized then
+ begin
+ aContext := TCefRequestContextRef.Shared(FBrowser.Host.RequestContext, aHandler);
+ Result := (aContext <> nil);
+ end;
+end;
+
+procedure TFMXChromium.CloseBrowser(aForceClose : boolean);
+begin
+ if Initialized then FBrowser.Host.CloseBrowser(aForceClose);
+end;
+
+function TFMXChromium.CreateBrowserHost(aWindowInfo : PCefWindowInfo;
+ const aURL : ustring;
+ const aSettings : PCefBrowserSettings;
+ const aContext : ICefRequestContext): Boolean;
+var
+ TempURL : TCefString;
+begin
+ TempURL := CefString(aURL);
+ Result := cef_browser_host_create_browser(aWindowInfo, FHandler.Wrap, @TempURL, aSettings, CefGetData(aContext)) <> 0;
+end;
+
+function TFMXChromium.CreateBrowserHostSync(aWindowInfo : PCefWindowInfo;
+ const aURL : ustring;
+ const aSettings : PCefBrowserSettings;
+ const aContext : ICefRequestContext): ICefBrowser;
+var
+ TempURL : TCefString;
+ TempBrowser : PCefBrowser;
+begin
+ TempURL := CefString(aURL);
+ TempBrowser := cef_browser_host_create_browser_sync(aWindowInfo, FHandler.Wrap, @TempURL, aSettings, CefGetData(aContext));
+ Result := TCefBrowserRef.UnWrap(TempBrowser);
+end;
+
+procedure TFMXChromium.Find(aIdentifier : integer; const aSearchText : ustring; aForward, aMatchCase, aFindNext : Boolean);
+begin
+ if Initialized then FBrowser.Host.Find(aIdentifier, aSearchText, aForward, aMatchCase, aFindNext);
+end;
+
+procedure TFMXChromium.StopFinding(aClearSelection : Boolean);
+begin
+ if Initialized then FBrowser.Host.StopFinding(aClearSelection);
+end;
+
+procedure TFMXChromium.Print;
+begin
+ if Initialized then FBrowser.Host.Print;
+end;
+
+procedure TFMXChromium.PrintToPDF(const aFilePath, aTitle, aURL : ustring);
+var
+ TempSettings : TCefPdfPrintSettings;
+begin
+ if Initialized then
+ begin
+ GetPrintPDFSettings(TempSettings, aTitle, aURL);
+ if (FPDFPrintcb = nil) then FPDFPrintcb := TCefCustomPDFPrintCallBack.Create(self);
+ FBrowser.Host.PrintToPdf(aFilePath, @TempSettings, FPDFPrintcb);
+ end;
+end;
+
+procedure TFMXChromium.ClipboardCopy;
+var
+ TempFrame : ICefFrame;
+begin
+ if Initialized then
+ begin
+ TempFrame := FBrowser.FocusedFrame;
+ if (TempFrame = nil) then TempFrame := FBrowser.MainFrame;
+
+ if (TempFrame <> nil) then TempFrame.Copy;
+ end;
+end;
+
+procedure TFMXChromium.ClipboardPaste;
+var
+ TempFrame : ICefFrame;
+begin
+ if Initialized then
+ begin
+ TempFrame := FBrowser.FocusedFrame;
+ if (TempFrame = nil) then TempFrame := FBrowser.MainFrame;
+
+ if (TempFrame <> nil) then TempFrame.Paste;
+ end;
+end;
+
+procedure TFMXChromium.ClipboardCut;
+var
+ TempFrame : ICefFrame;
+begin
+ if Initialized then
+ begin
+ TempFrame := FBrowser.FocusedFrame;
+ if (TempFrame = nil) then TempFrame := FBrowser.MainFrame;
+
+ if (TempFrame <> nil) then TempFrame.Cut;
+ end;
+end;
+
+procedure TFMXChromium.ClipboardUndo;
+var
+ TempFrame : ICefFrame;
+begin
+ if Initialized then
+ begin
+ TempFrame := FBrowser.FocusedFrame;
+ if (TempFrame = nil) then TempFrame := FBrowser.MainFrame;
+
+ if (TempFrame <> nil) then TempFrame.Undo;
+ end;
+end;
+
+procedure TFMXChromium.ClipboardRedo;
+var
+ TempFrame : ICefFrame;
+begin
+ if Initialized then
+ begin
+ TempFrame := FBrowser.FocusedFrame;
+ if (TempFrame = nil) then TempFrame := FBrowser.MainFrame;
+
+ if (TempFrame <> nil) then TempFrame.Redo;
+ end;
+end;
+
+procedure TFMXChromium.ClipboardDel;
+var
+ TempFrame : ICefFrame;
+begin
+ if Initialized then
+ begin
+ TempFrame := FBrowser.FocusedFrame;
+ if (TempFrame = nil) then TempFrame := FBrowser.MainFrame;
+
+ if (TempFrame <> nil) then TempFrame.Del;
+ end;
+end;
+
+procedure TFMXChromium.SelectAll;
+var
+ TempFrame : ICefFrame;
+begin
+ if Initialized then
+ begin
+ TempFrame := FBrowser.FocusedFrame;
+ if (TempFrame = nil) then TempFrame := FBrowser.MainFrame;
+
+ if (TempFrame <> nil) then TempFrame.SelectAll;
+ end;
+end;
+
+procedure TFMXChromium.GetPrintPDFSettings(var aSettings : TCefPdfPrintSettings; const aTitle, aURL : string);
+begin
+ if (FPDFPrintOptions <> nil) then
+ begin
+ aSettings.header_footer_title := CefString(aTitle);
+ aSettings.header_footer_url := CefString(aURL);
+ aSettings.page_width := FPDFPrintOptions.page_width;
+ aSettings.page_height := FPDFPrintOptions.page_height;
+ aSettings.scale_factor := FPDFPrintOptions.scale_factor;
+ aSettings.margin_top := FPDFPrintOptions.margin_top;
+ aSettings.margin_right := FPDFPrintOptions.margin_right;
+ aSettings.margin_bottom := FPDFPrintOptions.margin_bottom;
+ aSettings.margin_left := FPDFPrintOptions.margin_left;
+ aSettings.margin_type := FPDFPrintOptions.margin_type;
+ aSettings.header_footer_enabled := FPDFPrintOptions.header_footer_enabled;
+ aSettings.selection_only := FPDFPrintOptions.selection_only;
+ aSettings.landscape := FPDFPrintOptions.landscape;
+ aSettings.backgrounds_enabled := FPDFPrintOptions.backgrounds_enabled;
+ end;
+end;
+
+procedure TFMXChromium.GetSettings(var aSettings : TCefBrowserSettings);
+begin
+ if (FFontOptions <> nil) and (FOptions <> nil) then
+ begin
+ aSettings.size := SizeOf(TCefBrowserSettings);
+ aSettings.windowless_frame_rate := FOptions.WindowlessFrameRate;
+ aSettings.standard_font_family := CefString(FFontOptions.StandardFontFamily);
+ aSettings.fixed_font_family := CefString(FFontOptions.FixedFontFamily);
+ aSettings.serif_font_family := CefString(FFontOptions.SerifFontFamily);
+ aSettings.sans_serif_font_family := CefString(FFontOptions.SansSerifFontFamily);
+ aSettings.cursive_font_family := CefString(FFontOptions.CursiveFontFamily);
+ aSettings.fantasy_font_family := CefString(FFontOptions.FantasyFontFamily);
+ aSettings.default_font_size := FFontOptions.DefaultFontSize;
+ aSettings.default_fixed_font_size := FFontOptions.DefaultFixedFontSize;
+ aSettings.minimum_font_size := FFontOptions.MinimumFontSize;
+ aSettings.minimum_logical_font_size := FFontOptions.MinimumLogicalFontSize;
+ aSettings.remote_fonts := FFontOptions.RemoteFonts;
+ aSettings.default_encoding := CefString(DefaultEncoding);
+ aSettings.javascript := FOptions.Javascript;
+ aSettings.javascript_close_windows := FOptions.JavascriptCloseWindows;
+ aSettings.javascript_access_clipboard := FOptions.JavascriptAccessClipboard;
+ aSettings.javascript_dom_paste := FOptions.JavascriptDomPaste;
+ aSettings.plugins := FOptions.Plugins;
+ aSettings.universal_access_from_file_urls := FOptions.UniversalAccessFromFileUrls;
+ aSettings.file_access_from_file_urls := FOptions.FileAccessFromFileUrls;
+ aSettings.web_security := FOptions.WebSecurity;
+ aSettings.image_loading := FOptions.ImageLoading;
+ aSettings.image_shrink_standalone_to_fit := FOptions.ImageShrinkStandaloneToFit;
+ aSettings.text_area_resize := FOptions.TextAreaResize;
+ aSettings.tab_to_links := FOptions.TabToLinks;
+ aSettings.local_storage := FOptions.LocalStorage;
+ aSettings.databases := FOptions.Databases;
+ aSettings.application_cache := FOptions.ApplicationCache;
+ aSettings.webgl := FOptions.Webgl;
+ aSettings.background_color := FOptions.BackgroundColor;
+ aSettings.accept_language_list := CefString(FOptions.AcceptLanguageList);
+ end;
+end;
+
+procedure TFMXChromium.InitializeSettings(var aSettings : TCefBrowserSettings);
+begin
+ aSettings.size := SizeOf(TCefBrowserSettings);
+ aSettings.windowless_frame_rate := 30;
+ aSettings.standard_font_family := CefString('');
+ aSettings.fixed_font_family := CefString('');
+ aSettings.serif_font_family := CefString('');
+ aSettings.sans_serif_font_family := CefString('');
+ aSettings.cursive_font_family := CefString('');
+ aSettings.fantasy_font_family := CefString('');
+ aSettings.default_font_size := 0;
+ aSettings.default_fixed_font_size := 0;
+ aSettings.minimum_font_size := 0;
+ aSettings.minimum_logical_font_size := 0;
+ aSettings.remote_fonts := STATE_DEFAULT;
+ aSettings.default_encoding := CefString('');
+ aSettings.javascript := STATE_DEFAULT;
+ aSettings.javascript_close_windows := STATE_DEFAULT;
+ aSettings.javascript_access_clipboard := STATE_DEFAULT;
+ aSettings.javascript_dom_paste := STATE_DEFAULT;
+ aSettings.plugins := STATE_DEFAULT;
+ aSettings.universal_access_from_file_urls := STATE_DEFAULT;
+ aSettings.file_access_from_file_urls := STATE_DEFAULT;
+ aSettings.web_security := STATE_DEFAULT;
+ aSettings.image_loading := STATE_DEFAULT;
+ aSettings.image_shrink_standalone_to_fit := STATE_DEFAULT;
+ aSettings.text_area_resize := STATE_DEFAULT;
+ aSettings.tab_to_links := STATE_DEFAULT;
+ aSettings.local_storage := STATE_DEFAULT;
+ aSettings.databases := STATE_DEFAULT;
+ aSettings.application_cache := STATE_DEFAULT;
+ aSettings.webgl := STATE_DEFAULT;
+ aSettings.background_color := 0;
+ aSettings.accept_language_list := CefString('');
+end;
+
+procedure TFMXChromium.LoadURL(const aURL : ustring);
+var
+ TempFrame : ICefFrame;
+begin
+ if Initialized then
+ begin
+ TempFrame := FBrowser.MainFrame;
+ if (TempFrame <> nil) then TempFrame.LoadUrl(aURL);
+ end;
+end;
+
+procedure TFMXChromium.LoadString(const aString : ustring; const aURL : ustring);
+var
+ TempFrame : ICefFrame;
+begin
+ if Initialized then
+ begin
+ TempFrame := FBrowser.MainFrame;
+ if (TempFrame <> nil) then TempFrame.LoadString(aString, aURL);
+ end;
+end;
+
+procedure TFMXChromium.LoadRequest(const aRequest: ICefRequest);
+var
+ TempFrame : ICefFrame;
+begin
+ if Initialized then
+ begin
+ TempFrame := FBrowser.MainFrame;
+ if (TempFrame <> nil) then TempFrame.LoadRequest(aRequest);
+ end;
+end;
+
+procedure TFMXChromium.GoBack;
+begin
+ if Initialized and CanGoBack then FBrowser.GoBack;
+end;
+
+procedure TFMXChromium.GoForward;
+begin
+ if Initialized and CanGoForward then FBrowser.GoForward;
+end;
+
+procedure TFMXChromium.Reload;
+begin
+ if Initialized then FBrowser.Reload;
+end;
+
+procedure TFMXChromium.ReloadIgnoreCache;
+begin
+ if Initialized then FBrowser.ReloadIgnoreCache;
+end;
+
+procedure TFMXChromium.StopLoad;
+begin
+ if Initialized then FBrowser.StopLoad;
+end;
+
+procedure TFMXChromium.StartDownload(const aURL : ustring);
+begin
+ if Initialized then FBrowser.Host.StartDownload(aURL);
+end;
+
+function TFMXChromium.GetIsLoading : boolean;
+begin
+ Result := Initialized and FBrowser.IsLoading;
+end;
+
+function TFMXChromium.GetMultithreadApp : boolean;
+begin
+ Result := True;
+
+ try
+ if (GlobalCEFApp <> nil) then Result := GlobalCEFApp.MultiThreadedMessageLoop;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXChromium.GetMultithreadApp', e) then raise;
+ end;
+end;
+
+function TFMXChromium.GetHasDocument : boolean;
+begin
+ Result := Initialized and FBrowser.HasDocument;
+end;
+
+function TFMXChromium.GetHasView : boolean;
+begin
+ Result := Initialized and FBrowser.Host.HasView;
+end;
+
+function TFMXChromium.GetHasDevTools : boolean;
+begin
+ Result := Initialized and FBrowser.Host.HasDevTools;
+end;
+
+function TFMXChromium.GetHasClientHandler : boolean;
+begin
+ Result := (FHandler <> nil);
+end;
+
+function TFMXChromium.GetHasBrowser : boolean;
+begin
+ Result := (FBrowser <> nil);
+end;
+
+function TFMXChromium.GetWindowHandle : THandle;
+begin
+ if Initialized then
+ Result := FBrowser.Host.WindowHandle
+ else
+ Result := 0;
+end;
+
+function TFMXChromium.GetFrameIsFocused : boolean;
+begin
+ Result := Initialized and (FBrowser.FocusedFrame <> nil);
+end;
+
+function TFMXChromium.GetWindowlessFrameRate : integer;
+begin
+ if Initialized then
+ Result := FBrowser.Host.GetWindowlessFrameRate
+ else
+ Result := 0;
+end;
+
+function TFMXChromium.GetVisibleNavigationEntry : ICefNavigationEntry;
+begin
+ if Initialized then
+ Result := FBrowser.Host.VisibleNavigationEntry
+ else
+ Result := nil;
+end;
+
+function TFMXChromium.GetHasValidMainFrame : boolean;
+begin
+ Result := Initialized and (FBrowser.MainFrame <> nil) and FBrowser.MainFrame.IsValid;
+end;
+
+function TFMXChromium.GetFrameCount : NativeUInt;
+begin
+ if Initialized then
+ Result := FBrowser.GetFrameCount
+ else
+ Result := 0;
+end;
+
+function TFMXChromium.GetRequestContextCache : string;
+begin
+ if Initialized then
+ Result := FBrowser.host.RequestContext.CachePath
+ else
+ if (GlobalCEFApp <> nil) then
+ Result := GlobalCEFApp.cache
+ else
+ Result := '';
+end;
+
+function TFMXChromium.GetRequestContextIsGlobal : boolean;
+begin
+ Result := Initialized and FBrowser.host.RequestContext.IsGlobal;
+end;
+
+procedure TFMXChromium.SetWindowlessFrameRate(aValue : integer);
+begin
+ if Initialized then FBrowser.Host.SetWindowlessFrameRate(aValue);
+end;
+
+function TFMXChromium.GetCanGoBack : boolean;
+begin
+ Result := Initialized and FBrowser.CanGoBack;
+end;
+
+function TFMXChromium.GetCanGoForward : boolean;
+begin
+ Result := Initialized and FBrowser.CanGoForward;
+end;
+
+function TFMXChromium.GetIsPopUp : boolean;
+begin
+ Result := Initialized and FBrowser.IsPopUp;
+end;
+
+function TFMXChromium.GetInitialized : boolean;
+begin
+ Result := FInitialized and not(FClosing) and (FBrowser <> nil);
+end;
+
+function TFMXChromium.GetDocumentURL : string;
+var
+ TempFrame : ICefFrame;
+begin
+ Result := '';
+
+ if Initialized then
+ begin
+ TempFrame := FBrowser.MainFrame;
+ if (TempFrame <> nil) then Result := TempFrame.URL;
+ end;
+end;
+
+function TFMXChromium.GetZoomLevel : double;
+begin
+ Result := 0;
+
+ if Initialized then Result := FBrowser.Host.ZoomLevel;
+end;
+
+procedure TFMXChromium.SetZoomLevel(const aValue : double);
+begin
+ if Initialized then FBrowser.Host.ZoomLevel := aValue;
+end;
+
+function TFMXChromium.GetZoomPct : double;
+begin
+ Result := power(1.2, ZoomLevel) * 100;
+end;
+
+procedure TFMXChromium.SetZoomPct(const aValue : double);
+begin
+ if Initialized and (aValue > 0) then ZoomLevel := LogN(1.2, aValue / 100);
+end;
+
+procedure TFMXChromium.ApplyZoomStep;
+begin
+ case FZoomStep of
+ ZOOM_STEP_25 : ZoomPct := 25;
+ ZOOM_STEP_33 : ZoomPct := 33;
+ ZOOM_STEP_50 : ZoomPct := 50;
+ ZOOM_STEP_67 : ZoomPct := 67;
+ ZOOM_STEP_75 : ZoomPct := 75;
+ ZOOM_STEP_90 : ZoomPct := 90;
+ ZOOM_STEP_100 : ZoomPct := 100;
+ ZOOM_STEP_110 : ZoomPct := 110;
+ ZOOM_STEP_125 : ZoomPct := 125;
+ ZOOM_STEP_150 : ZoomPct := 150;
+ ZOOM_STEP_175 : ZoomPct := 175;
+ ZOOM_STEP_200 : ZoomPct := 200;
+ ZOOM_STEP_250 : ZoomPct := 250;
+ ZOOM_STEP_300 : ZoomPct := 300;
+ ZOOM_STEP_400 : ZoomPct := 400;
+ ZOOM_STEP_500 : ZoomPct := 500;
+ end;
+end;
+
+procedure TFMXChromium.SetZoomStep(aValue : byte);
+begin
+ if Initialized and (aValue in [ZOOM_STEP_MIN..ZOOM_STEP_MAX]) then
+ begin
+ FZoomStep := aValue;
+ ApplyZoomStep;
+ end;
+end;
+
+procedure TFMXChromium.IncZoomStep;
+begin
+ if Initialized and (FZoomStep < ZOOM_STEP_MAX) then
+ begin
+ inc(FZoomStep);
+ ApplyZoomStep;
+ end;
+end;
+
+procedure TFMXChromium.DecZoomStep;
+begin
+ if Initialized and (FZoomStep > ZOOM_STEP_MIN) then
+ begin
+ dec(FZoomStep);
+ ApplyZoomStep;
+ end;
+end;
+
+procedure TFMXChromium.ResetZoomStep;
+begin
+ ZoomStep := ZOOM_STEP_DEF;
+end;
+
+procedure TFMXChromium.SetDoNotTrack(aValue : boolean);
+begin
+ if (FDoNotTrack <> aValue) then
+ begin
+ FDoNotTrack := aValue;
+ FUpdatePreferences := True;
+ end;
+end;
+
+procedure TFMXChromium.SetSendReferrer(aValue : boolean);
+begin
+ if (FSendReferrer <> aValue) then
+ begin
+ FSendReferrer := aValue;
+ FUpdatePreferences := True;
+ end;
+end;
+
+procedure TFMXChromium.SetHyperlinkAuditing(aValue : boolean);
+begin
+ if (FHyperlinkAuditing <> aValue) then
+ begin
+ FHyperlinkAuditing := aValue;
+ FUpdatePreferences := True;
+ end;
+end;
+
+procedure TFMXChromium.SetWebRTCIPHandlingPolicy(aValue : TCefWebRTCHandlingPolicy);
+begin
+ if (FWebRTCIPHandlingPolicy <> aValue) then
+ begin
+ FWebRTCIPHandlingPolicy := aValue;
+ FUpdatePreferences := True;
+ end;
+end;
+
+procedure TFMXChromium.SetWebRTCMultipleRoutes(aValue : TCefState);
+begin
+ if (FWebRTCMultipleRoutes <> aValue) then
+ begin
+ FWebRTCMultipleRoutes := aValue;
+ FUpdatePreferences := True;
+ end;
+end;
+
+procedure TFMXChromium.SetWebRTCNonProxiedUDP(aValue : TCefState);
+begin
+ if (FWebRTCNonProxiedUDP <> aValue) then
+ begin
+ FWebRTCNonProxiedUDP := aValue;
+ FUpdatePreferences := True;
+ end;
+end;
+
+procedure TFMXChromium.SetCookiePrefs(aValue : integer);
+begin
+ if (FCookiePrefs <> aValue) then
+ begin
+ FCookiePrefs := aValue;
+ FUpdatePreferences := True;
+ end;
+end;
+
+procedure TFMXChromium.SetImagesPrefs(aValue : integer);
+begin
+ if (FImagesPrefs <> aValue) then
+ begin
+ FImagesPrefs := aValue;
+ FUpdatePreferences := True;
+ end;
+end;
+
+procedure TFMXChromium.SetProxyType(aValue : integer);
+begin
+ if (FProxyType <> aValue) then
+ begin
+ FProxyType := aValue;
+ FUpdatePreferences := True;
+ end;
+end;
+
+procedure TFMXChromium.SetProxyScheme(aValue : TCefProxyScheme);
+begin
+ if (FProxyScheme <> aValue) then
+ begin
+ FProxyScheme := aValue;
+ FUpdatePreferences := True;
+ end;
+end;
+
+procedure TFMXChromium.SetProxyServer(const aValue : string);
+begin
+ if (FProxyServer <> aValue) then
+ begin
+ FProxyServer := aValue;
+ FUpdatePreferences := True;
+ end;
+end;
+
+procedure TFMXChromium.SetProxyPort(aValue : integer);
+begin
+ if (FProxyPort <> aValue) then
+ begin
+ FProxyPort := aValue;
+ FUpdatePreferences := True;
+ end;
+end;
+
+procedure TFMXChromium.SetProxyUsername(const aValue : string);
+begin
+ if (FProxyUsername <> aValue) then
+ begin
+ FProxyUsername := aValue;
+ FUpdatePreferences := True;
+ end;
+end;
+
+procedure TFMXChromium.SetProxyPassword(const aValue : string);
+begin
+ if (FProxyPassword <> aValue) then
+ begin
+ FProxyPassword := aValue;
+ FUpdatePreferences := True;
+ end;
+end;
+
+procedure TFMXChromium.SetProxyScriptURL(const aValue : string);
+begin
+ if (FProxyScriptURL <> aValue) then
+ begin
+ FProxyScriptURL := aValue;
+ FUpdatePreferences := True;
+ end;
+end;
+
+procedure TFMXChromium.SetProxyByPassList(const aValue : string);
+begin
+ if (FProxyByPassList <> aValue) then
+ begin
+ FProxyByPassList := aValue;
+ FUpdatePreferences := True;
+ end;
+end;
+
+procedure TFMXChromium.SetCustomHeaderName(const aValue : string);
+begin
+ if (FCustomHeaderName <> aValue) then
+ begin
+ FCustomHeaderName := aValue;
+ FAddCustomHeader := (length(FCustomHeaderName) > 0) and (length(FCustomHeaderValue) > 0);
+ end;
+end;
+
+procedure TFMXChromium.SetCustomHeaderValue(const aValue : string);
+begin
+ if (FCustomHeaderValue <> aValue) then
+ begin
+ FCustomHeaderValue := aValue;
+ FAddCustomHeader := (length(FCustomHeaderName) > 0) and (length(FCustomHeaderValue) > 0);
+ end;
+end;
+
+procedure TFMXChromium.doGetHTML(const aFrameName : ustring);
+var
+ TempFrame : ICefFrame;
+begin
+ if Initialized then
+ begin
+ if (length(aFrameName) > 0) then
+ TempFrame := FBrowser.GetFrame(aFrameName)
+ else
+ TempFrame := FBrowser.MainFrame;
+
+ if (TempFrame <> nil) then
+ begin
+ if (FVisitor = nil) then FVisitor := TCustomCefStringVisitor.Create(self);
+ TempFrame.GetSource(FVisitor);
+ end;
+ end;
+end;
+
+procedure TFMXChromium.doGetHTML(const aFrame : ICefFrame);
+begin
+ if Initialized and (aFrame <> nil) then
+ begin
+ if (FVisitor = nil) then FVisitor := TCustomCefStringVisitor.Create(self);
+ aFrame.GetSource(FVisitor);
+ end;
+end;
+
+procedure TFMXChromium.doGetHTML(const aFrameIdentifier : int64);
+var
+ TempFrame : ICefFrame;
+begin
+ if Initialized then
+ begin
+ if (aFrameIdentifier <> 0) then
+ TempFrame := FBrowser.GetFrameByident(aFrameIdentifier)
+ else
+ TempFrame := FBrowser.MainFrame;
+
+ if (TempFrame <> nil) then
+ begin
+ if (FVisitor = nil) then FVisitor := TCustomCefStringVisitor.Create(self);
+ TempFrame.GetSource(FVisitor);
+ end;
+ end;
+end;
+
+procedure TFMXChromium.doGetText(const aFrameName : ustring);
+var
+ TempFrame : ICefFrame;
+begin
+ if Initialized then
+ begin
+ if (length(aFrameName) > 0) then
+ TempFrame := FBrowser.GetFrame(aFrameName)
+ else
+ TempFrame := FBrowser.MainFrame;
+
+ if (TempFrame <> nil) then
+ begin
+ if (FVisitor = nil) then FVisitor := TCustomCefStringVisitor.Create(self);
+ TempFrame.GetText(FVisitor);
+ end;
+ end;
+end;
+
+procedure TFMXChromium.doGetText(const aFrame : ICefFrame);
+begin
+ if Initialized and (aFrame <> nil) then
+ begin
+ if (FVisitor = nil) then FVisitor := TCustomCefStringVisitor.Create(self);
+ aFrame.GetText(FVisitor);
+ end;
+end;
+
+procedure TFMXChromium.doGetText(const aFrameIdentifier : int64);
+var
+ TempFrame : ICefFrame;
+begin
+ if Initialized then
+ begin
+ if (aFrameIdentifier <> 0) then
+ TempFrame := FBrowser.GetFrameByident(aFrameIdentifier)
+ else
+ TempFrame := FBrowser.MainFrame;
+
+ if (TempFrame <> nil) then
+ begin
+ if (FVisitor = nil) then FVisitor := TCustomCefStringVisitor.Create(self);
+ TempFrame.GetText(FVisitor);
+ end;
+ end;
+end;
+
+function TFMXChromium.DeleteCookies : boolean;
+var
+ TempManager : ICefCookieManager;
+begin
+ Result := False;
+
+ if Initialized and (FBrowser.Host <> nil) and (FBrowser.Host.RequestContext <> nil) then
+ begin
+ TempManager := FBrowser.Host.RequestContext.GetDefaultCookieManager(nil);
+
+ if (TempManager <> nil) then
+ begin
+ if (FCookiDeletercb = nil) then FCookiDeletercb := TCefCustomDeleteCookiesCallback.Create(self);
+
+ Result := TempManager.DeleteCookies('', '', FCookiDeletercb);
+ end;
+ end;
+end;
+
+// Leave aFrameName empty to get the HTML source from the main frame
+procedure TFMXChromium.RetrieveHTML(const aFrameName : ustring);
+var
+ TempTask: ICefTask;
+begin
+ // Results will be received in the OnTextResultAvailable event of this class
+ if Initialized then
+ begin
+ TempTask := TCefGetHTMLTask.Create(self, aFrameName);
+ CefPostTask(TID_UI, TempTask);
+ end;
+end;
+
+procedure TFMXChromium.RetrieveHTML(const aFrame : ICefFrame);
+var
+ TempTask: ICefTask;
+begin
+ // Results will be received in the OnTextResultAvailable event of this class
+ if Initialized then
+ begin
+ TempTask := TCefGetHTMLTask.Create(self, aFrame);
+ CefPostTask(TID_UI, TempTask);
+ end;
+end;
+
+procedure TFMXChromium.RetrieveHTML(const aFrameIdentifier : int64);
+var
+ TempTask: ICefTask;
+begin
+ // Results will be received in the OnTextResultAvailable event of this class
+ if Initialized then
+ begin
+ TempTask := TCefGetHTMLTask.Create(self, aFrameIdentifier);
+ CefPostTask(TID_UI, TempTask);
+ end;
+end;
+
+// Leave aFrameName empty to get the HTML source from the main frame
+procedure TFMXChromium.RetrieveText(const aFrameName : ustring);
+var
+ TempTask: ICefTask;
+begin
+ // Results will be received in the OnTextResultAvailable event of this class
+ if Initialized then
+ begin
+ TempTask := TCefGetTextTask.Create(self, aFrameName);
+ CefPostTask(TID_UI, TempTask);
+ end;
+end;
+
+procedure TFMXChromium.RetrieveText(const aFrame : ICefFrame);
+var
+ TempTask: ICefTask;
+begin
+ // Results will be received in the OnTextResultAvailable event of this class
+ if Initialized then
+ begin
+ TempTask := TCefGetTextTask.Create(self, aFrame);
+ CefPostTask(TID_UI, TempTask);
+ end;
+end;
+
+procedure TFMXChromium.RetrieveText(const aFrameIdentifier : int64);
+var
+ TempTask: ICefTask;
+begin
+ // Results will be received in the OnTextResultAvailable event of this class
+ if Initialized then
+ begin
+ TempTask := TCefGetTextTask.Create(self, aFrameIdentifier);
+ CefPostTask(TID_UI, TempTask);
+ end;
+end;
+
+function TFMXChromium.GetFrameNames(var aFrameNames : TStrings) : boolean;
+begin
+ Result := Initialized and FBrowser.GetFrameNames(aFrameNames);
+end;
+
+function TFMXChromium.GetFrameIdentifiers(var aFrameCount : NativeUInt; var aFrameIdentifierArray : TCefFrameIdentifierArray) : boolean;
+begin
+ Result := Initialized and FBrowser.GetFrameIdentifiers(aFrameCount, aFrameIdentifierArray);
+end;
+
+procedure TFMXChromium.UpdatePreferences;
+var
+ TempTask: ICefTask;
+begin
+ if Initialized then
+ begin
+ TempTask := TCefUpdatePrefsTask.Create(self);
+ CefPostTask(TID_UI, TempTask);
+ end;
+end;
+
+procedure TFMXChromium.SavePreferences(const aFileName : string);
+var
+ TempTask: ICefTask;
+begin
+ if Initialized and (length(aFileName) > 0) then
+ begin
+ FPrefsFileName := aFileName;
+ TempTask := TCefSavePrefsTask.Create(self);
+ CefPostTask(TID_UI, TempTask);
+ end;
+end;
+
+procedure TFMXChromium.ResolveHost(const aURL : ustring);
+begin
+ // Results will be received in the OnResolvedHostAvailable event of this class
+ if Initialized and (length(aURL) > 0) then
+ begin
+ if (FResolveHostcb = nil) then FResolveHostcb := TCefCustomResolveCallback.Create(self);
+ FBrowser.Host.RequestContext.ResolveHost(aURL, FResolveHostcb);
+ end;
+end;
+
+procedure TFMXChromium.SimulateMouseWheel(aDeltaX, aDeltaY : integer);
+var
+ TempEvent : TCefMouseEvent;
+begin
+ if Initialized then
+ begin
+ TempEvent.x := 0;
+ TempEvent.y := 0;
+ TempEvent.modifiers := EVENTFLAG_NONE;
+ FBrowser.Host.SendMouseWheelEvent(@TempEvent, aDeltaX, aDeltaY);
+ end;
+end;
+
+procedure TFMXChromium.doUpdatePreferences;
+begin
+ FUpdatePreferences := False;
+
+ UpdateProxyPrefs;
+ UpdatePreference('enable_do_not_track', FDoNotTrack);
+ UpdatePreference('enable_referrers', FSendReferrer);
+ UpdatePreference('enable_a_ping', FHyperlinkAuditing);
+
+ case FWebRTCIPHandlingPolicy of
+ hpDefaultPublicAndPrivateInterfaces :
+ UpdatePreference('webrtc.ip_handling_policy', 'default_public_and_private_interfaces');
+
+ hpDefaultPublicInterfaceOnly :
+ UpdatePreference('webrtc.ip_handling_policy', 'default_public_interface_only');
+
+ hpDisableNonProxiedUDP :
+ UpdatePreference('webrtc.ip_handling_policy', 'disable_non_proxied_udp');
+ end;
+
+ if (FWebRTCMultipleRoutes <> STATE_DEFAULT) then
+ UpdatePreference('webrtc.multiple_routes_enabled', (FWebRTCMultipleRoutes = STATE_ENABLED));
+
+ if (FWebRTCNonProxiedUDP <> STATE_DEFAULT) then
+ UpdatePreference('webrtc.nonproxied_udp_enabled', (FWebRTCNonProxiedUDP = STATE_ENABLED));
+end;
+
+function TFMXChromium.UpdateProxyPrefs : boolean;
+var
+ TempError : ustring;
+ TempProxy : ICefValue;
+ TempValue : ICefValue;
+ TempDict : ICefDictionaryValue;
+begin
+ Result := False;
+
+ try
+ if (FBrowser <> nil) and FBrowser.Host.RequestContext.CanSetPreference('proxy') then
+ begin
+ TempProxy := TCefValueRef.New;
+ TempValue := TCefValueRef.New;
+ TempDict := TCefDictionaryValueRef.New;
+
+ case FProxyType of
+ CEF_PROXYTYPE_AUTODETECT :
+ begin
+ TempValue.SetString('auto_detect');
+ TempDict.SetValue('mode', TempValue);
+ end;
+
+ CEF_PROXYTYPE_SYSTEM :
+ begin
+ TempValue.SetString('system');
+ TempDict.SetValue('mode', TempValue);
+ end;
+
+ CEF_PROXYTYPE_FIXED_SERVERS :
+ begin
+ TempValue.SetString('fixed_servers');
+ TempDict.SetValue('mode', TempValue);
+
+ case FProxyScheme of
+ psSOCKS4 : TempDict.SetString('server', 'socks4://' + FProxyServer + ':' + inttostr(FProxyPort));
+ psSOCKS5 : TempDict.SetString('server', 'socks5://' + FProxyServer + ':' + inttostr(FProxyPort));
+ else TempDict.SetString('server', FProxyServer + ':' + inttostr(FProxyPort));
+ end;
+
+ if (length(FProxyByPassList) > 0) then TempDict.SetString('bypass_list', FProxyByPassList);
+ end;
+
+ CEF_PROXYTYPE_PAC_SCRIPT :
+ begin
+ TempValue.SetString('pac_script');
+ TempDict.SetValue('mode', TempValue);
+ TempDict.SetString('pac_url', FProxyScriptURL);
+ end;
+
+ else // CEF_PROXYTYPE_DIRECT
+ begin
+ TempValue.SetString('direct');
+ TempDict.SetValue('mode', TempValue);
+ end;
+ end;
+
+ Result := TempProxy.SetDictionary(TempDict) and
+ FBrowser.Host.RequestContext.SetPreference('proxy', TempProxy, TempError);
+
+ if not(Result) then
+ OutputDebugMessage('TFMXChromium.UpdateProxyPrefs error : ' + quotedstr(TempError));
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXChromium.UpdateProxyPrefs', e) then raise;
+ end;
+end;
+
+function TFMXChromium.UpdatePreference(const aName : string; aValue : boolean) : boolean;
+var
+ TempError : ustring;
+ TempValue : ICefValue;
+begin
+ Result := False;
+
+ try
+ if (FBrowser <> nil) and FBrowser.Host.RequestContext.CanSetPreference(aName) then
+ begin
+ TempValue := TCefValueRef.New;
+
+ if aValue then
+ TempValue.SetBool(1)
+ else
+ TempValue.SetBool(0);
+
+ Result := FBrowser.Host.RequestContext.SetPreference(aName, TempValue, TempError);
+
+ if not(Result) then
+ OutputDebugMessage('TFMXChromium.UpdatePreference error : ' + quotedstr(TempError));
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXChromium.UpdatePreference', e) then raise;
+ end;
+end;
+
+function TFMXChromium.UpdatePreference(const aName : string; aValue : integer) : boolean;
+var
+ TempError : ustring;
+ TempValue : ICefValue;
+begin
+ Result := False;
+
+ try
+ if (FBrowser <> nil) and FBrowser.Host.RequestContext.CanSetPreference(aName) then
+ begin
+ TempValue := TCefValueRef.New;
+ TempValue.SetInt(aValue);
+ Result := FBrowser.Host.RequestContext.SetPreference(aName, TempValue, TempError);
+
+ if not(Result) then
+ OutputDebugMessage('TFMXChromium.UpdatePreference error : ' + quotedstr(TempError));
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXChromium.UpdatePreference', e) then raise;
+ end;
+end;
+
+function TFMXChromium.UpdatePreference(const aName : string; const aValue : double) : boolean;
+var
+ TempError : ustring;
+ TempValue : ICefValue;
+begin
+ Result := False;
+
+ try
+ if (FBrowser <> nil) and FBrowser.Host.RequestContext.CanSetPreference(aName) then
+ begin
+ TempValue := TCefValueRef.New;
+ TempValue.SetDouble(aValue);
+ Result := FBrowser.Host.RequestContext.SetPreference(aName, TempValue, TempError);
+
+ if not(Result) then
+ OutputDebugMessage('TFMXChromium.UpdatePreference error : ' + quotedstr(TempError));
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXChromium.UpdatePreference', e) then raise;
+ end;
+end;
+
+function TFMXChromium.UpdatePreference(const aName, aValue : string) : boolean;
+var
+ TempError : ustring;
+ TempValue : ICefValue;
+begin
+ Result := False;
+
+ try
+ if (FBrowser <> nil) and FBrowser.Host.RequestContext.CanSetPreference(aName) then
+ begin
+ TempValue := TCefValueRef.New;
+ TempValue.SetString(aValue);
+ Result := FBrowser.Host.RequestContext.SetPreference(aName, TempValue, TempError);
+
+ if not(Result) then
+ OutputDebugMessage('TFMXChromium.UpdatePreference error : ' + quotedstr(TempError));
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXChromium.UpdatePreference', e) then raise;
+ end;
+end;
+
+procedure TFMXChromium.HandleNull(const aValue : ICefValue; var aResultSL : TStringList; const aRoot, aKey : string);
+var
+ TempKey : string;
+begin
+ if (aRoot <> '') then
+ TempKey := aRoot + '.' + aKey
+ else
+ TempKey := aKey;
+
+ if (length(TempKey) > 0) then
+ aResultSL.Add(TempKey + ' : -null-')
+ else
+ aResultSL.Add('-null-');
+end;
+
+procedure TFMXChromium.HandleBool(const aValue : ICefValue; var aResultSL : TStringList; const aRoot, aKey : string);
+var
+ TempKey : string;
+begin
+ if (aRoot <> '') then
+ TempKey := aRoot + '.' + aKey
+ else
+ TempKey := aKey;
+
+ if (length(TempKey) > 0) then
+ aResultSL.Add(TempKey + ' : ' + BoolToStr(aValue.GetBool, true))
+ else
+ aResultSL.Add(BoolToStr(aValue.GetBool, true));
+end;
+
+procedure TFMXChromium.HandleInteger(const aValue : ICefValue; var aResultSL : TStringList; const aRoot, aKey : string);
+var
+ TempKey : string;
+begin
+ if (aRoot <> '') then
+ TempKey := aRoot + '.' + aKey
+ else
+ TempKey := aKey;
+
+ if (length(TempKey) > 0) then
+ aResultSL.Add(TempKey + ' : ' + IntToStr(aValue.GetInt))
+ else
+ aResultSL.Add(IntToStr(aValue.GetInt));
+end;
+
+procedure TFMXChromium.HandleDouble(const aValue : ICefValue; var aResultSL : TStringList; const aRoot, aKey : string);
+var
+ TempKey : string;
+begin
+ if (aRoot <> '') then
+ TempKey := aRoot + '.' + aKey
+ else
+ TempKey := aKey;
+
+ if (length(TempKey) > 0) then
+ aResultSL.Add(TempKey + ' : ' + FloatToStr(aValue.GetDouble))
+ else
+ aResultSL.Add(FloatToStr(aValue.GetDouble));
+end;
+
+procedure TFMXChromium.HandleString(const aValue : ICefValue; var aResultSL : TStringList; const aRoot, aKey : string);
+var
+ TempKey : string;
+begin
+ if (aRoot <> '') then
+ TempKey := aRoot + '.' + aKey
+ else
+ TempKey := aKey;
+
+ if (length(TempKey) > 0) then
+ aResultSL.Add(TempKey + ' : ' + aValue.GetString)
+ else
+ aResultSL.Add(aValue.GetString);
+end;
+
+procedure TFMXChromium.HandleBinary(const aValue : ICefValue; var aResultSL : TStringList; const aRoot, aKey : string);
+var
+ TempKey : string;
+begin
+ if (aRoot <> '') then
+ TempKey := aRoot + '.' + aKey
+ else
+ TempKey := aKey;
+
+ if (length(TempKey) > 0) then
+ aResultSL.Add(TempKey + ' : -binary-')
+ else
+ aResultSL.Add('-binary-');
+end;
+
+procedure TFMXChromium.HandleList(const aValue : ICefValue; var aResultSL : TStringList; const aRoot, aKey : string);
+var
+ TempKey, TempResult : string;
+ i, j : integer;
+ TempList : ICefListValue;
+ TempValue : ICefValue;
+ TempSL : TStringList;
+begin
+ if (aRoot <> '') then
+ TempKey := aRoot + '.' + aKey
+ else
+ TempKey := aKey;
+
+ TempList := aValue.GetList;
+ TempSL := TStringList.Create;
+
+ i := 0;
+ j := TempList.GetSize;
+
+ TempResult := '(' + inttostr(j) + '){';
+
+ while (i < j) do
+ begin
+ TempValue := TempList.GetValue(i);
+
+ case TempValue.GetType of
+ VTYPE_NULL : TempResult := TempResult + '-null-,';
+ VTYPE_BOOL : TempResult := TempResult + BoolToStr(aValue.GetBool, true) + ',';
+ VTYPE_INT : TempResult := TempResult + IntToStr(aValue.GetInt) + ',';
+ VTYPE_DOUBLE : TempResult := TempResult + FloatToStr(aValue.GetDouble) + ',';
+ VTYPE_STRING : TempResult := TempResult + aValue.GetString + ',';
+ VTYPE_BINARY : TempResult := TempResult + '-binary-,';
+ VTYPE_DICTIONARY :
+ begin
+ TempSL.Clear;
+ HandleDictionary(TempValue.GetDictionary, TempSL, '');
+ TempResult := TempResult + TempSL.CommaText + ',';
+ end;
+
+ VTYPE_LIST :
+ begin
+ TempSL.Clear;
+ HandleList(TempValue, TempSL, '', '');
+ TempResult := TempResult + TempSL.CommaText + ',';
+ end;
+
+ else TempResult := TempResult + '-invalid-,';
+ end;
+
+ inc(i);
+ end;
+
+ i := length(TempResult);
+ if (i > 0) and (TempResult[i] = ',') then TempResult := copy(TempResult, 1, pred(i));
+ TempResult := TempResult + '}';
+
+ if (length(TempKey) > 0) then
+ aResultSL.Add(TempKey + ' : ' + TempResult)
+ else
+ aResultSL.Add(TempResult);
+
+ TempSL.Free;
+end;
+
+procedure TFMXChromium.HandleInvalid(const aValue : ICefValue; var aResultSL : TStringList; const aRoot, aKey : string);
+var
+ TempKey : string;
+begin
+ if (aRoot <> '') then
+ TempKey := aRoot + '.' + aKey
+ else
+ TempKey := aKey;
+
+ if (length(TempKey) > 0) then
+ aResultSL.Add(TempKey + ' : -invalid-')
+ else
+ aResultSL.Add('-invalid-');
+end;
+
+procedure TFMXChromium.HandleDictionary(const aDict : ICefDictionaryValue; var aResultSL : TStringList; const aRoot : string);
+var
+ TempKeys : TStringList;
+ i, j : integer;
+ TempValue : ICefValue;
+ TempNewKey : string;
+begin
+ TempKeys := nil;
+
+ try
+ try
+ if (aDict <> nil) then
+ begin
+ TempKeys := TStringList.Create;
+ aDict.GetKeys(TempKeys);
+
+ i := 0;
+ j := TempKeys.Count;
+
+ while (i < j) do
+ begin
+ TempValue := aDict.GetValue(TempKeys[i]);
+
+ case TempValue.GetType of
+ VTYPE_NULL : HandleNull(TempValue, aResultSL, aRoot, TempKeys[i]);
+ VTYPE_BOOL : HandleBool(TempValue, aResultSL, aRoot, TempKeys[i]);
+ VTYPE_INT : HandleInteger(TempValue, aResultSL, aRoot, TempKeys[i]);
+ VTYPE_DOUBLE : HandleDouble(TempValue, aResultSL, aRoot, TempKeys[i]);
+ VTYPE_STRING : HandleString(TempValue, aResultSL, aRoot, TempKeys[i]);
+ VTYPE_BINARY : HandleBinary(TempValue, aResultSL, aRoot, TempKeys[i]);
+ VTYPE_LIST : HandleList(TempValue, aResultSL, aRoot, TempKeys[i]);
+ VTYPE_DICTIONARY :
+ begin
+ if (length(aRoot) > 0) then
+ TempNewKey := aRoot + '.' + TempKeys[i]
+ else
+ TempNewKey := TempKeys[i];
+
+ HandleDictionary(TempValue.GetDictionary, aResultSL, TempNewKey);
+ end;
+
+ else
+ HandleInvalid(TempValue, aResultSL, aRoot, TempKeys[i]);
+ end;
+
+ inc(i);
+ end;
+
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXChromium.HandleDictionary', e) then raise;
+ end;
+ finally
+ if (TempKeys <> nil) then TempKeys.Free;
+ end;
+end;
+
+function TFMXChromium.doSavePreferences : boolean;
+var
+ TempDict : ICefDictionaryValue;
+ TempPrefs : TStringList;
+begin
+ Result := False;
+ TempPrefs := nil;
+
+ try
+ try
+ if Initialized then
+ begin
+ TempPrefs := TStringList.Create;
+ TempDict := FBrowser.Host.RequestContext.GetAllPreferences(True);
+ HandleDictionary(TempDict, TempPrefs, '');
+ TempPrefs.SaveToFile(FPrefsFileName);
+ Result := True;
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXChromium.Internal_SavePreferences', e) then raise;
+ end;
+ finally
+ if (TempPrefs <> nil) then FreeAndNil(TempPrefs);
+ end;
+end;
+
+procedure TFMXChromium.doResolvedHostAvailable(result: TCefErrorCode; const resolvedIps: TStrings);
+begin
+ if assigned(FOnResolvedHostAvailable) then FOnResolvedHostAvailable(self, result, resolvedIps);
+end;
+
+function TFMXChromium.MustCreateLoadHandler : boolean;
+begin
+ Result := assigned(FOnLoadStart) or
+ assigned(FOnLoadEnd) or
+ assigned(FOnLoadError) or
+ assigned(FOnLoadingStateChange);
+end;
+
+function TFMXChromium.MustCreateFocusHandler : boolean;
+begin
+ Result := assigned(FOnTakeFocus) or
+ assigned(FOnSetFocus) or
+ assigned(FOnGotFocus);
+end;
+
+function TFMXChromium.MustCreateContextMenuHandler : boolean;
+begin
+ Result := assigned(FOnBeforeContextMenu) or
+ assigned(FOnRunContextMenu) or
+ assigned(FOnContextMenuCommand) or
+ assigned(FOnContextMenuDismissed);
+end;
+
+function TFMXChromium.MustCreateDialogHandler : boolean;
+begin
+ Result := assigned(FOnFileDialog);
+end;
+
+function TFMXChromium.MustCreateKeyboardHandler : boolean;
+begin
+ Result := assigned(FOnPreKeyEvent) or
+ assigned(FOnKeyEvent);
+end;
+
+function TFMXChromium.MustCreateDisplayHandler : boolean;
+begin
+ Result := assigned(FOnAddressChange) or
+ assigned(FOnTitleChange) or
+ assigned(FOnFavIconUrlChange) or
+ assigned(FOnFullScreenModeChange) or
+ assigned(FOnTooltip) or
+ assigned(FOnStatusMessage) or
+ assigned(FOnConsoleMessage) or
+ assigned(FOnAutoResize);
+end;
+
+function TFMXChromium.MustCreateDownloadHandler : boolean;
+begin
+ Result := assigned(FOnBeforeDownload) or
+ assigned(FOnDownloadUpdated);
+end;
+
+function TFMXChromium.MustCreateGeolocationHandler : boolean;
+begin
+ Result := assigned(FOnRequestGeolocationPermission) or
+ assigned(FOnCancelGeolocationPermission);
+end;
+
+function TFMXChromium.MustCreateJsDialogHandler : boolean;
+begin
+ Result := assigned(FOnJsdialog) or
+ assigned(FOnBeforeUnloadDialog) or
+ assigned(FOnResetDialogState) or
+ assigned(FOnDialogClosed);
+end;
+
+function TFMXChromium.MustCreateLifeSpanHandler : boolean;
+begin
+ Result := assigned(FOnBeforePopup) or
+ assigned(FOnAfterCreated) or
+ assigned(FOnBeforeClose) or
+ assigned(FOnClose);
+end;
+
+function TFMXChromium.MustCreateRequestHandler : boolean;
+begin
+ Result := assigned(FOnBeforeBrowse) or
+ assigned(FOnOpenUrlFromTab) or
+ assigned(FOnBeforeResourceLoad) or
+ assigned(FOnGetResourceHandler) or
+ assigned(FOnResourceRedirect) or
+ assigned(FOnResourceResponse) or
+ assigned(FOnGetResourceResponseFilter) or
+ assigned(FOnResourceLoadComplete) or
+ assigned(FOnGetAuthCredentials) or
+ assigned(FOnQuotaRequest) or
+ assigned(FOnProtocolExecution) or
+ assigned(FOnCertificateError) or
+ assigned(FOnSelectClientCertificate) or
+ assigned(FOnPluginCrashed) or
+ assigned(FOnRenderViewReady) or
+ assigned(FOnRenderProcessTerminated);
+end;
+
+function TFMXChromium.MustCreateDragHandler : boolean;
+begin
+ Result := assigned(FOnDragEnter) or
+ assigned(FOnDraggableRegionsChanged);
+end;
+
+function TFMXChromium.MustCreateFindHandler : boolean;
+begin
+ Result := assigned(FOnFindResult);
+end;
+
+procedure TFMXChromium.doTextResultAvailable(const aText : string);
+begin
+ if assigned(FOnTextResultAvailable) then FOnTextResultAvailable(self, aText);
+end;
+
+procedure TFMXChromium.ExecuteJavaScript(const aCode, aScriptURL, aFrameName : ustring; aStartLine : integer);
+var
+ TempFrame : ICefFrame;
+begin
+ try
+ if Initialized then
+ begin
+ if (length(aFrameName) > 0) then
+ TempFrame := FBrowser.GetFrame(aFrameName)
+ else
+ TempFrame := FBrowser.MainFrame;
+
+ if (TempFrame <> nil) then
+ TempFrame.ExecuteJavaScript(aCode, aScriptURL, aStartLine);
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXChromium.ExecuteJavaScript', e) then raise;
+ end;
+end;
+
+procedure TFMXChromium.ExecuteJavaScript(const aCode, aScriptURL : ustring; const aFrame : ICefFrame; aStartLine : integer);
+begin
+ try
+ if Initialized and (aFrame <> nil) then
+ aFrame.ExecuteJavaScript(aCode, aScriptURL, aStartLine);
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXChromium.ExecuteJavaScript', e) then raise;
+ end;
+end;
+
+procedure TFMXChromium.ExecuteJavaScript(const aCode, aScriptURL : ustring; const aFrameIdentifier : int64; aStartLine : integer = 0);
+var
+ TempFrame : ICefFrame;
+begin
+ try
+ if Initialized then
+ begin
+ if (aFrameIdentifier <> 0) then
+ TempFrame := FBrowser.GetFrameByident(aFrameIdentifier)
+ else
+ TempFrame := FBrowser.MainFrame;
+
+ if (TempFrame <> nil) then
+ TempFrame.ExecuteJavaScript(aCode, aScriptURL, aStartLine);
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXChromium.ExecuteJavaScript', e) then raise;
+ end;
+end;
+
+procedure TFMXChromium.doCookiesDeleted(numDeleted : integer);
+begin
+ if assigned(FOnCookiesDeleted) then FOnCookiesDeleted(self, numDeleted);
+end;
+
+procedure TFMXChromium.doPdfPrintFinished(aResultOK : boolean);
+begin
+ if assigned(FOnPdfPrintFinished) then FOnPdfPrintFinished(self, aResultOK);
+end;
+
+function TFMXChromium.doOnClose(const browser: ICefBrowser): Boolean;
+begin
+ Result := False;
+
+ if (browser <> nil) and (FBrowserId = browser.Identifier) then FClosing := True;
+
+ if Assigned(FOnClose) then FOnClose(Self, browser, Result);
+end;
+
+procedure TFMXChromium.doOnBeforeClose(const browser: ICefBrowser);
+begin
+ if (browser <> nil) and (FBrowserId = browser.Identifier) then
+ begin
+ FInitialized := False;
+ ClearBrowserReference;
+ DestroyClientHandler;
+ end;
+
+ if Assigned(FOnBeforeClose) then FOnBeforeClose(Self, browser);
+end;
+
+procedure TFMXChromium.doOnAddressChange(const browser: ICefBrowser; const frame: ICefFrame; const url: ustring);
+begin
+ if Assigned(FOnAddressChange) then FOnAddressChange(Self, browser, frame, url);
+end;
+
+procedure TFMXChromium.doOnAfterCreated(const browser: ICefBrowser);
+begin
+ if MultithreadApp and (FBrowser = nil) then
+ begin
+ FBrowser := browser;
+ if (FBrowser <> nil) then FBrowserId := FBrowser.Identifier;
+ end;
+
+ doUpdatePreferences;
+
+ FInitialized := (FBrowser <> nil) and (FBrowserId <> 0);
+
+ if Assigned(FOnAfterCreated) then FOnAfterCreated(Self, browser);
+end;
+
+function TFMXChromium.doOnBeforeBrowse(const browser : ICefBrowser;
+ const frame : ICefFrame;
+ const request : ICefRequest;
+ isRedirect : Boolean): Boolean;
+begin
+ Result := False;
+
+ if FUpdatePreferences then doUpdatePreferences;
+
+ if Assigned(FOnBeforeBrowse) then FOnBeforeBrowse(Self, browser, frame, request, isRedirect, Result);
+end;
+
+procedure TFMXChromium.doOnBeforeContextMenu(const browser : ICefBrowser;
+ const frame : ICefFrame;
+ const params : ICefContextMenuParams;
+ const model : ICefMenuModel);
+begin
+ if Assigned(FOnBeforeContextMenu) then FOnBeforeContextMenu(Self, browser, frame, params, model);
+end;
+
+function TFMXChromium.doRunContextMenu(const browser : ICefBrowser;
+ const frame : ICefFrame;
+ const params : ICefContextMenuParams;
+ const model : ICefMenuModel;
+ const callback : ICefRunContextMenuCallback): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnRunContextMenu) then FOnRunContextMenu(Self, browser, frame, params, model, callback, Result);
+end;
+
+procedure TFMXChromium.doOnBeforeDownload(const browser : ICefBrowser;
+ const downloadItem : ICefDownloadItem;
+ const suggestedName : ustring;
+ const callback : ICefBeforeDownloadCallback);
+begin
+ if Assigned(FOnBeforeDownload) then FOnBeforeDownload(Self, browser, downloadItem, suggestedName, callback);
+end;
+
+function TFMXChromium.doOnBeforePopup(const browser : ICefBrowser;
+ const frame : ICefFrame;
+ const targetUrl : ustring;
+ const targetFrameName : ustring;
+ targetDisposition : TCefWindowOpenDisposition;
+ userGesture : Boolean;
+ var popupFeatures : TCefPopupFeatures;
+ var windowInfo : TCefWindowInfo;
+ var client : ICefClient;
+ var settings : TCefBrowserSettings;
+ var noJavascriptAccess : Boolean): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnBeforePopup) then
+ FOnBeforePopup(Self, browser, frame, targetUrl, targetFrameName,
+ targetDisposition, userGesture, popupFeatures, windowInfo, client,
+ settings, noJavascriptAccess, Result);
+end;
+
+function TFMXChromium.doOnBeforeResourceLoad(const browser : ICefBrowser;
+ const frame : ICefFrame;
+ const request : ICefRequest;
+ const callback : ICefRequestCallback): TCefReturnValue;
+var
+ TempHeaderMap : ICefStringMultimap;
+begin
+ if FAddCustomHeader then
+ begin
+ TempHeaderMap := TCefStringMultimapOwn.Create;
+ request.GetHeaderMap(TempHeaderMap);
+ TempHeaderMap.Append(FCustomHeaderName, FCustomHeaderValue);
+ request.SetHeaderMap(TempHeaderMap);
+ TempHeaderMap := nil;
+ end;
+
+ if not(FSendReferrer) then request.SetReferrer('', REFERRER_POLICY_NO_REFERRER);
+
+ Result := RV_CONTINUE;
+
+ if Assigned(FOnBeforeResourceLoad) then FOnBeforeResourceLoad(Self, browser, frame, request, callback, Result);
+end;
+
+function TFMXChromium.doOnBeforeUnloadDialog(const browser : ICefBrowser;
+ const messageText : ustring;
+ isReload : Boolean;
+ const callback : ICefJsDialogCallback): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnBeforeUnloadDialog) then FOnBeforeUnloadDialog(Self, browser, messageText, isReload, callback, Result);
+end;
+
+procedure TFMXChromium.doOnCancelGeolocationPermission(const browser : ICefBrowser; requestId : Integer);
+begin
+ if Assigned(FOnCancelGeolocationPermission) then
+ FOnCancelGeolocationPermission(Self, browser, requestId);
+end;
+
+function TFMXChromium.doOnCertificateError(const browser : ICefBrowser;
+ certError : TCefErrorcode;
+ const requestUrl : ustring;
+ const sslInfo : ICefSslInfo;
+ const callback : ICefRequestCallback): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnCertificateError) then
+ FOnCertificateError(Self, browser, certError, requestUrl, sslInfo, callback, Result);
+end;
+
+function TFMXChromium.doOnConsoleMessage(const browser : ICefBrowser;
+ const aMessage : ustring;
+ const source : ustring;
+ line : Integer): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnConsoleMessage) then FOnConsoleMessage(Self, browser, aMessage, source, line, Result);
+end;
+
+function TFMXChromium.doOnAutoResize(const browser : ICefBrowser;
+ const new_size : PCefSize): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnAutoResize) then FOnAutoResize(Self, browser, new_size, Result);
+end;
+
+function TFMXChromium.doOnContextMenuCommand(const browser : ICefBrowser;
+ const frame : ICefFrame;
+ const params : ICefContextMenuParams;
+ commandId : Integer;
+ eventFlags : TCefEventFlags): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnContextMenuCommand) then
+ FOnContextMenuCommand(Self, browser, frame, params, commandId, eventFlags, Result);
+end;
+
+procedure TFMXChromium.doOnContextMenuDismissed(const browser: ICefBrowser; const frame: ICefFrame);
+begin
+ if Assigned(FOnContextMenuDismissed) then FOnContextMenuDismissed(Self, browser, frame);
+end;
+
+procedure TFMXChromium.doOnCursorChange(const browser : ICefBrowser;
+ cursor : TCefCursorHandle;
+ cursorType : TCefCursorType;
+ const customCursorInfo : PCefCursorInfo);
+begin
+ if assigned(FOnCursorChange) then FOnCursorChange(self, browser, cursor, cursorType, customCursorInfo);
+end;
+
+procedure TFMXChromium.doOnDialogClosed(const browser: ICefBrowser);
+begin
+ if Assigned(FOnDialogClosed) then FOnDialogClosed(Self, browser);
+end;
+
+procedure TFMXChromium.doOnDownloadUpdated(const browser : ICefBrowser;
+ const downloadItem : ICefDownloadItem;
+ const callback : ICefDownloadItemCallback);
+begin
+ if Assigned(FOnDownloadUpdated) then FOnDownloadUpdated(Self, browser, downloadItem, callback);
+end;
+
+function TFMXChromium.doOnDragEnter(const browser : ICefBrowser;
+ const dragData : ICefDragData;
+ mask : TCefDragOperations): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnDragEnter) then FOnDragEnter(Self, browser, dragData, mask, Result);
+end;
+
+procedure TFMXChromium.doOnDraggableRegionsChanged(const browser : ICefBrowser;
+ regionsCount : NativeUInt;
+ regions : PCefDraggableRegionArray);
+begin
+ if Assigned(FOnDraggableRegionsChanged) then FOnDraggableRegionsChanged(Self, browser, regionsCount, regions);
+end;
+
+procedure TFMXChromium.doOnFaviconUrlChange(const browser: ICefBrowser; iconUrls: TStrings);
+begin
+ if Assigned(FOnFavIconUrlChange) then FOnFavIconUrlChange(Self, browser, iconUrls);
+end;
+
+function TFMXChromium.doOnFileDialog(const browser : ICefBrowser;
+ mode : TCefFileDialogMode;
+ const title : ustring;
+ const defaultFilePath : ustring;
+ acceptFilters : TStrings;
+ selectedAcceptFilter : Integer;
+ const callback : ICefFileDialogCallback): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnFileDialog) then
+ FOnFileDialog(Self, browser, mode, title, defaultFilePath, acceptFilters,
+ selectedAcceptFilter, callback, Result);
+end;
+
+procedure TFMXChromium.doOnFindResult(const browser : ICefBrowser;
+ identifier : integer;
+ count : Integer;
+ const selectionRect : PCefRect;
+ activeMatchOrdinal : Integer;
+ finalUpdate : Boolean);
+begin
+ if Assigned(FOnFindResult) then
+ FOnFindResult(Self, browser, identifier, count, selectionRect, activeMatchOrdinal, finalUpdate);
+end;
+
+procedure TFMXChromium.doOnFullScreenModeChange(const browser: ICefBrowser; fullscreen: Boolean);
+begin
+ if Assigned(FOnFullScreenModeChange) then FOnFullScreenModeChange(Self, browser, fullscreen);
+end;
+
+function TFMXChromium.doOnGetAuthCredentials(const browser : ICefBrowser;
+ const frame : ICefFrame;
+ isProxy : Boolean;
+ const host : ustring;
+ port : Integer;
+ const realm : ustring;
+ const scheme : ustring;
+ const callback : ICefAuthCallback): Boolean;
+begin
+ Result := False;
+
+ if isProxy then
+ begin
+ if (FProxyType = CEF_PROXYTYPE_FIXED_SERVERS) and (callback <> nil) then
+ begin
+ Result := True;
+ callback.cont(FProxyUsername, FProxyPassword);
+ end;
+ end
+ else
+ if (frame <> nil) and frame.IsMain and Assigned(FOnGetAuthCredentials) then
+ FOnGetAuthCredentials(Self, browser, frame, isProxy, host, port, realm, scheme, callback, Result);
+end;
+
+function TFMXChromium.doOnGetResourceHandler(const browser : ICefBrowser;
+ const frame : ICefFrame;
+ const request : ICefRequest): ICefResourceHandler;
+begin
+ Result := nil;
+
+ if Assigned(FOnGetResourceHandler) then
+ FOnGetResourceHandler(Self, browser, frame, request, Result);
+end;
+
+procedure TFMXChromium.doOnGetAccessibilityHandler(var aAccessibilityHandler : ICefAccessibilityHandler);
+begin
+ if assigned(FOnGetAccessibilityHandler) then FOnGetAccessibilityHandler(Self, aAccessibilityHandler);
+end;
+
+function TFMXChromium.doOnGetRootScreenRect(const browser: ICefBrowser; var rect: TCefRect): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnGetRootScreenRect) then FOnGetRootScreenRect(Self, browser, rect, Result);
+end;
+
+function TFMXChromium.doOnGetScreenInfo(const browser: ICefBrowser; var screenInfo: TCefScreenInfo): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnGetScreenInfo) then FOnGetScreenInfo(Self, browser, screenInfo, Result);
+end;
+
+function TFMXChromium.doOnGetScreenPoint(const browser: ICefBrowser; viewX, viewY: Integer; var screenX, screenY: Integer): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnGetScreenPoint) then FOnGetScreenPoint(Self, browser, viewX, viewY, screenX, screenY, Result);
+end;
+
+function TFMXChromium.doOnGetViewRect(const browser: ICefBrowser; var rect: TCefRect): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnGetViewRect) then FOnGetViewRect(Self, browser, rect, Result);
+end;
+
+procedure TFMXChromium.doOnGotFocus(const browser: ICefBrowser);
+begin
+ if Assigned(FOnGotFocus) then FOnGotFocus(Self, browser)
+end;
+
+function TFMXChromium.doOnJsdialog(const browser : ICefBrowser;
+ const originUrl : ustring;
+ dialogType : TCefJsDialogType;
+ const messageText : ustring;
+ const defaultPromptText : ustring;
+ const callback : ICefJsDialogCallback;
+ out suppressMessage : Boolean): Boolean;
+begin
+ Result := False;
+
+ if not(Initialized) then
+ suppressMessage := True
+ else
+ begin
+ suppressMessage := False;
+
+ if Assigned(FOnJsdialog) then
+ FOnJsdialog(Self, browser, originUrl, dialogType, messageText,
+ defaultPromptText, callback, suppressMessage, Result);
+ end;
+end;
+
+function TFMXChromium.doOnKeyEvent(const browser : ICefBrowser;
+ const event : PCefKeyEvent;
+ osEvent : TCefEventHandle): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnKeyEvent) then FOnKeyEvent(Self, browser, event, osEvent, Result);
+end;
+
+procedure TFMXChromium.doOnLoadEnd(const browser : ICefBrowser;
+ const frame : ICefFrame;
+ httpStatusCode : Integer);
+begin
+ if Assigned(FOnLoadEnd) then FOnLoadEnd(Self, browser, frame, httpStatusCode);
+end;
+
+procedure TFMXChromium.doOnLoadError(const browser : ICefBrowser;
+ const frame : ICefFrame;
+ errorCode : Integer;
+ const errorText : ustring;
+ const failedUrl : ustring);
+begin
+ if Assigned(FOnLoadError) then FOnLoadError(Self, browser, frame, errorCode, errorText, failedUrl);
+end;
+
+procedure TFMXChromium.doOnLoadingStateChange(const browser: ICefBrowser; isLoading, canGoBack, canGoForward: Boolean);
+begin
+ if Assigned(FOnLoadingStateChange) then FOnLoadingStateChange(Self, browser, isLoading, canGoBack, canGoForward);
+end;
+
+procedure TFMXChromium.doOnLoadStart(const browser: ICefBrowser; const frame: ICefFrame; transitionType: TCefTransitionType);
+begin
+ if Assigned(FOnLoadStart) then FOnLoadStart(Self, browser, frame, transitionType);
+end;
+
+function TFMXChromium.doOnOpenUrlFromTab(const browser : ICefBrowser;
+ const frame : ICefFrame;
+ const targetUrl : ustring;
+ targetDisposition : TCefWindowOpenDisposition;
+ userGesture : Boolean): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnOpenUrlFromTab) then
+ FOnOpenUrlFromTab(Self, browser, frame, targetUrl, targetDisposition, userGesture, Result);
+end;
+
+procedure TFMXChromium.doOnPaint(const browser : ICefBrowser;
+ kind : TCefPaintElementType;
+ dirtyRectsCount : NativeUInt;
+ const dirtyRects : PCefRectArray;
+ const buffer : Pointer;
+ width : Integer;
+ height : Integer);
+begin
+ if Assigned(FOnPaint) then FOnPaint(Self, browser, kind, dirtyRectsCount, dirtyRects, buffer, width, height);
+end;
+
+function TFMXChromium.doOnSelectClientCertificate(const browser : ICefBrowser;
+ isProxy : boolean;
+ const host : ustring;
+ port : integer;
+ certificatesCount : NativeUInt;
+ const certificates : TCefX509CertificateArray;
+ const callback : ICefSelectClientCertificateCallback): boolean;
+begin
+ Result := False;
+
+ if assigned(FOnSelectClientCertificate) then
+ FOnSelectClientCertificate(self, browser, isProxy, host, port, certificatesCount, certificates, callback, Result);
+end;
+
+procedure TFMXChromium.doOnPluginCrashed(const browser: ICefBrowser; const pluginPath: ustring);
+begin
+ if Assigned(FOnPluginCrashed) then FOnPluginCrashed(Self, browser, pluginPath);
+end;
+
+procedure TFMXChromium.doOnPopupShow(const browser: ICefBrowser; show: Boolean);
+begin
+ if assigned(FOnPopupShow) then FOnPopupShow(self, browser, show);
+end;
+
+procedure TFMXChromium.doOnPopupSize(const browser: ICefBrowser; const rect: PCefRect);
+begin
+ if assigned(FOnPopupSize) then FOnPopupSize(self, browser, rect);
+end;
+
+function TFMXChromium.doOnPreKeyEvent(const browser : ICefBrowser;
+ const event : PCefKeyEvent;
+ osEvent : TCefEventHandle;
+ out isKeyboardShortcut : Boolean): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnPreKeyEvent) then FOnPreKeyEvent(Self, browser, event, osEvent, isKeyboardShortcut, Result);
+end;
+
+function TFMXChromium.doOnProcessMessageReceived(const browser : ICefBrowser;
+ sourceProcess : TCefProcessId;
+ const aMessage : ICefProcessMessage): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnProcessMessageReceived) then
+ FOnProcessMessageReceived(Self, browser, sourceProcess, aMessage, Result);
+end;
+
+procedure TFMXChromium.doOnProtocolExecution(const browser : ICefBrowser;
+ const url : ustring;
+ out allowOsExecution : Boolean);
+begin
+ if Assigned(FOnProtocolExecution) then FOnProtocolExecution(Self, browser, url, allowOsExecution);
+end;
+
+function TFMXChromium.doOnQuotaRequest(const browser : ICefBrowser;
+ const originUrl : ustring;
+ newSize : Int64;
+ const callback : ICefRequestCallback): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnQuotaRequest) then FOnQuotaRequest(Self, browser, originUrl, newSize, callback, Result);
+end;
+
+procedure TFMXChromium.doOnRenderProcessTerminated(const browser: ICefBrowser; status: TCefTerminationStatus);
+begin
+ if Assigned(FOnRenderProcessTerminated) then FOnRenderProcessTerminated(Self, browser, status);
+end;
+
+procedure TFMXChromium.doOnRenderViewReady(const browser: ICefBrowser);
+begin
+ if Assigned(FOnRenderViewReady) then FOnRenderViewReady(Self, browser);
+end;
+
+function TFMXChromium.doOnRequestGeolocationPermission(const browser : ICefBrowser;
+ const requestingUrl : ustring;
+ requestId : Integer;
+ const callback : ICefGeolocationCallback): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnRequestGeolocationPermission) then
+ FOnRequestGeolocationPermission(Self, browser, requestingUrl, requestId, callback, Result);
+end;
+
+procedure TFMXChromium.doOnResetDialogState(const browser: ICefBrowser);
+begin
+ if Assigned(FOnResetDialogState) then FOnResetDialogState(Self, browser);
+end;
+
+procedure TFMXChromium.doOnResourceRedirect(const browser : ICefBrowser;
+ const frame : ICefFrame;
+ const request : ICefRequest;
+ const response : ICefResponse;
+ var newUrl : ustring);
+begin
+ if Assigned(FOnResourceRedirect) then FOnResourceRedirect(Self, browser, frame, request, response, newUrl);
+end;
+
+function TFMXChromium.doOnResourceResponse(const browser : ICefBrowser;
+ const frame : ICefFrame;
+ const request : ICefRequest;
+ const response : ICefResponse): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnResourceResponse) then FOnResourceResponse(Self, browser, frame, request, response, Result);
+end;
+function TFMXChromium.doOnGetResourceResponseFilter(const browser : ICefBrowser;
+ const frame : ICefFrame;
+ const request : ICefRequest;
+ const response : ICefResponse) : ICefResponseFilter;
+begin
+ Result := nil;
+
+ if Assigned(FOnGetResourceResponseFilter) then
+ FOnGetResourceResponseFilter(self, browser, frame, request, response, Result);
+end;
+
+procedure TFMXChromium.doOnResourceLoadComplete(const browser : ICefBrowser;
+ const frame : ICefFrame;
+ const request : ICefRequest;
+ const response : ICefResponse;
+ status : TCefUrlRequestStatus;
+ receivedContentLength : Int64);
+begin
+ if Assigned(FOnResourceLoadComplete) then
+ FOnResourceLoadComplete(self, browser, frame, request, response, status, receivedContentLength);
+end;
+
+procedure TFMXChromium.doOnScrollOffsetChanged(const browser: ICefBrowser; x, y: Double);
+begin
+ if Assigned(FOnScrollOffsetChanged) then FOnScrollOffsetChanged(Self, browser, x, y);
+end;
+
+procedure TFMXChromium.doOnIMECompositionRangeChanged(const browser : ICefBrowser;
+ const selected_range : PCefRange;
+ character_boundsCount : NativeUInt;
+ const character_bounds : PCefRect);
+begin
+ if assigned(FOnIMECompositionRangeChanged) then
+ FOnIMECompositionRangeChanged(self, browser, selected_range, character_boundsCount, character_bounds);
+end;
+
+function TFMXChromium.doOnSetFocus(const browser: ICefBrowser; source: TCefFocusSource): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnSetFocus) then FOnSetFocus(Self, browser, source, Result);
+end;
+
+function TFMXChromium.doOnStartDragging(const browser : ICefBrowser;
+ const dragData : ICefDragData;
+ allowedOps : TCefDragOperations;
+ x : integer;
+ y : Integer): Boolean;
+begin
+ Result := False;
+end;
+
+procedure TFMXChromium.doOnStatusMessage(const browser: ICefBrowser; const value: ustring);
+begin
+ if Assigned(FOnStatusMessage) then FOnStatusMessage(Self, browser, value);
+end;
+
+procedure TFMXChromium.doOnTakeFocus(const browser: ICefBrowser; next: Boolean);
+begin
+ if Assigned(FOnTakeFocus) then FOnTakeFocus(Self, browser, next);
+end;
+
+procedure TFMXChromium.doOnTitleChange(const browser: ICefBrowser; const title: ustring);
+begin
+ if Assigned(FOnTitleChange) then FOnTitleChange(Self, browser, title);
+end;
+
+function TFMXChromium.doOnTooltip(const browser: ICefBrowser; var text: ustring): Boolean;
+begin
+ Result := False;
+
+ if Assigned(FOnTooltip) then FOnTooltip(Self, browser, text, Result);
+end;
+
+procedure TFMXChromium.doOnUpdateDragCursor(const browser: ICefBrowser; operation: TCefDragOperation);
+begin
+ //
+end;
+
+function TFMXChromium.GetParentForm : TCustomForm;
+var
+ TempComp : TComponent;
+begin
+ Result := nil;
+ TempComp := Owner;
+
+ while (TempComp <> nil) do
+ if (TempComp is TCustomForm) then
+ begin
+ Result := TCustomForm(TempComp);
+ exit;
+ end
+ else
+ TempComp := TempComp.owner;
+end;
+
+procedure TFMXChromium.MoveFormTo(const x, y: Integer);
+var
+ TempForm : TCustomForm;
+ {$IFDEF DELPHI17_UP}
+ TempRect : TRect;
+ {$ENDIF}
+begin
+ TempForm := GetParentForm;
+ {$IFDEF DELPHI17_UP}
+ if (TempForm <> nil) then
+ begin
+ TempRect.Left := min(max(x, max(screen.DesktopLeft, 0)), screen.DesktopWidth - TempForm.Width);
+ TempRect.Top := min(max(y, max(screen.DesktopTop, 0)), screen.DesktopHeight - TempForm.Height);
+ TempRect.Right := TempRect.Left + TempForm.Width - 1;
+ TempRect.Bottom := TempRect.Top + TempForm.Height - 1;
+
+ TempForm.SetBounds(TempRect.Left, TempRect.Top, TempRect.Right - TempRect.Left + 1, TempRect.Bottom - TempRect.Top + 1);
+ end;
+ {$ELSE}
+ TempForm.SetBounds(x, y, TempForm.Width, TempForm.Height);
+ {$ENDIF}
+end;
+
+procedure TFMXChromium.MoveFormBy(const x, y: Integer);
+var
+ TempForm : TCustomForm;
+ {$IFDEF DELPHI17_UP}
+ TempRect : TRect;
+ {$ENDIF}
+begin
+ TempForm := GetParentForm;
+ {$IFDEF DELPHI17_UP}
+ if (TempForm <> nil) then
+ begin
+ TempRect.Left := min(max(TempForm.Left + x, max(screen.DesktopLeft, 0)), screen.DesktopWidth - TempForm.Width);
+ TempRect.Top := min(max(TempForm.Top + y, max(screen.DesktopTop, 0)), screen.DesktopHeight - TempForm.Height);
+ TempRect.Right := TempRect.Left + TempForm.Width - 1;
+ TempRect.Bottom := TempRect.Top + TempForm.Height - 1;
+
+ TempForm.SetBounds(TempRect.Left, TempRect.Top, TempRect.Right - TempRect.Left + 1, TempRect.Bottom - TempRect.Top + 1);
+ end;
+ {$ELSE}
+ TempForm.SetBounds(TempForm.Left + x, TempForm.Top + y, TempForm.Width, TempForm.Height);
+ {$ENDIF}
+end;
+
+procedure TFMXChromium.ResizeFormWidthTo(const x : Integer);
+var
+ TempForm : TCustomForm;
+ TempX, TempDeltaX : integer;
+begin
+ TempForm := GetParentForm;
+
+ if (TempForm <> nil) then
+ begin
+ TempX := max(x, 100);
+ TempDeltaX := TempForm.Width - TempForm.ClientWidth;
+ TempForm.Width := TempX + TempDeltaX;
+ end;
+end;
+
+procedure TFMXChromium.ResizeFormHeightTo(const y : Integer);
+var
+ TempForm : TCustomForm;
+ TempY, TempDeltaY : integer;
+begin
+ TempForm := GetParentForm;
+
+ if (TempForm <> nil) then
+ begin
+ TempY := max(y, 100);
+ TempDeltaY := TempForm.Height - TempForm.ClientHeight;
+ TempForm.Height := TempY + TempDeltaY;
+ end;
+end;
+
+procedure TFMXChromium.SetFormLeftTo(const x : Integer);
+var
+ TempForm : TCustomForm;
+begin
+ TempForm := GetParentForm;
+
+ if (TempForm <> nil) then
+ {$IFDEF DELPHI17_UP}
+ TempForm.Left := min(max(x, max(screen.DesktopLeft, 0)), screen.DesktopWidth - TempForm.Width);
+ {$ELSE}
+ TempForm.Left := x;
+ {$ENDIF}
+end;
+
+procedure TFMXChromium.SetFormTopTo(const y : Integer);
+var
+ TempForm : TCustomForm;
+begin
+ TempForm := GetParentForm;
+
+ if (TempForm <> nil) then
+ {$IFDEF DELPHI17_UP}
+ TempForm.Top := min(max(y, max(screen.DesktopTop, 0)), screen.DesktopHeight - TempForm.Height);
+ {$ELSE}
+ TempForm.Top := y;
+ {$ENDIF}
+end;
+
+procedure TFMXChromium.WasResized;
+begin
+ if Initialized then FBrowser.Host.WasResized;
+end;
+
+procedure TFMXChromium.WasHidden(hidden: Boolean);
+begin
+ if Initialized then FBrowser.Host.WasHidden(hidden);
+end;
+
+procedure TFMXChromium.NotifyScreenInfoChanged;
+begin
+ if Initialized then FBrowser.Host.NotifyScreenInfoChanged;
+end;
+
+procedure TFMXChromium.NotifyMoveOrResizeStarted;
+begin
+ if Initialized then FBrowser.Host.NotifyMoveOrResizeStarted;
+end;
+
+procedure TFMXChromium.Invalidate(kind: TCefPaintElementType);
+begin
+ if Initialized then FBrowser.Host.Invalidate(kind);
+end;
+
+procedure TFMXChromium.SendKeyEvent(const event: PCefKeyEvent);
+begin
+ if Initialized then FBrowser.Host.SendKeyEvent(event);
+end;
+
+procedure TFMXChromium.SendMouseClickEvent(const event : PCefMouseEvent;
+ kind : TCefMouseButtonType;
+ mouseUp : Boolean;
+ clickCount : Integer);
+begin
+ if Initialized then FBrowser.Host.SendMouseClickEvent(event, kind, mouseUp, clickCount);
+end;
+
+procedure TFMXChromium.SendMouseMoveEvent(const event: PCefMouseEvent; mouseLeave: Boolean);
+begin
+ if Initialized then FBrowser.Host.SendMouseMoveEvent(event, mouseLeave);
+end;
+
+procedure TFMXChromium.SendMouseWheelEvent(const event: PCefMouseEvent; deltaX, deltaY: Integer);
+begin
+ if Initialized then FBrowser.Host.SendMouseWheelEvent(event, deltaX, deltaY);
+end;
+
+procedure TFMXChromium.SendFocusEvent(setFocus: Boolean);
+begin
+ if Initialized then FBrowser.Host.SendFocusEvent(setFocus);
+end;
+
+procedure TFMXChromium.SendCaptureLostEvent;
+begin
+ if Initialized then FBrowser.Host.SendCaptureLostEvent;
+end;
+
+procedure TFMXChromium.SetFocus(focus: Boolean);
+begin
+ if Initialized then FBrowser.Host.SetFocus(focus);
+end;
+
+procedure TFMXChromium.SetAccessibilityState(accessibilityState: TCefState);
+begin
+ if Initialized then FBrowser.Host.SetAccessibilityState(accessibilityState);
+end;
+
+function TFMXChromium.SendProcessMessage(targetProcess: TCefProcessId; const ProcMessage: ICefProcessMessage): Boolean;
+begin
+ Result := Initialized and FBrowser.SendProcessMessage(targetProcess, ProcMessage);
+end;
+
+procedure TFMXChromium.DragTargetDragEnter(const dragData: ICefDragData; const event: PCefMouseEvent; allowedOps: TCefDragOperations);
+begin
+ if Initialized then FBrowser.Host.DragTargetDragEnter(dragData, event, allowedOps);
+end;
+
+procedure TFMXChromium.DragTargetDragOver(const event: PCefMouseEvent; allowedOps: TCefDragOperations);
+begin
+ if Initialized then FBrowser.Host.DragTargetDragOver(event, allowedOps);
+end;
+
+procedure TFMXChromium.DragTargetDragLeave;
+begin
+ if Initialized then FBrowser.Host.DragTargetDragLeave;
+end;
+
+procedure TFMXChromium.DragTargetDrop(event: PCefMouseEvent);
+begin
+ if Initialized then FBrowser.Host.DragTargetDrop(event);
+end;
+
+procedure TFMXChromium.DragSourceEndedAt(x, y: Integer; op: TCefDragOperation);
+begin
+ if Initialized then FBrowser.Host.DragSourceEndedAt(x, y, op);
+end;
+
+procedure TFMXChromium.DragSourceSystemDragEnded;
+begin
+ if Initialized then FBrowser.Host.DragSourceSystemDragEnded;
+end;
+
+end.
diff --git a/source/uFMXWorkScheduler.pas b/source/uFMXWorkScheduler.pas
new file mode 100644
index 00000000..05796737
--- /dev/null
+++ b/source/uFMXWorkScheduler.pas
@@ -0,0 +1,260 @@
+// ************************************************************************
+// ***************************** 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 © 2018 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.
+ *
+ *)
+
+unit uFMXWorkScheduler;
+
+{$IFNDEF CPUX64}
+ {$ALIGN ON}
+ {$MINENUMSIZE 4}
+{$ENDIF}
+
+{$I cef.inc}
+
+interface
+
+uses
+ System.Classes, System.Types,
+ FMX.Types, FMX.Controls,
+ uCEFConstants, uCEFWorkSchedulerThread;
+
+type
+ TFMXWorkScheduler = class(TComponent)
+ protected
+ FThread : TCEFWorkSchedulerThread;
+ FDepleteWorkCycles : cardinal;
+ FDepleteWorkDelay : cardinal;
+ FDefaultInterval : integer;
+ FStopped : boolean;
+ {$IFDEF MSWINDOWS}
+ {$WARN SYMBOL_PLATFORM OFF}
+ FPriority : TThreadPriority;
+ {$WARN SYMBOL_PLATFORM ON}
+ {$ENDIF}
+
+ procedure CreateThread;
+ procedure DestroyThread;
+ procedure DepleteWork;
+ procedure NextPulse(aInterval : integer);
+ procedure DoWork;
+ procedure DoMessageLoopWork;
+
+ procedure SetDefaultInterval(aValue : integer);
+ {$IFDEF MSWINDOWS}
+ {$WARN SYMBOL_PLATFORM OFF}
+ procedure SetPriority(aValue : TThreadPriority);
+ {$WARN SYMBOL_PLATFORM ON}
+ {$ENDIF}
+
+
+ procedure Thread_OnPulse(Sender : TObject);
+
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ procedure AfterConstruction; override;
+ procedure ScheduleMessagePumpWork(const delay_ms : int64);
+ procedure StopScheduler;
+ procedure ScheduleWork(const delay_ms : int64);
+
+ published
+ {$IFDEF MSWINDOWS}
+ {$WARN SYMBOL_PLATFORM OFF}
+ property Priority : TThreadPriority read FPriority write SetPriority default tpNormal;
+ {$WARN SYMBOL_PLATFORM ON}
+ {$ENDIF}
+ property DefaultInterval : integer read FDefaultInterval write SetDefaultInterval default CEF_TIMER_MAXDELAY;
+ property DepleteWorkCycles : cardinal read FDepleteWorkCycles write FDepleteWorkCycles default CEF_TIMER_DEPLETEWORK_CYCLES;
+ property DepleteWorkDelay : cardinal read FDepleteWorkDelay write FDepleteWorkDelay default CEF_TIMER_DEPLETEWORK_DELAY;
+ end;
+
+implementation
+
+uses
+ {$IFDEF MSWINDOWS}
+ WinApi.Windows,
+ {$ENDIF}
+ System.SysUtils, System.Math,
+ FMX.Platform, FMX.Platform.Win, FMX.Forms,
+ uCEFMiscFunctions, uCEFApplication;
+
+constructor TFMXWorkScheduler.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+
+ FThread := nil;
+ FStopped := False;
+ {$IFDEF MSWINDOWS}
+ {$WARN SYMBOL_PLATFORM OFF}
+ FPriority := tpNormal;
+ {$WARN SYMBOL_PLATFORM ON}
+ {$ENDIF}
+ FDefaultInterval := CEF_TIMER_MAXDELAY;
+ FDepleteWorkCycles := CEF_TIMER_DEPLETEWORK_CYCLES;
+ FDepleteWorkDelay := CEF_TIMER_DEPLETEWORK_DELAY;
+end;
+
+destructor TFMXWorkScheduler.Destroy;
+begin
+ DestroyThread;
+
+ inherited Destroy;
+end;
+
+procedure TFMXWorkScheduler.AfterConstruction;
+begin
+ inherited AfterConstruction;
+
+ if not(csDesigning in ComponentState) then CreateThread;
+end;
+
+procedure TFMXWorkScheduler.CreateThread;
+begin
+ FThread := TCEFWorkSchedulerThread.Create;
+ {$IFDEF MSWINDOWS}
+ FThread.Priority := FPriority;
+ {$ENDIF}
+ FThread.DefaultInterval := FDefaultInterval;
+ FThread.OnPulse := Thread_OnPulse;
+ FThread.Start;
+end;
+
+procedure TFMXWorkScheduler.DestroyThread;
+begin
+ try
+ if (FThread <> nil) then
+ begin
+ FThread.Terminate;
+ FThread.NextPulse(0);
+ FThread.WaitFor;
+ FreeAndNil(FThread);
+ end;
+ except
+ on e : exception do
+ if CustomExceptionHandler('TFMXWorkScheduler.DestroyThread', e) then raise;
+ end;
+end;
+
+procedure TFMXWorkScheduler.DoMessageLoopWork;
+begin
+ if (GlobalCEFApp <> nil) then GlobalCEFApp.DoMessageLoopWork;
+end;
+
+procedure TFMXWorkScheduler.SetDefaultInterval(aValue : integer);
+begin
+ FDefaultInterval := aValue;
+ if (FThread <> nil) then FThread.DefaultInterval := aValue;
+end;
+
+{$IFDEF MSWINDOWS}
+{$WARN SYMBOL_PLATFORM OFF}
+procedure TFMXWorkScheduler.SetPriority(aValue : TThreadPriority);
+begin
+ FPriority := aValue;
+ if (FThread <> nil) then FThread.Priority := aValue;
+end;
+{$WARN SYMBOL_PLATFORM ON}
+{$ENDIF}
+
+procedure TFMXWorkScheduler.DepleteWork;
+var
+ i : cardinal;
+begin
+ i := FDepleteWorkCycles;
+
+ while (i > 0) do
+ begin
+ DoMessageLoopWork;
+ Sleep(FDepleteWorkDelay);
+ dec(i);
+ end;
+end;
+
+procedure TFMXWorkScheduler.ScheduleMessagePumpWork(const delay_ms : int64);
+{$IFDEF MSWINDOWS}
+var
+ TempHandle : HWND;
+{$ENDIF}
+begin
+ if not(FStopped) then
+ begin
+ {$IFDEF MSWINDOWS}
+ {$IFDEF DELPHI17_UP}
+ TempHandle := ApplicationHWND;
+ {$ELSE}
+ TempHandle := FmxHandleToHWND(Application.MainForm.Handle);
+ {$ENDIF}
+ if (TempHandle <> 0) then
+ WinApi.Windows.PostMessage(TempHandle, CEF_PUMPHAVEWORK, 0, LPARAM(delay_ms));
+ {$ENDIF}
+ end;
+end;
+
+procedure TFMXWorkScheduler.StopScheduler;
+begin
+ FStopped := True;
+ NextPulse(0);
+ DepleteWork;
+end;
+
+procedure TFMXWorkScheduler.Thread_OnPulse(Sender: TObject);
+begin
+ if not(FStopped) then DoMessageLoopWork;
+end;
+
+procedure TFMXWorkScheduler.DoWork;
+begin
+ DoMessageLoopWork;
+ NextPulse(FDefaultInterval);
+end;
+
+procedure TFMXWorkScheduler.ScheduleWork(const delay_ms : int64);
+begin
+ if not(FStopped) then
+ begin
+ if (delay_ms <= 0) then
+ DoWork
+ else
+ NextPulse(delay_ms);
+ end;
+end;
+
+procedure TFMXWorkScheduler.NextPulse(aInterval : integer);
+begin
+ if (FThread <> nil) then FThread.NextPulse(aInterval);
+end;
+
+end.