1
0
mirror of https://github.com/salvadordf/CEF4Delphi.git synced 2024-11-24 08:02:15 +02:00

Added TCEFSentinel to more demos

- Check that all frames are valid before using them
- Added an error page to MiniBrowser.
This commit is contained in:
Salvador Díaz Fau 2019-10-13 18:50:23 +02:00
parent 9391d68ee0
commit 77121dc510
89 changed files with 1097 additions and 522 deletions

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,7 +143,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 CreateGlobalCEFApp;
begin
@ -229,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);
@ -236,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

@ -72,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,6 +59,7 @@ type
Edit1: TEdit;
Button1: TButton;
Timer1: TTimer;
CEFSentinel1: TCEFSentinel;
procedure FormCreate(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
@ -69,6 +70,7 @@ type
procedure ChromiumWindow1Close(Sender: TObject);
procedure ChromiumWindow1BeforeClose(Sender: TObject);
procedure CEFSentinel1Close(Sender: TObject);
private
procedure WMMove(var aMessage : TWMMove); message WM_MOVE;
@ -86,6 +88,7 @@ type
procedure Chromium_OnAfterCreated(Sender: TObject);
procedure Chromium_OnGetResourceHandler(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const request: ICefRequest; var aResourceHandler : ICefResourceHandler);
procedure Chromium_OnBeforePopup(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 Chromium_OnGetResourceRequestHandler(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const request: ICefRequest; is_navigation, is_download: boolean; const request_initiator: ustring; var disable_default_handling: boolean; var aExternalResourceRequestHandler : ICefResourceRequestHandler; var aUseInternalResourceRequestHandler : boolean);
public
{ Public declarations }
@ -107,7 +110,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 CreateGlobalCEFApp;
begin
@ -157,9 +161,10 @@ 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.OnGetResourceRequestHandler := Chromium_OnGetResourceRequestHandler;
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.
@ -173,20 +178,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);
@ -223,6 +229,21 @@ begin
Result := (targetDisposition in [WOD_NEW_FOREGROUND_TAB, WOD_NEW_BACKGROUND_TAB, WOD_NEW_POPUP, WOD_NEW_WINDOW]);
end;
procedure TMainForm.Chromium_OnGetResourceRequestHandler( Sender : TObject;
const browser : ICefBrowser;
const frame : ICefFrame;
const request : ICefRequest;
is_navigation : boolean;
is_download : boolean;
const request_initiator : ustring;
var disable_default_handling : boolean;
var aExternalResourceRequestHandler : ICefResourceRequestHandler;
var aUseInternalResourceRequestHandler : boolean);
begin
disable_default_handling := True;
aUseInternalResourceRequestHandler := True;
end;
procedure TMainForm.WMMove(var aMessage : TWMMove);
begin
inherited;

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;
@ -351,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);
@ -359,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,7 +172,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 CreateGlobalCEFApp;
begin
@ -226,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.
@ -235,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;
@ -250,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);
@ -142,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;
@ -156,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);
@ -163,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,6 +114,13 @@ 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;
@ -157,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);
@ -164,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

@ -50,7 +50,7 @@ uses
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,7 +116,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 CreateGlobalCEFApp;
begin
@ -164,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';
@ -248,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

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;
@ -181,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);
@ -189,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;
@ -326,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);
@ -334,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;
@ -382,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){'+
@ -393,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;
@ -159,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);
@ -167,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;
@ -162,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);
@ -170,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
@ -184,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);
@ -228,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){'+
@ -239,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 :
@ -342,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;
@ -149,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);
@ -220,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
@ -137,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);
@ -208,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

@ -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
@ -138,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);
@ -209,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
@ -162,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);
@ -233,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
@ -142,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);
@ -213,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
@ -143,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);
@ -214,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,7 +170,8 @@ 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
@ -299,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;
@ -861,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
@ -181,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
@ -198,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

