1
0
mirror of https://github.com/salvadordf/CEF4Delphi.git synced 2025-05-23 21:50:21 +02:00

Merge pull request #229 from salvadordf/beta

Branches and releases reorganization
This commit is contained in:
Salvador Díaz Fau 2019-10-15 11:30:31 +02:00 committed by GitHub
commit 50f6843cc8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
233 changed files with 8504 additions and 6114 deletions

View File

@ -3,10 +3,10 @@ CEF4Delphi is an open source project created by Salvador D
CEF4Delphi is based on DCEF3, made by Henri Gourvest. The original license of DCEF3 still applies to CEF4Delphi. Read the license terms in the first lines of any *.pas file. CEF4Delphi is based on DCEF3, made by Henri Gourvest. The original license of DCEF3 still applies to CEF4Delphi. Read the license terms in the first lines of any *.pas file.
CEF4Delphi uses CEF 76.1.13 which includes Chromium 76.0.3809.132. CEF4Delphi uses CEF 77.1.14 which includes Chromium 77.0.3865.120.
The CEF binaries used by CEF4Delphi are available for download at spotify : The CEF binaries used by CEF4Delphi are available for download at spotify :
* [32 bits](http://opensource.spotify.com/cefbuilds/cef_binary_76.1.13%2Bgf19c584%2Bchromium-76.0.3809.132_windows32.tar.bz2) * [32 bits](http://opensource.spotify.com/cefbuilds/cef_binary_77.1.14%2Bg4fb61d2%2Bchromium-77.0.3865.120_windows32.tar.bz2)
* [64 bits](http://opensource.spotify.com/cefbuilds/cef_binary_76.1.13%2Bgf19c584%2Bchromium-76.0.3809.132_windows64.tar.bz2) * [64 bits](http://opensource.spotify.com/cefbuilds/cef_binary_77.1.14%2Bg4fb61d2%2Bchromium-77.0.3865.120_windows64.tar.bz2)
CEF4Delphi was developed and tested on Delphi 10.3 Rio and it has been tested in Delphi 7, Delphi XE, Delphi 10, Delphi 10.2 and Lazarus 2.0.4/FPC 3.0.4. CEF4Delphi includes VCL, FireMonkey (FMX) and Lazarus components. CEF4Delphi was developed and tested on Delphi 10.3 Rio and it has been tested in Delphi 7, Delphi XE, Delphi 10, Delphi 10.2 and Lazarus 2.0.4/FPC 3.0.4. CEF4Delphi includes VCL, FireMonkey (FMX) and Lazarus components.
@ -16,6 +16,9 @@ CEF4Delphi was developed and tested on Delphi 10.3 Rio and it has been tested in
* [Developer Forums](https://www.briskbard.com/forum) * [Developer Forums](https://www.briskbard.com/forum)
* These components need Windows 7, 8, 8.1, 10 or newer to run. If you need Windows XP and Vista support use [OldCEF4Delphi](https://github.com/salvadordf/OldCEF4Delphi) * These components need Windows 7, 8, 8.1, 10 or newer to run. If you need Windows XP and Vista support use [OldCEF4Delphi](https://github.com/salvadordf/OldCEF4Delphi)
## Stable releases
This is the development branch and it may have issues. Use the [latest release](https://github.com/salvadordf/CEF4Delphi/releases) if you need a stable component.
## Suppport ## Suppport
If you find this project useful, please consider making a donation. If you find this project useful, please consider making a donation.

View File

@ -5,7 +5,7 @@
<FrameworkType>FMX</FrameworkType> <FrameworkType>FMX</FrameworkType>
<MainSource>FMXExternalPumpBrowser.dpr</MainSource> <MainSource>FMXExternalPumpBrowser.dpr</MainSource>
<Base>True</Base> <Base>True</Base>
<Config Condition="'$(Config)'==''">Release</Config> <Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform> <Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>3</TargetedPlatforms> <TargetedPlatforms>3</TargetedPlatforms>
<AppType>Application</AppType> <AppType>Application</AppType>

View File

@ -199,7 +199,6 @@ begin
GlobalCEFApp.ExternalMessagePump := True; GlobalCEFApp.ExternalMessagePump := True;
GlobalCEFApp.MultiThreadedMessageLoop := False; GlobalCEFApp.MultiThreadedMessageLoop := False;
GlobalCEFApp.OnScheduleMessagePumpWork := GlobalCEFApp_OnScheduleMessagePumpWork; GlobalCEFApp.OnScheduleMessagePumpWork := GlobalCEFApp_OnScheduleMessagePumpWork;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end; end;
procedure TFMXExternalPumpBrowserFrm.FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure TFMXExternalPumpBrowserFrm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);

View File

@ -5,7 +5,7 @@
<FrameworkType>FMX</FrameworkType> <FrameworkType>FMX</FrameworkType>
<MainSource>FMXToolBoxBrowser.dpr</MainSource> <MainSource>FMXToolBoxBrowser.dpr</MainSource>
<Base>True</Base> <Base>True</Base>
<Config Condition="'$(Config)'==''">Release</Config> <Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform> <Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>3</TargetedPlatforms> <TargetedPlatforms>3</TargetedPlatforms>
<AppType>Application</AppType> <AppType>Application</AppType>

View File

@ -133,7 +133,6 @@ procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnContextInitialized := GlobalCEFApp_OnContextInitialized; GlobalCEFApp.OnContextInitialized := GlobalCEFApp_OnContextInitialized;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end; end;
function TMainForm.PostCustomMessage(aMessage, wParam : cardinal; lParam : integer) : boolean; function TMainForm.PostCustomMessage(aMessage, wParam : cardinal; lParam : integer) : boolean;

View File

@ -5,7 +5,7 @@
<FrameworkType>FMX</FrameworkType> <FrameworkType>FMX</FrameworkType>
<MainSource>SimpleFMXBrowser.dpr</MainSource> <MainSource>SimpleFMXBrowser.dpr</MainSource>
<Base>True</Base> <Base>True</Base>
<Config Condition="'$(Config)'==''">Release</Config> <Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform> <Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>3</TargetedPlatforms> <TargetedPlatforms>3</TargetedPlatforms>
<AppType>Application</AppType> <AppType>Application</AppType>

View File

@ -149,7 +149,6 @@ uses
procedure CreateGlobalCEFApp; procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
//GlobalCEFApp.LogFile := 'cef.log'; //GlobalCEFApp.LogFile := 'cef.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE; //GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;

View File

@ -113,7 +113,6 @@ begin
GlobalCEFApp.BrowserSubprocessPath := 'OSRSubProcess.exe'; GlobalCEFApp.BrowserSubprocessPath := 'OSRSubProcess.exe';
GlobalCEFApp.ExternalMessagePump := False; GlobalCEFApp.ExternalMessagePump := False;
GlobalCEFApp.MultiThreadedMessageLoop := False; GlobalCEFApp.MultiThreadedMessageLoop := False;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
// This demo uses a different EXE for the subprocesses. // This demo uses a different EXE for the subprocesses.
// With this configuration it's not necessary to have the // With this configuration it's not necessary to have the

View File

@ -78,7 +78,6 @@ begin
GlobalCEFApp.SetCurrentDir := True; GlobalCEFApp.SetCurrentDir := True;
GlobalCEFApp.ExternalMessagePump := False; GlobalCEFApp.ExternalMessagePump := False;
GlobalCEFApp.MultiThreadedMessageLoop := False; GlobalCEFApp.MultiThreadedMessageLoop := False;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
GlobalCEFApp.StartSubProcess; GlobalCEFApp.StartSubProcess;
GlobalCEFApp.Free; GlobalCEFApp.Free;

View File

@ -82,4 +82,9 @@ object CookieVisitorFrm: TCookieVisitorFrm
Left = 32 Left = 32
Top = 280 Top = 280
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 32
Top = 336
end
end end

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFCookieManager, uCEFCookieVisitor, uCEFWinControl; uCEFCookieManager, uCEFCookieVisitor, uCEFWinControl, uCEFSentinel;
const const
MINIBROWSER_SHOWCOOKIES = WM_APP + $101; MINIBROWSER_SHOWCOOKIES = WM_APP + $101;
@ -68,6 +68,7 @@ type
CEFWindowParent1: TCEFWindowParent; CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium; Chromium1: TChromium;
Timer1: TTimer; Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
@ -96,6 +97,7 @@ type
var aAction : TCefCloseBrowserAction); var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject; procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
private private
procedure WMMove(var aMessage : TWMMove); message WM_MOVE; procedure WMMove(var aMessage : TWMMove); message WM_MOVE;
@ -141,12 +143,12 @@ uses
// ================= // =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. // 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure CreateGlobalCEFApp; procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
//GlobalCEFApp.LogFile := 'cef.log'; //GlobalCEFApp.LogFile := 'cef.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE; //GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end; end;
@ -230,6 +232,12 @@ begin
Chromium1.LoadURL(Edit1.Text); Chromium1.LoadURL(Edit1.Text);
end; end;
procedure TCookieVisitorFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TCookieVisitorFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure TCookieVisitorFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0); PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -237,8 +245,7 @@ end;
procedure TCookieVisitorFrm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); procedure TCookieVisitorFrm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TCookieVisitorFrm.Chromium1BeforeContextMenu(Sender: TObject; procedure TCookieVisitorFrm.Chromium1BeforeContextMenu(Sender: TObject;

View File

@ -159,7 +159,7 @@ begin
if (FStream <> nil) and (DataOut <> nil) then if (FStream <> nil) and (DataOut <> nil) then
begin begin
BytesRead := FStream.Read(DataOut^, BytesToRead); BytesRead := FStream.Read(DataOut^, BytesToRead);
Result := True; Result := (BytesRead > 0);
end end
else else
Result := False; Result := False;

View File

@ -12,7 +12,6 @@ object MainForm: TMainForm
Font.Style = [] Font.Style = []
OldCreateOrder = False OldCreateOrder = False
Position = poScreenCenter Position = poScreenCenter
OnClose = FormClose
OnCloseQuery = FormCloseQuery OnCloseQuery = FormCloseQuery
OnCreate = FormCreate OnCreate = FormCreate
OnShow = FormShow OnShow = FormShow
@ -73,4 +72,9 @@ object MainForm: TMainForm
Left = 48 Left = 48
Top = 240 Top = 240
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 48
Top = 304
end
end end

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFChromiumWindow, uCEFInterfaces, uCustomResourceHandler, uCEFChromium, uCEFWindowParent, uCEFChromiumWindow, uCEFInterfaces, uCustomResourceHandler,
uCEFConstants, uCEFTypes, uCEFWinControl; uCEFConstants, uCEFTypes, uCEFWinControl, uCEFSentinel;
type type
TMainForm = class(TForm) TMainForm = class(TForm)
@ -59,17 +59,18 @@ type
Edit1: TEdit; Edit1: TEdit;
Button1: TButton; Button1: TButton;
Timer1: TTimer; Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject); procedure Button1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject); procedure Timer1Timer(Sender: TObject);
procedure ChromiumWindow1Close(Sender: TObject); procedure ChromiumWindow1Close(Sender: TObject);
procedure ChromiumWindow1BeforeClose(Sender: TObject); procedure ChromiumWindow1BeforeClose(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
private private
procedure WMMove(var aMessage : TWMMove); message WM_MOVE; procedure WMMove(var aMessage : TWMMove); message WM_MOVE;
@ -108,12 +109,12 @@ uses
// ================= // =================
// 1. The FormCloseQuery event sets CanClose to False and calls TChromiumWindow.CloseBrowser, which triggers the TChromiumWindow.OnClose event. // 1. The FormCloseQuery event sets CanClose to False and calls TChromiumWindow.CloseBrowser, which triggers the TChromiumWindow.OnClose event.
// 2. The TChromiumWindow.OnClose event calls TChromiumWindow.DestroyChildWindow which triggers the TChromiumWindow.OnBeforeClose event. // 2. The TChromiumWindow.OnClose event calls TChromiumWindow.DestroyChildWindow which triggers the TChromiumWindow.OnBeforeClose event.
// 3. TChromiumWindow.OnBeforeClose sets FCanClose to True and closes the form. // 3. TChromiumWindow.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure CreateGlobalCEFApp; procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
//GlobalCEFApp.LogFile := 'cef.log'; //GlobalCEFApp.LogFile := 'cef.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE; //GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end; end;
@ -123,11 +124,6 @@ begin
ChromiumWindow1.LoadURL(Edit1.Text); ChromiumWindow1.LoadURL(Edit1.Text);
end; end;
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FHandler := nil;
end;
procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin begin
CanClose := FCanClose; CanClose := FCanClose;
@ -136,6 +132,7 @@ begin
begin begin
FClosing := True; FClosing := True;
Visible := False; Visible := False;
FHandler := nil;
ChromiumWindow1.CloseBrowser(True); ChromiumWindow1.CloseBrowser(True);
end; end;
end; end;
@ -179,20 +176,21 @@ begin
Timer1.Enabled := True; Timer1.Enabled := True;
end; end;
procedure TMainForm.ChromiumWindow1BeforeClose(Sender: TObject); procedure TMainForm.CEFSentinel1Close(Sender: TObject);
begin begin
FCanClose := True; FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0); PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TMainForm.ChromiumWindow1BeforeClose(Sender: TObject);
begin
CEFSentinel1.Start;
end;
procedure TMainForm.ChromiumWindow1Close(Sender: TObject); procedure TMainForm.ChromiumWindow1Close(Sender: TObject);
begin begin
// DestroyChildWindow will destroy the child window created by CEF at the top of the Z order. // DestroyChildWindow will destroy the child window created by CEF at the top of the Z order.
if not(ChromiumWindow1.DestroyChildWindow) then if not(ChromiumWindow1.DestroyChildWindow) then CEFSentinel1.Start;
begin
FCanClose := True;
Close;
end;
end; end;
procedure TMainForm.Chromium_OnAfterCreated(Sender: TObject); procedure TMainForm.Chromium_OnAfterCreated(Sender: TObject);

View File

@ -100,7 +100,6 @@ begin
GlobalCEFApp.UserDataPath := 'cef\User Data'; GlobalCEFApp.UserDataPath := 'cef\User Data';
} }
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
GlobalCEFApp.SetCurrentDir := True; GlobalCEFApp.SetCurrentDir := True;
GlobalCEFApp.BrowserSubprocessPath := 'SubProcess.exe'; GlobalCEFApp.BrowserSubprocessPath := 'SubProcess.exe';

View File

@ -70,7 +70,6 @@ begin
GlobalCEFApp.UserDataPath := 'cef\User Data'; GlobalCEFApp.UserDataPath := 'cef\User Data';
} }
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
GlobalCEFApp.SetCurrentDir := True; GlobalCEFApp.SetCurrentDir := True;
GlobalCEFApp.StartSubProcess; GlobalCEFApp.StartSubProcess;

View File

@ -110,4 +110,9 @@ object DOMVisitorFrm: TDOMVisitorFrm
Left = 16 Left = 16
Top = 96 Top = 96
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 16
Top = 160
end
end end

View File

