From b47a8e2d52b587e5d81546b92cedfef4c0866dd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Salvador=20D=C3=ADaz=20Fau?= Date: Thu, 25 Jan 2018 21:34:04 +0100 Subject: [PATCH] FireMonkey support added - New Delphi package called CEF4Delphi_FMX.dpk that includes VCL and FMX components. - New FMX comopnents : TFMXChromium, TFMXBufferPanel and TFMXWorkScheduler. - New FMX demo : FMXExternalPumpBrowser - Improved WorkScheduler for VCL too. - New GlobalCEFApp.DisableWebSecurity property. --- demos/DOMVisitor/DOMVisitor.dproj | 1 - demos/DOMVisitor/uDOMVisitor.dfm | 3 - demos/DOMVisitor/uDOMVisitor.pas | 12 +- .../FMXExternalPumpBrowser/00-DeleteDCUs.bat | 14 + .../FMXExternalPumpBrowser.dpr | 92 + .../FMXExternalPumpBrowser.dproj | 617 +++ demos/FMXExternalPumpBrowser/cef.inc | 384 ++ .../uFMXApplicationService.pas | 204 + .../uFMXExternalPumpBrowser.fmx | 91 + .../uFMXExternalPumpBrowser.pas | 806 ++++ .../OSRExternalPumpBrowser.dpr | 1 + demos/SimpleOSRBrowser/SimpleOSRBrowser.dpr | 1 + demos/SimpleOSRBrowser/uSimpleOSRBrowser.dfm | 4 +- demos/SimpleOSRBrowser/uSimpleOSRBrowser.pas | 8 +- {source => packages}/00-CreateResources.bat | 0 packages/00-DeleteDCUs.bat | 13 + packages/CEF4Delphi.dpk | 170 + {source => packages}/CEF4Delphi.dproj | 267 +- {source => packages}/CEF4Delphi.res | Bin {source => packages}/CEF4Delphi_D7.cfg | 0 {source => packages}/CEF4Delphi_D7.dof | 0 packages/CEF4Delphi_D7.dpk | 166 + {source => packages}/CEF4Delphi_D7.skincfg | 0 packages/CEF4Delphi_D7_Register.pas | 60 + packages/CEF4Delphi_FMX.dpk | 174 + packages/CEF4Delphi_FMX.dproj | 672 ++++ packages/CEF4Delphi_FMX.res | Bin 0 -> 724 bytes packages/CEF4Delphi_FMX_Register.pas | 62 + .../CEF4Delphi_Register.pas | 2 +- packages/bufferpanel.bmp | Bin 0 -> 1782 bytes packages/cef.inc | 384 ++ {source => packages}/chromium.bmp | Bin packages/chromium.dcr | Bin 0 -> 16484 bytes packages/chromium.rc | 9 + packages/chromiumwindow.bmp | Bin 0 -> 1782 bytes {source => packages}/dcu/placeholder.txt | 0 packages/server.bmp | Bin 0 -> 1782 bytes packages/windowparent.bmp | Bin 0 -> 1782 bytes packages/workscheduler.bmp | Bin 0 -> 1782 bytes source/CEF4Delphi.dpk | 169 - source/CEF4Delphi_D7.dpk | 165 - source/CEF4Delphi_D7.res | Bin 1960 -> 0 bytes source/chromium.dcr | Bin 3676 -> 0 bytes source/chromium.rc | 2 - source/uBufferPanel.pas | 41 +- source/uCEFApplication.pas | 17 +- source/uCEFChromium.pas | 150 +- source/uCEFConstants.pas | 10 +- source/uCEFDeleteCookiesCallback.pas | 11 +- source/uCEFDomVisitor.pas | 2 +- source/uCEFInterfaces.pas | 14 + source/uCEFPDFPrintCallback.pas | 11 +- source/uCEFResolveCallback.pas | 11 +- source/uCEFStringVisitor.pas | 11 +- source/uCEFTask.pas | 69 +- source/uCEFWorkScheduler.pas | 224 +- source/uCEFWorkSchedulerThread.pas | 222 ++ source/uFMXBufferPanel.pas | 426 ++ source/uFMXChromium.pas | 3435 +++++++++++++++++ source/uFMXWorkScheduler.pas | 260 ++ 60 files changed, 8748 insertions(+), 719 deletions(-) create mode 100644 demos/FMXExternalPumpBrowser/00-DeleteDCUs.bat create mode 100644 demos/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dpr create mode 100644 demos/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dproj create mode 100644 demos/FMXExternalPumpBrowser/cef.inc create mode 100644 demos/FMXExternalPumpBrowser/uFMXApplicationService.pas create mode 100644 demos/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.fmx create mode 100644 demos/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.pas rename {source => packages}/00-CreateResources.bat (100%) create mode 100644 packages/00-DeleteDCUs.bat create mode 100644 packages/CEF4Delphi.dpk rename {source => packages}/CEF4Delphi.dproj (74%) rename {source => packages}/CEF4Delphi.res (100%) rename {source => packages}/CEF4Delphi_D7.cfg (100%) rename {source => packages}/CEF4Delphi_D7.dof (100%) create mode 100644 packages/CEF4Delphi_D7.dpk rename {source => packages}/CEF4Delphi_D7.skincfg (100%) create mode 100644 packages/CEF4Delphi_D7_Register.pas create mode 100644 packages/CEF4Delphi_FMX.dpk create mode 100644 packages/CEF4Delphi_FMX.dproj create mode 100644 packages/CEF4Delphi_FMX.res create mode 100644 packages/CEF4Delphi_FMX_Register.pas rename source/uCEFRegisterComponents.pas => packages/CEF4Delphi_Register.pas (98%) create mode 100644 packages/bufferpanel.bmp create mode 100644 packages/cef.inc rename {source => packages}/chromium.bmp (100%) create mode 100644 packages/chromium.dcr create mode 100644 packages/chromium.rc create mode 100644 packages/chromiumwindow.bmp rename {source => packages}/dcu/placeholder.txt (100%) create mode 100644 packages/server.bmp create mode 100644 packages/windowparent.bmp create mode 100644 packages/workscheduler.bmp delete mode 100644 source/CEF4Delphi.dpk delete mode 100644 source/CEF4Delphi_D7.dpk delete mode 100644 source/CEF4Delphi_D7.res delete mode 100644 source/chromium.dcr delete mode 100644 source/chromium.rc create mode 100644 source/uCEFWorkSchedulerThread.pas create mode 100644 source/uFMXBufferPanel.pas create mode 100644 source/uFMXChromium.pas create mode 100644 source/uFMXWorkScheduler.pas 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 @@
DOMVisitorFrm
- 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 + + +
FMXExternalPumpBrowserFrm
+
+ + + 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 0000000000000000000000000000000000000000..0b1d7bfebb7dc1e50dd62d97ee57ed52405f8ff3 GIT binary patch literal 724 zcmaiyO-chn5QSgDEQ~Jn2D)%9BMgEdNKhjKCJ`NixCvv7F_2_JCSJqCxc4^hy@BIb zJvRA4v7mpe-s@M@B}sdXq9_O36-%n#ze7yL`9jqKACy!hwjJH7%Y305cCp%OagLcA z?9JYT&o9aFC5K;6omVnK@Ah>Rxsj1KjrodN!@mtcq`{@L4O09EhnXd5Hf{%cf(+Q&} dHp%u%btQ1M>8&QaI_o9Bk + * 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 0000000000000000000000000000000000000000..46d51f4e33a09b3204b0a3cf1696e0826a65718b GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7v_dwutFg59|nNz3l}bsO~Q=%4>W`l05=EX z67q}!>ZK6C?FE_xXOqf+>xDRmRPAu}aC3kn$ZWU*A{lVKqwc{PVx!@MHCW(+qu~P& i3apGl7(Ngu0Z9l0tFs9T0`*d>SVlGn>?kq`xH$l~)s9O5 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..9aadbeb31de30d9b1d16714a08ba330baeaf28ac GIT binary patch literal 16484 zcmeHOX>e0lme%x-{xQ@2tN-+$sp_fu)6><})v2zT>FP;((n*|dnq~_L1VRX*Lz89; zvEXkW}V`F*M;zgTnVePAJ*_Join8gr0pLD}TNP^fRKT;VT zu3w#ZbqK?m6$lU@#az!{5pZ`2+h5P5h9-_%(V~R(`;Em+>a!PmFgMn;07y z>lp9hNa)v$fBw-Ep`U~K>DPb%6yO+)4q*J`U&!B+arYMQg|xd1cNgatrzfVzUE?mB z%VBk(fx#&{@e>Awh=iYF*wpxx#b{CYsk_>{TAN#2B@%yYZpA4&@e>AMShy_h@y+;f zT~(jzR-L%LBu!p;RF(f%gD}O>mS?|pb-3}mvaU$l*nj~ThQU-Ym_fhYV(*bk+e_2c z1^YBbpAMBC8R5i_a6g|^*LnvVJu0zV#&NV4^+`(Q9UT}P4h21N37J%?D2~?@{~hAS z$}dcU1aozwS&-=ND4w&(XU#n`hK}jsX1B6(q^(5W*$I*03BqoevPz*)-Z-vf9W+*+ zfVf4RY^zPN*QcXdM9I@5?eh-RyuE+UssP&9K#ifDqwej4AT>KMVLcf)TUT<(#Q)MF zO0w0ZIwa?ujZ9}#CYr4_)!A}s-l_Jvv_7XAXwYq3U9W8yL6EA1)l~O%LK8oTI2j61 zgoy#6cc^7j*EFuIn$$J=ar{j)?--ah%f?l8+P+?h6Fb8(dIcAU%8x-43gVHKOx^Ap zCN4(%-K02%3ku?pQxmTJCOLCR++2koY55@ zA1X~4E>HBgvV=j_2|YLU?u`2>j!Qdbl)0>SYUkU$FYFCxfn%>fTYB(SF>{|oTA^p3 zHdLk>1!qlybB3z4+ni)qCvVYXcm~HLCw2xD7H(L?v|?UOnO&FmUfJ_X(ShID6tyN{ zmZc`!)^O3@aM4AJ&_3{tjHm~5*{XB~R2_|X599($eh z*$v5F7B3WT!w zH_AVcV}J1{PQrTb$-i(jPZ3PLEj1MK}c1g~C*pRXNRzX5v z?G3NX5p39S@rXSTnRYp+-OeavBLaS7r#~+K7Qu|f#kUa)-+xYY^vBOwd<+ZsvG^E^ zkFoeT6^oCt`1tIz@%s}WU#Ic$O-3B!ZN_$FjT;$nA%EP?*v$9?GRZiczxyO5TvePL z`7wjx|9e6!LG;zyiAvAT&NekQi9{kkpI@~`f`~vMsIRYgI2^Zb-I|=7oOlU>cyn`e zS67$E;{jmQ1aW|Ti#Sls^%4YeqL0^$y=L?Tae^~5GlMxsO%NwISbFFdH9?%<%+Jq5 zx2Or?!0GAfSy)&AX4C|6fPn7YxdY6o3E~82X=w?VQ4_=o&b@p0fEhJG95^zW?7@Qv z;G-sp0|d0ZybL~Sf;ho>^ytyUmmr7}oV7o_LL~?eeWpdtdlrnp`p#BUc+V5j@DV8_a5DB8{Ush$7)3(qkOB z*Ol9yvt3zq*w9j-Z^*f4ka%qR@R1NF`XGvgM94e+@V1l`t1n&n0M&roKg4xko@XibM+~EeVP-cPD%QNlI@n}c?LuaqeDKI&S&qp%ByEQ4jNMt%!odSMl?V^ zP!_05j`-_}jTz&eg}w=+QF6)9aB*&QXwfs`ul~8UuEDkk9xWAtIB*aKa2wMAsm$Al zQns_1>1aq>oU%$!{h>YSt@fliFpHCBpIa9wBxT3tp*AFRkcDWTIKa^90**VlL^K-LA3gQGOI7SYzjyRjM##(c_3O}D2 zQE2l&yUk8QbyQb))T6q&^fivwp_S5@8Zkx=lzcYUa$Z$(d=IMY{GE_FEPehBw>=V%} zv@>QOYKn-=chEjWB^(J8QSEQ+ge;9o-y)7*r)Y`l5nlSkO{m@zg%6c3QCo?lM<5@z_^C&wzo5$mg zk3X$ipgJ@%GSb%8<_i!hIxQ|PlBy9(PoTR`2x=1+ogEz=27>{o#EOp}KOP+&MSY2s z^-z?vTCH}w9q&2;3|Ig{3KJo3KM52%6$%9e=~56zE|&ub<^hgIqk(fdolf8o#c)x8 z7>!1g$po|D6v+Mk{UIPY?d|Oi$AK)$v;dr*o(2yPv)K$BsPsG>fMb|SrBbWaD0@P@ zu&|KHWD+}PWo1=VRNz7Y0lh$Gy zb8~RZh<3)5fdeb$<>g^!YK;aU%a0!2UtWeo19QydF&K>i!PIOv8}6*<;ovSq39huX zl+9-2ww?3&9z1*qhn|_61CDES^ybZ*xC-nH->_ILaFX!#x*Z_gGAQU_FpI_FaJgEY z?l!bEnRJ7Lb#--^FFXorz+K_k5pkdlrUo1k?tP4hR+wNxVPSD`F_242N?_s6&QACS zp@=wGESMU1D}jR7VS-pY9Lvheii(Q3TrOq}W#Aj+-9bbgcrtJ>48MYbZtw&+IZT0v z1FVWC38n}FPbeY|>;_ka$3hc0GTaPkL^t4oLSBX7^m#Z~bi7Rf6nUiseK1WBZh>$D zazq^12agL%a5KV#Aw+!d$(jFGJhH;q9rGd!iZz8-!=#uLe1N<+X>V`G?cdVU0vBp* zY{Xq$TU#3uCmeZAJyiNLWGi<2vG(pa2~#mQKl40)`^;v|Wg|BvG2 zTOs-6)OiMMz(eSA`IE z%4>o`CV^}Wdwgs~DWL~@e}aQ;DfWQaaaUGWUWi24U*lKgF4zlWe@eEcN@ftYT;A49W0yx?2A~QxmnHN;W$Isvah|M)N)EGG!Ae=%ai9~|UCdLB|i7d9F zNGYUJDHx@mEiEM_ z1z9qtkaA#W#-D!{(khDc0x*1RMaUMOY?E;$_6H6uKn+_{Q^Sn^MBB{MG;z5JJ2KY) z8v*373JDIj+aW~e3mi-tDGo6#7VdiL33P&bxR>)je(mD+S28#Jdu7=Tf`hA*rJ+aY zK;{K}Sd7>f--;Jyopu_GjuC^hwxaatCf1=p7w&(H&n_W2xH<+06In-G7Xt?R`-ox1 zB2kB=+HEpUx$HBewkd~k%5LzO2Zh{nf`d#V7zBJUPGtp)*x_ncTHDRWIw8MCP$}kf zg_Rruw}Q_uleXPLdW5gyaTm}GhA^npV3mnJ0!~@(yT3fY^%rNizH)lsdx?MBj+Suj z5Q-DTZdeyok5KS{BZb`Z009)i5mvHGk8Xr1iaw3Y|KxwK?E3GVE&q{n-~-$;7!XYG zXZSV&$I+i{&&`nmn0SqV%TNB8ck%=FiEU;7*iv$2L-Bz>W}n!P2SqT*i+SMGRad!< zdb395b(y_R6U;klH#7?>!u5Fp6b#ta*-CpuC1-D57$~Vb#2yKWx1MLnp#>*bEsho%}h&Ei0Nh) z3W+Hoq^3zICqV?AAE<9&Ay=XB!g{40wQZD*ZEJ!Y~=r zXa*du$Ki0;qT^LI%d4*|SsA+4N7F6$9TT6I^~1*R9lAcw>TGXxuMKeIaXOu_$L;tr zwxaIVEWc3SQEcd<8#+t$A_loI>BiM=y<%S8=EJe=W+(th9=P?eHWVj5FSgQ13Nh_5YdjW>dHhR&&`^W}aPY|Ga*`y$iGtPNF?5#VQie%HU-_Z$ zFFG|qJ3By2fMUfy=doxvRpv3hQb-Xlz(E4>dcEL8QF1bk;tI2bVUsm3j7k;EtLnN; z^_wiL@|r~<*i_+Tusf5w$Gz-A2;j)$^ZCGuqH4^>rO$1>l`{52=d?o8kTcann|fcY zW#y~$4u^JRslTe`_Azc@VjC@mSA2;_yVOcc<~~V!|M)_4e!|PNBRX#0 zj`k4X$P@eaS{kfv%0K_EFu9AFCS=@%(OGe$xgd#i|J?c{H?|*nw%=({1xeU?UVSJ? z;uc(tj1+5c&4yVX)um%ey-R93=2qj_f(` LOz!Ttf8YHJ5?8uf literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..f19ceb46f0b2022eca2a874879e143741ff74b7d GIT binary patch literal 1782 zcmds%T}V@57{~3VyY9Ozx~b^Ko4Sf1iomcCD=E7XEJGx$K(LTlqioZyXgSBUxp}s; zvvc<4);2%3;dGhqBR?|T2W)6d{j`-kN49D$jv8W`0@X0V`Jm{c420(?e_Ne%4D*p9dbAvdqSzz z>h<;YR4SDg2s14$ErheMun>tvlF1~)FfaZlrBaEvEXyt~E(U|a_X1%?E|>T4GMmjv zqbQ2wIF!q2j8`lcLw&7QOE{<)6$l)KLh+85PNy@OOnrTQDwWD;H0u8dWC%|NgCQIa zgOkZ*KJo&5hS$o<3g$^)SgOb4K@8yd`1s`HByuNs;Sq~+xm+V7BghBMX0v&{UZ2nB z_xlk{O-Ic8Qvk%FF0tKrfFg=Hct7Z4wF!je$`rW`ej+6r1%J5t!(EiN_Ohm?NL_V~)prmMsv}t_vX7{Xgh)6(Bpo2Qyfj)|(v@zEebD4b`UZ34%Lcy)D^B%pCSN3)MB zj1SB8b=P$FOFHfrw^v_is;j~ug%GlP435KWnvZ`jG9)AM39fQmO literal 0 HcmV?d00001 diff --git a/packages/windowparent.bmp b/packages/windowparent.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0e45ae0883fc9ccb968c1bf5430617f63dc445f9 GIT binary patch literal 1782 zcmd6nv1)@*6hQ6LEqgzqU(gTeo)3+Ji-QghMHHkz&{YD#iYOu)(HN40H-wPQ`#SW% zlLvYZ_o4W?J-%8CA6(yAZ@2Zb>@4ex`#&35%Y$4l51iL?x9ht0ecyFm+qQQrL2(?% z^Sms}!Z0j~;@1H5APAx;%JZC{8gwFm*kQ1}0q8PMS(XO_(4|vV6=zg~E*)Myv#CLs zPSZ5ZrUso(9LH_j(o};^1iG%HsRms-ec#hmgD#z67-*_Nr;{YfIF9Vqpc8>v;Ob(Y)I$+Pg8IHVJA&fPOCl4*PJCSx=jJ32br{}eNg)Ya8BH#e8fW*<@Iayb+V zZEbB`s`{qt>gtMl^j%e@Cdw8=rY#mrI2`6wpziPQ)9JL$X3MK86bkWpJdsG8ot*)O zDrhvq3=$|N_xJaC@Ub2-u-olmum_IU>y;$w^z;;tD2$gvh(sdMXcSvGrJlpX!zU0< z4-O9MIXruEasu%D{G2h63yUCm0N}9DRL#gM))hOG}H3i~arm%)rDt0l^>5zVIZOOoCzwy1ToFhK4pb zH!=kviqA60oI>0Mi!UzT(Ed^($j<8V6TiZU=TK((?gQ@kc85D3r( zmqtcL#>dA4vP|_KdV5=2TU%OMnwy(HnawV@+iW)D+gDYZ9A1GlTwf1fWDAX{y=`T2RQE0s#bQqyNzhJ#DP!^3pu@p^&W+}%}gZU{8YOfDCWM1atm zqA2XFMjUpT!{L~knwp)RW!si6FMr(L66j*71SgqJudlE37JMcfu~>|d)UVf(Dz?nt z-X1qkOiUO}CdubJqRMF0=l8Fytk5rsq733nur)apLu+sld!PHMiU#!t!`RpuS&O)<2XG%JvusSGMVU_V#r2Ll_rNI!{IirGN3k+K*+Iz zj{~mqC80&cSV)tDZ$y#AQVBsOX3#`!a1eXpi5hWObgR`0ip`Fwhc*#gpk9zQIrzip z;!(s*j2Q@t?A6YGU*(fkzwY!U7L+w5)mTbXWPl3M_Vza0e`8~V2(7KHv5S|Nmo+){ InT>7BvYq zmdVU47||1UY_?6d1Sn>Vk_v8kbOHX*?P}nYUA8U;g8>J`gg~HyPwgv!Rd}F-!zQeL zLB#_@5YwKkxO|MWIz7eZVjPN&BV?R{Tx6kXS;vWhW?4hwfiy>@Ma>lZrTdyc(t8_(#tEPT{!XWiw9lOlz-<77ME zBF>UsZPy&9b{-vp)gjlk9p|9Xhl!Hc&m)=50_8|Zj+-wr8wo9Lq2jD^KN6CYzEz-u zHPJI2~juM)K=J*nZBrN+rA>^1_I7tY2LYDmtUz_0MBD@P% zh3Bg;aMt&W&F6dmzObVRYF(7cBjsC+>X{Nm_CHaVdnxR2L(fepN2dx`# z+;$1Hcz-Ra9GM&MyjF6VqdVBfE}yUPj=c?4VOP~#XJ6uX>K{GJovH6lgR5#35dUT* zr0_=(+i0PQW7JW@I`IUD%v?tmXB7TanmkvP!*jM}dJsohW=oJg!zmirqy95jy~nph zlO9i%#^kJU zcukFp+Xj8gYHK*+OdZM`~Sq@1>gTfpJ(-Mt78N<7#}Gz+?3#=oQvE>x9bqS@ diff --git a/source/chromium.dcr b/source/chromium.dcr deleted file mode 100644 index f58c4ec9554ca1fc9825d7409f5ad4d69c9b8bca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3676 zcmeHKNlY7O6rT3bL)%*~J@(jRdQCy9(nbnONmP`Gk^rT&G&DdO1Od$E*cf7#0#TCy z!5FjHX0wgK2A9QV8*ktRY~z&~FW4B{EG~ldM&IBtVUsHLSYdth>&=_@ee?cre(A{w zf*_y4b$A%NAUyR8et;lXAai*5K5_^78o7ZaA-9o4Bmub#YwULg`S9ao(&rF-`u2M7 zC_<1K(D>w|*mYd@X79}z9Q<{#x3d=sMgrb|7xTK;+yDsR7LxD?3eHf@-$Gd^5OUdF zdaZs=F*hljoRmrl$R^yXOacW^2E`=tWB_^Gg)hkE3JycxmSt$qHgO(Vxdm3tI@1*dhpn2M&lmQ)dV0U2G zQct<9zXY~Jb`o_P7nn)&jKqcN+W-jA+B;iVte>ORW7u*kv86wO4kG)}eawlOdh*vq zRKk-ZLn13ur}U+&K1I`*rfJI1Hf3lU)71_4tit;JFn-*U5u6WNw@Zrot<{Ip4ymsz+ z<{uefv_HIxsl*OJool!rlQiR!<~4DHbGRYuv+QDvq|P?33s}|UcZY*yllR&MRBVL7 z&W&f~e#y!Iid&N4LIu8gz8~cWl>L6?K*X-v)JsB!(Xe@9+djX8X~RzSy2D7GL$D}_ zyKF-h6Lt4H^5Q{+#8}gVg&rD#t_rl1LV#0>c9$!ADpg$CETMc%a&x_|#Q-DI!PX=MXUsV5qSN@%- z`o5T%K2n=8TKA)*J`(_enEAtSO)3cXQW6EspP~39_e{LK5kv(o!s^uFnsiBBrmQhb z*7yst{+b4)}%^n(j?E)r`jl5aYxwe zK56WE`h^*wM7*Ae&+{L+7YhDsl9-EeFw8EVi^(t_Zz12nq)dK0@GfWM*?A8ZU(U$O W8F@J)Lzgr1az>v1JM{mUk^caADx?1Z 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.