@ -292,7 +292,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 CreateGlobalCEFApp;
begin
@ -472,7 +473,8 @@ begin
if Chromium1.IsSameBrowser(browser) and
(frame <> nil) and
frame.IsMain then
frame.IsMain and
frame.IsValid then
InspectRequest(request);
end;
@ -544,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) + '; ' +
@ -554,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;
@ -708,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
@ -717,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;
@ -890,7 +901,8 @@ begin
if Chromium1.IsSameBrowser(browser) and
(frame <> nil) and
frame.IsMain then
frame.IsMain and
frame.IsValid then
InspectResponse(response);
end;
@ -1084,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;

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);
@ -325,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,7 +144,8 @@ 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
@ -243,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;
@ -352,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,7 +142,8 @@ 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
@ -208,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;
@ -333,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
@ -141,7 +143,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 CreateGlobalCEFApp;
begin
@ -357,7 +360,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 +384,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
@ -403,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;
@ -506,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;
@ -541,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
@ -151,6 +154,12 @@ begin
// 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);
@ -159,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

@ -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

@ -132,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

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
@ -172,12 +176,17 @@ 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.

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,7 +177,8 @@ 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
@ -326,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;
@ -894,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

@ -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

@ -147,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

View File

@ -103,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

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,
@ -222,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
@ -345,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

@ -218,7 +218,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.
@ -239,21 +239,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 GlobalCEFApp_OnProcessMessageReceived(const browser : ICefBrowser;
@ -262,7 +274,6 @@ procedure GlobalCEFApp_OnProcessMessageReceived(const browser : ICefBrowse
const message : ICefProcessMessage;
var aHandled : boolean);
var
TempFrame : ICefFrame;
TempVisitor : TCefFastDomVisitor2;
begin
aHandled := False;
@ -271,12 +282,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, frame, DOMVisitor_OnDocAvailable);
TempFrame.VisitDom(TempVisitor);
frame.VisitDom(TempVisitor);
end;
aHandled := True;
@ -284,12 +293,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, frame, DOMVisitor_OnDocAvailableFullMarkup);
TempFrame.VisitDom(TempVisitor);
frame.VisitDom(TempVisitor);
end;
aHandled := True;

View File

@ -1,4 +1,4 @@
// ************************************************************************
// ************************************************************************
// ***************************** CEF4Delphi *******************************
// ************************************************************************
//
@ -246,7 +246,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

@ -1,4 +1,4 @@
// ************************************************************************
// ************************************************************************
// ***************************** CEF4Delphi *******************************
// ************************************************************************
//
@ -432,7 +432,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);
@ -476,7 +477,7 @@ begin
TempString := 'Image size : ' + inttostr(TempSize) + #13 + #10 +
'Encoded image : ' + TempEncodedStream.DataString;
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;
@ -512,9 +513,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

View File

@ -388,7 +388,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){'+
@ -399,16 +399,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

@ -1,4 +1,4 @@
// ************************************************************************
// ************************************************************************
// ***************************** CEF4Delphi *******************************
// ************************************************************************
//
@ -69,35 +69,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

@ -1,4 +1,4 @@
// ************************************************************************
// ************************************************************************
// ***************************** CEF4Delphi *******************************
// ************************************************************************
//
@ -63,19 +63,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

@ -1,4 +1,4 @@
// ************************************************************************
// ************************************************************************
// ***************************** CEF4Delphi *******************************
// ************************************************************************
//
@ -496,6 +496,7 @@ begin
if Chromium1.IsSameBrowser(browser) and
(frame <> nil) and
frame.IsValid and
frame.IsMain then
InspectRequest(request);
end;
@ -568,8 +569,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) + '; ' +
@ -578,8 +579,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;
@ -720,6 +721,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
StatusPnl.Caption := 'main frame loaded : ' + quotedstr(frame.name)
else
@ -902,6 +905,7 @@ begin
if Chromium1.IsSameBrowser(browser) and
(frame <> nil) and
frame.IsValid and
frame.IsMain then
InspectResponse(response);
end;

View File

