From 187a4d825c53a7db7d25478c9bc6da75aa0fcafc Mon Sep 17 00:00:00 2001 From: Salvador Diaz Fau Date: Sun, 3 Jan 2021 18:36:17 +0100 Subject: [PATCH] Added TabbedBrowser2 demo for Linux Update the TCEFBitmapBitBuffer size instead of destrying and creating it when the browser is resized. --- README.md | 2 +- .../TabbedBrowser2/00-Delete.bat | 2 + .../TabbedBrowser2/TabbedBrowser2.dproj | 983 ++++++++++++++++++ .../TabbedBrowser2/TabbedBrowser2.lpi | 110 ++ .../TabbedBrowser2/TabbedBrowser2.lpr | 76 ++ .../TabbedBrowser2/TabbedBrowser2.lps | 251 +++++ demos/Lazarus_Linux/TabbedBrowser2/cef.inc | 456 ++++++++ .../TabbedBrowser2/interfaces.pas | 30 + .../TabbedBrowser2/uBrowserFrame.lfm | 221 ++++ .../TabbedBrowser2/uBrowserFrame.pas | 480 +++++++++ .../TabbedBrowser2/uBrowserTab.pas | 149 +++ .../TabbedBrowser2/uMainForm.lfm | 62 ++ .../TabbedBrowser2/uMainForm.pas | 316 ++++++ source/uCEFBitmapBitBuffer.pas | 77 +- source/uCEFBufferPanel.pas | 41 +- update_CEF4Delphi.json | 2 +- 16 files changed, 3221 insertions(+), 37 deletions(-) create mode 100644 demos/Lazarus_Linux/TabbedBrowser2/00-Delete.bat create mode 100644 demos/Lazarus_Linux/TabbedBrowser2/TabbedBrowser2.dproj create mode 100644 demos/Lazarus_Linux/TabbedBrowser2/TabbedBrowser2.lpi create mode 100644 demos/Lazarus_Linux/TabbedBrowser2/TabbedBrowser2.lpr create mode 100644 demos/Lazarus_Linux/TabbedBrowser2/TabbedBrowser2.lps create mode 100644 demos/Lazarus_Linux/TabbedBrowser2/cef.inc create mode 100644 demos/Lazarus_Linux/TabbedBrowser2/interfaces.pas create mode 100644 demos/Lazarus_Linux/TabbedBrowser2/uBrowserFrame.lfm create mode 100644 demos/Lazarus_Linux/TabbedBrowser2/uBrowserFrame.pas create mode 100644 demos/Lazarus_Linux/TabbedBrowser2/uBrowserTab.pas create mode 100644 demos/Lazarus_Linux/TabbedBrowser2/uMainForm.lfm create mode 100644 demos/Lazarus_Linux/TabbedBrowser2/uMainForm.pas diff --git a/README.md b/README.md index a0ee7bf8..0a7c0f30 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # CEF4Delphi [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Use%20CEF4Delphi%20to%20embed%20Chromium-based%20browsers%20in%20your%20application&url=https://github.com/salvadordf/CEF4Delphi&via=briskbard&hashtags=cef4delphi,delphi,lazarus,fpc) -CEF4Delphi is an open source project created by Salvador Díaz Fau to embed Chromium-based browsers in applications made with [Delphi](https://www.embarcadero.com/products/delphi/starter) or [Lazarus/FPC](https://www.lazarus-ide.org/). +CEF4Delphi is an open source project created by Salvador Díaz Fau to embed Chromium-based browsers in applications made with [Delphi](https://www.embarcadero.com/products/delphi/starter) or [Lazarus/FPC](https://www.lazarus-ide.org/) for Windows and Linux. CEF4Delphi is based on DCEF3, made by Henri Gourvest. The original license of DCEF3 still applies to CEF4Delphi. Read the license terms in the first lines of any *.pas file. diff --git a/demos/Lazarus_Linux/TabbedBrowser2/00-Delete.bat b/demos/Lazarus_Linux/TabbedBrowser2/00-Delete.bat new file mode 100644 index 00000000..0b5ba5c8 --- /dev/null +++ b/demos/Lazarus_Linux/TabbedBrowser2/00-Delete.bat @@ -0,0 +1,2 @@ +rmdir /S /Q lib +rmdir /S /Q backup diff --git a/demos/Lazarus_Linux/TabbedBrowser2/TabbedBrowser2.dproj b/demos/Lazarus_Linux/TabbedBrowser2/TabbedBrowser2.dproj new file mode 100644 index 00000000..c6a0dab1 --- /dev/null +++ b/demos/Lazarus_Linux/TabbedBrowser2/TabbedBrowser2.dproj @@ -0,0 +1,983 @@ + + + {2A491C1D-D0F3-4D4B-9606-F7FC09C7713E} + 18.8 + VCL + TabbedBrowser2.dpr + True + Debug + Win32 + 1 + Application + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + .\$(Platform)\$(Config) + ..\..\..\bin + false + false + false + false + false + System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) + $(BDS)\bin\delphi_PROJECTICON.ico + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png + TabbedBrowser2 + 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;RESTComponents;vclFireDAC;IndyProtocols250;FireDACDb2Driver;IndyCore250;DataSnapFireDAC;svnui;tethering;dsnapcon;FireDACADSDriver;FireDACMSAccDriver;fmxFireDAC;DBXMSSQLDriver;vclimg;FireDACInfxDriver;DatasnapConnectorsFreePascal;FireDAC;FireDACMSSQLDriver;vcltouch;Componentes_UI;vcldb;bindcompfmx;svn;Detours;FireDACSqliteDriver;FireDACPgDriver;DBXOracleDriver;inetdb;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;SVGPackage;soaprtl;DbxCommonDriver;FireDACIBDriver;fmx;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;fmxdae;vclwinx;rtl;FireDACDSDriver;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;dbexpress;FireDACDBXDriver;vclx;bindcomp;appanalytics;dsnap;DataSnapCommon;DBXInformixDriver;FireDACCommon;bindcompvcl;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;vclie;CEF4Delphi_FMX;bindengine;DBXMySQLDriver;FireDACOracleDriver;dsnapxml;FireDACMySQLDriver;dbrtl;inetdbxpress;DBXFirebirdDriver;DataSnapProviderClient;FireDACMongoDBDriver;FireDACCommonODBC;FireDACCommonDriver;CloudService;DataSnapClient;VisualStyles;IndySystem250;inet;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 + + + DBXSqliteDriver;bindcompdbx;fmxase;DBXDb2Driver;DBXInterBaseDriver;vcl;DBXSybaseASEDriver;vclactnband;RESTComponents;vclFireDAC;IndyProtocols250;FireDACDb2Driver;IndyCore250;DataSnapFireDAC;tethering;dsnapcon;FireDACADSDriver;FireDACMSAccDriver;fmxFireDAC;DBXMSSQLDriver;vclimg;FireDACInfxDriver;DatasnapConnectorsFreePascal;FireDAC;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;FireDACSqliteDriver;FireDACPgDriver;DBXOracleDriver;inetdb;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;soaprtl;DbxCommonDriver;FireDACIBDriver;fmx;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;fmxdae;vclwinx;rtl;FireDACDSDriver;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;dbexpress;FireDACDBXDriver;vclx;bindcomp;appanalytics;dsnap;DataSnapCommon;DBXInformixDriver;FireDACCommon;bindcompvcl;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;vclie;CEF4Delphi_FMX;bindengine;DBXMySQLDriver;FireDACOracleDriver;dsnapxml;FireDACMySQLDriver;dbrtl;inetdbxpress;DBXFirebirdDriver;DataSnapProviderClient;FireDACMongoDBDriver;FireDACCommonODBC;FireDACCommonDriver;CloudService;DataSnapClient;IndySystem250;inet;DataSnapServerMidas;$(DCC_UsePackage) + + + DEBUG;$(DCC_Define) + true + false + true + true + true + + + false + true + PerMonitorV2 + true + 1033 + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + true + PerMonitorV2 + + + + MainSource + + +
MainForm
+
+ +
BrowserFrame
+ TFrame +
+ + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + +
+ + Delphi.Personality.12 + Application + + + + TabbedBrowser2.dpr + + + IP Abstraction Indy Implementation Design Time + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + + + TabbedBrowser2.exe + true + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + classes + 1 + + + classes + 1 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + Contents\Resources\StartUp\ + 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 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 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 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + + + Contents + 1 + + + Contents + 1 + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + Contents\MacOS + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + + + + + + + + + + + True + False + + + 12 + + + + +
diff --git a/demos/Lazarus_Linux/TabbedBrowser2/TabbedBrowser2.lpi b/demos/Lazarus_Linux/TabbedBrowser2/TabbedBrowser2.lpi new file mode 100644 index 00000000..ce2f35e9 --- /dev/null +++ b/demos/Lazarus_Linux/TabbedBrowser2/TabbedBrowser2.lpi @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + <UseAppBundle Value="False"/> + <ResourceType Value="res"/> + </General> + <BuildModes Count="1"> + <Item1 Name="Default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + <Modes Count="0"/> + </RunParams> + <RequiredPackages Count="2"> + <Item1> + <PackageName Value="CEF4Delphi_Lazarus"/> + </Item1> + <Item2> + <PackageName Value="LCL"/> + </Item2> + </RequiredPackages> + <Units Count="5"> + <Unit0> + <Filename Value="TabbedBrowser2.lpr"/> + <IsPartOfProject Value="True"/> + </Unit0> + <Unit1> + <Filename Value="uMainForm.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="MainForm"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + </Unit1> + <Unit2> + <Filename Value="uBrowserFrame.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="BrowserFrame"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Frame"/> + </Unit2> + <Unit3> + <Filename Value="uBrowserTab.pas"/> + <IsPartOfProject Value="True"/> + </Unit3> + <Unit4> + <Filename Value="interfaces.pas"/> + <IsPartOfProject Value="True"/> + <UnitName Value="Interfaces"/> + </Unit4> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="..\..\..\bin\TabbedBrowser2"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <SyntaxMode Value="Delphi"/> + </SyntaxOptions> + </Parsing> + <Linking> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + <Other> + <CustomOptions Value="-dUseCThreads"/> + <OtherDefines Count="1"> + <Define0 Value="UseCThreads"/> + </OtherDefines> + </Other> + </CompilerOptions> + <Debugging> + <Exceptions Count="3"> + <Item1> + <Name Value="EAbort"/> + </Item1> + <Item2> + <Name Value="ECodetoolError"/> + </Item2> + <Item3> + <Name Value="EFOpenError"/> + </Item3> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/demos/Lazarus_Linux/TabbedBrowser2/TabbedBrowser2.lpr b/demos/Lazarus_Linux/TabbedBrowser2/TabbedBrowser2.lpr new file mode 100644 index 00000000..b32985ec --- /dev/null +++ b/demos/Lazarus_Linux/TabbedBrowser2/TabbedBrowser2.lpr @@ -0,0 +1,76 @@ +// ************************************************************************ +// ***************************** 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 <hgourvest@gmail.com> + * 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 TabbedBrowser2; + +{$mode objfpc}{$H+} + +{$I cef.inc} + +uses + {$IFDEF UNIX}{$IFDEF UseCThreads} + cthreads, + {$ENDIF}{$ENDIF} + // "Interfaces" is a custom unit used to initialize the LCL WidgetSet + // We keep the same name to avoid a Lazarus warning. + Interfaces, // this includes the LCL widgetset + Forms, + uCEFApplication, + uMainForm in 'uMainForm.pas' {MainForm}, + uBrowserFrame in 'uBrowserFrame.pas' {BrowserFrame: TFrame}, + uBrowserTab in 'uBrowserTab.pas'; + +{.$R *.res} + +begin + CreateGlobalCEFApp; + + if GlobalCEFApp.StartMainProcess then + begin + // The LCL Widgetset must be initialized after the CEF initialization and + // only in the browser process. + CustomWidgetSetInitialization; + RequireDerivedFormResource:=True; + Application.Scaled:=True; + Application.Initialize; + Application.CreateForm(TMainForm, MainForm); + Application.Run; + CustomWidgetSetFinalization; + end; + + DestroyGlobalCEFApp; +end. diff --git a/demos/Lazarus_Linux/TabbedBrowser2/TabbedBrowser2.lps b/demos/Lazarus_Linux/TabbedBrowser2/TabbedBrowser2.lps new file mode 100644 index 00000000..22d2f435 --- /dev/null +++ b/demos/Lazarus_Linux/TabbedBrowser2/TabbedBrowser2.lps @@ -0,0 +1,251 @@ +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <ProjectSession> + <PathDelim Value="\"/> + <Version Value="11"/> + <BuildModes Active="Default"/> + <Units Count="12"> + <Unit0> + <Filename Value="TabbedBrowser2.lpr"/> + <IsPartOfProject Value="True"/> + <TopLine Value="31"/> + <CursorPos X="48" Y="56"/> + <UsageCount Value="24"/> + <Loaded Value="True"/> + <DefaultSyntaxHighlighter Value="Delphi"/> + </Unit0> + <Unit1> + <Filename Value="uMainForm.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="MainForm"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <EditorIndex Value="1"/> + <TopLine Value="86"/> + <CursorPos X="54" Y="201"/> + <UsageCount Value="24"/> + <Bookmarks Count="1"> + <Item0 X="26" Y="194" ID="1"/> + </Bookmarks> + <Loaded Value="True"/> + <LoadedDesigner Value="True"/> + <DefaultSyntaxHighlighter Value="Delphi"/> + </Unit1> + <Unit2> + <Filename Value="uBrowserFrame.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="BrowserFrame"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Frame"/> + <IsVisibleTab Value="True"/> + <EditorIndex Value="3"/> + <TopLine Value="118"/> + <CursorPos X="16" Y="145"/> + <UsageCount Value="24"/> + <Bookmarks Count="3"> + <Item0 X="22" Y="471" ID="2"/> + <Item1 X="50" Y="392" ID="3"/> + <Item2 X="36" Y="415" ID="4"/> + </Bookmarks> + <Loaded Value="True"/> + <LoadedDesigner Value="True"/> + <DefaultSyntaxHighlighter Value="Delphi"/> + </Unit2> + <Unit3> + <Filename Value="uBrowserTab.pas"/> + <IsPartOfProject Value="True"/> + <EditorIndex Value="2"/> + <CursorPos X="87" Y="78"/> + <UsageCount Value="24"/> + <Loaded Value="True"/> + <DefaultSyntaxHighlighter Value="Delphi"/> + </Unit3> + <Unit4> + <Filename Value="interfaces.pas"/> + <IsPartOfProject Value="True"/> + <UnitName Value="Interfaces"/> + <EditorIndex Value="-1"/> + <UsageCount Value="24"/> + <DefaultSyntaxHighlighter Value="Delphi"/> + </Unit4> + <Unit5> + <Filename Value="..\..\..\source\uCEFApplicationCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="953"/> + <CursorPos Y="960"/> + <UsageCount Value="10"/> + </Unit5> + <Unit6> + <Filename Value="..\..\..\source\uCEFMiscFunctions.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="1476"/> + <CursorPos X="86" Y="1495"/> + <UsageCount Value="10"/> + </Unit6> + <Unit7> + <Filename Value="..\..\..\..\..\..\..\usr\share\lazarus\2.0.10\lcl\forms.pp"/> + <UnitName Value="Forms"/> + <EditorIndex Value="-1"/> + <TopLine Value="1461"/> + <CursorPos X="69" Y="1482"/> + <UsageCount Value="10"/> + </Unit7> + <Unit8> + <Filename Value="..\..\..\..\..\..\..\usr\share\lazarus\2.0.10\lcl\controls.pp"/> + <UnitName Value="Controls"/> + <EditorIndex Value="-1"/> + <TopLine Value="2242"/> + <CursorPos X="14" Y="2262"/> + <UsageCount Value="10"/> + </Unit8> + <Unit9> + <Filename Value="..\..\..\..\..\..\..\usr\share\fpcsrc\3.2.0\rtl\objpas\classes\classesh.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="96"/> + <CursorPos X="27" Y="118"/> + <UsageCount Value="10"/> + </Unit9> + <Unit10> + <Filename Value="..\SimpleBrowser2\usimplebrowser2.pas"/> + <UnitName Value="uSimpleBrowser2"/> + <EditorIndex Value="-1"/> + <TopLine Value="130"/> + <CursorPos X="33" Y="159"/> + <UsageCount Value="10"/> + <DefaultSyntaxHighlighter Value="Delphi"/> + </Unit10> + <Unit11> + <Filename Value="..\..\..\source\uCEFLinkedWindowParent.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="85"/> + <CursorPos X="3" Y="177"/> + <UsageCount Value="10"/> + </Unit11> + </Units> + <OtherDefines Count="1"> + <Define0 Value="UseCThreads"/> + </OtherDefines> + <JumpHistory Count="29" HistoryIndex="28"> + <Position1> + <Filename Value="uBrowserFrame.pas"/> + <Caret Line="124" Column="17" TopLine="103"/> + </Position1> + <Position2> + <Filename Value="uBrowserFrame.pas"/> + <Caret Line="463" Column="3" TopLine="436"/> + </Position2> + <Position3> + <Filename Value="uBrowserTab.pas"/> + <Caret Line="117" Column="67" TopLine="84"/> + </Position3> + <Position4> + <Filename Value="uBrowserTab.pas"/> + <Caret Line="128" Column="61" TopLine="103"/> + </Position4> + <Position5> + <Filename Value="uBrowserFrame.pas"/> + <Caret Line="144" Column="19" TopLine="123"/> + </Position5> + <Position6> + <Filename Value="uBrowserTab.pas"/> + <Caret Line="133" Column="90" TopLine="103"/> + </Position6> + <Position7> + <Filename Value="uBrowserTab.pas"/> + <Caret Line="61" Column="67" TopLine="39"/> + </Position7> + <Position8> + <Filename Value="uBrowserTab.pas"/> + <Caret Line="131" Column="41" TopLine="103"/> + </Position8> + <Position9> + <Filename Value="uBrowserTab.pas"/> + <Caret Line="61" Column="19" TopLine="39"/> + </Position9> + <Position10> + <Filename Value="uBrowserTab.pas"/> + <Caret Line="126" Column="42" TopLine="103"/> + </Position10> + <Position11> + <Filename Value="uBrowserFrame.pas"/> + <Caret Line="144" Column="19" TopLine="90"/> + </Position11> + <Position12> + <Filename Value="uMainForm.pas"/> + <Caret Line="96" Column="28" TopLine="86"/> + </Position12> + <Position13> + <Filename Value="uMainForm.pas"/> + <Caret Line="264" Column="38" TopLine="240"/> + </Position13> + <Position14> + <Filename Value="uMainForm.pas"/> + <Caret Line="87" Column="15" TopLine="71"/> + </Position14> + <Position15> + <Filename Value="uMainForm.pas"/> + <Caret Line="262" Column="75" TopLine="240"/> + </Position15> + <Position16> + <Filename Value="uMainForm.pas"/> + <Caret Line="303" Column="41" TopLine="261"/> + </Position16> + <Position17> + <Filename Value="uMainForm.pas"/> + <Caret Line="84" Column="15" TopLine="71"/> + </Position17> + <Position18> + <Filename Value="uMainForm.pas"/> + <Caret Line="271" Column="41" TopLine="264"/> + </Position18> + <Position19> + <Filename Value="uMainForm.pas"/> + <Caret Line="85" Column="15" TopLine="63"/> + </Position19> + <Position20> + <Filename Value="uBrowserFrame.pas"/> + <Caret Line="113" Column="73" TopLine="90"/> + </Position20> + <Position21> + <Filename Value="uBrowserFrame.pas"/> + <Caret Line="132" Column="32" TopLine="96"/> + </Position21> + <Position22> + <Filename Value="uMainForm.pas"/> + <Caret Line="303" Column="69" TopLine="259"/> + </Position22> + <Position23> + <Filename Value="uMainForm.pas"/> + <Caret Line="190" Column="3" TopLine="170"/> + </Position23> + <Position24> + <Filename Value="uMainForm.pas"/> + <Caret Line="219" TopLine="205"/> + </Position24> + <Position25> + <Filename Value="uMainForm.pas"/> + <Caret Line="71" TopLine="60"/> + </Position25> + <Position26> + <Filename Value="uBrowserFrame.pas"/> + <Caret Line="78" Column="25" TopLine="62"/> + </Position26> + <Position27> + <Filename Value="uBrowserFrame.pas"/> + <Caret Line="359" Column="49" TopLine="355"/> + </Position27> + <Position28> + <Filename Value="uBrowserFrame.pas"/> + <Caret Line="77" Column="17" TopLine="56"/> + </Position28> + <Position29> + <Filename Value="uBrowserFrame.pas"/> + <Caret Line="464" Column="59" TopLine="40"/> + </Position29> + </JumpHistory> + <RunParams> + <FormatVersion Value="2"/> + <Modes Count="0" ActiveMode=""/> + </RunParams> + </ProjectSession> +</CONFIG> diff --git a/demos/Lazarus_Linux/TabbedBrowser2/cef.inc b/demos/Lazarus_Linux/TabbedBrowser2/cef.inc new file mode 100644 index 00000000..a4c8d038 --- /dev/null +++ b/demos/Lazarus_Linux/TabbedBrowser2/cef.inc @@ -0,0 +1,456 @@ +// ************************************************************************ +// ***************************** CEF4Delphi ******************************* +// ************************************************************************ +// +// CEF4Delphi is based on DCEF3 which uses CEF3 to embed a chromium-based +// browser in Delphi applications. +// +// The original license of DCEF3 still applies to CEF4Delphi. +// +// For more information about CEF4Delphi visit : +// https://www.briskbard.com/index.php?lang=en&pageid=cef +// +// Copyright © 2017 Salvador Diaz Fau. All rights reserved. +// +// ************************************************************************ +// ************ vvvv Original license and comments below vvvv ************* +// ************************************************************************ +(* + * Delphi Chromium Embedded 3 + * + * Usage allowed under the restrictions of the Lesser GNU General Public License + * or alternatively the restrictions of the Mozilla Public License 1.1 + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + * the specific language governing rights and limitations under the License. + * + * Unit owner : Henri Gourvest <hgourvest@gmail.com> + * Web site : http://www.progdigy.com + * Repository : http://code.google.com/p/delphichromiumembedded/ + * Group : http://groups.google.com/group/delphichromiumembedded + * + * Embarcadero Technologies, Inc is not permitted to use or redistribute + * this source code without explicit permission. + * + *) + + // The complete list of compiler versions is here : + // http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Compiler_Versions + +{$DEFINE DELPHI_VERSION_UNKNOW} + +// Delphi 5 +{$IFDEF VER130} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} +{$ENDIF} + +// Delphi 6 +{$IFDEF VER140} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} +{$ENDIF} + +// Delphi 7 +{$IFDEF VER150} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} +{$ENDIF} + +// Delphi 8 +{$IFDEF VER160} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} +{$ENDIF} + +// Delphi 2005 +{$IFDEF VER170} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} +{$ENDIF} + +{$IFDEF VER180} + {$UNDEF DELPHI_VERSION_UNKNOW} + // Delphi 2007 + {$IFDEF VER185} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + // Delphi 2006 + {$ELSE} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$ENDIF} +{$ENDIF} + +// Delphi 2009 +{$IFDEF VER200} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} +{$ENDIF} + +//Delphi 2010 +{$IFDEF VER210} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} +{$ENDIF} + +// Delphi XE +{$IFDEF VER220} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} +{$ENDIF} + +// Delphi XE2 (First FireMonkey and 64bit compiler) +{$IFDEF VER230} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} +{$ENDIF} + +// Delphi XE3 +{$IFDEF VER240} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} +{$ENDIF} + +// Delphi XE4 +{$IFDEF VER250} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} +{$ENDIF} + +// Delphi XE5 +{$IFDEF VER260} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} +{$ENDIF} + +// Delphi XE6 +{$IFDEF VER270} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} +{$ENDIF} + +// Delphi XE7 +{$IFDEF VER280} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} +{$ENDIF} + +// Delphi XE8 +{$IFDEF VER290} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI22_UP} +{$ENDIF VER290} + +// Rad Studio 10 - Delphi Seattle +{$IFDEF VER300} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI23_UP} +{$ENDIF} + +// Rad Studio 10.1 - Delphi Berlin +{$IFDEF VER310} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI24_UP} +{$ENDIF} + +// Rad Studio 10.2 - Delphi Tokyo +{$IFDEF VER320} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI25_UP} +{$ENDIF} + +// Rad Studio 10.3 - Delphi Rio +{$IFDEF VER330} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI26_UP} +{$ENDIF} + +// Rad Studio 10.4 - Delphi Sydney +{$IFDEF VER340} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI26_UP} + {$DEFINE DELPHI27_UP} +{$ENDIF} + +{$IFDEF FPC} + {$DEFINE SUPPORTS_INLINE} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30200)} + {$DEFINE FPC_VER_320} + {$IFEND} +{$ELSE} + {$IFDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI26_UP} + {$DEFINE DELPHI27_UP} + {$ENDIF} +{$ENDIF} + +{$IFDEF DELPHI9_UP} + {$DEFINE SUPPORTS_INLINE} +{$ENDIF} + +{$IF DEFINED(CPUX32) OR + DEFINED(CPU386) OR + DEFINED(CPUi386) OR + DEFINED(CPUPOWERPC32) OR + DEFINED(CPUSPARC32) OR + DEFINED(CPU32BITS) OR + DEFINED(CPUARM32) OR + DEFINED(WIN32) OR + DEFINED(IOS32) OR + DEFINED(MACOS32) OR + DEFINED(LINUX32) OR + DEFINED(POSIX32) OR + DEFINED(ANDROID32)} + {$DEFINE TARGET_32BITS} +{$IFEND} + diff --git a/demos/Lazarus_Linux/TabbedBrowser2/interfaces.pas b/demos/Lazarus_Linux/TabbedBrowser2/interfaces.pas new file mode 100644 index 00000000..60c7250f --- /dev/null +++ b/demos/Lazarus_Linux/TabbedBrowser2/interfaces.pas @@ -0,0 +1,30 @@ +unit Interfaces; + +{$mode objfpc}{$H+} + +interface + +{$IFDEF UNIX}{$IFNDEF DisableCWString}uses cwstring;{$ENDIF}{$ENDIF} + +procedure CustomWidgetSetInitialization; +procedure CustomWidgetSetFinalization; + +implementation + +uses + {$IFNDEF EnableLibOverlay} + gtk2DisableLibOverlay, + {$ENDIF} + Gtk2Int, Forms; + +procedure CustomWidgetSetInitialization; +begin + CreateWidgetset(TGtk2WidgetSet); +end; + +procedure CustomWidgetSetFinalization; +begin + FreeWidgetSet; +end; + +end. diff --git a/demos/Lazarus_Linux/TabbedBrowser2/uBrowserFrame.lfm b/demos/Lazarus_Linux/TabbedBrowser2/uBrowserFrame.lfm new file mode 100644 index 00000000..f2a64ec1 --- /dev/null +++ b/demos/Lazarus_Linux/TabbedBrowser2/uBrowserFrame.lfm @@ -0,0 +1,221 @@ +object BrowserFrame: TBrowserFrame + Left = 0 + Height = 670 + Top = 0 + Width = 932 + ClientHeight = 670 + ClientWidth = 932 + TabOrder = 0 + DesignLeft = 318 + DesignTop = 172 + object NavControlPnl: TPanel + Left = 0 + Height = 28 + Top = 0 + Width = 932 + Align = alTop + BevelOuter = bvNone + ClientHeight = 28 + ClientWidth = 932 + Enabled = False + TabOrder = 0 + object NavButtonPnl: TPanel + Left = 0 + Height = 28 + Top = 0 + Width = 123 + Align = alLeft + BevelOuter = bvNone + ClientHeight = 28 + ClientWidth = 123 + TabOrder = 0 + object BackBtn: TButton + Left = 0 + Height = 25 + Top = 0 + Width = 25 + Caption = '3' + Font.CharSet = SYMBOL_CHARSET + Font.Color = clWindowText + Font.Height = -19 + Font.Name = 'Webdings' + OnClick = BackBtnClick + ParentFont = False + TabOrder = 0 + end + object ForwardBtn: TButton + Left = 30 + Height = 25 + Top = 0 + Width = 25 + Caption = '4' + Font.CharSet = SYMBOL_CHARSET + Font.Color = clWindowText + Font.Height = -19 + Font.Name = 'Webdings' + OnClick = ForwardBtnClick + ParentFont = False + TabOrder = 1 + end + object ReloadBtn: TButton + Left = 59 + Height = 25 + Top = 0 + Width = 25 + Caption = 'q' + Font.CharSet = SYMBOL_CHARSET + Font.Color = clWindowText + Font.Height = -19 + Font.Name = 'Webdings' + OnClick = ReloadBtnClick + ParentFont = False + TabOrder = 2 + end + object StopBtn: TButton + Left = 88 + Height = 25 + Top = 0 + Width = 25 + Caption = '=' + Font.CharSet = SYMBOL_CHARSET + Font.Color = clWindowText + Font.Height = -19 + Font.Name = 'Webdings' + OnClick = StopBtnClick + ParentFont = False + TabOrder = 3 + end + end + object URLEditPnl: TPanel + Left = 123 + Height = 28 + Top = 0 + Width = 774 + Align = alClient + BevelOuter = bvNone + ClientHeight = 28 + ClientWidth = 774 + TabOrder = 1 + object URLCbx: TComboBox + Left = 0 + Height = 27 + Top = 1 + Width = 774 + Anchors = [akTop, akLeft, akRight] + ItemHeight = 0 + ItemIndex = 0 + Items.Strings = ( + 'https://www.google.com' + 'https://www.whatismybrowser.com/detect/what-http-headers-is-my-browser-sending' + 'https://www.w3schools.com/js/tryit.asp?filename=tryjs_win_close' + 'https://www.w3schools.com/js/tryit.asp?filename=tryjs_alert' + 'https://www.w3schools.com/js/tryit.asp?filename=tryjs_loc_assign' + 'https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_style_backgroundcolor' + 'https://www.w3schools.com/html/html5_video.asp' + 'http://www.adobe.com/software/flash/about/' + 'http://isflashinstalled.com/' + 'https://helpx.adobe.com/flash-player.html' + 'https://www.ultrasounds.com/' + 'https://www.whatismybrowser.com/detect/is-flash-installed' + 'http://html5test.com/' + 'https://webrtc.github.io/samples/src/content/devices/input-output/' + 'https://test.webrtc.org/' + 'https://www.w3schools.com/' + 'http://webglsamples.org/' + 'https://get.webgl.org/' + 'https://www.briskbard.com' + 'https://www.youtube.com' + 'https://html5demos.com/drag/' + 'https://developers.google.com/maps/documentation/javascript/examples/streetview-embed?hl=fr' + 'https://www.w3schools.com/Tags/tryit.asp?filename=tryhtml_iframe_name' + 'http://www-db.deis.unibo.it/courses/TW/DOCS/w3schools/html/tryit.asp-filename=tryhtml5_html_manifest.html' + 'https://www.browserleaks.com/webrtc' + 'https://frames-per-second.appspot.com/' + 'chrome://version/' + 'chrome://net-internals/' + 'chrome://tracing/' + 'chrome://appcache-internals/' + 'chrome://blob-internals/' + 'chrome://view-http-cache/' + 'chrome://credits/' + 'chrome://histograms/' + 'chrome://media-internals/' + 'chrome://kill' + 'chrome://crash' + 'chrome://hang' + 'chrome://shorthang' + 'chrome://gpuclean' + 'chrome://gpucrash' + 'chrome://gpuhang' + 'chrome://extensions-support' + 'chrome://process-internals' + ) + TabOrder = 0 + Text = 'https://www.google.com' + end + end + object ConfigPnl: TPanel + Left = 897 + Height = 28 + Top = 0 + Width = 35 + Align = alRight + BevelOuter = bvNone + ClientHeight = 28 + ClientWidth = 35 + TabOrder = 2 + object GoBtn: TButton + Left = 5 + Height = 25 + Top = 0 + Width = 25 + Caption = 'â–º' + Font.CharSet = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -17 + Font.Name = 'Arial' + Font.Style = [fsBold] + OnClick = GoBtnClick + ParentFont = False + TabOrder = 0 + end + end + end + object StatusBar1: TStatusBar + Left = 0 + Height = 17 + Top = 653 + Width = 932 + Panels = < + item + Width = 500 + end> + SimplePanel = False + end + object CEFLinkedWindowParent1: TCEFLinkedWindowParent + Left = 0 + Height = 625 + Top = 28 + Width = 932 + Align = alClient + TabOrder = 2 + OnEnter = CEFLinkedWindowParent1Enter + OnExit = CEFLinkedWindowParent1Exit + Chromium = Chromium1 + end + object Chromium1: TChromium + OnLoadError = Chromium1LoadError + OnLoadingStateChange = Chromium1LoadingStateChange + OnGotFocus = Chromium1GotFocus + OnAddressChange = Chromium1AddressChange + OnTitleChange = Chromium1TitleChange + OnStatusMessage = Chromium1StatusMessage + OnBeforePopup = Chromium1BeforePopup + OnAfterCreated = Chromium1AfterCreated + OnBeforeClose = Chromium1BeforeClose + OnClose = Chromium1Close + OnOpenUrlFromTab = Chromium1OpenUrlFromTab + Left = 40 + Top = 72 + end +end diff --git a/demos/Lazarus_Linux/TabbedBrowser2/uBrowserFrame.pas b/demos/Lazarus_Linux/TabbedBrowser2/uBrowserFrame.pas new file mode 100644 index 00000000..bd9782d4 --- /dev/null +++ b/demos/Lazarus_Linux/TabbedBrowser2/uBrowserFrame.pas @@ -0,0 +1,480 @@ +// ************************************************************************ +// ***************************** CEF4Delphi ******************************* +// ************************************************************************ +// +// CEF4Delphi is based on DCEF3 which uses CEF to embed a chromium-based +// browser in Delphi applications. +// +// The original license of DCEF3 still applies to CEF4Delphi. +// +// For more information about CEF4Delphi visit : +// https://www.briskbard.com/index.php?lang=en&pageid=cef +// +// Copyright © 2021 Salvador Diaz Fau. All rights reserved. +// +// ************************************************************************ +// ************ vvvv Original license and comments below vvvv ************* +// ************************************************************************ +(* + * Delphi Chromium Embedded 3 + * + * Usage allowed under the restrictions of the Lesser GNU General Public License + * or alternatively the restrictions of the Mozilla Public License 1.1 + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + * the specific language governing rights and limitations under the License. + * + * Unit owner : Henri Gourvest <hgourvest@gmail.com> + * 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 uBrowserFrame; + +{$mode objfpc}{$H+} + +{$I cef.inc} + +interface + +uses + LCLIntf, LCLType, LMessages, Messages, SysUtils, Variants, SyncObjs, Classes, + Graphics, Controls, Forms, Dialogs, ExtCtrls, ComCtrls, StdCtrls, + uCEFWinControl, uCEFWindowParent, uCEFChromiumCore, uCEFChromium, uCEFTypes, + uCEFInterfaces, uCEFConstants, uCEFLinkedWindowParent, uCEFChromiumEvents; + +type + TBrowserTitleEvent = procedure(Sender: TObject; const aTitle : string) of object; + + { TBrowserFrame } + + TBrowserFrame = class(TFrame) + CEFLinkedWindowParent1: TCEFLinkedWindowParent; + NavControlPnl: TPanel; + NavButtonPnl: TPanel; + BackBtn: TButton; + ForwardBtn: TButton; + ReloadBtn: TButton; + StopBtn: TButton; + URLEditPnl: TPanel; + URLCbx: TComboBox; + ConfigPnl: TPanel; + GoBtn: TButton; + StatusBar1: TStatusBar; + Chromium1: TChromium; + + procedure CEFLinkedWindowParent1Enter(Sender: TObject); + procedure CEFLinkedWindowParent1Exit(Sender: TObject); + + procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); + procedure Chromium1AddressChange(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const url: ustring); + procedure Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); + procedure Chromium1Close(Sender: TObject; const browser: ICefBrowser; var aAction: TCefCloseBrowserAction); + procedure Chromium1GotFocus(Sender: TObject; const browser: ICefBrowser); + procedure Chromium1LoadError(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; errorCode: Integer; const errorText, failedUrl: ustring); + procedure Chromium1LoadingStateChange(Sender: TObject; const browser: ICefBrowser; isLoading, canGoBack, canGoForward: Boolean); + procedure Chromium1StatusMessage(Sender: TObject; const browser: ICefBrowser; const value: ustring); + procedure Chromium1TitleChange(Sender: TObject; const browser: ICefBrowser; const title: ustring); + procedure Chromium1BeforePopup(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl, targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; const popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo; var client: ICefClient; var settings: TCefBrowserSettings; var extra_info: ICefDictionaryValue; var noJavascriptAccess, Result: Boolean); + procedure Chromium1OpenUrlFromTab(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; out Result: Boolean); + + procedure BackBtnClick(Sender: TObject); + procedure ForwardBtnClick(Sender: TObject); + procedure ReloadBtnClick(Sender: TObject); + procedure StopBtnClick(Sender: TObject); + procedure GoBtnClick(Sender: TObject); + + protected + FClosing : boolean; // Indicates that this frame is destroying the browser + FHomepage : string; + FOnBrowserDestroyed : TNotifyEvent; + FOnBrowserTitleChange : TBrowserTitleEvent; + FBrowserCS : TCriticalSection; + FBrowserAddress : string; + FBrowserIsLoading : boolean; + FBrowserCanGoBack : boolean; + FBrowserCanGoForward : boolean; + FBrowserStatusText : string; + FBrowserTitle : string; + + procedure SetBrowserAddress(const aValue : string); + procedure SetBrowserIsLoading(aValue : boolean); + procedure SetBrowserCanGoBack(aValue : boolean); + procedure SetBrowserCanGoForward(aValue : boolean); + procedure SetBrowserStatusText(const aValue : string); + procedure SetBrowserTitle(const aValue : string); + + function GetBrowserAddress : string; + function GetBrowserIsLoading : boolean; + function GetBrowserCanGoBack : boolean; + function GetBrowserCanGoForward : boolean; + function GetBrowserStatusText : string; + function GetBrowserTitle : string; + + procedure BrowserCreatedMsg(Data: PtrInt); + procedure BrowserUpdateAddressMsg(Data: PtrInt); + procedure BrowserUpdateLoadingStateMsg(Data: PtrInt); + procedure BrowserUpdateStatusTextMsg(Data: PtrInt); + procedure BrowserUpdateTitleMsg(Data: PtrInt); + + procedure SendCompMessage(aMsg : cardinal); + + property BrowserAddress : string read GetBrowserAddress write SetBrowserAddress; + property BrowserIsLoading : boolean read GetBrowserIsLoading write SetBrowserIsLoading; + property BrowserCanGoBack : boolean read GetBrowserCanGoBack write SetBrowserCanGoBack; + property BrowserCanGoForward : boolean read GetBrowserCanGoForward write SetBrowserCanGoForward; + property BrowserStatusText : string read GetBrowserStatusText write SetBrowserStatusText; + property BrowserTitle : string read GetBrowserTitle write SetBrowserTitle; + + public + constructor Create(AOwner : TComponent); override; + destructor Destroy; override; + procedure NotifyMoveOrResizeStarted; + procedure CreateBrowser; + procedure CloseBrowser; + + property Closing : boolean read FClosing; + property Homepage : string read FHomepage write FHomepage; + property OnBrowserDestroyed : TNotifyEvent read FOnBrowserDestroyed write FOnBrowserDestroyed; + property OnBrowserTitleChange : TBrowserTitleEvent read FOnBrowserTitleChange write FOnBrowserTitleChange; + end; + +implementation + +{$R *.lfm} + +const + CEF_UPDATEADDRESS = 301; + CEF_UPDATELOADINGSTATE = 302; + CEF_UPDATESTATUSTEXT = 303; + CEF_UPDATETITLE = 304; + +constructor TBrowserFrame.Create(AOwner : TComponent); +begin + inherited Create(AOwner); + + FClosing := False; + FHomepage := ''; + FBrowserAddress := ''; + FBrowserIsLoading := False; + FBrowserCanGoBack := False; + FBrowserCanGoForward := False; + FBrowserStatusText := ''; + FBrowserTitle := ''; + FOnBrowserDestroyed := nil; + FOnBrowserTitleChange := nil; + FBrowserCS := TCriticalSection.Create; +end; + +destructor TBrowserFrame.Destroy; +begin + FBrowserCS.Free; + inherited Destroy; +end; + +procedure TBrowserFrame.SetBrowserAddress(const aValue : string); +begin + FBrowserCS.Acquire; + FBrowserAddress := aValue; + FBrowserCS.Release; +end; + +procedure TBrowserFrame.SetBrowserIsLoading(aValue : boolean); +begin + FBrowserCS.Acquire; + FBrowserIsLoading := aValue; + FBrowserCS.Release; +end; + +procedure TBrowserFrame.SetBrowserCanGoBack(aValue : boolean); +begin + FBrowserCS.Acquire; + FBrowserCanGoBack := aValue; + FBrowserCS.Release; +end; + +procedure TBrowserFrame.SetBrowserCanGoForward(aValue : boolean); +begin + FBrowserCS.Acquire; + FBrowserCanGoForward := aValue; + FBrowserCS.Release; +end; + +procedure TBrowserFrame.SetBrowserStatusText(const aValue : string); +begin + FBrowserCS.Acquire; + FBrowserStatusText := aValue; + FBrowserCS.Release; +end; + +procedure TBrowserFrame.SetBrowserTitle(const aValue : string); +begin + FBrowserCS.Acquire; + FBrowserTitle := aValue; + FBrowserCS.Release; +end; + +function TBrowserFrame.GetBrowserAddress : string; +begin + FBrowserCS.Acquire; + Result := FBrowserAddress; + FBrowserCS.Release; +end; + +function TBrowserFrame.GetBrowserIsLoading : boolean; +begin + FBrowserCS.Acquire; + Result := FBrowserIsLoading; + FBrowserCS.Release; +end; + +function TBrowserFrame.GetBrowserCanGoBack : boolean; +begin + FBrowserCS.Acquire; + Result := FBrowserCanGoBack; + FBrowserCS.Release; +end; + +function TBrowserFrame.GetBrowserCanGoForward : boolean; +begin + FBrowserCS.Acquire; + Result := FBrowserCanGoForward; + FBrowserCS.Release; +end; + +function TBrowserFrame.GetBrowserStatusText : string; +begin + FBrowserCS.Acquire; + Result := FBrowserStatusText; + FBrowserCS.Release; +end; + +function TBrowserFrame.GetBrowserTitle : string; +begin + FBrowserCS.Acquire; + Result := FBrowserTitle; + FBrowserCS.Release; +end; + +procedure TBrowserFrame.NotifyMoveOrResizeStarted; +begin + Chromium1.NotifyMoveOrResizeStarted; +end; + +procedure TBrowserFrame.ReloadBtnClick(Sender: TObject); +begin + Chromium1.Reload; +end; + +procedure TBrowserFrame.StopBtnClick(Sender: TObject); +begin + Chromium1.StopLoad; +end; + +procedure TBrowserFrame.CreateBrowser; +begin + Chromium1.DefaultURL := FHomepage; + Chromium1.CreateBrowser(CEFLinkedWindowParent1.Handle, CEFLinkedWindowParent1.BoundsRect); +end; + +procedure TBrowserFrame.CloseBrowser; +begin + if not(FClosing) then + begin + FClosing := True; + NavControlPnl.Enabled := False; + Chromium1.CloseBrowser(True); + end; +end; + +procedure TBrowserFrame.ForwardBtnClick(Sender: TObject); +begin + Chromium1.GoForward; +end; + +procedure TBrowserFrame.GoBtnClick(Sender: TObject); +begin + Chromium1.LoadURL(UTF8Decode(URLCbx.Text)); +end; + +procedure TBrowserFrame.Chromium1AfterCreated(Sender: TObject; + const browser: ICefBrowser); +begin + SendCompMessage(CEF_AFTERCREATED); +end; + +procedure TBrowserFrame.CEFLinkedWindowParent1Enter(Sender: TObject); +begin + if not(csDesigning in ComponentState) and + Chromium1.Initialized and + not(Chromium1.FrameIsFocused) then + Chromium1.SendFocusEvent(True); +end; + +procedure TBrowserFrame.CEFLinkedWindowParent1Exit(Sender: TObject); +begin + if not(csDesigning in ComponentState) then + Chromium1.SendCaptureLostEvent; +end; + +procedure TBrowserFrame.BackBtnClick(Sender: TObject); +begin + Chromium1.GoBack; +end; + +procedure TBrowserFrame.Chromium1AddressChange(Sender: TObject; + const browser: ICefBrowser; const frame: ICefFrame; const url: ustring); +begin + BrowserAddress := url; + SendCompMessage(CEF_UPDATEADDRESS); +end; + +procedure TBrowserFrame.Chromium1BeforeClose(Sender: TObject; + const browser: ICefBrowser); +begin + if assigned(FOnBrowserDestroyed) then FOnBrowserDestroyed(self); +end; + +procedure TBrowserFrame.Chromium1BeforePopup(Sender: TObject; + const browser: ICefBrowser; const frame: ICefFrame; const targetUrl, + targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition; + userGesture: Boolean; const popupFeatures: TCefPopupFeatures; + var windowInfo: TCefWindowInfo; var client: ICefClient; + var settings: TCefBrowserSettings; var extra_info: ICefDictionaryValue; + var noJavascriptAccess, Result: Boolean); +begin + // For simplicity, this demo blocks all popup windows and new tabs + Result := (targetDisposition in [WOD_NEW_FOREGROUND_TAB, WOD_NEW_BACKGROUND_TAB, WOD_NEW_POPUP, WOD_NEW_WINDOW]); +end; + +procedure TBrowserFrame.Chromium1Close(Sender: TObject; + const browser: ICefBrowser; var aAction: TCefCloseBrowserAction); +begin + // continue closing the browser + aAction := cbaClose; +end; + +procedure TBrowserFrame.Chromium1GotFocus(Sender: TObject; + const browser: ICefBrowser); +begin + CEFLinkedWindowParent1.SetFocus; +end; + +procedure TBrowserFrame.Chromium1LoadError(Sender: TObject; + const browser: ICefBrowser; const frame: ICefFrame; errorCode: Integer; + const errorText, failedUrl: ustring); +var + TempString : string; +begin + if (errorCode = ERR_ABORTED) then exit; + + TempString := '<html><body bgcolor="white">' + + '<h2>Failed to load URL ' + failedUrl + + ' with error ' + errorText + + ' (' + inttostr(errorCode) + ').</h2></body></html>'; + + Chromium1.LoadString(UTF8Decode(TempString), frame); +end; + +procedure TBrowserFrame.Chromium1LoadingStateChange(Sender: TObject; + const browser: ICefBrowser; isLoading, canGoBack, canGoForward: Boolean); +begin + BrowserIsLoading := isLoading; + BrowserCanGoBack := canGoBack; + BrowserCanGoForward := canGoForward; + + SendCompMessage(CEF_UPDATELOADINGSTATE); +end; + +procedure TBrowserFrame.Chromium1OpenUrlFromTab(Sender: TObject; + const browser: ICefBrowser; const frame: ICefFrame; const targetUrl: ustring; + targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; + out Result: Boolean); +begin + // For simplicity, this demo blocks all popup windows and new tabs + Result := (targetDisposition in [WOD_NEW_FOREGROUND_TAB, WOD_NEW_BACKGROUND_TAB, WOD_NEW_POPUP, WOD_NEW_WINDOW]); +end; + +procedure TBrowserFrame.Chromium1StatusMessage(Sender: TObject; + const browser: ICefBrowser; const value: ustring); +begin + BrowserStatusText := value; + SendCompMessage(CEF_UPDATESTATUSTEXT); +end; + +procedure TBrowserFrame.Chromium1TitleChange(Sender: TObject; + const browser: ICefBrowser; const title: ustring); +begin + if (length(title) > 0) then + BrowserTitle := title + else + BrowserTitle := Chromium1.DocumentURL; + + SendCompMessage(CEF_UPDATETITLE); +end; + +procedure TBrowserFrame.BrowserCreatedMsg(Data: PtrInt); +begin + CEFLinkedWindowParent1.UpdateSize; + NavControlPnl.Enabled := True; +end; + +procedure TBrowserFrame.BrowserUpdateAddressMsg(Data: PtrInt); +var + TempURL : string; +begin + TempURL := BrowserAddress; + + if (URLCbx.Items.IndexOf(TempURL) < 0) then URLCbx.Items.Add(TempURL); + + URLCbx.Text := TempURL; +end; + +procedure TBrowserFrame.BrowserUpdateLoadingStateMsg(Data: PtrInt); +begin + BackBtn.Enabled := BrowserCanGoBack; + ForwardBtn.Enabled := BrowserCanGoForward; + + if BrowserIsLoading then + begin + ReloadBtn.Enabled := False; + StopBtn.Enabled := True; + end + else + begin + ReloadBtn.Enabled := True; + StopBtn.Enabled := False; + end; +end; + +procedure TBrowserFrame.BrowserUpdateStatusTextMsg(Data: PtrInt); +begin + StatusBar1.Panels[0].Text := BrowserStatusText; +end; + +procedure TBrowserFrame.BrowserUpdateTitleMsg(Data: PtrInt); +begin + if assigned(FOnBrowserTitleChange) then + FOnBrowserTitleChange(self, BrowserTitle); +end; + +procedure TBrowserFrame.SendCompMessage(aMsg : cardinal); +begin + case aMsg of + CEF_AFTERCREATED : Application.QueueAsyncCall(@BrowserCreatedMsg, 0); + CEF_UPDATEADDRESS : Application.QueueAsyncCall(@BrowserUpdateAddressMsg, 0); + CEF_UPDATELOADINGSTATE : Application.QueueAsyncCall(@BrowserUpdateLoadingStateMsg, 0); + CEF_UPDATESTATUSTEXT : Application.QueueAsyncCall(@BrowserUpdateStatusTextMsg, 0); + CEF_UPDATETITLE : Application.QueueAsyncCall(@BrowserUpdateTitleMsg, 0); + end; +end; + +end. + + diff --git a/demos/Lazarus_Linux/TabbedBrowser2/uBrowserTab.pas b/demos/Lazarus_Linux/TabbedBrowser2/uBrowserTab.pas new file mode 100644 index 00000000..ea17055e --- /dev/null +++ b/demos/Lazarus_Linux/TabbedBrowser2/uBrowserTab.pas @@ -0,0 +1,149 @@ +// ************************************************************************ +// ***************************** CEF4Delphi ******************************* +// ************************************************************************ +// +// CEF4Delphi is based on DCEF3 which uses CEF to embed a chromium-based +// browser in Delphi applications. +// +// The original license of DCEF3 still applies to CEF4Delphi. +// +// For more information about CEF4Delphi visit : +// https://www.briskbard.com/index.php?lang=en&pageid=cef +// +// Copyright © 2021 Salvador Diaz Fau. All rights reserved. +// +// ************************************************************************ +// ************ vvvv Original license and comments below vvvv ************* +// ************************************************************************ +(* + * Delphi Chromium Embedded 3 + * + * Usage allowed under the restrictions of the Lesser GNU General Public License + * or alternatively the restrictions of the Mozilla Public License 1.1 + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + * the specific language governing rights and limitations under the License. + * + * Unit owner : Henri Gourvest <hgourvest@gmail.com> + * 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 uBrowserTab; + +{$mode objfpc}{$H+} + +{$I cef.inc} + +interface + +uses + LCLIntf, LCLType, LMessages, Classes, Messages, ComCtrls, Controls, + Forms, + uBrowserFrame; + +type + TBrowserTab = class(TTabSheet) + protected + FBrowserFrame : TBrowserFrame; + FTabID : cardinal; + + function GetParentForm : TCustomForm; + + procedure SendFormMessage(aMsg : cardinal; aData : PtrInt = 0); + + procedure BrowserFrame_OnBrowserDestroyed(Sender: TObject); + procedure BrowserFrame_OnBrowserTitleChange(Sender: TObject; const aTitle : string); + + property ParentForm : TCustomForm read GetParentForm; + + public + constructor Create(AOwner: TComponent; aTabID : cardinal; const aCaption : string); reintroduce; + procedure NotifyMoveOrResizeStarted; + procedure CreateBrowser(const aHomepage : string); + procedure CloseBrowser; + + property TabID : cardinal read FTabID; + end; + +implementation + +uses + uMainForm; + +constructor TBrowserTab.Create(AOwner: TComponent; aTabID : cardinal; const aCaption : string); +begin + inherited Create(AOwner); + + FTabID := aTabID; + Caption := aCaption; + FBrowserFrame := nil; +end; + +function TBrowserTab.GetParentForm : TCustomForm; +var + TempParent : TWinControl; +begin + TempParent := Parent; + + while (TempParent <> nil) and not(TempParent is TCustomForm) do + TempParent := TempParent.Parent; + + if (TempParent <> nil) and (TempParent is TCustomForm) then + Result := TCustomForm(TempParent) + else + Result := nil; +end; + +procedure TBrowserTab.SendFormMessage(aMsg : cardinal; aData : PtrInt); +var + TempForm : TCustomForm; +begin + TempForm := ParentForm; + if (TempForm <> nil) and (TempForm is TMainForm) then + TMainForm(TempForm).SendCompMessage(aMsg, aData); +end; + +procedure TBrowserTab.NotifyMoveOrResizeStarted; +begin + FBrowserFrame.NotifyMoveOrResizeStarted; +end; + +procedure TBrowserTab.CreateBrowser(const aHomepage : string); +begin + FBrowserFrame := TBrowserFrame.Create(self); + FBrowserFrame.Parent := self; + FBrowserFrame.Align := alClient; + FBrowserFrame.Visible := True; + FBrowserFrame.Homepage := aHomepage; + FBrowserFrame.OnBrowserDestroyed := @BrowserFrame_OnBrowserDestroyed; + FBrowserFrame.OnBrowserTitleChange := @BrowserFrame_OnBrowserTitleChange; + + FBrowserFrame.CreateBrowser; +end; + +procedure TBrowserTab.CloseBrowser; +begin + if (FBrowserFrame <> nil) then FBrowserFrame.CloseBrowser; +end; + +procedure TBrowserTab.BrowserFrame_OnBrowserDestroyed(Sender: TObject); +begin + // This event is executed in a CEF thread so we have to use + // Application.QueueAsyncCall to destroy the tab in the main application + // thread. + SendFormMessage(CEF_DESTROYTAB, PtrInt(TabID)); +end; + +procedure TBrowserTab.BrowserFrame_OnBrowserTitleChange(Sender: TObject; const aTitle : string); +begin + Caption := aTitle; +end; + +end. diff --git a/demos/Lazarus_Linux/TabbedBrowser2/uMainForm.lfm b/demos/Lazarus_Linux/TabbedBrowser2/uMainForm.lfm new file mode 100644 index 00000000..d7153422 --- /dev/null +++ b/demos/Lazarus_Linux/TabbedBrowser2/uMainForm.lfm @@ -0,0 +1,62 @@ +object MainForm: TMainForm + Left = 357 + Height = 704 + Top = 89 + Width = 991 + Caption = 'Initializing. Please, wait...' + ClientHeight = 704 + ClientWidth = 991 + Color = clBtnFace + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + OnActivate = FormActivate + OnCloseQuery = FormCloseQuery + OnCreate = FormCreate + Position = poScreenCenter + LCLVersion = '2.0.10.0' + object BrowserPageCtrl: TPageControl + Left = 34 + Height = 704 + Top = 0 + Width = 957 + Align = alClient + TabOrder = 0 + end + object ButtonPnl: TPanel + Left = 0 + Height = 704 + Top = 0 + Width = 34 + Align = alLeft + BevelOuter = bvNone + ClientHeight = 704 + ClientWidth = 34 + Enabled = False + TabOrder = 1 + object AddTabBtn: TSpeedButton + Left = 4 + Height = 26 + Top = 4 + Width = 26 + Caption = '+' + Font.Color = clWindowText + Font.Height = -24 + Font.Name = 'Arial Black' + OnClick = AddTabBtnClick + ParentFont = False + end + object RemoveTabBtn: TSpeedButton + Left = 4 + Height = 26 + Top = 33 + Width = 26 + Caption = '−' + Font.Color = clWindowText + Font.Height = -24 + Font.Name = 'Arial Black' + OnClick = RemoveTabBtnClick + ParentFont = False + end + end +end diff --git a/demos/Lazarus_Linux/TabbedBrowser2/uMainForm.pas b/demos/Lazarus_Linux/TabbedBrowser2/uMainForm.pas new file mode 100644 index 00000000..c39b3784 --- /dev/null +++ b/demos/Lazarus_Linux/TabbedBrowser2/uMainForm.pas @@ -0,0 +1,316 @@ +// ************************************************************************ +// ***************************** CEF4Delphi ******************************* +// ************************************************************************ +// +// CEF4Delphi is based on DCEF3 which uses CEF to embed a chromium-based +// browser in Delphi applications. +// +// The original license of DCEF3 still applies to CEF4Delphi. +// +// For more information about CEF4Delphi visit : +// https://www.briskbard.com/index.php?lang=en&pageid=cef +// +// Copyright © 2021 Salvador Diaz Fau. All rights reserved. +// +// ************************************************************************ +// ************ vvvv Original license and comments below vvvv ************* +// ************************************************************************ +(* + * Delphi Chromium Embedded 3 + * + * Usage allowed under the restrictions of the Lesser GNU General Public License + * or alternatively the restrictions of the Mozilla Public License 1.1 + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + * the specific language governing rights and limitations under the License. + * + * Unit owner : Henri Gourvest <hgourvest@gmail.com> + * 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 uMainForm; + +{$mode objfpc}{$H+} + +{$I cef.inc} + +interface + +uses + LCLIntf, LCLType, LMessages, Messages, SysUtils, Variants, Classes, Graphics, + Controls, Forms, Dialogs, ComCtrls, ToolWin, Buttons, ExtCtrls, + uCEFApplication, uCEFTypes, uCEFConstants; + +const + CEF_INITIALIZED = $100; + CEF_DESTROYTAB = $101; + + HOMEPAGE_URL = 'https://www.google.com'; + DEFAULT_TAB_CAPTION = 'New tab'; + +type + + { TMainForm } + + TMainForm = class(TForm) + BrowserPageCtrl: TPageControl; + ButtonPnl: TPanel; + AddTabBtn: TSpeedButton; + RemoveTabBtn: TSpeedButton; + + procedure AddTabBtnClick(Sender: TObject); + procedure RemoveTabBtnClick(Sender: TObject); + + procedure FormActivate(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); + + protected + // Variables to control when can we destroy the form safely + FCanClose : boolean; + FClosing : boolean; + FLastTabID : cardinal; // Used by NextTabID to generate unique tab IDs + + function GetNextTabID : cardinal; + + procedure EnableButtonPnl; + function CloseAllTabs : boolean; + procedure CloseTab(aIndex : integer); + procedure NotifyMoveOrResizeStarted; + procedure BrowserInitializedMsg(Data: PtrInt); + procedure BrowserDestroyedTabMsg(Data: PtrInt); + + procedure WMMove(var aMessage: TLMMove); message LM_MOVE; + procedure WMSize(var aMessage: TLMSize); message LM_SIZE; + procedure WMWindowPosChanged(var aMessage: TLMWindowPosChanged); message LM_WINDOWPOSCHANGED; + + property NextTabID : cardinal read GetNextTabID; + + public + procedure SendCompMessage(aMsg : cardinal; aData : PtrInt = 0); + end; + +var + MainForm: TMainForm = nil; + +procedure CreateGlobalCEFApp; + +implementation + +{$R *.lfm} + +uses + uBrowserTab; + +// This demo shows how to use a TPageControl with TFrames that include +// CEF4Delphi browsers. + +// Instead of a regular TTabSheet we use a custom TBrowserTab class that +// inherits from TTabSheet and instead of a regular TFrame we use a custom +// TBrowserFrame class that inherits from TFrame. + +// To create a new tab you need to call TBrowserTab.CreateBrowser in the last +// step to create all the browser components and initialize the browser. + +// To close a tab you have to call TBrowserTab.CloseBrowser and wait for a +// CEF_DESTROYTAB message with the TBrowserTab.TabID value. +// Then you find the tab with that unique TabID and free it. + +// Most of the TChromium events store the parameter values in a set of class +// fields which are protected by a critial section and then they call +// TBrowserFrame.SendCompMessage to execute the GUI code in the main thread. + +// TBrowserFrame has all the usual code to close CEF4Delphi browsers following +// a similar destruction sequence than the MiniBrowser demo : +// +// 1. TBrowserTab.CloseBrowser calls TChromium.CloseBrowser which triggers the +// TChromium.OnClose event. +// 2. TChromium.OnClose sets aAction to cbaClose which trigges the +// TChromium.OnBeforeClose event. +// 3. TChromium.OnBeforeClose executes the TBrowserFrame.OnBrowserDestroyed +// event which will be used in TBrowserTab to send a CEF_DESTROYTAB message +// to the main form to free the tab. + +// To close safely this demo you must close all the browser tabs first following +// this steps : +// +// 1. FormCloseQuery sets CanClose to FALSE and calls CloseAllTabs and FClosing +// is set to TRUE. +// 2. Each tab will send a CEF_DESTROYTAB message to free that tab. +// 3. When TPageControl has no tabs then we can set FCanClose to TRUE and +// close the main form. + +procedure GlobalCEFApp_OnContextInitialized; +begin + if (MainForm <> nil) and MainForm.Showing and MainForm.Focused then + MainForm.SendCompMessage(CEF_INITIALIZED); +end; + +procedure CreateGlobalCEFApp; +begin + GlobalCEFApp := TCefApplication.Create; + GlobalCEFApp.OnContextInitialized := @GlobalCEFApp_OnContextInitialized; +end; + +procedure TMainForm.EnableButtonPnl; +begin + if not(ButtonPnl.Enabled) then + begin + ButtonPnl.Enabled := True; + Caption := 'Tabbed Browser 2'; + cursor := crDefault; + if (BrowserPageCtrl.PageCount = 0) then AddTabBtn.Click; + end; +end; + +function TMainForm.GetNextTabID : cardinal; +begin + inc(FLastTabID); + Result := FLastTabID; +end; + +procedure TMainForm.AddTabBtnClick(Sender: TObject); +var + TempNewTab : TBrowserTab; +begin + TempNewTab := TBrowserTab.Create(self, NextTabID, DEFAULT_TAB_CAPTION); + TempNewTab.PageControl := BrowserPageCtrl; + + BrowserPageCtrl.ActivePageIndex := pred(BrowserPageCtrl.PageCount); + + TempNewTab.CreateBrowser(HOMEPAGE_URL); +end; + +procedure TMainForm.FormActivate(Sender: TObject); +begin + if (GlobalCEFApp <> nil) and GlobalCEFApp.GlobalContextInitialized then + EnableButtonPnl; +end; + +procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean); +begin + CanClose := FCanClose; + + if not(FClosing) then + begin + FClosing := True; + ButtonPnl.Enabled := False; + + if not(CloseAllTabs) then + begin + FCanClose := True; + CanClose := True; + end; + end; +end; + +procedure TMainForm.FormCreate(Sender: TObject); +begin + FCanClose := False; + FClosing := False; + FLastTabID := 0; +end; + +procedure TMainForm.RemoveTabBtnClick(Sender: TObject); +begin + CloseTab(BrowserPageCtrl.ActivePageIndex); +end; + +function TMainForm.CloseAllTabs : boolean; +var + i : integer; +begin + Result := False; + i := pred(BrowserPageCtrl.PageCount); + + while (i >= 0) do + begin + TBrowserTab(BrowserPageCtrl.Pages[i]).CloseBrowser; + Result := True; + dec(i); + end; +end; + +procedure TMainForm.CloseTab(aIndex : integer); +begin + if (aIndex >= 0) and (aIndex < BrowserPageCtrl.PageCount) then + TBrowserTab(BrowserPageCtrl.Pages[aIndex]).CloseBrowser; +end; + +procedure TMainForm.NotifyMoveOrResizeStarted; +var + i : integer; +begin + i := 0; + while (i < BrowserPageCtrl.PageCount) do + begin + TBrowserTab(BrowserPageCtrl.Pages[i]).NotifyMoveOrResizeStarted; + inc(i); + end; +end; + +procedure TMainForm.WMMove(var aMessage : TLMMove); +begin + inherited; + NotifyMoveOrResizeStarted; +end; + +procedure TMainForm.WMSize(var aMessage: TLMSize); +begin + inherited; + NotifyMoveOrResizeStarted; +end; + +procedure TMainForm.WMWindowPosChanged(var aMessage: TLMWindowPosChanged); +begin + inherited; + NotifyMoveOrResizeStarted; +end; + +procedure TMainForm.BrowserInitializedMsg(Data: PtrInt); +begin + EnableButtonPnl; +end; + +procedure TMainForm.BrowserDestroyedTabMsg(Data: PtrInt); +var + i : integer; + TempTab : TBrowserTab; +begin + i := 0; + while (i < BrowserPageCtrl.PageCount) do + begin + TempTab := TBrowserTab(BrowserPageCtrl.Pages[i]); + + if (TempTab.TabID = cardinal(Data)) then + begin + TempTab.Free; + break; + end + else + inc(i); + end; + + if FClosing and (BrowserPageCtrl.PageCount = 0) then + begin + FCanClose := True; + close; + end; +end; + +procedure TMainForm.SendCompMessage(aMsg : cardinal; aData : PtrInt); +begin + case aMsg of + CEF_INITIALIZED : Application.QueueAsyncCall(@BrowserInitializedMsg, aData); + CEF_DESTROYTAB : Application.QueueAsyncCall(@BrowserDestroyedTabMsg, aData); + end; +end; + +end. diff --git a/source/uCEFBitmapBitBuffer.pas b/source/uCEFBitmapBitBuffer.pas index 576427ba..d9cb7d23 100644 --- a/source/uCEFBitmapBitBuffer.pas +++ b/source/uCEFBitmapBitBuffer.pas @@ -58,10 +58,13 @@ uses type TCEFBitmapBitBuffer = class protected - FBuffer : pointer; - FWidth : integer; - FHeight : integer; + FBuffer : pointer; + FImageWidth : integer; + FImageHeight : integer; + FBufferWidth : integer; + FBufferHeight : integer; + function GetBufferScanlineSize : integer; function GetScanlineSize : integer; function GetBufferLength : integer; function GetEmpty : boolean; @@ -73,13 +76,15 @@ type public constructor Create(aWidth, aHeight : integer); destructor Destroy; override; + procedure UpdateSize(aWidth, aHeight : integer); - property Width : integer read FWidth; - property Height : integer read FHeight; + property Width : integer read FImageWidth; + property Height : integer read FImageHeight; property BufferLength : integer read GetBufferLength; property Empty : boolean read GetEmpty; property Scanline[y : integer] : PByte read GetScanline; - property ScanlineSize : integer read GetScanlineSize; + property ScanlineSize : integer read GetScanlineSize; + property BufferScanlineSize : integer read GetBufferScanlineSize; property BufferBits : pointer read FBuffer; end; @@ -87,24 +92,19 @@ implementation const RGBQUAD_SIZE = 4; + BUFFER_MULTIPLIER = 1.1; constructor TCEFBitmapBitBuffer.Create(aWidth, aHeight : integer); begin inherited Create; - if (aWidth > 0) and (aHeight > 0) then - begin - FWidth := aWidth; - FHeight := aHeight; + FBuffer := nil; + FImageWidth := 0; + FImageHeight := 0; + FBufferWidth := 0; + FBufferHeight := 0; - CreateBuffer; - end - else - begin - FWidth := 0; - FHeight := 0; - FBuffer := nil; - end; + UpdateSize(aWidth, aHeight); end; destructor TCEFBitmapBitBuffer.Destroy; @@ -125,12 +125,17 @@ end; function TCEFBitmapBitBuffer.GetScanlineSize : integer; begin - Result := FWidth * RGBQUAD_SIZE; + Result := FImageWidth * RGBQUAD_SIZE; +end; + +function TCEFBitmapBitBuffer.GetBufferScanlineSize : integer; +begin + Result := FBufferWidth * RGBQUAD_SIZE; end; function TCEFBitmapBitBuffer.GetBufferLength : integer; begin - Result := FHeight * ScanlineSize; + Result := FBufferHeight * BufferScanlineSize; end; function TCEFBitmapBitBuffer.GetEmpty : boolean; @@ -140,12 +145,12 @@ end; function TCEFBitmapBitBuffer.GetScanline(y : integer) : PByte; begin - if (FBuffer = nil) or (y >= FHeight) then + if (FBuffer = nil) or (y >= FImageHeight) then Result := nil else begin Result := PByte(FBuffer); - if (y > 0) then inc(Result, y * ScanlineSize); + if (y > 0) then inc(Result, y * BufferScanlineSize); end; end; @@ -162,4 +167,32 @@ begin end; end; +procedure TCEFBitmapBitBuffer.UpdateSize(aWidth, aHeight : integer); +begin + if (aWidth > 0) and (aHeight > 0) then + begin + FImageWidth := aWidth; + FImageHeight := aHeight; + + if (FImageWidth > FBufferWidth) or + (FImageHeight > FBufferHeight) then + begin + FBufferWidth := round(FImageWidth * BUFFER_MULTIPLIER); + FBufferHeight := round(FImageHeight * BUFFER_MULTIPLIER); + + DestroyBuffer; + CreateBuffer; + end; + end + else + begin + FImageWidth := 0; + FImageHeight := 0; + FBufferWidth := 0; + FBufferHeight := 0; + + DestroyBuffer; + end; +end; + end. diff --git a/source/uCEFBufferPanel.pas b/source/uCEFBufferPanel.pas index 9fed8b4d..ee7ccb8b 100644 --- a/source/uCEFBufferPanel.pas +++ b/source/uCEFBufferPanel.pas @@ -983,16 +983,12 @@ function TBufferPanel.UpdateBufferDimensions(aWidth, aHeight : integer) : boolea begin Result := False; - if ((FBuffer = nil) or - (FBuffer.Width <> aWidth) or - (FBuffer.Height <> aHeight)) then + if (FBuffer = nil) then begin - if (FBuffer <> nil) then FreeAndNil(FBuffer); - {$IFDEF MSWINDOWS} FBuffer := TBitmap.Create; FBuffer.PixelFormat := pf32bit; - FBuffer.HandleType := bmDIB; + FBuffer.HandleType := bmDIB; FBuffer.Width := aWidth; FBuffer.Height := aHeight; FScanlineSize := aWidth * SizeOf(TRGBQuad); @@ -1002,7 +998,22 @@ begin {$ENDIF} Result := True; - end; + end + else + if (FBuffer.Width <> aWidth) or + (FBuffer.Height <> aHeight) then + begin + {$IFDEF MSWINDOWS} + FBuffer.Width := aWidth; + FBuffer.Height := aHeight; + FScanlineSize := aWidth * SizeOf(TRGBQuad); + {$ELSE} + FBuffer.UpdateSize(aWidth, aHeight); + FScanlineSize := FBuffer.ScanlineSize; + {$ENDIF} + + Result := True; + end; end; {$IFNDEF MSWINDOWS} @@ -1010,16 +1021,20 @@ function TBufferPanel.UpdatePopupBufferDimensions(aWidth, aHeight : integer) : b begin Result := False; - if ((FPopupBuffer = nil) or - (FPopupBuffer.Width <> aWidth) or - (FPopupBuffer.Height <> aHeight)) then + if (FPopupBuffer = nil) then begin - if (FPopupBuffer <> nil) then FreeAndNil(FPopupBuffer); - FPopupBuffer := TCEFBitmapBitBuffer.Create(aWidth, aHeight); FPopupScanlineSize := FPopupBuffer.ScanlineSize; Result := True; - end; + end + else + if (FPopupBuffer.Width <> aWidth) or + (FPopupBuffer.Height <> aHeight) then + begin + FPopupBuffer.UpdateSize(aWidth, aHeight); + FPopupScanlineSize := FPopupBuffer.ScanlineSize; + Result := True; + end; end; {$ENDIF} diff --git a/update_CEF4Delphi.json b/update_CEF4Delphi.json index 4a6ea165..c511fdec 100644 --- a/update_CEF4Delphi.json +++ b/update_CEF4Delphi.json @@ -2,7 +2,7 @@ "UpdateLazPackages" : [ { "ForceNotify" : true, - "InternalVersion" : 220, + "InternalVersion" : 221, "Name" : "cef4delphi_lazarus.lpk", "Version" : "87.1.12.0" }