unit uBrowserWindowDom; {$mode objfpc}{$H+} {$IFDEF MSWINDOWS}{$I ..\..\..\source\cef.inc}{$ELSE}{$I ../../../source/cef.inc}{$ENDIF} interface uses GlobalCefApplication, uCEFLazarusCocoa, // required for Cocoa SysUtils, Messages, Forms, Controls, Dialogs, ExtCtrls, StdCtrls, LMessages, Menus, uCEFTypes, uCEFInterfaces, uHelperProcessDom, uCEFWorkScheduler, uCEFBrowserWindow, uCEFProcessMessage, Classes; type { TForm1 } TForm1 = class(TForm) AddressEdt: TComboBox; GoBtn: TButton; AddressPnl: TPanel; BrowserWindow1: TBrowserWindow; mDomHere: TMenuItem; procedure Chromium1BeforePopup(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl, targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; const popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo; var client: ICefClient; var settings: TCefBrowserSettings; var extra_info: ICefDictionaryValue; var noJavascriptAccess: Boolean; var Result: Boolean); procedure Chromium1OpenUrlFromTab(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; out Result: Boolean); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure FormCreate(Sender: TObject); procedure GoBtnClick(Sender: TObject); procedure BrowserWindow1BrowserClosed(Sender: TObject); private FContextXY: TPoint; procedure DoBeforeContextMenu(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const params: ICefContextMenuParams; const model: ICefMenuModel); procedure DoCaptureMenuXY; procedure DoContextMenuCmd(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const params: ICefContextMenuParams; commandId: Integer; eventFlags: TCefEventFlags; out Result: Boolean); procedure DoProcessMessageReceived(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; sourceProcess: TCefProcessId; const message: ICefProcessMessage; out Result: Boolean); protected {$IFDEF WINDOWS} procedure WMEnterMenuLoop(var aMessage: TMessage); message WM_ENTERMENULOOP; procedure WMExitMenuLoop(var aMessage: TMessage); message WM_EXITMENULOOP; {$ENDIF} public end; var Form1: TForm1; implementation {$R *.lfm} // This is a demo with the simplest web browser you can build using CEF4Delphi and // it doesn't show any sign of progress like other web browsers do. // Remember that it may take a few seconds to load if Windows update, your antivirus or // any other windows service is using your hard drive. // Depending on your internet connection it may take longer than expected. // Please check that your firewall or antivirus are not blocking this application // or the domain "google.com". If you don't live in the US, you'll be redirected to // another domain which will take a little time too. // This demo uses a TChromium and a TCEFLinkedWindowParent // We need to use TCEFLinkedWindowParent in Linux to update the browser // visibility and size automatically. // Destruction steps // ================= // 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. // 2. TChromium.OnClose sets aAction to cbaClose to destroy the browser, which triggers the TChromium.OnBeforeClose event. // 3. TChromium.OnBeforeClose sets FCanClose := True and sends CEF_BEFORECLOSE to close the form. uses uCEFApplication; { TForm1 } procedure TForm1.GoBtnClick(Sender: TObject); begin BrowserWindow1.LoadURL(UTF8Decode(AddressEdt.Text)); end; procedure TForm1.BrowserWindow1BrowserClosed(Sender: TObject); begin Close; end; procedure TForm1.DoBeforeContextMenu(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const params: ICefContextMenuParams; const model: ICefMenuModel); begin model.Clear; model.AddItem(1, 'Get DOM'); TThread.Synchronize(nil, @DoCaptureMenuXY); end; procedure TForm1.DoCaptureMenuXY; begin FContextXY := BrowserWindow1.ScreenToClient(Mouse.CursorPos); end; procedure TForm1.DoContextMenuCmd(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const params: ICefContextMenuParams; commandId: Integer; eventFlags: TCefEventFlags; out Result: Boolean); var TempMsg : ICefProcessMessage; begin if commandId = 1 then begin TempMsg := TCefProcessMessageRef.New(MSG_REQUEST_DOM); // Same name than TCefCustomRenderProcessHandler.MessageName TempMsg.ArgumentList.SetInt(0, FContextXY.X); TempMsg.ArgumentList.SetInt(1, FContextXY.Y); BrowserWindow1.Chromium.SendProcessMessage(PID_RENDERER, TempMsg); end; end; procedure TForm1.DoProcessMessageReceived(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; sourceProcess: TCefProcessId; const message: ICefProcessMessage; out Result: Boolean); begin Result := False; case message.Name of MSG_RESPONSE_DOM: begin Caption := message.ArgumentList.GetString(0); Result := True; end; end; end; {$IFDEF WINDOWS} procedure TForm1.WMEnterMenuLoop(var aMessage: TMessage); begin inherited; if (aMessage.wParam = 0) and (GlobalCEFApp <> nil) then GlobalCEFApp.OsmodalLoop := True; end; procedure TForm1.WMExitMenuLoop(var aMessage: TMessage); begin inherited; if (aMessage.wParam = 0) and (GlobalCEFApp <> nil) then GlobalCEFApp.OsmodalLoop := False; end; {$ENDIF} procedure TForm1.Chromium1BeforePopup(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl, targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; const popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo; var client: ICefClient; var settings: TCefBrowserSettings; var extra_info: ICefDictionaryValue; var noJavascriptAccess: Boolean; var Result: Boolean); begin // For simplicity, this demo blocks all popup windows and new tabs Result := (targetDisposition in [WOD_NEW_FOREGROUND_TAB, WOD_NEW_BACKGROUND_TAB, WOD_NEW_POPUP, WOD_NEW_WINDOW]); end; procedure TForm1.Chromium1OpenUrlFromTab(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; out Result: Boolean); begin // For simplicity, this demo blocks all popup windows and new tabs Result := (targetDisposition in [WOD_NEW_FOREGROUND_TAB, WOD_NEW_BACKGROUND_TAB, WOD_NEW_POPUP, WOD_NEW_WINDOW]); end; procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin BrowserWindow1.CloseBrowser(True); CanClose := BrowserWindow1.IsClosed; end; procedure TForm1.FormCreate(Sender: TObject); begin BrowserWindow1.Chromium.OnBeforeContextMenu := @DoBeforeContextMenu; BrowserWindow1.Chromium.OnContextMenuCommand := @DoContextMenuCmd; BrowserWindow1.Chromium.OnProcessMessageReceived := @DoProcessMessageReceived; BrowserWindow1.LoadURL(UTF8Decode(AddressEdt.Text)); end; initialization {$IFDEF DARWIN} // $IFDEF MACOSX AddCrDelegate; {$ENDIF} if GlobalCEFApp = nil then begin CreateGlobalCEFApp; if not GlobalCEFApp.StartMainProcess then begin DestroyGlobalCEFApp; DestroyGlobalCEFWorkScheduler; halt(0); // exit the subprocess end; end; finalization (* Destroy from this unit, which is used after "Interfaces". So this happens before the Application object is destroyed *) if GlobalCEFWorkScheduler <> nil then GlobalCEFWorkScheduler.StopScheduler; DestroyGlobalCEFApp; DestroyGlobalCEFWorkScheduler; end.