@ -10,7 +10,7 @@
<IsPartOfProject Value="True"/>
<TopLine Value="38"/>
<CursorPos X="61" Y="64"/>
<UsageCount Value="22"/>
<UsageCount Value="23"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit0>
@ -22,9 +22,12 @@
<ResourceBaseClass Value="Form"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="1"/>
<TopLine Value="307"/>
<CursorPos Y="328"/>
<UsageCount Value="22"/>
<TopLine Value="313"/>
<CursorPos X="59" Y="328"/>
<UsageCount Value="23"/>
<Bookmarks Count="1">
<Item0 X="58" Y="328" ID="1"/>
</Bookmarks>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
@ -35,10 +38,10 @@
<ComponentName Value="ChildForm"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<EditorIndex Value="3"/>
<EditorIndex Value="2"/>
<TopLine Value="52"/>
<CursorPos X="54" Y="97"/>
<UsageCount Value="22"/>
<UsageCount Value="23"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
@ -52,11 +55,10 @@
</Unit3>
<Unit4>
<Filename Value="..\..\..\source\uCEFChromium.pas"/>
<EditorIndex Value="2"/>
<TopLine Value="3887"/>
<CursorPos X="61" Y="3906"/>
<EditorIndex Value="-1"/>
<TopLine Value="1009"/>
<CursorPos X="9" Y="1022"/>
<UsageCount Value="10"/>
<Loaded Value="True"/>
</Unit4>
<Unit5>
<Filename Value="..\..\..\source\uCEFMiscFunctions.pas"/>
@ -83,120 +85,120 @@
</Units>
<JumpHistory Count="30" HistoryIndex="29">
<Position1>
<Filename Value="uMainForm.pas"/>
<Caret Line="224" Column="25" TopLine="204"/>
<Filename Value="uChildForm.pas"/>
<Caret Line="62" Column="384" TopLine="51"/>
</Position1>
<Position2>
<Filename Value="uMainForm.pas"/>
<Caret Line="277" Column="13" TopLine="257"/>
<Caret Line="199" Column="59" TopLine="183"/>
</Position2>
<Position3>
<Filename Value="uMainForm.pas"/>
<Caret Line="292" Column="19" TopLine="272"/>
<Caret Line="344" Column="17" TopLine="320"/>
</Position3>
<Position4>
<Filename Value="uMainForm.pas"/>
<Caret Line="294" Column="19" TopLine="274"/>
<Caret Line="346" Column="19" TopLine="322"/>
</Position4>
<Position5>
<Filename Value="uMainForm.pas"/>
<Caret Line="295" Column="19" TopLine="275"/>
<Caret Line="197" Column="72" TopLine="182"/>
</Position5>
<Position6>
<Filename Value="uMainForm.pas"/>
<Caret Line="298" Column="15" TopLine="278"/>
<Caret Line="352" Column="56" TopLine="322"/>
</Position6>
<Position7>
<Filename Value="uMainForm.pas"/>
<Caret Line="86" Column="15" TopLine="75"/>
<Caret Line="332" TopLine="310"/>
</Position7>
<Position8>
<Filename Value="uMainForm.pas"/>
<Caret Line="223" Column="26" TopLine="203"/>
<Caret Line="334" Column="51" TopLine="310"/>
</Position8>
<Position9>
<Filename Value="uMainForm.pas"/>
<Caret Line="224" Column="25" TopLine="204"/>
<Caret Line="67" TopLine="49"/>
</Position9>
<Position10>
<Filename Value="uMainForm.pas"/>
<Caret Line="277" Column="13" TopLine="257"/>
<Caret Line="340" TopLine="311"/>
</Position10>
<Position11>
<Filename Value="uMainForm.pas"/>
<Caret Line="292" TopLine="281"/>
<Caret Line="337" TopLine="311"/>
</Position11>
<Position12>
<Filename Value="uMainForm.pas"/>
<Caret Line="295" TopLine="281"/>
<Caret Line="343" Column="33" TopLine="314"/>
</Position12>
<Position13>
<Filename Value="uChildForm.pas"/>
<Caret Line="62" Column="23" TopLine="54"/>
<Filename Value="uMainForm.pas"/>
<Caret Line="337" TopLine="314"/>
</Position13>
<Position14>
<Filename Value="uChildForm.pas"/>
<Caret Line="222" Column="3" TopLine="220"/>
<Filename Value="uMainForm.pas"/>
<Caret Line="346" Column="58" TopLine="320"/>
</Position14>
<Position15>
<Filename Value="uChildForm.pas"/>
<Caret Line="77" Column="22" TopLine="48"/>
<Filename Value="uMainForm.pas"/>
<Caret Line="337" TopLine="320"/>
</Position15>
<Position16>
<Filename Value="uMainForm.pas"/>
<Caret Line="286" Column="54" TopLine="260"/>
<Caret Line="184" Column="66" TopLine="175"/>
</Position16>
<Position17>
<Filename Value="uMainForm.pas"/>
<Caret Line="98" Column="33" TopLine="77"/>
<Caret Line="337" Column="30" TopLine="322"/>
</Position17>
<Position18>
<Filename Value="uChildForm.pas"/>
<Caret Line="78" Column="22" TopLine="71"/>
<Filename Value="uMainForm.pas"/>
<Caret Line="67" TopLine="49"/>
</Position18>
<Position19>
<Filename Value="uChildForm.pas"/>
<Caret Line="253" Column="14" TopLine="231"/>
<Filename Value="uMainForm.pas"/>
<Caret Line="180" Column="40" TopLine="166"/>
</Position19>
<Position20>
<Filename Value="uMainForm.pas"/>
<Caret Line="76" Column="384" TopLine="70"/>
<Caret Line="335" Column="59" TopLine="309"/>
</Position20>
<Position21>
<Filename Value="uChildForm.pas"/>
<Caret Line="250" Column="32" TopLine="223"/>
<Filename Value="uMainForm.pas"/>
<Caret Line="333" Column="40" TopLine="309"/>
</Position21>
<Position22>
<Filename Value="uChildForm.pas"/>
<Caret Line="62" Column="384" TopLine="51"/>
<Filename Value="uMainForm.pas"/>
<Caret Line="332" TopLine="309"/>
</Position22>
<Position23>
<Filename Value="uMainForm.pas"/>
<Caret Line="199" Column="59" TopLine="183"/>
<Caret Line="339" TopLine="309"/>
</Position23>
<Position24>
<Filename Value="uMainForm.pas"/>
<Caret Line="344" Column="17" TopLine="320"/>
<Caret Line="188" Column="99" TopLine="177"/>
</Position24>
<Position25>
<Filename Value="uMainForm.pas"/>
<Caret Line="346" Column="19" TopLine="322"/>
<Caret Line="343" Column="19" TopLine="333"/>
</Position25>
<Position26>
<Filename Value="uMainForm.pas"/>
<Caret Line="197" Column="72" TopLine="182"/>
<Caret Line="69" TopLine="52"/>
</Position26>
<Position27>
<Filename Value="uMainForm.pas"/>
<Caret Line="352" Column="56" TopLine="322"/>
<Caret Line="336" TopLine="321"/>
</Position27>
<Position28>
<Filename Value="uMainForm.pas"/>
<Caret Line="332" TopLine="310"/>
<Caret Line="335" TopLine="320"/>
</Position28>
<Position29>
<Filename Value="uMainForm.pas"/>
<Caret Line="334" Column="51" TopLine="310"/>
<Caret Line="330" Column="32" TopLine="320"/>
</Position29>
<Position30>
<Filename Value="uMainForm.pas"/>

