diff --git a/demos/Lazarus_any_OS/BrowserWindow/README.txt b/demos/Lazarus_any_OS/BrowserWindow/README.txt
index 5f7d3918..99a23a57 100644
--- a/demos/Lazarus_any_OS/BrowserWindow/README.txt
+++ b/demos/Lazarus_any_OS/BrowserWindow/README.txt
@@ -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
diff --git a/demos/Lazarus_any_OS/BrowserWindow/globalcefapplication.pas b/demos/Lazarus_any_OS/BrowserWindow/globalcefapplication.pas
index 4e97ab04..64a101b3 100644
--- a/demos/Lazarus_any_OS/BrowserWindow/globalcefapplication.pas
+++ b/demos/Lazarus_any_OS/BrowserWindow/globalcefapplication.pas
@@ -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;
diff --git a/demos/Lazarus_any_OS/BrowserWindowDom/AppHelper/00-Delete.bat b/demos/Lazarus_any_OS/BrowserWindowDom/AppHelper/00-Delete.bat
new file mode 100644
index 00000000..0b5ba5c8
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowDom/AppHelper/00-Delete.bat
@@ -0,0 +1,2 @@
+rmdir /S /Q lib
+rmdir /S /Q backup
diff --git a/demos/Lazarus_any_OS/BrowserWindowDom/AppHelper/AppHelper.ico b/demos/Lazarus_any_OS/BrowserWindowDom/AppHelper/AppHelper.ico
new file mode 100644
index 00000000..25c186a5
Binary files /dev/null and b/demos/Lazarus_any_OS/BrowserWindowDom/AppHelper/AppHelper.ico differ
diff --git a/demos/Lazarus_any_OS/BrowserWindowDom/AppHelper/AppHelper.lpi b/demos/Lazarus_any_OS/BrowserWindowDom/AppHelper/AppHelper.lpi
new file mode 100644
index 00000000..d948d88f
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowDom/AppHelper/AppHelper.lpi
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowDom/AppHelper/AppHelper.lpr b/demos/Lazarus_any_OS/BrowserWindowDom/AppHelper/AppHelper.lpr
new file mode 100644
index 00000000..d0d2e185
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowDom/AppHelper/AppHelper.lpr
@@ -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
+ * 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.
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowDom/AppHelper/AppHelper.res b/demos/Lazarus_any_OS/BrowserWindowDom/AppHelper/AppHelper.res
new file mode 100644
index 00000000..bcdc0667
Binary files /dev/null and b/demos/Lazarus_any_OS/BrowserWindowDom/AppHelper/AppHelper.res differ
diff --git a/demos/Lazarus_any_OS/BrowserWindowDom/AppHelper/cef.inc b/demos/Lazarus_any_OS/BrowserWindowDom/AppHelper/cef.inc
new file mode 100644
index 00000000..c8ce967e
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowDom/AppHelper/cef.inc
@@ -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
+ * 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}
diff --git a/demos/Lazarus_any_OS/BrowserWindowDom/AppHelper/create_mac_helper_apps.sh b/demos/Lazarus_any_OS/BrowserWindowDom/AppHelper/create_mac_helper_apps.sh
new file mode 100755
index 00000000..eb60983c
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowDom/AppHelper/create_mac_helper_apps.sh
@@ -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"
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowDom/BrowserWindowDom.ico b/demos/Lazarus_any_OS/BrowserWindowDom/BrowserWindowDom.ico
new file mode 100644
index 00000000..0341321b
Binary files /dev/null and b/demos/Lazarus_any_OS/BrowserWindowDom/BrowserWindowDom.ico differ
diff --git a/demos/Lazarus_any_OS/BrowserWindowDom/BrowserWindowDom.lpi b/demos/Lazarus_any_OS/BrowserWindowDom/BrowserWindowDom.lpi
new file mode 100644
index 00000000..3ec9b24d
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowDom/BrowserWindowDom.lpi
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowDom/BrowserWindowDom.lpr b/demos/Lazarus_any_OS/BrowserWindowDom/BrowserWindowDom.lpr
new file mode 100644
index 00000000..3e8fa958
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowDom/BrowserWindowDom.lpr
@@ -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
+ * 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.
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowDom/BrowserWindowDom.res b/demos/Lazarus_any_OS/BrowserWindowDom/BrowserWindowDom.res
new file mode 100644
index 00000000..bec39b4a
Binary files /dev/null and b/demos/Lazarus_any_OS/BrowserWindowDom/BrowserWindowDom.res differ
diff --git a/demos/Lazarus_any_OS/BrowserWindowDom/README.txt b/demos/Lazarus_any_OS/BrowserWindowDom/README.txt
new file mode 100644
index 00000000..a2ae5a16
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowDom/README.txt
@@ -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
+
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowDom/cef.inc b/demos/Lazarus_any_OS/BrowserWindowDom/cef.inc
new file mode 100644
index 00000000..c8ce967e
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowDom/cef.inc
@@ -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
+ * 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}
diff --git a/demos/Lazarus_any_OS/BrowserWindowDom/create_mac_helper.sh b/demos/Lazarus_any_OS/BrowserWindowDom/create_mac_helper.sh
new file mode 100755
index 00000000..49927781
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowDom/create_mac_helper.sh
@@ -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//\n NSPrincipalClass<\/key>\n TCrCocoaApplication<\/string>/" ../../../bin/BrowserWindowDom.app/Contents/Info.plist
+fi
+
+cd "$CDIR"
diff --git a/demos/Lazarus_any_OS/BrowserWindowDom/globalcefapplication.pas b/demos/Lazarus_any_OS/BrowserWindowDom/globalcefapplication.pas
new file mode 100644
index 00000000..6302bb21
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowDom/globalcefapplication.pas
@@ -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
+ * 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.
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowDom/initsubprocess.pas b/demos/Lazarus_any_OS/BrowserWindowDom/initsubprocess.pas
new file mode 100644
index 00000000..512c43e8
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowDom/initsubprocess.pas
@@ -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
+ * 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.
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowDom/uBrowserWindowDom.lfm b/demos/Lazarus_any_OS/BrowserWindowDom/uBrowserWindowDom.lfm
new file mode 100644
index 00000000..09e1ab2d
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowDom/uBrowserWindowDom.lfm
@@ -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
diff --git a/demos/Lazarus_any_OS/BrowserWindowDom/uBrowserWindowDom.pas b/demos/Lazarus_any_OS/BrowserWindowDom/uBrowserWindowDom.pas
new file mode 100644
index 00000000..8dd1e314
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowDom/uBrowserWindowDom.pas
@@ -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
+ * 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.
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowDom/uHelperProcessDom.pas b/demos/Lazarus_any_OS/BrowserWindowDom/uHelperProcessDom.pas
new file mode 100644
index 00000000..0583260c
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowDom/uHelperProcessDom.pas
@@ -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
+ * 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.
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowEx/BrowserWindowEx.ico b/demos/Lazarus_any_OS/BrowserWindowEx/BrowserWindowEx.ico
new file mode 100644
index 00000000..0341321b
Binary files /dev/null and b/demos/Lazarus_any_OS/BrowserWindowEx/BrowserWindowEx.ico differ
diff --git a/demos/Lazarus_any_OS/BrowserWindowEx/BrowserWindowEx.lpi b/demos/Lazarus_any_OS/BrowserWindowEx/BrowserWindowEx.lpi
new file mode 100644
index 00000000..cbecfe3f
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowEx/BrowserWindowEx.lpi
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowEx/BrowserWindowEx.lpr b/demos/Lazarus_any_OS/BrowserWindowEx/BrowserWindowEx.lpr
new file mode 100644
index 00000000..5d93ede8
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowEx/BrowserWindowEx.lpr
@@ -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
+ * 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.
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowEx/BrowserWindowEx.res b/demos/Lazarus_any_OS/BrowserWindowEx/BrowserWindowEx.res
new file mode 100644
index 00000000..bec39b4a
Binary files /dev/null and b/demos/Lazarus_any_OS/BrowserWindowEx/BrowserWindowEx.res differ
diff --git a/demos/Lazarus_any_OS/BrowserWindowEx/README.txt b/demos/Lazarus_any_OS/BrowserWindowEx/README.txt
new file mode 100644
index 00000000..86f182ca
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowEx/README.txt
@@ -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
+
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowEx/cef.inc b/demos/Lazarus_any_OS/BrowserWindowEx/cef.inc
new file mode 100644
index 00000000..c8ce967e
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowEx/cef.inc
@@ -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
+ * 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}
diff --git a/demos/Lazarus_any_OS/BrowserWindowEx/create_mac_helper.sh b/demos/Lazarus_any_OS/BrowserWindowEx/create_mac_helper.sh
new file mode 100644
index 00000000..290132e0
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowEx/create_mac_helper.sh
@@ -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//\n NSPrincipalClass<\/key>\n TCrCocoaApplication<\/string>/" ../../../bin/BrowserWindowEx.app/Contents/Info.plist
+fi
+
+cd "$CDIR"
diff --git a/demos/Lazarus_any_OS/BrowserWindowEx/globalcefapplication.pas b/demos/Lazarus_any_OS/BrowserWindowEx/globalcefapplication.pas
new file mode 100644
index 00000000..239db909
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowEx/globalcefapplication.pas
@@ -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
+ * 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.
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowEx/initsubprocess.pas b/demos/Lazarus_any_OS/BrowserWindowEx/initsubprocess.pas
new file mode 100644
index 00000000..512c43e8
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowEx/initsubprocess.pas
@@ -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
+ * 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.
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowEx/uBrowserWindowEx.lfm b/demos/Lazarus_any_OS/BrowserWindowEx/uBrowserWindowEx.lfm
new file mode 100644
index 00000000..4ce25b65
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowEx/uBrowserWindowEx.lfm
@@ -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
diff --git a/demos/Lazarus_any_OS/BrowserWindowEx/uBrowserWindowEx.pas b/demos/Lazarus_any_OS/BrowserWindowEx/uBrowserWindowEx.pas
new file mode 100644
index 00000000..c6007c1a
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowEx/uBrowserWindowEx.pas
@@ -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
+ * 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.
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowOsrDom/AppHelper/00-Delete.bat b/demos/Lazarus_any_OS/BrowserWindowOsrDom/AppHelper/00-Delete.bat
new file mode 100644
index 00000000..0b5ba5c8
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowOsrDom/AppHelper/00-Delete.bat
@@ -0,0 +1,2 @@
+rmdir /S /Q lib
+rmdir /S /Q backup
diff --git a/demos/Lazarus_any_OS/BrowserWindowOsrDom/AppHelper/AppHelper.ico b/demos/Lazarus_any_OS/BrowserWindowOsrDom/AppHelper/AppHelper.ico
new file mode 100644
index 00000000..25c186a5
Binary files /dev/null and b/demos/Lazarus_any_OS/BrowserWindowOsrDom/AppHelper/AppHelper.ico differ
diff --git a/demos/Lazarus_any_OS/BrowserWindowOsrDom/AppHelper/AppHelper.lpi b/demos/Lazarus_any_OS/BrowserWindowOsrDom/AppHelper/AppHelper.lpi
new file mode 100644
index 00000000..d948d88f
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowOsrDom/AppHelper/AppHelper.lpi
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowOsrDom/AppHelper/AppHelper.lpr b/demos/Lazarus_any_OS/BrowserWindowOsrDom/AppHelper/AppHelper.lpr
new file mode 100644
index 00000000..d0d2e185
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowOsrDom/AppHelper/AppHelper.lpr
@@ -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
+ * 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.
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowOsrDom/AppHelper/AppHelper.res b/demos/Lazarus_any_OS/BrowserWindowOsrDom/AppHelper/AppHelper.res
new file mode 100644
index 00000000..bcdc0667
Binary files /dev/null and b/demos/Lazarus_any_OS/BrowserWindowOsrDom/AppHelper/AppHelper.res differ
diff --git a/demos/Lazarus_any_OS/BrowserWindowOsrDom/AppHelper/cef.inc b/demos/Lazarus_any_OS/BrowserWindowOsrDom/AppHelper/cef.inc
new file mode 100644
index 00000000..c8ce967e
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowOsrDom/AppHelper/cef.inc
@@ -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
+ * 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}
diff --git a/demos/Lazarus_any_OS/BrowserWindowOsrDom/AppHelper/create_mac_helper_apps.sh b/demos/Lazarus_any_OS/BrowserWindowOsrDom/AppHelper/create_mac_helper_apps.sh
new file mode 100755
index 00000000..eb60983c
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowOsrDom/AppHelper/create_mac_helper_apps.sh
@@ -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"
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowOsrDom/BrowserWindowOsrDom.ico b/demos/Lazarus_any_OS/BrowserWindowOsrDom/BrowserWindowOsrDom.ico
new file mode 100644
index 00000000..0341321b
Binary files /dev/null and b/demos/Lazarus_any_OS/BrowserWindowOsrDom/BrowserWindowOsrDom.ico differ
diff --git a/demos/Lazarus_any_OS/BrowserWindowOsrDom/BrowserWindowOsrDom.lpi b/demos/Lazarus_any_OS/BrowserWindowOsrDom/BrowserWindowOsrDom.lpi
new file mode 100644
index 00000000..b7441b66
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowOsrDom/BrowserWindowOsrDom.lpi
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowOsrDom/BrowserWindowOsrDom.pas b/demos/Lazarus_any_OS/BrowserWindowOsrDom/BrowserWindowOsrDom.pas
new file mode 100644
index 00000000..83cde90b
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowOsrDom/BrowserWindowOsrDom.pas
@@ -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
+ * 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.
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowOsrDom/BrowserWindowOsrDom.res b/demos/Lazarus_any_OS/BrowserWindowOsrDom/BrowserWindowOsrDom.res
new file mode 100644
index 00000000..bec39b4a
Binary files /dev/null and b/demos/Lazarus_any_OS/BrowserWindowOsrDom/BrowserWindowOsrDom.res differ
diff --git a/demos/Lazarus_any_OS/BrowserWindowOsrDom/README.txt b/demos/Lazarus_any_OS/BrowserWindowOsrDom/README.txt
new file mode 100644
index 00000000..38409acc
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowOsrDom/README.txt
@@ -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
+
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowOsrDom/cef.inc b/demos/Lazarus_any_OS/BrowserWindowOsrDom/cef.inc
new file mode 100644
index 00000000..c8ce967e
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowOsrDom/cef.inc
@@ -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
+ * 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}
diff --git a/demos/Lazarus_any_OS/BrowserWindowOsrDom/create_mac_helper.sh b/demos/Lazarus_any_OS/BrowserWindowOsrDom/create_mac_helper.sh
new file mode 100755
index 00000000..fc4e694f
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowOsrDom/create_mac_helper.sh
@@ -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//\n NSPrincipalClass<\/key>\n TCrCocoaApplication<\/string>/" ../../../bin/BrowserWindowOsrDom.app/Contents/Info.plist
+fi
+
+cd "$CDIR"
diff --git a/demos/Lazarus_any_OS/BrowserWindowOsrDom/globalcefapplication.pas b/demos/Lazarus_any_OS/BrowserWindowOsrDom/globalcefapplication.pas
new file mode 100644
index 00000000..46db6401
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowOsrDom/globalcefapplication.pas
@@ -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
+ * 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.
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowOsrDom/initsubprocess.pas b/demos/Lazarus_any_OS/BrowserWindowOsrDom/initsubprocess.pas
new file mode 100644
index 00000000..512c43e8
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowOsrDom/initsubprocess.pas
@@ -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
+ * 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.
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowOsrDom/uBrowserWindowDom.lfm b/demos/Lazarus_any_OS/BrowserWindowOsrDom/uBrowserWindowDom.lfm
new file mode 100644
index 00000000..0dc868b3
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowOsrDom/uBrowserWindowDom.lfm
@@ -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
diff --git a/demos/Lazarus_any_OS/BrowserWindowOsrDom/uBrowserWindowDom.pas b/demos/Lazarus_any_OS/BrowserWindowOsrDom/uBrowserWindowDom.pas
new file mode 100644
index 00000000..7c4437da
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowOsrDom/uBrowserWindowDom.pas
@@ -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
+ * 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.
+
diff --git a/demos/Lazarus_any_OS/BrowserWindowOsrDom/uHelperProcessDom.pas b/demos/Lazarus_any_OS/BrowserWindowOsrDom/uHelperProcessDom.pas
new file mode 100644
index 00000000..d9604544
--- /dev/null
+++ b/demos/Lazarus_any_OS/BrowserWindowOsrDom/uHelperProcessDom.pas
@@ -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
+ * 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.
+
diff --git a/packages/cef4delphi_lazarus.lpk b/packages/cef4delphi_lazarus.lpk
index 37a1e18f..4f293e26 100644
--- a/packages/cef4delphi_lazarus.lpk
+++ b/packages/cef4delphi_lazarus.lpk
@@ -22,7 +22,7 @@
-
+
@@ -840,6 +840,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/cef4delphi_lazarus.pas b/packages/cef4delphi_lazarus.pas
index 5ddb7c66..e5dcc2ac 100644
--- a/packages/cef4delphi_lazarus.pas
+++ b/packages/cef4delphi_lazarus.pas
@@ -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
diff --git a/source/uCEFApplicationCore.pas b/source/uCEFApplicationCore.pas
index 551b7283..3e428eef 100644
--- a/source/uCEFApplicationCore.pas
+++ b/source/uCEFApplicationCore.pas
@@ -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;
diff --git a/source/uCEFBufferPanel.pas b/source/uCEFBufferPanel.pas
index ced2cc3e..74c8eb59 100644
--- a/source/uCEFBufferPanel.pas
+++ b/source/uCEFBufferPanel.pas
@@ -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;
diff --git a/source/uCEFLazApplication.pas b/source/uCEFLazApplication.pas
new file mode 100644
index 00000000..3298395d
--- /dev/null
+++ b/source/uCEFLazApplication.pas
@@ -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.
+
diff --git a/source/uCEFLazarusOsrBrowserWindow.pas b/source/uCEFLazarusOsrBrowserWindow.pas
new file mode 100644
index 00000000..bbe4ffc3
--- /dev/null
+++ b/source/uCEFLazarusOsrBrowserWindow.pas
@@ -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
+ * 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.
+
diff --git a/source/uceflazarusbrowserwindow.pas b/source/uceflazarusbrowserwindow.pas
index aa1b4c66..fa68d1ac 100644
--- a/source/uceflazarusbrowserwindow.pas
+++ b/source/uceflazarusbrowserwindow.pas
@@ -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;