Merge pull request #350 from User4martin/fpc-work-3a

Fpc work 3a
This commit is contained in:
Salvador Díaz Fau 2021-03-14 10:58:03 +01:00 committed by GitHub
commit f759f2e405
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
58 changed files with 6942 additions and 101 deletions

View File

@ -28,13 +28,13 @@ Note:
** Mac
1) Go to "project options" and create the "App Bundle"
2) Download the CEF framework and place the content of the "Release" folder into ExternalPumpBrowser.app/Contents/Frameworks/Chromium Embedded Framework.framework
2) Download the CEF framework and place the content of the "Release" folder into BrowserWindow.app/Contents/Frameworks/Chromium Embedded Framework.framework
You should have:
Chromium Embedded Framework
Libraries/*
Resources/*
3) Open project "AppHelper", create App Bundle and compile the AppHelper.
Run create_mac_helper.sh
4) Open project ExternalPumpBrowser, compile and run
4) Open project BrowserWindow, compile and run

View File

@ -51,7 +51,7 @@ unit GlobalCefApplication;
interface
uses
uCEFApplication, uCEFWorkScheduler, FileUtil;
uCEFApplication, uCEFWorkScheduler, uCEFLazApplication, FileUtil;
procedure CreateGlobalCEFApp;
@ -75,7 +75,8 @@ begin
GlobalCEFWorkScheduler := TCEFWorkScheduler.Create(nil);
{$ENDIF}
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp := TCefLazApplication.Create;
GlobalCEFApp.CheckCEFFiles := False;
{$IFDEF USE_MULTI_THREAD_LOOP}
// On Windows/Linux CEF can use threads for the message-loop
GlobalCEFApp.MultiThreadedMessageLoop := True;

View File

@ -0,0 +1,2 @@
rmdir /S /Q lib
rmdir /S /Q backup

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
<CompatibilityMode Value="True"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="AppHelper"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
<XPManifest>
<DpiAware Value="True"/>
</XPManifest>
<Icon Value="0"/>
</General>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<DestinationDirectory Value="B:\laz_other\CEF4Delphi\demos\Lazarus Mac\SubProcess"/>
<CompressFinally Value="False"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages Count="2">
<Item1>
<PackageName Value="CEF4Delphi_Lazarus"/>
</Item1>
<Item2>
<PackageName Value="LCL"/>
</Item2>
</RequiredPackages>
<Units Count="2">
<Unit0>
<Filename Value="AppHelper.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="..\uHelperProcessDom.pas"/>
<IsPartOfProject Value="True"/>
</Unit1>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="..\..\..\..\bin\AppHelper"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<OtherUnitFiles Value=".."/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<IncludeAssertionCode Value="True"/>
</SyntaxOptions>
</Parsing>
<CodeGeneration>
<Checks>
<IOChecks Value="True"/>
<RangeChecks Value="True"/>
<OverflowChecks Value="True"/>
<StackChecks Value="True"/>
</Checks>
</CodeGeneration>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf3"/>
</Debugging>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
</CompilerOptions>
</CONFIG>

View File

@ -0,0 +1,73 @@
// ************************************************************************
// ***************************** 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.
*
*)
program AppHelper;
(*
* The compiled exe should be copied into
* SimpleBrowser.app/Content/Frameworks/SimpleBrowser2 Helper.app/Content/MacOS/SimpleBrowser2 Helper
* including app bundle in SimpleBrowser2.app/Content/Frameworks/SimpleBrowser2 Helper.app
*)
{$mode objfpc}{$H+}
{$I cef.inc}
uses
{$IFDEF UNIX}
cthreads,
{$ENDIF}
Interfaces, // this includes the LCL widgetset
uHelperProcessDom,
uCEFApplication, uCEFTypes, uCEFConstants, LazFileUtils, sysutils;
begin
GlobalCEFApp := TCefApplication.Create;
InitProcessMessagesHandler;
// The main process and the subprocess *MUST* have the same GlobalCEFApp
// properties and events, specially FrameworkDirPath, ResourcesDirPath,
// LocalesDirPath, cache and UserDataPath paths.
{$IFDEF MACOSX}
GlobalCEFApp.InitLibLocationFromArgs;
{$ENDIF}
GlobalCEFApp.StartSubProcess;
GlobalCEFApp.Free;
GlobalCEFApp := nil;
end.

View File

@ -0,0 +1,468 @@
// ************************************************************************
// ***************************** 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}
// Delphi uses MACOS for the new MacOSX and DARWIN is not defined
// FPC uses DARWIN for the new MacOSX and MACOS is defined for the classic Macintosh OS (System 7)
// We define MACOSX to avoid conflicts in both situations
{$IFDEF FPC}
{$IFDEF DARWIN}
{$DEFINE MACOSX}
{$ENDIF}
{$ELSE}
{$IFDEF MACOS}
{$DEFINE MACOSX}
{$ENDIF}
{$ENDIF}

View File

@ -0,0 +1,57 @@
#!/bin/sh
BASEDIR=$(dirname "$0")
DEST=$1
SRC=$2
if [ "$SRC" = "" ];
then
SRC=$BASEDIR/../../../../bin/AppHelper.app
fi
if [ "$1" = "" ] || [ ! -e "$DEST" ] || [ ! -e "$SRC" ];
then
echo "Usage"
echo " $0 destpath/project.app"
echo " $0 destpath/project.app sourcedir/AppHelper.app"
echo
if [ ! -e "$DEST" ];
then
echo "Error: Target app bundle not found. (Did you compile AND create the bundle?)"
fi
if [ ! -e "$SRC" ];
then
echo "Error: Source (AppHelper) app bundle not found. (Did you compile AND create the bundle?)"
fi
exit;
fi
SRCAPP=$(basename "$SRC")
SRCAPP="${SRCAPP%\.app}"
DESTAPP=$(basename "$DEST")
DESTAPP="${DESTAPP%\.app}"
SUB=""
rm -rf "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app"
cp -r "$SRC" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app"
mv "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/MacOS/$SRCAPP" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/MacOS/$DESTAPP Helper$SUB"
sed -i '' "s/$SRCAPP/$DESTAPP Helper$SUB/g" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/Info.plist"
SUB=" (GPU)"
rm -rf "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app"
cp -r "$SRC" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app"
mv "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/MacOS/$SRCAPP" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/MacOS/$DESTAPP Helper$SUB"
sed -i '' "s/$SRCAPP/$DESTAPP Helper$SUB/g" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/Info.plist"
SUB=" (Renderer)"
rm -rf "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app"
cp -r "$SRC" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app"
mv "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/MacOS/$SRCAPP" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/MacOS/$DESTAPP Helper$SUB"
sed -i '' "s/$SRCAPP/$DESTAPP Helper$SUB/g" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/Info.plist"
SUB=" (Plugin)"
rm -rf "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app"
cp -r "$SRC" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app"
mv "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/MacOS/$SRCAPP" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/MacOS/$DESTAPP Helper$SUB"
sed -i '' "s/$SRCAPP/$DESTAPP Helper$SUB/g" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/Info.plist"

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

View File

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<General>
<Flags>
<CompatibilityMode Value="True"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="BrowserWindowDom"/>
<Scaled Value="True"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
<XPManifest>
<DpiAware Value="True"/>
</XPManifest>
<Icon Value="0"/>
</General>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<DestinationDirectory Value="B:/laz_other/CEF4Delphi/demos/Lazarus_any_OS/BrowserWindowDom"/>
<CompressFinally Value="False"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages Count="3">
<Item1>
<PackageName Value="LazDebuggerGdbmi"/>
</Item1>
<Item2>
<PackageName Value="CEF4Delphi_Lazarus"/>
</Item2>
<Item3>
<PackageName Value="LCL"/>
</Item3>
</RequiredPackages>
<Units Count="5">
<Unit0>
<Filename Value="BrowserWindowDom.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="uBrowserWindowDom.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="Form1"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
</Unit1>
<Unit2>
<Filename Value="initsubprocess.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="InitSubProcess"/>
</Unit2>
<Unit3>
<Filename Value="globalcefapplication.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="GlobalCefApplication"/>
</Unit3>
<Unit4>
<Filename Value="uHelperProcessDom.pas"/>
<IsPartOfProject Value="True"/>
</Unit4>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<Target>
<Filename Value="../../../bin/BrowserWindowDom"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf3"/>
</Debugging>
</Linking>
<Other>
<CustomOptions Value="-dUseCthreads"/>
</Other>
</CompilerOptions>
</CONFIG>

View File

@ -0,0 +1,84 @@
// ************************************************************************
// ***************************** 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.
*
*)
(*
* Include the following files
* BrowserWindow.app/Contents/Frameworks/ExternalPumpBrowser Helper.app/
* files from the demos/Lazarus_Mac/AppHelper project
* use create_mac_helper.sh
*
* BrowserWindow.app/Contents/Frameworks/Chromium Embedded Framework.framework
* files from Release folder in cef download
*
*)
program BrowserWindowDom;
{$mode objfpc}{$H+}
{$I cef.inc}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
{$IFDEF LINUX}
InitSubProcess, // On Linux this unit must be used *before* the "interfaces" unit.
{$ENDIF}
Interfaces,
Forms,
uBrowserWindowDom, GlobalCefApplication,
uHelperProcessDom // Used here, for any OS where the main exe server as AppHelper too.
{ you can add units after this }
;
{$R *.res}
{$IFDEF WIN32}
// CEF needs to set the LARGEADDRESSAWARE ($20) flag which allows 32-bit processes to use up to 3GB of RAM.
{$SetPEFlags $20}
{$ENDIF}
begin
RequireDerivedFormResource:=True;
Application.Scaled := True;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

View File

@ -0,0 +1,40 @@
BrowserWindow
# ABOUT
This example uses
TLazarusBrowserWindow
Examining DOM
TCEFWorkScheduler feeds the CEF messageloop by calling DoMessageLoopWork(). On Mac this is currently the only way to run the CEF messageloop.
# SETUP
** Windows
1) Download the CEF framework and place the content of the "Release" folder into the same folder as your exe.
Alternatively you can point "GlobalCEFApp.FrameworkDirPath" to the location with the libraries.
2) Run the project
** Linux
1) Download the CEF framework and place the content of the "Release" folder into the same folder as your exe.
Alternatively you can point "GlobalCEFApp.FrameworkDirPath" to the location with the libraries.
2) Run the project
Note:
- For your own Linux project you must modify the project source (lpr) and add "InitSubProcess" to the "uses" clause, so that it is in the list *before* the unit "Interfaces".
- The call to "DestroyGlobalCEFApp" must be in a unit *not* used by "unit InitSubProcess" (including not used in any nested way).
** Mac
1) Go to "project options" and create the "App Bundle"
2) Download the CEF framework and place the content of the "Release" folder into BrowserWindowDom.app/Contents/Frameworks/Chromium Embedded Framework.framework
You should have:
Chromium Embedded Framework
Libraries/*
Resources/*
3) Open project "AppHelper" (from the subfolder in this project's folder), create App Bundle and compile the AppHelper.
Run create_mac_helper.sh
4) Open project BrowserWindowDom, compile and run

View File

@ -0,0 +1,468 @@
// ************************************************************************
// ***************************** 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}
// Delphi uses MACOS for the new MacOSX and DARWIN is not defined
// FPC uses DARWIN for the new MacOSX and MACOS is defined for the classic Macintosh OS (System 7)
// We define MACOSX to avoid conflicts in both situations
{$IFDEF FPC}
{$IFDEF DARWIN}
{$DEFINE MACOSX}
{$ENDIF}
{$ELSE}
{$IFDEF MACOS}
{$DEFINE MACOSX}
{$ENDIF}
{$ENDIF}

View File

@ -0,0 +1,13 @@
#!/bin/sh
CDIR=$(pwd)
cd "$(dirname "$0")"
./AppHelper/create_mac_helper_apps.sh ../../../bin/BrowserWindowDom.app
if [ "$(grep -i TCrCocoaApplication ../../../bin/BrowserWindowDom.app/Contents/Info.plist)" = "" ];
then
sed -i '' "1,4s/<dict>/<dict>\n <key>NSPrincipalClass<\/key>\n <string>TCrCocoaApplication<\/string>/" ../../../bin/BrowserWindowDom.app/Contents/Info.plist
fi
cd "$CDIR"

View File

@ -0,0 +1,118 @@
// ************************************************************************
// ***************************** 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 GlobalCefApplication;
{$mode ObjFPC}{$H+}
{$I cef.inc}
{.$DEFINE USE_MULTI_THREAD_LOOP} // Only Windows/Linux
{.$DEFINE USE_APP_HELPER} // Optional on Windows/Linux
{$IFDEF MACOSX}
{$UNDEF USE_MULTI_THREAD_LOOP} // Will fail on Mac
{$DEFINE USE_APP_HELPER} // Required on Mac
{$ENDIF}
interface
uses
uCEFApplication, uCEFWorkScheduler, uCEFLazApplication, FileUtil,
uHelperProcessDom;
procedure CreateGlobalCEFApp;
implementation
procedure GlobalCEFApp_OnScheduleMessagePumpWork(const aDelayMS : int64);
begin
if (GlobalCEFWorkScheduler <> nil) then GlobalCEFWorkScheduler.ScheduleMessagePumpWork(aDelayMS);
end;
procedure CreateGlobalCEFApp;
begin
if GlobalCEFApp <> nil then
exit;
{$IFnDEF USE_MULTI_THREAD_LOOP}
// 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 := TCEFWorkScheduler.Create(nil);
{$ENDIF}
GlobalCEFApp := TCefLazApplication.Create;
GlobalCEFApp.CheckCEFFiles := False;
{$IFDEF USE_MULTI_THREAD_LOOP}
// On Windows/Linux CEF can use threads for the message-loop
GlobalCEFApp.MultiThreadedMessageLoop := True;
{$ELSE}
// use External Pump for message-loop
GlobalCEFApp.ExternalMessagePump := True;
GlobalCEFApp.MultiThreadedMessageLoop := False;
GlobalCEFApp.OnScheduleMessagePumpWork := @GlobalCEFApp_OnScheduleMessagePumpWork;
{$ENDIF}
{$IFnDEF MACOSX}
{$IFDEF USE_APP_HELPER}
(* Use AppHelper as subprocess, instead of the main exe *)
GlobalCEFApp.BrowserSubprocessPath := 'AppHelper' + GetExeExt;
{$ENDIF}
{$ENDIF}
{$IFDEF MACOSX}
(* Enable the below to prevent being asked for permission to access "Chromium Safe Storage"
If set to true, Cookies will not be encrypted.
*)
GlobalCEFApp.UseMockKeyChain := True;
{$ENDIF}
{$IFDEF LINUX}
// This is a workaround for the 'GPU is not usable error' issue :
// https://bitbucket.org/chromiumembedded/cef/issues/2964/gpu-is-not-usable-error-during-cef
GlobalCEFApp.DisableZygote := True; // this property adds the "--no-zygote" command line switch
{$ENDIF}
{
GlobalCEFApp.LogFile := 'cef.log';
GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
}
InitProcessMessagesHandler; // This is for the AppHelper process.
end;
end.

View File

@ -0,0 +1,61 @@
// ************************************************************************
// ***************************** 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 InitSubProcess;
{$mode ObjFPC}{$H+}
{$I cef.inc}
interface
uses
GlobalCefApplication, uCEFApplication, uCEFWorkScheduler;
implementation
initialization
CreateGlobalCEFApp;
if not GlobalCEFApp.StartMainProcess then begin
if GlobalCEFWorkScheduler <> nil then
GlobalCEFWorkScheduler.StopScheduler;
DestroyGlobalCEFApp;
DestroyGlobalCEFWorkScheduler;
halt(0); // exit the subprocess
end;
end.

View File

@ -0,0 +1,73 @@
object Form1: TForm1
Left = 473
Height = 589
Top = 227
Width = 967
Caption = 'Initializing browser. Please wait...'
ClientHeight = 589
ClientWidth = 967
OnCloseQuery = FormCloseQuery
OnCreate = FormCreate
Position = poScreenCenter
LCLVersion = '2.1.0.0'
object AddressPnl: TPanel
Left = 0
Height = 23
Top = 0
Width = 967
Align = alTop
BevelOuter = bvNone
ClientHeight = 23
ClientWidth = 967
TabOrder = 0
object GoBtn: TButton
Left = 932
Height = 23
Top = 0
Width = 35
Align = alRight
Caption = 'Go'
OnClick = GoBtnClick
TabOrder = 0
end
object AddressEdt: TComboBox
Left = 0
Height = 23
Top = 0
Width = 932
Align = alClient
ItemHeight = 15
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/html/html5_video.asp'
'http://www.adobe.com/software/flash/about/'
'http://isflashinstalled.com/'
'chrome://version/'
'http://html5test.com/'
'https://www.w3schools.com/'
'http://webglsamples.org/'
'https://get.webgl.org/'
'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'
'https://www.browserleaks.com/webrtc'
'https://frames-per-second.appspot.com/'
)
TabOrder = 1
Text = 'https://www.google.com'
end
end
object LazarusBrowserWindow1: TLazarusBrowserWindow
Left = 0
Height = 566
Top = 23
Width = 967
Align = alClient
TabOrder = 1
OnBrowserClosed = LazarusBrowserWindow1BrowserClosed
end
end

View File

@ -0,0 +1,258 @@
// ************************************************************************
// ***************************** 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 uBrowserWindowDom;
{$mode objfpc}{$H+}
{$I cef.inc}
interface
uses
GlobalCefApplication,
uCEFLazarusCocoa, // required for Cocoa
SysUtils, Messages, Forms, Controls,
Dialogs, ExtCtrls, StdCtrls, LMessages, Menus,
uCEFTypes, uCEFInterfaces, uHelperProcessDom,
uCEFWorkScheduler, uCEFLazarusBrowserWindow, uCEFProcessMessage, Classes;
type
{ TForm1 }
TForm1 = class(TForm)
AddressEdt: TComboBox;
GoBtn: TButton;
AddressPnl: TPanel;
LazarusBrowserWindow1: TLazarusBrowserWindow;
mDomHere: TMenuItem;
procedure Chromium1BeforePopup(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl, targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; const popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo; var client: ICefClient; var settings: TCefBrowserSettings; var extra_info: ICefDictionaryValue; var noJavascriptAccess: Boolean; var Result: Boolean);
procedure Chromium1OpenUrlFromTab(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; out Result: Boolean);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormCreate(Sender: TObject);
procedure GoBtnClick(Sender: TObject);
procedure LazarusBrowserWindow1BrowserClosed(Sender: TObject);
private
FContextXY: TPoint;
procedure DoBeforeContextMenu(Sender: TObject; const browser: ICefBrowser;
const frame: ICefFrame; const params: ICefContextMenuParams;
const model: ICefMenuModel);
procedure DoCaptureMenuXY;
procedure DoContextMenuCmd(Sender: TObject; const browser: ICefBrowser;
const frame: ICefFrame; const params: ICefContextMenuParams;
commandId: Integer; eventFlags: TCefEventFlags; out Result: Boolean);
procedure DoProcessMessageReceived(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame;
sourceProcess: TCefProcessId; const message: ICefProcessMessage; out
Result: Boolean);
protected
{$IFDEF WINDOWS}
procedure WMEnterMenuLoop(var aMessage: TMessage); message WM_ENTERMENULOOP;
procedure WMExitMenuLoop(var aMessage: TMessage); message WM_EXITMENULOOP;
{$ENDIF}
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
// This is a demo with the simplest web browser you can build using CEF4Delphi and
// it doesn't show any sign of progress like other web browsers do.
// Remember that it may take a few seconds to load if Windows update, your antivirus or
// any other windows service is using your hard drive.
// Depending on your internet connection it may take longer than expected.
// Please check that your firewall or antivirus are not blocking this application
// or the domain "google.com". If you don't live in the US, you'll be redirected to
// another domain which will take a little time too.
// This demo uses a TChromium and a TCEFLinkedWindowParent
// We need to use TCEFLinkedWindowParent in Linux to update the browser
// visibility and size automatically.
// Destruction steps
// =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sets aAction to cbaClose to destroy the browser, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends CEF_BEFORECLOSE to close the form.
uses
uCEFApplication;
{ TForm1 }
procedure TForm1.GoBtnClick(Sender: TObject);
begin
LazarusBrowserWindow1.LoadURL(UTF8Decode(AddressEdt.Text));
end;
procedure TForm1.LazarusBrowserWindow1BrowserClosed(Sender: TObject);
begin
Close;
end;
procedure TForm1.DoBeforeContextMenu(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame;
const params: ICefContextMenuParams; const model: ICefMenuModel);
begin
model.Clear;
model.AddItem(1, 'Get DOM');
TThread.Synchronize(nil, @DoCaptureMenuXY);
end;
procedure TForm1.DoCaptureMenuXY;
begin
FContextXY := LazarusBrowserWindow1.ScreenToClient(Mouse.CursorPos);
end;
procedure TForm1.DoContextMenuCmd(Sender: TObject; const browser: ICefBrowser;
const frame: ICefFrame; const params: ICefContextMenuParams;
commandId: Integer; eventFlags: TCefEventFlags; out Result: Boolean);
var
TempMsg : ICefProcessMessage;
begin
if commandId = 1 then
begin
TempMsg := TCefProcessMessageRef.New(MSG_REQUEST_DOM); // Same name than TCefCustomRenderProcessHandler.MessageName
TempMsg.ArgumentList.SetInt(0, FContextXY.X);
TempMsg.ArgumentList.SetInt(1, FContextXY.Y);
LazarusBrowserWindow1.Chromium.SendProcessMessage(PID_RENDERER, TempMsg);
end;
end;
procedure TForm1.DoProcessMessageReceived(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame;
sourceProcess: TCefProcessId; const message: ICefProcessMessage; out
Result: Boolean);
begin
Result := False;
case message.Name of
MSG_RESPONSE_DOM: begin
Caption := message.ArgumentList.GetString(0);
Result := True;
end;
end;
end;
{$IFDEF WINDOWS}
procedure TForm1.WMEnterMenuLoop(var aMessage: TMessage);
begin
inherited;
if (aMessage.wParam = 0) and (GlobalCEFApp <> nil) then GlobalCEFApp.OsmodalLoop := True;
end;
procedure TForm1.WMExitMenuLoop(var aMessage: TMessage);
begin
inherited;
if (aMessage.wParam = 0) and (GlobalCEFApp <> nil) then GlobalCEFApp.OsmodalLoop := False;
end;
{$ENDIF}
procedure TForm1.Chromium1BeforePopup(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame; const targetUrl,
targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition;
userGesture: Boolean; const popupFeatures: TCefPopupFeatures;
var windowInfo: TCefWindowInfo; var client: ICefClient;
var settings: TCefBrowserSettings; var extra_info: ICefDictionaryValue;
var noJavascriptAccess: Boolean; var Result: Boolean);
begin
// For simplicity, this demo blocks all popup windows and new tabs
Result := (targetDisposition in [WOD_NEW_FOREGROUND_TAB, WOD_NEW_BACKGROUND_TAB, WOD_NEW_POPUP, WOD_NEW_WINDOW]);
end;
procedure TForm1.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 TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
LazarusBrowserWindow1.CloseBrowser(True);
CanClose := LazarusBrowserWindow1.IsClosed;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
LazarusBrowserWindow1.Chromium.OnBeforeContextMenu := @DoBeforeContextMenu;
LazarusBrowserWindow1.Chromium.OnContextMenuCommand := @DoContextMenuCmd;
LazarusBrowserWindow1.Chromium.OnProcessMessageReceived := @DoProcessMessageReceived;
LazarusBrowserWindow1.LoadURL(UTF8Decode(AddressEdt.Text));
end;
initialization
{$IFDEF DARWIN} // $IFDEF MACOSX
AddCrDelegate;
{$ENDIF}
if GlobalCEFApp = nil then begin
CreateGlobalCEFApp;
if not GlobalCEFApp.StartMainProcess then begin
DestroyGlobalCEFApp;
DestroyGlobalCEFWorkScheduler;
halt(0); // exit the subprocess
end;
end;
finalization
(* Destroy from this unit, which is used after "Interfaces". So this happens before the Application object is destroyed *)
if GlobalCEFWorkScheduler <> nil then
GlobalCEFWorkScheduler.StopScheduler;
DestroyGlobalCEFApp;
DestroyGlobalCEFWorkScheduler;
end.

View File

@ -0,0 +1,161 @@
// ************************************************************************
// ***************************** 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 uHelperProcessDom;
(* The code in this unit is executed in the renderer sub-process
*)
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils, uCEFApplication, uCEFInterfaces, uCEFDomVisitor, uCEFTypes,
uCEFProcessMessage;
const
MSG_REQUEST_DOM = 'MSG_REQUEST_DOM';
MSG_RESPONSE_DOM = 'MSG_RESPONSE_DOM';
procedure InitProcessMessagesHandler;
implementation
type
{ TDomVisitorFindXY }
TDomVisitorFindXY = class(TCefDomVisitorOwn)
protected
FFrame : ICefFrame;
FX, FY: Integer;
procedure visit(const document: ICefDomDocument); override;
public
constructor Create(AFrame: ICefFrame; X,Y: Integer); reintroduce; virtual;
end;
{ TDomVisitorFindXY }
procedure TDomVisitorFindXY.visit(const document: ICefDomDocument);
var
node, foundNode: ICefDomNode;
nb: TCefRect;
TempMsg : ICefProcessMessage;
begin
node := document.GetBody;
foundNode := nil;
if node <> nil then
begin
nb := node.GetElementBounds;
if (FX >= nb.x) and (FX < nb.x + nb.width) and
(FY >= nb.y) and (FY < nb.y + nb.height)
then
begin
while node <> nil do
begin
foundNode := node;
if node.HasChildren then
begin
node := node.FirstChild;
while node <> nil do
begin
nb := node.GetElementBounds;
if (FX >= nb.x) and (FX < nb.x + nb.width) and
(FY >= nb.y) and (FY < nb.y + nb.height)
then
break // go outer loop
else
node := node.NextSibling;
end;
end
else
node := nil;
end;
end;
end;
TempMsg := TCefProcessMessageRef.New(MSG_RESPONSE_DOM); // Same name than TCefCustomRenderProcessHandler.MessageName
if foundNode <> nil then
TempMsg.ArgumentList.SetString(0, foundNode.AsMarkup)
else
TempMsg.ArgumentList.SetString(0, 'Not Found');
if (FFrame <> nil) and FFrame.IsValid then
FFrame.SendProcessMessage(PID_BROWSER, TempMsg);
end;
constructor TDomVisitorFindXY.Create(AFrame: ICefFrame; X, Y: Integer);
begin
FFrame := AFrame;
FX := X;
FY := Y;
inherited Create;
end;
procedure DoProcessMessageReceived(const browser: ICefBrowser;
const frame: ICefFrame; sourceProcess: TCefProcessId;
const message: ICefProcessMessage; var aHandled: boolean);
var
TempVisitor : TDomVisitorFindXY;
begin
aHandled := False;
case message.Name of
MSG_REQUEST_DOM: begin
if (frame <> nil) and frame.IsValid then
begin
TempVisitor := TDomVisitorFindXY.Create(
frame,
message.ArgumentList.GetInt(0),
message.ArgumentList.GetInt(1)
);
frame.VisitDom(TempVisitor);
end;
aHandled := True;
end;
end;
end;
procedure InitProcessMessagesHandler;
begin
GlobalCEFApp.OnProcessMessageReceived := @DoProcessMessageReceived;
end;
end.

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

View File

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<General>
<Flags>
<CompatibilityMode Value="True"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="BrowserWindowEx"/>
<Scaled Value="True"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
<XPManifest>
<DpiAware Value="True"/>
</XPManifest>
<Icon Value="0"/>
</General>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<DestinationDirectory Value="B:/laz_other/CEF4Delphi/demos/Lazarus_any_OS/BrowserWindowEx"/>
<CompressFinally Value="False"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages Count="2">
<Item1>
<PackageName Value="CEF4Delphi_Lazarus"/>
</Item1>
<Item2>
<PackageName Value="LCL"/>
</Item2>
</RequiredPackages>
<Units Count="4">
<Unit0>
<Filename Value="BrowserWindowEx.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="uBrowserWindowEx.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="Form1"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
</Unit1>
<Unit2>
<Filename Value="initsubprocess.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="InitSubProcess"/>
</Unit2>
<Unit3>
<Filename Value="globalcefapplication.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="GlobalCefApplication"/>
</Unit3>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<Target>
<Filename Value="../../../bin/BrowserWindowEx"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf3"/>
</Debugging>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
<Other>
<CustomOptions Value="-dUseCthreads"/>
</Other>
</CompilerOptions>
</CONFIG>

View File

@ -0,0 +1,83 @@
// ************************************************************************
// ***************************** 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.
*
*)
(*
* Include the following files
* BrowserWindowEx.app/Contents/Frameworks/ExternalPumpBrowser Helper.app/
* files from the demos/Lazarus_Mac/AppHelper project
* use create_mac_helper.sh
*
* BrowserWindowEx.app/Contents/Frameworks/Chromium Embedded Framework.framework
* files from Release folder in cef download
*
*)
program BrowserWindowEx;
{$mode objfpc}{$H+}
{$I cef.inc}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
{$IFDEF LINUX}
InitSubProcess, // On Linux this unit must be used *before* the "interfaces" unit.
{$ENDIF}
Interfaces,
Forms,
uBrowserWindowEx, GlobalCefApplication
{ you can add units after this }
;
{$R *.res}
{$IFDEF WIN32}
// CEF needs to set the LARGEADDRESSAWARE ($20) flag which allows 32-bit processes to use up to 3GB of RAM.
{$SetPEFlags $20}
{$ENDIF}
begin
RequireDerivedFormResource:=True;
Application.Scaled := True;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

View File

@ -0,0 +1,40 @@
BrowserWindow
# ABOUT
This example uses
TLazarusBrowserWindow
TCEFWorkScheduler
TCEFWorkScheduler feeds the CEF messageloop by calling DoMessageLoopWork(). On Mac this is currently the only way to run the CEF messageloop.
# SETUP
** Windows
1) Download the CEF framework and place the content of the "Release" folder into the same folder as your exe.
Alternatively you can point "GlobalCEFApp.FrameworkDirPath" to the location with the libraries.
2) Run the project
** Linux
1) Download the CEF framework and place the content of the "Release" folder into the same folder as your exe.
Alternatively you can point "GlobalCEFApp.FrameworkDirPath" to the location with the libraries.
2) Run the project
Note:
- For your own Linux project you must modify the project source (lpr) and add "InitSubProcess" to the "uses" clause, so that it is in the list *before* the unit "Interfaces".
- The call to "DestroyGlobalCEFApp" must be in a unit *not* used by "unit InitSubProcess" (including not used in any nested way).
** Mac
1) Go to "project options" and create the "App Bundle"
2) Download the CEF framework and place the content of the "Release" folder into BrowserWindowEx.app/Contents/Frameworks/Chromium Embedded Framework.framework
You should have:
Chromium Embedded Framework
Libraries/*
Resources/*
3) Open project "AppHelper", create App Bundle and compile the AppHelper.
Run create_mac_helper.sh
4) Open project BrowserWindowEx, compile and run

View File

@ -0,0 +1,468 @@
// ************************************************************************
// ***************************** 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}
// Delphi uses MACOS for the new MacOSX and DARWIN is not defined
// FPC uses DARWIN for the new MacOSX and MACOS is defined for the classic Macintosh OS (System 7)
// We define MACOSX to avoid conflicts in both situations
{$IFDEF FPC}
{$IFDEF DARWIN}
{$DEFINE MACOSX}
{$ENDIF}
{$ELSE}
{$IFDEF MACOS}
{$DEFINE MACOSX}
{$ENDIF}
{$ENDIF}

View File

@ -0,0 +1,13 @@
#!/bin/sh
CDIR=$(pwd)
cd "$(dirname "$0")"
../AppHelper/create_mac_helper_apps.sh ../../../bin/BrowserWindowEx.app
if [ "$(grep -i TCrCocoaApplication ../../../bin/BrowserWindowEx.app/Contents/Info.plist)" = "" ];
then
sed -i '' "1,4s/<dict>/<dict>\n <key>NSPrincipalClass<\/key>\n <string>TCrCocoaApplication<\/string>/" ../../../bin/BrowserWindowEx.app/Contents/Info.plist
fi
cd "$CDIR"

View File

@ -0,0 +1,116 @@
// ************************************************************************
// ***************************** 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 GlobalCefApplication;
{$mode ObjFPC}{$H+}
{$I cef.inc}
{.$DEFINE USE_MULTI_THREAD_LOOP} // Only Windows/Linux
{.$DEFINE USE_APP_HELPER} // Optional on Windows/Linux
{$IFDEF MACOSX}
{$UNDEF USE_MULTI_THREAD_LOOP} // Will fail on Mac
{$DEFINE USE_APP_HELPER} // Required on Mac
{$ENDIF}
interface
uses
uCEFApplication, uCEFWorkScheduler, FileUtil;
procedure CreateGlobalCEFApp;
implementation
procedure GlobalCEFApp_OnScheduleMessagePumpWork(const aDelayMS : int64);
begin
if (GlobalCEFWorkScheduler <> nil) then GlobalCEFWorkScheduler.ScheduleMessagePumpWork(aDelayMS);
end;
procedure CreateGlobalCEFApp;
begin
if GlobalCEFApp <> nil then
exit;
{$IFnDEF USE_MULTI_THREAD_LOOP}
// 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 := TCEFWorkScheduler.Create(nil);
{$ENDIF}
GlobalCEFApp := TCefApplication.Create;
{$IFDEF USE_MULTI_THREAD_LOOP}
// On Windows/Linux CEF can use threads for the message-loop
GlobalCEFApp.MultiThreadedMessageLoop := True;
{$ELSE}
// use External Pump for message-loop
GlobalCEFApp.ExternalMessagePump := True;
GlobalCEFApp.MultiThreadedMessageLoop := False;
GlobalCEFApp.OnScheduleMessagePumpWork := @GlobalCEFApp_OnScheduleMessagePumpWork;
{$ENDIF}
GlobalCEFApp.CheckCEFFiles := false;
{$IFnDEF MACOSX}
{$IFDEF USE_APP_HELPER}
(* Use AppHelper as subprocess, instead of the main exe *)
GlobalCEFApp.BrowserSubprocessPath := 'AppHelper' + GetExeExt;
{$ENDIF}
{$ENDIF}
{$IFDEF MACOSX}
(* Enable the below to prevent being asked for permission to access "Chromium Safe Storage"
If set to true, Cookies will not be encrypted.
*)
GlobalCEFApp.UseMockKeyChain := True;
{$ENDIF}
{$IFDEF LINUX}
// This is a workaround for the 'GPU is not usable error' issue :
// https://bitbucket.org/chromiumembedded/cef/issues/2964/gpu-is-not-usable-error-during-cef
GlobalCEFApp.DisableZygote := True; // this property adds the "--no-zygote" command line switch
{$ENDIF}
{
GlobalCEFApp.LogFile := 'cef.log';
GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
}
end;
end.

View File

@ -0,0 +1,61 @@
// ************************************************************************
// ***************************** 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 InitSubProcess;
{$mode ObjFPC}{$H+}
{$I cef.inc}
interface
uses
GlobalCefApplication, uCEFApplication, uCEFWorkScheduler;
implementation
initialization
CreateGlobalCEFApp;
if not GlobalCEFApp.StartMainProcess then begin
if GlobalCEFWorkScheduler <> nil then
GlobalCEFWorkScheduler.StopScheduler;
DestroyGlobalCEFApp;
DestroyGlobalCEFWorkScheduler;
halt(0); // exit the subprocess
end;
end.

View File

@ -0,0 +1,245 @@
object Form1: TForm1
Left = 473
Height = 589
Top = 227
Width = 967
Caption = 'Initializing browser. Please wait...'
ClientHeight = 589
ClientWidth = 967
OnCloseQuery = FormCloseQuery
OnCreate = FormCreate
Position = poScreenCenter
LCLVersion = '2.1.0.0'
object PanelLeft: TPanel
Left = 0
Height = 557
Top = 32
Width = 484
Align = alLeft
ClientHeight = 557
ClientWidth = 484
TabOrder = 0
object AddressPnlLeft: TPanel
Left = 1
Height = 23
Top = 1
Width = 482
Align = alTop
BevelOuter = bvNone
ClientHeight = 23
ClientWidth = 482
Enabled = False
TabOrder = 0
object GoBtnLeft: TButton
Left = 424
Height = 23
Top = 0
Width = 35
Align = alRight
Caption = 'Go'
OnClick = GoBtnLeftClick
TabOrder = 0
end
object AddressEdtLeft: TComboBox
Left = 0
Height = 23
Top = 0
Width = 424
Align = alClient
ItemHeight = 15
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/html/html5_video.asp'
'http://www.adobe.com/software/flash/about/'
'http://isflashinstalled.com/'
'chrome://version/'
'http://html5test.com/'
'https://www.w3schools.com/'
'http://webglsamples.org/'
'https://get.webgl.org/'
'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'
'https://www.browserleaks.com/webrtc'
'https://frames-per-second.appspot.com/'
)
TabOrder = 1
Text = 'https://www.google.com'
end
object CloseBtnLeft: TSpeedButton
Left = 459
Height = 23
Top = 0
Width = 23
Align = alRight
Images = ImageList1
ImageIndex = 0
OnClick = CloseBtnLeftClick
end
end
object OpenBtnLeft: TSpeedButton
AnchorSideLeft.Control = PanelLeft
AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = PanelLeft
AnchorSideTop.Side = asrCenter
Left = 182
Height = 70
Top = 243
Width = 120
Caption = 'Open Browser'
OnClick = OpenBtnLeftClick
end
end
object Splitter1: TSplitter
Left = 484
Height = 557
Top = 32
Width = 5
end
object PanelRight: TPanel
Left = 489
Height = 557
Top = 32
Width = 478
Align = alClient
ClientHeight = 557
ClientWidth = 478
TabOrder = 2
object AddressPnlRight: TPanel
Left = 1
Height = 23
Top = 1
Width = 476
Align = alTop
BevelOuter = bvNone
ClientHeight = 23
ClientWidth = 476
Enabled = False
TabOrder = 0
object GoBtnRight: TButton
Left = 418
Height = 23
Top = 0
Width = 35
Align = alRight
Caption = 'Go'
OnClick = GoBtnRightClick
TabOrder = 0
end
object AddressEdtRight: TComboBox
Left = 0
Height = 23
Top = 0
Width = 418
Align = alClient
ItemHeight = 15
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/html/html5_video.asp'
'http://www.adobe.com/software/flash/about/'
'http://isflashinstalled.com/'
'chrome://version/'
'http://html5test.com/'
'https://www.w3schools.com/'
'http://webglsamples.org/'
'https://get.webgl.org/'
'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'
'https://www.browserleaks.com/webrtc'
'https://frames-per-second.appspot.com/'
)
TabOrder = 1
Text = 'https://www.google.com'
end
object CloseBtnRight: TSpeedButton
Left = 453
Height = 23
Top = 0
Width = 23
Align = alRight
Images = ImageList1
ImageIndex = 0
OnClick = CloseBtnRightClick
end
end
object OpenBtnRight: TSpeedButton
AnchorSideLeft.Control = PanelRight
AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = PanelRight
AnchorSideTop.Side = asrCenter
Left = 179
Height = 70
Top = 243
Width = 120
Caption = 'Open Browser'
OnClick = OpenBtnRightClick
end
end
object Panel1: TPanel
Left = 0
Height = 32
Top = 0
Width = 967
Align = alTop
AutoSize = True
ChildSizing.LeftRightSpacing = 5
ChildSizing.TopBottomSpacing = 3
ChildSizing.HorizontalSpacing = 10
ChildSizing.VerticalSpacing = 3
ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 5
ClientHeight = 32
ClientWidth = 967
TabOrder = 3
object BtnCloseApp: TButton
Left = 5
Height = 25
Top = 3
Width = 80
Caption = 'Close App'
OnClick = BtnCloseAppClick
TabOrder = 0
end
object BtnCloseForm: TButton
Left = 95
Height = 25
Top = 3
Width = 86
Caption = 'Close Form'
OnClick = BtnCloseFormClick
TabOrder = 1
end
object BtnModal: TButton
Left = 191
Height = 25
Top = 3
Width = 92
Caption = 'Show Modal'
OnClick = BtnModalClick
TabOrder = 2
end
end
object ImageList1: TImageList
left = 672
top = 104
Bitmap = {
4C7A010000001000000010000000D70000000000000078DAE591CB0A82501445
FD19C5C7F58DA2A0F8C2FFF2178BA0226C12A6A1627DC1E9EE410D1CA8E3BA70
270716FBEC7504E1775E92BCCA3C6FC8B2A66C3ECFB22B99665B2CF160E3F841
41D092A24C296661F82CD2B4E1B30B79DE9E9678E482759C9E5C77204D9BAA28
6AC9F7917D20513C966B1D900BD63447DE6320DB6E48D7CF244975B1D503726D
7B20C67ABEC39D7719ABAD2CFA6267E48255D58EFFDBD7C79A7FB8425FEC8C5C
B09AD69061D424CB5DB6C4E346F00C579FBEC805CBD889CF778BFE715FDC68EE
19B960B7F8FFB7F70660608313
}
end
end

View File

@ -0,0 +1,395 @@
// ************************************************************************
// ***************************** 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 uBrowserWindowEx;
{$mode objfpc}{$H+}
{$I cef.inc}
interface
uses
GlobalCefApplication,
uCEFLazarusCocoa, // required for Cocoa
SysUtils, Messages, Forms, Controls,
Dialogs, ExtCtrls, StdCtrls, LMessages, Buttons,
uCEFTypes, uCEFInterfaces,
uCEFWorkScheduler, uCEFLazarusBrowserWindow, Classes;
type
{ TForm1 }
TForm1 = class(TForm)
AddressEdtLeft: TComboBox;
AddressEdtRight: TComboBox;
AddressPnlRight: TPanel;
BtnCloseApp: TButton;
BtnCloseForm: TButton;
BtnModal: TButton;
GoBtnLeft: TButton;
AddressPnlLeft: TPanel;
GoBtnRight: TButton;
ImageList1: TImageList;
Panel1: TPanel;
PanelRight: TPanel;
PanelLeft: TPanel;
CloseBtnLeft: TSpeedButton;
CloseBtnRight: TSpeedButton;
OpenBtnLeft: TSpeedButton;
OpenBtnRight: TSpeedButton;
Splitter1: TSplitter;
procedure BtnCloseAppClick(Sender: TObject);
procedure BtnCloseFormClick(Sender: TObject);
procedure BtnModalClick(Sender: TObject);
procedure Chromium1BeforePopup(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl, targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; const popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo; var client: ICefClient; var settings: TCefBrowserSettings; var extra_info: ICefDictionaryValue; var noJavascriptAccess: Boolean; var Result: Boolean);
procedure Chromium1OpenUrlFromTab(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; out Result: Boolean);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormCreate(Sender: TObject);
procedure OpenBtnLeftClick(Sender: TObject);
procedure LeftBrowserCreated(Sender: TObject);
procedure GoBtnLeftClick(Sender: TObject);
procedure CloseBtnLeftClick(Sender: TObject);
procedure LeftBrowserClosed(Sender: TObject);
procedure OpenBtnRightClick(Sender: TObject);
procedure RightBrowserCreated(Sender: TObject);
procedure GoBtnRightClick(Sender: TObject);
procedure CloseBtnRightClick(Sender: TObject);
procedure RightBrowserClosed(Sender: TObject);
procedure DoShowModal(Data: PtrInt);
procedure MaybeTerminateApp(Sender: TObject);
procedure MaybeCloseApp(Sender: TObject);
protected
FBrowserLeft, FBrowserRight: TLazarusBrowserWindow;
FClosingBrowsers: TList;
{$IFDEF WINDOWS}
procedure WMEnterMenuLoop(var aMessage: TMessage); message WM_ENTERMENULOOP;
procedure WMExitMenuLoop(var aMessage: TMessage); message WM_EXITMENULOOP;
{$ENDIF}
public
constructor Create(TheOwner: TComponent); override;
destructor Destroy; override;
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
// This is a demo with the simplest web browser you can build using CEF4Delphi and
// it doesn't show any sign of progress like other web browsers do.
// Remember that it may take a few seconds to load if Windows update, your antivirus or
// any other windows service is using your hard drive.
// Depending on your internet connection it may take longer than expected.
// Please check that your firewall or antivirus are not blocking this application
// or the domain "google.com". If you don't live in the US, you'll be redirected to
// another domain which will take a little time too.
// This demo uses a TChromium and a TCEFLinkedWindowParent
// We need to use TCEFLinkedWindowParent in Linux to update the browser
// visibility and size automatically.
// Destruction steps
// =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sets aAction to cbaClose to destroy the browser, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends CEF_BEFORECLOSE to close the form.
uses
uCEFApplication;
{ TForm1 }
procedure TForm1.OpenBtnLeftClick(Sender: TObject);
begin
FBrowserLeft := TLazarusBrowserWindow.Create(Self);
FBrowserLeft.Chromium.OnBeforePopup := @Chromium1BeforePopup;
FBrowserLeft.Chromium.OnOpenUrlFromTab := @Chromium1OpenUrlFromTab;
FBrowserLeft.OnBrowserCreated := @LeftBrowserCreated;
FBrowserLeft.OnBrowserClosed := @LeftBrowserClosed;
FBrowserLeft.Align := alClient;
FBrowserLeft.Parent := PanelLeft;
OpenBtnLeft.Enabled := False;
GoBtnLeftClick(nil);
end;
procedure TForm1.LeftBrowserCreated(Sender: TObject);
begin
AddressPnlLeft.Enabled := True;
end;
procedure TForm1.GoBtnLeftClick(Sender: TObject);
begin
FBrowserLeft.LoadURL(UTF8Decode(AddressEdtLeft.Text));
end;
procedure TForm1.CloseBtnLeftClick(Sender: TObject);
begin
AddressPnlLeft.Enabled := False;
FClosingBrowsers.Add(FBrowserLeft);
FBrowserLeft.CloseBrowser(True);
FBrowserLeft := nil;
//FreeAndNil(FBrowserLeft);
OpenBtnLeft.Enabled := True;
end;
procedure TForm1.LeftBrowserClosed(Sender: TObject);
begin
FClosingBrowsers.Remove(Sender);
Sender.Free;
end;
procedure TForm1.OpenBtnRightClick(Sender: TObject);
begin
FBrowserRight := TLazarusBrowserWindow.Create(Self);
FBrowserRight.Chromium.OnBeforePopup := @Chromium1BeforePopup;
FBrowserRight.Chromium.OnOpenUrlFromTab := @Chromium1OpenUrlFromTab;
FBrowserRight.OnBrowserCreated := @RightBrowserCreated;
{$IFDEF MACOSX}
FBrowserRight.OnBrowserClosed := @RightBrowserClosed;
{$ENDIF}
FBrowserRight.Align := alClient;
FBrowserRight.Parent := PanelRight;
OpenBtnRight.Enabled := False;
GoBtnRightClick(nil);
end;
procedure TForm1.RightBrowserCreated(Sender: TObject);
begin
AddressPnlRight.Enabled := True;
end;
procedure TForm1.GoBtnRightClick(Sender: TObject);
begin
FBrowserRight.LoadURL(UTF8Decode(AddressEdtRight.Text));
end;
procedure TForm1.CloseBtnRightClick(Sender: TObject);
begin
AddressPnlRight.Enabled := False;
{$IFDEF MACOSX}
FClosingBrowsers.Add(FBrowserRight);
FBrowserRight.CloseBrowser(True);
FBrowserRight := nil;
{$ELSE}
FreeAndNil(FBrowserRight);
{$ENDIF}
OpenBtnRight.Enabled := True;
end;
procedure TForm1.RightBrowserClosed(Sender: TObject);
begin
FClosingBrowsers.Remove(Sender);
Sender.Free;
end;
{$IFDEF WINDOWS}
procedure TForm1.WMEnterMenuLoop(var aMessage: TMessage);
begin
inherited;
if (aMessage.wParam = 0) and (GlobalCEFApp <> nil) then GlobalCEFApp.OsmodalLoop := True;
end;
procedure TForm1.WMExitMenuLoop(var aMessage: TMessage);
begin
inherited;
if (aMessage.wParam = 0) and (GlobalCEFApp <> nil) then GlobalCEFApp.OsmodalLoop := False;
end;
{$ENDIF}
constructor TForm1.Create(TheOwner: TComponent);
begin
FClosingBrowsers := TList.Create;
inherited Create(TheOwner);
end;
destructor TForm1.Destroy;
begin
inherited Destroy;
FreeAndNil(FClosingBrowsers);
end;
procedure TForm1.Chromium1BeforePopup(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame; const targetUrl,
targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition;
userGesture: Boolean; const popupFeatures: TCefPopupFeatures;
var windowInfo: TCefWindowInfo; var client: ICefClient;
var settings: TCefBrowserSettings; var extra_info: ICefDictionaryValue;
var noJavascriptAccess: Boolean; var Result: Boolean);
begin
// For simplicity, this demo blocks all popup windows and new tabs
Result := (targetDisposition in [WOD_NEW_FOREGROUND_TAB, WOD_NEW_BACKGROUND_TAB, WOD_NEW_POPUP, WOD_NEW_WINDOW]);
end;
procedure TForm1.MaybeTerminateApp(Sender: TObject);
begin
Sender.Free;
FClosingBrowsers.Remove(Sender);
if FClosingBrowsers.Count = 0 then
Application.Terminate;
end;
procedure TForm1.BtnCloseAppClick(Sender: TObject);
begin
// Does not call CloseQuery
Hide;
{$IFDEF MACOSX}
(* This demo takes no precaution against the App being closed by outher means
while waiting for all browsers to close
*)
if FBrowserLeft <> nil then begin
FBrowserLeft.OnBrowserClosed := @MaybeTerminateApp;
CloseBtnLeftClick(nil);
end;
if FBrowserRight <> nil then begin
FBrowserRight.OnBrowserClosed := @MaybeTerminateApp;
CloseBtnRightClick(nil);
end;
if FClosingBrowsers.Count = 0 then
Application.Terminate;
{$ELSE}
if FBrowserLeft <> nil then
FBrowserLeft.WaitForBrowserClosed;
if FBrowserRight <> nil then
FBrowserRight.WaitForBrowserClosed;
Application.Terminate;
{$ENDIF}
end;
procedure TForm1.BtnCloseFormClick(Sender: TObject);
begin
Close;
end;
procedure TForm1.BtnModalClick(Sender: TObject);
begin
{$IFDEF MACOSX}
Application.QueueAsyncCall(@DoShowModal, 0);
{$ELSE}
DoShowModal(0);
{$ENDIF}
end;
procedure TForm1.DoShowModal(Data: PtrInt);
var
m: TForm1;
begin
m := TForm1.Create(Application);
m.BtnModal.Enabled := False;
m.Caption := 'MOD';
m.BtnCloseApp.Visible := False;
m.ShowModal;
m.Free;
end;
procedure TForm1.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 TForm1.MaybeCloseApp(Sender: TObject);
begin
Sender.Free;
FClosingBrowsers.Remove(Sender);
if FClosingBrowsers.Count = 0 then
Close;
end;
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
Hide;
if FBrowserLeft <> nil then begin
FBrowserLeft.OnBrowserClosed := @MaybeCloseApp;
CloseBtnLeftClick(nil);
end;
if FBrowserRight <> nil then begin
FBrowserRight.OnBrowserClosed := @MaybeCloseApp;
CloseBtnRightClick(nil);
end;
CanClose := FClosingBrowsers.Count = 0;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
OpenBtnLeftClick(nil);
end;
initialization
{$IFDEF DARWIN} // $IFDEF MACOSX
AddCrDelegate;
{$ENDIF}
if GlobalCEFApp = nil then begin
CreateGlobalCEFApp;
if not GlobalCEFApp.StartMainProcess then begin
DestroyGlobalCEFApp;
DestroyGlobalCEFWorkScheduler;
halt(0); // exit the subprocess
end;
end;
finalization
(* Destroy from this unit, which is used after "Interfaces". So this happens before the Application object is destroyed *)
if GlobalCEFWorkScheduler <> nil then
GlobalCEFWorkScheduler.StopScheduler;
DestroyGlobalCEFApp;
DestroyGlobalCEFWorkScheduler;
end.

View File

@ -0,0 +1,2 @@
rmdir /S /Q lib
rmdir /S /Q backup

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
<CompatibilityMode Value="True"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="AppHelper"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
<XPManifest>
<DpiAware Value="True"/>
</XPManifest>
<Icon Value="0"/>
</General>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<DestinationDirectory Value="B:\laz_other\CEF4Delphi\demos\Lazarus Mac\SubProcess"/>
<CompressFinally Value="False"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages Count="2">
<Item1>
<PackageName Value="CEF4Delphi_Lazarus"/>
</Item1>
<Item2>
<PackageName Value="LCL"/>
</Item2>
</RequiredPackages>
<Units Count="2">
<Unit0>
<Filename Value="AppHelper.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="..\uHelperProcessDom.pas"/>
<IsPartOfProject Value="True"/>
</Unit1>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="..\..\..\..\bin\AppHelper"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<OtherUnitFiles Value=".."/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<IncludeAssertionCode Value="True"/>
</SyntaxOptions>
</Parsing>
<CodeGeneration>
<Checks>
<IOChecks Value="True"/>
<RangeChecks Value="True"/>
<OverflowChecks Value="True"/>
<StackChecks Value="True"/>
</Checks>
</CodeGeneration>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf3"/>
</Debugging>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
</CompilerOptions>
</CONFIG>

View File

@ -0,0 +1,73 @@
// ************************************************************************
// ***************************** 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.
*
*)
program AppHelper;
(*
* The compiled exe should be copied into
* SimpleBrowser.app/Content/Frameworks/SimpleBrowser2 Helper.app/Content/MacOS/SimpleBrowser2 Helper
* including app bundle in SimpleBrowser2.app/Content/Frameworks/SimpleBrowser2 Helper.app
*)
{$mode objfpc}{$H+}
{$I cef.inc}
uses
{$IFDEF UNIX}
cthreads,
{$ENDIF}
Interfaces, // this includes the LCL widgetset
uHelperProcessDom,
uCEFApplication, uCEFTypes, uCEFConstants, LazFileUtils, sysutils;
begin
GlobalCEFApp := TCefApplication.Create;
InitProcessMessagesHandler;
// The main process and the subprocess *MUST* have the same GlobalCEFApp
// properties and events, specially FrameworkDirPath, ResourcesDirPath,
// LocalesDirPath, cache and UserDataPath paths.
{$IFDEF MACOSX}
GlobalCEFApp.InitLibLocationFromArgs;
{$ENDIF}
GlobalCEFApp.StartSubProcess;
GlobalCEFApp.Free;
GlobalCEFApp := nil;
end.

View File

@ -0,0 +1,468 @@
// ************************************************************************
// ***************************** 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}
// Delphi uses MACOS for the new MacOSX and DARWIN is not defined
// FPC uses DARWIN for the new MacOSX and MACOS is defined for the classic Macintosh OS (System 7)
// We define MACOSX to avoid conflicts in both situations
{$IFDEF FPC}
{$IFDEF DARWIN}
{$DEFINE MACOSX}
{$ENDIF}
{$ELSE}
{$IFDEF MACOS}
{$DEFINE MACOSX}
{$ENDIF}
{$ENDIF}

View File

@ -0,0 +1,57 @@
#!/bin/sh
BASEDIR=$(dirname "$0")
DEST=$1
SRC=$2
if [ "$SRC" = "" ];
then
SRC=$BASEDIR/../../../../bin/AppHelper.app
fi
if [ "$1" = "" ] || [ ! -e "$DEST" ] || [ ! -e "$SRC" ];
then
echo "Usage"
echo " $0 destpath/project.app"
echo " $0 destpath/project.app sourcedir/AppHelper.app"
echo
if [ ! -e "$DEST" ];
then
echo "Error: Target app bundle not found. (Did you compile AND create the bundle?)"
fi
if [ ! -e "$SRC" ];
then
echo "Error: Source (AppHelper) app bundle not found. (Did you compile AND create the bundle?)"
fi
exit;
fi
SRCAPP=$(basename "$SRC")
SRCAPP="${SRCAPP%\.app}"
DESTAPP=$(basename "$DEST")
DESTAPP="${DESTAPP%\.app}"
SUB=""
rm -rf "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app"
cp -r "$SRC" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app"
mv "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/MacOS/$SRCAPP" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/MacOS/$DESTAPP Helper$SUB"
sed -i '' "s/$SRCAPP/$DESTAPP Helper$SUB/g" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/Info.plist"
SUB=" (GPU)"
rm -rf "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app"
cp -r "$SRC" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app"
mv "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/MacOS/$SRCAPP" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/MacOS/$DESTAPP Helper$SUB"
sed -i '' "s/$SRCAPP/$DESTAPP Helper$SUB/g" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/Info.plist"
SUB=" (Renderer)"
rm -rf "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app"
cp -r "$SRC" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app"
mv "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/MacOS/$SRCAPP" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/MacOS/$DESTAPP Helper$SUB"
sed -i '' "s/$SRCAPP/$DESTAPP Helper$SUB/g" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/Info.plist"
SUB=" (Plugin)"
rm -rf "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app"
cp -r "$SRC" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app"
mv "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/MacOS/$SRCAPP" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/MacOS/$DESTAPP Helper$SUB"
sed -i '' "s/$SRCAPP/$DESTAPP Helper$SUB/g" "$DEST/Contents/Frameworks/$DESTAPP Helper$SUB.app/Contents/Info.plist"

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

View File

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<General>
<Flags>
<CompatibilityMode Value="True"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="BrowserWindowOsrDom"/>
<Scaled Value="True"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
<XPManifest>
<DpiAware Value="True"/>
</XPManifest>
<Icon Value="0"/>
</General>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<DestinationDirectory Value="B:/laz_other/CEF4Delphi/demos/Lazarus_any_OS/BrowserWindowDom"/>
<CompressFinally Value="False"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages Count="3">
<Item1>
<PackageName Value="LazDebuggerGdbmi"/>
</Item1>
<Item2>
<PackageName Value="CEF4Delphi_Lazarus"/>
</Item2>
<Item3>
<PackageName Value="LCL"/>
</Item3>
</RequiredPackages>
<Units Count="5">
<Unit0>
<Filename Value="BrowserWindowOsrDom.pas"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="uBrowserWindowDom.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="Form1"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
</Unit1>
<Unit2>
<Filename Value="initsubprocess.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="InitSubProcess"/>
</Unit2>
<Unit3>
<Filename Value="globalcefapplication.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="GlobalCefApplication"/>
</Unit3>
<Unit4>
<Filename Value="uHelperProcessDom.pas"/>
<IsPartOfProject Value="True"/>
</Unit4>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<Target>
<Filename Value="../../../bin/BrowserWindowOsrDom"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf3"/>
</Debugging>
</Linking>
<Other>
<CustomOptions Value="-dUseCthreads"/>
</Other>
</CompilerOptions>
</CONFIG>

View File

@ -0,0 +1,84 @@
// ************************************************************************
// ***************************** 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.
*
*)
(*
* Include the following files
* BrowserWindow.app/Contents/Frameworks/ExternalPumpBrowser Helper.app/
* files from the demos/Lazarus_Mac/AppHelper project
* use create_mac_helper.sh
*
* BrowserWindow.app/Contents/Frameworks/Chromium Embedded Framework.framework
* files from Release folder in cef download
*
*)
program BrowserWindowOsrDom;
{$mode objfpc}{$H+}
{$I cef.inc}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
{$IFDEF LINUX}
InitSubProcess, // On Linux this unit must be used *before* the "interfaces" unit.
{$ENDIF}
Interfaces,
Forms,
uBrowserWindowDom, GlobalCefApplication,
uHelperProcessDom // Used here, for any OS where the main exe server as AppHelper too.
{ you can add units after this }
;
{$R *.res}
{$IFDEF WIN32}
// CEF needs to set the LARGEADDRESSAWARE ($20) flag which allows 32-bit processes to use up to 3GB of RAM.
{$SetPEFlags $20}
{$ENDIF}
begin
RequireDerivedFormResource:=True;
Application.Scaled := True;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

View File

@ -0,0 +1,40 @@
BrowserWindow
# ABOUT
This example uses
TLazarusBrowserWindow
Examining DOM
TCEFWorkScheduler feeds the CEF messageloop by calling DoMessageLoopWork(). On Mac this is currently the only way to run the CEF messageloop.
# SETUP
** Windows
1) Download the CEF framework and place the content of the "Release" folder into the same folder as your exe.
Alternatively you can point "GlobalCEFApp.FrameworkDirPath" to the location with the libraries.
2) Run the project
** Linux
1) Download the CEF framework and place the content of the "Release" folder into the same folder as your exe.
Alternatively you can point "GlobalCEFApp.FrameworkDirPath" to the location with the libraries.
2) Run the project
Note:
- For your own Linux project you must modify the project source (lpr) and add "InitSubProcess" to the "uses" clause, so that it is in the list *before* the unit "Interfaces".
- The call to "DestroyGlobalCEFApp" must be in a unit *not* used by "unit InitSubProcess" (including not used in any nested way).
** Mac
1) Go to "project options" and create the "App Bundle"
2) Download the CEF framework and place the content of the "Release" folder into BrowserWindowOsrDom.app/Contents/Frameworks/Chromium Embedded Framework.framework
You should have:
Chromium Embedded Framework
Libraries/*
Resources/*
3) Open project "AppHelper" (from the subfolder in this project's folder), create App Bundle and compile the AppHelper.
Run create_mac_helper.sh
4) Open project BrowserWindowOsrDom, compile and run

View File

@ -0,0 +1,468 @@
// ************************************************************************
// ***************************** 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}
// Delphi uses MACOS for the new MacOSX and DARWIN is not defined
// FPC uses DARWIN for the new MacOSX and MACOS is defined for the classic Macintosh OS (System 7)
// We define MACOSX to avoid conflicts in both situations
{$IFDEF FPC}
{$IFDEF DARWIN}
{$DEFINE MACOSX}
{$ENDIF}
{$ELSE}
{$IFDEF MACOS}
{$DEFINE MACOSX}
{$ENDIF}
{$ENDIF}

View File

@ -0,0 +1,13 @@
#!/bin/sh
CDIR=$(pwd)
cd "$(dirname "$0")"
./AppHelper/create_mac_helper_apps.sh ../../../bin/BrowserWindowOsrDom.app
if [ "$(grep -i TCrCocoaApplication ../../../bin/BrowserWindowOsrDom.app/Contents/Info.plist)" = "" ];
then
sed -i '' "1,4s/<dict>/<dict>\n <key>NSPrincipalClass<\/key>\n <string>TCrCocoaApplication<\/string>/" ../../../bin/BrowserWindowOsrDom.app/Contents/Info.plist
fi
cd "$CDIR"

View File

@ -0,0 +1,120 @@
// ************************************************************************
// ***************************** 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 GlobalCefApplication;
{$mode ObjFPC}{$H+}
{$I cef.inc}
{.$DEFINE USE_MULTI_THREAD_LOOP} // Only Windows/Linux
{.$DEFINE USE_APP_HELPER} // Optional on Windows/Linux
{$IFDEF MACOSX}
{$UNDEF USE_MULTI_THREAD_LOOP} // Will fail on Mac
{$DEFINE USE_APP_HELPER} // Required on Mac
{$ENDIF}
interface
uses
uCEFApplication, uCEFWorkScheduler, uCEFLazApplication, FileUtil,
uHelperProcessDom;
procedure CreateGlobalCEFApp;
implementation
procedure GlobalCEFApp_OnScheduleMessagePumpWork(const aDelayMS : int64);
begin
if (GlobalCEFWorkScheduler <> nil) then GlobalCEFWorkScheduler.ScheduleMessagePumpWork(aDelayMS);
end;
procedure CreateGlobalCEFApp;
begin
if GlobalCEFApp <> nil then
exit;
{$IFnDEF USE_MULTI_THREAD_LOOP}
// 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 := TCEFWorkScheduler.Create(nil);
{$ENDIF}
GlobalCEFApp := TCefLazApplication.Create;
GlobalCEFApp.CheckCEFFiles := False;
{$IFDEF USE_MULTI_THREAD_LOOP}
// On Windows/Linux CEF can use threads for the message-loop
GlobalCEFApp.MultiThreadedMessageLoop := True;
{$ELSE}
// use External Pump for message-loop
GlobalCEFApp.ExternalMessagePump := True;
GlobalCEFApp.MultiThreadedMessageLoop := False;
GlobalCEFApp.OnScheduleMessagePumpWork := @GlobalCEFApp_OnScheduleMessagePumpWork;
{$ENDIF}
GlobalCEFApp.CheckCEFFiles := false;
{$IFnDEF MACOSX}
{$IFDEF USE_APP_HELPER}
(* Use AppHelper as subprocess, instead of the main exe *)
GlobalCEFApp.BrowserSubprocessPath := 'AppHelper' + GetExeExt;
{$ENDIF}
{$ENDIF}
{$IFDEF MACOSX}
(* Enable the below to prevent being asked for permission to access "Chromium Safe Storage"
If set to true, Cookies will not be encrypted.
*)
GlobalCEFApp.UseMockKeyChain := True;
{$ENDIF}
{$IFDEF LINUX}
// This is a workaround for the 'GPU is not usable error' issue :
// https://bitbucket.org/chromiumembedded/cef/issues/2964/gpu-is-not-usable-error-during-cef
GlobalCEFApp.DisableZygote := True; // this property adds the "--no-zygote" command line switch
{$ENDIF}
{
GlobalCEFApp.LogFile := 'cef.log';
GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
}
InitProcessMessagesHandler; // This is for the AppHelper process.
end;
end.

View File

@ -0,0 +1,61 @@
// ************************************************************************
// ***************************** 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 InitSubProcess;
{$mode ObjFPC}{$H+}
{$I cef.inc}
interface
uses
GlobalCefApplication, uCEFApplication, uCEFWorkScheduler;
implementation
initialization
CreateGlobalCEFApp;
if not GlobalCEFApp.StartMainProcess then begin
if GlobalCEFWorkScheduler <> nil then
GlobalCEFWorkScheduler.StopScheduler;
DestroyGlobalCEFApp;
DestroyGlobalCEFWorkScheduler;
halt(0); // exit the subprocess
end;
end.

View File

@ -0,0 +1,82 @@
object Form1: TForm1
Left = 473
Height = 589
Top = 227
Width = 967
Caption = 'Initializing browser. Please wait...'
ClientHeight = 589
ClientWidth = 967
OnCloseQuery = FormCloseQuery
OnCreate = FormCreate
Position = poScreenCenter
LCLVersion = '2.1.0.0'
object AddressPnl: TPanel
Left = 0
Height = 23
Top = 0
Width = 967
Align = alTop
BevelOuter = bvNone
ClientHeight = 23
ClientWidth = 967
TabOrder = 0
object GoBtn: TButton
Left = 932
Height = 23
Top = 0
Width = 35
Align = alRight
Caption = 'Go'
OnClick = GoBtnClick
TabOrder = 0
end
object AddressEdt: TComboBox
Left = 0
Height = 23
Top = 0
Width = 932
Align = alClient
ItemHeight = 15
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/html/html5_video.asp'
'http://www.adobe.com/software/flash/about/'
'http://isflashinstalled.com/'
'chrome://version/'
'http://html5test.com/'
'https://www.w3schools.com/'
'http://webglsamples.org/'
'https://get.webgl.org/'
'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'
'https://www.browserleaks.com/webrtc'
'https://frames-per-second.appspot.com/'
)
TabOrder = 1
Text = 'https://www.google.com'
end
end
object LazarusOsrBrowserWindow1: TLazarusOsrBrowserWindow
Left = 0
Height = 566
Top = 23
Width = 967
CopyOriginalBuffer = True
Align = alClient
TabOrder = 1
OnMouseMove = LazarusOsrBrowserWindow1MouseMove
OnBrowserClosed = LazarusBrowserWindow1BrowserClosed
end
object PopupMenu1: TPopupMenu
left = 418
top = 126
object MenuItem1: TMenuItem
Caption = 'Nothing in this menu'
end
end
end

View File

@ -0,0 +1,266 @@
// ************************************************************************
// ***************************** 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 uBrowserWindowDom;
{$mode objfpc}{$H+}
{$I cef.inc}
interface
uses
GlobalCefApplication,
uCEFLazarusCocoa, // required for Cocoa
SysUtils, Messages, Forms, Controls, Dialogs, ExtCtrls, StdCtrls, LMessages,
Menus, Graphics, uCEFTypes, uCEFInterfaces, uHelperProcessDom,
uCEFWorkScheduler, uCEFLazarusBrowserWindow, uCEFProcessMessage,
uCEFLazarusOsrBrowserWindow, Classes;
type
{ TForm1 }
TForm1 = class(TForm)
AddressEdt: TComboBox;
GoBtn: TButton;
AddressPnl: TPanel;
LazarusOsrBrowserWindow1: TLazarusOsrBrowserWindow;
mDomHere: TMenuItem;
MenuItem1: TMenuItem;
PopupMenu1: TPopupMenu;
procedure Chromium1BeforePopup(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl, targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; const popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo; var client: ICefClient; var settings: TCefBrowserSettings; var extra_info: ICefDictionaryValue; var noJavascriptAccess: Boolean; var Result: Boolean);
procedure Chromium1OpenUrlFromTab(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; out Result: Boolean);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormCreate(Sender: TObject);
procedure GoBtnClick(Sender: TObject);
procedure LazarusBrowserWindow1BrowserClosed(Sender: TObject);
procedure LazarusOsrBrowserWindow1MouseMove(Sender: TObject;
Shift: TShiftState; X, Y: Integer);
private
FCurRect: TRect;
procedure DoOnMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer; var AHandled: Boolean);
procedure DoOnMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer; var AHandled: Boolean);
procedure DoOnPaint(Sender: TObject);
procedure DoProcessMessageReceived(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame;
sourceProcess: TCefProcessId; const message: ICefProcessMessage; out
Result: Boolean);
protected
{$IFDEF WINDOWS}
procedure WMEnterMenuLoop(var aMessage: TMessage); message WM_ENTERMENULOOP;
procedure WMExitMenuLoop(var aMessage: TMessage); message WM_EXITMENULOOP;
procedure WMDpiChanged(var Message: TMessage); message WM_DPICHANGED;
{$ENDIF}
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
uses
uCEFApplication;
{ TForm1 }
procedure TForm1.GoBtnClick(Sender: TObject);
begin
LazarusOsrBrowserWindow1.Chromium.LoadURL(UTF8Decode(AddressEdt.Text));
end;
procedure TForm1.LazarusBrowserWindow1BrowserClosed(Sender: TObject);
begin
Close;
end;
procedure TForm1.LazarusOsrBrowserWindow1MouseMove(Sender: TObject;
Shift: TShiftState; X, Y: Integer);
var
TempMsg : ICefProcessMessage;
begin
TempMsg := TCefProcessMessageRef.New(MSG_REQUEST_DOM_R); // Same name than TCefCustomRenderProcessHandler.MessageName
TempMsg.ArgumentList.SetInt(0, X);
TempMsg.ArgumentList.SetInt(1, Y);
LazarusOsrBrowserWindow1.Chromium.SendProcessMessage(PID_RENDERER, TempMsg);
end;
procedure TForm1.DoOnMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer; var AHandled: Boolean);
begin
AHandled := Button = mbRight;
if Button = mbRight then begin
PopupMenu1.PopUp(X, Y);
end;
end;
procedure TForm1.DoOnMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer; var AHandled: Boolean);
begin
AHandled := Button = mbRight;
end;
procedure TForm1.DoOnPaint(Sender: TObject);
begin
if (FCurRect.Width > 0) and (FCurRect.Height > 0) then begin
LazarusOsrBrowserWindow1.Canvas.Brush.Style := bsClear;
LazarusOsrBrowserWindow1.Canvas.Pen.Style := psSolid;
LazarusOsrBrowserWindow1.Canvas.Pen.Color := clRed;
LazarusOsrBrowserWindow1.Canvas.Rectangle(FCurRect);
end;
end;
procedure TForm1.DoProcessMessageReceived(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame;
sourceProcess: TCefProcessId; const message: ICefProcessMessage; out
Result: Boolean);
begin
Result := False;
case message.Name of
MSG_RESPONSE_DOM_R: begin
FCurRect.Left := message.ArgumentList.GetInt(0);
FCurRect.Top := message.ArgumentList.GetInt(1);
FCurRect.Width := message.ArgumentList.GetInt(2);
FCurRect.Height := message.ArgumentList.GetInt(3);
Result := True;
LazarusOsrBrowserWindow1.Invalidate;
end;
end;
end;
{$IFDEF WINDOWS}
procedure TForm1.WMEnterMenuLoop(var aMessage: TMessage);
begin
inherited;
if (aMessage.wParam = 0) and (GlobalCEFApp <> nil) then GlobalCEFApp.OsmodalLoop := True;
end;
procedure TForm1.WMExitMenuLoop(var aMessage: TMessage);
begin
inherited;
if (aMessage.wParam = 0) and (GlobalCEFApp <> nil) then GlobalCEFApp.OsmodalLoop := False;
end;
procedure TForm1.WMDpiChanged(var Message: TMessage);
begin
inherited;
if (GlobalCEFApp <> nil) then
GlobalCEFApp.UpdateDeviceScaleFactor;
if (LazarusOsrBrowserWindow1.Chromium <> nil) then
begin
LazarusOsrBrowserWindow1.Chromium.NotifyScreenInfoChanged;
LazarusOsrBrowserWindow1.Chromium.WasResized;
end;
end;
{$ENDIF}
procedure TForm1.Chromium1BeforePopup(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame; const targetUrl,
targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition;
userGesture: Boolean; const popupFeatures: TCefPopupFeatures;
var windowInfo: TCefWindowInfo; var client: ICefClient;
var settings: TCefBrowserSettings; var extra_info: ICefDictionaryValue;
var noJavascriptAccess: Boolean; var Result: Boolean);
begin
// For simplicity, this demo blocks all popup windows and new tabs
Result := (targetDisposition in [WOD_NEW_FOREGROUND_TAB, WOD_NEW_BACKGROUND_TAB, WOD_NEW_POPUP, WOD_NEW_WINDOW]);
end;
procedure TForm1.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 TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
LazarusOsrBrowserWindow1.CloseBrowser(True);
CanClose := LazarusOsrBrowserWindow1.IsClosed;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FCurRect.Width := 0;
LazarusOsrBrowserWindow1.Chromium.OnProcessMessageReceived := @DoProcessMessageReceived;
LazarusOsrBrowserWindow1.OnMouseDown := @DoOnMouseDown;
LazarusOsrBrowserWindow1.OnMouseUp := @DoOnMouseUp;
LazarusOsrBrowserWindow1.OnPaint := @DoOnPaint;
LazarusOsrBrowserWindow1.Chromium.LoadURL(UTF8Decode(AddressEdt.Text));
end;
initialization
{$IFDEF DARWIN} // $IFDEF MACOSX
AddCrDelegate;
{$ENDIF}
if GlobalCEFApp = nil then begin
CreateGlobalCEFApp;
if not GlobalCEFApp.StartMainProcess then begin
DestroyGlobalCEFApp;
DestroyGlobalCEFWorkScheduler;
halt(0); // exit the subprocess
end;
end;
finalization
(* Destroy from this unit, which is used after "Interfaces". So this happens before the Application object is destroyed *)
if GlobalCEFWorkScheduler <> nil then
GlobalCEFWorkScheduler.StopScheduler;
DestroyGlobalCEFApp;
DestroyGlobalCEFWorkScheduler;
end.

View File

@ -0,0 +1,170 @@
// ************************************************************************
// ***************************** 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 uHelperProcessDom;
(* The code in this unit is executed in the renderer sub-process
*)
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils, uCEFApplication, uCEFInterfaces, uCEFDomVisitor, uCEFTypes,
uCEFProcessMessage;
const
MSG_REQUEST_DOM_R = 'MSG_REQUEST_DOM_R';
MSG_RESPONSE_DOM_R = 'MSG_RESPONSE_DOM_R';
procedure InitProcessMessagesHandler;
implementation
type
{ TDomVisitorFindXY }
TDomVisitorFindXY = class(TCefDomVisitorOwn)
protected
FFrame : ICefFrame;
FX, FY: Integer;
procedure visit(const document: ICefDomDocument); override;
public
constructor Create(AFrame: ICefFrame; X,Y: Integer); reintroduce; virtual;
end;
{ TDomVisitorFindXY }
procedure TDomVisitorFindXY.visit(const document: ICefDomDocument);
var
node, foundNode: ICefDomNode;
nb: TCefRect;
TempMsg : ICefProcessMessage;
begin
node := document.GetBody;
foundNode := nil;
if node <> nil then
begin
nb := node.GetElementBounds;
if (FX >= nb.x) and (FX < nb.x + nb.width) and
(FY >= nb.y) and (FY < nb.y + nb.height)
then
begin
while node <> nil do
begin
foundNode := node;
if node.HasChildren then
begin
node := node.FirstChild;
while node <> nil do
begin
nb := node.GetElementBounds;
if (FX >= nb.x) and (FX < nb.x + nb.width) and
(FY >= nb.y) and (FY < nb.y + nb.height)
then
break // go outer loop
else
node := node.NextSibling;
end;
end
else
node := nil;
end;
end;
end;
TempMsg := TCefProcessMessageRef.New(MSG_RESPONSE_DOM_R); // Same name than TCefCustomRenderProcessHandler.MessageName
if foundNode <> nil then begin
nb := foundNode.GetElementBounds;
TempMsg.ArgumentList.SetInt(0, nb.X);
TempMsg.ArgumentList.SetInt(1, nb.y);
TempMsg.ArgumentList.SetInt(2, nb.width);
TempMsg.ArgumentList.SetInt(3, nb.height);
end
else begin
TempMsg.ArgumentList.SetInt(0, 0);
TempMsg.ArgumentList.SetInt(1, 0);
TempMsg.ArgumentList.SetInt(2, 0);
TempMsg.ArgumentList.SetInt(3, 0);
end;
if (FFrame <> nil) and FFrame.IsValid then
FFrame.SendProcessMessage(PID_BROWSER, TempMsg);
end;
constructor TDomVisitorFindXY.Create(AFrame: ICefFrame; X, Y: Integer);
begin
FFrame := AFrame;
FX := X;
FY := Y;
inherited Create;
end;
procedure DoProcessMessageReceived(const browser: ICefBrowser;
const frame: ICefFrame; sourceProcess: TCefProcessId;
const message: ICefProcessMessage; var aHandled: boolean);
var
TempVisitor : TDomVisitorFindXY;
begin
aHandled := False;
case message.Name of
MSG_REQUEST_DOM_R: begin
if (frame <> nil) and frame.IsValid then
begin
TempVisitor := TDomVisitorFindXY.Create(
frame,
message.ArgumentList.GetInt(0),
message.ArgumentList.GetInt(1)
);
frame.VisitDom(TempVisitor);
end;
aHandled := True;
end;
end;
end;
procedure InitProcessMessagesHandler;
begin
GlobalCEFApp.OnProcessMessageReceived := @DoProcessMessageReceived;
end;
end.

View File

@ -22,7 +22,7 @@
<Description Value="CEF4Delphi is an open source project created by Salvador Díaz Fau to embed Chromium-based browsers in applications made with Delphi or Lazarus/FPC."/>
<License Value="MPL 1.1"/>
<Version Major="89" Release="6"/>
<Files Count="200">
<Files Count="202">
<Item1>
<Filename Value="..\source\uCEFAccessibilityHandler.pas"/>
<UnitName Value="uCEFAccessibilityHandler"/>
@ -840,6 +840,15 @@
<HasRegisterProc Value="True"/>
<UnitName Value="uceflazarusbrowserwindow"/>
</Item200>
<Item201>
<Filename Value="..\source\uCEFLazApplication.pas"/>
<UnitName Value="uCEFLazApplication"/>
</Item201>
<Item202>
<Filename Value="..\source\uCEFLazarusOsrBrowserWindow.pas"/>
<HasRegisterProc Value="True"/>
<UnitName Value="uCEFLazarusOsrBrowserWindow"/>
</Item202>
</Files>
<RequiredPkgs Count="4">
<Item1>

View File

@ -65,8 +65,9 @@ uses
uCEFMediaSinkDeviceInfoCallback, uCEFJson, uCEFBitmapBitBuffer,
uCEFPrintDialogCallback, uCEFPrintHandler, uCEFPrintJobCallback,
uCEFLinuxFunctions, uCEFLinuxTypes, uCEFLinuxConstants,
uCEFWorkSchedulerQueueThread, uCEFLinkedWinControlBase, uCEFLazarusCocoa,
uCEFLazarusBrowserWindow, LazarusPackageIntf;
uCEFWorkSchedulerQueueThread, uCEFLinkedWinControlBase, uCEFLazarusCocoa,
uCEFLazarusBrowserWindow, uCEFLazApplication, uCEFLazarusOsrBrowserWindow,
LazarusPackageIntf;
implementation
@ -90,6 +91,8 @@ begin
RegisterUnit('uCEFScrollViewComponent', @uCEFScrollViewComponent.Register);
RegisterUnit('uCEFTextfieldComponent', @uCEFTextfieldComponent.Register);
RegisterUnit('uCEFLazarusBrowserWindow', @uCEFLazarusBrowserWindow.Register);
RegisterUnit('uCEFLazarusOsrBrowserWindow',
@uCEFLazarusOsrBrowserWindow.Register);
end;
initialization

View File

@ -391,7 +391,7 @@ type
// ICefLoadHandler and ICefPrintHandler should use them.
procedure Internal_OnBeforeCommandLineProcessing(const processType: ustring; const commandLine: ICefCommandLine);
procedure Internal_OnRegisterCustomSchemes(const registrar: TCefSchemeRegistrarRef);
procedure Internal_OnContextInitialized;
procedure Internal_OnContextInitialized; virtual;
procedure Internal_OnBeforeChildProcessLaunch(const commandLine: ICefCommandLine);
procedure Internal_OnScheduleMessagePumpWork(const delayMs: Int64);
function Internal_GetLocalizedString(stringId: Integer; var stringVal: ustring) : boolean;

View File

@ -133,6 +133,11 @@ type
procedure WMIMEEndComp(var aMessage: TMessage);
procedure WMIMESetContext(var aMessage: TMessage);
procedure WMIMEComposition(var aMessage: TMessage);
procedure DoOnIMECancelComposition; virtual;
procedure DoOnIMECommitText(const aText : ustring; const replacement_range : PCefRange; relative_cursor_pos : integer); virtual;
procedure DoOnIMESetComposition(const aText : ustring; const underlines : TCefCompositionUnderlineDynArray; const replacement_range, selection_range : TCefRange); virtual;
{$ENDIF}
public
@ -636,6 +641,8 @@ begin
Canvas.Brush.Style := bsSolid;
Canvas.FillRect(rect(0, 0, Width, Height));
end;
if Assigned(OnPaint) then OnPaint(Self);
end;
{$IFDEF MSWINDOWS}
@ -735,7 +742,7 @@ end;
procedure TBufferPanel.WMIMEEndComp(var aMessage: TMessage);
begin
if assigned(FOnIMECancelComposition) then FOnIMECancelComposition(self);
DoOnIMECancelComposition;
if (FIMEHandler <> nil) then
begin
@ -775,7 +782,7 @@ begin
TempRange.from := high(Integer);
TempRange.to_ := high(Integer);
FOnIMECommitText(self, TempText, @TempRange, 0);
DoOnIMECommitText(TempText, @TempRange, 0);
end;
FIMEHandler.ResetComposition;
@ -791,14 +798,14 @@ begin
TempSelection.from := TempCompStart;
TempSelection.to_ := TempCompStart + length(TempText);
FOnIMESetComposition(self, TempText, TempUnderlines, TempRange, TempSelection);
DoOnIMESetComposition(TempText, TempUnderlines, TempRange, TempSelection);
end;
FIMEHandler.UpdateCaretPosition(pred(TempCompStart));
end
else
begin
if assigned(FOnIMECancelComposition) then FOnIMECancelComposition(self);
DoOnIMECancelComposition;
FIMEHandler.ResetComposition;
FIMEHandler.DestroyImeWindow;
@ -812,6 +819,28 @@ begin
end;
end;
end;
procedure TBufferPanel.DoOnIMECancelComposition;
begin
if FOnIMECancelComposition <> nil then
FOnIMECancelComposition(Self);
end;
procedure TBufferPanel.DoOnIMECommitText(const aText: ustring;
const replacement_range: PCefRange; relative_cursor_pos: integer);
begin
if FOnIMECommitText <> nil then
FOnIMECommitText(Self, aText, replacement_range, relative_cursor_pos);
end;
procedure TBufferPanel.DoOnIMESetComposition(const aText: ustring;
const underlines: TCefCompositionUnderlineDynArray; const replacement_range,
selection_range: TCefRange);
begin
if FOnIMESetComposition <> nil then
FOnIMESetComposition(Self, aText, underlines, replacement_range, selection_range);
end;
{$ENDIF}
function TBufferPanel.GetBufferBits : pointer;

View File

@ -0,0 +1,80 @@
unit uCEFLazApplication;
{$IFDEF FPC}
{$MODE OBJFPC}{$H+}
{$ENDIF}
{$I cef.inc}
interface
uses
{$IFDEF DELPHI16_UP}
{$ELSE}
Forms, LclProc, Classes, SysUtils,
{$ENDIF}
uCEFTypes, uCEFApplication;
type
{ TCefLazApplication }
TCefLazApplication = class(TCefApplication)
protected
FContextInitializedHandlers: TMethodList;
FContextInitializedDone: Boolean;
procedure CallContextInitializedHandlers(Data: PtrInt);
public
constructor Create;
destructor Destroy; override;
procedure Internal_OnContextInitialized; override; // In UI thread
Procedure AddContextInitializedHandler(AHandler: TNotifyEvent);
Procedure RemoveContextInitializedHandler(AHandler: TNotifyEvent);
end;
implementation
{ TCefLazApplication }
procedure TCefLazApplication.Internal_OnContextInitialized;
begin
inherited Internal_OnContextInitialized;
Application.QueueAsyncCall(@CallContextInitializedHandlers, 0);
//TThread.Queue(@CallContextInitializedHandlers);
end;
procedure TCefLazApplication.CallContextInitializedHandlers(Data: PtrInt);
begin
FContextInitializedHandlers.CallNotifyEvents(Self);
FContextInitializedDone := True;
end;
constructor TCefLazApplication.Create;
begin
FContextInitializedHandlers := TMethodList.Create;
inherited Create;
end;
destructor TCefLazApplication.Destroy;
begin
inherited Destroy;
FContextInitializedHandlers.Free;
end;
procedure TCefLazApplication.AddContextInitializedHandler(AHandler: TNotifyEvent);
begin
FContextInitializedHandlers.Add(TMethod(AHandler));
if FContextInitializedDone then
AHandler(Self);
end;
procedure TCefLazApplication.RemoveContextInitializedHandler(
AHandler: TNotifyEvent);
begin
FContextInitializedHandlers.Remove(TMethod(AHandler));
end;
end.

View File

@ -0,0 +1,917 @@
// ************************************************************************
// ***************************** 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 uCEFLazarusOsrBrowserWindow;
{$mode objfpc}{$H+}
{$i cef.inc}
interface
uses
{$IFDEF FPC}
LResources,
{$ENDIF}
uCEFApplication, uCEFChromiumWindow, uCEFTypes, uCEFInterfaces, uCEFChromium,
uCEFLinkedWinControlBase, uCEFLazApplication, uCEFBufferPanel,
uCEFLazarusBrowserWindow, uCEFBitmapBitBuffer, uCEFMiscFunctions,
uCEFConstants, Forms, ExtCtrls, LCLType, Graphics, Controls, syncobjs,
LazLogger, Classes, sysutils, math;
type
TBrowserMouseEvent = procedure(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer;
var AHandled: Boolean) of Object;
{ TLazarusOsrBrowserWindow }
TLazarusOsrBrowserWindow = class(TBufferPanel)
private
FPopUpBitmap : TBitmap;
FPopUpRect : TRect;
FShowPopUp : boolean;
FResizing : boolean;
FPendingResize : boolean;
FResizeCS : syncobjs.TCriticalSection;
//FIMECS : TCriticalSection;
FDeviceBounds : TCefRectDynArray;
FSelectedRange : TCefRange;
FLastKeyDown: Word;
procedure AsyncInvalidate(Data: PtrInt);
procedure AsyncResize(Data: PtrInt);
procedure SyncIMERangeChanged;
procedure DoGetChromiumBeforePopup(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame; const targetUrl,
targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition;
userGesture: Boolean; const popupFeatures: TCefPopupFeatures;
var windowInfo: TCefWindowInfo; var client: ICefClient;
var settings: TCefBrowserSettings; var extra_info: ICefDictionaryValue;
var noJavascriptAccess: Boolean; var Result: Boolean);
procedure DoGetChromiumPopupShow(Sender: TObject;
const browser: ICefBrowser; AShow: Boolean);
procedure DoGetChromiumPopupSize(Sender: TObject;
const browser: ICefBrowser; const rect: PCefRect);
procedure DoGetChromiumTooltip(Sender: TObject;
const browser: ICefBrowser; var AText: ustring; out Result: Boolean);
procedure DoGetChromiumIMECompositionRangeChanged(Sender: TObject;
const browser: ICefBrowser; const selected_range: PCefRange;
character_boundsCount: NativeUInt; const character_bounds: PCefRect);
procedure DoGetChromiumCursorChange(Sender: TObject;
const browser: ICefBrowser; cursor_: TCefCursorHandle;
cursorType: TCefCursorType; const customCursorInfo: PCefCursorInfo;
var aResult: boolean);
procedure DoGetChromiumGetScreenInfo(Sender: TObject;
const browser: ICefBrowser; var screenInfo: TCefScreenInfo; out
Result: Boolean);
procedure DoGetChromiumGetScreenPoint(Sender: TObject;
const browser: ICefBrowser; viewX, viewY: Integer; var screenX,
screenY: Integer; out Result: Boolean);
procedure DoGetChromiumViewRect(Sender: TObject;
const browser: ICefBrowser; var rect: TCefRect);
procedure DoChromiumPaint(Sender: TObject; const browser: ICefBrowser;
kind: TCefPaintElementType; dirtyRectsCount: NativeUInt;
const dirtyRects: PCefRectArray; const ABuffer: Pointer; AWidth,
AHeight: Integer);
private
FChromium : TLazChromium;
FOnBrowserClosed : TNotifyEvent;
FOnBrowserCreated : TNotifyEvent;
FOnMouseDown: TBrowserMouseEvent;
FOnMouseUp: TBrowserMouseEvent;
procedure DoCreateBrowserAfterContext(Sender: TObject);
protected
function GetChromium: TLazChromium;
function getModifiers(Shift: TShiftState): TCefEventFlags;
function getKeyModifiers(Shift: TShiftState): TCefEventFlags;
function GetButton(Button: TMouseButton): TCefMouseButtonType;
procedure DestroyHandle; override;
procedure RealizeBounds; override;
procedure DoEnter; override;
procedure DoExit; override;
procedure Click; override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure MouseEnter; override;
procedure MouseLeave; override;
function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint): Boolean; override;
(* Key input works only for windows.
*)
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure UTF8KeyPress(var UTF8Key: TUTF8Char); override;
procedure KeyUp(var Key: Word; Shift: TShiftState); override;
{$IFDEF MSWINDOWS}
procedure DoOnIMECancelComposition; override;
procedure DoOnIMECommitText(const aText : ustring; const replacement_range : PCefRange; relative_cursor_pos : integer); override;
procedure DoOnIMESetComposition(const aText : ustring; const underlines : TCefCompositionUnderlineDynArray; const replacement_range, selection_range : TCefRange); override;
{$ENDIF}
procedure CaptureChanged; override;
procedure DoOnCreated(Sender: TObject);
procedure DoOnClosed(Sender: TObject);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure CreateHandle; override;
procedure CloseBrowser(aForceClose: boolean);
procedure WaitForBrowserClosed;
function IsClosed: boolean;
procedure LoadURL(aURL: ustring);
//
published
property Chromium : TLazChromium read GetChromium;
property OnBrowserCreated : TNotifyEvent read FOnBrowserCreated write FOnBrowserCreated;
property OnBrowserClosed : TNotifyEvent read FOnBrowserClosed write FOnBrowserClosed;
property OnMouseDown: TBrowserMouseEvent read FOnMouseDown write FOnMouseDown;
property OnMouseUp: TBrowserMouseEvent read FOnMouseUp write FOnMouseUp;
end;
{$IFDEF FPC}
procedure Register;
{$ENDIF}
implementation
{ TLazarusOsrBrowserWindow }
procedure TLazarusOsrBrowserWindow.AsyncInvalidate(Data: PtrInt);
begin
Invalidate;
end;
procedure TLazarusOsrBrowserWindow.AsyncResize(Data: PtrInt);
begin
try
FResizeCS.Acquire;
if FResizing then
FPendingResize := True
else
if BufferIsResized then
Chromium.Invalidate(PET_VIEW)
else
begin
FResizing := True;
Chromium.WasResized;
end;
finally
FResizeCS.Release;
end;
end;
procedure TLazarusOsrBrowserWindow.SyncIMERangeChanged;
begin
ChangeCompositionRange(FSelectedRange, FDeviceBounds);
end;
procedure TLazarusOsrBrowserWindow.DoGetChromiumBeforePopup(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame; const targetUrl,
targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition;
userGesture: Boolean; const popupFeatures: TCefPopupFeatures;
var windowInfo: TCefWindowInfo; var client: ICefClient;
var settings: TCefBrowserSettings; var extra_info: ICefDictionaryValue;
var noJavascriptAccess: Boolean; var Result: Boolean);
begin
// For simplicity, this demo blocks all popup windows and new tabs
Result := (targetDisposition in [WOD_NEW_FOREGROUND_TAB, WOD_NEW_BACKGROUND_TAB, WOD_NEW_POPUP, WOD_NEW_WINDOW]);
end;
procedure TLazarusOsrBrowserWindow.DoGetChromiumPopupShow(Sender: TObject;
const browser: ICefBrowser; AShow: Boolean);
begin
if aShow then
FShowPopUp := True
else
begin
FShowPopUp := False;
FPopUpRect := rect(0, 0, 0, 0);
if (Chromium <> nil) then Chromium.Invalidate(PET_VIEW);
end;
end;
procedure TLazarusOsrBrowserWindow.DoGetChromiumPopupSize(Sender: TObject;
const browser: ICefBrowser; const rect: PCefRect);
begin
LogicalToDevice(rect^, ScreenScale);
FPopUpRect.Left := rect^.x;
FPopUpRect.Top := rect^.y;
FPopUpRect.Right := rect^.x + rect^.width - 1;
FPopUpRect.Bottom := rect^.y + rect^.height - 1;
end;
procedure TLazarusOsrBrowserWindow.DoGetChromiumTooltip(Sender: TObject;
const browser: ICefBrowser; var AText: ustring; out Result: Boolean);
begin
hint := aText;
ShowHint := (length(aText) > 0);
Result := True;
end;
procedure TLazarusOsrBrowserWindow.DoGetChromiumIMECompositionRangeChanged(
Sender: TObject; const browser: ICefBrowser; const selected_range: PCefRange;
character_boundsCount: NativeUInt; const character_bounds: PCefRect);
var
TempPRect : PCefRect;
i : NativeUInt;
TempScale : single;
begin
// TChromium.OnIMECompositionRangeChanged is triggered in a different thread
// and all functions using a IMM context need to be executed in the same
// thread, in this case the main thread. We need to save the parameters and
// send a message to the form to execute Panel1.ChangeCompositionRange in
// the main thread.
if (FDeviceBounds <> nil) then
begin
Finalize(FDeviceBounds);
FDeviceBounds := nil;
end;
FSelectedRange := selected_range^;
if (character_boundsCount > 0) then
begin
SetLength(FDeviceBounds, character_boundsCount);
i := 0;
TempPRect := character_bounds;
TempScale := ScreenScale;
while (i < character_boundsCount) do
begin
FDeviceBounds[i] := TempPRect^;
LogicalToDevice(FDeviceBounds[i], TempScale);
inc(TempPRect);
inc(i);
end;
end;
TThread.Synchronize(nil, @SyncIMERangeChanged);
end;
procedure TLazarusOsrBrowserWindow.DoGetChromiumCursorChange(Sender: TObject;
const browser: ICefBrowser; cursor_: TCefCursorHandle;
cursorType: TCefCursorType; const customCursorInfo: PCefCursorInfo;
var aResult: boolean);
begin
Cursor := CefCursorToWindowsCursor(cursorType);
aResult := True;
end;
procedure TLazarusOsrBrowserWindow.DoGetChromiumGetScreenInfo(Sender: TObject;
const browser: ICefBrowser; var screenInfo: TCefScreenInfo; out
Result: Boolean);
var
TempRect : TCEFRect;
TempScale : single;
begin
TempScale := ScreenScale;
TempRect.x := 0;
TempRect.y := 0;
TempRect.width := DeviceToLogical(Width, TempScale);
TempRect.height := DeviceToLogical(Height, TempScale);
screenInfo.device_scale_factor := TempScale;
screenInfo.depth := 0;
screenInfo.depth_per_component := 0;
screenInfo.is_monochrome := Ord(False);
screenInfo.rect := TempRect;
screenInfo.available_rect := TempRect;
Result := True;
end;
procedure TLazarusOsrBrowserWindow.DoGetChromiumGetScreenPoint(Sender: TObject;
const browser: ICefBrowser; viewX, viewY: Integer; var screenX,
screenY: Integer; out Result: Boolean);
var
TempScreenPt, TempViewPt : TPoint;
TempScale : single;
begin
TempScale := ScreenScale;
TempViewPt.x := LogicalToDevice(viewX, TempScale);
TempViewPt.y := LogicalToDevice(viewY, TempScale);
TempScreenPt := ClientToScreen(TempViewPt);
screenX := TempScreenPt.x;
screenY := TempScreenPt.y;
Result := True;
end;
procedure TLazarusOsrBrowserWindow.DoGetChromiumViewRect(Sender: TObject;
const browser: ICefBrowser; var rect: TCefRect);
var
TempScale : single;
begin
TempScale := ScreenScale;
rect.x := 0;
rect.y := 0;
rect.width := DeviceToLogical(Width, TempScale);
rect.height := DeviceToLogical(Height, TempScale);
end;
procedure TLazarusOsrBrowserWindow.DoChromiumPaint(Sender: TObject;
const browser: ICefBrowser; kind: TCefPaintElementType;
dirtyRectsCount: NativeUInt; const dirtyRects: PCefRectArray;
const ABuffer: Pointer; AWidth, AHeight: Integer);
var
src, dst: PByte;
i, j, TempLineSize, TempSrcOffset, TempDstOffset, SrcStride : Integer;
n : NativeUInt;
TempWidth, TempHeight: integer;
TempBufferBits : Pointer;
TempForcedResize : boolean;
TempBitmap : TBitmap;
TempSrcRect : TRect;
{$IFDEF DARWIN}
s: PByte;
ls: integer;
{$ENDIF}
begin
try
FResizeCS.Acquire;
TempForcedResize := False;
if BeginBufferDraw then
begin
if (kind = PET_POPUP) then
begin
if (FPopUpBitmap = nil) or
(aWidth <> FPopUpBitmap.Width) or
(aHeight <> FPopUpBitmap.Height) then
begin
if (FPopUpBitmap <> nil) then FPopUpBitmap.Free;
FPopUpBitmap := TBitmap.Create;
FPopUpBitmap.PixelFormat := pf32bit;
FPopUpBitmap.HandleType := bmDIB;
FPopUpBitmap.Width := aWidth;
FPopUpBitmap.Height := aHeight;
end;
TempBitmap := FPopUpBitmap;
TempBitmap.BeginUpdate;
TempWidth := FPopUpBitmap.Width;
TempHeight := FPopUpBitmap.Height;
end
else
begin
TempForcedResize := UpdateBufferDimensions(aWidth, aHeight) or not(BufferIsResized(False));
TempBitmap := Buffer;
TempBitmap.BeginUpdate;
TempWidth := BufferWidth;
TempHeight := BufferHeight;
end;
SrcStride := aWidth * SizeOf(TRGBQuad);
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) {$IFnDEF DARWIN}* SizeOf(TRGBQuad){$ENDIF};
if (TempLineSize > 0) then
begin
TempSrcOffset := ((dirtyRects^[n].y * aWidth) + dirtyRects^[n].x) * SizeOf(TRGBQuad);
TempDstOffset := (dirtyRects^[n].x * SizeOf(TRGBQuad));
src := @PByte(ABuffer)[TempSrcOffset];
i := 0;
j := min(dirtyRects^[n].height, TempHeight - dirtyRects^[n].y);
while (i < j) do
begin
TempBufferBits := TempBitmap.Scanline[dirtyRects^[n].y + i];
dst := @PByte(TempBufferBits)[TempDstOffset];
{$IFDEF DARWIN}
ls := TempLineSize;
s := src;
while ls > 0 do begin
PCardinal(dst)^ := (s[0] shl 24) or (s[1] shl 16) or (s[2] shl 8) or s[3];
inc(dst, 4);
inc(s, 4);
dec(ls);
end;
{$ELSE}
Move(src^, dst^, TempLineSize);
{$ENDIF}
Inc(src, SrcStride);
inc(i);
end;
end;
end;
inc(n);
end;
TempBitmap.EndUpdate;
if FShowPopup and (FPopUpBitmap <> nil) then
begin
TempSrcRect := Rect(0, 0,
min(FPopUpRect.Right - FPopUpRect.Left, FPopUpBitmap.Width),
min(FPopUpRect.Bottom - FPopUpRect.Top, FPopUpBitmap.Height));
BufferDraw(FPopUpBitmap, TempSrcRect, FPopUpRect);
end;
EndBufferDraw;
if HandleAllocated then
//PostMessage(Handle, CEF_PENDINGINVALIDATE, 0, 0);
Application.QueueAsyncCall(@AsyncInvalidate, 0);
if (kind = PET_VIEW) then
begin
if (TempForcedResize or FPendingResize) and
HandleAllocated then
Application.QueueAsyncCall(@AsyncResize, 0);
//PostMessage(Handle, CEF_PENDINGRESIZE, 0, 0);
FResizing := False;
FPendingResize := False;
end;
end;
finally
FResizeCS.Release;
end;
end;
function TLazarusOsrBrowserWindow.GetChromium: TLazChromium;
begin
Result := FChromium;
end;
function TLazarusOsrBrowserWindow.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 TLazarusOsrBrowserWindow.getKeyModifiers(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 (ssNum in Shift) then Result := Result or EVENTFLAG_NUM_LOCK_ON;
if (ssCaps in Shift) then Result := Result or EVENTFLAG_CAPS_LOCK_ON;
end;
function TLazarusOsrBrowserWindow.GetButton(Button: TMouseButton
): TCefMouseButtonType;
begin
case Button of
TMouseButton.mbRight : Result := MBT_RIGHT;
TMouseButton.mbMiddle : Result := MBT_MIDDLE;
else Result := MBT_LEFT;
end;
end;
procedure TLazarusOsrBrowserWindow.DoCreateBrowserAfterContext(Sender: TObject);
begin
FChromium.CreateBrowser(nil);
end;
procedure TLazarusOsrBrowserWindow.CreateHandle;
begin
inherited CreateHandle;
if not (csDesigning in ComponentState) then begin
if GlobalCEFApp is TCefLazApplication then
TCefLazApplication(GlobalCEFApp).AddContextInitializedHandler(@DoCreateBrowserAfterContext)
else
DoCreateBrowserAfterContext(nil);
end;
end;
procedure TLazarusOsrBrowserWindow.DestroyHandle;
begin
if (GlobalCEFApp = nil) or
(not FChromium.HasBrowser) or
(csDesigning in ComponentState)
then begin
inherited DestroyHandle;
exit;
end;
FChromium.CloseBrowser(True);
inherited DestroyHandle;
end;
procedure TLazarusOsrBrowserWindow.RealizeBounds;
begin
inherited RealizeBounds;
Chromium.NotifyMoveOrResizeStarted;
AsyncResize(0);
end;
procedure TLazarusOsrBrowserWindow.DoEnter;
begin
inherited DoEnter;
Chromium.SendFocusEvent(True);
end;
procedure TLazarusOsrBrowserWindow.DoExit;
begin
inherited DoExit;
Chromium.SendFocusEvent(False);
end;
procedure TLazarusOsrBrowserWindow.Click;
begin
inherited Click;
SetFocus;
end;
procedure TLazarusOsrBrowserWindow.MouseDown(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
TempEvent : TCefMouseEvent;
LastClickCount: integer;
IsHandled: Boolean;
begin
inherited MouseDown(Button, Shift, X, Y);
IsHandled := False;
if FOnMouseDown <> nil then
FOnMouseDown(Self, Button, Shift, X, Y, IsHandled);
if IsHandled then
exit;
SetFocus;
LastClickCount := 1;
if ssDouble in Shift then LastClickCount := 2
else if ssTriple in Shift then LastClickCount := 3
else if ssQuad in Shift then LastClickCount := 4;
TempEvent.x := X;
TempEvent.y := Y;
TempEvent.modifiers := getModifiers(Shift);
DeviceToLogical(TempEvent, ScreenScale);
Chromium.SendMouseClickEvent(@TempEvent, GetButton(Button), False, LastClickCount);
end;
procedure TLazarusOsrBrowserWindow.MouseUp(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
TempEvent : TCefMouseEvent;
LastClickCount: integer;
IsHandled: Boolean;
begin
inherited MouseUp(Button, Shift, X, Y);
IsHandled := False;
if FOnMouseDown <> nil then
FOnMouseDown(Self, Button, Shift, X, Y, IsHandled);
if IsHandled then
exit;
LastClickCount := 1;
if ssDouble in Shift then LastClickCount := 2
else if ssTriple in Shift then LastClickCount := 3
else if ssQuad in Shift then LastClickCount := 4;
TempEvent.x := X;
TempEvent.y := Y;
TempEvent.modifiers := getModifiers(Shift);
DeviceToLogical(TempEvent, ScreenScale);
Chromium.SendMouseClickEvent(@TempEvent, GetButton(Button), True, LastClickCount);
end;
procedure TLazarusOsrBrowserWindow.MouseMove(Shift: TShiftState; X, Y: Integer);
var
TempEvent : TCefMouseEvent;
begin
inherited MouseMove(Shift, X, Y);
TempEvent.x := x;
TempEvent.y := y;
TempEvent.modifiers := getModifiers(Shift);
DeviceToLogical(TempEvent, ScreenScale);
Chromium.SendMouseMoveEvent(@TempEvent, False);
end;
procedure TLazarusOsrBrowserWindow.MouseEnter;
var
TempEvent : TCefMouseEvent;
TempPoint : TPoint;
begin
inherited MouseEnter;
TempPoint := ScreenToClient(mouse.CursorPos);
TempEvent.x := TempPoint.x;
TempEvent.y := TempPoint.y;
TempEvent.modifiers := EVENTFLAG_NONE;
DeviceToLogical(TempEvent, ScreenScale);
Chromium.SendMouseMoveEvent(@TempEvent, False);
end;
procedure TLazarusOsrBrowserWindow.MouseLeave;
var
TempEvent : TCefMouseEvent;
TempPoint : TPoint;
TempTime : integer;
begin
inherited MouseLeave;
TempPoint := ScreenToClient(mouse.CursorPos);
TempPoint := ScreenToclient(TempPoint);
TempEvent.x := TempPoint.x;
TempEvent.y := TempPoint.y;
{$IFDEF MSWINDOWS}
TempEvent.modifiers := GetCefMouseModifiers;
{$ELSE}
TempEvent.modifiers := EVENTFLAG_NONE;
{$ENDIF}
DeviceToLogical(TempEvent, ScreenScale);
Chromium.SendMouseMoveEvent(@TempEvent, True);
end;
function TLazarusOsrBrowserWindow.DoMouseWheel(Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint): Boolean;
var
TempEvent : TCefMouseEvent;
begin
Result := inherited DoMouseWheel(Shift, WheelDelta, MousePos);
TempEvent.x := MousePos.x;
TempEvent.y := MousePos.y;
TempEvent.modifiers := getModifiers(Shift);
DeviceToLogical(TempEvent, ScreenScale);
{$IFDEF MSWINDOWS}
if CefIsKeyDown(VK_SHIFT) then
Chromium.SendMouseWheelEvent(@TempEvent, WheelDelta, 0)
else
{$ENDIF}
Chromium.SendMouseWheelEvent(@TempEvent, 0, WheelDelta);
end;
procedure TLazarusOsrBrowserWindow.KeyDown(var Key: Word; Shift: TShiftState);
var
TempKeyEvent : TCefKeyEvent;
begin
FLastKeyDown := Key;
if (Key <> 0) and (Chromium <> nil) 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);
Chromium.SendKeyEvent(@TempKeyEvent);
if (Key in [VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN, VK_TAB]) then Key := 0;
end;
inherited KeyDown(Key, Shift);
end;
procedure TLazarusOsrBrowserWindow.UTF8KeyPress(var UTF8Key: TUTF8Char);
var
TempKeyEvent : TCefKeyEvent;
TempString : UnicodeString;
begin
if Focused then
begin
TempString := UTF8Decode(UTF8Key);
if (length(TempString) > 0) then
begin
TempKeyEvent.kind := KEYEVENT_CHAR;
{$IFDEF MSWINDOWS}
TempKeyEvent.modifiers := GetCefKeyboardModifiers(WParam(TempString[1]), 0);
TempKeyEvent.windows_key_code := ord(TempString[1]);
{$ELSE}
TempKeyEvent.modifiers := getKeyModifiers(GetKeyShiftState);
TempKeyEvent.windows_key_code := FLastKeyDown;
{$ENDIF}
TempKeyEvent.native_key_code := 0;
TempKeyEvent.is_system_key := ord(False);
TempKeyEvent.character := TempString[1];
TempKeyEvent.unmodified_character := TempString[1];
TempKeyEvent.focus_on_editable_field := ord(False);
Chromium.SendKeyEvent(@TempKeyEvent);
end;
end;
inherited UTF8KeyPress(UTF8Key);
end;
procedure TLazarusOsrBrowserWindow.KeyUp(var Key: Word; Shift: TShiftState);
var
TempKeyEvent : TCefKeyEvent;
begin
if (Key <> 0) and (Chromium <> nil) 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);
Chromium.SendKeyEvent(@TempKeyEvent);
end;
inherited KeyUp(Key, Shift);
end;
{$IFDEF MSWINDOWS}
procedure TLazarusOsrBrowserWindow.DoOnIMECancelComposition;
begin
inherited DoOnIMECancelComposition;
Chromium.IMECancelComposition;
end;
procedure TLazarusOsrBrowserWindow.DoOnIMECommitText(const aText: ustring;
const replacement_range: PCefRange; relative_cursor_pos: integer);
begin
inherited DoOnIMECommitText(aText, replacement_range, relative_cursor_pos);
Chromium.IMECommitText(aText, replacement_range, relative_cursor_pos);;
end;
procedure TLazarusOsrBrowserWindow.DoOnIMESetComposition(const aText: ustring;
const underlines: TCefCompositionUnderlineDynArray; const replacement_range,
selection_range: TCefRange);
begin
inherited DoOnIMESetComposition(aText, underlines, replacement_range, selection_range);
Chromium.IMESetComposition(aText, underlines, @replacement_range, @selection_range);
end;
{$ENDIF}
procedure TLazarusOsrBrowserWindow.CaptureChanged;
begin
inherited CaptureChanged;
if (Chromium <> nil) then Chromium.SendCaptureLostEvent;
end;
procedure TLazarusOsrBrowserWindow.DoOnCreated(Sender: TObject);
begin
if Assigned(FOnBrowserCreated) then
FOnBrowserCreated(Self);
end;
procedure TLazarusOsrBrowserWindow.DoOnClosed(Sender: TObject);
begin
if (not(csDestroying in ComponentState)) and
Assigned(FOnBrowserClosed)
then
FOnBrowserClosed(Self);
end;
constructor TLazarusOsrBrowserWindow.Create(AOwner: TComponent);
begin
FResizeCS := TCriticalSection.Create;
FDeviceBounds := nil;
FSelectedRange.from := 0;
FSelectedRange.to_ := 0;
FChromium := TLazChromium.Create(Self);
FChromium.OnBrowserClosed := {$IFDEF FPC}@{$ENDIF}DoOnClosed;
FChromium.OnBrowserCreated := {$IFDEF FPC}@{$ENDIF}DoOnCreated;
FChromium.OnPaint := {$IFDEF FPC}@{$ENDIF}DoChromiumPaint;
FChromium.OnGetViewRect := {$IFDEF FPC}@{$ENDIF}DoGetChromiumViewRect;
FChromium.OnCursorChange := {$IFDEF FPC}@{$ENDIF}DoGetChromiumCursorChange;
FChromium.OnGetScreenPoint := {$IFDEF FPC}@{$ENDIF}DoGetChromiumGetScreenPoint;
FChromium.OnGetScreenInfo := {$IFDEF FPC}@{$ENDIF}DoGetChromiumGetScreenInfo;
FChromium.OnPopupShow := {$IFDEF FPC}@{$ENDIF}DoGetChromiumPopupShow;
FChromium.OnPopupSize := {$IFDEF FPC}@{$ENDIF}DoGetChromiumPopupSize;
FChromium.OnTooltip := {$IFDEF FPC}@{$ENDIF}DoGetChromiumTooltip;
FChromium.OnBeforePopup := {$IFDEF FPC}@{$ENDIF}DoGetChromiumBeforePopup;
FChromium.OnIMECompositionRangeChanged := @DoGetChromiumIMECompositionRangeChanged;
inherited Create(AOwner);
CopyOriginalBuffer := true;
end;
destructor TLazarusOsrBrowserWindow.Destroy;
begin
inherited Destroy;
FreeAndNil(FResizeCS);
if (FDeviceBounds <> nil) then
begin
Finalize(FDeviceBounds);
FDeviceBounds := nil;
end;
end;
procedure TLazarusOsrBrowserWindow.CloseBrowser(aForceClose: boolean);
begin
FChromium.CloseBrowser(aForceClose);
end;
procedure TLazarusOsrBrowserWindow.WaitForBrowserClosed;
begin
if not FChromium.HasBrowser then
exit;
FChromium.CloseBrowser(True);
while FChromium.HasBrowser do begin
Application.ProcessMessages;
if GlobalCEFApp.ExternalMessagePump then
GlobalCEFApp.DoMessageLoopWork;
sleep(5);
end;
// TODO : sent closed?
end;
function TLazarusOsrBrowserWindow.IsClosed: boolean;
begin
Result := not FChromium.HasBrowser;
end;
procedure TLazarusOsrBrowserWindow.LoadURL(aURL: ustring);
begin
FChromium.LoadURL(aURL);
end;
{$IFDEF FPC}
procedure Register;
begin
// {$I res/tlazarusosrbrowserwindow.lrs}
RegisterComponents('Chromium', [TLazarusOsrBrowserWindow]);
end;
{$ENDIF}
end.

View File

@ -47,7 +47,8 @@ uses
LResources,
{$ENDIF}
uCEFApplication, uCEFChromiumWindow, uCEFTypes, uCEFInterfaces, uCEFChromium,
uCEFLinkedWinControlBase, Forms, ExtCtrls, Classes, sysutils;
uCEFLinkedWinControlBase, uCEFLazApplication, uCEFBrowserViewComponent, Forms,
ExtCtrls, Controls, Classes, sysutils;
type
@ -56,29 +57,80 @@ type
only close once that event was finished.
*)
{ TLazChromium }
TLazChromium = class(TChromium)
private type
TLazChromiumState = (csNoBrowser, csCreatingBrowser, csHasBrowser, csClosingBrowser, csCloseAfterCreate);
private
FState : TLazChromiumState;
FOnBrowserClosed : TNotifyEvent;
FOnBrowserCreated : TNotifyEvent;
FLoadUrl, FFrameName : ustring;
function GetIsClosing: Boolean;
protected
function GetHasBrowser : boolean; reintroduce;
procedure doOnBeforeClose(const ABrowser: ICefBrowser); override;
procedure doOnAfterCreated(const ABrowser: ICefBrowser); override;
procedure DoCreated(Data: PtrInt);
procedure DoOnClosed(Data: PtrInt);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function CreateBrowser(const aBrowserParent: TWinControl = nil;
const aWindowName: ustring = ''; const aContext: ICefRequestContext =
nil; const aExtraInfo: ICefDictionaryValue = nil): boolean; overload; override;
function CreateBrowser(aParentHandle: TCefWindowHandle;
aParentRect: TRect; const aWindowName: ustring = '';
const aContext: ICefRequestContext = nil;
const aExtraInfo: ICefDictionaryValue = nil): boolean; overload; override;
procedure CreateBrowser(const aWindowName: ustring); overload; override;
function CreateBrowser(const aURL: ustring;
const aBrowserViewComp: TCEFBrowserViewComponent;
const aContext: ICefRequestContext = nil;
const aExtraInfo: ICefDictionaryValue = nil): boolean; overload; override;
// CloseBrowser will work, even if the browser is still in creation, and Initialized is still false
procedure CloseBrowser(aForceClose: boolean); reintroduce;
// LoadURL will work, even if the browser is still in creation, and Initialized is still false
procedure LoadURL(const aURL: ustring; const aFrameName: ustring = ''); overload;
property HasBrowser: Boolean read GetHasBrowser; // Includes browser in creation
property IsClosing : Boolean read GetIsClosing;
(* - Events to be called in main thread
- OnBrowserCreated: the parent event may be called when procedure Initialized is still false.
- OnBrowserCreated: may not be called, if the CloseBrowser has already been called
*)
property OnBrowserCreated : TNotifyEvent read FOnBrowserCreated write FOnBrowserCreated;
property OnBrowserClosed : TNotifyEvent read FOnBrowserClosed write FOnBrowserClosed;
end;
TLazarusBrowserWindow = class;
{ TChromiumWrapper }
TChromiumWrapper = class
protected type
TWrapperChromiumState = (csNoBrowser, csCreatingBrowser, csHasBrowser, csClosingBrowser, csCloseAfterCreate);
TWrapperState = (wsNone, wsWaitingForClose, wsSentCloseEventAfterWait, wsDestroyAfterWait);
protected
FChromium : TChromium;
FChromiumState : TWrapperChromiumState;
FChromium : TLazChromium;
FWrapperState : TWrapperState;
FBrowserWindow : TLazarusBrowserWindow;
FLoadUrl : ustring;
procedure WebBrowser_OnAfterCreated(Sender: TObject; const browser: ICefBrowser);
procedure WebBrowser_OnClose(Sender: TObject; const browser: ICefBrowser; var aAction : TCefCloseBrowserAction); reintroduce;
procedure WebBrowser_OnBeforeClose(Sender: TObject; const browser: ICefBrowser); reintroduce;
procedure DoOnAfterCreated(Sender: TObject);
procedure DoOnBeforeClose(Sender: TObject);
procedure BrowserThread_OnClose(Sender: TObject; const browser: ICefBrowser; var aAction : TCefCloseBrowserAction);
{$IFDEF FPC}
procedure WebBrowser_OnGotFocus(Sender: TObject; const browser: ICefBrowser);
procedure BrowserThread_OnGotFocus(Sender: TObject; const browser: ICefBrowser);
{$ENDIF}
procedure DoCreated(Data: PtrInt);
procedure MaybeDestroy;
public
@ -95,6 +147,8 @@ type
It is the callers responsibility to take any necessary precaution.
*)
procedure WaitForBrowserClosed;
property Chromium: TLazChromium read FChromium;
end;
{ TLazarusBrowserWindow }
@ -112,6 +166,7 @@ type
FTimer : TTimer;
procedure DoCreateBrowser(Sender: TObject);
procedure DoCreateBrowserAfterContext(Sender: TObject);
protected
function GetChromium: TChromium; override;
procedure DestroyHandle; override;
@ -148,11 +203,29 @@ procedure Register;
implementation
{ TChromiumWrapper }
{ TLazChromium }
procedure TChromiumWrapper.WebBrowser_OnAfterCreated(Sender: TObject;
const browser: ICefBrowser);
function TLazChromium.GetIsClosing: Boolean;
begin
Result := FState in [csCloseAfterCreate, csClosingBrowser];
end;
function TLazChromium.GetHasBrowser: boolean;
begin
Result := (FState <> csNoBrowser) or (inherited GetHasBrowser);
end;
procedure TLazChromium.doOnBeforeClose(const ABrowser: ICefBrowser);
begin
inherited doOnBeforeClose(ABrowser);
FState := csNoBrowser;
Application.QueueAsyncCall(@DoOnClosed, 0);
end;
procedure TLazChromium.doOnAfterCreated(const ABrowser: ICefBrowser);
begin
inherited doOnAfterCreated(ABrowser);
(* We may still be in Chromium.CreateBrowserSync
In that case initialization will happen after this event,
but before the call to CreateBrowser returns
@ -160,7 +233,127 @@ begin
Application.QueueAsyncCall(@DoCreated, 0);
end;
procedure TChromiumWrapper.WebBrowser_OnClose(Sender: TObject;
procedure TLazChromium.DoCreated(Data: PtrInt);
var
u, f: ustring;
begin
// Any other state, means this is a late async call
case FState of
csCreatingBrowser: begin
FState := csHasBrowser;
if FLoadUrl <> '' then begin
u := FLoadUrl;
f := FFrameName;
LoadURL(u, f);
end;
if (FOnBrowserCreated <> nil) then
FOnBrowserCreated(Self);
end;
csCloseAfterCreate: begin
FState := csHasBrowser;
CloseBrowser(True);
end;
end;
end;
procedure TLazChromium.DoOnClosed(Data: PtrInt);
begin
if (FOnBrowserClosed <> nil) then
FOnBrowserClosed(Self);
end;
constructor TLazChromium.Create(AOwner: TComponent);
begin
FState := csNoBrowser;
inherited Create(AOwner);
end;
destructor TLazChromium.Destroy;
begin
inherited Destroy;
Application.RemoveAsyncCalls(Self);
end;
function TLazChromium.CreateBrowser(const aBrowserParent: TWinControl;
const aWindowName: ustring; const aContext: ICefRequestContext;
const aExtraInfo: ICefDictionaryValue): boolean;
begin
FState := csCreatingBrowser;
Result := inherited CreateBrowser(aBrowserParent, aWindowName, aContext,
aExtraInfo);
if Initialized then
DoCreated(0);
end;
function TLazChromium.CreateBrowser(aParentHandle: TCefWindowHandle;
aParentRect: TRect; const aWindowName: ustring;
const aContext: ICefRequestContext; const aExtraInfo: ICefDictionaryValue): boolean;
begin
FState := csCreatingBrowser;
Result := inherited CreateBrowser(aParentHandle, aParentRect, aWindowName,
aContext, aExtraInfo);
if Initialized then
DoCreated(0);
end;
procedure TLazChromium.CreateBrowser(const aWindowName: ustring);
begin
FState := csCreatingBrowser;
inherited CreateBrowser(aWindowName);
if Initialized then
DoCreated(0);
end;
function TLazChromium.CreateBrowser(const aURL: ustring;
const aBrowserViewComp: TCEFBrowserViewComponent;
const aContext: ICefRequestContext; const aExtraInfo: ICefDictionaryValue
): boolean;
begin
FState := csCreatingBrowser;
Result := inherited CreateBrowser(aURL, aBrowserViewComp, aContext, aExtraInfo);
if Initialized then
DoCreated(0);
end;
procedure TLazChromium.CloseBrowser(aForceClose: boolean);
begin
if FState = csCreatingBrowser then begin
FState := csCloseAfterCreate;
exit;
end
else
if FState in [csHasBrowser] then
begin
FState := csClosingBrowser;
inherited CloseBrowser(aForceClose);
end;
end;
procedure TLazChromium.LoadURL(const aURL: ustring; const aFrameName: ustring);
begin
FLoadUrl := '';
FFrameName := '';
if FState = csHasBrowser then
begin
inherited LoadURL(aURL, aFrameName);
end
else
begin
FLoadUrl := aURL;
FFrameName := aFrameName;
end;
end;
{ TChromiumWrapper }
procedure TChromiumWrapper.DoOnAfterCreated(Sender: TObject);
begin
if (FBrowserWindow <> nil) then
FBrowserWindow.DoOnCreated;
end;
procedure TChromiumWrapper.BrowserThread_OnClose(Sender: TObject;
const browser: ICefBrowser; var aAction: TCefCloseBrowserAction);
begin
(* FBrowserWindow should always be <> nil
@ -173,46 +366,23 @@ begin
aAction := cbaClose;
end;
procedure TChromiumWrapper.WebBrowser_OnBeforeClose(Sender: TObject;
const browser: ICefBrowser);
procedure TChromiumWrapper.DoOnBeforeClose(Sender: TObject);
begin
FChromiumState := csNoBrowser;
if (FBrowserWindow <> nil) then begin
if FWrapperState = wsWaitingForClose then
FWrapperState := wsSentCloseEventAfterWait
else
Application.QueueAsyncCall(@FBrowserWindow.DoOnClosed, 0);
FBrowserWindow.DoOnClosed(0);
end;
end;
procedure TChromiumWrapper.WebBrowser_OnGotFocus(Sender: TObject;
procedure TChromiumWrapper.BrowserThread_OnGotFocus(Sender: TObject;
const browser: ICefBrowser);
begin
if (FBrowserWindow <> nil) then
Application.QueueAsyncCall(@FBrowserWindow.DoOnFocus, 0);
end;
procedure TChromiumWrapper.DoCreated(Data: PtrInt);
begin
// Any other state, means this is a late async call
case FChromiumState of
csCreatingBrowser: begin
FChromiumState := csHasBrowser;
if FLoadUrl <> '' then
LoadURL(FLoadUrl);
if (FBrowserWindow <> nil) then
FBrowserWindow.DoOnCreated;
end;
csCloseAfterCreate: begin
FChromiumState := csHasBrowser;
CloseBrowser(True);
end;
end;
end;
procedure TChromiumWrapper.MaybeDestroy;
begin
CloseBrowser(True);
@ -221,25 +391,24 @@ begin
if FWrapperState in [wsWaitingForClose, wsSentCloseEventAfterWait] then
FWrapperState := wsDestroyAfterWait;
if FChromiumState = csNoBrowser then
if not FChromium.HasBrowser then
Destroy;
end;
constructor TChromiumWrapper.Create(AOwner: TLazarusBrowserWindow);
begin
FBrowserWindow := AOwner;
FChromiumState := csNoBrowser;
FWrapperState := wsNone;
if not(csDesigning in AOwner.ComponentState) then
begin
FChromium := TChromium.Create(nil);
FChromium.OnClose := {$IFDEF FPC}@{$ENDIF}WebBrowser_OnClose;
FChromium.OnBeforeClose := {$IFDEF FPC}@{$ENDIF}WebBrowser_OnBeforeClose;
FChromium.OnAfterCreated := {$IFDEF FPC}@{$ENDIF}WebBrowser_OnAfterCreated;
FChromium := TLazChromium.Create(nil);
FChromium.OnClose := {$IFDEF FPC}@{$ENDIF}BrowserThread_OnClose;
FChromium.OnBrowserClosed := {$IFDEF FPC}@{$ENDIF}DoOnBeforeClose;
FChromium.OnBrowserCreated := {$IFDEF FPC}@{$ENDIF}DoOnAfterCreated;
{$IFDEF LINUX}
// This is a workaround for the CEF issue #2026. Read below for more info.
FChromium.OnGotFocus := {$IFDEF FPC}@{$ENDIF}WebBrowser_OnGotFocus;
FChromium.OnGotFocus := {$IFDEF FPC}@{$ENDIF}BrowserThread_OnGotFocus;
{$ENDIF}
end;
@ -248,8 +417,7 @@ end;
destructor TChromiumWrapper.Destroy;
begin
if FChromiumState <> csNoBrowser then
if FChromium.HasBrowser then
WaitForBrowserClosed;
inherited Destroy;
@ -259,56 +427,35 @@ end;
function TChromiumWrapper.CreateBrowser: boolean;
begin
if FChromiumState <> csNoBrowser then
if FChromium.HasBrowser then
exit(False);
FChromiumState := csCreatingBrowser;
Result := FChromium.CreateBrowser(FBrowserWindow, '');
if Result then begin
if FChromium.Initialized then
DoCreated(0);
end
else begin
FChromiumState := csNoBrowser;
end;
end;
procedure TChromiumWrapper.LoadURL(aURL: ustring);
begin
FLoadUrl := '';
if FChromiumState = csHasBrowser then
FChromium.LoadURL(aURL)
else
FLoadUrl := aURL;
FChromium.LoadURL(aURL);
end;
procedure TChromiumWrapper.CloseBrowser(aForceClose: boolean);
begin
if FChromiumState = csCreatingBrowser then begin
FChromiumState := csCloseAfterCreate;
end
else
if FChromiumState in [csHasBrowser] then
begin
FChromiumState := csClosingBrowser;
FChromium.CloseBrowser(aForceClose);
end;
FChromium.CloseBrowser(aForceClose);
end;
function TChromiumWrapper.IsClosed: boolean;
begin
Result := FChromiumState = csNoBrowser;
Result := not FChromium.HasBrowser;
end;
procedure TChromiumWrapper.WaitForBrowserClosed;
begin
if FChromiumState = csNoBrowser then
if not FChromium.HasBrowser then
exit;
if FChromiumState <> csClosingBrowser then
CloseBrowser(True);
FChromium.CloseBrowser(True);
FWrapperState := wsWaitingForClose;
while FChromiumState <> csNoBrowser do begin
while FChromium.HasBrowser do begin
Application.ProcessMessages;
if GlobalCEFApp.ExternalMessagePump then
GlobalCEFApp.DoMessageLoopWork;
@ -330,15 +477,15 @@ end;
procedure TLazarusBrowserWindow.DoCreateBrowser(Sender: TObject);
begin
FTimer.Enabled := False;
if FTimer <> nil then
FTimer.Enabled := False;
case FChromiumWrapper.FChromiumState of
csCreatingBrowser, csHasBrowser: begin
if FChromiumWrapper.Chromium.HasBrowser then begin
if not FChromiumWrapper.Chromium.IsClosing then begin
FreeAndNil(FTimer);
exit;
end;
csClosingBrowser, csCloseAfterCreate: begin
// need new wrapper // This could prevent an OnBrowserClosed event
end
else begin
FChromiumWrapper.MaybeDestroy;
FChromiumWrapper := TChromiumWrapper.Create(Self);
end;
@ -351,11 +498,26 @@ begin
if GlobalCEFApp.ExternalMessagePump then
GlobalCEFApp.DoMessageLoopWork;
if FTimer = nil then
FTimer := TTimer.Create(Self);
FTimer.OnTimer := @DoCreateBrowser;
FTimer.Interval := 100;
FTimer.Enabled := True;
end;
end;
procedure TLazarusBrowserWindow.DoCreateBrowserAfterContext(Sender: TObject);
begin
{$IFnDEF WINDOWS}
FTimer := TTimer.Create(Self);
FTimer.Interval := 20;
FTimer.OnTimer := @DoCreateBrowser;
FTimer.Enabled := True;
{$ELSE}
DoCreateBrowser(nil);
{$ENDIF}
end;
function TLazarusBrowserWindow.GetChromium: TChromium;
begin
Result := FChromiumWrapper.FChromium;
@ -368,10 +530,11 @@ begin
(* On Windows we can create the browser immediately.
But at least on Linux, we need to wait
*)
FTimer := TTimer.Create(Self);
FTimer.Interval := 20;
FTimer.OnTimer := @DoCreateBrowser;
FTimer.Enabled := True;
if GlobalCEFApp is TCefLazApplication then
TCefLazApplication(GlobalCEFApp).AddContextInitializedHandler(@DoCreateBrowserAfterContext)
else
DoCreateBrowserAfterContext(nil);
end;
end;
@ -381,7 +544,7 @@ begin
FreeAndNil(FTimer);
if (GlobalCEFApp = nil) or
(FChromiumWrapper.FChromiumState = csNoBrowser) or
(not FChromiumWrapper.Chromium.HasBrowser) or
(csDesigning in ComponentState)
then begin
inherited DestroyHandle;