From 373a19f8f512974d9c0c15b58fd5a5e009d3c24a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Salvador=20D=C3=ADaz=20Fau?= Date: Mon, 13 Jan 2025 18:45:34 +0100 Subject: [PATCH] Added WebpageSnapshot demo for UniGUI --- .../WebpageSnapshot/00-DeleteDCUs.bat | 18 + demos/Delphi_UniGUI/WebpageSnapshot/Main.dfm | 166 +++ demos/Delphi_UniGUI/WebpageSnapshot/Main.pas | 138 ++ .../WebpageSnapshot/MainModule.dfm | 5 + .../WebpageSnapshot/MainModule.pas | 32 + .../WebpageSnapshot/ServerModule.dfm | 18 + .../WebpageSnapshot/ServerModule.pas | 40 + .../WebpageSnapshot/WebpageSnapshotUniGUI.dpr | 18 + .../WebpageSnapshotUniGUI.dproj | 1162 +++++++++++++++++ .../WebpageSnapshotUniGUIGrp.groupproj | 48 + .../WebpageSnapshotUniGUI_sp.dpr | 21 + .../WebpageSnapshotUniGUI_sp.dproj | 1115 ++++++++++++++++ .../WebpageSnapshot/uCEFBrowserThread.pas | 715 ++++++++++ .../WebpageSnapshot/uCEFLoader.pas | 26 + update_CEF4Delphi.json | 2 +- 15 files changed, 3523 insertions(+), 1 deletion(-) create mode 100644 demos/Delphi_UniGUI/WebpageSnapshot/00-DeleteDCUs.bat create mode 100644 demos/Delphi_UniGUI/WebpageSnapshot/Main.dfm create mode 100644 demos/Delphi_UniGUI/WebpageSnapshot/Main.pas create mode 100644 demos/Delphi_UniGUI/WebpageSnapshot/MainModule.dfm create mode 100644 demos/Delphi_UniGUI/WebpageSnapshot/MainModule.pas create mode 100644 demos/Delphi_UniGUI/WebpageSnapshot/ServerModule.dfm create mode 100644 demos/Delphi_UniGUI/WebpageSnapshot/ServerModule.pas create mode 100644 demos/Delphi_UniGUI/WebpageSnapshot/WebpageSnapshotUniGUI.dpr create mode 100644 demos/Delphi_UniGUI/WebpageSnapshot/WebpageSnapshotUniGUI.dproj create mode 100644 demos/Delphi_UniGUI/WebpageSnapshot/WebpageSnapshotUniGUIGrp.groupproj create mode 100644 demos/Delphi_UniGUI/WebpageSnapshot/WebpageSnapshotUniGUI_sp.dpr create mode 100644 demos/Delphi_UniGUI/WebpageSnapshot/WebpageSnapshotUniGUI_sp.dproj create mode 100644 demos/Delphi_UniGUI/WebpageSnapshot/uCEFBrowserThread.pas create mode 100644 demos/Delphi_UniGUI/WebpageSnapshot/uCEFLoader.pas diff --git a/demos/Delphi_UniGUI/WebpageSnapshot/00-DeleteDCUs.bat b/demos/Delphi_UniGUI/WebpageSnapshot/00-DeleteDCUs.bat new file mode 100644 index 00000000..a9a84095 --- /dev/null +++ b/demos/Delphi_UniGUI/WebpageSnapshot/00-DeleteDCUs.bat @@ -0,0 +1,18 @@ +del /s /q *.dcu +del /s /q *.exe +del /s /q *.res +del /s /q *.rsm +del /s /q *.log +del /s /q *.dsk +del /s /q *.identcache +del /s /q *.stat +del /s /q *.local +del /s /q *.~* +rmdir Win32\Debug +rmdir Win32\Release +rmdir Win32 +rmdir Win64\Debug +rmdir Win64\Release +rmdir Win64 +rmdir __history +rmdir __recovery diff --git a/demos/Delphi_UniGUI/WebpageSnapshot/Main.dfm b/demos/Delphi_UniGUI/WebpageSnapshot/Main.dfm new file mode 100644 index 00000000..144a6c70 --- /dev/null +++ b/demos/Delphi_UniGUI/WebpageSnapshot/Main.dfm @@ -0,0 +1,166 @@ +object MainForm: TMainForm + Left = 0 + Top = 0 + ClientHeight = 645 + ClientWidth = 800 + Caption = 'Webpage Snapshot UniGUI' + OnShow = UniFormShow + BorderStyle = bsSingle + OldCreateOrder = False + OnClose = UniFormClose + BorderIcons = [biSystemMenu] + MonitoredKeys.Keys = <> + OnCreate = UniFormCreate + TextHeight = 15 + object UniPanel1: TUniPanel + Left = 0 + Top = 0 + Width = 800 + Height = 23 + Hint = '' + Align = alTop + TabOrder = 0 + BorderStyle = ubsNone + Caption = '' + object AddressCb: TUniComboBox + Left = 0 + Top = 0 + Width = 725 + Height = 23 + Hint = '' + Text = 'https://www.google.com' + Items.Strings = ( + 'https://www.google.com' + + 'https://www.whatismybrowser.com/detect/what-http-headers-is-my-b' + + 'rowser-sending' + 'https://www.w3schools.com/js/tryit.asp?filename=tryjs_win_close' + 'https://www.w3schools.com/js/tryit.asp?filename=tryjs_alert' + 'https://www.w3schools.com/js/tryit.asp?filename=tryjs_loc_assign' + + 'https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_styl' + + 'e_backgroundcolor' + + 'https://www.w3schools.com/Tags/tryit.asp?filename=tryhtml_iframe' + + '_name' + + 'https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_input' + + '_type_file' + + 'https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_stat' + + 'e_throw_error' + 'https://www.htmlquick.com/es/reference/tags/input-file.html' + + 'https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/' + + 'file' + + 'https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElemen' + + 't/webkitdirectory' + 'https://www.w3schools.com/html/html5_video.asp' + 'http://html5test.com/' + + 'https://webrtc.github.io/samples/src/content/devices/input-outpu' + + 't/' + 'https://test.webrtc.org/' + 'https://www.browserleaks.com/webrtc' + 'https://shaka-player-demo.appspot.com/demo/' + 'http://webglsamples.org/' + 'https://get.webgl.org/' + 'https://www.briskbard.com' + 'https://www.youtube.com' + 'https://html5demos.com/drag/' + 'https://frames-per-second.appspot.com/' + + 'https://www.sede.fnmt.gob.es/certificados/persona-fisica/verific' + + 'ar-estado' + 'https://www.kirupa.com/html5/accessing_your_webcam_in_html5.htm' + 'https://www.xdumaine.com/enumerateDevices/test/' + + 'https://dagrs.berkeley.edu/sites/default/files/2020-01/sample.pd' + + 'f' + 'https://codepen.io/udaymanvar/pen/MWaePBY' + + 'https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/acc' + + 'ept' + 'chrome://version/' + 'chrome://net-internals/' + 'chrome://tracing/' + 'chrome://appcache-internals/' + 'chrome://blob-internals/' + 'chrome://view-http-cache/' + 'chrome://credits/' + 'chrome://histograms/' + 'chrome://media-internals/' + 'chrome://kill' + 'chrome://crash' + 'chrome://hang' + 'chrome://shorthang' + 'chrome://gpuclean' + 'chrome://gpucrash' + 'chrome://gpuhang' + 'chrome://extensions-support' + 'chrome://process-internals') + ItemIndex = 0 + Align = alClient + TabOrder = 1 + IconItems = <> + end + object GoBtn: TUniButton + Left = 725 + Top = 0 + Width = 75 + Height = 23 + Hint = '' + Caption = 'Go' + Align = alRight + TabOrder = 2 + OnClick = GoBtnClick + end + end + object UniStatusBar1: TUniStatusBar + Left = 0 + Top = 623 + Width = 800 + Hint = '' + Panels = < + item + Width = 600 + end> + SizeGrip = False + Align = alBottom + ParentColor = False + end + object UniMemo1: TUniMemo + Left = 0 + Top = 534 + Width = 800 + Height = 89 + Hint = '' + Align = alBottom + ReadOnly = True + TabOrder = 2 + end + object UniCanvas1: TUniCanvas + Left = 0 + Top = 23 + Width = 800 + Height = 511 + Hint = '' + Align = alClient + ExplicitLeft = 200 + ExplicitTop = 104 + ExplicitWidth = 320 + ExplicitHeight = 320 + end + object UniTimer1: TUniTimer + Interval = 100 + ClientEvent.Strings = ( + 'function(sender)' + '{' + ' ' + '}') + OnTimer = UniTimer1Timer + Left = 496 + Top = 376 + end +end diff --git a/demos/Delphi_UniGUI/WebpageSnapshot/Main.pas b/demos/Delphi_UniGUI/WebpageSnapshot/Main.pas new file mode 100644 index 00000000..ac2f28be --- /dev/null +++ b/demos/Delphi_UniGUI/WebpageSnapshot/Main.pas @@ -0,0 +1,138 @@ +unit Main; + +interface + +uses + Windows, Messages, SysUtils, Variants, Classes, Graphics, + Controls, Forms, uniGUITypes, uniGUIAbstractClasses, + uniGUIClasses, uniGUIRegClasses, uniGUIForm, uniImage, uniButton, + uniMultiItem, uniComboBox, uniGUIBaseClasses, uniPanel, + uCEFBrowserThread, uniStatusBar, uniMemo, uniTimer, uniCanvas; + +type + TMainForm = class(TUniForm) + UniPanel1: TUniPanel; + AddressCb: TUniComboBox; + GoBtn: TUniButton; + UniStatusBar1: TUniStatusBar; + UniMemo1: TUniMemo; + UniCanvas1: TUniCanvas; + UniTimer1: TUniTimer; + procedure UniFormCreate(Sender: TObject); + procedure UniFormClose(Sender: TObject; var Action: TCloseAction); + procedure GoBtnClick(Sender: TObject); + procedure UniFormShow(Sender: TObject); + procedure UniTimer1Timer(Sender: TObject); + private + FThread : TCEFBrowserThread; + FMustRefresh : boolean; + + procedure Thread_OnError(Sender: TObject); + procedure Thread_OnSnapshotAvailable(Sender: TObject); + procedure Thread_OnHTMLAvailable(Sender: TObject); + public + { Public declarations } + end; + +function MainForm: TMainForm; + +implementation + +{$R *.dfm} + +uses + uniGUIVars, MainModule, uniGUIApplication, + uCEFApplication; + +function MainForm: TMainForm; +begin + Result := TMainForm(UniMainModule.GetFormInstance(TMainForm)); +end; + +procedure TMainForm.GoBtnClick(Sender: TObject); +begin + UniStatusBar1.Panels[0].Text := 'Loading...'; + screen.cursor := crAppStart; + FMustRefresh := False; + + if (FThread = nil) then + begin + FThread := TCEFBrowserThread.Create(AddressCb.Text, UniCanvas1.Width, UniCanvas1.Height); + FThread.OnError := Thread_OnError; + FThread.OnSnapshotAvailable := Thread_OnSnapshotAvailable; + FThread.OnHTMLAvailable := Thread_OnHTMLAvailable; + FThread.SyncEvents := True; + FThread.Start; + end + else + FThread.LoadUrl(AddressCb.Text); +end; + +procedure TMainForm.UniFormClose(Sender: TObject; var Action: TCloseAction); +begin + if (FThread <> nil) then + begin + if FThread.TerminateBrowserThread then + FThread.WaitFor; + + FreeAndNil(FThread); + end; +end; + +procedure TMainForm.UniFormCreate(Sender: TObject); +begin + FThread := nil; +end; + +procedure TMainForm.UniFormShow(Sender: TObject); +begin + if GlobalCEFApp.GlobalContextInitialized then + UniMemo1.Lines.Add('GlobalCEFApp Initialized') + else + UniMemo1.Lines.Add('Error: ' + GlobalCEFApp.LastErrorMessage); + + UniMemo1.Refresh; +end; + +procedure TMainForm.UniTimer1Timer(Sender: TObject); +begin + if FMustRefresh then + begin + FMustRefresh := False; + Repaint; + end; +end; + +procedure TMainForm.Thread_OnError(Sender: TObject); +begin + UniStatusBar1.Panels[0].Text := 'Error ' + inttostr(FThread.ErrorCode) + ' : ' + FThread.ErrorText + ' - ' + FThread.FailedUrl; + screen.cursor := crDefault; +end; + +procedure TMainForm.Thread_OnSnapshotAvailable(Sender: TObject); +var + TempBitmap : TBitmap; +begin + TempBitmap := nil; + screen.cursor := crDefault; + + if FThread.CopySnapshot(TempBitmap) then + begin + UniCanvas1.Bitmap.Assign(TempBitmap); + UniStatusBar1.Panels[0].Text := 'Snapshot copied successfully'; + TempBitmap.Free; + end + else + UniStatusBar1.Panels[0].Text := 'There was an error copying the snapshot'; +end; + +procedure TMainForm.Thread_OnHTMLAvailable(Sender: TObject); +begin + UniMemo1.Lines.Add(FThread.HTMLcopy); + FMustRefresh := True; +end; + +initialization + RegisterAppFormClass(TMainForm); + +end. diff --git a/demos/Delphi_UniGUI/WebpageSnapshot/MainModule.dfm b/demos/Delphi_UniGUI/WebpageSnapshot/MainModule.dfm new file mode 100644 index 00000000..c1217e4f --- /dev/null +++ b/demos/Delphi_UniGUI/WebpageSnapshot/MainModule.dfm @@ -0,0 +1,5 @@ +object UniMainModule: TUniMainModule + MonitoredKeys.Keys = <> + Height = 480 + Width = 640 +end diff --git a/demos/Delphi_UniGUI/WebpageSnapshot/MainModule.pas b/demos/Delphi_UniGUI/WebpageSnapshot/MainModule.pas new file mode 100644 index 00000000..eaa1b04f --- /dev/null +++ b/demos/Delphi_UniGUI/WebpageSnapshot/MainModule.pas @@ -0,0 +1,32 @@ +unit MainModule; + +interface + +uses + uniGUIMainModule, SysUtils, Classes; + +type + TUniMainModule = class(TUniGUIMainModule) + private + { Private declarations } + public + { Public declarations } + end; + +function UniMainModule: TUniMainModule; + +implementation + +{$R *.dfm} + +uses + UniGUIVars, ServerModule, uniGUIApplication; + +function UniMainModule: TUniMainModule; +begin + Result := TUniMainModule(UniApplication.UniMainModule) +end; + +initialization + RegisterMainModuleClass(TUniMainModule); +end. diff --git a/demos/Delphi_UniGUI/WebpageSnapshot/ServerModule.dfm b/demos/Delphi_UniGUI/WebpageSnapshot/ServerModule.dfm new file mode 100644 index 00000000..0bbee61e --- /dev/null +++ b/demos/Delphi_UniGUI/WebpageSnapshot/ServerModule.dfm @@ -0,0 +1,18 @@ +object UniServerModule: TUniServerModule + TempFolder = 'temp\' + Title = 'New Application' + SuppressErrors = [] + Bindings = <> + SSL.SSLOptions.RootCertFile = 'root.pem' + SSL.SSLOptions.CertFile = 'cert.pem' + SSL.SSLOptions.KeyFile = 'key.pem' + SSL.SSLOptions.Method = sslvSSLv23 + SSL.SSLOptions.SSLVersions = [sslvTLSv1_1, sslvTLSv1_2] + SSL.SSLOptions.Mode = sslmUnassigned + SSL.SSLOptions.VerifyMode = [] + SSL.SSLOptions.VerifyDepth = 0 + ConnectionFailureRecovery.ErrorMessage = 'Connection Error' + ConnectionFailureRecovery.RetryMessage = 'Retrying...' + Height = 480 + Width = 640 +end diff --git a/demos/Delphi_UniGUI/WebpageSnapshot/ServerModule.pas b/demos/Delphi_UniGUI/WebpageSnapshot/ServerModule.pas new file mode 100644 index 00000000..6b50de79 --- /dev/null +++ b/demos/Delphi_UniGUI/WebpageSnapshot/ServerModule.pas @@ -0,0 +1,40 @@ +unit ServerModule; + +interface + +uses + Classes, SysUtils, uniGUIServer, uniGUIMainModule, uniGUIApplication, uIdCustomHTTPServer, + uniGUITypes; + +type + TUniServerModule = class(TUniGUIServerModule) + private + { Private declarations } + protected + procedure FirstInit; override; + public + { Public declarations } + end; + +function UniServerModule: TUniServerModule; + +implementation + +{$R *.dfm} + +uses + UniGUIVars; + +function UniServerModule: TUniServerModule; +begin + Result := TUniServerModule(UniGUIServerInstance); +end; + +procedure TUniServerModule.FirstInit; +begin + InitServerModule(Self); +end; + +initialization + RegisterServerModuleClass(TUniServerModule); +end. diff --git a/demos/Delphi_UniGUI/WebpageSnapshot/WebpageSnapshotUniGUI.dpr b/demos/Delphi_UniGUI/WebpageSnapshot/WebpageSnapshotUniGUI.dpr new file mode 100644 index 00000000..d6ca68be --- /dev/null +++ b/demos/Delphi_UniGUI/WebpageSnapshot/WebpageSnapshotUniGUI.dpr @@ -0,0 +1,18 @@ +program WebpageSnapshotUniGUI; + +uses + Forms, + ServerModule in 'ServerModule.pas' {UniServerModule: TUniGUIServerModule}, + MainModule in 'MainModule.pas' {UniMainModule: TUniGUIMainModule}, + Main in 'Main.pas' {MainForm: TUniForm}, + uCEFLoader in 'uCEFLoader.pas', + uCEFBrowserThread in 'uCEFBrowserThread.pas'; + +{$R *.res} + +begin + ReportMemoryLeaksOnShutdown := True; + Application.Initialize; + TUniServerModule.Create(Application); + Application.Run; +end. diff --git a/demos/Delphi_UniGUI/WebpageSnapshot/WebpageSnapshotUniGUI.dproj b/demos/Delphi_UniGUI/WebpageSnapshot/WebpageSnapshotUniGUI.dproj new file mode 100644 index 00000000..f7beba8e --- /dev/null +++ b/demos/Delphi_UniGUI/WebpageSnapshot/WebpageSnapshotUniGUI.dproj @@ -0,0 +1,1162 @@ + + + {6BA654AC-0CD5-4079-83E5-D9E5217C407B} + 20.2 + VCL + True + Debug + Win32 + WebpageSnapshotUniGUI + 1 + Application + WebpageSnapshotUniGUI.dpr + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + .\$(Platform)\$(Config) + ..\..\..\bin + false + false + false + false + false + System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) + $(BDS)\bin\delphi_PROJECTICON.ico + $(BDS)\bin\delphi_PROJECTICNS.icns + WebpageSnapshotUniGUI + ..\..\..\source;$(DCC_UnitSearchPath) + 3082 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + + + fmx;DbxCommonDriver;bindengine;IndyIPCommon;FireDACCommonDriver;IndyProtocols;IndyIPClient;dbxcds;FmxTeeUI;bindcompfmx;ibmonitor;FireDACSqliteDriver;DbxClientDriver;soapmidas;fmxFireDAC;dbexpress;inet;fmxase;dbrtl;CustomIPTransport;DBXInterBaseDriver;IndySystem;ibxbindings;bindcomp;FireDACCommon;inetstn;IndyCore;RESTBackendComponents;bindcompdbx;rtl;RESTComponents;DBXSqliteDriver;IndyIPServer;dsnapxml;FireDAC;xmlrtl;tethering;ibxpress;dsnap;CloudService;FMXTee;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage) + activity-1.7.2.dex.jar;annotation-experimental-1.3.0.dex.jar;annotation-jvm-1.6.0.dex.jar;annotations-13.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;billing-6.0.1.dex.jar;biometric-1.1.0.dex.jar;browser-1.4.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;concurrent-futures-1.1.0.dex.jar;core-1.10.1.dex.jar;core-common-2.2.0.dex.jar;core-ktx-1.10.1.dex.jar;core-runtime-2.2.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;error_prone_annotations-2.9.0.dex.jar;exifinterface-1.3.6.dex.jar;firebase-annotations-16.2.0.dex.jar;firebase-common-20.3.1.dex.jar;firebase-components-17.1.0.dex.jar;firebase-datatransport-18.1.7.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-encoders-proto-16.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.1.3.dex.jar;firebase-installations-interop-17.1.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-23.1.2.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;kotlin-stdlib-1.8.22.dex.jar;kotlin-stdlib-common-1.8.22.dex.jar;kotlin-stdlib-jdk7-1.8.22.dex.jar;kotlin-stdlib-jdk8-1.8.22.dex.jar;kotlinx-coroutines-android-1.6.4.dex.jar;kotlinx-coroutines-core-jvm-1.6.4.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.6.1.dex.jar;lifecycle-livedata-2.6.1.dex.jar;lifecycle-livedata-core-2.6.1.dex.jar;lifecycle-runtime-2.6.1.dex.jar;lifecycle-service-2.6.1.dex.jar;lifecycle-viewmodel-2.6.1.dex.jar;lifecycle-viewmodel-savedstate-2.6.1.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;okio-jvm-3.4.0.dex.jar;play-services-ads-22.2.0.dex.jar;play-services-ads-base-22.2.0.dex.jar;play-services-ads-identifier-18.0.0.dex.jar;play-services-ads-lite-22.2.0.dex.jar;play-services-appset-16.0.1.dex.jar;play-services-base-18.1.0.dex.jar;play-services-basement-18.1.0.dex.jar;play-services-cloud-messaging-17.0.1.dex.jar;play-services-location-21.0.1.dex.jar;play-services-maps-18.1.0.dex.jar;play-services-measurement-base-20.1.2.dex.jar;play-services-measurement-sdk-api-20.1.2.dex.jar;play-services-stats-17.0.2.dex.jar;play-services-tasks-18.0.2.dex.jar;print-1.0.0.dex.jar;profileinstaller-1.3.0.dex.jar;room-common-2.2.5.dex.jar;room-runtime-2.2.5.dex.jar;savedstate-1.2.1.dex.jar;sqlite-2.1.0.dex.jar;sqlite-framework-2.1.0.dex.jar;startup-runtime-1.1.1.dex.jar;tracing-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.1.8.dex.jar;transport-runtime-3.1.8.dex.jar;user-messaging-platform-2.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.7.0.dex.jar + + + fmx;DbxCommonDriver;bindengine;IndyIPCommon;FireDACCommonDriver;IndyProtocols;IndyIPClient;dbxcds;FmxTeeUI;bindcompfmx;ibmonitor;FireDACSqliteDriver;DbxClientDriver;soapmidas;fmxFireDAC;dbexpress;inet;dbrtl;CustomIPTransport;DBXInterBaseDriver;IndySystem;ibxbindings;bindcomp;FireDACCommon;inetstn;MfPackX317;IndyCore;RESTBackendComponents;bindcompdbx;rtl;RESTComponents;DBXSqliteDriver;IndyIPServer;dsnapxml;FireDAC;xmlrtl;tethering;ibxpress;dsnap;CloudService;FMXTee;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage) + activity-1.7.2.dex.jar;annotation-experimental-1.3.0.dex.jar;annotation-jvm-1.6.0.dex.jar;annotations-13.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;billing-6.0.1.dex.jar;biometric-1.1.0.dex.jar;browser-1.4.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;concurrent-futures-1.1.0.dex.jar;core-1.10.1.dex.jar;core-common-2.2.0.dex.jar;core-ktx-1.10.1.dex.jar;core-runtime-2.2.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;error_prone_annotations-2.9.0.dex.jar;exifinterface-1.3.6.dex.jar;firebase-annotations-16.2.0.dex.jar;firebase-common-20.3.1.dex.jar;firebase-components-17.1.0.dex.jar;firebase-datatransport-18.1.7.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-encoders-proto-16.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.1.3.dex.jar;firebase-installations-interop-17.1.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-23.1.2.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;kotlin-stdlib-1.8.22.dex.jar;kotlin-stdlib-common-1.8.22.dex.jar;kotlin-stdlib-jdk7-1.8.22.dex.jar;kotlin-stdlib-jdk8-1.8.22.dex.jar;kotlinx-coroutines-android-1.6.4.dex.jar;kotlinx-coroutines-core-jvm-1.6.4.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.6.1.dex.jar;lifecycle-livedata-2.6.1.dex.jar;lifecycle-livedata-core-2.6.1.dex.jar;lifecycle-runtime-2.6.1.dex.jar;lifecycle-service-2.6.1.dex.jar;lifecycle-viewmodel-2.6.1.dex.jar;lifecycle-viewmodel-savedstate-2.6.1.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;okio-jvm-3.4.0.dex.jar;play-services-ads-22.2.0.dex.jar;play-services-ads-base-22.2.0.dex.jar;play-services-ads-identifier-18.0.0.dex.jar;play-services-ads-lite-22.2.0.dex.jar;play-services-appset-16.0.1.dex.jar;play-services-base-18.1.0.dex.jar;play-services-basement-18.1.0.dex.jar;play-services-cloud-messaging-17.0.1.dex.jar;play-services-location-21.0.1.dex.jar;play-services-maps-18.1.0.dex.jar;play-services-measurement-base-20.1.2.dex.jar;play-services-measurement-sdk-api-20.1.2.dex.jar;play-services-stats-17.0.2.dex.jar;play-services-tasks-18.0.2.dex.jar;print-1.0.0.dex.jar;profileinstaller-1.3.0.dex.jar;room-common-2.2.5.dex.jar;room-runtime-2.2.5.dex.jar;savedstate-1.2.1.dex.jar;sqlite-2.1.0.dex.jar;sqlite-framework-2.1.0.dex.jar;startup-runtime-1.1.1.dex.jar;tracing-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.1.8.dex.jar;transport-runtime-3.1.8.dex.jar;user-messaging-platform-2.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.7.0.dex.jar + + + fmx;DbxCommonDriver;bindengine;IndyIPCommon;FireDACCommonDriver;IndyProtocols;IndyIPClient;dbxcds;FmxTeeUI;bindcompfmx;ibmonitor;FireDACSqliteDriver;DbxClientDriver;soapmidas;fmxFireDAC;dbexpress;inet;fmxase;dbrtl;CustomIPTransport;DBXInterBaseDriver;IndySystem;ibxbindings;bindcomp;FireDACCommon;inetstn;MfPackX317;IndyCore;RESTBackendComponents;bindcompdbx;rtl;RESTComponents;DBXSqliteDriver;IndyIPServer;dsnapxml;FireDAC;xmlrtl;tethering;ibxpress;dsnap;CloudService;FMXTee;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage) + + + fmx;DbxCommonDriver;bindengine;IndyIPCommon;FireDACCommonDriver;IndyProtocols;IndyIPClient;dbxcds;FmxTeeUI;bindcompfmx;ibmonitor;FireDACSqliteDriver;DbxClientDriver;soapmidas;fmxFireDAC;dbexpress;inet;fmxase;dbrtl;CustomIPTransport;DBXInterBaseDriver;IndySystem;ibxbindings;bindcomp;FireDACCommon;inetstn;MfPackX317;IndyCore;RESTBackendComponents;bindcompdbx;rtl;RESTComponents;DBXSqliteDriver;IndyIPServer;dsnapxml;FireDAC;xmlrtl;tethering;ibxpress;dsnap;CloudService;FMXTee;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage) + + + fmx;DbxCommonDriver;bindengine;IndyIPCommon;FireDACCommonODBC;FireDACCommonDriver;IndyProtocols;IndyIPClient;dbxcds;FmxTeeUI;bindcompfmx;inetdb;ibmonitor;FireDACSqliteDriver;DbxClientDriver;soapmidas;fmxFireDAC;dbexpress;DBXMySQLDriver;inet;fmxase;dbrtl;fmxdae;CustomIPTransport;DBXInterBaseDriver;IndySystem;ibxbindings;bindcomp;FireDACCommon;inetstn;MfPackX317;IndyCore;RESTBackendComponents;bindcompdbx;rtl;FireDACMySQLDriver;RESTComponents;DBXSqliteDriver;IndyIPServer;dsnapxml;FireDACPgDriver;FireDAC;inetdbxpress;xmlrtl;tethering;ibxpress;dsnap;CloudService;fmxobj;FMXTee;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage) + + + fmx;DbxCommonDriver;bindengine;IndyIPCommon;FireDACCommonODBC;FireDACCommonDriver;IndyProtocols;IndyIPClient;dbxcds;FmxTeeUI;bindcompfmx;inetdb;ibmonitor;FireDACSqliteDriver;DbxClientDriver;soapmidas;fmxFireDAC;dbexpress;DBXMySQLDriver;inet;fmxase;dbrtl;fmxdae;CustomIPTransport;DBXInterBaseDriver;IndySystem;ibxbindings;bindcomp;FireDACCommon;inetstn;MfPackX317;IndyCore;RESTBackendComponents;bindcompdbx;rtl;FireDACMySQLDriver;RESTComponents;DBXSqliteDriver;IndyIPServer;dsnapxml;FireDACPgDriver;FireDAC;inetdbxpress;xmlrtl;tethering;ibxpress;dsnap;CloudService;fmxobj;FMXTee;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage) + + + vclwinx;fmx;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;FireDACCommonODBC;FireDACCommonDriver;appanalytics;IndyProtocols;vclx;Skia.Package.RTL;IndyIPClient;dbxcds;vcledge;bindcompvclwinx;FmxTeeUI;bindcompfmx;madBasic_;uSynEdit_R2025;inetdb;ibmonitor;FireDACSqliteDriver;DbxClientDriver;WebView4DelphiVCLRTL;Tee;soapmidas;vclactnband;TeeUI;fmxFireDAC;dbexpress;CEF4DelphiVCLRTL;DBXMySQLDriver;VclSmp;inet;vcltouch;fmxase;uniGUI29VCL;dbrtl;uniGUI29m;Skia.Package.FMX;fmxdae;TeeDB;FireDACMSAccDriver;CustomIPTransport;CEF4DelphiFMXRTL;vcldsnap;DBXInterBaseDriver;madExcept_;IndySystem;uniGUI29Chart;Skia.Package.VCL;vcldb;ibxbindings;vclFireDAC;madDisAsm_;bindcomp;FireDACCommon;inetstn;MfPackX317;IndyCore;RESTBackendComponents;TMSMQTTPkgDXE15;bindcompdbx;rtl;FireDACMySQLDriver;FireDACADSDriver;RESTComponents;DBXSqliteDriver;vcl;IndyIPServer;dsnapxml;dsnapcon;adortl;WebView4DelphiFMXRTL;TMSMQTTPkgDEDXE15;vclimg;FireDACPgDriver;FireDAC;inetdbxpress;xmlrtl;tethering;ibxpress;bindcompvcl;dsnap;CloudService;vclib;fmxobj;bindcompvclsmp;FMXTee;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + $(BDS)\bin\default_app.manifest + + + vclwinx;fmx;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;FireDACCommonODBC;FireDACCommonDriver;appanalytics;IndyProtocols;vclx;IndyIPClient;dbxcds;vcledge;bindcompvclwinx;FmxTeeUI;bindcompfmx;uSynEdit_R2025;inetdb;ibmonitor;FireDACSqliteDriver;DbxClientDriver;WebView4DelphiVCLRTL;Tee;soapmidas;vclactnband;TeeUI;fmxFireDAC;dbexpress;CEF4DelphiVCLRTL;DBXMySQLDriver;VclSmp;inet;vcltouch;fmxase;uniGUI29VCL;dbrtl;uniGUI29m;fmxdae;TeeDB;FireDACMSAccDriver;CustomIPTransport;CEF4DelphiFMXRTL;vcldsnap;DBXInterBaseDriver;IndySystem;uniGUI29Chart;Skia.Package.VCL;vcldb;ibxbindings;vclFireDAC;bindcomp;FireDACCommon;inetstn;IndyCore;RESTBackendComponents;bindcompdbx;rtl;FireDACMySQLDriver;FireDACADSDriver;RESTComponents;DBXSqliteDriver;vcl;IndyIPServer;dsnapxml;dsnapcon;adortl;WebView4DelphiFMXRTL;vclimg;FireDACPgDriver;FireDAC;inetdbxpress;xmlrtl;tethering;ibxpress;bindcompvcl;dsnap;CloudService;vclib;fmxobj;bindcompvclsmp;FMXTee;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage) + + + DEBUG;$(DCC_Define) + true + false + true + true + true + true + true + + + false + PerMonitorV2 + true + 1033 + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + PerMonitorV2 + + + + MainSource + + +
UniServerModule
+ dfm + TUniGUIServerModule +
+ +
UniMainModule
+ dfm + TUniGUIMainModule +
+ +
MainForm
+ dfm + TUniForm +
+ + + + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + +
+ + Delphi.Personality.12 + Application + + + + WebpageSnapshotUniGUI.dpr + + + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + + + WebpageSnapshotUniGUI.exe + true + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-anydpi-v21 + 1 + + + res\drawable-anydpi-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values-v31 + 1 + + + res\values-v31 + 1 + + + + + res\drawable-anydpi-v26 + 1 + + + res\drawable-anydpi-v26 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-anydpi-v33 + 1 + + + res\drawable-anydpi-v33 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-night-v21 + 1 + + + res\values-night-v21 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable-anydpi-v24 + 1 + + + res\drawable-anydpi-v24 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-night-anydpi-v21 + 1 + + + res\drawable-night-anydpi-v21 + 1 + + + + + res\drawable-anydpi-v31 + 1 + + + res\drawable-anydpi-v31 + 1 + + + + + res\drawable-night-anydpi-v31 + 1 + + + res\drawable-night-anydpi-v31 + 1 + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + Contents\Resources\StartUp\ + 0 + + + Contents\Resources\StartUp\ + 0 + + + Contents\Resources\StartUp\ + 0 + + + 0 + + + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + ..\ + 1 + + + + + Contents + 1 + + + Contents + 1 + + + Contents + 1 + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + Contents\MacOS + 1 + + + Contents\MacOS + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + ..\ + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen + 64 + + + ..\$(PROJECTNAME).launchscreen + 64 + + + + + 1 + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + + + + + + + + + + + + + False + False + False + False + False + False + True + False + + + 12 + + + + +
diff --git a/demos/Delphi_UniGUI/WebpageSnapshot/WebpageSnapshotUniGUIGrp.groupproj b/demos/Delphi_UniGUI/WebpageSnapshot/WebpageSnapshotUniGUIGrp.groupproj new file mode 100644 index 00000000..bea00ebd --- /dev/null +++ b/demos/Delphi_UniGUI/WebpageSnapshot/WebpageSnapshotUniGUIGrp.groupproj @@ -0,0 +1,48 @@ + + + {CA1ADB9C-FCE8-4DC1-B7CF-DD26E7B81B65} + + + + + + + + + + + Default.Personality.12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/demos/Delphi_UniGUI/WebpageSnapshot/WebpageSnapshotUniGUI_sp.dpr b/demos/Delphi_UniGUI/WebpageSnapshot/WebpageSnapshotUniGUI_sp.dpr new file mode 100644 index 00000000..f24014a7 --- /dev/null +++ b/demos/Delphi_UniGUI/WebpageSnapshot/WebpageSnapshotUniGUI_sp.dpr @@ -0,0 +1,21 @@ +program WebpageSnapshotUniGUI_sp; + +uses + uCEFApplicationCore; + +const + IMAGE_FILE_LARGE_ADDRESS_AWARE = $0020; + +// CEF needs to set the LARGEADDRESSAWARE ($20) flag which allows 32-bit processes to use up to 3GB of RAM. +{$IFDEF WIN32}{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}{$ENDIF} + +begin + GlobalCEFApp := TCefApplicationCore.Create; + GlobalCEFApp.WindowlessRenderingEnabled := True; + GlobalCEFApp.ShowMessageDlg := False; + GlobalCEFApp.BlinkSettings := 'hideScrollbars'; + + GlobalCEFApp.StartSubProcess; + DestroyGlobalCEFApp; +end. + diff --git a/demos/Delphi_UniGUI/WebpageSnapshot/WebpageSnapshotUniGUI_sp.dproj b/demos/Delphi_UniGUI/WebpageSnapshot/WebpageSnapshotUniGUI_sp.dproj new file mode 100644 index 00000000..5b977b9d --- /dev/null +++ b/demos/Delphi_UniGUI/WebpageSnapshot/WebpageSnapshotUniGUI_sp.dproj @@ -0,0 +1,1115 @@ + + + {6ABCF641-08D0-4F35-9D13-2FBD18E5152A} + 20.2 + VCL + WebpageSnapshotUniGUI_sp.dpr + True + Debug + Win32 + 1 + Application + WebpageSnapshotUniGUI_sp + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + 3082 + System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + $(BDS)\bin\delphi_PROJECTICON.ico + WebpageSnapshotUniGUI_sp + .\$(Platform)\$(Config) + false + false + false + false + false + ..\..\..\bin + ..\..\..\source;$(DCC_UnitSearchPath) + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + true + 1033 + CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName) + $(BDS)\bin\default_app.manifest + DBXSqliteDriver;RESTComponents;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;frxe23;vclFireDAC;emsclientfiredac;DataSnapFireDAC;svnui;tethering;Componentes;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;svn;Intraweb;DBXOracleDriver;inetdb;Componentes_Int;CEF4Delphi;FmxTeeUI;FireDACIBDriver;fmx;fmxdae;vclib;FireDACDBXDriver;dbexpress;IndyProtocols230;vclx;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;frxTee23;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;CloudService;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;vcl;DBXSybaseASEDriver;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;Componentes_UI;TeeDB;FireDAC;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;soaprtl;DbxCommonDriver;Componentes_Misc;ibxpress;Tee;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;Componentes_RTF;DBXInformixDriver;bindcompvcl;frxDB23;Componentes_vCard;TeeUI;IndyCore230;vclribbon;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;IndySystem230;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;frx23;fmxase;$(DCC_UsePackage) + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png + + + DBXSqliteDriver;RESTComponents;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;emsclientfiredac;DataSnapFireDAC;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;Intraweb;DBXOracleDriver;inetdb;FmxTeeUI;FireDACIBDriver;fmx;fmxdae;vclib;FireDACDBXDriver;dbexpress;IndyProtocols230;vclx;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;CloudService;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;vcl;DBXSybaseASEDriver;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;TeeDB;FireDAC;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;soaprtl;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;bindcompvcl;TeeUI;IndyCore230;vclribbon;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;IndySystem230;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;fmxase;$(DCC_UsePackage) + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + Debug + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + (None) + + + DEBUG;$(DCC_Define) + true + false + true + true + true + + + true + 1033 + true + false + PerMonitor + CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName) + Debug + + + 1033 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + true + Debug + true + 1033 + CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName) + PerMonitor + + + + MainSource + + + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + + + + Delphi.Personality.12 + Application + + + + WebpageSnapshotUniGUI_sp.dpr + + + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + + + WebpageSnapshotUniGUI_sp.exe + true + + + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-anydpi-v21 + 1 + + + res\drawable-anydpi-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values-v31 + 1 + + + res\values-v31 + 1 + + + + + res\drawable-anydpi-v26 + 1 + + + res\drawable-anydpi-v26 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-anydpi-v33 + 1 + + + res\drawable-anydpi-v33 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-night-v21 + 1 + + + res\values-night-v21 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable-anydpi-v24 + 1 + + + res\drawable-anydpi-v24 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-night-anydpi-v21 + 1 + + + res\drawable-night-anydpi-v21 + 1 + + + + + res\drawable-anydpi-v31 + 1 + + + res\drawable-anydpi-v31 + 1 + + + + + res\drawable-night-anydpi-v31 + 1 + + + res\drawable-night-anydpi-v31 + 1 + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + Contents\Resources\StartUp\ + 0 + + + Contents\Resources\StartUp\ + 0 + + + Contents\Resources\StartUp\ + 0 + + + 0 + + + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + ..\ + 1 + + + + + Contents + 1 + + + Contents + 1 + + + Contents + 1 + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + Contents\MacOS + 1 + + + Contents\MacOS + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + ..\ + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen + 64 + + + ..\$(PROJECTNAME).launchscreen + 64 + + + + + 1 + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + + + + + + + + + + + + + + True + False + + + 12 + + + + + diff --git a/demos/Delphi_UniGUI/WebpageSnapshot/uCEFBrowserThread.pas b/demos/Delphi_UniGUI/WebpageSnapshot/uCEFBrowserThread.pas new file mode 100644 index 00000000..319ccd9a --- /dev/null +++ b/demos/Delphi_UniGUI/WebpageSnapshot/uCEFBrowserThread.pas @@ -0,0 +1,715 @@ +unit uCEFBrowserThread; + +{$I ..\..\..\source\cef.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes, Vcl.Graphics, System.SyncObjs, System.Math, + {$ELSE} + Windows, Messages, SysUtils, Classes, Graphics, SyncObjs, Math, + {$ENDIF} + uCEFChromium, uCEFTypes, uCEFInterfaces, uCEFConstants, uCEFBrowserBitmap, uCEFChromiumCore, uCEFMiscFunctions; + +type + TCEFBrowserThread = class(TThread) + protected + FBrowser : TChromium; + FBrowserBitmap : TCEFBrowserBitmap; + FBrowserSize : TSize; + FScreenScale : single; + FPopUpBitmap : TBitmap; + FPopUpRect : TRect; + FResizeCS : TCriticalSection; + FBrowserInfoCS : TCriticalSection; + FShowPopUp : boolean; + FClosing : boolean; + FResizing : boolean; + FPendingResize : boolean; + FInitialized : boolean; + FDefaultURL : ustring; + FDelayMs : integer; + FOnSnapshotAvailable : TNotifyEvent; + FOnHTMLAvailable : TNotifyEvent; + FOnError : TNotifyEvent; + FErrorCode : integer; + FErrorText : ustring; + FFailedUrl : ustring; + FPendingUrl : ustring; + FSyncEvents : boolean; + FHTMLcopy : ustring; + + function GetErrorCode : integer; + function GetErrorText : ustring; + function GetFailedUrl : ustring; + function GetHTMLcopy : ustring; + function GetInitialized : boolean; + + procedure SetErrorText(const aValue : ustring); + procedure SetHTMLcopy(const aValue : ustring); + + procedure Browser_OnAfterCreated(Sender: TObject; const browser: ICefBrowser); + procedure Browser_OnPaint(Sender: TObject; const browser: ICefBrowser; kind: TCefPaintElementType; dirtyRectsCount: NativeUInt; const dirtyRects: PCefRectArray; const buffer: Pointer; aWidth, aHeight: Integer); + procedure Browser_OnGetViewRect(Sender: TObject; const browser: ICefBrowser; var rect: TCefRect); + procedure Browser_OnGetScreenPoint(Sender: TObject; const browser: ICefBrowser; viewX, viewY: Integer; var screenX, screenY: Integer; out Result: Boolean); + procedure Browser_OnGetScreenInfo(Sender: TObject; const browser: ICefBrowser; var screenInfo: TCefScreenInfo; out Result: Boolean); + procedure Browser_OnPopupShow(Sender: TObject; const browser: ICefBrowser; show: Boolean); + procedure Browser_OnPopupSize(Sender: TObject; const browser: ICefBrowser; const rect: PCefRect); + procedure Browser_OnBeforePopup(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; popup_id: Integer; 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 Browser_OnBeforeClose(Sender: TObject; const browser: ICefBrowser); + procedure Browser_OnLoadError(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; errorCode: TCefErrorCode; const errorText, failedUrl: ustring); + procedure Browser_OnLoadingStateChange(Sender: TObject; const browser: ICefBrowser; isLoading, canGoBack, canGoForward: Boolean); + procedure Browser_OnTextResultAvailable(Sender: TObject; const aText : ustring); + + procedure DoOnError; + procedure DoOnSnapshotAvailable; + procedure DoOnHTMLAvailable; + procedure Resize; + function CreateBrowser : boolean; + procedure CloseBrowser; + procedure InitError; + procedure WebpagePostProcessing; + procedure WebpageError; + procedure LoadPendingURL; + procedure Execute; override; + + public + constructor Create(const aDefaultURL : ustring; aWidth, aHeight : integer; aDelayMs : integer = 500; const aScreenScale : single = 1); + destructor Destroy; override; + procedure AfterConstruction; override; + function TerminateBrowserThread : boolean; + function CopySnapshot(var aSnapshot : TBitmap) : boolean; + function SaveSnapshotToFile(const aPath : ustring) : boolean; + procedure LoadUrl(const aURL : ustring); + + property ErrorCode : integer read GetErrorCode; + property ErrorText : ustring read GetErrorText write SetErrorText; + property FailedUrl : ustring read GetFailedUrl; + property Initialized : boolean read GetInitialized; + property Closing : boolean read FClosing; + property SyncEvents : boolean read FSyncEvents write FSyncEvents; + property HTMLcopy : ustring read GetHTMLcopy write SetHTMLcopy; + + property OnSnapshotAvailable : TNotifyEvent read FOnSnapshotAvailable write FOnSnapshotAvailable; + property OnHTMLAvailable : TNotifyEvent read FOnHTMLAvailable write FOnHTMLAvailable; + property OnError : TNotifyEvent read FOnError write FOnError; + end; + +implementation + +const + CEF_WEBPAGE_LOADED_MSG = WM_APP + 1; + CEF_WEBPAGE_ERROR_MSG = WM_APP + 2; + CEF_CLOSE_BROWSER_MSG = WM_APP + 3; + CEF_LOAD_PENDING_URL_MSG = WM_APP + 4; + +constructor TCEFBrowserThread.Create(const aDefaultURL : ustring; aWidth, aHeight, aDelayMs : integer; const aScreenScale : single); +begin + inherited Create(True); + + FreeOnTerminate := False; + FInitialized := False; + FBrowser := nil; + FBrowserBitmap := nil; + FBrowserSize.cx := aWidth; + FBrowserSize.cy := aHeight; + FScreenScale := aScreenScale; + FDefaultURL := aDefaultURL; + FPopUpBitmap := nil; + FPopUpRect := rect(0, 0, 0, 0); + FShowPopUp := False; + FResizing := False; + FPendingResize := False; + FResizeCS := nil; + FBrowserInfoCS := nil; + FDelayMs := aDelayMs; + FOnSnapshotAvailable := nil; + FOnHTMLAvailable := nil; + FOnError := nil; + FClosing := False; + FSyncEvents := False; +end; + +destructor TCEFBrowserThread.Destroy; +begin + if (FBrowser <> nil) then + FreeAndNil(FBrowser); + + if (FBrowserBitmap <> nil) then + FreeAndNil(FBrowserBitmap); + + if (FPopUpBitmap <> nil) then + FreeAndNil(FPopUpBitmap); + + if (FResizeCS <> nil) then + FreeAndNil(FResizeCS); + + if (FBrowserInfoCS <> nil) then + FreeAndNil(FBrowserInfoCS); + + inherited Destroy; +end; + +procedure TCEFBrowserThread.AfterConstruction; +begin + inherited AfterConstruction; + + FResizeCS := TCriticalSection.Create; + FBrowserInfoCS := TCriticalSection.Create; + + FBrowserBitmap := TCEFBrowserBitmap.Create; + FBrowserBitmap.PixelFormat := pf32bit; + FBrowserBitmap.HandleType := bmDIB; + FBrowserBitmap.DeviceScaleFactor := FScreenScale; + FBrowserBitmap.SetSize(FBrowserSize.cx, FBrowserSize.cy); + + FBrowser := TChromium.Create(nil); + FBrowser.DefaultURL := FDefaultURL; + FBrowser.Options.BackgroundColor := CefColorSetARGB($FF, $FF, $FF, $FF); + FBrowser.OnAfterCreated := Browser_OnAfterCreated; + FBrowser.OnPaint := Browser_OnPaint; + FBrowser.OnGetViewRect := Browser_OnGetViewRect; + FBrowser.OnGetScreenPoint := Browser_OnGetScreenPoint; + FBrowser.OnGetScreenInfo := Browser_OnGetScreenInfo; + FBrowser.OnPopupShow := Browser_OnPopupShow; + FBrowser.OnPopupSize := Browser_OnPopupSize; + FBrowser.OnBeforePopup := Browser_OnBeforePopup; + FBrowser.OnBeforeClose := Browser_OnBeforeClose; + FBrowser.OnLoadError := Browser_OnLoadError; + FBrowser.OnLoadingStateChange := Browser_OnLoadingStateChange; + FBrowser.OnTextResultAvailable := Browser_OnTextResultAvailable; +end; + +function TCEFBrowserThread.GetErrorCode : integer; +begin + if assigned(FBrowserInfoCS) then + try + FBrowserInfoCS.Acquire; + Result := FErrorCode; + finally + FBrowserInfoCS.Release; + end + else + Result := 0; +end; + +function TCEFBrowserThread.GetErrorText : ustring; +begin + if assigned(FBrowserInfoCS) then + try + FBrowserInfoCS.Acquire; + Result := FErrorText; + finally + FBrowserInfoCS.Release; + end + else + Result := ''; +end; + +function TCEFBrowserThread.GetFailedUrl : ustring; +begin + if assigned(FBrowserInfoCS) then + try + FBrowserInfoCS.Acquire; + Result := FFailedUrl; + finally + FBrowserInfoCS.Release; + end + else + Result := ''; +end; + +function TCEFBrowserThread.GetHTMLcopy : ustring; +begin + if assigned(FBrowserInfoCS) then + try + FBrowserInfoCS.Acquire; + Result := FHTMLcopy; + finally + FBrowserInfoCS.Release; + end + else + Result := ''; +end; + +function TCEFBrowserThread.GetInitialized : boolean; +begin + Result := False; + + if assigned(FBrowserInfoCS) and assigned(FBrowser) then + try + FBrowserInfoCS.Acquire; + Result := FInitialized and FBrowser.Initialized; + finally + FBrowserInfoCS.Release; + end; +end; + +procedure TCEFBrowserThread.SetErrorText(const aValue : ustring); +begin + if assigned(FBrowserInfoCS) then + try + FBrowserInfoCS.Acquire; + FErrorText := aValue; + finally + FBrowserInfoCS.Release; + end; +end; + +procedure TCEFBrowserThread.SetHTMLcopy(const aValue : ustring); +begin + if assigned(FBrowserInfoCS) then + try + FBrowserInfoCS.Acquire; + FHTMLcopy := aValue; + finally + FBrowserInfoCS.Release; + end; +end; + +function TCEFBrowserThread.CopySnapshot(var aSnapshot : TBitmap) : boolean; +begin + Result := False; + + if FClosing or Terminated or not(Initialized) then exit; + + if assigned(FBrowserInfoCS) then + try + try + FBrowserInfoCS.Acquire; + + if assigned(FBrowserBitmap) and not(FBrowserBitmap.Empty) then + begin + if (aSnapshot = nil) then + begin + aSnapshot := TBitmap.Create; + aSnapshot.PixelFormat := pf32bit; + aSnapshot.HandleType := bmDIB; + end; + + if (aSnapshot.Width <> FBrowserBitmap.Width) then + aSnapshot.Width := FBrowserBitmap.Width; + + if (aSnapshot.Height <> FBrowserBitmap.Height) then + aSnapshot.Height := FBrowserBitmap.Height; + + aSnapshot.Canvas.Draw(0, 0, FBrowserBitmap); + Result := True; + end; + except + on e : exception do + if CustomExceptionHandler('TCEFBrowserThread.CopySnapshot', e) then raise; + end; + finally + FBrowserInfoCS.Release; + end; +end; + +function TCEFBrowserThread.SaveSnapshotToFile(const aPath : ustring) : boolean; +begin + Result := False; + + if FClosing or Terminated or not(Initialized) then exit; + + if assigned(FBrowserInfoCS) and (length(aPath) > 0) then + try + try + FBrowserInfoCS.Acquire; + + if assigned(FBrowserBitmap) and not(FBrowserBitmap.Empty) then + begin + FBrowserBitmap.SaveToFile(aPath); + Result := True; + end; + except + on e : exception do + if CustomExceptionHandler('TCEFBrowserThread.SaveSnapshotToFile', e) then raise; + end; + finally + FBrowserInfoCS.Release; + end; +end; + +procedure TCEFBrowserThread.LoadUrl(const aURL : ustring); +begin + if FClosing or Terminated or not(Initialized) then exit; + + if assigned(FBrowserInfoCS) then + try + FBrowserInfoCS.Acquire; + FPendingUrl := aURL; + PostThreadMessage(ThreadID, CEF_LOAD_PENDING_URL_MSG, 0, 0); + finally + FBrowserInfoCS.Release; + end; +end; + +function TCEFBrowserThread.TerminateBrowserThread : boolean; +begin + Result := Initialized and + PostThreadMessage(ThreadID, CEF_CLOSE_BROWSER_MSG, 0, 0); +end; + +procedure TCEFBrowserThread.Browser_OnAfterCreated(Sender: TObject; const browser: ICefBrowser); +begin + if assigned(FBrowserInfoCS) then + try + FBrowserInfoCS.Acquire; + FInitialized := True; + finally + FBrowserInfoCS.Release; + end; +end; + +procedure TCEFBrowserThread.Browser_OnPaint(Sender: TObject; const browser: ICefBrowser; kind: TCefPaintElementType; dirtyRectsCount: NativeUInt; const dirtyRects: PCefRectArray; const buffer: Pointer; aWidth, aHeight: Integer); +var + src, dst: PByte; + i, j, TempLineSize, TempSrcOffset, TempDstOffset, SrcStride, DstStride : Integer; + n : NativeUInt; + TempWidth, TempHeight, TempScanlineSize : integer; + TempBufferBits : Pointer; + TempForcedResize : boolean; + TempSrcRect : TRect; +begin + if assigned(FResizeCS) and assigned(FBrowserBitmap) then + try + FResizeCS.Acquire; + TempForcedResize := False; + + if FBrowserBitmap.BeginDraw 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; + + TempWidth := FPopUpBitmap.Width; + TempHeight := FPopUpBitmap.Height; + TempScanlineSize := FPopUpBitmap.Width * SizeOf(TRGBQuad); + TempBufferBits := FPopUpBitmap.Scanline[pred(FPopUpBitmap.Height)]; + end + else + begin + TempForcedResize := FBrowserBitmap.UpdateDimensions(aWidth, aHeight); + TempWidth := FBrowserBitmap.Width; + TempHeight := FBrowserBitmap.Height; + TempScanlineSize := FBrowserBitmap.ScanlineSize; + TempBufferBits := FBrowserBitmap.BufferBits; + end; + + if (TempBufferBits <> nil) then + begin + SrcStride := aWidth * SizeOf(TRGBQuad); + DstStride := - TempScanlineSize; + + n := 0; + + while (n < dirtyRectsCount) do + begin + if (dirtyRects[n].x >= 0) and (dirtyRects[n].y >= 0) then + begin + TempLineSize := min(dirtyRects[n].width, TempWidth - dirtyRects[n].x) * SizeOf(TRGBQuad); + + if (TempLineSize > 0) then + begin + TempSrcOffset := ((dirtyRects[n].y * aWidth) + dirtyRects[n].x) * SizeOf(TRGBQuad); + TempDstOffset := ((TempScanlineSize * pred(TempHeight)) - (dirtyRects[n].y * TempScanlineSize)) + + (dirtyRects[n].x * SizeOf(TRGBQuad)); + + src := @PByte(buffer)[TempSrcOffset]; + dst := @PByte(TempBufferBits)[TempDstOffset]; + + i := 0; + j := min(dirtyRects[n].height, TempHeight - dirtyRects[n].y); + + while (i < j) do + begin + Move(src^, dst^, TempLineSize); + + Inc(dst, DstStride); + Inc(src, SrcStride); + inc(i); + end; + end; + end; + + inc(n); + end; + + 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)); + + FBrowserBitmap.BufferDraw(FPopUpBitmap, TempSrcRect, FPopUpRect); + end; + end; + + FBrowserBitmap.EndDraw; + + if (kind = PET_VIEW) then + begin + if TempForcedResize or FPendingResize then + PostThreadMessage(ThreadID, CEF_PENDINGRESIZE, 0, 0); + + FResizing := False; + FPendingResize := False; + end; + end; + finally + FResizeCS.Release; + end; +end; + +procedure TCEFBrowserThread.Browser_OnGetViewRect(Sender: TObject; const browser: ICefBrowser; var rect: TCefRect); +begin + rect.x := 0; + rect.y := 0; + rect.width := DeviceToLogical(FBrowserBitmap.Width, FScreenScale); + rect.height := DeviceToLogical(FBrowserBitmap.Height, FScreenScale); +end; + +procedure TCEFBrowserThread.Browser_OnGetScreenPoint(Sender: TObject; const browser: ICefBrowser; viewX, viewY: Integer; var screenX, screenY: Integer; out Result: Boolean); +begin + screenX := LogicalToDevice(viewX, FScreenScale); + screenY := LogicalToDevice(viewY, FScreenScale); + Result := True; +end; + +procedure TCEFBrowserThread.Browser_OnGetScreenInfo(Sender: TObject; const browser: ICefBrowser; var screenInfo: TCefScreenInfo; out Result: Boolean); +var + TempRect : TCEFRect; +begin + TempRect.x := 0; + TempRect.y := 0; + TempRect.width := DeviceToLogical(FBrowserBitmap.Width, FScreenScale); + TempRect.height := DeviceToLogical(FBrowserBitmap.Height, FScreenScale); + + screenInfo.device_scale_factor := FScreenScale; + screenInfo.depth := 0; + screenInfo.depth_per_component := 0; + screenInfo.is_monochrome := Ord(False); + screenInfo.rect := TempRect; + screenInfo.available_rect := TempRect; + + Result := True; +end; + +procedure TCEFBrowserThread.Browser_OnPopupShow(Sender: TObject; const browser: ICefBrowser; show: Boolean); +begin + if show then + FShowPopUp := True + else + begin + FShowPopUp := False; + FPopUpRect := rect(0, 0, 0, 0); + + if (FBrowser <> nil) then FBrowser.Invalidate(PET_VIEW); + end; +end; + +procedure TCEFBrowserThread.Browser_OnPopupSize(Sender: TObject; const browser: ICefBrowser; const rect: PCefRect); +begin + LogicalToDevice(rect^, FScreenScale); + + FPopUpRect.Left := rect.x; + FPopUpRect.Top := rect.y; + FPopUpRect.Right := rect.x + rect.width - 1; + FPopUpRect.Bottom := rect.y + rect.height - 1; +end; + +procedure TCEFBrowserThread.Browser_OnBeforePopup(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; popup_id: Integer; 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 [CEF_WOD_NEW_FOREGROUND_TAB, CEF_WOD_NEW_BACKGROUND_TAB, CEF_WOD_NEW_POPUP, CEF_WOD_NEW_WINDOW]); +end; + +procedure TCEFBrowserThread.Browser_OnBeforeClose(Sender: TObject; const browser: ICefBrowser); +begin + PostThreadMessage(ThreadID, WM_QUIT, 0, 0); +end; + +procedure TCEFBrowserThread.Browser_OnLoadError(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; errorCode: TCefErrorCode; const errorText, failedUrl: ustring); +begin + if not(FClosing) and not(Terminated) and (frame <> nil) and frame.IsValid and frame.IsMain and assigned(FBrowserInfoCS) then + try + FBrowserInfoCS.Acquire; + + FErrorCode := errorCode; + FErrorText := errorText; + FFailedUrl := failedUrl; + + PostThreadMessage(ThreadID, CEF_WEBPAGE_ERROR_MSG, 0, 0); + finally + FBrowserInfoCS.Release; + end; +end; + +procedure TCEFBrowserThread.Browser_OnLoadingStateChange(Sender: TObject; const browser: ICefBrowser; isLoading, canGoBack, canGoForward: Boolean); +begin + if not(FClosing) and not(Terminated) and not(isLoading) then + PostThreadMessage(ThreadID, CEF_WEBPAGE_LOADED_MSG, 0, 0); +end; + +procedure TCEFBrowserThread.Browser_OnTextResultAvailable(Sender: TObject; const aText : ustring); +begin + HTMLcopy := aText; + + if assigned(FOnHTMLAvailable) then + begin + if FSyncEvents then + Synchronize(DoOnHTMLAvailable) + else + DoOnHTMLAvailable; + end; +end; + +procedure TCEFBrowserThread.Resize; +begin + if FClosing or Terminated or not(Initialized) then exit; + + if assigned(FResizeCS) and assigned(FBrowserBitmap) then + try + FResizeCS.Acquire; + + if FResizing then + FPendingResize := True + else + begin + FResizing := True; + FBrowser.WasResized; + end; + finally + FResizeCS.Release; + end; +end; + +function TCEFBrowserThread.CreateBrowser : boolean; +begin + Result := (FBrowser <> nil) and FBrowser.CreateBrowser; +end; + +procedure TCEFBrowserThread.LoadPendingURL; +begin + if FClosing or Terminated or not(Initialized) then exit; + + if assigned(FBrowserInfoCS) then + try + FBrowserInfoCS.Acquire; + + if (length(FPendingURL) > 0) then + begin + FBrowser.LoadURL(FPendingURL); + FPendingURL := ''; + end; + finally + FBrowserInfoCS.Release; + end; +end; + +procedure TCEFBrowserThread.WebpagePostProcessing; +begin + if FClosing or Terminated then + exit; + + if (FDelayMs > 0) then + sleep(FDelayMs); + + if assigned(FOnHTMLAvailable) then + FBrowser.RetrieveHTML(); + + if assigned(FOnSnapshotAvailable) then + begin + if FSyncEvents then + Synchronize(DoOnSnapshotAvailable) + else + DoOnSnapshotAvailable; + end; +end; + +procedure TCEFBrowserThread.WebpageError; +begin + if not(FClosing) and not(Terminated) and assigned(FOnError) then + begin + if FSyncEvents then + Synchronize(DoOnError) + else + DoOnError; + end; +end; + +procedure TCEFBrowserThread.CloseBrowser; +begin + if not(FClosing) and assigned(FBrowser) then + begin + FClosing := True; + FBrowser.CloseBrowser(True); + end; +end; + +procedure TCEFBrowserThread.DoOnError; +begin + FOnError(self); +end; + +procedure TCEFBrowserThread.DoOnSnapshotAvailable; +begin + FOnSnapshotAvailable(self); +end; + +procedure TCEFBrowserThread.DoOnHTMLAvailable; +begin + FOnHTMLAvailable(self); +end; + +procedure TCEFBrowserThread.InitError; +begin + ErrorText := 'There was an error initializing the CEF browser.'; + + if FSyncEvents then + Synchronize(DoOnError) + else + DoOnError; +end; + +procedure TCEFBrowserThread.Execute; +var + TempCont : boolean; + TempMsg : TMsg; +begin + if CreateBrowser then + begin + TempCont := True; + PeekMessage(TempMsg, 0, WM_USER, WM_USER, PM_NOREMOVE); + + while TempCont and GetMessage(TempMsg, 0, 0, 0) and not(Terminated) do + begin + case TempMsg.Message of + CEF_PENDINGRESIZE : Resize; + CEF_CLOSE_BROWSER_MSG : CloseBrowser; + CEF_LOAD_PENDING_URL_MSG : LoadPendingURL; + CEF_WEBPAGE_LOADED_MSG : WebpagePostProcessing; + CEF_WEBPAGE_ERROR_MSG : WebpageError; + WM_QUIT : TempCont := False; + end; + + DispatchMessage(TempMsg); + end; + end + else + InitError; +end; + +end. diff --git a/demos/Delphi_UniGUI/WebpageSnapshot/uCEFLoader.pas b/demos/Delphi_UniGUI/WebpageSnapshot/uCEFLoader.pas new file mode 100644 index 00000000..eb2d4774 --- /dev/null +++ b/demos/Delphi_UniGUI/WebpageSnapshot/uCEFLoader.pas @@ -0,0 +1,26 @@ +unit uCEFLoader; + +interface + +uses + uCEFApplication; + +implementation + +procedure CreateGlobalCEFApp; +begin + GlobalCEFApp := TCefApplication.Create; + GlobalCEFApp.WindowlessRenderingEnabled := True; + GlobalCEFApp.ShowMessageDlg := False; + GlobalCEFApp.BrowserSubprocessPath := 'WebpageSnapshotUniGUI_sp.exe'; // This is the other EXE for the CEF subprocesses. It's on the same directory as this app. + GlobalCEFApp.BlinkSettings := 'hideScrollbars'; // This setting removes all scrollbars to capture a cleaner snapshot + GlobalCEFApp.StartMainProcess; +end; + +initialization + CreateGlobalCEFApp; + +finalization + DestroyGlobalCEFApp; + +end. diff --git a/update_CEF4Delphi.json b/update_CEF4Delphi.json index a77dd27f..92ae86d4 100644 --- a/update_CEF4Delphi.json +++ b/update_CEF4Delphi.json @@ -2,7 +2,7 @@ "UpdateLazPackages" : [ { "ForceNotify" : true, - "InternalVersion" : 692, + "InternalVersion" : 693, "Name" : "cef4delphi_lazarus.lpk", "Version" : "131.4.1" }