View File

@ -1,7 +1,7 @@
object MainForm: TMainForm
Left = 101
Left = 679
Height = 624
Top = 120
Top = 160
Width = 1038
Caption = 'Initializing browser. Please wait...'
ClientHeight = 624
@ -71,7 +71,7 @@ object MainForm: TMainForm
top = 152
end
object ApplicationProperties1: TApplicationProperties
left = 59
top = 235
left = 56
top = 216
end
end

View File

@ -45,7 +45,7 @@ uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, SyncObjs,
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes, uChildForm,
uCEFWinControl, uCEFChromiumEvents;
uCEFWinControl, uCEFChromiumEvents, uCEFSentinel;
const
CEF_CREATENEXTCHILD = WM_APP + $A50;
@ -325,8 +325,7 @@ begin
Chromium1.LoadURL(AddressEdt.Text);
end;
procedure TMainForm.Chromium1BeforeClose(Sender: TObject;
const browser: ICefBrowser);
procedure TMainForm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
begin
FCanClose := True;
PostMessage(Handle, WM_CLOSE, 0, 0);

View File

@ -366,7 +366,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;

View File

@ -1553,7 +1553,7 @@ begin
TempFrame := FBrowser.FocusedFrame;
if (TempFrame = nil) then TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.Copy;
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.Copy;
end;
end;
@ -1566,7 +1566,7 @@ begin
TempFrame := FBrowser.FocusedFrame;
if (TempFrame = nil) then TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.Paste;
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.Paste;
end;
end;
@ -1579,7 +1579,7 @@ begin
TempFrame := FBrowser.FocusedFrame;
if (TempFrame = nil) then TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.Cut;
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.Cut;
end;
end;
@ -1592,7 +1592,7 @@ begin
TempFrame := FBrowser.FocusedFrame;
if (TempFrame = nil) then TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.Undo;
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.Undo;
end;
end;
@ -1605,7 +1605,7 @@ begin
TempFrame := FBrowser.FocusedFrame;
if (TempFrame = nil) then TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.Redo;
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.Redo;
end;
end;
@ -1618,7 +1618,7 @@ begin
TempFrame := FBrowser.FocusedFrame;
if (TempFrame = nil) then TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.Del;
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.Del;
end;
end;
@ -1631,7 +1631,7 @@ begin
TempFrame := FBrowser.FocusedFrame;
if (TempFrame = nil) then TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.SelectAll;
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.SelectAll;
end;
end;
@ -1743,13 +1743,13 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.LoadUrl(aURL);
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.LoadUrl(aURL);
end;
end;
procedure TChromium.LoadURL(const aURL : ustring; const aFrame : ICefFrame);
begin
if Initialized and (aFrame <> nil) then aFrame.LoadUrl(aURL);
if Initialized and (aFrame <> nil) and aFrame.IsValid then aFrame.LoadUrl(aURL);
end;
procedure TChromium.LoadURL(const aURL : ustring; const aFrameIdentifier : int64);
@ -1763,7 +1763,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.LoadUrl(aURL);
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.LoadUrl(aURL);
end;
end;
@ -1774,7 +1774,7 @@ begin
if Initialized then
begin
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.LoadString(aString, aURL);
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.LoadString(aString, aURL);
end;
end;
@ -1785,7 +1785,7 @@ begin
if Initialized then
begin
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.LoadRequest(aRequest);
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.LoadRequest(aRequest);
end;
end;
@ -1975,7 +1975,7 @@ begin
if Initialized then
begin
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then Result := TempFrame.URL;
if (TempFrame <> nil) and TempFrame.IsValid then Result := TempFrame.URL;
end;
end;
@ -2436,7 +2436,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then
if (TempFrame <> nil) and TempFrame.IsValid then
try
TempVisitor := TCustomCefStringVisitor.Create(self);
TempFrame.GetSource(TempVisitor);
@ -2450,7 +2450,7 @@ procedure TChromium.RetrieveHTML(const aFrame : ICefFrame);
var
TempVisitor : ICefStringVisitor;
begin
if Initialized and (aFrame <> nil) then
if Initialized and (aFrame <> nil) and aFrame.IsValid then
try
TempVisitor := TCustomCefStringVisitor.Create(self);
aFrame.GetSource(TempVisitor);
@ -2471,7 +2471,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then
if (TempFrame <> nil) and TempFrame.IsValid then
try
TempVisitor := TCustomCefStringVisitor.Create(self);
TempFrame.GetSource(TempVisitor);
@ -2494,7 +2494,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then
if (TempFrame <> nil) and TempFrame.IsValid then
try
TempVisitor := TCustomCefStringVisitor.Create(self);
TempFrame.GetText(TempVisitor);
@ -2508,7 +2508,7 @@ procedure TChromium.RetrieveText(const aFrame : ICefFrame);
var
TempVisitor : ICefStringVisitor;
begin
if Initialized and (aFrame <> nil) then
if Initialized and (aFrame <> nil) and aFrame.IsValid then
try
TempVisitor := TCustomCefStringVisitor.Create(self);
aFrame.GetText(TempVisitor);
@ -2529,7 +2529,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then
if (TempFrame <> nil) and TempFrame.IsValid then
try
TempVisitor := TCustomCefStringVisitor.Create(self);
TempFrame.GetText(TempVisitor);
@ -3427,7 +3427,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then
if (TempFrame <> nil) and TempFrame.IsValid then
TempFrame.ExecuteJavaScript(aCode, aScriptURL, aStartLine);
end;
except
@ -3439,7 +3439,7 @@ end;
procedure TChromium.ExecuteJavaScript(const aCode, aScriptURL : ustring; const aFrame : ICefFrame; aStartLine : integer);
begin
try
if Initialized and (aFrame <> nil) then
if Initialized and (aFrame <> nil) and aFrame.IsValid then
aFrame.ExecuteJavaScript(aCode, aScriptURL, aStartLine);
except
on e : exception do
@ -3459,7 +3459,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then
if (TempFrame <> nil) and TempFrame.IsValid then
TempFrame.ExecuteJavaScript(aCode, aScriptURL, aStartLine);
end;
except
@ -4602,7 +4602,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then
if (TempFrame <> nil) and TempFrame.IsValid then
TempFrame.SendProcessMessage(targetProcess, ProcMessage);
end;
except
@ -4614,7 +4614,7 @@ end;
procedure TChromium.SendProcessMessage(targetProcess: TCefProcessId; const ProcMessage: ICefProcessMessage; const aFrame : ICefFrame);
begin
try
if Initialized and (aFrame <> nil) then
if Initialized and (aFrame <> nil) and aFrame.IsValid then
aFrame.SendProcessMessage(targetProcess, ProcMessage);
except
on e : exception do
@ -4634,7 +4634,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then
if (TempFrame <> nil) and TempFrame.IsValid then
TempFrame.SendProcessMessage(targetProcess, ProcMessage);
end;
except
@ -4657,7 +4657,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then
if (TempFrame <> nil) and TempFrame.IsValid then
Result := TempFrame.CreateUrlRequest(request, client);
end;
except
@ -4671,7 +4671,7 @@ begin
Result := nil;
try
if Initialized and (aFrame <> nil) then
if Initialized and (aFrame <> nil) and aFrame.IsValid then
Result := aFrame.CreateUrlRequest(request, client);
except
on e : exception do
@ -4693,7 +4693,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then
if (TempFrame <> nil) and TempFrame.IsValid then
Result := TempFrame.CreateUrlRequest(request, client);
end;
except