@ -51,7 +51,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Types, ComCtrls, ClipBrd, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Types, ComCtrls, ClipBrd,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFWinControl; uCEFWinControl, uCEFSentinel;
const const
MINIBROWSER_VISITDOM_PARTIAL = WM_APP + $101; MINIBROWSER_VISITDOM_PARTIAL = WM_APP + $101;
@ -81,6 +81,7 @@ type
Panel1: TPanel; Panel1: TPanel;
GoBtn: TButton; GoBtn: TButton;
VisitDOMBtn: TButton; VisitDOMBtn: TButton;
CEFSentinel1: TCEFSentinel;
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; procedure Chromium1AfterCreated(Sender: TObject;
@ -111,6 +112,7 @@ type
var aAction : TCefCloseBrowserAction); var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject; procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
private private
{ Private declarations } { Private declarations }
protected protected
@ -165,7 +167,8 @@ uses
// ================= // =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. // 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure SimpleDOMIteration(const aDocument: ICefDomDocument); procedure SimpleDOMIteration(const aDocument: ICefDomDocument);
var var
@ -226,7 +229,7 @@ end;
procedure DOMVisitor_OnDocAvailable(const browser: ICefBrowser; const frame: ICefFrame; const document: ICefDomDocument); procedure DOMVisitor_OnDocAvailable(const browser: ICefBrowser; const frame: ICefFrame; const document: ICefDomDocument);
var var
msg: ICefProcessMessage; TempMessage : ICefProcessMessage;
begin begin
// This function is called from a different process. // This function is called from a different process.
// document is only valid inside this function. // document is only valid inside this function.
@ -247,21 +250,33 @@ begin
// Sending back some custom results to the browser process // Sending back some custom results to the browser process
// Notice that the DOMVISITOR_MSGNAME_PARTIAL message name needs to be recognized in // Notice that the DOMVISITOR_MSGNAME_PARTIAL message name needs to be recognized in
// Chromium1ProcessMessageReceived // Chromium1ProcessMessageReceived
msg := TCefProcessMessageRef.New(DOMVISITOR_MSGNAME_PARTIAL); try
msg.ArgumentList.SetString(0, 'document.Title : ' + document.Title); TempMessage := TCefProcessMessageRef.New(DOMVISITOR_MSGNAME_PARTIAL);
frame.SendProcessMessage(PID_BROWSER, msg); TempMessage.ArgumentList.SetString(0, 'document.Title : ' + document.Title);
if (frame <> nil) and frame.IsValid then
frame.SendProcessMessage(PID_BROWSER, TempMessage);
finally
TempMessage := nil;
end;
end; end;
procedure DOMVisitor_OnDocAvailableFullMarkup(const browser: ICefBrowser; const frame: ICefFrame; const document: ICefDomDocument); procedure DOMVisitor_OnDocAvailableFullMarkup(const browser: ICefBrowser; const frame: ICefFrame; const document: ICefDomDocument);
var var
msg: ICefProcessMessage; TempMessage : ICefProcessMessage;
begin begin
// Sending back some custom results to the browser process // Sending back some custom results to the browser process
// Notice that the DOMVISITOR_MSGNAME_FULL message name needs to be recognized in // Notice that the DOMVISITOR_MSGNAME_FULL message name needs to be recognized in
// Chromium1ProcessMessageReceived // Chromium1ProcessMessageReceived
msg := TCefProcessMessageRef.New(DOMVISITOR_MSGNAME_FULL); try
msg.ArgumentList.SetString(0, document.Body.AsMarkup); TempMessage := TCefProcessMessageRef.New(DOMVISITOR_MSGNAME_FULL);
frame.SendProcessMessage(PID_BROWSER, msg); TempMessage.ArgumentList.SetString(0, document.Body.AsMarkup);
if (frame <> nil) and frame.IsValid then
frame.SendProcessMessage(PID_BROWSER, TempMessage);
finally
TempMessage := nil;
end;
end; end;
procedure DOMVisitor_GetFrameIDs(const browser: ICefBrowser; const frame : ICefFrame); procedure DOMVisitor_GetFrameIDs(const browser: ICefBrowser; const frame : ICefFrame);
@ -285,9 +300,15 @@ begin
inc(i); inc(i);
end; end;
try
TempMsg := TCefProcessMessageRef.New(FRAMEIDS_MSGNAME); TempMsg := TCefProcessMessageRef.New(FRAMEIDS_MSGNAME);
TempMsg.ArgumentList.SetString(0, TempString); TempMsg.ArgumentList.SetString(0, TempString);
if (frame <> nil) and frame.IsValid then
frame.SendProcessMessage(PID_BROWSER, TempMsg); frame.SendProcessMessage(PID_BROWSER, TempMsg);
finally
TempMsg := nil;
end;
end; end;
end; end;
@ -297,7 +318,6 @@ procedure GlobalCEFApp_OnProcessMessageReceived(const browser : ICefBrowse
const message : ICefProcessMessage; const message : ICefProcessMessage;
var aHandled : boolean); var aHandled : boolean);
var var
TempFrame : ICefFrame;
TempVisitor : TCefFastDomVisitor2; TempVisitor : TCefFastDomVisitor2;
begin begin
aHandled := False; aHandled := False;
@ -306,12 +326,10 @@ begin
begin begin
if (message.name = RETRIEVEDOM_MSGNAME_PARTIAL) then if (message.name = RETRIEVEDOM_MSGNAME_PARTIAL) then
begin begin
TempFrame := browser.MainFrame; if (frame <> nil) and frame.IsValid then
if (TempFrame <> nil) then
begin begin
TempVisitor := TCefFastDomVisitor2.Create(browser, TempFrame, DOMVisitor_OnDocAvailable); TempVisitor := TCefFastDomVisitor2.Create(browser, frame, DOMVisitor_OnDocAvailable);
TempFrame.VisitDom(TempVisitor); frame.VisitDom(TempVisitor);
end; end;
aHandled := True; aHandled := True;
@ -319,12 +337,10 @@ begin
else else
if (message.name = RETRIEVEDOM_MSGNAME_FULL) then if (message.name = RETRIEVEDOM_MSGNAME_FULL) then
begin begin
TempFrame := browser.MainFrame; if (frame <> nil) and frame.IsValid then
if (TempFrame <> nil) then
begin begin
TempVisitor := TCefFastDomVisitor2.Create(browser, TempFrame, DOMVisitor_OnDocAvailableFullMarkup); TempVisitor := TCefFastDomVisitor2.Create(browser, frame, DOMVisitor_OnDocAvailableFullMarkup);
TempFrame.VisitDom(TempVisitor); frame.VisitDom(TempVisitor);
end; end;
aHandled := True; aHandled := True;
@ -343,7 +359,6 @@ begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.RemoteDebuggingPort := 9000; GlobalCEFApp.RemoteDebuggingPort := 9000;
GlobalCEFApp.OnProcessMessageReceived := GlobalCEFApp_OnProcessMessageReceived; GlobalCEFApp.OnProcessMessageReceived := GlobalCEFApp_OnProcessMessageReceived;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
// Enabling the debug log file for then DOM visitor demo. // Enabling the debug log file for then DOM visitor demo.
// This adds lots of warnings to the console, specially if you run this inside VirtualBox. // This adds lots of warnings to the console, specially if you run this inside VirtualBox.
@ -352,6 +367,12 @@ begin
GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO; GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO;
end; end;
procedure TDOMVisitorFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TDOMVisitorFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure TDOMVisitorFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0); PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -360,8 +381,7 @@ end;
procedure TDOMVisitorFrm.Chromium1BeforeClose(Sender: TObject; procedure TDOMVisitorFrm.Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TDOMVisitorFrm.Chromium1BeforeContextMenu(Sender: TObject; procedure TDOMVisitorFrm.Chromium1BeforeContextMenu(Sender: TObject;

View File

@ -1122,4 +1122,9 @@ object Form1: TForm1
Left = 128 Left = 128
Top = 200 Top = 200
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 56
Top = 256
end
end end

View File

@ -52,7 +52,7 @@ uses
ImageList, ImgList, ImageList, ImgList,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes,
uCEFWinControl; uCEFWinControl, uCEFSentinel;
type type
TForm1 = class(TForm) TForm1 = class(TForm)
@ -91,6 +91,7 @@ type
RemoveFormatBtn: TToolButton; RemoveFormatBtn: TToolButton;
OutdentBtn: TToolButton; OutdentBtn: TToolButton;
Separator7: TToolButton; Separator7: TToolButton;
CEFSentinel1: TCEFSentinel;
procedure Timer1Timer(Sender: TObject); procedure Timer1Timer(Sender: TObject);
@ -124,6 +125,7 @@ type
procedure FillColorBtnClick(Sender: TObject); procedure FillColorBtnClick(Sender: TObject);
procedure RemoveFormatBtnClick(Sender: TObject); procedure RemoveFormatBtnClick(Sender: TObject);
procedure OutdentBtnClick(Sender: TObject); procedure OutdentBtnClick(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
protected protected
// Variables to control when can we destroy the form safely // Variables to control when can we destroy the form safely
@ -170,12 +172,14 @@ uses
// ================= // =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. // 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure CreateGlobalCEFApp; procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors'; //GlobalCEFApp.LogFile := 'cef.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end; end;
procedure TForm1.FillColorBtnClick(Sender: TObject); procedure TForm1.FillColorBtnClick(Sender: TObject);
@ -225,6 +229,12 @@ begin
if not(Chromium1.CreateBrowser(CEFWindowParent1)) then Timer1.Enabled := True; if not(Chromium1.CreateBrowser(CEFWindowParent1)) then Timer1.Enabled := True;
end; end;
procedure TForm1.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TForm1.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure TForm1.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin begin
// Now the browser is fully initialized we can send a message to the main form to load the initial web page. // Now the browser is fully initialized we can send a message to the main form to load the initial web page.
@ -234,8 +244,7 @@ end;
procedure TForm1.Chromium1BeforeClose(Sender: TObject; procedure TForm1.Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TForm1.Chromium1Close(Sender: TObject; procedure TForm1.Chromium1Close(Sender: TObject;
@ -249,7 +258,7 @@ procedure TForm1.Chromium1LoadEnd(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame; const browser: ICefBrowser; const frame: ICefFrame;
httpStatusCode: Integer); httpStatusCode: Integer);
begin begin
if (frame <> nil) and not(frame.isMain) then exit; if (frame <> nil) and (not(frame.IsValid) or not(frame.isMain)) then exit;
// Enable the "designMode" for all loaded files to edit them // Enable the "designMode" for all loaded files to edit them
EnableDesignMode; EnableDesignMode;

View File

@ -99,4 +99,9 @@ object ExternalPumpBrowserFrm: TExternalPumpBrowserFrm
Left = 56 Left = 56
Top = 152 Top = 152
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 56
Top = 224
end
end end

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFTypes, uCEFConstants, uCEFInterfaces, uCEFWorkScheduler, uCEFChromium, uCEFWindowParent, uCEFTypes, uCEFConstants, uCEFInterfaces, uCEFWorkScheduler,
uCEFWinControl; uCEFWinControl, uCEFSentinel;
type type
TExternalPumpBrowserFrm = class(TForm) TExternalPumpBrowserFrm = class(TForm)
@ -60,6 +60,7 @@ type
CEFWindowParent1: TCEFWindowParent; CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium; Chromium1: TChromium;
URLCbx: TComboBox; URLCbx: TComboBox;
CEFSentinel1: TCEFSentinel;
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
@ -79,6 +80,7 @@ type
var client: ICefClient; var settings: TCefBrowserSettings; var client: ICefClient; var settings: TCefBrowserSettings;
var extra_info: ICefDictionaryValue; var extra_info: ICefDictionaryValue;
var noJavascriptAccess: Boolean; var Result: Boolean); var noJavascriptAccess: Boolean; var Result: Boolean);
procedure CEFSentinel1Close(Sender: TObject);
private private
FCanClose : boolean; FCanClose : boolean;
@ -110,6 +112,13 @@ uses
// This demo has a simple browser with a TChromium + TCEFWindowParent combination // This demo has a simple browser with a TChromium + TCEFWindowParent combination
// It was necessary to destroy the browser following the destruction sequence described in the MDIBrowser demo. // It was necessary to destroy the browser following the destruction sequence described in the MDIBrowser demo.
// Destruction steps
// =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure GlobalCEFApp_OnScheduleMessagePumpWork(const aDelayMS : int64); procedure GlobalCEFApp_OnScheduleMessagePumpWork(const aDelayMS : int64);
begin begin
if (GlobalCEFWorkScheduler <> nil) then GlobalCEFWorkScheduler.ScheduleMessagePumpWork(aDelayMS); if (GlobalCEFWorkScheduler <> nil) then GlobalCEFWorkScheduler.ScheduleMessagePumpWork(aDelayMS);
@ -128,7 +137,6 @@ begin
GlobalCEFApp.ExternalMessagePump := True; GlobalCEFApp.ExternalMessagePump := True;
GlobalCEFApp.MultiThreadedMessageLoop := False; GlobalCEFApp.MultiThreadedMessageLoop := False;
GlobalCEFApp.OnScheduleMessagePumpWork := GlobalCEFApp_OnScheduleMessagePumpWork; GlobalCEFApp.OnScheduleMessagePumpWork := GlobalCEFApp_OnScheduleMessagePumpWork;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end; end;
procedure TExternalPumpBrowserFrm.FormCreate(Sender: TObject); procedure TExternalPumpBrowserFrm.FormCreate(Sender: TObject);
@ -145,7 +153,6 @@ begin
begin begin
FClosing := True; FClosing := True;
Visible := False; Visible := False;
AddressPnl.Enabled := False;
Chromium1.CloseBrowser(True); Chromium1.CloseBrowser(True);
end; end;
end; end;
@ -157,6 +164,12 @@ begin
if not(Chromium1.CreateBrowser(CEFWindowParent1, '')) then Timer1.Enabled := True; if not(Chromium1.CreateBrowser(CEFWindowParent1, '')) then Timer1.Enabled := True;
end; end;
procedure TExternalPumpBrowserFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TExternalPumpBrowserFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure TExternalPumpBrowserFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0); PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -164,8 +177,7 @@ end;
procedure TExternalPumpBrowserFrm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); procedure TExternalPumpBrowserFrm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TExternalPumpBrowserFrm.Chromium1BeforePopup(Sender: TObject; procedure TExternalPumpBrowserFrm.Chromium1BeforePopup(Sender: TObject;

View File

@ -45,4 +45,9 @@ object MainForm: TMainForm
Left = 272 Left = 272
Top = 120 Top = 120
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 328
Top = 120
end
end end

View File

@ -49,13 +49,14 @@ uses
Controls, Forms, Dialogs, Controls, Forms, Dialogs,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFTypes, uCEFConstants, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFTypes, uCEFConstants,
Vcl.ExtCtrls, uCEFWinControl; Vcl.ExtCtrls, uCEFWinControl, uCEFSentinel;
type type
TMainForm = class(TForm) TMainForm = class(TForm)
CEFWindowParent1: TCEFWindowParent; CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium; Chromium1: TChromium;
Timer1: TTimer; Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure Chromium1PreKeyEvent(Sender: TObject; procedure Chromium1PreKeyEvent(Sender: TObject;
const browser: ICefBrowser; const event: PCefKeyEvent; osEvent: PMsg; const browser: ICefBrowser; const event: PCefKeyEvent; osEvent: PMsg;
out isKeyboardShortcut, Result: Boolean); out isKeyboardShortcut, Result: Boolean);
@ -80,6 +81,7 @@ type
const browser: ICefBrowser); const browser: ICefBrowser);
procedure Chromium1Close(Sender: TObject; const browser: ICefBrowser; procedure Chromium1Close(Sender: TObject; const browser: ICefBrowser;
var aAction : TCefCloseBrowserAction); var aAction : TCefCloseBrowserAction);
procedure CEFSentinel1Close(Sender: TObject);
private private
{ Private declarations } { Private declarations }
protected protected
@ -112,10 +114,16 @@ implementation
uses uses
uCEFApplication; uCEFApplication;
// Destruction steps
// =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure CreateGlobalCEFApp; procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
//GlobalCEFApp.LogFile := 'cef.log'; //GlobalCEFApp.LogFile := 'cef.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE; //GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end; end;
@ -158,6 +166,12 @@ begin
if (TempKeyMsg.CharCode = VK_ESCAPE) then aHandled := True; if (TempKeyMsg.CharCode = VK_ESCAPE) then aHandled := True;
end; end;
procedure TMainForm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TMainForm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure TMainForm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0); PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -165,8 +179,7 @@ end;
procedure TMainForm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); procedure TMainForm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TMainForm.Chromium1BeforePopup(Sender: TObject; procedure TMainForm.Chromium1BeforePopup(Sender: TObject;

View File

@ -72,4 +72,9 @@ object JSDialogBrowserFrm: TJSDialogBrowserFrm
Left = 56 Left = 56
Top = 88 Top = 88
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 56
Top = 152
end
end end

View File

@ -44,13 +44,13 @@ interface
uses uses
{$IFDEF DELPHI16_UP} {$IFDEF DELPHI16_UP}
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, System.SyncObjs, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, System.SyncObjs, System.UITypes,
{$ELSE} {$ELSE}
Windows, Messages, SysUtils, Variants, Classes, Graphics, Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, SyncObjs, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, SyncObjs,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFChromiumWindow, uCEFInterfaces, uCEFTypes, uCEFConstants, uCEFChromium, uCEFWindowParent, uCEFChromiumWindow, uCEFInterfaces, uCEFTypes, uCEFConstants,
uCEFWinControl; uCEFWinControl, uCEFSentinel;
const const
CEFBROWSER_SHOWJSDIALOG = WM_APP + $101; CEFBROWSER_SHOWJSDIALOG = WM_APP + $101;
@ -62,6 +62,7 @@ type
AddressEdt: TEdit; AddressEdt: TEdit;
GoBtn: TButton; GoBtn: TButton;
Timer1: TTimer; Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure ChromiumWindow1AfterCreated(Sender: TObject); procedure ChromiumWindow1AfterCreated(Sender: TObject);
@ -71,6 +72,7 @@ type
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure ChromiumWindow1Close(Sender: TObject); procedure ChromiumWindow1Close(Sender: TObject);
procedure ChromiumWindow1BeforeClose(Sender: TObject); procedure ChromiumWindow1BeforeClose(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
protected protected
FJSDialogInfoCS : TCriticalSection; FJSDialogInfoCS : TCriticalSection;
@ -114,12 +116,12 @@ uses
// ================= // =================
// 1. The FormCloseQuery event sets CanClose to False and calls TChromiumWindow.CloseBrowser, which triggers the TChromiumWindow.OnClose event. // 1. The FormCloseQuery event sets CanClose to False and calls TChromiumWindow.CloseBrowser, which triggers the TChromiumWindow.OnClose event.
// 2. The TChromiumWindow.OnClose event calls TChromiumWindow.DestroyChildWindow which triggers the TChromiumWindow.OnBeforeClose event. // 2. The TChromiumWindow.OnClose event calls TChromiumWindow.DestroyChildWindow which triggers the TChromiumWindow.OnBeforeClose event.
// 3. TChromiumWindow.OnBeforeClose sets FCanClose to True and closes the form. // 3. TChromiumWindow.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure CreateGlobalCEFApp; procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
//GlobalCEFApp.LogFile := 'cef.log'; //GlobalCEFApp.LogFile := 'cef.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE; //GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end; end;
@ -165,6 +167,12 @@ begin
if not(ChromiumWindow1.CreateBrowser) then Timer1.Enabled := True; if not(ChromiumWindow1.CreateBrowser) then Timer1.Enabled := True;
end; end;
procedure TJSDialogBrowserFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSDialogBrowserFrm.ChromiumWindow1AfterCreated(Sender: TObject); procedure TJSDialogBrowserFrm.ChromiumWindow1AfterCreated(Sender: TObject);
begin begin
Caption := 'JS Dialog Browser'; Caption := 'JS Dialog Browser';
@ -249,18 +257,13 @@ end;
procedure TJSDialogBrowserFrm.ChromiumWindow1BeforeClose(Sender: TObject); procedure TJSDialogBrowserFrm.ChromiumWindow1BeforeClose(Sender: TObject);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TJSDialogBrowserFrm.ChromiumWindow1Close(Sender: TObject); procedure TJSDialogBrowserFrm.ChromiumWindow1Close(Sender: TObject);
begin begin
// DestroyChildWindow will destroy the child window created by CEF at the top of the Z order. // DestroyChildWindow will destroy the child window created by CEF at the top of the Z order.
if not(ChromiumWindow1.DestroyChildWindow) then if not(ChromiumWindow1.DestroyChildWindow) then CEFSentinel1.Start;
begin
FCanClose := True;
Close;
end;
end; end;
procedure TJSDialogBrowserFrm.Chromium_OnBeforePopup(Sender: TObject; procedure TJSDialogBrowserFrm.Chromium_OnBeforePopup(Sender: TObject;

View File

@ -79,4 +79,9 @@ object JSEvalFrm: TJSEvalFrm
Left = 16 Left = 16
Top = 96 Top = 96
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 16
Top = 160
end
end end

View File

@ -51,7 +51,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Types, ComCtrls, ClipBrd, EncdDecd, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Types, ComCtrls, ClipBrd, EncdDecd,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFWinControl; uCEFWinControl, uCEFSentinel;
const const
MINIBROWSER_SHOWTEXTVIEWER = WM_APP + $101; MINIBROWSER_SHOWTEXTVIEWER = WM_APP + $101;
@ -74,6 +74,7 @@ type
GoBtn: TButton; GoBtn: TButton;
AddressEdt: TEdit; AddressEdt: TEdit;
Timer1: TTimer; Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
@ -102,6 +103,7 @@ type
var aAction : TCefCloseBrowserAction); var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject; procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
private private
{ Private declarations } { Private declarations }
@ -178,8 +180,14 @@ uses
// ================= // =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. // 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure TJSEvalFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSEvalFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure TJSEvalFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin begin
@ -189,8 +197,7 @@ end;
procedure TJSEvalFrm.Chromium1BeforeClose(Sender: TObject; procedure TJSEvalFrm.Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TJSEvalFrm.Chromium1BeforeContextMenu(Sender : TObject; procedure TJSEvalFrm.Chromium1BeforeContextMenu(Sender : TObject;
@ -435,6 +442,7 @@ begin
end; end;
end; end;
if (pFrame <> nil) and pFrame.IsValid then
pFrame.SendProcessMessage(PID_BROWSER, pAnswer); pFrame.SendProcessMessage(PID_BROWSER, pAnswer);
end; end;
@ -464,7 +472,7 @@ begin
TempString := 'Image size : ' + inttostr(TempSize) + #13 + #10 + TempString := 'Image size : ' + inttostr(TempSize) + #13 + #10 +
'Encoded image : ' + EncodeBase64(TempPointer, TempSize); 'Encoded image : ' + EncodeBase64(TempPointer, TempSize);
if pAnswer.ArgumentList.SetString(0, TempString) then if (pFrame <> nil) and pFrame.IsValid and pAnswer.ArgumentList.SetString(0, TempString) then
pFrame.SendProcessMessage(PID_BROWSER, pAnswer); pFrame.SendProcessMessage(PID_BROWSER, pAnswer);
end; end;
end; end;
@ -497,9 +505,9 @@ begin
begin begin
TempScript := pMessage.ArgumentList.GetString(0); TempScript := pMessage.ArgumentList.GetString(0);
if (length(TempScript) > 0) then if (length(TempScript) > 0) and (pFrame <> nil) and pFrame.IsValid then
begin begin
pV8Context := pBrowser.MainFrame.GetV8Context; pV8Context := pFrame.GetV8Context;
if pV8Context.Enter then if pV8Context.Enter then
begin begin
@ -524,7 +532,6 @@ procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnProcessMessageReceived := RenderProcessHandler_OnProcessMessageReceivedEvent; GlobalCEFApp.OnProcessMessageReceived := RenderProcessHandler_OnProcessMessageReceivedEvent;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end; end;
procedure TJSEvalFrm.Chromium1ProcessMessageReceived( Sender : TObject; procedure TJSEvalFrm.Chromium1ProcessMessageReceived( Sender : TObject;

View File

@ -79,4 +79,10 @@ object JSExecutingFunctionsFrm: TJSExecutingFunctionsFrm
Left = 32 Left = 32
Top = 288 Top = 288
end end
object CEFSentinel1: TCEFSentinel
MinInitDelayMs = 2000
OnClose = CEFSentinel1Close
Left = 32
Top = 360
end
end end

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes,
uCEFConstants, uCEFv8Value, uCEFWinControl; uCEFConstants, uCEFv8Value, uCEFWinControl, uCEFSentinel;
const const
JSDEMO_CONTEXTMENU_EXECFUNCTION = MENU_ID_USER_FIRST + 1; JSDEMO_CONTEXTMENU_EXECFUNCTION = MENU_ID_USER_FIRST + 1;
@ -65,6 +65,7 @@ type
CEFWindowParent1: TCEFWindowParent; CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium; Chromium1: TChromium;
Timer1: TTimer; Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
@ -91,6 +92,7 @@ type
var aAction : TCefCloseBrowserAction); var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject; procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected protected
// Variables to control when can we destroy the form safely // Variables to control when can we destroy the form safely
FCanClose : boolean; // Set to True in TChromium.OnBeforeClose FCanClose : boolean; // Set to True in TChromium.OnBeforeClose
@ -134,7 +136,8 @@ implementation
// ================= // =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. // 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
uses uses
uCEFProcessMessage, uMyV8Handler; uCEFProcessMessage, uMyV8Handler;
@ -174,7 +177,6 @@ begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnContextCreated := GlobalCEFApp_OnContextCreated; GlobalCEFApp.OnContextCreated := GlobalCEFApp_OnContextCreated;
GlobalCEFApp.OnProcessMessageReceived := GlobalCEFApp_OnProcessMessageReceived; GlobalCEFApp.OnProcessMessageReceived := GlobalCEFApp_OnProcessMessageReceived;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end; end;
procedure TJSExecutingFunctionsFrm.GoBtnClick(Sender: TObject); procedure TJSExecutingFunctionsFrm.GoBtnClick(Sender: TObject);
@ -182,6 +184,12 @@ begin
Chromium1.LoadURL(Edit1.Text); Chromium1.LoadURL(Edit1.Text);
end; end;
procedure TJSExecutingFunctionsFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSExecutingFunctionsFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure TJSExecutingFunctionsFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0); PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -190,8 +198,7 @@ end;
procedure TJSExecutingFunctionsFrm.Chromium1BeforeClose(Sender: TObject; procedure TJSExecutingFunctionsFrm.Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TJSExecutingFunctionsFrm.Chromium1BeforeContextMenu( procedure TJSExecutingFunctionsFrm.Chromium1BeforeContextMenu(

View File

@ -89,4 +89,9 @@ object JSExtensionFrm: TJSExtensionFrm
Left = 32 Left = 32
Top = 288 Top = 288
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 32
Top = 360
end
end end

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFWinControl; uCEFWinControl, uCEFSentinel;
const const
MINIBROWSER_SHOWTEXTVIEWER = WM_APP + $100; MINIBROWSER_SHOWTEXTVIEWER = WM_APP + $100;
@ -71,6 +71,7 @@ type
CEFWindowParent1: TCEFWindowParent; CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium; Chromium1: TChromium;
Timer1: TTimer; Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure Chromium1BeforeContextMenu(Sender: TObject; procedure Chromium1BeforeContextMenu(Sender: TObject;
@ -99,6 +100,7 @@ type
var aAction : TCefCloseBrowserAction); var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject; procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected protected
FText : string; FText : string;
// Variables to control when can we destroy the form safely // Variables to control when can we destroy the form safely
@ -273,7 +275,8 @@ uses
// the TChromium.OnClose event. // the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 // 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1
// in the main thread, which triggers the TChromium.OnBeforeClose event. // in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure GlobalCEFApp_OnWebKitInitialized; procedure GlobalCEFApp_OnWebKitInitialized;
@ -315,7 +318,6 @@ procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnWebKitInitialized := GlobalCEFApp_OnWebKitInitialized; GlobalCEFApp.OnWebKitInitialized := GlobalCEFApp_OnWebKitInitialized;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
{$IFDEF DEBUG} {$IFDEF DEBUG}
GlobalCEFApp.LogFile := 'debug.log'; GlobalCEFApp.LogFile := 'debug.log';
GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO; GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO;
@ -327,6 +329,12 @@ begin
Chromium1.LoadURL(Edit1.Text); Chromium1.LoadURL(Edit1.Text);
end; end;
procedure TJSExtensionFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSExtensionFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure TJSExtensionFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0); PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -335,8 +343,7 @@ end;
procedure TJSExtensionFrm.Chromium1BeforeClose(Sender: TObject; procedure TJSExtensionFrm.Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TJSExtensionFrm.Chromium1BeforeContextMenu(Sender: TObject; procedure TJSExtensionFrm.Chromium1BeforeContextMenu(Sender: TObject;
@ -383,7 +390,7 @@ begin
case commandId of case commandId of
MINIBROWSER_CONTEXTMENU_SETJSEVENT : MINIBROWSER_CONTEXTMENU_SETJSEVENT :
if (browser <> nil) and (browser.MainFrame <> nil) then if (frame <> nil) and frame.IsValid then
begin begin
TempJSCode := 'document.body.addEventListener("mouseover", function(evt){'+ TempJSCode := 'document.body.addEventListener("mouseover", function(evt){'+
'function getpath(n){'+ 'function getpath(n){'+
@ -394,16 +401,16 @@ begin
'myextension.mouseover(getpath(evt.target))}'+ 'myextension.mouseover(getpath(evt.target))}'+
')'; ')';
browser.MainFrame.ExecuteJavaScript(TempJSCode, 'about:blank', 0); frame.ExecuteJavaScript(TempJSCode, 'about:blank', 0);
end; end;
MINIBROWSER_CONTEXTMENU_JSVISITDOM : MINIBROWSER_CONTEXTMENU_JSVISITDOM :
if (browser <> nil) and (browser.MainFrame <> nil) then if (frame <> nil) and frame.IsValid then
begin begin
TempJSCode := 'var testhtml = document.body.innerHTML; ' + TempJSCode := 'var testhtml = document.body.innerHTML; ' +
'myextension.sendresulttobrowser(testhtml, ' + quotedstr(CUSTOMNAME_MESSAGE_NAME) + ');'; 'myextension.sendresulttobrowser(testhtml, ' + quotedstr(CUSTOMNAME_MESSAGE_NAME) + ');';
browser.MainFrame.ExecuteJavaScript(TempJSCode, 'about:blank', 0); frame.ExecuteJavaScript(TempJSCode, 'about:blank', 0);
end; end;
MINIBROWSER_CONTEXTMENU_SHOWDEVTOOLS : MINIBROWSER_CONTEXTMENU_SHOWDEVTOOLS :

View File

@ -67,16 +67,23 @@ function TTestExtensionHandler.Execute(const name : ustring;
var retval : ICefv8Value; var retval : ICefv8Value;
var exception : ustring): Boolean; var exception : ustring): Boolean;
var var
msg: ICefProcessMessage; TempMessage : ICefProcessMessage;
TempFrame : ICefFrame;
begin begin
Result := False;
try
if (name = 'mouseover') then if (name = 'mouseover') then
begin begin
if (length(arguments) > 0) and arguments[0].IsString then if (length(arguments) > 0) and arguments[0].IsString then
begin begin
msg := TCefProcessMessageRef.New(MOUSEOVER_MESSAGE_NAME); TempMessage := TCefProcessMessageRef.New(MOUSEOVER_MESSAGE_NAME);
msg.ArgumentList.SetString(0, arguments[0].GetStringValue); TempMessage.ArgumentList.SetString(0, arguments[0].GetStringValue);
TCefv8ContextRef.Current.Browser.MainFrame.SendProcessMessage(PID_BROWSER, msg); TempFrame := TCefv8ContextRef.Current.Browser.MainFrame;
if (TempFrame <> nil) and TempFrame.IsValid then
TempFrame.SendProcessMessage(PID_BROWSER, TempMessage);
end; end;
Result := True; Result := True;
@ -86,16 +93,20 @@ begin
begin begin
if (length(arguments) > 1) and arguments[0].IsString and arguments[1].IsString then if (length(arguments) > 1) and arguments[0].IsString and arguments[1].IsString then
begin begin
msg := TCefProcessMessageRef.New(arguments[1].GetStringValue); TempMessage := TCefProcessMessageRef.New(arguments[1].GetStringValue);
msg.ArgumentList.SetString(0, arguments[0].GetStringValue); TempMessage.ArgumentList.SetString(0, arguments[0].GetStringValue);
TCefv8ContextRef.Current.Browser.MainFrame.SendProcessMessage(PID_BROWSER, msg); TempFrame := TCefv8ContextRef.Current.Browser.MainFrame;
if (TempFrame <> nil) and TempFrame.IsValid then
TempFrame.SendProcessMessage(PID_BROWSER, TempMessage);
end; end;
Result := True; Result := True;
end end;
else finally
Result := False; TempMessage := nil;
end;
end; end;
end. end.

View File

@ -87,4 +87,9 @@ object JSExtensionWithFunctionFrm: TJSExtensionWithFunctionFrm
Left = 32 Left = 32
Top = 288 Top = 288
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 32
Top = 352
end
end end

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFWinControl; uCEFWinControl, uCEFSentinel;
type type
TJSExtensionWithFunctionFrm = class(TForm) TJSExtensionWithFunctionFrm = class(TForm)
@ -61,6 +61,7 @@ type
Chromium1: TChromium; Chromium1: TChromium;
Timer1: TTimer; Timer1: TTimer;
StatusBar1: TStatusBar; StatusBar1: TStatusBar;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
@ -82,6 +83,7 @@ type
var aAction : TCefCloseBrowserAction); var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject; procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected protected
// Variables to control when can we destroy the form safely // Variables to control when can we destroy the form safely
FCanClose : boolean; // Set to True in TChromium.OnBeforeClose FCanClose : boolean; // Set to True in TChromium.OnBeforeClose
@ -121,7 +123,8 @@ uses
// ================= // =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. // 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
{$IFDEF DELPHI12_UP}procedure {$IFDEF DELPHI12_UP}procedure
{$ELSE}class procedure TJSSimpleExtensionFrm.{$ENDIF}GlobalCEFApp_OnWebKitInitializedEvent; {$ELSE}class procedure TJSSimpleExtensionFrm.{$ENDIF}GlobalCEFApp_OnWebKitInitializedEvent;
@ -152,7 +155,6 @@ begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnWebKitInitialized := {$IFNDEF DELPHI12_UP}TJSSimpleExtensionFrm.{$ENDIF} GlobalCEFApp.OnWebKitInitialized := {$IFNDEF DELPHI12_UP}TJSSimpleExtensionFrm.{$ENDIF}
GlobalCEFApp_OnWebKitInitializedEvent; GlobalCEFApp_OnWebKitInitializedEvent;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end; end;
procedure TJSExtensionWithFunctionFrm.GoBtnClick(Sender: TObject); procedure TJSExtensionWithFunctionFrm.GoBtnClick(Sender: TObject);
@ -160,6 +162,12 @@ begin
Chromium1.LoadURL(Edit1.Text); Chromium1.LoadURL(Edit1.Text);
end; end;
procedure TJSExtensionWithFunctionFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSExtensionWithFunctionFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure TJSExtensionWithFunctionFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0); PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -168,8 +176,7 @@ end;
procedure TJSExtensionWithFunctionFrm.Chromium1BeforeClose(Sender: TObject; procedure TJSExtensionWithFunctionFrm.Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TJSExtensionWithFunctionFrm.Chromium1BeforePopup(Sender: TObject; procedure TJSExtensionWithFunctionFrm.Chromium1BeforePopup(Sender: TObject;

View File

@ -61,19 +61,28 @@ function TMyV8Handler.Execute(const name : ustring;
var retval : ICefv8Value; var retval : ICefv8Value;
var exception : ustring): Boolean; var exception : ustring): Boolean;
var var
msg: ICefProcessMessage; TempMessage : ICefProcessMessage;
TempFrame : ICefFrame;
begin begin
Result := False;
try
if (name = 'myfunc') then if (name = 'myfunc') then
begin begin
msg := TCefProcessMessageRef.New(TEST_MESSAGE_NAME); TempMessage := TCefProcessMessageRef.New(TEST_MESSAGE_NAME);
msg.ArgumentList.SetString(0, 'Message received!'); TempMessage.ArgumentList.SetString(0, 'Message received!');
TCefv8ContextRef.Current.Browser.MainFrame.SendProcessMessage(PID_BROWSER, msg);
TempFrame := TCefv8ContextRef.Current.Browser.MainFrame;
if (TempFrame <> nil) and TempFrame.IsValid then
TempFrame.SendProcessMessage(PID_BROWSER, TempMessage);
retval := TCefv8ValueRef.NewString('My Value!'); retval := TCefv8ValueRef.NewString('My Value!');
Result := True; Result := True;
end end;
else finally
Result := False; TempMessage := nil;
end;
end; end;

View File

@ -76,4 +76,9 @@ object JSExtensionWithObjectParameterFrm: TJSExtensionWithObjectParameterFrm
Left = 32 Left = 32
Top = 288 Top = 288
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 32
Top = 352
end
end end

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFWinControl; uCEFWinControl, uCEFSentinel;
type type
TJSExtensionWithObjectParameterFrm = class(TForm) TJSExtensionWithObjectParameterFrm = class(TForm)
@ -60,6 +60,7 @@ type
CEFWindowParent1: TCEFWindowParent; CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium; Chromium1: TChromium;
Timer1: TTimer; Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
@ -78,6 +79,7 @@ type
var aAction : TCefCloseBrowserAction); var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject; procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected protected
// Variables to control when can we destroy the form safely // Variables to control when can we destroy the form safely
FCanClose : boolean; // Set to True in TChromium.OnBeforeClose FCanClose : boolean; // Set to True in TChromium.OnBeforeClose
@ -120,7 +122,8 @@ uses
// ================= // =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. // 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
{$IFDEF DELPHI12_UP}procedure {$IFDEF DELPHI12_UP}procedure
{$ELSE}class procedure TJSSimpleExtensionFrm.{$ENDIF}GlobalCEFApp_OnWebKitInitializedEvent; {$ELSE}class procedure TJSSimpleExtensionFrm.{$ENDIF}GlobalCEFApp_OnWebKitInitializedEvent;
@ -155,7 +158,6 @@ begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnWebKitInitialized := {$IFNDEF DELPHI12_UP}TJSSimpleExtensionFrm.{$ENDIF} GlobalCEFApp.OnWebKitInitialized := {$IFNDEF DELPHI12_UP}TJSSimpleExtensionFrm.{$ENDIF}
GlobalCEFApp_OnWebKitInitializedEvent; GlobalCEFApp_OnWebKitInitializedEvent;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end; end;
procedure TJSExtensionWithObjectParameterFrm.GoBtnClick(Sender: TObject); procedure TJSExtensionWithObjectParameterFrm.GoBtnClick(Sender: TObject);
@ -163,6 +165,13 @@ begin
Chromium1.LoadURL(Edit1.Text); Chromium1.LoadURL(Edit1.Text);
end; end;
procedure TJSExtensionWithObjectParameterFrm.CEFSentinel1Close(
Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSExtensionWithObjectParameterFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure TJSExtensionWithObjectParameterFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0); PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -171,8 +180,7 @@ end;
procedure TJSExtensionWithObjectParameterFrm.Chromium1BeforeClose( procedure TJSExtensionWithObjectParameterFrm.Chromium1BeforeClose(
Sender: TObject; const browser: ICefBrowser); Sender: TObject; const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TJSExtensionWithObjectParameterFrm.Chromium1BeforePopup( procedure TJSExtensionWithObjectParameterFrm.Chromium1BeforePopup(

View File

@ -89,4 +89,9 @@ object JSRTTIExtensionFrm: TJSRTTIExtensionFrm
Left = 32 Left = 32
Top = 288 Top = 288
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 32
Top = 352
end
end end

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFWinControl; uCEFWinControl, uCEFSentinel;
const const
MINIBROWSER_SHOWTEXTVIEWER = WM_APP + $100; MINIBROWSER_SHOWTEXTVIEWER = WM_APP + $100;
@ -72,6 +72,7 @@ type
CEFWindowParent1: TCEFWindowParent; CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium; Chromium1: TChromium;
Timer1: TTimer; Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure Chromium1BeforeContextMenu(Sender: TObject; procedure Chromium1BeforeContextMenu(Sender: TObject;
@ -100,6 +101,7 @@ type
var aAction : TCefCloseBrowserAction); var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject; procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected protected
FText : string; FText : string;
// Variables to control when can we destroy the form safely // Variables to control when can we destroy the form safely
@ -155,7 +157,8 @@ uses
// ================= // =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. // 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure GlobalCEFApp_OnWebKitInitialized; procedure GlobalCEFApp_OnWebKitInitialized;
begin begin
@ -173,7 +176,6 @@ procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnWebKitInitialized := GlobalCEFApp_OnWebKitInitialized; GlobalCEFApp.OnWebKitInitialized := GlobalCEFApp_OnWebKitInitialized;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
{$IFDEF DEBUG} {$IFDEF DEBUG}
GlobalCEFApp.LogFile := 'debug.log'; GlobalCEFApp.LogFile := 'debug.log';
GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO; GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO;
@ -185,6 +187,12 @@ begin
Chromium1.LoadURL(Edit1.Text); Chromium1.LoadURL(Edit1.Text);
end; end;
procedure TJSRTTIExtensionFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSRTTIExtensionFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure TJSRTTIExtensionFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0); PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -229,7 +237,7 @@ begin
// Here is the code executed for each custom context menu entry // Here is the code executed for each custom context menu entry
case commandId of case commandId of
MINIBROWSER_CONTEXTMENU_SETJSEVENT : MINIBROWSER_CONTEXTMENU_SETJSEVENT :
if (browser <> nil) and (browser.MainFrame <> nil) then if (frame <> nil) and frame.IsValid then
begin begin
TempJSCode := 'document.body.addEventListener("mouseover", function(evt){'+ TempJSCode := 'document.body.addEventListener("mouseover", function(evt){'+
'function getpath(n){'+ 'function getpath(n){'+
@ -240,17 +248,17 @@ begin
'myextension.mouseover(getpath(evt.target))}'+ // This is the call from JavaScript to the extension with DELPHI code in uTestExtension.pas 'myextension.mouseover(getpath(evt.target))}'+ // This is the call from JavaScript to the extension with DELPHI code in uTestExtension.pas
')'; ')';
browser.MainFrame.ExecuteJavaScript(TempJSCode, 'about:blank', 0); frame.ExecuteJavaScript(TempJSCode, 'about:blank', 0);
end; end;
MINIBROWSER_CONTEXTMENU_JSVISITDOM : MINIBROWSER_CONTEXTMENU_JSVISITDOM :
if (browser <> nil) and (browser.MainFrame <> nil) then if (frame <> nil) and frame.IsValid then
begin begin
// This is the call from JavaScript to the extension with DELPHI code in uTestExtension.pas // This is the call from JavaScript to the extension with DELPHI code in uTestExtension.pas
TempJSCode := 'var testhtml = document.body.innerHTML; ' + TempJSCode := 'var testhtml = document.body.innerHTML; ' +
'myextension.sendresulttobrowser(testhtml, ' + quotedstr(CUSTOMNAME_MESSAGE_NAME) + ');'; 'myextension.sendresulttobrowser(testhtml, ' + quotedstr(CUSTOMNAME_MESSAGE_NAME) + ');';
browser.MainFrame.ExecuteJavaScript(TempJSCode, 'about:blank', 0); frame.ExecuteJavaScript(TempJSCode, 'about:blank', 0);
end; end;
MINIBROWSER_CONTEXTMENU_SHOWDEVTOOLS : MINIBROWSER_CONTEXTMENU_SHOWDEVTOOLS :
@ -343,8 +351,7 @@ end;
procedure TJSRTTIExtensionFrm.Chromium1BeforeClose( procedure TJSRTTIExtensionFrm.Chromium1BeforeClose(
Sender: TObject; const browser: ICefBrowser); Sender: TObject; const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TJSRTTIExtensionFrm.Chromium1Close( procedure TJSRTTIExtensionFrm.Chromium1Close(

View File

@ -63,24 +63,41 @@ uses
class procedure TTestExtension.mouseover(const data: string); class procedure TTestExtension.mouseover(const data: string);
var var
msg: ICefProcessMessage; TempMessage : ICefProcessMessage;
TempFrame : ICefFrame;
begin begin
msg := TCefProcessMessageRef.New(MOUSEOVER_MESSAGE_NAME); try
msg.ArgumentList.SetString(0, data); TempMessage := TCefProcessMessageRef.New(MOUSEOVER_MESSAGE_NAME);
TempMessage.ArgumentList.SetString(0, data);
// Sending a message back to the browser. It'll be received in the TChromium.OnProcessMessageReceived event. // Sending a message back to the browser. It'll be received in the TChromium.OnProcessMessageReceived event.
// TCefv8ContextRef.Current returns the v8 context for the frame that is currently executing Javascript. // TCefv8ContextRef.Current returns the v8 context for the frame that is currently executing Javascript.
TCefv8ContextRef.Current.Browser.MainFrame.SendProcessMessage(PID_BROWSER, msg);
TempFrame := TCefv8ContextRef.Current.Browser.MainFrame;
if (TempFrame <> nil) and TempFrame.IsValid then
TempFrame.SendProcessMessage(PID_BROWSER, TempMessage);
finally
TempMessage := nil;
end;
end; end;
class procedure TTestExtension.sendresulttobrowser(const msgtext, msgname : string); class procedure TTestExtension.sendresulttobrowser(const msgtext, msgname : string);
var var
msg: ICefProcessMessage; TempMessage : ICefProcessMessage;
TempFrame : ICefFrame;
begin begin
msg := TCefProcessMessageRef.New(msgname); try
msg.ArgumentList.SetString(0, msgtext); TempMessage := TCefProcessMessageRef.New(msgname);
TempMessage.ArgumentList.SetString(0, msgtext);
TCefv8ContextRef.Current.Browser.MainFrame.SendProcessMessage(PID_BROWSER, msg); TempFrame := TCefv8ContextRef.Current.Browser.MainFrame;
if (TempFrame <> nil) and TempFrame.IsValid then
TempFrame.SendProcessMessage(PID_BROWSER, TempMessage);
finally
TempMessage := nil;
end;
end; end;
end. end.

View File

@ -76,4 +76,9 @@ object JSSimpleExtensionFrm: TJSSimpleExtensionFrm
Left = 32 Left = 32
Top = 288 Top = 288
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 32
Top = 344
end
end end

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFWinControl; uCEFWinControl, uCEFSentinel;
type type
TJSSimpleExtensionFrm = class(TForm) TJSSimpleExtensionFrm = class(TForm)
@ -60,6 +60,7 @@ type
CEFWindowParent1: TCEFWindowParent; CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium; Chromium1: TChromium;
Timer1: TTimer; Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
@ -78,6 +79,7 @@ type
var aAction : TCefCloseBrowserAction); var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject; procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected protected
// Variables to control when can we destroy the form safely // Variables to control when can we destroy the form safely
FCanClose : boolean; // Set to True in TChromium.OnBeforeClose FCanClose : boolean; // Set to True in TChromium.OnBeforeClose
@ -117,7 +119,8 @@ uses
// ================= // =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. // 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
{$IFDEF DELPHI12_UP}procedure {$IFDEF DELPHI12_UP}procedure
{$ELSE}class procedure TJSSimpleExtensionFrm.{$ENDIF}GlobalCEFApp_OnWebKitInitializedEvent; {$ELSE}class procedure TJSSimpleExtensionFrm.{$ENDIF}GlobalCEFApp_OnWebKitInitializedEvent;
@ -142,7 +145,6 @@ begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnWebKitInitialized := {$IFNDEF DELPHI12_UP}TJSSimpleExtensionFrm.{$ENDIF} GlobalCEFApp.OnWebKitInitialized := {$IFNDEF DELPHI12_UP}TJSSimpleExtensionFrm.{$ENDIF}
GlobalCEFApp_OnWebKitInitializedEvent; GlobalCEFApp_OnWebKitInitializedEvent;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end; end;
procedure TJSSimpleExtensionFrm.GoBtnClick(Sender: TObject); procedure TJSSimpleExtensionFrm.GoBtnClick(Sender: TObject);
@ -150,6 +152,12 @@ begin
Chromium1.LoadURL(Edit1.Text); Chromium1.LoadURL(Edit1.Text);
end; end;
procedure TJSSimpleExtensionFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSSimpleExtensionFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure TJSSimpleExtensionFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0); PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -221,8 +229,7 @@ end;
procedure TJSSimpleExtensionFrm.Chromium1BeforeClose( procedure TJSSimpleExtensionFrm.Chromium1BeforeClose(
Sender: TObject; const browser: ICefBrowser); Sender: TObject; const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TJSSimpleExtensionFrm.Chromium1Close( procedure TJSSimpleExtensionFrm.Chromium1Close(

View File

@ -76,4 +76,9 @@ object JSSimpleWindowBindingFrm: TJSSimpleWindowBindingFrm
Left = 32 Left = 32
Top = 288 Top = 288
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 32
Top = 344
end
end end

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes,
uCEFConstants, uCEFv8Value, uCEFWinControl; uCEFConstants, uCEFv8Value, uCEFWinControl, uCEFSentinel;
type type
TJSSimpleWindowBindingFrm = class(TForm) TJSSimpleWindowBindingFrm = class(TForm)
@ -60,6 +60,7 @@ type
CEFWindowParent1: TCEFWindowParent; CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium; Chromium1: TChromium;
Timer1: TTimer; Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
@ -78,6 +79,7 @@ type
var aAction : TCefCloseBrowserAction); var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject; procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected protected
// Variables to control when can we destroy the form safely // Variables to control when can we destroy the form safely
FCanClose : boolean; // Set to True in TChromium.OnBeforeClose FCanClose : boolean; // Set to True in TChromium.OnBeforeClose
@ -112,7 +114,8 @@ implementation
// ================= // =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. // 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure GlobalCEFApp_OnContextCreated(const browser: ICefBrowser; const frame: ICefFrame; const context: ICefv8Context); procedure GlobalCEFApp_OnContextCreated(const browser: ICefBrowser; const frame: ICefFrame; const context: ICefv8Context);
var var
@ -130,7 +133,6 @@ procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnContextCreated := GlobalCEFApp_OnContextCreated; GlobalCEFApp.OnContextCreated := GlobalCEFApp_OnContextCreated;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end; end;
procedure TJSSimpleWindowBindingFrm.GoBtnClick(Sender: TObject); procedure TJSSimpleWindowBindingFrm.GoBtnClick(Sender: TObject);
@ -138,6 +140,12 @@ begin
Chromium1.LoadURL(Edit1.Text); Chromium1.LoadURL(Edit1.Text);
end; end;
procedure TJSSimpleWindowBindingFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSSimpleWindowBindingFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure TJSSimpleWindowBindingFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0); PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -209,8 +217,7 @@ end;
procedure TJSSimpleWindowBindingFrm.Chromium1BeforeClose( procedure TJSSimpleWindowBindingFrm.Chromium1BeforeClose(
Sender: TObject; const browser: ICefBrowser); Sender: TObject; const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TJSSimpleWindowBindingFrm.Chromium1Close( procedure TJSSimpleWindowBindingFrm.Chromium1Close(

View File

@ -68,7 +68,6 @@ end;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnContextCreated := GlobalCEFApp_OnContextCreated; GlobalCEFApp.OnContextCreated := GlobalCEFApp_OnContextCreated;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
// The main process and the subprocess *MUST* have the same FrameworkDirPath, ResourcesDirPath, // The main process and the subprocess *MUST* have the same FrameworkDirPath, ResourcesDirPath,
// LocalesDirPath, cache, cookies and UserDataPath paths // LocalesDirPath, cache, cookies and UserDataPath paths

View File

@ -76,4 +76,9 @@ object JSSimpleWindowBindingFrm: TJSSimpleWindowBindingFrm
Left = 32 Left = 32
Top = 288 Top = 288
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 32
Top = 352
end
end end

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes,
uCEFConstants, uCEFv8Value, uCEFWinControl; uCEFConstants, uCEFv8Value, uCEFWinControl, uCEFSentinel;
type type
TJSSimpleWindowBindingFrm = class(TForm) TJSSimpleWindowBindingFrm = class(TForm)
@ -60,6 +60,7 @@ type
CEFWindowParent1: TCEFWindowParent; CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium; Chromium1: TChromium;
Timer1: TTimer; Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
@ -78,6 +79,7 @@ type
var aAction : TCefCloseBrowserAction); var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject; procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected protected
FText : string; FText : string;
// Variables to control when can we destroy the form safely // Variables to control when can we destroy the form safely
@ -113,7 +115,8 @@ implementation
// ================= // =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. // 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure CreateGlobalCEFApp; procedure CreateGlobalCEFApp;
begin begin
@ -129,7 +132,6 @@ begin
// 4. Run this demo : JSSimpleWindowBinding // 4. Run this demo : JSSimpleWindowBinding
GlobalCEFApp.BrowserSubprocessPath := 'SubProcess.exe'; GlobalCEFApp.BrowserSubprocessPath := 'SubProcess.exe';
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
//GlobalCEFApp.LogFile := 'cef.log'; //GlobalCEFApp.LogFile := 'cef.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE; //GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end; end;
@ -139,6 +141,12 @@ begin
Chromium1.LoadURL(Edit1.Text); Chromium1.LoadURL(Edit1.Text);
end; end;
procedure TJSSimpleWindowBindingFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSSimpleWindowBindingFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure TJSSimpleWindowBindingFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0); PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -210,8 +218,7 @@ end;
procedure TJSSimpleWindowBindingFrm.Chromium1BeforeClose( procedure TJSSimpleWindowBindingFrm.Chromium1BeforeClose(
Sender: TObject; const browser: ICefBrowser); Sender: TObject; const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TJSSimpleWindowBindingFrm.Chromium1Close( procedure TJSSimpleWindowBindingFrm.Chromium1Close(

View File

@ -76,4 +76,9 @@ object JSWindowBindingWithArrayBufferFrm: TJSWindowBindingWithArrayBufferFrm
Left = 32 Left = 32
Top = 288 Top = 288
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 32
Top = 344
end
end end

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFWinControl; uCEFWinControl, uCEFSentinel;
type type
TJSWindowBindingWithArrayBufferFrm = class(TForm) TJSWindowBindingWithArrayBufferFrm = class(TForm)
@ -60,6 +60,7 @@ type
CEFWindowParent1: TCEFWindowParent; CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium; Chromium1: TChromium;
Timer1: TTimer; Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
@ -78,6 +79,7 @@ type
var aAction : TCefCloseBrowserAction); var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject; procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected protected
// Variables to control when can we destroy the form safely // Variables to control when can we destroy the form safely
FCanClose : boolean; // Set to True in TChromium.OnBeforeClose FCanClose : boolean; // Set to True in TChromium.OnBeforeClose
@ -115,7 +117,8 @@ uses
// ================= // =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. // 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure FreeCustomArrayBufer(buffer : Pointer); procedure FreeCustomArrayBufer(buffer : Pointer);
begin begin
@ -155,7 +158,6 @@ procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnContextCreated := GlobalCEFApp_OnContextCreated; GlobalCEFApp.OnContextCreated := GlobalCEFApp_OnContextCreated;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end; end;
procedure TJSWindowBindingWithArrayBufferFrm.GoBtnClick(Sender: TObject); procedure TJSWindowBindingWithArrayBufferFrm.GoBtnClick(Sender: TObject);
@ -163,6 +165,13 @@ begin
Chromium1.LoadURL(Edit1.Text); Chromium1.LoadURL(Edit1.Text);
end; end;
procedure TJSWindowBindingWithArrayBufferFrm.CEFSentinel1Close(
Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSWindowBindingWithArrayBufferFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure TJSWindowBindingWithArrayBufferFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0); PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -234,8 +243,7 @@ end;
procedure TJSWindowBindingWithArrayBufferFrm.Chromium1BeforeClose( procedure TJSWindowBindingWithArrayBufferFrm.Chromium1BeforeClose(
Sender: TObject; const browser: ICefBrowser); Sender: TObject; const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TJSWindowBindingWithArrayBufferFrm.Chromium1Close( procedure TJSWindowBindingWithArrayBufferFrm.Chromium1Close(

View File

@ -76,4 +76,9 @@ object JSWindowBindingWithFunctionFrm: TJSWindowBindingWithFunctionFrm
Left = 32 Left = 32
Top = 288 Top = 288
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 32
Top = 352
end
end end

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFWinControl; uCEFWinControl, uCEFSentinel;
type type
TJSWindowBindingWithFunctionFrm = class(TForm) TJSWindowBindingWithFunctionFrm = class(TForm)
@ -60,6 +60,7 @@ type
CEFWindowParent1: TCEFWindowParent; CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium; Chromium1: TChromium;
Timer1: TTimer; Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
@ -78,6 +79,7 @@ type
var aAction : TCefCloseBrowserAction); var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject; procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected protected
// Variables to control when can we destroy the form safely // Variables to control when can we destroy the form safely
FCanClose : boolean; // Set to True in TChromium.OnBeforeClose FCanClose : boolean; // Set to True in TChromium.OnBeforeClose
@ -115,7 +117,8 @@ uses
// ================= // =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. // 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure GlobalCEFApp_OnContextCreated(const browser: ICefBrowser; const frame: ICefFrame; const context: ICefv8Context); procedure GlobalCEFApp_OnContextCreated(const browser: ICefBrowser; const frame: ICefFrame; const context: ICefv8Context);
var var
@ -135,7 +138,6 @@ procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnContextCreated := GlobalCEFApp_OnContextCreated; GlobalCEFApp.OnContextCreated := GlobalCEFApp_OnContextCreated;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end; end;
procedure TJSWindowBindingWithFunctionFrm.GoBtnClick(Sender: TObject); procedure TJSWindowBindingWithFunctionFrm.GoBtnClick(Sender: TObject);
@ -143,6 +145,13 @@ begin
Chromium1.LoadURL(Edit1.Text); Chromium1.LoadURL(Edit1.Text);
end; end;
procedure TJSWindowBindingWithFunctionFrm.CEFSentinel1Close(
Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSWindowBindingWithFunctionFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure TJSWindowBindingWithFunctionFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0); PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -214,8 +223,7 @@ end;
procedure TJSWindowBindingWithFunctionFrm.Chromium1BeforeClose( procedure TJSWindowBindingWithFunctionFrm.Chromium1BeforeClose(
Sender: TObject; const browser: ICefBrowser); Sender: TObject; const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TJSWindowBindingWithFunctionFrm.Chromium1Close( procedure TJSWindowBindingWithFunctionFrm.Chromium1Close(

View File

@ -76,4 +76,9 @@ object JSWindowBindingWithObjectFrm: TJSWindowBindingWithObjectFrm
Left = 32 Left = 32
Top = 288 Top = 288
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 32
Top = 352
end
end end

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFWinControl; uCEFWinControl, uCEFSentinel;
type type
TJSWindowBindingWithObjectFrm = class(TForm) TJSWindowBindingWithObjectFrm = class(TForm)
@ -60,6 +60,7 @@ type
CEFWindowParent1: TCEFWindowParent; CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium; Chromium1: TChromium;
Timer1: TTimer; Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
@ -78,6 +79,7 @@ type
var aAction : TCefCloseBrowserAction); var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject; procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected protected
// Variables to control when can we destroy the form safely // Variables to control when can we destroy the form safely
FCanClose : boolean; // Set to True in TChromium.OnBeforeClose FCanClose : boolean; // Set to True in TChromium.OnBeforeClose
@ -115,7 +117,8 @@ uses
// ================= // =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. // 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure GlobalCEFApp_OnContextCreated(const browser: ICefBrowser; const frame: ICefFrame; const context: ICefv8Context); procedure GlobalCEFApp_OnContextCreated(const browser: ICefBrowser; const frame: ICefFrame; const context: ICefv8Context);
var var
@ -136,7 +139,6 @@ procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnContextCreated := GlobalCEFApp_OnContextCreated; GlobalCEFApp.OnContextCreated := GlobalCEFApp_OnContextCreated;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end; end;
procedure TJSWindowBindingWithObjectFrm.GoBtnClick(Sender: TObject); procedure TJSWindowBindingWithObjectFrm.GoBtnClick(Sender: TObject);
@ -144,6 +146,12 @@ begin
Chromium1.LoadURL(Edit1.Text); Chromium1.LoadURL(Edit1.Text);
end; end;
procedure TJSWindowBindingWithObjectFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSWindowBindingWithObjectFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure TJSWindowBindingWithObjectFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0); PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -215,8 +223,7 @@ end;
procedure TJSWindowBindingWithObjectFrm.Chromium1BeforeClose( procedure TJSWindowBindingWithObjectFrm.Chromium1BeforeClose(
Sender: TObject; const browser: ICefBrowser); Sender: TObject; const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TJSWindowBindingWithObjectFrm.Chromium1Close( procedure TJSWindowBindingWithObjectFrm.Chromium1Close(

View File

@ -80,4 +80,9 @@ object Form1: TForm1
Left = 24 Left = 24
Top = 206 Top = 206
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 24
Top = 280
end
end end

View File

@ -50,7 +50,8 @@ uses
Windows, Messages, SysUtils, Variants, Classes, SyncObjs, Windows, Messages, SysUtils, Variants, Classes, SyncObjs,
Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, AppEvnts, Keyboard, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, AppEvnts, Keyboard,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFTypes, uCEFInterfaces, uCEFConstants, uCEFBufferPanel; uCEFChromium, uCEFTypes, uCEFInterfaces, uCEFConstants, uCEFBufferPanel,
uCEFSentinel;
const const
HOMEPAGE_URL = 'https://www.google.com'; HOMEPAGE_URL = 'https://www.google.com';
@ -72,9 +73,11 @@ type
Timer1: TTimer; Timer1: TTimer;
Panel1: TBufferPanel; Panel1: TBufferPanel;
TouchKeyboard1: TTouchKeyboard; TouchKeyboard1: TTouchKeyboard;
CEFSentinel1: TCEFSentinel;
procedure AppEventsMessage(var Msg: tagMSG; var Handled: Boolean); procedure AppEventsMessage(var Msg: tagMSG; var Handled: Boolean);
procedure Timer1Timer(Sender: TObject); procedure Timer1Timer(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
procedure Panel1Enter(Sender: TObject); procedure Panel1Enter(Sender: TObject);
procedure Panel1Exit(Sender: TObject); procedure Panel1Exit(Sender: TObject);
@ -167,14 +170,14 @@ uses
// 2- chrmosr.CloseBrowser(True) will trigger chrmosr.OnClose and we have to // 2- chrmosr.CloseBrowser(True) will trigger chrmosr.OnClose and we have to
// set "Result" to false and CEF3 will destroy the internal browser immediately. // set "Result" to false and CEF3 will destroy the internal browser immediately.
// 3- chrmosr.OnBeforeClose is triggered because the internal browser was destroyed. // 3- chrmosr.OnBeforeClose is triggered because the internal browser was destroyed.
// Now we set FCanClose to True and send WM_CLOSE to the form. // Now we call TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4- TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure CreateGlobalCEFApp; procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.WindowlessRenderingEnabled := True; GlobalCEFApp.WindowlessRenderingEnabled := True;
GlobalCEFApp.EnableHighDPISupport := True; GlobalCEFApp.EnableHighDPISupport := True;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end; end;
procedure TForm1.AppEventsMessage(var Msg: tagMSG; var Handled: Boolean); procedure TForm1.AppEventsMessage(var Msg: tagMSG; var Handled: Boolean);
@ -300,8 +303,7 @@ end;
procedure TForm1.chrmosrBeforeClose(Sender: TObject; const browser: ICefBrowser); procedure TForm1.chrmosrBeforeClose(Sender: TObject; const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TForm1.chrmosrBeforeContextMenu( Sender : TObject; procedure TForm1.chrmosrBeforeContextMenu( Sender : TObject;
@ -862,6 +864,12 @@ begin
(cardinal(aCurrentTime - FLastClickTime) > GetDoubleClickTime); (cardinal(aCurrentTime - FLastClickTime) > GetDoubleClickTime);
end; end;
procedure TForm1.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TForm1.Panel1Enter(Sender: TObject); procedure TForm1.Panel1Enter(Sender: TObject);
begin begin
chrmosr.SendFocusEvent(True); chrmosr.SendFocusEvent(True);

View File

@ -80,4 +80,9 @@ object MainForm: TMainForm
TabOrder = 0 TabOrder = 0
end end
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 56
Top = 80
end
end end

View File

@ -45,12 +45,13 @@ uses
{$IFDEF DELPHI16_UP} {$IFDEF DELPHI16_UP}
Winapi.Windows, System.SysUtils, System.Classes, Vcl.Graphics, Vcl.Forms, Winapi.Windows, System.SysUtils, System.Classes, Vcl.Graphics, Vcl.Forms,
Vcl.Controls, Vcl.StdCtrls, Vcl.Dialogs, Vcl.Buttons, Winapi.Messages, Vcl.Controls, Vcl.StdCtrls, Vcl.Dialogs, Vcl.Buttons, Winapi.Messages,
Vcl.ExtCtrls, Vcl.ComCtrls; Vcl.ExtCtrls, Vcl.ComCtrls,
{$ELSE} {$ELSE}
Windows, SysUtils, Classes, Graphics, Forms, Windows, SysUtils, Classes, Graphics, Forms,
Controls, StdCtrls, Dialogs, Buttons, Messages, Controls, StdCtrls, Dialogs, Buttons, Messages,
ExtCtrls, ComCtrls; ExtCtrls, ComCtrls,
{$ENDIF} {$ENDIF}
uCEFSentinel;
const const
CEFBROWSER_CREATED = WM_APP + $100; CEFBROWSER_CREATED = WM_APP + $100;
@ -64,10 +65,12 @@ type
NewBtn: TSpeedButton; NewBtn: TSpeedButton;
ExitBtn: TSpeedButton; ExitBtn: TSpeedButton;
NewContextChk: TCheckBox; NewContextChk: TCheckBox;
CEFSentinel1: TCEFSentinel;
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure NewBtnClick(Sender: TObject); procedure NewBtnClick(Sender: TObject);
procedure ExitBtnClick(Sender: TObject); procedure ExitBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
private private
// Variables to control when can we destroy the form safely // Variables to control when can we destroy the form safely
FCanClose : boolean; // Set to True when all the child forms are closed FCanClose : boolean; // Set to True when all the child forms are closed
@ -104,7 +107,8 @@ uses
// Destruction steps // Destruction steps
// ================= // =================
// 1. Destroy all child forms // 1. Destroy all child forms
// 2. Wait until all the child forms are closed before closing the main form and terminating the application. // 2. Wait until all the child forms are closed before calling TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when all renderer processes are closed
// 3. TCEFSentinel.OnClose closes the main form.
procedure GlobalCEFApp_OnContextInitialized; procedure GlobalCEFApp_OnContextInitialized;
begin begin
@ -116,7 +120,6 @@ procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnContextInitialized := GlobalCEFApp_OnContextInitialized; GlobalCEFApp.OnContextInitialized := GlobalCEFApp_OnContextInitialized;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end; end;
procedure TMainForm.CreateMDIChild(const Name: string); procedure TMainForm.CreateMDIChild(const Name: string);
@ -182,14 +185,19 @@ begin
CloseAllChildForms; CloseAllChildForms;
end; end;
procedure TMainForm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TMainForm.ChildDestroyedMsg(var aMessage : TMessage); procedure TMainForm.ChildDestroyedMsg(var aMessage : TMessage);
begin begin
// If there are no more child forms we can destroy the main form // If there are no more child forms we can destroy the main form
if FClosing and (MDIChildCount = 0) then if FClosing and (MDIChildCount = 0) then
begin begin
ButtonPnl.Enabled := False; ButtonPnl.Enabled := False;
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
end; end;

View File

@ -80,4 +80,9 @@ object MainForm: TMainForm
TabOrder = 0 TabOrder = 0
end end
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 32
Top = 56
end
end end

View File

@ -51,7 +51,7 @@ uses
Controls, StdCtrls, Dialogs, Buttons, Messages, Controls, StdCtrls, Dialogs, Buttons, Messages,
ExtCtrls, ComCtrls, ExtCtrls, ComCtrls,
{$ENDIF} {$ENDIF}
uCEFWorkScheduler; uCEFWorkScheduler, uCEFSentinel;
const const
CEFBROWSER_CREATED = WM_APP + $100; CEFBROWSER_CREATED = WM_APP + $100;
@ -65,10 +65,12 @@ type
NewBtn: TSpeedButton; NewBtn: TSpeedButton;
ExitBtn: TSpeedButton; ExitBtn: TSpeedButton;
NewContextChk: TCheckBox; NewContextChk: TCheckBox;
CEFSentinel1: TCEFSentinel;
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure NewBtnClick(Sender: TObject); procedure NewBtnClick(Sender: TObject);
procedure ExitBtnClick(Sender: TObject); procedure ExitBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
private private
// Variables to control when can we destroy the form safely // Variables to control when can we destroy the form safely
FCanClose : boolean; // Set to True when all the child forms are closed FCanClose : boolean; // Set to True when all the child forms are closed
@ -103,7 +105,8 @@ uses
// Destruction steps // Destruction steps
// ================= // =================
// 1. Destroy all child forms // 1. Destroy all child forms
// 2. Wait until all the child forms are closed before closing the main form and terminating the application. // 2. Wait until all the child forms are closed before calling TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when all renderer processes are closed
// 3. TCEFSentinel.OnClose closes the main form.
procedure GlobalCEFApp_OnContextInitialized; procedure GlobalCEFApp_OnContextInitialized;
begin begin
@ -129,7 +132,6 @@ begin
GlobalCEFApp.MultiThreadedMessageLoop := False; GlobalCEFApp.MultiThreadedMessageLoop := False;
GlobalCEFApp.OnScheduleMessagePumpWork := GlobalCEFApp_OnScheduleMessagePumpWork; GlobalCEFApp.OnScheduleMessagePumpWork := GlobalCEFApp_OnScheduleMessagePumpWork;
GlobalCEFApp.OnContextInitialized := GlobalCEFApp_OnContextInitialized; GlobalCEFApp.OnContextInitialized := GlobalCEFApp_OnContextInitialized;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end; end;
procedure TMainForm.CreateMDIChild(const Name: string); procedure TMainForm.CreateMDIChild(const Name: string);
@ -199,9 +201,14 @@ begin
if FClosing and (MDIChildCount = 0) then if FClosing and (MDIChildCount = 0) then
begin begin
ButtonPnl.Enabled := False; ButtonPnl.Enabled := False;
CEFSentinel1.Start;
end;
end;
procedure TMainForm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True; FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0); PostMessage(Handle, WM_CLOSE, 0, 0);
end;
end; end;
procedure TMainForm.CEFInitializedMsg(var aMessage : TMessage); procedure TMainForm.CEFInitializedMsg(var aMessage : TMessage);

View File

@ -290,6 +290,7 @@ object MiniBrowserFrm: TMiniBrowserFrm
OnCertificateError = Chromium1CertificateError OnCertificateError = Chromium1CertificateError
OnBeforeResourceLoad = Chromium1BeforeResourceLoad OnBeforeResourceLoad = Chromium1BeforeResourceLoad
OnResourceResponse = Chromium1ResourceResponse OnResourceResponse = Chromium1ResourceResponse
OnBeforePluginLoad = Chromium1BeforePluginLoad
Left = 32 Left = 32
Top = 224 Top = 224
end end
@ -395,4 +396,9 @@ object MiniBrowserFrm: TMiniBrowserFrm
Left = 32 Left = 32
Top = 344 Top = 344
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 32
Top = 408
end
end end

View File

@ -51,7 +51,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Types, ComCtrls, ClipBrd, AppEvnts, ActiveX, ShlObj, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Types, ComCtrls, ClipBrd, AppEvnts, ActiveX, ShlObj,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFWinControl; uCEFWinControl, uCEFSentinel;
const const
MINIBROWSER_SHOWDEVTOOLS = WM_APP + $101; MINIBROWSER_SHOWDEVTOOLS = WM_APP + $101;
@ -126,6 +126,7 @@ type
Downloadimage1: TMenuItem; Downloadimage1: TMenuItem;
Simulatekeyboardpresses1: TMenuItem; Simulatekeyboardpresses1: TMenuItem;
Flushcookies1: TMenuItem; Flushcookies1: TMenuItem;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure BackBtnClick(Sender: TObject); procedure BackBtnClick(Sender: TObject);
procedure ForwardBtnClick(Sender: TObject); procedure ForwardBtnClick(Sender: TObject);
@ -226,6 +227,11 @@ type
procedure Simulatekeyboardpresses1Click(Sender: TObject); procedure Simulatekeyboardpresses1Click(Sender: TObject);
procedure Flushcookies1Click(Sender: TObject); procedure Flushcookies1Click(Sender: TObject);
procedure Chromium1CookiesFlushed(Sender: TObject); procedure Chromium1CookiesFlushed(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
procedure Chromium1BeforePluginLoad(Sender: TObject; const mimeType,
pluginUrl: ustring; isMainFrame: Boolean;
const topOriginUrl: ustring; const pluginInfo: ICefWebPluginInfo;
var pluginPolicy: TCefPluginPolicy; var aResult: Boolean);
protected protected
FResponse : TStringList; FResponse : TStringList;
@ -286,15 +292,16 @@ uses
// ================= // =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. // 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure CreateGlobalCEFApp; procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
GlobalCEFApp.LogFile := 'debug.log'; GlobalCEFApp.LogFile := 'debug.log';
GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO; GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO;
GlobalCEFApp.cache := 'cache'; GlobalCEFApp.cache := 'cache';
GlobalCEFApp.EnablePrintPreview := True;
//GlobalCEFApp.RemoteDebuggingPort := 19999; //GlobalCEFApp.RemoteDebuggingPort := 19999;
end; end;
@ -331,6 +338,12 @@ begin
if (length(TempURL) > 0) then Chromium1.ResolveHost(TempURL); if (length(TempURL) > 0) then Chromium1.ResolveHost(TempURL);
end; end;
procedure TMiniBrowserFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TMiniBrowserFrm.Chromium1AddressChange(Sender: TObject; procedure TMiniBrowserFrm.Chromium1AddressChange(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame; const url: ustring); const browser: ICefBrowser; const frame: ICefFrame; const url: ustring);
begin begin
@ -348,11 +361,7 @@ end;
procedure TMiniBrowserFrm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); procedure TMiniBrowserFrm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
begin begin
// The main browser is being destroyed // The main browser is being destroyed
if (Chromium1.BrowserId = 0) then if (Chromium1.BrowserId = 0) then CEFSentinel1.Start;
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
end; end;
procedure TMiniBrowserFrm.Chromium1BeforeContextMenu(Sender: TObject; procedure TMiniBrowserFrm.Chromium1BeforeContextMenu(Sender: TObject;
@ -439,6 +448,22 @@ begin
callback.cont(TempFullPath, False); callback.cont(TempFullPath, False);
end; end;
procedure TMiniBrowserFrm.Chromium1BeforePluginLoad(Sender: TObject;
const mimeType, pluginUrl: ustring; isMainFrame: Boolean;
const topOriginUrl: ustring; const pluginInfo: ICefWebPluginInfo;
var pluginPolicy: TCefPluginPolicy; var aResult: Boolean);
begin
// Always allow the PDF plugin to load.
if (pluginPolicy <> PLUGIN_POLICY_ALLOW) and
(CompareText(mimeType, 'application/pdf') = 0) then
begin
pluginPolicy := PLUGIN_POLICY_ALLOW;
aResult := True;
end
else
aResult := False;
end;
procedure TMiniBrowserFrm.Chromium1BeforeResourceLoad(Sender: TObject; procedure TMiniBrowserFrm.Chromium1BeforeResourceLoad(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame; const browser: ICefBrowser; const frame: ICefFrame;
const request: ICefRequest; const callback: ICefRequestCallback; const request: ICefRequest; const callback: ICefRequestCallback;
@ -448,7 +473,8 @@ begin
if Chromium1.IsSameBrowser(browser) and if Chromium1.IsSameBrowser(browser) and
(frame <> nil) and (frame <> nil) and
frame.IsMain then frame.IsMain and
frame.IsValid then
InspectRequest(request); InspectRequest(request);
end; end;
@ -520,8 +546,8 @@ begin
end; end;
MINIBROWSER_CONTEXTMENU_JSWRITEDOC : MINIBROWSER_CONTEXTMENU_JSWRITEDOC :
if (browser <> nil) and (browser.MainFrame <> nil) then if (frame <> nil) and frame.IsValid then
browser.MainFrame.ExecuteJavaScript( frame.ExecuteJavaScript(
'var css = ' + chr(39) + '@page {size: A4; margin: 0;} @media print {html, body {width: 210mm; height: 297mm;}}' + chr(39) + '; ' + 'var css = ' + chr(39) + '@page {size: A4; margin: 0;} @media print {html, body {width: 210mm; height: 297mm;}}' + chr(39) + '; ' +
'var style = document.createElement(' + chr(39) + 'style' + chr(39) + '); ' + 'var style = document.createElement(' + chr(39) + 'style' + chr(39) + '); ' +
'style.type = ' + chr(39) + 'text/css' + chr(39) + '; ' + 'style.type = ' + chr(39) + 'text/css' + chr(39) + '; ' +
@ -530,8 +556,8 @@ begin
'about:blank', 0); 'about:blank', 0);
MINIBROWSER_CONTEXTMENU_JSPRINTDOC : MINIBROWSER_CONTEXTMENU_JSPRINTDOC :
if (browser <> nil) and (browser.MainFrame <> nil) then if (frame <> nil) and frame.IsValid then
browser.MainFrame.ExecuteJavaScript('window.print();', 'about:blank', 0); frame.ExecuteJavaScript('window.print();', 'about:blank', 0);
MINIBROWSER_CONTEXTMENU_UNMUTEAUDIO : MINIBROWSER_CONTEXTMENU_UNMUTEAUDIO :
Chromium1.AudioMuted := False; Chromium1.AudioMuted := False;
@ -684,6 +710,8 @@ procedure TMiniBrowserFrm.Chromium1LoadEnd(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame; const browser: ICefBrowser; const frame: ICefFrame;
httpStatusCode: Integer); httpStatusCode: Integer);
begin begin
if (frame = nil) or not(frame.IsValid) then exit;
if frame.IsMain then if frame.IsMain then
StatusBar1.Panels[1].Text := 'main frame loaded : ' + quotedstr(frame.name) StatusBar1.Panels[1].Text := 'main frame loaded : ' + quotedstr(frame.name)
else else
@ -693,10 +721,17 @@ end;
procedure TMiniBrowserFrm.Chromium1LoadError(Sender: TObject; procedure TMiniBrowserFrm.Chromium1LoadError(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame; errorCode: Integer; const browser: ICefBrowser; const frame: ICefFrame; errorCode: Integer;
const errorText, failedUrl: ustring); const errorText, failedUrl: ustring);
var
TempString : string;
begin begin
CefDebugLog('Error code:' + inttostr(errorCode) + if (errorCode = ERR_ABORTED) then exit;
' - Error text :' + quotedstr(errorText) +
' - URL:' + failedUrl, CEF_LOG_SEVERITY_ERROR); TempString := '<html><body bgcolor="white">' +
'<h2>Failed to load URL ' + failedUrl +
' with error ' + errorText +
' (' + inttostr(errorCode) + ').</h2></body></html>';
frame.LoadURL(CefGetDataURI(TempString, 'text/html'));
end; end;
procedure TMiniBrowserFrm.Chromium1LoadingProgressChange(Sender: TObject; procedure TMiniBrowserFrm.Chromium1LoadingProgressChange(Sender: TObject;
@ -866,7 +901,8 @@ begin
if Chromium1.IsSameBrowser(browser) and if Chromium1.IsSameBrowser(browser) and
(frame <> nil) and (frame <> nil) and
frame.IsMain then frame.IsMain and
frame.IsValid then
InspectResponse(response); InspectResponse(response);
end; end;
@ -1060,9 +1096,9 @@ begin
TempFile.LoadFromFile(OpenDialog1.FileName); TempFile.LoadFromFile(OpenDialog1.FileName);
if (OpenDialog1.FilterIndex = 1) then if (OpenDialog1.FilterIndex = 1) then
TempDATA := 'data:text/html;charset=utf-8;base64,' + CefBase64Encode(TempFile.Memory, TempFile.Size) TempDATA := CefGetDataURI(TempFile.Memory, TempFile.Size, 'text/html', 'utf-8')
else else
TempDATA := 'data:application/pdf;charset=utf-8;base64,' + CefBase64Encode(TempFile.Memory, TempFile.Size); TempDATA := CefGetDataURI(TempFile.Memory, TempFile.Size, 'application/pdf', 'utf-8');
Chromium1.LoadURL(TempDATA); Chromium1.LoadURL(TempDATA);
end; end;
@ -1156,8 +1192,11 @@ begin
end; end;
procedure TMiniBrowserFrm.CopyAllTextMsg(var aMessage : TMessage); procedure TMiniBrowserFrm.CopyAllTextMsg(var aMessage : TMessage);
var
TempName : string;
begin begin
Chromium1.RetrieveText; TempName := InputBox('Frame name', 'Type the fame name or leave it blank to select the main frame :', '');
Chromium1.RetrieveText(TempName);
end; end;
procedure TMiniBrowserFrm.CopyFramesIDsMsg(var aMessage : TMessage); procedure TMiniBrowserFrm.CopyFramesIDsMsg(var aMessage : TMessage);

View File

@ -4,7 +4,7 @@ object PreferencesFrm: TPreferencesFrm
BorderIcons = [biSystemMenu] BorderIcons = [biSystemMenu]
BorderStyle = bsSingle BorderStyle = bsSingle
Caption = 'Preferences' Caption = 'Preferences'
ClientHeight = 397 ClientHeight = 388
ClientWidth = 428 ClientWidth = 428
Color = clBtnFace Color = clBtnFace
Font.Charset = DEFAULT_CHARSET Font.Charset = DEFAULT_CHARSET
@ -13,33 +13,20 @@ object PreferencesFrm: TPreferencesFrm
Font.Name = 'Tahoma' Font.Name = 'Tahoma'
Font.Style = [] Font.Style = []
FormStyle = fsStayOnTop FormStyle = fsStayOnTop
Padding.Left = 10
Padding.Top = 10
Padding.Right = 10
Padding.Bottom = 10
OldCreateOrder = False OldCreateOrder = False
Position = poScreenCenter Position = poScreenCenter
PixelsPerInch = 96 PixelsPerInch = 96
TextHeight = 13 TextHeight = 13
object Button1: TButton
Left = 232
Top = 364
Width = 75
Height = 25
Caption = 'Ok'
ModalResult = 1
TabOrder = 2
end
object Button2: TButton
Left = 345
Top = 364
Width = 75
Height = 25
Caption = 'Cancel'
ModalResult = 2
TabOrder = 3
end
object GroupBox1: TGroupBox object GroupBox1: TGroupBox
Left = 8 Left = 10
Top = 8 Top = 10
Width = 412 Width = 408
Height = 250 Height = 250
Align = alTop
Caption = ' Proxy ' Caption = ' Proxy '
TabOrder = 0 TabOrder = 0
object ProxyTypeLbl: TLabel object ProxyTypeLbl: TLabel
@ -186,10 +173,11 @@ object PreferencesFrm: TPreferencesFrm
end end
end end
object GroupBox2: TGroupBox object GroupBox2: TGroupBox
Left = 8 Left = 10
Top = 271 Top = 260
Width = 412 Width = 408
Height = 84 Height = 84
Align = alTop
Caption = ' Custom header ' Caption = ' Custom header '
TabOrder = 1 TabOrder = 1
object HeaderNameLbl: TLabel object HeaderNameLbl: TLabel
@ -221,4 +209,37 @@ object PreferencesFrm: TPreferencesFrm
TabOrder = 1 TabOrder = 1
end end
end end
object Panel1: TPanel
Left = 10
Top = 353
Width = 408
Height = 25
Align = alBottom
BevelOuter = bvNone
Padding.Left = 30
Padding.Right = 30
TabOrder = 2
ExplicitTop = 373
object Button1: TButton
Left = 30
Top = 0
Width = 120
Height = 25
Align = alLeft
Caption = 'Ok'
ModalResult = 1
TabOrder = 0
end
object Button2: TButton
Left = 258
Top = 0
Width = 120
Height = 25
Align = alRight
Caption = 'Cancel'
ModalResult = 2
TabOrder = 1
ExplicitLeft = 278
end
end
end end

View File

@ -44,16 +44,14 @@ interface
uses uses
{$IFDEF DELPHI16_UP} {$IFDEF DELPHI16_UP}
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Samples.Spin; Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Samples.Spin, Vcl.ExtCtrls;
{$ELSE} {$ELSE}
Windows, Messages, SysUtils, Variants, Classes, Graphics, Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, Spin; Controls, Forms, Dialogs, StdCtrls, Spin, ExtCtrls;
{$ENDIF} {$ENDIF}
type type
TPreferencesFrm = class(TForm) TPreferencesFrm = class(TForm)
Button1: TButton;
Button2: TButton;
GroupBox1: TGroupBox; GroupBox1: TGroupBox;
ProxyTypeCbx: TComboBox; ProxyTypeCbx: TComboBox;
ProxyTypeLbl: TLabel; ProxyTypeLbl: TLabel;
@ -77,6 +75,9 @@ type
ProxySchemeCb: TComboBox; ProxySchemeCb: TComboBox;
MaxConnectionsPerProxyLbl: TLabel; MaxConnectionsPerProxyLbl: TLabel;
MaxConnectionsPerProxyEdt: TSpinEdit; MaxConnectionsPerProxyEdt: TSpinEdit;
Panel1: TPanel;
Button1: TButton;
Button2: TButton;
private private
{ Private declarations } { Private declarations }
public public

View File

@ -157,4 +157,9 @@ object OSRExternalPumpBrowserFrm: TOSRExternalPumpBrowserFrm
Left = 24 Left = 24
Top = 206 Top = 206
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 24
Top = 342
end
end end

View File

@ -50,7 +50,8 @@ uses
Windows, Messages, SysUtils, Variants, Classes, SyncObjs, Windows, Messages, SysUtils, Variants, Classes, SyncObjs,
Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, AppEvnts, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, AppEvnts,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFTypes, uCEFInterfaces, uCEFConstants, uCEFBufferPanel, uCEFWorkScheduler; uCEFChromium, uCEFTypes, uCEFInterfaces, uCEFConstants, uCEFBufferPanel, uCEFWorkScheduler,
uCEFSentinel;
type type
TOSRExternalPumpBrowserFrm = class(TForm) TOSRExternalPumpBrowserFrm = class(TForm)
@ -64,6 +65,7 @@ type
SaveDialog1: TSaveDialog; SaveDialog1: TSaveDialog;
Timer1: TTimer; Timer1: TTimer;
Panel1: TBufferPanel; Panel1: TBufferPanel;
CEFSentinel1: TCEFSentinel;
procedure AppEventsMessage(var Msg: tagMSG; var Handled: Boolean); procedure AppEventsMessage(var Msg: tagMSG; var Handled: Boolean);
@ -107,6 +109,7 @@ type
procedure Timer1Timer(Sender: TObject); procedure Timer1Timer(Sender: TObject);
procedure ComboBox1Enter(Sender: TObject); procedure ComboBox1Enter(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
protected protected
FPopUpBitmap : TBitmap; FPopUpBitmap : TBitmap;
@ -152,7 +155,8 @@ var
// 2- chrmosr.CloseBrowser(True) will trigger chrmosr.OnClose and we have to // 2- chrmosr.CloseBrowser(True) will trigger chrmosr.OnClose and we have to
// set "Result" to false and CEF3 will destroy the internal browser immediately. // set "Result" to false and CEF3 will destroy the internal browser immediately.
// 3- chrmosr.OnBeforeClose is triggered because the internal browser was destroyed. // 3- chrmosr.OnBeforeClose is triggered because the internal browser was destroyed.
// Now we set FCanClose to True and send WM_CLOSE to the form. // Now we call TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4- TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure CreateGlobalCEFApp; procedure CreateGlobalCEFApp;
procedure GlobalCEFApp_OnScheduleMessagePumpWork(const aDelayMS : int64); procedure GlobalCEFApp_OnScheduleMessagePumpWork(const aDelayMS : int64);
@ -187,7 +191,6 @@ begin
GlobalCEFApp.EnableHighDPISupport := True; GlobalCEFApp.EnableHighDPISupport := True;
GlobalCEFApp.ExternalMessagePump := True; GlobalCEFApp.ExternalMessagePump := True;
GlobalCEFApp.MultiThreadedMessageLoop := False; GlobalCEFApp.MultiThreadedMessageLoop := False;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
GlobalCEFApp.OnScheduleMessagePumpWork := GlobalCEFApp_OnScheduleMessagePumpWork; GlobalCEFApp.OnScheduleMessagePumpWork := GlobalCEFApp_OnScheduleMessagePumpWork;
end; end;
@ -326,6 +329,11 @@ begin
end; end;
procedure TOSRExternalPumpBrowserFrm.chrmosrBeforeClose(Sender: TObject; const browser: ICefBrowser); procedure TOSRExternalPumpBrowserFrm.chrmosrBeforeClose(Sender: TObject; const browser: ICefBrowser);
begin
CEFSentinel1.Start;
end;
procedure TOSRExternalPumpBrowserFrm.CEFSentinel1Close(Sender: TObject);
begin begin
FCanClose := True; FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0); PostMessage(Handle, WM_CLOSE, 0, 0);

View File

@ -82,4 +82,9 @@ object MainForm: TMainForm
Left = 56 Left = 56
Top = 216 Top = 216
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 56
Top = 288
end
end end

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, SyncObjs, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, SyncObjs,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes, uChildForm, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes, uChildForm,
Vcl.AppEvnts, uCEFWinControl; Vcl.AppEvnts, uCEFWinControl, uCEFSentinel;
const const
CEF_CREATENEXTCHILD = WM_APP + $A50; CEF_CREATENEXTCHILD = WM_APP + $A50;
@ -65,6 +65,7 @@ type
Chromium1: TChromium; Chromium1: TChromium;
CEFWindowParent1: TCEFWindowParent; CEFWindowParent1: TCEFWindowParent;
AppEvents: TApplicationEvents; AppEvents: TApplicationEvents;
CEFSentinel1: TCEFSentinel;
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure Timer1Timer(Sender: TObject); procedure Timer1Timer(Sender: TObject);
@ -79,6 +80,7 @@ type
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 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 Chromium1Close(Sender: TObject; const browser: ICefBrowser; var aAction: TCefCloseBrowserAction); procedure Chromium1Close(Sender: TObject; const browser: ICefBrowser; var aAction: TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); procedure Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected protected
FChildForm : TChildForm; FChildForm : TChildForm;
@ -142,14 +144,14 @@ uses
// 1. FormCloseQuery sets CanClose to FALSE and it closes all child forms. // 1. FormCloseQuery sets CanClose to FALSE and it closes all child forms.
// 2. When all the child forms are closed then FormCloseQuery is triggered again, sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 2. When all the child forms are closed then FormCloseQuery is triggered again, sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 3. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. // 3. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 4. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 4. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 5. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure CreateGlobalCEFApp; procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.WindowlessRenderingEnabled := True; GlobalCEFApp.WindowlessRenderingEnabled := True;
GlobalCEFApp.EnableHighDPISupport := True; GlobalCEFApp.EnableHighDPISupport := True;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
//GlobalCEFApp.LogFile := 'debug.log'; //GlobalCEFApp.LogFile := 'debug.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO; //GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO;
end; end;
@ -244,8 +246,7 @@ end;
procedure TMainForm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); procedure TMainForm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
function TMainForm.CreateClientHandler(var windowInfo : TCefWindowInfo; function TMainForm.CreateClientHandler(var windowInfo : TCefWindowInfo;
@ -353,6 +354,12 @@ begin
end; end;
end; end;
procedure TMainForm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TMainForm.ChildDestroyedMsg(var aMessage : TMessage); procedure TMainForm.ChildDestroyedMsg(var aMessage : TMessage);
begin begin
if FClosingChildren and (PopupChildCount = 0) then Close; if FClosingChildren and (PopupChildCount = 0) then Close;

View File

@ -77,4 +77,9 @@ object MainForm: TMainForm
Left = 56 Left = 56
Top = 152 Top = 152
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 48
Top = 208
end
end end

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, SyncObjs, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, SyncObjs,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes, uChildForm, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes, uChildForm,
Vcl.AppEvnts, uCEFWinControl; Vcl.AppEvnts, uCEFWinControl, uCEFSentinel;
const const
CEF_CREATENEXTCHILD = WM_APP + $A50; CEF_CREATENEXTCHILD = WM_APP + $A50;
@ -64,6 +64,7 @@ type
Timer1: TTimer; Timer1: TTimer;
Chromium1: TChromium; Chromium1: TChromium;
CEFWindowParent1: TCEFWindowParent; CEFWindowParent1: TCEFWindowParent;
CEFSentinel1: TCEFSentinel;
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure Timer1Timer(Sender: TObject); procedure Timer1Timer(Sender: TObject);
@ -77,6 +78,7 @@ type
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 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 Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); procedure Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
procedure Chromium1Close(Sender: TObject; const browser: ICefBrowser; var aAction: TCefCloseBrowserAction); procedure Chromium1Close(Sender: TObject; const browser: ICefBrowser; var aAction: TCefCloseBrowserAction);
procedure CEFSentinel1Close(Sender: TObject);
protected protected
FChildForm : TChildForm; FChildForm : TChildForm;
@ -140,13 +142,13 @@ uses
// 1. FormCloseQuery sets CanClose to FALSE and it closes all child forms. // 1. FormCloseQuery sets CanClose to FALSE and it closes all child forms.
// 2. When all the child forms are closed then FormCloseQuery is triggered again, sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 2. When all the child forms are closed then FormCloseQuery is triggered again, sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 3. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. // 3. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 4. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 4. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 5. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure CreateGlobalCEFApp; procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.EnableHighDPISupport := True; GlobalCEFApp.EnableHighDPISupport := True;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
//GlobalCEFApp.LogFile := 'cef.log'; //GlobalCEFApp.LogFile := 'cef.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE; //GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end; end;
@ -209,8 +211,7 @@ end;
procedure TMainForm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); procedure TMainForm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TMainForm.Chromium1BeforePopup(Sender : TObject; procedure TMainForm.Chromium1BeforePopup(Sender : TObject;
@ -334,6 +335,12 @@ begin
end; end;
end; end;
procedure TMainForm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TMainForm.ChildDestroyedMsg(var aMessage : TMessage); procedure TMainForm.ChildDestroyedMsg(var aMessage : TMessage);
begin begin
if FClosingChildren and (PopupChildCount = 0) then Close; if FClosingChildren and (PopupChildCount = 0) then Close;

View File

@ -98,4 +98,9 @@ object Form1: TForm1
Left = 56 Left = 56
Top = 152 Top = 152
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 56
Top = 224
end
end end

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, SyncObjs, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, SyncObjs,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes,
uCEFWinControl; uCEFWinControl, uCEFSentinel;
const const
CEF_SHOWDATA = WM_APP + $B00; CEF_SHOWDATA = WM_APP + $B00;
@ -65,6 +65,7 @@ type
Memo1: TMemo; Memo1: TMemo;
AddressCb: TComboBox; AddressCb: TComboBox;
Splitter1: TSplitter; Splitter1: TSplitter;
CEFSentinel1: TCEFSentinel;
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure Timer1Timer(Sender: TObject); procedure Timer1Timer(Sender: TObject);
@ -88,6 +89,7 @@ type
const browser: ICefBrowser; const frame: ICefFrame; const browser: ICefBrowser; const frame: ICefFrame;
const request: ICefRequest; const callback: ICefRequestCallback; const request: ICefRequest; const callback: ICefRequestCallback;
out Result: TCefReturnValue); out Result: TCefReturnValue);
procedure CEFSentinel1Close(Sender: TObject);
protected protected
// Variables to control when can we destroy the form safely // Variables to control when can we destroy the form safely
FCanClose : boolean; // Set to True in TChromium.OnBeforeClose FCanClose : boolean; // Set to True in TChromium.OnBeforeClose
@ -136,17 +138,16 @@ uses
// After the request has been handled we send a custom message to the form (CEF_SHOWDATA) // After the request has been handled we send a custom message to the form (CEF_SHOWDATA)
// to add the information to the TMemo safely in the main thread. // to add the information to the TMemo safely in the main thread.
// Destruction steps // Destruction steps
// ================= // =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. // 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure CreateGlobalCEFApp; procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
//GlobalCEFApp.LogFile := 'cef.log'; //GlobalCEFApp.LogFile := 'cef.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE; //GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end; end;
@ -256,6 +257,7 @@ var
i : integer; i : integer;
begin begin
TempArray := nil; TempArray := nil;
try try
try try
TempPostData := request.PostData; TempPostData := request.PostData;
@ -357,7 +359,9 @@ procedure TForm1.Chromium1BeforeResourceLoad(Sender: TObject;
begin begin
// This event is called before a resource request is loaded. // This event is called before a resource request is loaded.
// The request object may be modified. // The request object may be modified.
if (frame <> nil) and frame.IsValid then
HandleRequest(request, frame.IsMain); HandleRequest(request, frame.IsMain);
Result := RV_CONTINUE; Result := RV_CONTINUE;
end; end;
@ -379,6 +383,11 @@ begin
end; end;
procedure TForm1.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); procedure TForm1.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
begin
CEFSentinel1.Start;
end;
procedure TForm1.CEFSentinel1Close(Sender: TObject);
begin begin
FCanClose := True; FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0); PostMessage(Handle, WM_CLOSE, 0, 0);

View File

@ -167,4 +167,9 @@ object ResponseFilterBrowserFrm: TResponseFilterBrowserFrm
Left = 56 Left = 56
Top = 160 Top = 160
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 56
Top = 232
end
end end

View File

@ -51,7 +51,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, SyncObjs, ComCtrls, pngimage, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, SyncObjs, ComCtrls, pngimage,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes, uCEFResponseFilter, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes, uCEFResponseFilter,
uCEFWinControl; uCEFWinControl, uCEFSentinel;
const const
STREAM_COPY_COMPLETE = WM_APP + $B00; STREAM_COPY_COMPLETE = WM_APP + $B00;
@ -72,6 +72,7 @@ type
StatusBar1: TStatusBar; StatusBar1: TStatusBar;
CopyScriptBtn: TRadioButton; CopyScriptBtn: TRadioButton;
ReplaceLogoBtn: TRadioButton; ReplaceLogoBtn: TRadioButton;
CEFSentinel1: TCEFSentinel;
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
procedure Chromium1GetResourceResponseFilter(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const request: ICefRequest; const response: ICefResponse; out Result: ICefResponseFilter); procedure Chromium1GetResourceResponseFilter(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const request: ICefRequest; const response: ICefResponse; out Result: ICefResponseFilter);
@ -90,6 +91,7 @@ type
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure Timer1Timer(Sender: TObject); procedure Timer1Timer(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
protected protected
FFilter : ICefResponseFilter; // CEF Filter interface that receives the resource contents FFilter : ICefResponseFilter; // CEF Filter interface that receives the resource contents
@ -159,8 +161,9 @@ uses
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy // 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy
// CEFWindowParent1 in the main thread, which triggers the // CEFWindowParent1 in the main thread, which triggers the
// TChromium.OnBeforeClose event. // TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE // 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger
// to the form. // TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
// TCustomResponseFilter.OnFilter event might be called multiple times // TCustomResponseFilter.OnFilter event might be called multiple times
// when the resource is too big. In that case the resource will be split into // when the resource is too big. In that case the resource will be split into
@ -192,7 +195,6 @@ uses
procedure CreateGlobalCEFApp; procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
GlobalCEFApp.LogFile := 'cef.log'; GlobalCEFApp.LogFile := 'cef.log';
GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE; GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end; end;
@ -404,8 +406,7 @@ end;
procedure TResponseFilterBrowserFrm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); procedure TResponseFilterBrowserFrm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TResponseFilterBrowserFrm.Chromium1BeforePopup( Sender : TObject; procedure TResponseFilterBrowserFrm.Chromium1BeforePopup( Sender : TObject;
@ -507,7 +508,7 @@ const
var var
TempPath : string; TempPath : string;
begin begin
if frame.IsMain then if (frame <> nil) and frame.IsValid and frame.IsMain then
try try
try try
FStreamCS.Acquire; FStreamCS.Acquire;
@ -542,6 +543,12 @@ begin
{$ENDIF} {$ENDIF}
end; end;
procedure TResponseFilterBrowserFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TResponseFilterBrowserFrm.CheckResponseHeaders(const response : ICefResponse); procedure TResponseFilterBrowserFrm.CheckResponseHeaders(const response : ICefResponse);
var var
TempContentLength, TempContentEncoding : string; TempContentLength, TempContentEncoding : string;

View File

@ -82,4 +82,9 @@ object SchemeRegistrationBrowserFrm: TSchemeRegistrationBrowserFrm
Left = 16 Left = 16
Top = 96 Top = 96
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 16
Top = 152
end
end end

View File

@ -51,7 +51,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Types, ComCtrls, ClipBrd, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Types, ComCtrls, ClipBrd,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFSchemeRegistrar, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFSchemeRegistrar,
uCEFTypes, uCEFConstants, uCEFWinControl; uCEFTypes, uCEFConstants, uCEFWinControl, uCEFSentinel;
const const
MINIBROWSER_CONTEXTMENU_REGSCHEME = MENU_ID_USER_FIRST + 1; MINIBROWSER_CONTEXTMENU_REGSCHEME = MENU_ID_USER_FIRST + 1;
@ -65,6 +65,7 @@ type
Chromium1: TChromium; Chromium1: TChromium;
AddressCbx: TComboBox; AddressCbx: TComboBox;
Timer1: TTimer; Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure Chromium1AfterCreated(Sender: TObject; procedure Chromium1AfterCreated(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
procedure Chromium1BeforeContextMenu(Sender: TObject; procedure Chromium1BeforeContextMenu(Sender: TObject;
@ -91,6 +92,7 @@ type
var aAction : TCefCloseBrowserAction); var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject; procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
private private
{ Private declarations } { Private declarations }
protected protected
@ -135,7 +137,8 @@ uses
// ================= // =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. // 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure GlobalCEFApp_OnRegCustomSchemes(const registrar: TCefSchemeRegistrarRef); procedure GlobalCEFApp_OnRegCustomSchemes(const registrar: TCefSchemeRegistrarRef);
begin begin
@ -146,12 +149,17 @@ procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnRegCustomSchemes := GlobalCEFApp_OnRegCustomSchemes; GlobalCEFApp.OnRegCustomSchemes := GlobalCEFApp_OnRegCustomSchemes;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
// GlobalCEFApp.LogFile := 'debug.log'; // GlobalCEFApp.LogFile := 'debug.log';
// GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE; // GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end; end;
procedure TSchemeRegistrationBrowserFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TSchemeRegistrationBrowserFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure TSchemeRegistrationBrowserFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0); PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -160,8 +168,7 @@ end;
procedure TSchemeRegistrationBrowserFrm.Chromium1BeforeClose( procedure TSchemeRegistrationBrowserFrm.Chromium1BeforeClose(
Sender: TObject; const browser: ICefBrowser); Sender: TObject; const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TSchemeRegistrationBrowserFrm.Chromium1BeforeContextMenu( procedure TSchemeRegistrationBrowserFrm.Chromium1BeforeContextMenu(

View File

@ -68,9 +68,6 @@ begin
GlobalCEFApp.UserDataPath := 'cef\User Data'; GlobalCEFApp.UserDataPath := 'cef\User Data';
} }
// Disabling some features to improve stability
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
// You *MUST* call GlobalCEFApp.StartMainProcess in a if..then clause // You *MUST* call GlobalCEFApp.StartMainProcess in a if..then clause
// with the Application initialization inside the begin..end. // with the Application initialization inside the begin..end.
// Read this https://www.briskbard.com/index.php?lang=en&pageid=cef // Read this https://www.briskbard.com/index.php?lang=en&pageid=cef

View File

@ -72,4 +72,9 @@ object Form1: TForm1
Left = 56 Left = 56
Top = 88 Top = 88
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 56
Top = 160
end
end end

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFChromiumWindow, uCEFTypes, uCEFInterfaces, uCEFChromium, uCEFWindowParent, uCEFChromiumWindow, uCEFTypes, uCEFInterfaces,
uCEFWinControl; uCEFWinControl, uCEFSentinel;
type type
TForm1 = class(TForm) TForm1 = class(TForm)
@ -59,6 +59,7 @@ type
AddressEdt: TEdit; AddressEdt: TEdit;
GoBtn: TButton; GoBtn: TButton;
Timer1: TTimer; Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure Timer1Timer(Sender: TObject); procedure Timer1Timer(Sender: TObject);
@ -70,6 +71,7 @@ type
procedure ChromiumWindow1AfterCreated(Sender: TObject); procedure ChromiumWindow1AfterCreated(Sender: TObject);
procedure ChromiumWindow1Close(Sender: TObject); procedure ChromiumWindow1Close(Sender: TObject);
procedure ChromiumWindow1BeforeClose(Sender: TObject); procedure ChromiumWindow1BeforeClose(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
private private
// You have to handle this two messages to call NotifyMoveOrResizeStarted or some page elements will be misaligned. // You have to handle this two messages to call NotifyMoveOrResizeStarted or some page elements will be misaligned.
@ -116,7 +118,8 @@ uses
// ================= // =================
// 1. The FormCloseQuery event sets CanClose to False and calls TChromiumWindow.CloseBrowser, which triggers the TChromiumWindow.OnClose event. // 1. The FormCloseQuery event sets CanClose to False and calls TChromiumWindow.CloseBrowser, which triggers the TChromiumWindow.OnClose event.
// 2. The TChromiumWindow.OnClose event calls TChromiumWindow.DestroyChildWindow which triggers the TChromiumWindow.OnBeforeClose event. // 2. The TChromiumWindow.OnClose event calls TChromiumWindow.DestroyChildWindow which triggers the TChromiumWindow.OnBeforeClose event.
// 3. TChromiumWindow.OnBeforeClose sets FCanClose to True and closes the form. // 3. TChromiumWindow.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
@ -151,20 +154,21 @@ begin
if not(ChromiumWindow1.CreateBrowser) then Timer1.Enabled := True; if not(ChromiumWindow1.CreateBrowser) then Timer1.Enabled := True;
end; end;
procedure TForm1.ChromiumWindow1BeforeClose(Sender: TObject); procedure TForm1.CEFSentinel1Close(Sender: TObject);
begin begin
FCanClose := True; FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0); PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TForm1.ChromiumWindow1BeforeClose(Sender: TObject);
begin
CEFSentinel1.Start;
end;
procedure TForm1.ChromiumWindow1Close(Sender: TObject); procedure TForm1.ChromiumWindow1Close(Sender: TObject);
begin begin
// DestroyChildWindow will destroy the child window created by CEF at the top of the Z order. // DestroyChildWindow will destroy the child window created by CEF at the top of the Z order.
if not(ChromiumWindow1.DestroyChildWindow) then if not(ChromiumWindow1.DestroyChildWindow) then CEFSentinel1.Start;
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
end; end;
procedure TForm1.Chromium_OnBeforePopup( Sender : TObject; procedure TForm1.Chromium_OnBeforePopup( Sender : TObject;

View File

@ -70,9 +70,6 @@ begin
GlobalCEFApp.UserDataPath := 'cef\User Data'; GlobalCEFApp.UserDataPath := 'cef\User Data';
} }
// Disabling some features to improve stability
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
// You *MUST* call GlobalCEFApp.StartMainProcess in a if..then clause // You *MUST* call GlobalCEFApp.StartMainProcess in a if..then clause
// with the Application initialization inside the begin..end. // with the Application initialization inside the begin..end.
// Read this https://www.briskbard.com/index.php?lang=en&pageid=cef // Read this https://www.briskbard.com/index.php?lang=en&pageid=cef

View File

@ -77,4 +77,9 @@ object Form1: TForm1
Left = 56 Left = 56
Top = 152 Top = 152
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 56
Top = 224
end
end end

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes,
uCEFWinControl; uCEFWinControl, uCEFSentinel;
type type
TForm1 = class(TForm) TForm1 = class(TForm)
@ -60,6 +60,7 @@ type
Timer1: TTimer; Timer1: TTimer;
Chromium1: TChromium; Chromium1: TChromium;
CEFWindowParent1: TCEFWindowParent; CEFWindowParent1: TCEFWindowParent;
CEFSentinel1: TCEFSentinel;
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure Timer1Timer(Sender: TObject); procedure Timer1Timer(Sender: TObject);
@ -84,6 +85,7 @@ type
const targetUrl: ustring; const targetUrl: ustring;
targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean;
out Result: Boolean); out Result: Boolean);
procedure CEFSentinel1Close(Sender: TObject);
protected protected
// Variables to control when can we destroy the form safely // Variables to control when can we destroy the form safely
FCanClose : boolean; // Set to True in TChromium.OnBeforeClose FCanClose : boolean; // Set to True in TChromium.OnBeforeClose
@ -130,7 +132,8 @@ uses
// ================= // =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. // 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin begin
@ -162,6 +165,12 @@ begin
if not(Chromium1.CreateBrowser(CEFWindowParent1)) then Timer1.Enabled := True; if not(Chromium1.CreateBrowser(CEFWindowParent1)) then Timer1.Enabled := True;
end; end;
procedure TForm1.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TForm1.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure TForm1.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin begin
// Now the browser is fully initialized we can send a message to the main form to load the initial web page. // Now the browser is fully initialized we can send a message to the main form to load the initial web page.
@ -171,8 +180,7 @@ end;
procedure TForm1.Chromium1BeforeClose(Sender: TObject; procedure TForm1.Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser); const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TForm1.Chromium1BeforePopup(Sender: TObject; procedure TForm1.Chromium1BeforePopup(Sender: TObject;

View File

@ -94,4 +94,9 @@ object SimpleExternalPumpBrowserFrm: TSimpleExternalPumpBrowserFrm
Left = 56 Left = 56
Top = 88 Top = 88
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 56
Top = 160
end
end end

View File

@ -50,7 +50,8 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFTypes, uCEFConstants, uCEFInterfaces, uCEFWorkScheduler, uCEFChromium, uCEFWindowParent, uCEFTypes, uCEFConstants, uCEFInterfaces, uCEFWorkScheduler,
uCEFChromiumWindow, Vcl.ComCtrls, Vcl.AppEvnts, uCEFWinControl; uCEFChromiumWindow, Vcl.ComCtrls, Vcl.AppEvnts, uCEFWinControl,
uCEFSentinel;
type type
TSimpleExternalPumpBrowserFrm = class(TForm) TSimpleExternalPumpBrowserFrm = class(TForm)
@ -59,10 +60,12 @@ type
Timer1: TTimer; Timer1: TTimer;
URLCbx: TComboBox; URLCbx: TComboBox;
ChromiumWindow1: TChromiumWindow; ChromiumWindow1: TChromiumWindow;
CEFSentinel1: TCEFSentinel;
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure Timer1Timer(Sender: TObject); procedure Timer1Timer(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
@ -101,7 +104,8 @@ uses
// It was necessary to destroy the browser with the following destruction sequence : // It was necessary to destroy the browser with the following destruction sequence :
// 1. The FormCloseQuery event sets CanClose to False and calls TChromiumWindow.CloseBrowser, which triggers the TChromiumWindow.OnClose event. // 1. The FormCloseQuery event sets CanClose to False and calls TChromiumWindow.CloseBrowser, which triggers the TChromiumWindow.OnClose event.
// 2. The TChromiumWindow.OnClose event calls TChromiumWindow.DestroyChildWindow which triggers the TChromiumWindow.OnBeforeClose event. // 2. The TChromiumWindow.OnClose event calls TChromiumWindow.DestroyChildWindow which triggers the TChromiumWindow.OnBeforeClose event.
// 3. TChromiumWindow.OnBeforeClose sets FCanClose to True and closes the form. // 3. TChromiumWindow.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure GlobalCEFApp_OnScheduleMessagePumpWork(const aDelayMS : int64); procedure GlobalCEFApp_OnScheduleMessagePumpWork(const aDelayMS : int64);
begin begin
@ -120,7 +124,6 @@ begin
GlobalCEFApp.ExternalMessagePump := True; GlobalCEFApp.ExternalMessagePump := True;
GlobalCEFApp.MultiThreadedMessageLoop := False; GlobalCEFApp.MultiThreadedMessageLoop := False;
GlobalCEFApp.OnScheduleMessagePumpWork := GlobalCEFApp_OnScheduleMessagePumpWork; GlobalCEFApp.OnScheduleMessagePumpWork := GlobalCEFApp_OnScheduleMessagePumpWork;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end; end;
procedure TSimpleExternalPumpBrowserFrm.FormCreate(Sender: TObject); procedure TSimpleExternalPumpBrowserFrm.FormCreate(Sender: TObject);
@ -173,20 +176,21 @@ begin
GoBtn.Click; GoBtn.Click;
end; end;
procedure TSimpleExternalPumpBrowserFrm.ChromiumWindow1BeforeClose(Sender: TObject); procedure TSimpleExternalPumpBrowserFrm.CEFSentinel1Close(Sender: TObject);
begin begin
FCanClose := True; FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0); PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TSimpleExternalPumpBrowserFrm.ChromiumWindow1BeforeClose(Sender: TObject);
begin
CEFSentinel1.Start;
end;
procedure TSimpleExternalPumpBrowserFrm.ChromiumWindow1Close(Sender: TObject); procedure TSimpleExternalPumpBrowserFrm.ChromiumWindow1Close(Sender: TObject);
begin begin
// DestroyChildWindow will destroy the child window created by CEF at the top of the Z order. // DestroyChildWindow will destroy the child window created by CEF at the top of the Z order.
if not(ChromiumWindow1.DestroyChildWindow) then if not(ChromiumWindow1.DestroyChildWindow) then CEFSentinel1.Start;
begin
FCanClose := True;
Close;
end;
end; end;
procedure TSimpleExternalPumpBrowserFrm.GoBtnClick(Sender: TObject); procedure TSimpleExternalPumpBrowserFrm.GoBtnClick(Sender: TObject);

View File

@ -160,4 +160,9 @@ object Form1: TForm1
Left = 24 Left = 24
Top = 206 Top = 206
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 24
Top = 350
end
end end

View File

@ -50,7 +50,8 @@ uses
Windows, Messages, SysUtils, Variants, Classes, SyncObjs, Windows, Messages, SysUtils, Variants, Classes, SyncObjs,
Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, AppEvnts, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, AppEvnts,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFTypes, uCEFInterfaces, uCEFConstants, uCEFBufferPanel; uCEFChromium, uCEFTypes, uCEFInterfaces, uCEFConstants, uCEFBufferPanel,
uCEFSentinel;
const const
// Set this constant to True and load "file://transparency.html" to test a // Set this constant to True and load "file://transparency.html" to test a
@ -69,6 +70,7 @@ type
SaveDialog1: TSaveDialog; SaveDialog1: TSaveDialog;
Timer1: TTimer; Timer1: TTimer;
Panel1: TBufferPanel; Panel1: TBufferPanel;
CEFSentinel1: TCEFSentinel;
procedure AppEventsMessage(var Msg: tagMSG; var Handled: Boolean); procedure AppEventsMessage(var Msg: tagMSG; var Handled: Boolean);
@ -113,6 +115,7 @@ type
procedure Timer1Timer(Sender: TObject); procedure Timer1Timer(Sender: TObject);
procedure ComboBox1Enter(Sender: TObject); procedure ComboBox1Enter(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
protected protected
FPopUpBitmap : TBitmap; FPopUpBitmap : TBitmap;
@ -174,14 +177,14 @@ uses
// 2- chrmosr.CloseBrowser(True) will trigger chrmosr.OnClose and we have to // 2- chrmosr.CloseBrowser(True) will trigger chrmosr.OnClose and we have to
// set "Result" to false and CEF3 will destroy the internal browser immediately. // set "Result" to false and CEF3 will destroy the internal browser immediately.
// 3- chrmosr.OnBeforeClose is triggered because the internal browser was destroyed. // 3- chrmosr.OnBeforeClose is triggered because the internal browser was destroyed.
// Now we set FCanClose to True and send WM_CLOSE to the form. // Now we call TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4- TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure CreateGlobalCEFApp; procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.WindowlessRenderingEnabled := True; GlobalCEFApp.WindowlessRenderingEnabled := True;
GlobalCEFApp.EnableHighDPISupport := True; GlobalCEFApp.EnableHighDPISupport := True;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
// If you need transparency leave the GlobalCEFApp.BackgroundColor property // If you need transparency leave the GlobalCEFApp.BackgroundColor property
// with the default value or set the alpha channel to 0 // with the default value or set the alpha channel to 0
@ -327,8 +330,7 @@ end;
procedure TForm1.chrmosrBeforeClose(Sender: TObject; const browser: ICefBrowser); procedure TForm1.chrmosrBeforeClose(Sender: TObject; const browser: ICefBrowser);
begin begin
FCanClose := True; CEFSentinel1.Start;
PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TForm1.chrmosrBeforePopup(Sender : TObject; procedure TForm1.chrmosrBeforePopup(Sender : TObject;
@ -895,6 +897,12 @@ begin
(cardinal(aCurrentTime - FLastClickTime) > GetDoubleClickTime); (cardinal(aCurrentTime - FLastClickTime) > GetDoubleClickTime);
end; end;
procedure TForm1.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TForm1.Panel1Enter(Sender: TObject); procedure TForm1.Panel1Enter(Sender: TObject);
begin begin
chrmosr.SendFocusEvent(True); chrmosr.SendFocusEvent(True);

View File

@ -53,7 +53,6 @@ uses
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
// The main process and the subprocess *MUST* have the same GlobalCEFApp // The main process and the subprocess *MUST* have the same GlobalCEFApp
// properties and events, specially FrameworkDirPath, ResourcesDirPath, // properties and events, specially FrameworkDirPath, ResourcesDirPath,

View File

@ -65,7 +65,6 @@ begin
GlobalCEFApp.UserDataPath := 'cef\User Data'; GlobalCEFApp.UserDataPath := 'cef\User Data';
} }
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
GlobalCEFApp.BrowserSubprocessPath := 'SubProcess.exe'; GlobalCEFApp.BrowserSubprocessPath := 'SubProcess.exe';
// This demo uses a different EXE for the subprocesses. // This demo uses a different EXE for the subprocesses.

View File

@ -70,4 +70,9 @@ object Form1: TForm1
Left = 80 Left = 80
Top = 88 Top = 88
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 80
Top = 160
end
end end

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFChromiumWindow, uCEFTypes, uCEFInterfaces, uCEFChromium, uCEFWindowParent, uCEFChromiumWindow, uCEFTypes, uCEFInterfaces,
uCEFWinControl; uCEFWinControl, uCEFSentinel;
type type
TForm1 = class(TForm) TForm1 = class(TForm)
@ -59,6 +59,7 @@ type
AddressEdt: TEdit; AddressEdt: TEdit;
GoBtn: TButton; GoBtn: TButton;
Timer1: TTimer; Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure ChromiumWindow1AfterCreated(Sender: TObject); procedure ChromiumWindow1AfterCreated(Sender: TObject);
@ -66,6 +67,7 @@ type
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure ChromiumWindow1Close(Sender: TObject); procedure ChromiumWindow1Close(Sender: TObject);
procedure ChromiumWindow1BeforeClose(Sender: TObject); procedure ChromiumWindow1BeforeClose(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
private private
// You have to handle this two messages to call NotifyMoveOrResizeStarted or some page elements will be misaligned. // You have to handle this two messages to call NotifyMoveOrResizeStarted or some page elements will be misaligned.
procedure WMMove(var aMessage : TWMMove); message WM_MOVE; procedure WMMove(var aMessage : TWMMove); message WM_MOVE;
@ -110,7 +112,8 @@ uses
// ================= // =================
// 1. The FormCloseQuery event sets CanClose to False and calls TChromiumWindow.CloseBrowser, which triggers the TChromiumWindow.OnClose event. // 1. The FormCloseQuery event sets CanClose to False and calls TChromiumWindow.CloseBrowser, which triggers the TChromiumWindow.OnClose event.
// 2. The TChromiumWindow.OnClose event calls TChromiumWindow.DestroyChildWindow which triggers the TChromiumWindow.OnBeforeClose event. // 2. The TChromiumWindow.OnClose event calls TChromiumWindow.DestroyChildWindow which triggers the TChromiumWindow.OnBeforeClose event.
// 3. TChromiumWindow.OnBeforeClose sets FCanClose to True and closes the form. // 3. TChromiumWindow.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin begin
@ -147,14 +150,15 @@ end;
procedure TForm1.ChromiumWindow1Close(Sender: TObject); procedure TForm1.ChromiumWindow1Close(Sender: TObject);
begin begin
// DestroyChildWindow will destroy the child window created by CEF at the top of the Z order. // DestroyChildWindow will destroy the child window created by CEF at the top of the Z order.
if not(ChromiumWindow1.DestroyChildWindow) then if not(ChromiumWindow1.DestroyChildWindow) then CEFSentinel1.Start;
begin
FCanClose := True;
Close;
end;
end; end;
procedure TForm1.ChromiumWindow1BeforeClose(Sender: TObject); procedure TForm1.ChromiumWindow1BeforeClose(Sender: TObject);
begin
CEFSentinel1.Start;
end;
procedure TForm1.CEFSentinel1Close(Sender: TObject);
begin begin
FCanClose := True; FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0); PostMessage(Handle, WM_CLOSE, 0, 0);

View File

@ -202,4 +202,9 @@ object MainForm: TMainForm
TabOrder = 1 TabOrder = 1
OnChange = PageControl1Change OnChange = PageControl1Change
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 344
Top = 104
end
end end

View File

@ -49,7 +49,8 @@ uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, ComCtrls, Buttons, ExtCtrls, StdCtrls, Controls, Forms, Dialogs, ComCtrls, Buttons, ExtCtrls, StdCtrls,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants; uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFSentinel;
const const
CEFBROWSER_DESTROYWNDPARENT = WM_APP + $100; CEFBROWSER_DESTROYWNDPARENT = WM_APP + $100;
@ -72,6 +73,7 @@ type
URLCbx: TComboBox; URLCbx: TComboBox;
AddTabBtn: TButton; AddTabBtn: TButton;
RemoveTabBtn: TButton; RemoveTabBtn: TButton;
CEFSentinel1: TCEFSentinel;
procedure AddTabBtnClick(Sender: TObject); procedure AddTabBtnClick(Sender: TObject);
procedure RemoveTabBtnClick(Sender: TObject); procedure RemoveTabBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
@ -83,6 +85,7 @@ type
procedure StopBtnClick(Sender: TObject); procedure StopBtnClick(Sender: TObject);
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
protected protected
FClosingTab : boolean; FClosingTab : boolean;
@ -144,7 +147,9 @@ implementation
// This is the destruction sequence when the user closes the main form // This is the destruction sequence when the user closes the main form
// 1. FormCloseQuery hides the form and calls CloseAllBrowsers which calls TChromium.CloseBrowser in all tabs and triggers the TChromium.OnClose event. // 1. FormCloseQuery hides the form and calls CloseAllBrowsers which calls TChromium.CloseBrowser in all tabs and triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROYWNDPARENT message to destroy TCEFWindowParent in the main thread which triggers a TChromium.OnBeforeClose event. // 2. TChromium.OnClose sends a CEFBROWSER_DESTROYWNDPARENT message to destroy TCEFWindowParent in the main thread which triggers a TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sends a CEFBROWSER_CHECKTAGGEDTABS message to set the TAG property to 1 in the TabSheet containing the TChromium. Then sends WM_CLOSE in case all tabsheets have a TAG = 1. // 3. TChromium.OnBeforeClose sends a CEFBROWSER_CHECKTAGGEDTABS message to set the TAG property to 1 in the TabSheet containing the TChromium.
// When all tabsheets have a TAG = 1 it calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sends WM_CLOSE to the form.
procedure GlobalCEFApp_OnContextInitialized; procedure GlobalCEFApp_OnContextInitialized;
begin begin
@ -156,7 +161,6 @@ procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnContextInitialized := GlobalCEFApp_OnContextInitialized; GlobalCEFApp.OnContextInitialized := GlobalCEFApp_OnContextInitialized;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end; end;
procedure TMainForm.AddTabBtnClick(Sender: TObject); procedure TMainForm.AddTabBtnClick(Sender: TObject);
@ -350,11 +354,7 @@ begin
begin begin
PageControl1.Pages[aMessage.lParam].Tag := 1; PageControl1.Pages[aMessage.lParam].Tag := 1;
if AllTabSheetsAreTagged then if AllTabSheetsAreTagged then CEFSentinel1.Start;
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
end; end;
end; end;
@ -576,4 +576,10 @@ begin
end; end;
end; end;
procedure TMainForm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
end. end.

View File

@ -45,4 +45,8 @@ object MainForm: TMainForm
OnClick = Button1Click OnClick = Button1Click
end end
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 224
end
end end

View File

@ -44,11 +44,12 @@ interface
uses uses
{$IFDEF DELPHI16_UP} {$IFDEF DELPHI16_UP}
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls; Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls,
{$ELSE} {$ELSE}
Windows, Messages, SysUtils, Variants, Classes, Graphics, Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, ExtCtrls; Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
{$ENDIF} {$ENDIF}
uCEFSentinel;
const const
CEFBROWSER_CREATED = WM_APP + $100; CEFBROWSER_CREATED = WM_APP + $100;
@ -61,9 +62,11 @@ type
ButtonPnl: TPanel; ButtonPnl: TPanel;
Edit1: TEdit; Edit1: TEdit;
Button1: TButton; Button1: TButton;
CEFSentinel1: TCEFSentinel;
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject); procedure Button1Click(Sender: TObject);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
private private
// Variables to control when can we destroy the form safely // Variables to control when can we destroy the form safely
FCanClose : boolean; // Set to True when all the child forms are closed FCanClose : boolean; // Set to True when all the child forms are closed
@ -100,7 +103,8 @@ uses
// Destruction steps // Destruction steps
// ================= // =================
// 1. Destroy all child forms // 1. Destroy all child forms
// 2. Wait until all the child forms are closed before closing the main form and terminating the application. // 2. Wait until all the child forms are closed before calling TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when all renderer processes are closed
// 3. TCEFSentinel.OnClose closes the main form.
procedure GlobalCEFApp_OnContextInitialized; procedure GlobalCEFApp_OnContextInitialized;
begin begin
@ -112,7 +116,6 @@ procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnContextInitialized := GlobalCEFApp_OnContextInitialized; GlobalCEFApp.OnContextInitialized := GlobalCEFApp_OnContextInitialized;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end; end;
procedure TMainForm.CreateToolboxChild(const ChildCaption, URL: string); procedure TMainForm.CreateToolboxChild(const ChildCaption, URL: string);
@ -207,11 +210,7 @@ end;
procedure TMainForm.ChildDestroyedMsg(var aMessage : TMessage); procedure TMainForm.ChildDestroyedMsg(var aMessage : TMessage);
begin begin
// If there are no more child forms we can destroy the main form // If there are no more child forms we can destroy the main form
if FClosing and (ChildFormCount = 0) then if FClosing and (ChildFormCount = 0) then CEFSentinel1.Start;
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
end; end;
function TMainForm.CloseQuery: Boolean; function TMainForm.CloseQuery: Boolean;
@ -242,6 +241,12 @@ begin
cursor := crDefault; cursor := crDefault;
end; end;
procedure TMainForm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TMainForm.FormShow(Sender: TObject); procedure TMainForm.FormShow(Sender: TObject);
begin begin
if (GlobalCEFApp <> nil) and GlobalCEFApp.GlobalContextInitialized then if (GlobalCEFApp <> nil) and GlobalCEFApp.GlobalContextInitialized then

View File

@ -193,4 +193,9 @@ object URLRequestFrm: TURLRequestFrm
Left = 304 Left = 304
Top = 104 Top = 104
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
Left = 160
Top = 112
end
end end

View File

@ -47,7 +47,8 @@ uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, ComCtrls, StdCtrls, Controls, Forms, Dialogs, ComCtrls, StdCtrls,
{$ENDIF} {$ENDIF}
uCEFInterfaces, uCEFUrlRequestClientComponent, uCEFRequest, uCEFUrlRequest; uCEFInterfaces, uCEFUrlRequestClientComponent, uCEFRequest, uCEFUrlRequest,
uCEFSentinel;
const const
URLREQUEST_SUCCESS = WM_APP + $101; URLREQUEST_SUCCESS = WM_APP + $101;
@ -77,9 +78,12 @@ type
Label6: TLabel; Label6: TLabel;
PostParam2NameEdt: TEdit; PostParam2NameEdt: TEdit;
PostParam2ValueEdt: TEdit; PostParam2ValueEdt: TEdit;
CEFSentinel1: TCEFSentinel;
procedure DownloadBtnClick(Sender: TObject); procedure DownloadBtnClick(Sender: TObject);
procedure SendPostReqBtnClick(Sender: TObject); procedure SendPostReqBtnClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
procedure FormDestroy(Sender: TObject); procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
@ -90,8 +94,6 @@ type
procedure CEFUrlRequestClientComponent1RequestComplete(Sender: TObject; const request: ICefUrlRequest); procedure CEFUrlRequestClientComponent1RequestComplete(Sender: TObject; const request: ICefUrlRequest);
procedure CEFUrlRequestClientComponent1CreateURLRequest(Sender: TObject); procedure CEFUrlRequestClientComponent1CreateURLRequest(Sender: TObject);
procedure Button1Click(Sender: TObject);
private private
FMemStream : TMemoryStream; FMemStream : TMemoryStream;
FCanClose : boolean; FCanClose : boolean;
@ -134,7 +136,8 @@ implementation
// 1- Set CanClose to FALSE in the TForm.OnCloseQuery event and set FClosing to TRUE. // 1- Set CanClose to FALSE in the TForm.OnCloseQuery event and set FClosing to TRUE.
// 2- The next time TCEFUrlRequestClientComponent.OnDownloadProgress is executed we call request.Cancel, which triggers the // 2- The next time TCEFUrlRequestClientComponent.OnDownloadProgress is executed we call request.Cancel, which triggers the
// TCEFUrlRequestClientComponent.OnRequestComplete event. // TCEFUrlRequestClientComponent.OnRequestComplete event.
// 3- in the TCEFUrlRequestClientComponent.OnRequestComplete event we set FCanClose to TRUE and send WM_CLOSE to the form. // 3- in the TCEFUrlRequestClientComponent.OnRequestComplete event we call TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4- TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
uses uses
ShellApi, ShellApi,
@ -143,7 +146,8 @@ uses
procedure CreateGlobalCEFApp; procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors'; //GlobalCEFApp.LogFile := 'cef.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end; end;
procedure TURLRequestFrm.DownloadBtnClick(Sender: TObject); procedure TURLRequestFrm.DownloadBtnClick(Sender: TObject);
@ -221,6 +225,12 @@ begin
ShellExecute(0, 'open', 'https://ptsv2.com/t/cef4delphi', nil, nil, SW_SHOWNORMAL); ShellExecute(0, 'open', 'https://ptsv2.com/t/cef4delphi', nil, nil, SW_SHOWNORMAL);
end; end;
procedure TURLRequestFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TURLRequestFrm.CEFUrlRequestClientComponent1CreateURLRequest(Sender: TObject); procedure TURLRequestFrm.CEFUrlRequestClientComponent1CreateURLRequest(Sender: TObject);
begin begin
if FSendingGET then if FSendingGET then
@ -344,10 +354,7 @@ begin
// Use request.response here to get a ICefResponse interface with all the response headers, status, error code, etc. // Use request.response here to get a ICefResponse interface with all the response headers, status, error code, etc.
if FClosing then if FClosing then
begin CEFSentinel1.Start
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end
else else
if (request <> nil) and (request.RequestStatus = UR_SUCCESS) then if (request <> nil) and (request.RequestStatus = UR_SUCCESS) then
PostMessage(Handle, URLREQUEST_SUCCESS, 0, 0) PostMessage(Handle, URLREQUEST_SUCCESS, 0, 0)

View File

@ -8,7 +8,7 @@
<Unit0> <Unit0>
<Filename Value="CookieVisitor.lpr"/> <Filename Value="CookieVisitor.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<TopLine Value="44"/> <TopLine Value="40"/>
<CursorPos X="25" Y="74"/> <CursorPos X="25" Y="74"/>
<UsageCount Value="22"/> <UsageCount Value="22"/>
<Loaded Value="True"/> <Loaded Value="True"/>
@ -20,9 +20,10 @@
<ComponentName Value="CookieVisitorFrm"/> <ComponentName Value="CookieVisitorFrm"/>
<HasResources Value="True"/> <HasResources Value="True"/>
<ResourceBaseClass Value="Form"/> <ResourceBaseClass Value="Form"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="1"/> <EditorIndex Value="1"/>
<TopLine Value="139"/> <TopLine Value="131"/>
<CursorPos X="69" Y="149"/> <CursorPos X="82" Y="150"/>
<UsageCount Value="22"/> <UsageCount Value="22"/>
<Loaded Value="True"/> <Loaded Value="True"/>
<LoadedDesigner Value="True"/> <LoadedDesigner Value="True"/>
@ -41,15 +42,13 @@
</Unit2> </Unit2>
<Unit3> <Unit3>
<Filename Value="C:\lazarus\lcl\interfaces\win32\win32object.inc"/> <Filename Value="C:\lazarus\lcl\interfaces\win32\win32object.inc"/>
<IsVisibleTab Value="True"/> <EditorIndex Value="-1"/>
<EditorIndex Value="2"/> <TopLine Value="354"/>
<TopLine Value="355"/>
<CursorPos Y="413"/> <CursorPos Y="413"/>
<UsageCount Value="10"/> <UsageCount Value="10"/>
<Loaded Value="True"/>
</Unit3> </Unit3>
</Units> </Units>
<JumpHistory Count="12" HistoryIndex="11"> <JumpHistory Count="14" HistoryIndex="13">
<Position1> <Position1>
<Filename Value="CookieVisitor.lpr"/> <Filename Value="CookieVisitor.lpr"/>
</Position1> </Position1>
@ -97,6 +96,14 @@
<Filename Value="uCookieVisitor.pas"/> <Filename Value="uCookieVisitor.pas"/>
<Caret Line="149" Column="69" TopLine="139"/> <Caret Line="149" Column="69" TopLine="139"/>
</Position12> </Position12>
<Position13>
<Filename Value="uCookieVisitor.pas"/>
<Caret Line="150" Column="58" TopLine="139"/>
</Position13>
<Position14>
<Filename Value="uCookieVisitor.pas"/>
<Caret Line="155" Column="58" TopLine="144"/>
</Position14>
</JumpHistory> </JumpHistory>
<RunParams> <RunParams>
<FormatVersion Value="2"/> <FormatVersion Value="2"/>

View File

@ -15,7 +15,7 @@ object CookieVisitorFrm: TCookieVisitorFrm
OnDestroy = FormDestroy OnDestroy = FormDestroy
OnShow = FormShow OnShow = FormShow
Position = poScreenCenter Position = poScreenCenter
LCLVersion = '2.0.2.0' LCLVersion = '2.0.4.0'
object AddressBarPnl: TPanel object AddressBarPnl: TPanel
Left = 0 Left = 0
Height = 21 Height = 21
@ -75,4 +75,9 @@ object CookieVisitorFrm: TCookieVisitorFrm
left = 32 left = 32
top = 280 top = 280
end end
object CEFSentinel1: TCEFSentinel
OnClose = CEFSentinel1Close
left = 32
top = 352
end
end end

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants, uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFCookieManager, uCEFCookieVisitor, uCEFWinControl; uCEFCookieManager, uCEFCookieVisitor, uCEFWinControl, uCEFSentinel;
const const
MINIBROWSER_SHOWCOOKIES = WM_APP + $101; MINIBROWSER_SHOWCOOKIES = WM_APP + $101;
@ -61,13 +61,18 @@ const
MINIBROWSER_CONTEXTMENU_SETCOOKIE = MENU_ID_USER_FIRST + 3; MINIBROWSER_CONTEXTMENU_SETCOOKIE = MENU_ID_USER_FIRST + 3;
type type
{ TCookieVisitorFrm }
TCookieVisitorFrm = class(TForm) TCookieVisitorFrm = class(TForm)
AddressBarPnl: TPanel; AddressBarPnl: TPanel;
CEFSentinel1: TCEFSentinel;
Edit1: TEdit; Edit1: TEdit;
GoBtn: TButton; GoBtn: TButton;
CEFWindowParent1: TCEFWindowParent; CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium; Chromium1: TChromium;
Timer1: TTimer; Timer1: TTimer;
procedure CEFSentinel1Close(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
@ -141,12 +146,14 @@ uses
// ================= // =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. // 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. // 3. TChromium.OnBeforeClose calls TCEFSentinel.Start, which will trigger TCEFSentinel.OnClose when the renderer processes are closed.
// 4. TCEFSentinel.OnClose sets FCanClose := True and sends WM_CLOSE to the form.
procedure CreateGlobalCEFApp; procedure CreateGlobalCEFApp;
begin begin
GlobalCEFApp := TCefApplication.Create; GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors'; //GlobalCEFApp.LogFile := 'cef.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end; end;
// This function is called in the IO thread. // This function is called in the IO thread.
@ -233,12 +240,17 @@ begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0); PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
end; end;
procedure TCookieVisitorFrm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); procedure TCookieVisitorFrm.CEFSentinel1Close(Sender: TObject);
begin begin
FCanClose := True; FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0); PostMessage(Handle, WM_CLOSE, 0, 0);
end; end;
procedure TCookieVisitorFrm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
begin
CEFSentinel1.Start;
end;
procedure TCookieVisitorFrm.Chromium1BeforeContextMenu(Sender: TObject; procedure TCookieVisitorFrm.Chromium1BeforeContextMenu(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame; const browser: ICefBrowser; const frame: ICefFrame;
const params: ICefContextMenuParams; const model: ICefMenuModel); const params: ICefContextMenuParams; const model: ICefMenuModel);

View File

@ -8,7 +8,7 @@
<Unit0> <Unit0>
<Filename Value="CRBrowser.lpr"/> <Filename Value="CRBrowser.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<TopLine Value="40"/> <TopLine Value="36"/>
<CursorPos X="61" Y="62"/> <CursorPos X="61" Y="62"/>
<UsageCount Value="20"/> <UsageCount Value="20"/>
<Loaded Value="True"/> <Loaded Value="True"/>
@ -21,9 +21,9 @@
<HasResources Value="True"/> <HasResources Value="True"/>
<ResourceBaseClass Value="Form"/> <ResourceBaseClass Value="Form"/>
<IsVisibleTab Value="True"/> <IsVisibleTab Value="True"/>
<EditorIndex Value="1"/> <EditorIndex Value="2"/>
<TopLine Value="100"/> <TopLine Value="88"/>
<CursorPos X="66" Y="115"/> <CursorPos X="82" Y="113"/>
<UsageCount Value="20"/> <UsageCount Value="20"/>
<Loaded Value="True"/> <Loaded Value="True"/>
<LoadedDesigner Value="True"/> <LoadedDesigner Value="True"/>
@ -32,11 +32,11 @@
<Unit2> <Unit2>
<Filename Value="uCustomResourceHandler.pas"/> <Filename Value="uCustomResourceHandler.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/> <EditorIndex Value="1"/>
<WindowIndex Value="-1"/> <TopLine Value="92"/>
<TopLine Value="-1"/> <CursorPos X="35" Y="134"/>
<CursorPos X="-1" Y="-1"/>
<UsageCount Value="20"/> <UsageCount Value="20"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/> <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit2> </Unit2>
<Unit3> <Unit3>
@ -56,22 +56,20 @@
</Unit4> </Unit4>
<Unit5> <Unit5>
<Filename Value="..\..\..\source\uCEFChromium.pas"/> <Filename Value="..\..\..\source\uCEFChromium.pas"/>
<EditorIndex Value="2"/> <EditorIndex Value="-1"/>
<TopLine Value="750"/> <TopLine Value="750"/>
<CursorPos X="92" Y="760"/> <CursorPos X="92" Y="760"/>
<UsageCount Value="10"/> <UsageCount Value="10"/>
<Loaded Value="True"/>
</Unit5> </Unit5>
<Unit6> <Unit6>
<Filename Value="..\..\..\source\uCEFChromiumEvents.pas"/> <Filename Value="..\..\..\source\uCEFChromiumEvents.pas"/>
<EditorIndex Value="3"/> <EditorIndex Value="-1"/>
<TopLine Value="114"/> <TopLine Value="114"/>
<CursorPos X="3" Y="125"/> <CursorPos X="3" Y="125"/>
<UsageCount Value="10"/> <UsageCount Value="10"/>
<Loaded Value="True"/>
</Unit6> </Unit6>
</Units> </Units>
<JumpHistory Count="14" HistoryIndex="13"> <JumpHistory Count="16" HistoryIndex="15">
<Position1> <Position1>
<Filename Value="uMainForm.pas"/> <Filename Value="uMainForm.pas"/>
</Position1> </Position1>
@ -108,25 +106,33 @@
<Caret Line="136" Column="59" TopLine="124"/> <Caret Line="136" Column="59" TopLine="124"/>
</Position9> </Position9>
<Position10> <Position10>
<Filename Value="..\..\..\source\uCEFChromium.pas"/> <Filename Value="uMainForm.pas"/>
<Caret Line="760" Column="16" TopLine="750"/> <Caret Line="137" Column="84" TopLine="124"/>
</Position10> </Position10>
<Position11> <Position11>
<Filename Value="uMainForm.pas"/> <Filename Value="uMainForm.pas"/>
<Caret Line="137" Column="84" TopLine="124"/> <Caret Line="87" Column="145" TopLine="76"/>
</Position11> </Position11>
<Position12> <Position12>
<Filename Value="uMainForm.pas"/> <Filename Value="uMainForm.pas"/>
<Caret Line="87" Column="145" TopLine="76"/> <Caret Line="117" Column="69" TopLine="109"/>
</Position12> </Position12>
<Position13> <Position13>
<Filename Value="uMainForm.pas"/> <Filename Value="uMainForm.pas"/>
<Caret Line="117" Column="69" TopLine="109"/> <Caret Line="73" Column="30" TopLine="59"/>
</Position13> </Position13>
<Position14> <Position14>
<Filename Value="uMainForm.pas"/> <Filename Value="CRBrowser.lpr"/>
<Caret Line="73" Column="30" TopLine="59"/> <Caret Line="62" Column="61" TopLine="36"/>
</Position14> </Position14>
<Position15>
<Filename Value="uMainForm.pas"/>
<Caret Line="122" Column="44" TopLine="100"/>
</Position15>
<Position16>
<Filename Value="uMainForm.pas"/>
<Caret Line="124" Column="44" TopLine="102"/>
</Position16>
</JumpHistory> </JumpHistory>
<RunParams> <RunParams>
<FormatVersion Value="2"/> <FormatVersion Value="2"/>

Some files were not shown because too many files have changed in this diff Show More