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 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 :
* [32 bits](http://opensource.spotify.com/cefbuilds/cef_binary_76.1.13%2Bgf19c584%2Bchromium-76.0.3809.132_windows32.tar.bz2)
* [64 bits](http://opensource.spotify.com/cefbuilds/cef_binary_76.1.13%2Bgf19c584%2Bchromium-76.0.3809.132_windows64.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_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.
@ -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)
* 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
If you find this project useful, please consider making a donation.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFCookieManager, uCEFCookieVisitor, uCEFWinControl;
uCEFCookieManager, uCEFCookieVisitor, uCEFWinControl, uCEFSentinel;
const
MINIBROWSER_SHOWCOOKIES = WM_APP + $101;
@ -68,6 +68,7 @@ type
CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium;
Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject);
@ -96,6 +97,7 @@ type
var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
private
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.
// 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;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
//GlobalCEFApp.LogFile := 'cef.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end;
@ -230,6 +232,12 @@ begin
Chromium1.LoadURL(Edit1.Text);
end;
procedure TCookieVisitorFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TCookieVisitorFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -237,8 +245,7 @@ end;
procedure TCookieVisitorFrm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
procedure TCookieVisitorFrm.Chromium1BeforeContextMenu(Sender: TObject;

View File

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

View File

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

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFChromiumWindow, uCEFInterfaces, uCustomResourceHandler,
uCEFConstants, uCEFTypes, uCEFWinControl;
uCEFConstants, uCEFTypes, uCEFWinControl, uCEFSentinel;
type
TMainForm = class(TForm)
@ -59,17 +59,18 @@ type
Edit1: TEdit;
Button1: TButton;
Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormCreate(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure ChromiumWindow1Close(Sender: TObject);
procedure ChromiumWindow1BeforeClose(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
private
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.
// 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;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
//GlobalCEFApp.LogFile := 'cef.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end;
@ -123,11 +124,6 @@ begin
ChromiumWindow1.LoadURL(Edit1.Text);
end;
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FHandler := nil;
end;
procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
CanClose := FCanClose;
@ -136,6 +132,7 @@ begin
begin
FClosing := True;
Visible := False;
FHandler := nil;
ChromiumWindow1.CloseBrowser(True);
end;
end;
@ -163,9 +160,9 @@ end;
procedure TMainForm.FormShow(Sender: TObject);
begin
ChromiumWindow1.OnAfterCreated := Chromium_OnAfterCreated;
ChromiumWindow1.ChromiumBrowser.OnGetResourceHandler := Chromium_OnGetResourceHandler;
ChromiumWindow1.ChromiumBrowser.OnBeforePopup := Chromium_OnBeforePopup;
ChromiumWindow1.OnAfterCreated := Chromium_OnAfterCreated;
ChromiumWindow1.ChromiumBrowser.OnGetResourceHandler := Chromium_OnGetResourceHandler;
ChromiumWindow1.ChromiumBrowser.OnBeforePopup := Chromium_OnBeforePopup;
// GlobalCEFApp.GlobalContextInitialized has to be TRUE before creating any browser
// If it's not initialized yet, we use a simple timer to create the browser later.
@ -179,20 +176,21 @@ begin
Timer1.Enabled := True;
end;
procedure TMainForm.ChromiumWindow1BeforeClose(Sender: TObject);
procedure TMainForm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TMainForm.ChromiumWindow1BeforeClose(Sender: TObject);
begin
CEFSentinel1.Start;
end;
procedure TMainForm.ChromiumWindow1Close(Sender: TObject);
begin
// DestroyChildWindow will destroy the child window created by CEF at the top of the Z order.
if not(ChromiumWindow1.DestroyChildWindow) then
begin
FCanClose := True;
Close;
end;
if not(ChromiumWindow1.DestroyChildWindow) then CEFSentinel1.Start;
end;
procedure TMainForm.Chromium_OnAfterCreated(Sender: TObject);

View File

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

View File

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

View File

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

View File

@ -51,7 +51,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Types, ComCtrls, ClipBrd,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFWinControl;
uCEFWinControl, uCEFSentinel;
const
MINIBROWSER_VISITDOM_PARTIAL = WM_APP + $101;
@ -81,6 +81,7 @@ type
Panel1: TPanel;
GoBtn: TButton;
VisitDOMBtn: TButton;
CEFSentinel1: TCEFSentinel;
procedure GoBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject;
@ -111,6 +112,7 @@ type
var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
private
{ Private declarations }
protected
@ -165,7 +167,8 @@ uses
// =================
// 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 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);
var
@ -226,7 +229,7 @@ end;
procedure DOMVisitor_OnDocAvailable(const browser: ICefBrowser; const frame: ICefFrame; const document: ICefDomDocument);
var
msg: ICefProcessMessage;
TempMessage : ICefProcessMessage;
begin
// This function is called from a different process.
// document is only valid inside this function.
@ -247,21 +250,33 @@ begin
// Sending back some custom results to the browser process
// Notice that the DOMVISITOR_MSGNAME_PARTIAL message name needs to be recognized in
// Chromium1ProcessMessageReceived
msg := TCefProcessMessageRef.New(DOMVISITOR_MSGNAME_PARTIAL);
msg.ArgumentList.SetString(0, 'document.Title : ' + document.Title);
frame.SendProcessMessage(PID_BROWSER, msg);
try
TempMessage := TCefProcessMessageRef.New(DOMVISITOR_MSGNAME_PARTIAL);
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;
procedure DOMVisitor_OnDocAvailableFullMarkup(const browser: ICefBrowser; const frame: ICefFrame; const document: ICefDomDocument);
var
msg: ICefProcessMessage;
TempMessage : ICefProcessMessage;
begin
// Sending back some custom results to the browser process
// Notice that the DOMVISITOR_MSGNAME_FULL message name needs to be recognized in
// Chromium1ProcessMessageReceived
msg := TCefProcessMessageRef.New(DOMVISITOR_MSGNAME_FULL);
msg.ArgumentList.SetString(0, document.Body.AsMarkup);
frame.SendProcessMessage(PID_BROWSER, msg);
try
TempMessage := TCefProcessMessageRef.New(DOMVISITOR_MSGNAME_FULL);
TempMessage.ArgumentList.SetString(0, document.Body.AsMarkup);
if (frame <> nil) and frame.IsValid then
frame.SendProcessMessage(PID_BROWSER, TempMessage);
finally
TempMessage := nil;
end;
end;
procedure DOMVisitor_GetFrameIDs(const browser: ICefBrowser; const frame : ICefFrame);
@ -285,9 +300,15 @@ begin
inc(i);
end;
TempMsg := TCefProcessMessageRef.New(FRAMEIDS_MSGNAME);
TempMsg.ArgumentList.SetString(0, TempString);
frame.SendProcessMessage(PID_BROWSER, TempMsg);
try
TempMsg := TCefProcessMessageRef.New(FRAMEIDS_MSGNAME);
TempMsg.ArgumentList.SetString(0, TempString);
if (frame <> nil) and frame.IsValid then
frame.SendProcessMessage(PID_BROWSER, TempMsg);
finally
TempMsg := nil;
end;
end;
end;
@ -297,7 +318,6 @@ procedure GlobalCEFApp_OnProcessMessageReceived(const browser : ICefBrowse
const message : ICefProcessMessage;
var aHandled : boolean);
var
TempFrame : ICefFrame;
TempVisitor : TCefFastDomVisitor2;
begin
aHandled := False;
@ -306,12 +326,10 @@ begin
begin
if (message.name = RETRIEVEDOM_MSGNAME_PARTIAL) then
begin
TempFrame := browser.MainFrame;
if (TempFrame <> nil) then
if (frame <> nil) and frame.IsValid then
begin
TempVisitor := TCefFastDomVisitor2.Create(browser, TempFrame, DOMVisitor_OnDocAvailable);
TempFrame.VisitDom(TempVisitor);
TempVisitor := TCefFastDomVisitor2.Create(browser, frame, DOMVisitor_OnDocAvailable);
frame.VisitDom(TempVisitor);
end;
aHandled := True;
@ -319,12 +337,10 @@ begin
else
if (message.name = RETRIEVEDOM_MSGNAME_FULL) then
begin
TempFrame := browser.MainFrame;
if (TempFrame <> nil) then
if (frame <> nil) and frame.IsValid then
begin
TempVisitor := TCefFastDomVisitor2.Create(browser, TempFrame, DOMVisitor_OnDocAvailableFullMarkup);
TempFrame.VisitDom(TempVisitor);
TempVisitor := TCefFastDomVisitor2.Create(browser, frame, DOMVisitor_OnDocAvailableFullMarkup);
frame.VisitDom(TempVisitor);
end;
aHandled := True;
@ -343,7 +359,6 @@ begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.RemoteDebuggingPort := 9000;
GlobalCEFApp.OnProcessMessageReceived := GlobalCEFApp_OnProcessMessageReceived;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
// 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.
@ -352,6 +367,12 @@ begin
GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO;
end;
procedure TDOMVisitorFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TDOMVisitorFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -360,8 +381,7 @@ end;
procedure TDOMVisitorFrm.Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
procedure TDOMVisitorFrm.Chromium1BeforeContextMenu(Sender: TObject;

View File

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

View File

@ -52,7 +52,7 @@ uses
ImageList, ImgList,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes,
uCEFWinControl;
uCEFWinControl, uCEFSentinel;
type
TForm1 = class(TForm)
@ -91,6 +91,7 @@ type
RemoveFormatBtn: TToolButton;
OutdentBtn: TToolButton;
Separator7: TToolButton;
CEFSentinel1: TCEFSentinel;
procedure Timer1Timer(Sender: TObject);
@ -124,6 +125,7 @@ type
procedure FillColorBtnClick(Sender: TObject);
procedure RemoveFormatBtnClick(Sender: TObject);
procedure OutdentBtnClick(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
protected
// 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.
// 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;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
GlobalCEFApp := TCefApplication.Create;
//GlobalCEFApp.LogFile := 'cef.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end;
procedure TForm1.FillColorBtnClick(Sender: TObject);
@ -225,6 +229,12 @@ begin
if not(Chromium1.CreateBrowser(CEFWindowParent1)) then Timer1.Enabled := True;
end;
procedure TForm1.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TForm1.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin
// 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;
const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
procedure TForm1.Chromium1Close(Sender: TObject;
@ -249,7 +258,7 @@ procedure TForm1.Chromium1LoadEnd(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame;
httpStatusCode: Integer);
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
EnableDesignMode;

View File

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

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFTypes, uCEFConstants, uCEFInterfaces, uCEFWorkScheduler,
uCEFWinControl;
uCEFWinControl, uCEFSentinel;
type
TExternalPumpBrowserFrm = class(TForm)
@ -60,6 +60,7 @@ type
CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium;
URLCbx: TComboBox;
CEFSentinel1: TCEFSentinel;
procedure GoBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject);
@ -79,6 +80,7 @@ type
var client: ICefClient; var settings: TCefBrowserSettings;
var extra_info: ICefDictionaryValue;
var noJavascriptAccess: Boolean; var Result: Boolean);
procedure CEFSentinel1Close(Sender: TObject);
private
FCanClose : boolean;
@ -110,6 +112,13 @@ uses
// 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.
// 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);
begin
if (GlobalCEFWorkScheduler <> nil) then GlobalCEFWorkScheduler.ScheduleMessagePumpWork(aDelayMS);
@ -128,7 +137,6 @@ begin
GlobalCEFApp.ExternalMessagePump := True;
GlobalCEFApp.MultiThreadedMessageLoop := False;
GlobalCEFApp.OnScheduleMessagePumpWork := GlobalCEFApp_OnScheduleMessagePumpWork;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end;
procedure TExternalPumpBrowserFrm.FormCreate(Sender: TObject);
@ -143,9 +151,8 @@ begin
if not(FClosing) then
begin
FClosing := True;
Visible := False;
AddressPnl.Enabled := False;
FClosing := True;
Visible := False;
Chromium1.CloseBrowser(True);
end;
end;
@ -157,6 +164,12 @@ begin
if not(Chromium1.CreateBrowser(CEFWindowParent1, '')) then Timer1.Enabled := True;
end;
procedure TExternalPumpBrowserFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TExternalPumpBrowserFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -164,8 +177,7 @@ end;
procedure TExternalPumpBrowserFrm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
procedure TExternalPumpBrowserFrm.Chromium1BeforePopup(Sender: TObject;

View File

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

View File

@ -49,13 +49,14 @@ uses
Controls, Forms, Dialogs,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFTypes, uCEFConstants,
Vcl.ExtCtrls, uCEFWinControl;
Vcl.ExtCtrls, uCEFWinControl, uCEFSentinel;
type
TMainForm = class(TForm)
CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium;
Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure Chromium1PreKeyEvent(Sender: TObject;
const browser: ICefBrowser; const event: PCefKeyEvent; osEvent: PMsg;
out isKeyboardShortcut, Result: Boolean);
@ -80,6 +81,7 @@ type
const browser: ICefBrowser);
procedure Chromium1Close(Sender: TObject; const browser: ICefBrowser;
var aAction : TCefCloseBrowserAction);
procedure CEFSentinel1Close(Sender: TObject);
private
{ Private declarations }
protected
@ -112,10 +114,16 @@ implementation
uses
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;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
//GlobalCEFApp.LogFile := 'cef.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end;
@ -158,6 +166,12 @@ begin
if (TempKeyMsg.CharCode = VK_ESCAPE) then aHandled := True;
end;
procedure TMainForm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TMainForm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -165,8 +179,7 @@ end;
procedure TMainForm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
procedure TMainForm.Chromium1BeforePopup(Sender: TObject;

View File

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

View File

@ -44,13 +44,13 @@ interface
uses
{$IFDEF DELPHI16_UP}
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}
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, SyncObjs,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFChromiumWindow, uCEFInterfaces, uCEFTypes, uCEFConstants,
uCEFWinControl;
uCEFWinControl, uCEFSentinel;
const
CEFBROWSER_SHOWJSDIALOG = WM_APP + $101;
@ -62,6 +62,7 @@ type
AddressEdt: TEdit;
GoBtn: TButton;
Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure GoBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure ChromiumWindow1AfterCreated(Sender: TObject);
@ -71,6 +72,7 @@ type
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure ChromiumWindow1Close(Sender: TObject);
procedure ChromiumWindow1BeforeClose(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
protected
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.
// 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;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
//GlobalCEFApp.LogFile := 'cef.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end;
@ -165,6 +167,12 @@ begin
if not(ChromiumWindow1.CreateBrowser) then Timer1.Enabled := True;
end;
procedure TJSDialogBrowserFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSDialogBrowserFrm.ChromiumWindow1AfterCreated(Sender: TObject);
begin
Caption := 'JS Dialog Browser';
@ -249,18 +257,13 @@ end;
procedure TJSDialogBrowserFrm.ChromiumWindow1BeforeClose(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
procedure TJSDialogBrowserFrm.ChromiumWindow1Close(Sender: TObject);
begin
// DestroyChildWindow will destroy the child window created by CEF at the top of the Z order.
if not(ChromiumWindow1.DestroyChildWindow) then
begin
FCanClose := True;
Close;
end;
if not(ChromiumWindow1.DestroyChildWindow) then CEFSentinel1.Start;
end;
procedure TJSDialogBrowserFrm.Chromium_OnBeforePopup(Sender: TObject;

View File

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

View File

@ -51,7 +51,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Types, ComCtrls, ClipBrd, EncdDecd,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFWinControl;
uCEFWinControl, uCEFSentinel;
const
MINIBROWSER_SHOWTEXTVIEWER = WM_APP + $101;
@ -74,6 +74,7 @@ type
GoBtn: TButton;
AddressEdt: TEdit;
Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
procedure GoBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject);
@ -102,6 +103,7 @@ type
var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
private
{ Private declarations }
@ -178,8 +180,14 @@ uses
// =================
// 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 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);
begin
@ -189,8 +197,7 @@ end;
procedure TJSEvalFrm.Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
procedure TJSEvalFrm.Chromium1BeforeContextMenu(Sender : TObject;
@ -435,7 +442,8 @@ begin
end;
end;
pFrame.SendProcessMessage(PID_BROWSER, pAnswer);
if (pFrame <> nil) and pFrame.IsValid then
pFrame.SendProcessMessage(PID_BROWSER, pAnswer);
end;
procedure ParseBinaryValue(const pBrowser : ICefBrowser; const pFrame : ICefFrame; const aBinaryValue : ICefBinaryValue);
@ -464,7 +472,7 @@ begin
TempString := 'Image size : ' + inttostr(TempSize) + #13 + #10 +
'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);
end;
end;
@ -497,9 +505,9 @@ begin
begin
TempScript := pMessage.ArgumentList.GetString(0);
if (length(TempScript) > 0) then
if (length(TempScript) > 0) and (pFrame <> nil) and pFrame.IsValid then
begin
pV8Context := pBrowser.MainFrame.GetV8Context;
pV8Context := pFrame.GetV8Context;
if pV8Context.Enter then
begin
@ -524,7 +532,6 @@ procedure CreateGlobalCEFApp;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnProcessMessageReceived := RenderProcessHandler_OnProcessMessageReceivedEvent;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end;
procedure TJSEvalFrm.Chromium1ProcessMessageReceived( Sender : TObject;

View File

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

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes,
uCEFConstants, uCEFv8Value, uCEFWinControl;
uCEFConstants, uCEFv8Value, uCEFWinControl, uCEFSentinel;
const
JSDEMO_CONTEXTMENU_EXECFUNCTION = MENU_ID_USER_FIRST + 1;
@ -65,6 +65,7 @@ type
CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium;
Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
@ -91,6 +92,7 @@ type
var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected
// Variables to control when can we destroy the form safely
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.
// 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
uCEFProcessMessage, uMyV8Handler;
@ -174,7 +177,6 @@ begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnContextCreated := GlobalCEFApp_OnContextCreated;
GlobalCEFApp.OnProcessMessageReceived := GlobalCEFApp_OnProcessMessageReceived;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end;
procedure TJSExecutingFunctionsFrm.GoBtnClick(Sender: TObject);
@ -182,6 +184,12 @@ begin
Chromium1.LoadURL(Edit1.Text);
end;
procedure TJSExecutingFunctionsFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSExecutingFunctionsFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -190,8 +198,7 @@ end;
procedure TJSExecutingFunctionsFrm.Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
procedure TJSExecutingFunctionsFrm.Chromium1BeforeContextMenu(

View File

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

View File

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

View File

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

View File

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

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFWinControl;
uCEFWinControl, uCEFSentinel;
type
TJSExtensionWithFunctionFrm = class(TForm)
@ -61,6 +61,7 @@ type
Chromium1: TChromium;
Timer1: TTimer;
StatusBar1: TStatusBar;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
@ -82,6 +83,7 @@ type
var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected
// Variables to control when can we destroy the form safely
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.
// 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
{$ELSE}class procedure TJSSimpleExtensionFrm.{$ENDIF}GlobalCEFApp_OnWebKitInitializedEvent;
@ -152,7 +155,6 @@ begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnWebKitInitialized := {$IFNDEF DELPHI12_UP}TJSSimpleExtensionFrm.{$ENDIF}
GlobalCEFApp_OnWebKitInitializedEvent;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end;
procedure TJSExtensionWithFunctionFrm.GoBtnClick(Sender: TObject);
@ -160,6 +162,12 @@ begin
Chromium1.LoadURL(Edit1.Text);
end;
procedure TJSExtensionWithFunctionFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSExtensionWithFunctionFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -168,8 +176,7 @@ end;
procedure TJSExtensionWithFunctionFrm.Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
procedure TJSExtensionWithFunctionFrm.Chromium1BeforePopup(Sender: TObject;

View File

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

View File

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

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFWinControl;
uCEFWinControl, uCEFSentinel;
type
TJSExtensionWithObjectParameterFrm = class(TForm)
@ -60,6 +60,7 @@ type
CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium;
Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
@ -78,6 +79,7 @@ type
var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected
// Variables to control when can we destroy the form safely
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.
// 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
{$ELSE}class procedure TJSSimpleExtensionFrm.{$ENDIF}GlobalCEFApp_OnWebKitInitializedEvent;
@ -155,7 +158,6 @@ begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnWebKitInitialized := {$IFNDEF DELPHI12_UP}TJSSimpleExtensionFrm.{$ENDIF}
GlobalCEFApp_OnWebKitInitializedEvent;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end;
procedure TJSExtensionWithObjectParameterFrm.GoBtnClick(Sender: TObject);
@ -163,6 +165,13 @@ begin
Chromium1.LoadURL(Edit1.Text);
end;
procedure TJSExtensionWithObjectParameterFrm.CEFSentinel1Close(
Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSExtensionWithObjectParameterFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -171,8 +180,7 @@ end;
procedure TJSExtensionWithObjectParameterFrm.Chromium1BeforeClose(
Sender: TObject; const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
procedure TJSExtensionWithObjectParameterFrm.Chromium1BeforePopup(

View File

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

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFWinControl;
uCEFWinControl, uCEFSentinel;
const
MINIBROWSER_SHOWTEXTVIEWER = WM_APP + $100;
@ -72,6 +72,7 @@ type
CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium;
Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject);
procedure Chromium1BeforeContextMenu(Sender: TObject;
@ -100,6 +101,7 @@ type
var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected
FText : string;
// 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.
// 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;
begin
@ -173,7 +176,6 @@ procedure CreateGlobalCEFApp;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnWebKitInitialized := GlobalCEFApp_OnWebKitInitialized;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
{$IFDEF DEBUG}
GlobalCEFApp.LogFile := 'debug.log';
GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO;
@ -185,6 +187,12 @@ begin
Chromium1.LoadURL(Edit1.Text);
end;
procedure TJSRTTIExtensionFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSRTTIExtensionFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -229,7 +237,7 @@ begin
// Here is the code executed for each custom context menu entry
case commandId of
MINIBROWSER_CONTEXTMENU_SETJSEVENT :
if (browser <> nil) and (browser.MainFrame <> nil) then
if (frame <> nil) and frame.IsValid then
begin
TempJSCode := 'document.body.addEventListener("mouseover", function(evt){'+
'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
')';
browser.MainFrame.ExecuteJavaScript(TempJSCode, 'about:blank', 0);
frame.ExecuteJavaScript(TempJSCode, 'about:blank', 0);
end;
MINIBROWSER_CONTEXTMENU_JSVISITDOM :
if (browser <> nil) and (browser.MainFrame <> nil) then
if (frame <> nil) and frame.IsValid then
begin
// This is the call from JavaScript to the extension with DELPHI code in uTestExtension.pas
TempJSCode := 'var testhtml = document.body.innerHTML; ' +
'myextension.sendresulttobrowser(testhtml, ' + quotedstr(CUSTOMNAME_MESSAGE_NAME) + ');';
browser.MainFrame.ExecuteJavaScript(TempJSCode, 'about:blank', 0);
frame.ExecuteJavaScript(TempJSCode, 'about:blank', 0);
end;
MINIBROWSER_CONTEXTMENU_SHOWDEVTOOLS :
@ -343,8 +351,7 @@ end;
procedure TJSRTTIExtensionFrm.Chromium1BeforeClose(
Sender: TObject; const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
procedure TJSRTTIExtensionFrm.Chromium1Close(

View File

@ -63,24 +63,41 @@ uses
class procedure TTestExtension.mouseover(const data: string);
var
msg: ICefProcessMessage;
TempMessage : ICefProcessMessage;
TempFrame : ICefFrame;
begin
msg := TCefProcessMessageRef.New(MOUSEOVER_MESSAGE_NAME);
msg.ArgumentList.SetString(0, data);
try
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.
// TCefv8ContextRef.Current returns the v8 context for the frame that is currently executing Javascript.
TCefv8ContextRef.Current.Browser.MainFrame.SendProcessMessage(PID_BROWSER, msg);
// 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.
TempFrame := TCefv8ContextRef.Current.Browser.MainFrame;
if (TempFrame <> nil) and TempFrame.IsValid then
TempFrame.SendProcessMessage(PID_BROWSER, TempMessage);
finally
TempMessage := nil;
end;
end;
class procedure TTestExtension.sendresulttobrowser(const msgtext, msgname : string);
var
msg: ICefProcessMessage;
TempMessage : ICefProcessMessage;
TempFrame : ICefFrame;
begin
msg := TCefProcessMessageRef.New(msgname);
msg.ArgumentList.SetString(0, msgtext);
try
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.

View File

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

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFWinControl;
uCEFWinControl, uCEFSentinel;
type
TJSSimpleExtensionFrm = class(TForm)
@ -60,6 +60,7 @@ type
CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium;
Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
@ -78,6 +79,7 @@ type
var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected
// Variables to control when can we destroy the form safely
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.
// 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
{$ELSE}class procedure TJSSimpleExtensionFrm.{$ENDIF}GlobalCEFApp_OnWebKitInitializedEvent;
@ -142,7 +145,6 @@ begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnWebKitInitialized := {$IFNDEF DELPHI12_UP}TJSSimpleExtensionFrm.{$ENDIF}
GlobalCEFApp_OnWebKitInitializedEvent;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end;
procedure TJSSimpleExtensionFrm.GoBtnClick(Sender: TObject);
@ -150,6 +152,12 @@ begin
Chromium1.LoadURL(Edit1.Text);
end;
procedure TJSSimpleExtensionFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSSimpleExtensionFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -221,8 +229,7 @@ end;
procedure TJSSimpleExtensionFrm.Chromium1BeforeClose(
Sender: TObject; const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
procedure TJSSimpleExtensionFrm.Chromium1Close(

View File

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

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes,
uCEFConstants, uCEFv8Value, uCEFWinControl;
uCEFConstants, uCEFv8Value, uCEFWinControl, uCEFSentinel;
type
TJSSimpleWindowBindingFrm = class(TForm)
@ -60,6 +60,7 @@ type
CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium;
Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
@ -78,6 +79,7 @@ type
var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected
// Variables to control when can we destroy the form safely
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.
// 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);
var
@ -130,7 +133,6 @@ procedure CreateGlobalCEFApp;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnContextCreated := GlobalCEFApp_OnContextCreated;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end;
procedure TJSSimpleWindowBindingFrm.GoBtnClick(Sender: TObject);
@ -138,6 +140,12 @@ begin
Chromium1.LoadURL(Edit1.Text);
end;
procedure TJSSimpleWindowBindingFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSSimpleWindowBindingFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -209,8 +217,7 @@ end;
procedure TJSSimpleWindowBindingFrm.Chromium1BeforeClose(
Sender: TObject; const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
procedure TJSSimpleWindowBindingFrm.Chromium1Close(

View File

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

View File

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

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes,
uCEFConstants, uCEFv8Value, uCEFWinControl;
uCEFConstants, uCEFv8Value, uCEFWinControl, uCEFSentinel;
type
TJSSimpleWindowBindingFrm = class(TForm)
@ -60,6 +60,7 @@ type
CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium;
Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
@ -78,6 +79,7 @@ type
var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected
FText : string;
// 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.
// 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;
begin
@ -129,7 +132,6 @@ begin
// 4. Run this demo : JSSimpleWindowBinding
GlobalCEFApp.BrowserSubprocessPath := 'SubProcess.exe';
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
//GlobalCEFApp.LogFile := 'cef.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end;
@ -139,6 +141,12 @@ begin
Chromium1.LoadURL(Edit1.Text);
end;
procedure TJSSimpleWindowBindingFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSSimpleWindowBindingFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -210,8 +218,7 @@ end;
procedure TJSSimpleWindowBindingFrm.Chromium1BeforeClose(
Sender: TObject; const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
procedure TJSSimpleWindowBindingFrm.Chromium1Close(

View File

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

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFWinControl;
uCEFWinControl, uCEFSentinel;
type
TJSWindowBindingWithArrayBufferFrm = class(TForm)
@ -60,6 +60,7 @@ type
CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium;
Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
@ -78,6 +79,7 @@ type
var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected
// Variables to control when can we destroy the form safely
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.
// 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);
begin
@ -155,7 +158,6 @@ procedure CreateGlobalCEFApp;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnContextCreated := GlobalCEFApp_OnContextCreated;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end;
procedure TJSWindowBindingWithArrayBufferFrm.GoBtnClick(Sender: TObject);
@ -163,6 +165,13 @@ begin
Chromium1.LoadURL(Edit1.Text);
end;
procedure TJSWindowBindingWithArrayBufferFrm.CEFSentinel1Close(
Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSWindowBindingWithArrayBufferFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -234,8 +243,7 @@ end;
procedure TJSWindowBindingWithArrayBufferFrm.Chromium1BeforeClose(
Sender: TObject; const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
procedure TJSWindowBindingWithArrayBufferFrm.Chromium1Close(

View File

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

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFWinControl;
uCEFWinControl, uCEFSentinel;
type
TJSWindowBindingWithFunctionFrm = class(TForm)
@ -60,6 +60,7 @@ type
CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium;
Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
@ -78,6 +79,7 @@ type
var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected
// Variables to control when can we destroy the form safely
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.
// 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);
var
@ -135,7 +138,6 @@ procedure CreateGlobalCEFApp;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnContextCreated := GlobalCEFApp_OnContextCreated;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end;
procedure TJSWindowBindingWithFunctionFrm.GoBtnClick(Sender: TObject);
@ -143,6 +145,13 @@ begin
Chromium1.LoadURL(Edit1.Text);
end;
procedure TJSWindowBindingWithFunctionFrm.CEFSentinel1Close(
Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSWindowBindingWithFunctionFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -214,8 +223,7 @@ end;
procedure TJSWindowBindingWithFunctionFrm.Chromium1BeforeClose(
Sender: TObject; const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
procedure TJSWindowBindingWithFunctionFrm.Chromium1Close(

View File

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

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFWinControl;
uCEFWinControl, uCEFSentinel;
type
TJSWindowBindingWithObjectFrm = class(TForm)
@ -60,6 +60,7 @@ type
CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium;
Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject);
procedure GoBtnClick(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
@ -78,6 +79,7 @@ type
var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected
// Variables to control when can we destroy the form safely
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.
// 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);
var
@ -136,7 +139,6 @@ procedure CreateGlobalCEFApp;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnContextCreated := GlobalCEFApp_OnContextCreated;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end;
procedure TJSWindowBindingWithObjectFrm.GoBtnClick(Sender: TObject);
@ -144,6 +146,12 @@ begin
Chromium1.LoadURL(Edit1.Text);
end;
procedure TJSWindowBindingWithObjectFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TJSWindowBindingWithObjectFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -215,8 +223,7 @@ end;
procedure TJSWindowBindingWithObjectFrm.Chromium1BeforeClose(
Sender: TObject; const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
procedure TJSWindowBindingWithObjectFrm.Chromium1Close(

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -51,7 +51,7 @@ uses
Controls, StdCtrls, Dialogs, Buttons, Messages,
ExtCtrls, ComCtrls,
{$ENDIF}
uCEFWorkScheduler;
uCEFWorkScheduler, uCEFSentinel;
const
CEFBROWSER_CREATED = WM_APP + $100;
@ -65,10 +65,12 @@ type
NewBtn: TSpeedButton;
ExitBtn: TSpeedButton;
NewContextChk: TCheckBox;
CEFSentinel1: TCEFSentinel;
procedure FormCreate(Sender: TObject);
procedure NewBtnClick(Sender: TObject);
procedure ExitBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
private
// Variables to control when can we destroy the form safely
FCanClose : boolean; // Set to True when all the child forms are closed
@ -103,7 +105,8 @@ uses
// Destruction steps
// =================
// 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;
begin
@ -129,7 +132,6 @@ begin
GlobalCEFApp.MultiThreadedMessageLoop := False;
GlobalCEFApp.OnScheduleMessagePumpWork := GlobalCEFApp_OnScheduleMessagePumpWork;
GlobalCEFApp.OnContextInitialized := GlobalCEFApp_OnContextInitialized;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end;
procedure TMainForm.CreateMDIChild(const Name: string);
@ -199,11 +201,16 @@ begin
if FClosing and (MDIChildCount = 0) then
begin
ButtonPnl.Enabled := False;
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
end;
procedure TMainForm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TMainForm.CEFInitializedMsg(var aMessage : TMessage);
begin
Caption := 'MDI External Pump Browser';

View File

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

View File

@ -51,7 +51,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Types, ComCtrls, ClipBrd, AppEvnts, ActiveX, ShlObj,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFWinControl;
uCEFWinControl, uCEFSentinel;
const
MINIBROWSER_SHOWDEVTOOLS = WM_APP + $101;
@ -126,6 +126,7 @@ type
Downloadimage1: TMenuItem;
Simulatekeyboardpresses1: TMenuItem;
Flushcookies1: TMenuItem;
CEFSentinel1: TCEFSentinel;
procedure FormShow(Sender: TObject);
procedure BackBtnClick(Sender: TObject);
procedure ForwardBtnClick(Sender: TObject);
@ -226,6 +227,11 @@ type
procedure Simulatekeyboardpresses1Click(Sender: TObject);
procedure Flushcookies1Click(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
FResponse : TStringList;
@ -286,15 +292,16 @@ uses
// =================
// 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 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;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
GlobalCEFApp.LogFile := 'debug.log';
GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO;
GlobalCEFApp.cache := 'cache';
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.LogFile := 'debug.log';
GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO;
GlobalCEFApp.cache := 'cache';
GlobalCEFApp.EnablePrintPreview := True;
//GlobalCEFApp.RemoteDebuggingPort := 19999;
end;
@ -331,6 +338,12 @@ begin
if (length(TempURL) > 0) then Chromium1.ResolveHost(TempURL);
end;
procedure TMiniBrowserFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TMiniBrowserFrm.Chromium1AddressChange(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame; const url: ustring);
begin
@ -348,11 +361,7 @@ end;
procedure TMiniBrowserFrm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
begin
// The main browser is being destroyed
if (Chromium1.BrowserId = 0) then
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
if (Chromium1.BrowserId = 0) then CEFSentinel1.Start;
end;
procedure TMiniBrowserFrm.Chromium1BeforeContextMenu(Sender: TObject;
@ -439,6 +448,22 @@ begin
callback.cont(TempFullPath, False);
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;
const browser: ICefBrowser; const frame: ICefFrame;
const request: ICefRequest; const callback: ICefRequestCallback;
@ -448,7 +473,8 @@ begin
if Chromium1.IsSameBrowser(browser) and
(frame <> nil) and
frame.IsMain then
frame.IsMain and
frame.IsValid then
InspectRequest(request);
end;
@ -520,8 +546,8 @@ begin
end;
MINIBROWSER_CONTEXTMENU_JSWRITEDOC :
if (browser <> nil) and (browser.MainFrame <> nil) then
browser.MainFrame.ExecuteJavaScript(
if (frame <> nil) and frame.IsValid then
frame.ExecuteJavaScript(
'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) + '); ' +
'style.type = ' + chr(39) + 'text/css' + chr(39) + '; ' +
@ -530,8 +556,8 @@ begin
'about:blank', 0);
MINIBROWSER_CONTEXTMENU_JSPRINTDOC :
if (browser <> nil) and (browser.MainFrame <> nil) then
browser.MainFrame.ExecuteJavaScript('window.print();', 'about:blank', 0);
if (frame <> nil) and frame.IsValid then
frame.ExecuteJavaScript('window.print();', 'about:blank', 0);
MINIBROWSER_CONTEXTMENU_UNMUTEAUDIO :
Chromium1.AudioMuted := False;
@ -684,6 +710,8 @@ procedure TMiniBrowserFrm.Chromium1LoadEnd(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame;
httpStatusCode: Integer);
begin
if (frame = nil) or not(frame.IsValid) then exit;
if frame.IsMain then
StatusBar1.Panels[1].Text := 'main frame loaded : ' + quotedstr(frame.name)
else
@ -693,10 +721,17 @@ end;
procedure TMiniBrowserFrm.Chromium1LoadError(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame; errorCode: Integer;
const errorText, failedUrl: ustring);
var
TempString : string;
begin
CefDebugLog('Error code:' + inttostr(errorCode) +
' - Error text :' + quotedstr(errorText) +
' - URL:' + failedUrl, CEF_LOG_SEVERITY_ERROR);
if (errorCode = ERR_ABORTED) then exit;
TempString := '<html><body bgcolor="white">' +
'<h2>Failed to load URL ' + failedUrl +
' with error ' + errorText +
' (' + inttostr(errorCode) + ').</h2></body></html>';
frame.LoadURL(CefGetDataURI(TempString, 'text/html'));
end;
procedure TMiniBrowserFrm.Chromium1LoadingProgressChange(Sender: TObject;
@ -866,7 +901,8 @@ begin
if Chromium1.IsSameBrowser(browser) and
(frame <> nil) and
frame.IsMain then
frame.IsMain and
frame.IsValid then
InspectResponse(response);
end;
@ -1060,9 +1096,9 @@ begin
TempFile.LoadFromFile(OpenDialog1.FileName);
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
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);
end;
@ -1156,8 +1192,11 @@ begin
end;
procedure TMiniBrowserFrm.CopyAllTextMsg(var aMessage : TMessage);
var
TempName : string;
begin
Chromium1.RetrieveText;
TempName := InputBox('Frame name', 'Type the fame name or leave it blank to select the main frame :', '');
Chromium1.RetrieveText(TempName);
end;
procedure TMiniBrowserFrm.CopyFramesIDsMsg(var aMessage : TMessage);

View File

@ -4,7 +4,7 @@ object PreferencesFrm: TPreferencesFrm
BorderIcons = [biSystemMenu]
BorderStyle = bsSingle
Caption = 'Preferences'
ClientHeight = 397
ClientHeight = 388
ClientWidth = 428
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
@ -13,33 +13,20 @@ object PreferencesFrm: TPreferencesFrm
Font.Name = 'Tahoma'
Font.Style = []
FormStyle = fsStayOnTop
Padding.Left = 10
Padding.Top = 10
Padding.Right = 10
Padding.Bottom = 10
OldCreateOrder = False
Position = poScreenCenter
PixelsPerInch = 96
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
Left = 8
Top = 8
Width = 412
Left = 10
Top = 10
Width = 408
Height = 250
Align = alTop
Caption = ' Proxy '
TabOrder = 0
object ProxyTypeLbl: TLabel
@ -186,10 +173,11 @@ object PreferencesFrm: TPreferencesFrm
end
end
object GroupBox2: TGroupBox
Left = 8
Top = 271
Width = 412
Left = 10
Top = 260
Width = 408
Height = 84
Align = alTop
Caption = ' Custom header '
TabOrder = 1
object HeaderNameLbl: TLabel
@ -221,4 +209,37 @@ object PreferencesFrm: TPreferencesFrm
TabOrder = 1
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

View File

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

View File

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

View File

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

View File

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

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, SyncObjs,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes, uChildForm,
Vcl.AppEvnts, uCEFWinControl;
Vcl.AppEvnts, uCEFWinControl, uCEFSentinel;
const
CEF_CREATENEXTCHILD = WM_APP + $A50;
@ -65,6 +65,7 @@ type
Chromium1: TChromium;
CEFWindowParent1: TCEFWindowParent;
AppEvents: TApplicationEvents;
CEFSentinel1: TCEFSentinel;
procedure GoBtnClick(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 Chromium1Close(Sender: TObject; const browser: ICefBrowser; var aAction: TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
protected
FChildForm : TChildForm;
@ -142,14 +144,14 @@ uses
// 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.
// 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;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.WindowlessRenderingEnabled := True;
GlobalCEFApp.EnableHighDPISupport := True;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
//GlobalCEFApp.LogFile := 'debug.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO;
end;
@ -244,8 +246,7 @@ end;
procedure TMainForm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
function TMainForm.CreateClientHandler(var windowInfo : TCefWindowInfo;
@ -353,6 +354,12 @@ begin
end;
end;
procedure TMainForm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TMainForm.ChildDestroyedMsg(var aMessage : TMessage);
begin
if FClosingChildren and (PopupChildCount = 0) then Close;

View File

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

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, SyncObjs,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes, uChildForm,
Vcl.AppEvnts, uCEFWinControl;
Vcl.AppEvnts, uCEFWinControl, uCEFSentinel;
const
CEF_CREATENEXTCHILD = WM_APP + $A50;
@ -64,6 +64,7 @@ type
Timer1: TTimer;
Chromium1: TChromium;
CEFWindowParent1: TCEFWindowParent;
CEFSentinel1: TCEFSentinel;
procedure GoBtnClick(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 Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
procedure Chromium1Close(Sender: TObject; const browser: ICefBrowser; var aAction: TCefCloseBrowserAction);
procedure CEFSentinel1Close(Sender: TObject);
protected
FChildForm : TChildForm;
@ -140,13 +142,13 @@ uses
// 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.
// 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;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.EnableHighDPISupport := True;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
//GlobalCEFApp.LogFile := 'cef.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end;
@ -209,8 +211,7 @@ end;
procedure TMainForm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
procedure TMainForm.Chromium1BeforePopup(Sender : TObject;
@ -334,6 +335,12 @@ begin
end;
end;
procedure TMainForm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TMainForm.ChildDestroyedMsg(var aMessage : TMessage);
begin
if FClosingChildren and (PopupChildCount = 0) then Close;

View File

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

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, SyncObjs,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes,
uCEFWinControl;
uCEFWinControl, uCEFSentinel;
const
CEF_SHOWDATA = WM_APP + $B00;
@ -65,6 +65,7 @@ type
Memo1: TMemo;
AddressCb: TComboBox;
Splitter1: TSplitter;
CEFSentinel1: TCEFSentinel;
procedure GoBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
@ -88,6 +89,7 @@ type
const browser: ICefBrowser; const frame: ICefFrame;
const request: ICefRequest; const callback: ICefRequestCallback;
out Result: TCefReturnValue);
procedure CEFSentinel1Close(Sender: TObject);
protected
// Variables to control when can we destroy the form safely
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)
// to add the information to the TMemo safely in the main thread.
// 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 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;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
//GlobalCEFApp.LogFile := 'cef.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end;
@ -256,6 +257,7 @@ var
i : integer;
begin
TempArray := nil;
try
try
TempPostData := request.PostData;
@ -357,7 +359,9 @@ procedure TForm1.Chromium1BeforeResourceLoad(Sender: TObject;
begin
// This event is called before a resource request is loaded.
// The request object may be modified.
HandleRequest(request, frame.IsMain);
if (frame <> nil) and frame.IsValid then
HandleRequest(request, frame.IsMain);
Result := RV_CONTINUE;
end;
@ -379,6 +383,11 @@ begin
end;
procedure TForm1.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
begin
CEFSentinel1.Start;
end;
procedure TForm1.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);

View File

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

View File

@ -51,7 +51,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, SyncObjs, ComCtrls, pngimage,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes, uCEFResponseFilter,
uCEFWinControl;
uCEFWinControl, uCEFSentinel;
const
STREAM_COPY_COMPLETE = WM_APP + $B00;
@ -72,6 +72,7 @@ type
StatusBar1: TStatusBar;
CopyScriptBtn: TRadioButton;
ReplaceLogoBtn: TRadioButton;
CEFSentinel1: TCEFSentinel;
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);
@ -90,6 +91,7 @@ type
procedure GoBtnClick(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
protected
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
// 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.
// TCustomResponseFilter.OnFilter event might be called multiple times
// when the resource is too big. In that case the resource will be split into
@ -192,7 +195,6 @@ uses
procedure CreateGlobalCEFApp;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
GlobalCEFApp.LogFile := 'cef.log';
GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end;
@ -404,8 +406,7 @@ end;
procedure TResponseFilterBrowserFrm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
procedure TResponseFilterBrowserFrm.Chromium1BeforePopup( Sender : TObject;
@ -507,7 +508,7 @@ const
var
TempPath : string;
begin
if frame.IsMain then
if (frame <> nil) and frame.IsValid and frame.IsMain then
try
try
FStreamCS.Acquire;
@ -542,6 +543,12 @@ begin
{$ENDIF}
end;
procedure TResponseFilterBrowserFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TResponseFilterBrowserFrm.CheckResponseHeaders(const response : ICefResponse);
var
TempContentLength, TempContentEncoding : string;

View File

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

View File

@ -51,7 +51,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Types, ComCtrls, ClipBrd,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFSchemeRegistrar,
uCEFTypes, uCEFConstants, uCEFWinControl;
uCEFTypes, uCEFConstants, uCEFWinControl, uCEFSentinel;
const
MINIBROWSER_CONTEXTMENU_REGSCHEME = MENU_ID_USER_FIRST + 1;
@ -65,6 +65,7 @@ type
Chromium1: TChromium;
AddressCbx: TComboBox;
Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure Chromium1AfterCreated(Sender: TObject;
const browser: ICefBrowser);
procedure Chromium1BeforeContextMenu(Sender: TObject;
@ -91,6 +92,7 @@ type
var aAction : TCefCloseBrowserAction);
procedure Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser);
procedure CEFSentinel1Close(Sender: TObject);
private
{ Private declarations }
protected
@ -135,7 +137,8 @@ uses
// =================
// 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 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);
begin
@ -146,12 +149,17 @@ procedure CreateGlobalCEFApp;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnRegCustomSchemes := GlobalCEFApp_OnRegCustomSchemes;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
// GlobalCEFApp.LogFile := 'debug.log';
// GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end;
procedure TSchemeRegistrationBrowserFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TSchemeRegistrationBrowserFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
@ -160,8 +168,7 @@ end;
procedure TSchemeRegistrationBrowserFrm.Chromium1BeforeClose(
Sender: TObject; const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
procedure TSchemeRegistrationBrowserFrm.Chromium1BeforeContextMenu(

View File

@ -68,9 +68,6 @@ begin
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
// with the Application initialization inside the begin..end.
// Read this https://www.briskbard.com/index.php?lang=en&pageid=cef

View File

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

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFChromiumWindow, uCEFTypes, uCEFInterfaces,
uCEFWinControl;
uCEFWinControl, uCEFSentinel;
type
TForm1 = class(TForm)
@ -59,6 +59,7 @@ type
AddressEdt: TEdit;
GoBtn: TButton;
Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure GoBtnClick(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
@ -70,6 +71,7 @@ type
procedure ChromiumWindow1AfterCreated(Sender: TObject);
procedure ChromiumWindow1Close(Sender: TObject);
procedure ChromiumWindow1BeforeClose(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
private
// 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.
// 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);
@ -151,20 +154,21 @@ begin
if not(ChromiumWindow1.CreateBrowser) then Timer1.Enabled := True;
end;
procedure TForm1.ChromiumWindow1BeforeClose(Sender: TObject);
procedure TForm1.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TForm1.ChromiumWindow1BeforeClose(Sender: TObject);
begin
CEFSentinel1.Start;
end;
procedure TForm1.ChromiumWindow1Close(Sender: TObject);
begin
// DestroyChildWindow will destroy the child window created by CEF at the top of the Z order.
if not(ChromiumWindow1.DestroyChildWindow) then
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
if not(ChromiumWindow1.DestroyChildWindow) then CEFSentinel1.Start;
end;
procedure TForm1.Chromium_OnBeforePopup( Sender : TObject;

View File

@ -70,9 +70,6 @@ begin
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
// with the Application initialization inside the begin..end.
// Read this https://www.briskbard.com/index.php?lang=en&pageid=cef

View File

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

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes,
uCEFWinControl;
uCEFWinControl, uCEFSentinel;
type
TForm1 = class(TForm)
@ -60,6 +60,7 @@ type
Timer1: TTimer;
Chromium1: TChromium;
CEFWindowParent1: TCEFWindowParent;
CEFSentinel1: TCEFSentinel;
procedure GoBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
@ -84,6 +85,7 @@ type
const targetUrl: ustring;
targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean;
out Result: Boolean);
procedure CEFSentinel1Close(Sender: TObject);
protected
// Variables to control when can we destroy the form safely
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.
// 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);
begin
@ -162,6 +165,12 @@ begin
if not(Chromium1.CreateBrowser(CEFWindowParent1)) then Timer1.Enabled := True;
end;
procedure TForm1.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TForm1.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin
// 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;
const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
CEFSentinel1.Start;
end;
procedure TForm1.Chromium1BeforePopup(Sender: TObject;

View File

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

View File

@ -50,7 +50,8 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFTypes, uCEFConstants, uCEFInterfaces, uCEFWorkScheduler,
uCEFChromiumWindow, Vcl.ComCtrls, Vcl.AppEvnts, uCEFWinControl;
uCEFChromiumWindow, Vcl.ComCtrls, Vcl.AppEvnts, uCEFWinControl,
uCEFSentinel;
type
TSimpleExternalPumpBrowserFrm = class(TForm)
@ -59,10 +60,12 @@ type
Timer1: TTimer;
URLCbx: TComboBox;
ChromiumWindow1: TChromiumWindow;
CEFSentinel1: TCEFSentinel;
procedure GoBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
@ -101,7 +104,8 @@ uses
// 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.
// 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);
begin
@ -120,7 +124,6 @@ begin
GlobalCEFApp.ExternalMessagePump := True;
GlobalCEFApp.MultiThreadedMessageLoop := False;
GlobalCEFApp.OnScheduleMessagePumpWork := GlobalCEFApp_OnScheduleMessagePumpWork;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end;
procedure TSimpleExternalPumpBrowserFrm.FormCreate(Sender: TObject);
@ -173,20 +176,21 @@ begin
GoBtn.Click;
end;
procedure TSimpleExternalPumpBrowserFrm.ChromiumWindow1BeforeClose(Sender: TObject);
procedure TSimpleExternalPumpBrowserFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TSimpleExternalPumpBrowserFrm.ChromiumWindow1BeforeClose(Sender: TObject);
begin
CEFSentinel1.Start;
end;
procedure TSimpleExternalPumpBrowserFrm.ChromiumWindow1Close(Sender: TObject);
begin
// DestroyChildWindow will destroy the child window created by CEF at the top of the Z order.
if not(ChromiumWindow1.DestroyChildWindow) then
begin
FCanClose := True;
Close;
end;
if not(ChromiumWindow1.DestroyChildWindow) then CEFSentinel1.Start;
end;
procedure TSimpleExternalPumpBrowserFrm.GoBtnClick(Sender: TObject);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFChromiumWindow, uCEFTypes, uCEFInterfaces,
uCEFWinControl;
uCEFWinControl, uCEFSentinel;
type
TForm1 = class(TForm)
@ -59,6 +59,7 @@ type
AddressEdt: TEdit;
GoBtn: TButton;
Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure GoBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure ChromiumWindow1AfterCreated(Sender: TObject);
@ -66,6 +67,7 @@ type
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure ChromiumWindow1Close(Sender: TObject);
procedure ChromiumWindow1BeforeClose(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
private
// 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;
@ -110,7 +112,8 @@ uses
// =================
// 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.
// 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);
begin
@ -147,14 +150,15 @@ end;
procedure TForm1.ChromiumWindow1Close(Sender: TObject);
begin
// DestroyChildWindow will destroy the child window created by CEF at the top of the Z order.
if not(ChromiumWindow1.DestroyChildWindow) then
begin
FCanClose := True;
Close;
end;
if not(ChromiumWindow1.DestroyChildWindow) then CEFSentinel1.Start;
end;
procedure TForm1.ChromiumWindow1BeforeClose(Sender: TObject);
begin
CEFSentinel1.Start;
end;
procedure TForm1.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);

View File

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

View File

@ -49,7 +49,8 @@ uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, ComCtrls, Buttons, ExtCtrls, StdCtrls,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants;
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFSentinel;
const
CEFBROWSER_DESTROYWNDPARENT = WM_APP + $100;
@ -72,6 +73,7 @@ type
URLCbx: TComboBox;
AddTabBtn: TButton;
RemoveTabBtn: TButton;
CEFSentinel1: TCEFSentinel;
procedure AddTabBtnClick(Sender: TObject);
procedure RemoveTabBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject);
@ -83,6 +85,7 @@ type
procedure StopBtnClick(Sender: TObject);
procedure GoBtnClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
protected
FClosingTab : boolean;
@ -144,7 +147,9 @@ implementation
// 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.
// 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;
begin
@ -156,7 +161,6 @@ procedure CreateGlobalCEFApp;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnContextInitialized := GlobalCEFApp_OnContextInitialized;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
end;
procedure TMainForm.AddTabBtnClick(Sender: TObject);
@ -350,11 +354,7 @@ begin
begin
PageControl1.Pages[aMessage.lParam].Tag := 1;
if AllTabSheetsAreTagged then
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
if AllTabSheetsAreTagged then CEFSentinel1.Start;
end;
end;
@ -576,4 +576,10 @@ begin
end;
end;
procedure TMainForm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
end.

View File

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

View File

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

View File

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

View File

@ -47,7 +47,8 @@ uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, ComCtrls, StdCtrls,
{$ENDIF}
uCEFInterfaces, uCEFUrlRequestClientComponent, uCEFRequest, uCEFUrlRequest;
uCEFInterfaces, uCEFUrlRequestClientComponent, uCEFRequest, uCEFUrlRequest,
uCEFSentinel;
const
URLREQUEST_SUCCESS = WM_APP + $101;
@ -77,9 +78,12 @@ type
Label6: TLabel;
PostParam2NameEdt: TEdit;
PostParam2ValueEdt: TEdit;
CEFSentinel1: TCEFSentinel;
procedure DownloadBtnClick(Sender: TObject);
procedure SendPostReqBtnClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
@ -90,8 +94,6 @@ type
procedure CEFUrlRequestClientComponent1RequestComplete(Sender: TObject; const request: ICefUrlRequest);
procedure CEFUrlRequestClientComponent1CreateURLRequest(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
FMemStream : TMemoryStream;
FCanClose : boolean;
@ -134,7 +136,8 @@ implementation
// 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
// 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
ShellApi,
@ -143,7 +146,8 @@ uses
procedure CreateGlobalCEFApp;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
//GlobalCEFApp.LogFile := 'cef.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end;
procedure TURLRequestFrm.DownloadBtnClick(Sender: TObject);
@ -221,6 +225,12 @@ begin
ShellExecute(0, 'open', 'https://ptsv2.com/t/cef4delphi', nil, nil, SW_SHOWNORMAL);
end;
procedure TURLRequestFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TURLRequestFrm.CEFUrlRequestClientComponent1CreateURLRequest(Sender: TObject);
begin
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.
if FClosing then
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end
CEFSentinel1.Start
else
if (request <> nil) and (request.RequestStatus = UR_SUCCESS) then
PostMessage(Handle, URLREQUEST_SUCCESS, 0, 0)

View File

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

View File

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

View File

@ -50,7 +50,7 @@ uses
Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
{$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
uCEFCookieManager, uCEFCookieVisitor, uCEFWinControl;
uCEFCookieManager, uCEFCookieVisitor, uCEFWinControl, uCEFSentinel;
const
MINIBROWSER_SHOWCOOKIES = WM_APP + $101;
@ -61,13 +61,18 @@ const
MINIBROWSER_CONTEXTMENU_SETCOOKIE = MENU_ID_USER_FIRST + 3;
type
{ TCookieVisitorFrm }
TCookieVisitorFrm = class(TForm)
AddressBarPnl: TPanel;
CEFSentinel1: TCEFSentinel;
Edit1: TEdit;
GoBtn: TButton;
CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium;
Timer1: TTimer;
procedure CEFSentinel1Close(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
procedure FormShow(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.
// 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;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
//GlobalCEFApp.LogFile := 'cef.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
end;
// This function is called in the IO thread.
@ -233,12 +240,17 @@ begin
PostMessage(Handle, CEF_AFTERCREATED, 0, 0);
end;
procedure TCookieVisitorFrm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
procedure TCookieVisitorFrm.CEFSentinel1Close(Sender: TObject);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TCookieVisitorFrm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
begin
CEFSentinel1.Start;
end;
procedure TCookieVisitorFrm.Chromium1BeforeContextMenu(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame;
const params: ICefContextMenuParams; const model: ICefMenuModel);

View File

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

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