View File

@ -1352,7 +1352,7 @@ begin
TempFrame := FBrowser.FocusedFrame;
if (TempFrame = nil) then TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.Copy;
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.Copy;
end;
end;
@ -1365,7 +1365,7 @@ begin
TempFrame := FBrowser.FocusedFrame;
if (TempFrame = nil) then TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.Paste;
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.Paste;
end;
end;
@ -1378,7 +1378,7 @@ begin
TempFrame := FBrowser.FocusedFrame;
if (TempFrame = nil) then TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.Cut;
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.Cut;
end;
end;
@ -1391,7 +1391,7 @@ begin
TempFrame := FBrowser.FocusedFrame;
if (TempFrame = nil) then TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.Undo;
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.Undo;
end;
end;
@ -1404,7 +1404,7 @@ begin
TempFrame := FBrowser.FocusedFrame;
if (TempFrame = nil) then TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.Redo;
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.Redo;
end;
end;
@ -1417,7 +1417,7 @@ begin
TempFrame := FBrowser.FocusedFrame;
if (TempFrame = nil) then TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.Del;
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.Del;
end;
end;
@ -1430,7 +1430,7 @@ begin
TempFrame := FBrowser.FocusedFrame;
if (TempFrame = nil) then TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.SelectAll;
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.SelectAll;
end;
end;
@ -1542,13 +1542,13 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.LoadUrl(aURL);
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.LoadUrl(aURL);
end;
end;
procedure TFMXChromium.LoadURL(const aURL : ustring; const aFrame : ICefFrame);
begin
if Initialized and (aFrame <> nil) then aFrame.LoadUrl(aURL);
if Initialized and (aFrame <> nil) and aFrame.IsValid then aFrame.LoadUrl(aURL);
end;
procedure TFMXChromium.LoadURL(const aURL : ustring; const aFrameIdentifier : int64);
@ -1562,7 +1562,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.LoadUrl(aURL);
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.LoadUrl(aURL);
end;
end;
@ -1573,7 +1573,7 @@ begin
if Initialized then
begin
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.LoadString(aString, aURL);
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.LoadString(aString, aURL);
end;
end;
@ -1584,7 +1584,7 @@ begin
if Initialized then
begin
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then TempFrame.LoadRequest(aRequest);
if (TempFrame <> nil) and TempFrame.IsValid then TempFrame.LoadRequest(aRequest);
end;
end;
@ -1774,7 +1774,7 @@ begin
if Initialized then
begin
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then Result := TempFrame.URL;
if (TempFrame <> nil) and TempFrame.IsValid then Result := TempFrame.URL;
end;
end;
@ -2235,7 +2235,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then
if (TempFrame <> nil) and TempFrame.IsValid then
try
TempVisitor := TCustomCefStringVisitor.Create(self);
TempFrame.GetSource(TempVisitor);
@ -2249,7 +2249,7 @@ procedure TFMXChromium.RetrieveHTML(const aFrame : ICefFrame);
var
TempVisitor : ICefStringVisitor;
begin
if Initialized and (aFrame <> nil) then
if Initialized and (aFrame <> nil) and aFrame.IsValid then
try
TempVisitor := TCustomCefStringVisitor.Create(self);
aFrame.GetSource(TempVisitor);
@ -2270,7 +2270,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then
if (TempFrame <> nil) and TempFrame.IsValid then
try
TempVisitor := TCustomCefStringVisitor.Create(self);
TempFrame.GetSource(TempVisitor);
@ -2293,7 +2293,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then
if (TempFrame <> nil) and TempFrame.IsValid then
try
TempVisitor := TCustomCefStringVisitor.Create(self);
TempFrame.GetText(TempVisitor);
@ -2307,7 +2307,7 @@ procedure TFMXChromium.RetrieveText(const aFrame : ICefFrame);
var
TempVisitor : ICefStringVisitor;
begin
if Initialized and (aFrame <> nil) then
if Initialized and (aFrame <> nil) and aFrame.IsValid then
try
TempVisitor := TCustomCefStringVisitor.Create(self);
aFrame.GetText(TempVisitor);
@ -2328,7 +2328,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then
if (TempFrame <> nil) and TempFrame.IsValid then
try
TempVisitor := TCustomCefStringVisitor.Create(self);
TempFrame.GetText(TempVisitor);
@ -3157,7 +3157,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then
if (TempFrame <> nil) and TempFrame.IsValid then
TempFrame.ExecuteJavaScript(aCode, aScriptURL, aStartLine);
end;
except
@ -3169,7 +3169,7 @@ end;
procedure TFMXChromium.ExecuteJavaScript(const aCode, aScriptURL : ustring; const aFrame : ICefFrame; aStartLine : integer);
begin
try
if Initialized and (aFrame <> nil) then
if Initialized and (aFrame <> nil) and aFrame.IsValid then
aFrame.ExecuteJavaScript(aCode, aScriptURL, aStartLine);
except
on e : exception do
@ -3189,7 +3189,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then
if (TempFrame <> nil) and TempFrame.IsValid then
TempFrame.ExecuteJavaScript(aCode, aScriptURL, aStartLine);
end;
except
@ -4305,7 +4305,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then
if (TempFrame <> nil) and TempFrame.IsValid then
TempFrame.SendProcessMessage(targetProcess, ProcMessage);
end;
except
@ -4317,7 +4317,7 @@ end;
procedure TFMXChromium.SendProcessMessage(targetProcess: TCefProcessId; const ProcMessage: ICefProcessMessage; const aFrame : ICefFrame);
begin
try
if Initialized and (aFrame <> nil) then
if Initialized and (aFrame <> nil) and aFrame.IsValid then
aFrame.SendProcessMessage(targetProcess, ProcMessage);
except
on e : exception do
@ -4337,7 +4337,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then
if (TempFrame <> nil) and TempFrame.IsValid then
TempFrame.SendProcessMessage(targetProcess, ProcMessage);
end;
except
@ -4360,7 +4360,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then
if (TempFrame <> nil) and TempFrame.IsValid then
Result := TempFrame.CreateUrlRequest(request, client);
end;
except
@ -4374,7 +4374,7 @@ begin
Result := nil;
try
if Initialized and (aFrame <> nil) then
if Initialized and (aFrame <> nil) and aFrame.IsValid then
Result := aFrame.CreateUrlRequest(request, client);
except
on e : exception do
@ -4396,7 +4396,7 @@ begin
else
TempFrame := FBrowser.MainFrame;
if (TempFrame <> nil) then
if (TempFrame <> nil) and TempFrame.IsValid then
Result := TempFrame.CreateUrlRequest(request, client);
end;
except

View File

@ -241,6 +241,9 @@ function DeleteDirContents(const aDirectory : string; const aExcludeFiles : TStr
function DeleteFileList(const aFileList : TStringList) : boolean;
function MoveFileList(const aFileList : TStringList; const aSrcDirectory, aDstDirectory : string) : boolean;
function CefGetDataURI(const aString, aMimeType : ustring) : ustring; overload;
function CefGetDataURI(aData : pointer; aSize : integer; const aMimeType : ustring; const aCharset : ustring = '') : ustring; overload;
implementation
uses
@ -2132,4 +2135,25 @@ begin
end;
end;
function CefGetDataURI(const aString, aMimeType : ustring) : ustring;
var
TempUTF : AnsiString;
begin
TempUTF := UTF8Encode(aString);
if (length(TempUTF) > 0) then
Result := CefGetDataURI(@TempUTF[1], length(TempUTF), aMimeType, 'utf-8')
else
Result := '';
end;
function CefGetDataURI(aData : pointer; aSize : integer; const aMimeType, aCharset : ustring) : ustring;
begin
Result := 'data:' + aMimeType;
if (length(aCharset) > 0) then Result := Result + ';charset=' + aCharset;
Result := Result + ';base64,' + CefURIEncode(CefBase64Encode(aData, aSize), false);
end;
end.

View File

@ -552,25 +552,25 @@ var
TempUseInternalHandler : boolean;
begin
if (FEvents <> nil) then
begin
TempUseInternalHandler := True;
begin
TempUseInternalHandler := True;
IChromiumEvents(FEvents).doOnGetResourceRequestHandler(browser, frame, request,
is_navigation, is_download,
request_initiator,
disable_default_handling,
aResourceRequestHandler,
TempUseInternalHandler);
IChromiumEvents(FEvents).doOnGetResourceRequestHandler(browser, frame, request,
is_navigation, is_download,
request_initiator,
disable_default_handling,
aResourceRequestHandler,
TempUseInternalHandler);
if TempUseInternalHandler then
begin
if (FResourceRequestHandler <> nil) then
aResourceRequestHandler := FResourceRequestHandler
else
aResourceRequestHandler := nil;
end;
end
else
if TempUseInternalHandler then
begin
if (FResourceRequestHandler <> nil) then
aResourceRequestHandler := FResourceRequestHandler
else
aResourceRequestHandler := nil;
end;
end
else
inherited GetResourceRequestHandler(browser, frame, request,
is_navigation, is_download,
request_initiator,

View File

@ -1,8 +1,8 @@
{
"UpdateLazPackages" : [
{
"ForceNotify" : false,
"InternalVersion" : 42,
"ForceNotify" : true,
"InternalVersion" : 43,
"Name" : "cef4delphi_lazarus.lpk",
"Version" : "77.1.13.0"
}