├── Examples ├── LCLSimple │ ├── simple.app │ │ └── Contents │ │ │ ├── MacOS │ │ │ └── simple │ │ │ ├── PkgInfo │ │ │ ├── Frameworks │ │ │ └── put framework and subprocess here │ │ │ └── Info.plist │ ├── simple.ico │ ├── simple.lpr │ ├── main.lfm │ ├── main.pas │ └── simple.lpi ├── OSRDemo │ ├── osrdemo.app │ │ └── Contents │ │ │ ├── MacOS │ │ │ └── osrdemo │ │ │ ├── PkgInfo │ │ │ └── Info.plist │ ├── osrdemo.ico │ ├── osrdemo.lpr │ ├── main.lfm │ ├── osrdemo.lpi │ └── main.pas ├── SubProcess │ ├── subprocess.app │ │ └── Contents │ │ │ ├── MacOS │ │ │ └── subprocess │ │ │ ├── PkgInfo │ │ │ └── Info.plist │ ├── subprocess.lpr │ └── subprocess.lpi ├── LCLCefClient │ ├── Resources │ │ └── info │ ├── client.ico │ ├── client.lpr │ ├── printhandler.pas │ ├── schemehandler.pas │ ├── favicongetter.pas │ ├── main.lfm │ ├── client.lpi │ ├── main.pas │ └── webpanel.pas ├── DOMAccess │ ├── dom.ico │ ├── dom.lpr │ ├── handler.pas │ ├── main.lfm │ ├── main.pas │ └── dom.lpi ├── JavaScript │ ├── js.ico │ ├── js.lpr │ ├── handler.pas │ ├── main.lfm │ ├── main.pas │ └── js.lpi ├── Examples.md ├── GTK2Minimal │ ├── minimal.lpi │ └── minimal.lpr └── WinMinimal │ ├── minimal.lpi │ └── minimal.lpr ├── Component ├── icons.res ├── cef3.pas ├── cef3.lpk ├── cef3context.pas └── cef3cocoa.pas ├── .gitignore ├── cef.inc ├── cef3scp.pas ├── Readme.md ├── LICENSE └── cef3lib.pas /Examples/LCLSimple/simple.app/Contents/MacOS/simple: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Examples/OSRDemo/osrdemo.app/Contents/MacOS/osrdemo: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Examples/OSRDemo/osrdemo.app/Contents/PkgInfo: -------------------------------------------------------------------------------- 1 | APPL???? 2 | -------------------------------------------------------------------------------- /Examples/LCLSimple/simple.app/Contents/PkgInfo: -------------------------------------------------------------------------------- 1 | APPL???? 2 | -------------------------------------------------------------------------------- /Examples/SubProcess/subprocess.app/Contents/MacOS/subprocess: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Examples/SubProcess/subprocess.app/Contents/PkgInfo: -------------------------------------------------------------------------------- 1 | APPL???? 2 | -------------------------------------------------------------------------------- /Examples/LCLSimple/simple.app/Contents/Frameworks/put framework and subprocess here: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Component/icons.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dliw/fpCEF3/HEAD/Component/icons.res -------------------------------------------------------------------------------- /Examples/LCLCefClient/Resources/info: -------------------------------------------------------------------------------- 1 | Insert the contents of the Resources folder here. 2 | -------------------------------------------------------------------------------- /Examples/DOMAccess/dom.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dliw/fpCEF3/HEAD/Examples/DOMAccess/dom.ico -------------------------------------------------------------------------------- /Examples/JavaScript/js.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dliw/fpCEF3/HEAD/Examples/JavaScript/js.ico -------------------------------------------------------------------------------- /Examples/OSRDemo/osrdemo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dliw/fpCEF3/HEAD/Examples/OSRDemo/osrdemo.ico -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | backup/ 2 | lib/ 3 | *.lps 4 | *.[oa] 5 | *.exe 6 | *.res 7 | .directory 8 | gmon.out 9 | ppas.sh -------------------------------------------------------------------------------- /Examples/LCLSimple/simple.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dliw/fpCEF3/HEAD/Examples/LCLSimple/simple.ico -------------------------------------------------------------------------------- /Examples/LCLCefClient/client.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dliw/fpCEF3/HEAD/Examples/LCLCefClient/client.ico -------------------------------------------------------------------------------- /Examples/JavaScript/js.lpr: -------------------------------------------------------------------------------- 1 | Program js; 2 | 3 | {$MODE objfpc}{$H+} 4 | 5 | Uses 6 | {$IFDEF UNIX} 7 | cthreads, 8 | {$ENDIF} 9 | Interfaces, // this includes the LCL widgetset 10 | Forms, Main; 11 | 12 | {$R *.res} 13 | 14 | begin 15 | RequireDerivedFormResource := True; 16 | Application.Initialize; 17 | Application.CreateForm(TMainform, Mainform); 18 | Application.Run; 19 | end. 20 | 21 | -------------------------------------------------------------------------------- /Examples/OSRDemo/osrdemo.lpr: -------------------------------------------------------------------------------- 1 | Program osrdemo; 2 | 3 | {$MODE objfpc}{$H+} 4 | 5 | Uses 6 | {$IFDEF UNIX} 7 | cthreads, 8 | {$ENDIF} 9 | Interfaces, // this includes the LCL widgetset 10 | Forms, lazopenglcontext, Main; 11 | 12 | {$R *.res} 13 | 14 | begin 15 | RequireDerivedFormResource := True; 16 | Application.Initialize; 17 | Application.CreateForm(TMainform, Mainform); 18 | Application.Run; 19 | end. 20 | 21 | -------------------------------------------------------------------------------- /Examples/DOMAccess/dom.lpr: -------------------------------------------------------------------------------- 1 | Program dom; 2 | 3 | {$MODE objfpc}{$H+} 4 | 5 | Uses 6 | {$IFDEF UNIX} 7 | cthreads, 8 | {$ENDIF} 9 | Interfaces, // this includes the LCL widgetset 10 | Forms, Main, handler; 11 | 12 | {$R *.res} 13 | 14 | begin 15 | Application.Title := 'DOMAccess'; 16 | RequireDerivedFormResource := True; 17 | Application.Initialize; 18 | Application.CreateForm(TMainform, Mainform); 19 | Application.Run; 20 | end. 21 | 22 | -------------------------------------------------------------------------------- /Examples/LCLCefClient/client.lpr: -------------------------------------------------------------------------------- 1 | program client; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | Uses 6 | {$IFDEF UNIX}cthreads,{$ENDIF} 7 | Interfaces, // this includes the LCL widgetset 8 | Forms, Main; 9 | 10 | {$R *.res} 11 | 12 | begin 13 | RequireDerivedFormResource := True; 14 | {$IFDEF WINDOWS} 15 | Application.MainFormOnTaskBar := True; 16 | {$ENDIF} 17 | Application.Initialize; 18 | Application.CreateForm(TFMain, FMain); 19 | Application.Run; 20 | end. 21 | -------------------------------------------------------------------------------- /Examples/SubProcess/subprocess.lpr: -------------------------------------------------------------------------------- 1 | Program subprocess; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | Uses 6 | {$IFDEF UNIX} 7 | cthreads, 8 | {$ENDIF} 9 | cef3types, cef3api; 10 | 11 | Var 12 | Args : TCefMainArgs; 13 | 14 | begin 15 | CefLoadLibrary; 16 | 17 | {$IFDEF WINDOWS} 18 | Args.instance := HINSTANCE(); 19 | 20 | Halt(cef_execute_process(@Args, nil, nil)); 21 | {$ELSE} 22 | Args.argc := argc; 23 | Args.argv := argv; 24 | 25 | Halt(cef_execute_process(@Args, nil, nil)); 26 | {$ENDIF} 27 | end. 28 | 29 | -------------------------------------------------------------------------------- /Examples/LCLSimple/simple.lpr: -------------------------------------------------------------------------------- 1 | Program simple; 2 | 3 | {$MODE objfpc}{$H+} 4 | 5 | Uses 6 | {$IFDEF UNIX} 7 | cthreads, 8 | {$ENDIF} 9 | Interfaces, // this includes the LCL widgetset 10 | Forms, Main; 11 | 12 | {$R *.res} 13 | 14 | begin 15 | RequireDerivedFormResource := True; 16 | Application.Title := 'Simple'; 17 | {$IFDEF WINDOWS} 18 | Application.MainFormOnTaskBar := True; 19 | {$ENDIF} 20 | Application.Initialize; 21 | Application.CreateForm(TMainform, Mainform); 22 | Application.Run; 23 | end. 24 | 25 | -------------------------------------------------------------------------------- /Component/cef3.pas: -------------------------------------------------------------------------------- 1 | { This file was automatically created by Lazarus. Do not edit! 2 | This source is only used to compile and install the package. 3 | } 4 | 5 | unit CEF3; 6 | 7 | interface 8 | 9 | uses 10 | cef3types, cef3api, cef3lib, cef3intf, cef3ref, cef3own, cef3gui, cef3lcl, cef3osr, cef3context, 11 | cef3scp, LazarusPackageIntf; 12 | 13 | implementation 14 | 15 | procedure Register; 16 | begin 17 | RegisterUnit('cef3lcl', @cef3lcl.Register); 18 | RegisterUnit('cef3osr', @cef3osr.Register); 19 | RegisterUnit('cef3context', @cef3context.Register); 20 | end; 21 | 22 | initialization 23 | RegisterPackage('CEF3', @Register); 24 | end. 25 | -------------------------------------------------------------------------------- /Examples/LCLCefClient/printhandler.pas: -------------------------------------------------------------------------------- 1 | Unit PrintHandler; 2 | 3 | {$MODE objfpc}{$H+} 4 | 5 | Interface 6 | 7 | Uses 8 | Classes, SysUtils, 9 | cef3types, cef3own; 10 | 11 | Type 12 | { custom print handler } 13 | 14 | // only printing to PDF is implemented on Linux at the moment 15 | // for a complete printing support, the print handler needs to be fully implemented 16 | 17 | TCustomPrintHandler = class(TCefPrintHandlerOwn) 18 | protected 19 | function GetPdfPaperSize(DeviceUnitsPerInch: Integer): TCefSize; override; 20 | end; 21 | 22 | Implementation 23 | 24 | { TCustomPrintHandler } 25 | function TCustomPrintHandler.GetPdfPaperSize(DeviceUnitsPerInch: Integer): TCefSize; 26 | Var 27 | Size: TCefSize; 28 | begin 29 | // Use A4 size: width=8.267in, heigth=11.692in 30 | 31 | Size.width := Round(DeviceUnitsPerInch * 8.267); 32 | Size.height := Round(DeviceUnitsPerInch * 11.692); 33 | 34 | Result := Size; 35 | end; 36 | 37 | 38 | end. 39 | 40 | -------------------------------------------------------------------------------- /Examples/Examples.md: -------------------------------------------------------------------------------- 1 | # DOMAccess 2 | Shows how to access DOM and transfer data between main process and render processes. 3 | 4 | Thanks to zbyna for sharing his findings: 5 | http://forum.lazarus.freepascal.org/index.php/topic,20103.msg149867.html#msg149867 6 | 7 | # GTK2Minimal 8 | Minimal gtk2 example, doesn't use LCL and classes, direct use of the CEF3 API. 9 | 10 | # WinMinimal 11 | Windows counterpart to the gtk2 example. 12 | 13 | # JavaScript 14 | Shows interaction with JavaScript. 15 | 16 | Thanks to stacho for sharing: 17 | http://www.lazarusforum.de/viewtopic.php?p=70126#p70134 18 | 19 | # LCLCefClient 20 | Tabbed browser demonstrating various functionality: 21 | - Tab handling 22 | - Getting favicons for browsed pages (thanks to Doriano Blengino for providing his code) 23 | 24 | # LCLSimple 25 | Simple LCL example to get started. 26 | 27 | # OSRDemo 28 | Basic example on how to use TChromiumOSR. 29 | 30 | # SubProcess 31 | Minimal subprocess, can be used as is as long as no custom render handler is needed. 32 | -------------------------------------------------------------------------------- /cef.inc: -------------------------------------------------------------------------------- 1 | (* 2 | * Free Pascal Chromium Embedded 3 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, 6 | * You can obtain one at http://mozilla.org/MPL/2.0/. 7 | * 8 | * Author: dev.dliw@gmail.com 9 | * Repository: https://github.com/dliw/fpCEF3 10 | * 11 | * 12 | * Originally based on 'Delphi Chromium Embedded 3' by Henri Gourvest 13 | * 14 | * 15 | * Embarcadero Technologies, Inc is not permitted to use or redistribute 16 | * this source code without explicit permission. 17 | * 18 | *) 19 | 20 | {.$DEFINE DEBUG} 21 | 22 | // Don't change this, unless you know, what you are doing 23 | {$DEFINE CEF_STRING_TYPE_UTF16} 24 | 25 | {.$DEFINE CEF_STRING_TYPE_UTF8} 26 | {.$DEFINE CEF_STRING_TYPE_WIDE} 27 | 28 | {.$DEFINE CEF_MULTI_THREADED_MESSAGE_LOOP} 29 | {$DEFINE SUPPORTS_INLINE} 30 | 31 | // calling convention 32 | {$MACRO ON} 33 | {$IFDEF WINDOWS} 34 | {$DEFINE cconv:=stdcall} 35 | {$ELSE} 36 | {$DEFINE cconv:=cdecl} 37 | {$ENDIF} 38 | 39 | 40 | // Sanity check 41 | {$IFDEF CEF_MULTI_THREADED_MESSAGE_LOOP} 42 | {$IFNDEF WINDOWS} 43 | {$ERROR CEF doesn't support the mulithreaded message loop on systems other than Windows} 44 | {$ENDIF} 45 | {$ENDIF} 46 | -------------------------------------------------------------------------------- /Examples/SubProcess/subprocess.app/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | subprocess 9 | CFBundleName 10 | subprocess 11 | CFBundleIdentifier 12 | com.company.subprocess 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundlePackageType 16 | APPL 17 | CFBundleSignature 18 | subp 19 | CFBundleShortVersionString 20 | 0.1 21 | CFBundleVersion 22 | 1 23 | CSResourcesFileMapped 24 | 25 | CFBundleDocumentTypes 26 | 27 | 28 | CFBundleTypeRole 29 | Viewer 30 | CFBundleTypeExtensions 31 | 32 | * 33 | 34 | CFBundleTypeOSTypes 35 | 36 | fold 37 | disk 38 | **** 39 | 40 | 41 | 42 | NSHighResolutionCapable 43 | 44 | LSUIElement 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Examples/LCLSimple/simple.app/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | simple 9 | CFBundleName 10 | Simple 11 | CFBundleIdentifier 12 | com.company.simple 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundlePackageType 16 | APPL 17 | CFBundleSignature 18 | simp 19 | CFBundleShortVersionString 20 | 0.1 21 | CFBundleVersion 22 | 1 23 | CSResourcesFileMapped 24 | 25 | CFBundleDocumentTypes 26 | 27 | 28 | CFBundleTypeRole 29 | Viewer 30 | CFBundleTypeExtensions 31 | 32 | * 33 | 34 | CFBundleTypeOSTypes 35 | 36 | fold 37 | disk 38 | **** 39 | 40 | 41 | 42 | NSHighResolutionCapable 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Examples/OSRDemo/osrdemo.app/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | osrdemo 9 | CFBundleName 10 | osrdemo 11 | CFBundleIdentifier 12 | com.company.osrdemo 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundlePackageType 16 | APPL 17 | CFBundleSignature 18 | osrd 19 | CFBundleShortVersionString 20 | 0.1 21 | CFBundleVersion 22 | 1 23 | CSResourcesFileMapped 24 | 25 | CFBundleDocumentTypes 26 | 27 | 28 | CFBundleTypeRole 29 | Viewer 30 | CFBundleTypeExtensions 31 | 32 | * 33 | 34 | CFBundleTypeOSTypes 35 | 36 | fold 37 | disk 38 | **** 39 | 40 | 41 | 42 | NSHighResolutionCapable 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Examples/DOMAccess/handler.pas: -------------------------------------------------------------------------------- 1 | Unit Handler; 2 | 3 | {$MODE objfpc}{$H+} 4 | 5 | (* 6 | * Everything in here is called from a render process, so there is no access to GUI and all the 7 | * data of the main process. 8 | *) 9 | 10 | Interface 11 | 12 | Uses 13 | Classes, SysUtils, 14 | cef3types, cef3intf, cef3ref, cef3own; 15 | 16 | Type 17 | { Custom handler for the render process } 18 | TCustomRenderProcessHandler = class(TCefRenderProcessHandlerOwn) 19 | protected 20 | function OnProcessMessageReceived(const browser: ICefBrowser; sourceProcess: TCefProcessId; 21 | const message: ICefProcessMessage): Boolean; override; 22 | end; 23 | 24 | Implementation 25 | 26 | Var 27 | // Don't access outside of callbacks 28 | // Enables access to browser in callbacks, necessary unless nestedprocvars is used 29 | ActiveBrowser: ICefBrowser; 30 | 31 | procedure visitDOM(const document: ICefDomDocument); 32 | Var 33 | message: ICefProcessMessage; 34 | begin 35 | message := TCefProcessMessageRef.New('domdata'); 36 | With message.ArgumentList do 37 | begin 38 | SetString(0, document.GetTitle); 39 | SetBool(1, document.HasSelection); 40 | SetString(2, document.GetSelectionAsText); 41 | end; 42 | 43 | ActiveBrowser.SendProcessMessage(PID_BROWSER, message); 44 | end; 45 | 46 | { TCustomRenderProcessHandler } 47 | 48 | function TCustomRenderProcessHandler.OnProcessMessageReceived(const browser : ICefBrowser; 49 | sourceProcess : TCefProcessId; const message : ICefProcessMessage) : Boolean; 50 | begin 51 | ActiveBrowser := browser; 52 | Case message.Name of 53 | 'visitdom': 54 | begin 55 | browser.FocusedFrame.VisitDomProc(@visitDOM); 56 | Result := True; 57 | end; 58 | Else 59 | Result := inherited; 60 | end; 61 | end; 62 | 63 | end. 64 | 65 | -------------------------------------------------------------------------------- /cef3scp.pas: -------------------------------------------------------------------------------- 1 | (* 2 | * Free Pascal Chromium Embedded 3 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, 6 | * You can obtain one at http://mozilla.org/MPL/2.0/. 7 | * 8 | * Author: dev.dliw@gmail.com 9 | * Repository: https://github.com/dliw/fpCEF3 10 | *) 11 | 12 | Unit cef3scp; 13 | 14 | {$MODE objfpc}{$H+} 15 | 16 | {$I cef.inc} 17 | 18 | Interface 19 | 20 | Uses 21 | Classes, SysUtils, 22 | cef3api, cef3types; 23 | 24 | Type 25 | TCefBaseScopedRef = class 26 | private 27 | fData: Pointer; 28 | public 29 | constructor Create(data: Pointer); virtual; 30 | function Wrap: Pointer; 31 | end; 32 | 33 | TCefSchemeRegistrarRef = class(TCefBaseScopedRef) 34 | public 35 | function AddCustomScheme(const schemeName: ustring; 36 | isStandard, isLocal, isDisplayIsolated, isSecure, isCorsEnabled, isCspBypassing: Boolean): Boolean; 37 | end; 38 | 39 | implementation 40 | 41 | Uses cef3lib; 42 | 43 | { TCefBaseScopedRef } 44 | 45 | constructor TCefBaseScopedRef.Create(data: Pointer); 46 | begin 47 | Assert(data <> nil); 48 | fData := data; 49 | end; 50 | 51 | function TCefBaseScopedRef.Wrap: Pointer; 52 | begin 53 | Result := fData; 54 | end; 55 | 56 | { TCefSchemeRegistrarRef } 57 | 58 | function TCefSchemeRegistrarRef.AddCustomScheme(const schemeName: ustring; 59 | isStandard, isLocal, isDisplayIsolated, isSecure, isCorsEnabled, isCspBypassing: Boolean): Boolean; 60 | Var 61 | s : TCefString; 62 | begin 63 | s := CefString(schemeName); 64 | Result := PCefSchemeRegistrar(fData)^.add_custom_scheme(fData, @s, Ord(isStandard), Ord(isLocal), 65 | Ord(isDisplayIsolated), Ord(isSecure), Ord(isCorsEnabled), Ord(isCspBypassing)) <> 0; 66 | end; 67 | 68 | end. 69 | 70 | -------------------------------------------------------------------------------- /Examples/LCLSimple/main.lfm: -------------------------------------------------------------------------------- 1 | object Mainform: TMainform 2 | Left = 521 3 | Height = 476 4 | Top = 284 5 | Width = 810 6 | Caption = 'Browser -' 7 | ClientHeight = 476 8 | ClientWidth = 810 9 | DesignTimePPI = 94 10 | OnCloseQuery = FormCloseQuery 11 | LCLVersion = '1.8.2.0' 12 | object BGo: TButton 13 | AnchorSideTop.Control = Owner 14 | AnchorSideRight.Control = Owner 15 | AnchorSideRight.Side = asrBottom 16 | Left = 726 17 | Height = 25 18 | Top = 10 19 | Width = 79 20 | Anchors = [akTop, akRight] 21 | BorderSpacing.Top = 10 22 | BorderSpacing.Right = 5 23 | Caption = 'Go' 24 | OnClick = BGoClick 25 | TabOrder = 1 26 | end 27 | object LUrl: TStaticText 28 | AnchorSideTop.Control = Owner 29 | Left = 8 30 | Height = 22 31 | Top = 12 32 | Width = 25 33 | BorderSpacing.Top = 12 34 | Caption = 'Url:' 35 | TabOrder = 2 36 | end 37 | object EUrl: TEdit 38 | AnchorSideLeft.Control = LUrl 39 | AnchorSideLeft.Side = asrBottom 40 | AnchorSideTop.Control = Owner 41 | AnchorSideRight.Control = BGo 42 | Left = 38 43 | Height = 25 44 | Top = 10 45 | Width = 683 46 | Anchors = [akTop, akLeft, akRight] 47 | AutoSize = False 48 | BorderSpacing.Left = 5 49 | BorderSpacing.Top = 10 50 | BorderSpacing.Right = 5 51 | OnKeyDown = EUrlKeyDown 52 | TabOrder = 0 53 | Text = 'http://' 54 | end 55 | object Chromium: TChromium 56 | AnchorSideLeft.Control = Owner 57 | AnchorSideTop.Side = asrBottom 58 | AnchorSideRight.Control = Owner 59 | AnchorSideRight.Side = asrBottom 60 | AnchorSideBottom.Control = Owner 61 | AnchorSideBottom.Side = asrBottom 62 | Left = 0 63 | Height = 428 64 | Top = 48 65 | Width = 810 66 | TabStop = True 67 | Anchors = [akTop, akLeft, akRight, akBottom] 68 | TabOrder = 3 69 | OnTitleChange = ChromiumTitleChange 70 | OnTakeFocus = ChromiumTakeFocus 71 | OnBeforeUnloadDialog = ChromiumBeforeUnloadDialog 72 | OnBeforeClose = ChromiumBeforeClose 73 | OnLoadEnd = ChromiumLoadEnd 74 | DefaultUrl = 'about:blank' 75 | end 76 | end 77 | -------------------------------------------------------------------------------- /Examples/DOMAccess/main.lfm: -------------------------------------------------------------------------------- 1 | object Mainform: TMainform 2 | Left = 482 3 | Height = 587 4 | Top = 207 5 | Width = 921 6 | Anchors = [] 7 | Caption = 'Browser -' 8 | ClientHeight = 587 9 | ClientWidth = 921 10 | OnCreate = FormCreate 11 | LCLVersion = '1.6.4.0' 12 | object BGo: TButton 13 | AnchorSideTop.Control = Owner 14 | AnchorSideRight.Control = Owner 15 | AnchorSideRight.Side = asrBottom 16 | Left = 837 17 | Height = 25 18 | Top = 10 19 | Width = 79 20 | Anchors = [akTop, akRight] 21 | BorderSpacing.Top = 10 22 | BorderSpacing.Right = 5 23 | Caption = 'Go' 24 | OnClick = BGoClick 25 | TabOrder = 2 26 | end 27 | object LUrl: TStaticText 28 | AnchorSideTop.Control = Owner 29 | Left = 8 30 | Height = 22 31 | Top = 12 32 | Width = 25 33 | BorderSpacing.Top = 12 34 | Caption = 'Url:' 35 | Font.Style = [fsBold] 36 | ParentFont = False 37 | TabOrder = 0 38 | end 39 | object EUrl: TEdit 40 | AnchorSideLeft.Control = LUrl 41 | AnchorSideLeft.Side = asrBottom 42 | AnchorSideTop.Control = Owner 43 | AnchorSideRight.Control = BGo 44 | Left = 38 45 | Height = 25 46 | Top = 10 47 | Width = 794 48 | Anchors = [akTop, akLeft, akRight] 49 | AutoSize = False 50 | BorderSpacing.Left = 5 51 | BorderSpacing.Top = 10 52 | BorderSpacing.Right = 5 53 | OnKeyDown = EUrlKeyDown 54 | TabOrder = 1 55 | Text = 'http://' 56 | end 57 | object Log: TMemo 58 | AnchorSideLeft.Control = Owner 59 | AnchorSideRight.Control = Owner 60 | AnchorSideRight.Side = asrBottom 61 | AnchorSideBottom.Control = Owner 62 | AnchorSideBottom.Side = asrBottom 63 | Left = 0 64 | Height = 139 65 | Top = 448 66 | Width = 921 67 | Anchors = [akLeft, akRight, akBottom] 68 | ScrollBars = ssAutoVertical 69 | ReadOnly = True 70 | TabOrder = 4 71 | TabStop = False 72 | end 73 | object Chromium: TChromium 74 | AnchorSideLeft.Control = Owner 75 | AnchorSideTop.Side = asrBottom 76 | AnchorSideRight.Control = Owner 77 | AnchorSideRight.Side = asrBottom 78 | AnchorSideBottom.Control = Log 79 | Left = 0 80 | Height = 400 81 | Top = 48 82 | Width = 921 83 | TabStop = True 84 | Anchors = [akTop, akLeft, akRight, akBottom] 85 | TabOrder = 3 86 | OnProcessMessageReceived = ChromiumProcessMessageReceived 87 | OnTitleChange = ChromiumTitleChange 88 | OnKeyEvent = ChromiumKeyEvent 89 | OnLoadEnd = ChromiumLoadEnd 90 | DefaultUrl = 'https://github.com/dliw/fpCEF3' 91 | end 92 | end 93 | -------------------------------------------------------------------------------- /Examples/GTK2Minimal/minimal.lpi: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | <UseAppBundle Value="False"/> 14 | <ResourceType Value="res"/> 15 | </General> 16 | <i18n> 17 | <EnableI18N LFM="False"/> 18 | </i18n> 19 | <VersionInfo> 20 | <StringTable ProductVersion=""/> 21 | </VersionInfo> 22 | <BuildModes Count="1"> 23 | <Item1 Name="Default" Default="True"/> 24 | </BuildModes> 25 | <PublishOptions> 26 | <Version Value="2"/> 27 | <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> 28 | <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/> 29 | </PublishOptions> 30 | <RunParams> 31 | <local> 32 | <FormatVersion Value="1"/> 33 | </local> 34 | <environment> 35 | <UserOverrides Count="1"> 36 | <Variable0 Name="LD_LIBRARY_PATH" Value="."/> 37 | </UserOverrides> 38 | </environment> 39 | </RunParams> 40 | <RequiredPackages Count="1"> 41 | <Item1> 42 | <PackageName Value="CEF3"/> 43 | </Item1> 44 | </RequiredPackages> 45 | <Units Count="1"> 46 | <Unit0> 47 | <Filename Value="minimal.lpr"/> 48 | <IsPartOfProject Value="True"/> 49 | </Unit0> 50 | </Units> 51 | </ProjectOptions> 52 | <CompilerOptions> 53 | <Version Value="11"/> 54 | <Target> 55 | <Filename Value="minimal"/> 56 | </Target> 57 | <SearchPaths> 58 | <IncludeFiles Value="$(ProjOutDir)"/> 59 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 60 | </SearchPaths> 61 | <Parsing> 62 | <SyntaxOptions> 63 | <AllowLabel Value="False"/> 64 | </SyntaxOptions> 65 | </Parsing> 66 | <CodeGeneration> 67 | <TargetCPU Value="x86_64"/> 68 | <TargetOS Value="linux"/> 69 | </CodeGeneration> 70 | <Linking> 71 | <Options> 72 | <Win32> 73 | <GraphicApplication Value="True"/> 74 | </Win32> 75 | </Options> 76 | </Linking> 77 | </CompilerOptions> 78 | <Debugging> 79 | <Exceptions Count="3"> 80 | <Item1> 81 | <Name Value="EAbort"/> 82 | </Item1> 83 | <Item2> 84 | <Name Value="ECodetoolError"/> 85 | </Item2> 86 | <Item3> 87 | <Name Value="EFOpenError"/> 88 | </Item3> 89 | </Exceptions> 90 | </Debugging> 91 | </CONFIG> 92 | -------------------------------------------------------------------------------- /Examples/LCLCefClient/schemehandler.pas: -------------------------------------------------------------------------------- 1 | Unit SchemeHandler; 2 | 3 | {$MODE objfpc}{$H+} 4 | 5 | Interface 6 | 7 | Uses 8 | Classes, SysUtils, 9 | cef3types, cef3intf, cef3own; 10 | 11 | Type 12 | { custom scheme handler } 13 | 14 | TCustomScheme = class(TCefResourceHandlerOwn) 15 | private 16 | fData: TMemoryStream; 17 | fStatus: Integer; 18 | fStatusText: ustring; 19 | fMimeType: ustring; 20 | protected 21 | function ProcessRequest(const request: ICefRequest; const callback: ICefCallback): Boolean; override; 22 | procedure GetResponseHeaders(const response: ICefResponse; out responseLength: Int64; 23 | out redirectUrl: ustring); override; 24 | function ReadResponse(const dataOut: Pointer; bytesToRead: Integer; var bytesRead: Integer; 25 | const callback: ICefCallback): Boolean; override; 26 | public 27 | constructor Create(const browser: ICefBrowser; const frame: ICefFrame; 28 | const schemeName: ustring; const request: ICefRequest); override; 29 | destructor Destroy; override; 30 | end; 31 | 32 | Implementation 33 | 34 | { TCustomScheme } 35 | function TCustomScheme.ProcessRequest(const request: ICefRequest; 36 | const callback: ICefCallback): Boolean; 37 | Var 38 | Output: String; 39 | begin 40 | Result := True; 41 | 42 | fStatus := 200; 43 | fStatusText := 'OK'; 44 | fMimeType := 'text/html'; 45 | 46 | Output := UTF8Encode( 47 | '<!doctype html><html><head><meta charset="UTF-8"><title>Welcome' + 48 | '

Welcome to the LCLCefClient

fpCEF @ Github' 49 | ); 50 | 51 | fData.Clear; 52 | fData.Write(Output[1], Length(Output)); 53 | fData.Seek(0, soFromBeginning); 54 | 55 | callback.Cont; 56 | end; 57 | 58 | procedure TCustomScheme.GetResponseHeaders(const response: ICefResponse; out responseLength: Int64; 59 | out redirectUrl: ustring); 60 | begin 61 | response.Status := fStatus; 62 | response.StatusText := fStatusText; 63 | response.MimeType := fMimeType; 64 | 65 | responseLength := fData.Size; 66 | end; 67 | 68 | function TCustomScheme.ReadResponse(const dataOut: Pointer; bytesToRead: Integer; 69 | var bytesRead: Integer; const callback: ICefCallback): Boolean; 70 | begin 71 | bytesRead := fData.Read(dataOut^, bytesToRead); 72 | Result := True; 73 | end; 74 | 75 | constructor TCustomScheme.Create(const browser: ICefBrowser; const frame: ICefFrame; 76 | const schemeName: ustring; const request: ICefRequest); 77 | begin 78 | inherited; 79 | 80 | fData := TMemoryStream.Create; 81 | end; 82 | 83 | destructor TCustomScheme.Destroy; 84 | begin 85 | FreeAndNil(fData); 86 | 87 | inherited; 88 | end; 89 | 90 | end. 91 | 92 | -------------------------------------------------------------------------------- /Examples/JavaScript/handler.pas: -------------------------------------------------------------------------------- 1 | Unit Handler; 2 | 3 | {$MODE objfpc}{$H+} 4 | 5 | (* 6 | * Everything in here is called from a render process, so there is no access to GUI and all the 7 | * data of the main process. 8 | *) 9 | 10 | Interface 11 | 12 | Uses 13 | Classes, SysUtils, 14 | cef3types, cef3intf, cef3ref, cef3own, cef3lib; 15 | 16 | Type 17 | { Custom handler for the render process } 18 | TCustomRenderProcessHandler = class(TCefRenderProcessHandlerOwn) 19 | protected 20 | // Test Window Bindings 21 | procedure OnContextCreated(const browser: ICefBrowser; const frame: ICefFrame; const context: ICefv8Context); override; 22 | // Test Extension 23 | procedure OnWebKitInitialized; override; 24 | end; 25 | 26 | TMyHandler = class(TCefv8HandlerOwn) 27 | protected 28 | function Execute(const name: ustring; const obj: ICefv8Value; 29 | const arguments: ICefv8ValueArray; var retval: ICefv8Value; 30 | var exception: ustring): Boolean; override; 31 | end; 32 | 33 | Implementation 34 | 35 | Var 36 | mystr : String; 37 | 38 | { TMyHandler } 39 | 40 | function TMyHandler.Execute(const name : ustring; const obj : ICefv8Value; 41 | const arguments : ICefv8ValueArray; var retval : ICefv8Value; 42 | var exception : ustring) : Boolean; 43 | begin 44 | // return a value 45 | retval := TCefv8ValueRef.NewString( 46 | 'Handler called for function ' + name + '(#args = ' + IntToStr(Length(arguments)) + ')'); 47 | 48 | Result := True; 49 | end; 50 | 51 | { TCustomRenderProcessHandler } 52 | 53 | procedure TCustomRenderProcessHandler.OnContextCreated(const browser : ICefBrowser; 54 | const frame : ICefFrame; const context : ICefv8Context); 55 | Var 56 | myWin : ICefv8Value; 57 | args : ICefv8ValueArray; 58 | begin 59 | myWin := context.GetGlobal; 60 | mystr := 'a test string'; 61 | SetLength(args, 1); 62 | args[0] := TCefv8ValueRef.NewString(mystr); 63 | myWin.SetValueByKey('myval', args[0], []); 64 | end; 65 | 66 | procedure TCustomRenderProcessHandler.OnWebKitInitialized; 67 | Var 68 | Code: ustring; 69 | begin 70 | Code := 71 | 'var cef;'+ 72 | 'if (!cef)'+ 73 | ' cef = {};'+ 74 | 'if (!cef.test)'+ 75 | ' cef.test = {};'+ 76 | '(function() {'+ 77 | ' cef.test.__defineGetter__(''test_param'', function() {'+ 78 | ' native function GetTestParam();'+ 79 | ' return GetTestParam();'+ 80 | ' });'+ 81 | ' cef.test.__defineSetter__(''test_param'', function(b) {'+ 82 | ' native function SetTestParam();'+ 83 | ' if(b) SetTestParam(b);'+ 84 | ' });'+ 85 | ' cef.test.test_object = function() {'+ 86 | ' native function GetTestObject();'+ 87 | ' return GetTestObject();'+ 88 | ' };'+ 89 | '})();'; 90 | 91 | CefRegisterExtension('example/v8', Code, TMyHandler.Create as ICefv8Handler); 92 | end; 93 | 94 | end. 95 | 96 | -------------------------------------------------------------------------------- /Examples/LCLCefClient/favicongetter.pas: -------------------------------------------------------------------------------- 1 | Unit FaviconGetter; 2 | 3 | {$MODE objfpc}{$H+} 4 | 5 | Interface 6 | 7 | Uses 8 | Classes, SysUtils, Graphics, 9 | cef3types, cef3intf, cef3ref, cef3own, cef3lib; 10 | 11 | Type 12 | TIconReady = procedure(const Success: Boolean; const Icon: TIcon) of object; 13 | 14 | TFaviconGetter = class(TCefUrlrequestClientOwn) 15 | private 16 | fCallback: TIconReady; 17 | fStream: TMemoryStream; 18 | fExt: String; 19 | fUrlRequest: ICefUrlRequest; 20 | protected 21 | procedure OnDownloadData(const request: ICefUrlRequest; data: Pointer; dataLength: TSize); override; 22 | procedure OnRequestComplete(const request: ICefUrlRequest); override; 23 | public 24 | constructor Create(Url: String; Callback: TIconReady); reintroduce; 25 | 26 | procedure Cancel; 27 | end; 28 | 29 | Implementation 30 | 31 | { TFaviconGetter } 32 | 33 | procedure TFaviconGetter.OnDownloadData(const request: ICefUrlRequest; data: Pointer; 34 | dataLength: TSize); 35 | begin 36 | If Assigned(fCallback) then fStream.WriteBuffer(data^, dataLength); 37 | end; 38 | 39 | // In a real world application this would be the place to handle different file formats 40 | // and to resize the image appropriately 41 | procedure TFaviconGetter.OnRequestComplete(const request: ICefUrlRequest); 42 | Var 43 | Picture: TPicture; 44 | begin 45 | fUrlRequest := nil; 46 | 47 | If Assigned(fCallback) then 48 | begin 49 | If request.GetRequestStatus = UR_SUCCESS then 50 | begin 51 | fStream.Position := 0; 52 | 53 | try 54 | // Load the icon ... 55 | Picture := TPicture.Create; 56 | Picture.LoadFromStreamWithFileExt(fStream, fExt); 57 | 58 | // ... and add it to the TabIcons image list 59 | fCallback(True, Picture.Icon); 60 | except 61 | // Catch any exception 62 | // Broken things are easy to encounter on the internet, therefore robustness is very important 63 | On E: Exception do fCallback(False, nil); 64 | end; 65 | 66 | Picture.Free; 67 | end 68 | Else fCallback(False, nil); 69 | end; 70 | 71 | fStream.Free; 72 | end; 73 | 74 | constructor TFaviconGetter.Create(Url: String; Callback: TIconReady); 75 | Var 76 | Request: ICefRequest; 77 | begin 78 | inherited Create; 79 | 80 | fCallback := Callback; 81 | fStream := TMemoryStream.Create; 82 | 83 | // remember the file type for later 84 | fExt := ExtractFileExt(Url); 85 | 86 | // Set the data for the request ... 87 | Request := TCefRequestRef.New; 88 | Request.Url := Url; 89 | 90 | // ... and start the url request. The request client is FaviconGetter itself. 91 | fUrlRequest := TCefUrlRequestRef.New(Request, Self, nil); 92 | end; 93 | 94 | procedure TFaviconGetter.Cancel; 95 | begin 96 | // disable callback and cancel request 97 | fCallback := nil; 98 | If Assigned(fUrlRequest) then fUrlRequest.Cancel; 99 | end; 100 | 101 | end. 102 | 103 | -------------------------------------------------------------------------------- /Examples/LCLCefClient/main.lfm: -------------------------------------------------------------------------------- 1 | object FMain: TFMain 2 | Left = 566 3 | Height = 533 4 | Top = 347 5 | Width = 1201 6 | Caption = 'LCLCefClient' 7 | ClientHeight = 533 8 | ClientWidth = 1201 9 | DesignTimePPI = 94 10 | OnCloseQuery = FormCloseQuery 11 | LCLVersion = '1.8.2.0' 12 | object LUrl: TStaticText 13 | AnchorSideTop.Control = Owner 14 | Left = 8 15 | Height = 22 16 | Top = 12 17 | Width = 25 18 | BorderSpacing.Top = 12 19 | Caption = 'Url:' 20 | TabOrder = 0 21 | end 22 | object EUrl: TEdit 23 | AnchorSideLeft.Control = LUrl 24 | AnchorSideLeft.Side = asrBottom 25 | AnchorSideTop.Control = Owner 26 | AnchorSideRight.Control = BGo 27 | Left = 38 28 | Height = 25 29 | Top = 10 30 | Width = 995 31 | Anchors = [akTop, akLeft, akRight] 32 | AutoSize = False 33 | BorderSpacing.Left = 5 34 | BorderSpacing.Top = 10 35 | BorderSpacing.Right = 5 36 | OnKeyDown = EUrlKeyDown 37 | TabOrder = 1 38 | Text = 'http://' 39 | end 40 | object BGo: TButton 41 | AnchorSideTop.Control = Owner 42 | AnchorSideRight.Control = BNewTab 43 | Left = 1038 44 | Height = 25 45 | Top = 10 46 | Width = 79 47 | Anchors = [akTop, akRight] 48 | BorderSpacing.Top = 10 49 | BorderSpacing.Right = 5 50 | Caption = 'Go' 51 | OnClick = BGoClick 52 | TabOrder = 2 53 | end 54 | object Tabs: TPageControl 55 | AnchorSideLeft.Control = Owner 56 | AnchorSideTop.Control = EUrl 57 | AnchorSideTop.Side = asrBottom 58 | AnchorSideRight.Control = Owner 59 | AnchorSideRight.Side = asrBottom 60 | AnchorSideBottom.Control = Owner 61 | AnchorSideBottom.Side = asrBottom 62 | Left = 0 63 | Height = 488 64 | Top = 45 65 | Width = 1201 66 | Anchors = [akTop, akLeft, akRight, akBottom] 67 | BorderSpacing.Top = 10 68 | Images = TabIcons 69 | TabOrder = 5 70 | OnChange = TabsChange 71 | end 72 | object BNewTab: TButton 73 | AnchorSideTop.Control = Owner 74 | AnchorSideRight.Control = BCloseTab 75 | Left = 1122 76 | Height = 25 77 | Top = 10 78 | Width = 32 79 | Anchors = [akTop, akRight] 80 | BorderSpacing.Top = 10 81 | BorderSpacing.Right = 5 82 | Caption = '+' 83 | OnClick = BNewTabClick 84 | TabOrder = 3 85 | end 86 | object BCloseTab: TButton 87 | AnchorSideTop.Control = Owner 88 | AnchorSideRight.Control = Owner 89 | AnchorSideRight.Side = asrBottom 90 | Left = 1159 91 | Height = 25 92 | Top = 10 93 | Width = 32 94 | Anchors = [akTop, akRight] 95 | BorderSpacing.Top = 10 96 | BorderSpacing.Right = 10 97 | Caption = '-' 98 | Enabled = False 99 | OnClick = BCloseTabClick 100 | TabOrder = 4 101 | end 102 | object TabIcons: TImageList 103 | left = 1152 104 | top = 48 105 | end 106 | object SaveFile: TSaveDialog 107 | left = 1152 108 | top = 88 109 | end 110 | object OpenFile: TOpenDialog 111 | left = 1120 112 | top = 88 113 | end 114 | object OpenFolder: TSelectDirectoryDialog 115 | left = 1088 116 | top = 88 117 | end 118 | end 119 | -------------------------------------------------------------------------------- /Examples/JavaScript/main.lfm: -------------------------------------------------------------------------------- 1 | object Mainform: TMainform 2 | Left = 683 3 | Height = 587 4 | Top = 180 5 | Width = 921 6 | Anchors = [] 7 | Caption = 'Browser -' 8 | ClientHeight = 587 9 | ClientWidth = 921 10 | OnCreate = FormCreate 11 | LCLVersion = '1.6.4.0' 12 | object BGo: TButton 13 | AnchorSideTop.Control = Owner 14 | AnchorSideRight.Control = Owner 15 | AnchorSideRight.Side = asrBottom 16 | Left = 837 17 | Height = 25 18 | Top = 10 19 | Width = 79 20 | Anchors = [akTop, akRight] 21 | BorderSpacing.Top = 10 22 | BorderSpacing.Right = 5 23 | Caption = 'Go' 24 | OnClick = BGoClick 25 | TabOrder = 2 26 | end 27 | object LUrl: TStaticText 28 | AnchorSideTop.Control = Owner 29 | Left = 8 30 | Height = 22 31 | Top = 12 32 | Width = 25 33 | BorderSpacing.Top = 12 34 | Caption = 'Url:' 35 | Font.Style = [fsBold] 36 | ParentFont = False 37 | TabOrder = 0 38 | end 39 | object EUrl: TEdit 40 | AnchorSideLeft.Control = LUrl 41 | AnchorSideLeft.Side = asrBottom 42 | AnchorSideTop.Control = Owner 43 | AnchorSideRight.Control = BGo 44 | Left = 38 45 | Height = 25 46 | Top = 10 47 | Width = 794 48 | Anchors = [akTop, akLeft, akRight] 49 | AutoSize = False 50 | BorderSpacing.Left = 5 51 | BorderSpacing.Top = 10 52 | BorderSpacing.Right = 5 53 | OnKeyDown = EUrlKeyDown 54 | TabOrder = 1 55 | Text = 'http://' 56 | end 57 | object Chromium: TChromium 58 | AnchorSideLeft.Control = Owner 59 | AnchorSideTop.Side = asrBottom 60 | AnchorSideRight.Control = Owner 61 | AnchorSideRight.Side = asrBottom 62 | AnchorSideBottom.Control = Log 63 | Left = 0 64 | Height = 368 65 | Top = 80 66 | Width = 921 67 | Anchors = [akTop, akLeft, akRight, akBottom] 68 | TabOrder = 6 69 | OnTitleChange = ChromiumTitleChange 70 | OnJsdialog = ChromiumJsdialog 71 | DefaultUrl = 'example.com' 72 | end 73 | object Log: TMemo 74 | AnchorSideLeft.Control = Owner 75 | AnchorSideRight.Control = Owner 76 | AnchorSideRight.Side = asrBottom 77 | AnchorSideBottom.Control = Owner 78 | AnchorSideBottom.Side = asrBottom 79 | Left = 0 80 | Height = 139 81 | Top = 448 82 | Width = 921 83 | Anchors = [akLeft, akRight, akBottom] 84 | ReadOnly = True 85 | ScrollBars = ssAutoVertical 86 | TabOrder = 7 87 | TabStop = False 88 | end 89 | object Button1: TButton 90 | Left = 38 91 | Height = 25 92 | Top = 48 93 | Width = 180 94 | Caption = 'Load about:blank' 95 | OnClick = Button1Click 96 | TabOrder = 3 97 | end 98 | object Button2: TButton 99 | AnchorSideLeft.Control = Button1 100 | AnchorSideLeft.Side = asrBottom 101 | Left = 223 102 | Height = 25 103 | Top = 48 104 | Width = 180 105 | BorderSpacing.Left = 5 106 | Caption = 'alert(window.myval)' 107 | OnClick = Button2Click 108 | TabOrder = 4 109 | end 110 | object Button3: TButton 111 | AnchorSideLeft.Control = Button2 112 | AnchorSideLeft.Side = asrBottom 113 | Left = 408 114 | Height = 25 115 | Top = 48 116 | Width = 180 117 | BorderSpacing.Left = 5 118 | Caption = 'alert(cef.test.test_param)' 119 | OnClick = Button3Click 120 | TabOrder = 5 121 | end 122 | end 123 | -------------------------------------------------------------------------------- /Examples/LCLSimple/main.pas: -------------------------------------------------------------------------------- 1 | Unit Main; 2 | 3 | {$MODE objfpc}{$H+} 4 | 5 | Interface 6 | 7 | Uses 8 | Classes, SysUtils, FileUtil, Forms, Controls, Dialogs, StdCtrls, LCLType, 9 | cef3types, cef3lib, cef3intf, cef3lcl; 10 | 11 | Type 12 | 13 | { TMainform } 14 | 15 | TMainform = class(TForm) 16 | BGo: TButton; 17 | Chromium: TChromium; 18 | EUrl: TEdit; 19 | LUrl: TStaticText; 20 | procedure BGoClick(Sender: TObject); 21 | procedure ChromiumBeforeClose(Sender: TObject; const Browser: ICefBrowser); 22 | procedure ChromiumBeforeUnloadDialog(Sender: TObject; const Browser: ICefBrowser; 23 | const messageText: ustring; isReload: Boolean; const callback: ICefJsDialogCallback; 24 | out Result: Boolean); 25 | procedure ChromiumLoadEnd(Sender: TObject; const Browser: ICefBrowser; const Frame: ICefFrame; 26 | httpStatusCode: Integer); 27 | procedure ChromiumTakeFocus(Sender: TObject; const Browser: ICefBrowser; next_: Boolean); 28 | procedure ChromiumTitleChange(Sender: TObject; const Browser: ICefBrowser; const title: ustring); 29 | procedure EUrlKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); 30 | procedure FormCloseQuery(Sender: TObject; var CanClose: boolean); 31 | private 32 | { private declarations } 33 | public 34 | { public declarations } 35 | end; 36 | 37 | Var 38 | Mainform : TMainform; 39 | 40 | Implementation 41 | 42 | {$R *.lfm} 43 | 44 | { TMainform } 45 | 46 | procedure TMainform.BGoClick(Sender: TObject); 47 | begin 48 | Chromium.Load(EUrl.Text); 49 | end; 50 | 51 | procedure TMainform.ChromiumBeforeClose(Sender: TObject; const Browser: ICefBrowser); 52 | begin 53 | Halt; 54 | end; 55 | 56 | procedure TMainform.ChromiumBeforeUnloadDialog(Sender: TObject; const Browser: ICefBrowser; 57 | const messageText: ustring; isReload: Boolean; const callback: ICefJsDialogCallback; 58 | out Result: Boolean); 59 | Var 60 | AllowClose: Boolean; 61 | begin 62 | // use custom dialog 63 | Result := True; 64 | 65 | // show dialog 66 | AllowClose := MessageDlg('Confirmation', messageText, mtConfirmation, [mbYes,mbNo], 0) = mrYes; 67 | 68 | // execute callback 69 | callback.Cont(AllowClose, ''); 70 | end; 71 | 72 | procedure TMainform.ChromiumLoadEnd(Sender: TObject; const Browser: ICefBrowser; const Frame: ICefFrame; 73 | httpStatusCode: Integer); 74 | begin 75 | EUrl.Text := UTF8Encode(Browser.MainFrame.Url); 76 | end; 77 | 78 | procedure TMainform.ChromiumTakeFocus(Sender: TObject; const Browser: ICefBrowser; next_: Boolean); 79 | begin 80 | SelectNext(ActiveControl, next_, True); 81 | end; 82 | 83 | procedure TMainform.ChromiumTitleChange(Sender: TObject; const Browser: ICefBrowser; const title: ustring); 84 | begin 85 | Caption := 'Browser - ' + UTF8Encode(title); 86 | end; 87 | 88 | procedure TMainform.EUrlKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); 89 | begin 90 | If Key = VK_RETURN then BGoClick(Sender); 91 | end; 92 | 93 | procedure TMainform.FormCloseQuery(Sender: TObject; var CanClose: boolean); 94 | begin 95 | CanClose := Chromium.Browser.Host.TryCloseBrowser; 96 | end; 97 | 98 | 99 | Initialization 100 | {$IFNDEF DARWIN} 101 | {$INFO subprocess is set here, uncomment to use a subprocess} 102 | //CefBrowserSubprocessPath := '.' + PathDelim + 'subprocess'{$IFDEF WINDOWS}+'.exe'{$ENDIF}; 103 | {$ENDIF} 104 | 105 | end. 106 | -------------------------------------------------------------------------------- /Examples/LCLCefClient/client.lpi: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | <ResourceType Value="res"/> 10 | <UseXPManifest Value="True"/> 11 | <Icon Value="0"/> 12 | </General> 13 | <i18n> 14 | <EnableI18N LFM="False"/> 15 | </i18n> 16 | <BuildModes Count="1"> 17 | <Item1 Name="Default" Default="True"/> 18 | </BuildModes> 19 | <PublishOptions> 20 | <Version Value="2"/> 21 | </PublishOptions> 22 | <RunParams> 23 | <local> 24 | <FormatVersion Value="1"/> 25 | </local> 26 | <environment> 27 | <UserOverrides Count="1"> 28 | <Variable0 Name="LD_LIBRARY_PATH" Value="."/> 29 | </UserOverrides> 30 | </environment> 31 | </RunParams> 32 | <RequiredPackages Count="2"> 33 | <Item1> 34 | <PackageName Value="CEF3"/> 35 | </Item1> 36 | <Item2> 37 | <PackageName Value="LCL"/> 38 | </Item2> 39 | </RequiredPackages> 40 | <Units Count="6"> 41 | <Unit0> 42 | <Filename Value="client.lpr"/> 43 | <IsPartOfProject Value="True"/> 44 | </Unit0> 45 | <Unit1> 46 | <Filename Value="main.pas"/> 47 | <IsPartOfProject Value="True"/> 48 | <ComponentName Value="FMain"/> 49 | <HasResources Value="True"/> 50 | <ResourceBaseClass Value="Form"/> 51 | <UnitName Value="Main"/> 52 | </Unit1> 53 | <Unit2> 54 | <Filename Value="webpanel.pas"/> 55 | <IsPartOfProject Value="True"/> 56 | <UnitName Value="WebPanel"/> 57 | </Unit2> 58 | <Unit3> 59 | <Filename Value="favicongetter.pas"/> 60 | <IsPartOfProject Value="True"/> 61 | <UnitName Value="FaviconGetter"/> 62 | </Unit3> 63 | <Unit4> 64 | <Filename Value="printhandler.pas"/> 65 | <IsPartOfProject Value="True"/> 66 | <UnitName Value="PrintHandler"/> 67 | </Unit4> 68 | <Unit5> 69 | <Filename Value="schemehandler.pas"/> 70 | <IsPartOfProject Value="True"/> 71 | <UnitName Value="SchemeHandler"/> 72 | </Unit5> 73 | </Units> 74 | </ProjectOptions> 75 | <CompilerOptions> 76 | <Version Value="11"/> 77 | <Target> 78 | <Filename Value="client"/> 79 | </Target> 80 | <SearchPaths> 81 | <IncludeFiles Value="$(ProjOutDir)"/> 82 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 83 | </SearchPaths> 84 | <Parsing> 85 | <SyntaxOptions> 86 | <IncludeAssertionCode Value="True"/> 87 | </SyntaxOptions> 88 | </Parsing> 89 | <Linking> 90 | <Options> 91 | <Win32> 92 | <GraphicApplication Value="True"/> 93 | </Win32> 94 | </Options> 95 | </Linking> 96 | </CompilerOptions> 97 | <Debugging> 98 | <Exceptions Count="4"> 99 | <Item1> 100 | <Name Value="EAbort"/> 101 | </Item1> 102 | <Item2> 103 | <Name Value="ECodetoolError"/> 104 | </Item2> 105 | <Item3> 106 | <Name Value="EFOpenError"/> 107 | </Item3> 108 | <Item4> 109 | <Name Value="EInvalidGraphic"/> 110 | </Item4> 111 | </Exceptions> 112 | </Debugging> 113 | </CONFIG> 114 | -------------------------------------------------------------------------------- /Examples/JavaScript/main.pas: -------------------------------------------------------------------------------- 1 | Unit Main; 2 | 3 | {$MODE objfpc}{$H+} 4 | 5 | Interface 6 | 7 | Uses 8 | Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, LCLType, ExtCtrls, 9 | cef3types, cef3lib, cef3intf, cef3lcl, 10 | Handler; // custom render process handler 11 | 12 | Type 13 | 14 | { TMainform } 15 | 16 | TMainform = class(TForm) 17 | BGo : TButton; 18 | Button1 : TButton; 19 | Button2 : TButton; 20 | Button3 : TButton; 21 | Chromium : TChromium; 22 | EUrl : TEdit; 23 | LUrl : TStaticText; 24 | Log : TMemo; 25 | procedure BGoClick(Sender : TObject); 26 | procedure Button1Click(Sender : TObject); 27 | procedure Button2Click(Sender : TObject); 28 | procedure Button3Click(Sender : TObject); 29 | procedure ChromiumJsdialog(Sender: TObject; const Browser: ICefBrowser; 30 | const originUrl: ustring; dialogType: TCefJsDialogType; 31 | const messageText, defaultPromptText: ustring; callback: ICefJsDialogCallback; 32 | out suppressMessage: Boolean; out Result: Boolean); 33 | procedure ChromiumTitleChange(Sender : TObject; const Browser : ICefBrowser; 34 | const title : ustring); 35 | procedure EUrlKeyDown(Sender : TObject; var Key : Word; Shift : TShiftState); 36 | procedure FormCreate(Sender : TObject); 37 | private 38 | { private declarations } 39 | public 40 | { public declarations } 41 | end; 42 | 43 | Var 44 | Mainform : TMainform; 45 | 46 | Implementation 47 | 48 | {$R *.lfm} 49 | 50 | { TMainform } 51 | 52 | procedure TMainform.BGoClick(Sender: TObject); 53 | begin 54 | Chromium.Load(EUrl.Text); 55 | end; 56 | 57 | procedure TMainform.Button1Click(Sender: TObject); 58 | begin 59 | Chromium.Load('about:blank'); 60 | end; 61 | 62 | // JavaScript shows value of window.myval 63 | procedure TMainform.Button2Click(Sender: TObject); 64 | begin 65 | Chromium.Browser.MainFrame.ExecuteJavaScript('alert(window.myval);', 'about:blank', 0); 66 | end; 67 | 68 | // JavaScript executes TMyHandler.Execute 69 | procedure TMainform.Button3Click(Sender: TObject); 70 | begin 71 | Chromium.Browser.MainFrame.ExecuteJavaScript('alert(cef.test.test_param);', 'about:blank', 0); 72 | end; 73 | 74 | procedure TMainform.ChromiumJsdialog(Sender: TObject; const Browser: ICefBrowser; 75 | const originUrl: ustring; dialogType: TCefJsDialogType; 76 | const messageText, defaultPromptText: ustring; callback: ICefJsDialogCallback; 77 | out suppressMessage: Boolean; out Result: Boolean); 78 | begin 79 | If dialogType = JSDIALOGTYPE_ALERT then 80 | begin 81 | ShowMessage('JavaScript alert:' + LineEnding + messageText); 82 | callback.Cont(True, ''); 83 | Result := True; 84 | end 85 | Else Result := False; 86 | 87 | suppressMessage := False; 88 | end; 89 | 90 | procedure TMainform.ChromiumTitleChange(Sender: TObject; const Browser: ICefBrowser; const title: ustring); 91 | begin 92 | Caption := 'Browser - ' + UTF8Encode(title); 93 | end; 94 | 95 | procedure TMainform.EUrlKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); 96 | begin 97 | If Key = VK_RETURN then BGoClick(Sender); 98 | end; 99 | 100 | procedure TMainform.FormCreate(Sender: TObject); 101 | begin 102 | // No subprocess here 103 | // If you want to use a subprocess, this CefRenderProcessHandler has to be registered in subprocess 104 | CefRenderProcessHandler := TCustomRenderProcessHandler.Create; 105 | end; 106 | 107 | end. 108 | -------------------------------------------------------------------------------- /Examples/OSRDemo/main.lfm: -------------------------------------------------------------------------------- 1 | object Mainform: TMainform 2 | Left = 643 3 | Height = 475 4 | Top = 320 5 | Width = 762 6 | Caption = 'Browser -' 7 | ClientHeight = 475 8 | ClientWidth = 762 9 | DesignTimePPI = 94 10 | OnCreate = FormCreate 11 | OnDestroy = FormDestroy 12 | LCLVersion = '1.8.2.0' 13 | object BGo: TButton 14 | AnchorSideTop.Control = Owner 15 | AnchorSideRight.Control = Owner 16 | AnchorSideRight.Side = asrBottom 17 | Left = 678 18 | Height = 25 19 | Top = 10 20 | Width = 79 21 | Anchors = [akTop, akRight] 22 | BorderSpacing.Top = 10 23 | BorderSpacing.Right = 5 24 | Caption = 'Go' 25 | OnClick = BGoClick 26 | TabOrder = 0 27 | end 28 | object LUrl: TStaticText 29 | AnchorSideTop.Control = Owner 30 | Left = 8 31 | Height = 22 32 | Top = 12 33 | Width = 25 34 | BorderSpacing.Top = 12 35 | Caption = 'Url:' 36 | Font.Style = [fsBold] 37 | ParentFont = False 38 | TabOrder = 1 39 | end 40 | object EUrl: TEdit 41 | AnchorSideLeft.Control = LUrl 42 | AnchorSideLeft.Side = asrBottom 43 | AnchorSideTop.Control = Owner 44 | AnchorSideRight.Control = BGo 45 | Left = 38 46 | Height = 25 47 | Top = 10 48 | Width = 635 49 | Anchors = [akTop, akLeft, akRight] 50 | AutoSize = False 51 | BorderSpacing.Left = 5 52 | BorderSpacing.Top = 10 53 | BorderSpacing.Right = 5 54 | OnKeyDown = EUrlKeyDown 55 | TabOrder = 2 56 | Text = 'http://' 57 | end 58 | object OSRPanel: TOpenGLControl 59 | AnchorSideLeft.Control = Owner 60 | AnchorSideTop.Control = EUrl 61 | AnchorSideTop.Side = asrBottom 62 | AnchorSideRight.Control = Owner 63 | AnchorSideRight.Side = asrBottom 64 | AnchorSideBottom.Control = CBAnimate 65 | Left = 0 66 | Height = 404 67 | Top = 40 68 | Width = 762 69 | Anchors = [akTop, akLeft, akRight, akBottom] 70 | BorderSpacing.Top = 5 71 | BorderSpacing.Bottom = 5 72 | OnEnter = OSRPanelEnter 73 | OnExit = OSRPanelExit 74 | OnMouseDown = OSRPanelMouseDown 75 | OnMouseMove = OSRPanelMouseMove 76 | OnMouseUp = OSRPanelMouseUp 77 | OnMouseWheel = OSRPanelMouseWheel 78 | OnPaint = OSRPanelPaint 79 | OnResize = OSRPanelResize 80 | end 81 | object CBAnimate: TCheckBox 82 | AnchorSideLeft.Control = LUrl 83 | AnchorSideBottom.Control = Owner 84 | AnchorSideBottom.Side = asrBottom 85 | Left = 8 86 | Height = 26 87 | Top = 449 88 | Width = 74 89 | Anchors = [akLeft, akBottom] 90 | Caption = 'animate' 91 | Checked = True 92 | OnChange = CBAnimateChange 93 | State = cbChecked 94 | TabOrder = 4 95 | end 96 | object CBShowUpdate: TCheckBox 97 | AnchorSideLeft.Control = CBAnimate 98 | AnchorSideLeft.Side = asrBottom 99 | AnchorSideBottom.Control = Owner 100 | AnchorSideBottom.Side = asrBottom 101 | Left = 92 102 | Height = 26 103 | Top = 449 104 | Width = 103 105 | Anchors = [akLeft, akBottom] 106 | BorderSpacing.Left = 10 107 | Caption = 'show update' 108 | TabOrder = 5 109 | end 110 | object Chromium: TChromiumOSR 111 | OnGetViewRect = ChromiumGetViewRect 112 | OnGetScreenPoint = ChromiumGetScreenPoint 113 | OnPaint = ChromiumPaint 114 | DefaultUrl = 'https://github.com/dliw/fpCEF3' 115 | WindowlessFrameRate = 30 116 | BackgroundColor = clWhite 117 | left = 8 118 | top = 40 119 | end 120 | end 121 | -------------------------------------------------------------------------------- /Examples/DOMAccess/main.pas: -------------------------------------------------------------------------------- 1 | Unit Main; 2 | 3 | {$MODE objfpc}{$H+} 4 | 5 | Interface 6 | 7 | Uses 8 | Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, LCLType, ExtCtrls, 9 | cef3types, cef3lib, cef3intf, cef3ref, cef3lcl, 10 | Handler; // custom render process handler 11 | 12 | Type 13 | 14 | { TMainform } 15 | 16 | TMainform = class(TForm) 17 | BGo : TButton; 18 | Chromium : TChromium; 19 | EUrl : TEdit; 20 | LUrl : TStaticText; 21 | Log : TMemo; 22 | procedure BGoClick(Sender : TObject); 23 | procedure ChromiumKeyEvent(Sender : TObject; const Browser : ICefBrowser; 24 | const event : PCefKeyEvent; osEvent : TCefEventHandle; out Result : Boolean); 25 | procedure ChromiumLoadEnd(Sender : TObject; const Browser : ICefBrowser; 26 | const Frame : ICefFrame; httpStatusCode : Integer); 27 | procedure ChromiumProcessMessageReceived(Sender : TObject; 28 | const Browser : ICefBrowser; sourceProcess : TCefProcessId; 29 | const message : ICefProcessMessage; out Result : Boolean); 30 | procedure ChromiumTitleChange(Sender : TObject; const Browser : ICefBrowser; 31 | const title : ustring); 32 | procedure EUrlKeyDown(Sender : TObject; var Key : Word; Shift : TShiftState); 33 | procedure FormCreate(Sender : TObject); 34 | private 35 | { private declarations } 36 | public 37 | { public declarations } 38 | end; 39 | 40 | Var 41 | Mainform : TMainform; 42 | 43 | Implementation 44 | 45 | {$R *.lfm} 46 | 47 | { TMainform } 48 | 49 | procedure TMainform.BGoClick(Sender : TObject); 50 | begin 51 | Chromium.Load(EUrl.Text); 52 | end; 53 | 54 | procedure TMainform.ChromiumKeyEvent(Sender: TObject; const Browser: ICefBrowser; 55 | const event: PCefKeyEvent; osEvent: TCefEventHandle; out Result: Boolean); 56 | begin 57 | If event^.kind = KEYEVENT_KEYUP then 58 | begin 59 | If Browser.SendProcessMessage(PID_RENDERER,TCefProcessMessageRef.New('visitdom')) then 60 | Log.Append('Triggered DOM visit.') 61 | Else Log.Append('Failed to start DOM visit.'); 62 | 63 | Result := True; 64 | end; 65 | end; 66 | 67 | procedure TMainform.ChromiumLoadEnd(Sender : TObject; const Browser : ICefBrowser; const Frame : ICefFrame; 68 | httpStatusCode : Integer); 69 | begin 70 | EUrl.Text := UTF8Encode(Browser.MainFrame.Url); 71 | end; 72 | 73 | procedure TMainform.ChromiumProcessMessageReceived(Sender : TObject; 74 | const Browser : ICefBrowser; sourceProcess : TCefProcessId; 75 | const message : ICefProcessMessage; out Result : Boolean); 76 | begin 77 | Case message.Name of 78 | 'domdata': 79 | begin 80 | With message.ArgumentList do 81 | begin 82 | Log.Append('Title: ' + GetString(0)); 83 | Log.Append('HasSelection: ' + BoolToStr(GetBool(1), True)); 84 | Log.Append('Selection: ' + GetString(2)); 85 | end; 86 | Result := True; 87 | end; 88 | Else 89 | Log.Append('Unhandled message: ' + message.Name); 90 | inherited; 91 | end; 92 | end; 93 | 94 | procedure TMainform.ChromiumTitleChange(Sender : TObject; const Browser : ICefBrowser; const title : ustring); 95 | begin 96 | Caption := 'Browser - ' + UTF8Encode(title); 97 | end; 98 | 99 | procedure TMainform.EUrlKeyDown(Sender : TObject; var Key : Word; Shift : TShiftState); 100 | begin 101 | If Key = VK_RETURN then BGoClick(Sender); 102 | end; 103 | 104 | procedure TMainform.FormCreate(Sender : TObject); 105 | begin 106 | // No subprocess here 107 | // If you want to use a subprocess, this CefRenderProcessHandler has to be registered in subprocess 108 | CefRenderProcessHandler := TCustomRenderProcessHandler.Create; 109 | 110 | Log.Append('Press any key to get DOM data...'); 111 | end; 112 | 113 | end. 114 | -------------------------------------------------------------------------------- /Component/cef3.lpk: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <CONFIG> 3 | <Package Version="4"> 4 | <Name Value="CEF3"/> 5 | <Type Value="RunAndDesignTime"/> 6 | <Author Value="dliw <dev.dliw@gmail.com>"/> 7 | <CompilerOptions> 8 | <Version Value="11"/> 9 | <SearchPaths> 10 | <IncludeFiles Value=".."/> 11 | <OtherUnitFiles Value=".."/> 12 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 13 | </SearchPaths> 14 | <Parsing> 15 | <SyntaxOptions> 16 | <AllowLabel Value="False"/> 17 | </SyntaxOptions> 18 | </Parsing> 19 | <CodeGeneration> 20 | <SmartLinkUnit Value="True"/> 21 | <Optimizations> 22 | <OptimizationLevel Value="3"/> 23 | </Optimizations> 24 | </CodeGeneration> 25 | <Linking> 26 | <Debugging> 27 | <GenerateDebugInfo Value="False"/> 28 | </Debugging> 29 | </Linking> 30 | <Other> 31 | <CompilerMessages> 32 | <IgnoredMessages idx5024="True"/> 33 | </CompilerMessages> 34 | </Other> 35 | </CompilerOptions> 36 | <Description Value="Chromium component for Lazarus"/> 37 | <Version Major="3" Minor="3029" Release="1"/> 38 | <Files Count="13"> 39 | <Item1> 40 | <Filename Value="../cef.inc"/> 41 | <Type Value="Include"/> 42 | </Item1> 43 | <Item2> 44 | <Filename Value="../cef3types.pas"/> 45 | <UnitName Value="cef3types"/> 46 | </Item2> 47 | <Item3> 48 | <Filename Value="../cef3api.pas"/> 49 | <UnitName Value="cef3api"/> 50 | </Item3> 51 | <Item4> 52 | <Filename Value="../cef3lib.pas"/> 53 | <UnitName Value="cef3lib"/> 54 | </Item4> 55 | <Item5> 56 | <Filename Value="../cef3intf.pas"/> 57 | <UnitName Value="cef3intf"/> 58 | </Item5> 59 | <Item6> 60 | <Filename Value="../cef3ref.pas"/> 61 | <UnitName Value="cef3ref"/> 62 | </Item6> 63 | <Item7> 64 | <Filename Value="../cef3own.pas"/> 65 | <UnitName Value="cef3own"/> 66 | </Item7> 67 | <Item8> 68 | <Filename Value="../cef3gui.pas"/> 69 | <UnitName Value="cef3gui"/> 70 | </Item8> 71 | <Item9> 72 | <Filename Value="cef3lcl.pas"/> 73 | <HasRegisterProc Value="True"/> 74 | <UnitName Value="cef3lcl"/> 75 | </Item9> 76 | <Item10> 77 | <Filename Value="cef3osr.pas"/> 78 | <HasRegisterProc Value="True"/> 79 | <UnitName Value="cef3osr"/> 80 | </Item10> 81 | <Item11> 82 | <Filename Value="cef3context.pas"/> 83 | <HasRegisterProc Value="True"/> 84 | <UnitName Value="cef3context"/> 85 | </Item11> 86 | <Item12> 87 | <Filename Value="cef3cocoa.pas"/> 88 | <AddToUsesPkgSection Value="False"/> 89 | <UnitName Value="cef3cocoa"/> 90 | </Item12> 91 | <Item13> 92 | <Filename Value="../cef3scp.pas"/> 93 | <UnitName Value="cef3scp"/> 94 | </Item13> 95 | </Files> 96 | <RequiredPkgs Count="3"> 97 | <Item1> 98 | <PackageName Value="LCL"/> 99 | <MinVersion Major="1" Minor="4" Valid="True"/> 100 | </Item1> 101 | <Item2> 102 | <PackageName Value="LCLBase"/> 103 | </Item2> 104 | <Item3> 105 | <PackageName Value="FCL"/> 106 | </Item3> 107 | </RequiredPkgs> 108 | <UsageOptions> 109 | <CustomOptions Value="-dUseCThreads"/> 110 | <UnitPath Value="$(PkgOutDir)"/> 111 | </UsageOptions> 112 | <PublishOptions> 113 | <Version Value="2"/> 114 | </PublishOptions> 115 | <CustomOptions Items="ExternHelp" Version="2"> 116 | <_ExternHelp Items="Count"/> 117 | </CustomOptions> 118 | </Package> 119 | </CONFIG> 120 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | fpCEF3 2 | ====== 3 | 4 | Chromium Embedded Framework for Free Pascal 5 | 6 | ## How to get started 7 | 8 | - Install `cef3.lpk` into Lazarus 9 | - [Download CEF3][1] (standard or minimal distribution). Make sure to use the correct CEF3 version (see the changelog / release tag); other versions (older or newer) usually don't work and are *not* recommended 10 | - Create a new project or use one of the projects in the `Examples` folder. `LCLSimple` is a good starting point 11 | - Read the following section on how to correctly set up the file layout 12 | 13 | 14 | **Important**: 15 | Most examples use [build modes](http://wiki.freepascal.org/IDE_Window:_Compiler_Options#Selecting_the_active_build_mode). Make sure to select the correct one, otherwise compilation will fail. 16 | 17 | 18 | ## CEF setup 19 | 20 | ### macOS 21 | Follow the instructions on the [wiki][wiki-macos]. 22 | 23 | 24 | ### Windows and Linux 25 | A CEF package contains 26 | - the CEF library itself and related binaries in the `Release` or `Debug` folder and 27 | - resources in the `Resources` folder. 28 | 29 | By default CEF expects the library and binaries in `PATH` (Windows) or `LD_LIBRARY_PATH` (Linux) and the the resources in the same folder as the executable. A custom path for the library can be set using `CefLibraryDirPath`. The path for the resources can be changed by setting `CefResourcesDirPath` and `CefLocalesDirPath`. However, __some files cannot be moved__: 30 | 31 | #### Windows 32 | - `chrome_elf.dll` has to be in `PATH` or the same folder as the executable 33 | - `icudtl.dat` has to be in `PATH` 34 | 35 | #### Linux 36 | - `icudtl.dat` and `*_blob.bin` have to be in the same folder as the executable 37 | 38 | **Important**: 39 | Make sure to include `cthreads` as the first unit in your main program. 40 | If you build CEF3 yourself make sure `tcmalloc` is disabled. 41 | 42 | 43 | ## Hints 44 | Don't use `--single-process` or change `CefSingleProcess` to `True`. This mode is not officially supported by Chromium. 45 | 46 | If the browser goes "blank" (e.g. when loading a page), the render process crashed. See **Debugging** on how to debug the render process. The render process restarts automatically on the next page request. 47 | 48 | 49 | ### SubProcess 50 | If CEF is initialized a subprocess is started. By default a second instance of the main program is used as the subprocess. Nevertheless, the preferred way is to define an own (minimal) subprocess executable. In fpCEF3 this can be done by setting `CefBrowserSubprocessPath` to the **path** of the subprocess executable. In the `LCLSimple` example this setting can be found in the `Initialization` section at the end of `main.pas`. 51 | 52 | A minimal subprocess can be found in the folder `/Examples/SubProcess`. The subprocess also needs the CEF3 library and resources in its path, so it is recommended to put the subprocess executable in the same folder as the main exe. 53 | More details can be found [here][5]. 54 | 55 | ### Debugging 56 | Sometimes it is useful to debug the subprocesses spawned by cef. On Linux this can be done by adding 57 | ```shell 58 | --renderer-cmd-prefix='xterm -title renderer -e gdb --args' 59 | ``` 60 | to the command line. 61 | Further details can be found [here][6]. 62 | 63 | 64 | ### Supported platforms 65 | - Windows 66 | - Linux (Gtk2 or Qt4) 67 | - macOS (Cocoa) 68 | 69 | 70 | ### Documentation 71 | 72 | You can find comments and usage information in 73 | 74 | - cef3lib.pas / cef3api.pas 75 | - the example projects in the `Examples` folder 76 | - the official api docs [here][2] 77 | - the official cefclient example program [here][3] 78 | 79 | 80 | ## Links: 81 | * [Chromium Embedded Framework](https://bitbucket.org/chromiumembedded/cef) 82 | * [Delphi CEF](https://github.com/hgourvest/dcef3) 83 | 84 | * [fpCEF3](http://github.com/dliw/fpCEF3) 85 | 86 | [![Donate](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/dliw/donate) 87 | 88 | [wiki-macos]:https://github.com/dliw/fpCEF3/wiki/macOS 89 | [1]:http://www.magpcss.net/cef_downloads 90 | [2]:http://magpcss.org/ceforum/apidocs3/ 91 | [3]:https://bitbucket.org/chromiumembedded/cef/src/936e595fe5e9aa5e7641abf72e1f872f9d0ceb73/tests/cefclient/?at=master 92 | [5]:https://bitbucket.org/chromiumembedded/cef/wiki/Architecture#markdown-header-cef3 93 | [6]:https://chromium.googlesource.com/chromium/src/+/master/docs/linux_debugging.md 94 | -------------------------------------------------------------------------------- /Examples/LCLCefClient/main.pas: -------------------------------------------------------------------------------- 1 | Unit Main; 2 | 3 | {$MODE objfpc}{$H+} 4 | 5 | Interface 6 | 7 | Uses 8 | Classes, SysUtils, Forms, Controls, StdCtrls, ComCtrls, LCLType, Menus, Dialogs, 9 | WebPanel; 10 | 11 | Type 12 | TFMain = class(TForm) 13 | BGo: TButton; 14 | BNewTab: TButton; 15 | BCloseTab: TButton; 16 | EUrl: TEdit; 17 | OpenFile: TOpenDialog; 18 | SaveFile: TSaveDialog; 19 | OpenFolder: TSelectDirectoryDialog; 20 | TabIcons: TImageList; 21 | LUrl: TStaticText; 22 | Tabs: TPageControl; 23 | procedure BCloseTabClick(Sender: TObject); 24 | procedure BGoClick(Sender: TObject); 25 | procedure BNewTabClick(Sender: TObject); 26 | procedure EUrlKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); 27 | procedure FormCloseQuery(Sender: TObject; var CanClose: boolean); 28 | procedure TabsChange(Sender: TObject); 29 | private 30 | fCloseRequested: Boolean; 31 | fCloseAllowed: Boolean; 32 | 33 | procedure AddTab(First: Boolean = False); 34 | procedure TabAfterClose(const Index: Integer); 35 | procedure TabCloseStopped(Sender: TObject); 36 | protected 37 | procedure DoFirstShow; override; 38 | public 39 | procedure NewTab(const Url: String); 40 | end; 41 | 42 | Var 43 | FMain: TFMain; 44 | 45 | Implementation 46 | 47 | {$R *.lfm} 48 | 49 | { TFMain } 50 | 51 | procedure TFMain.FormCloseQuery(Sender: TObject; var CanClose: boolean); 52 | begin 53 | If fCloseAllowed then CanClose := True 54 | Else 55 | begin 56 | fCloseRequested := True; 57 | CanClose := False; 58 | 59 | // start closing tabs 60 | (Tabs.Page[Tabs.PageCount-1] as TWebPanel).RequestClose; 61 | end; 62 | end; 63 | 64 | procedure TFMain.DoFirstShow; 65 | begin 66 | fCloseRequested := False; 67 | fCloseAllowed := False; 68 | 69 | AddTab(True); 70 | end; 71 | 72 | procedure TFMain.TabsChange(Sender: TObject); 73 | begin 74 | EUrl.Text := (Tabs.ActivePage as TWebPanel).Url; 75 | end; 76 | 77 | procedure TFMain.BGoClick(Sender: TObject); 78 | begin 79 | (Tabs.ActivePage as TWebPanel).OpenUrl(EUrl.Text); 80 | end; 81 | 82 | procedure TFMain.BCloseTabClick(Sender: TObject); 83 | begin 84 | (Tabs.ActivePage as TWebPanel).RequestClose; 85 | end; 86 | 87 | procedure TFMain.BNewTabClick(Sender: TObject); 88 | begin 89 | AddTab; 90 | end; 91 | 92 | procedure TFMain.EUrlKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); 93 | begin 94 | If Key = VK_RETURN then BGoClick(Sender); 95 | end; 96 | 97 | procedure TFMain.AddTab(First: Boolean); 98 | Var 99 | TabSheet: TWebPanel; 100 | begin 101 | TabSheet := TWebPanel.Create(Tabs); 102 | TabSheet.Parent := Tabs; 103 | TabSheet.Caption := 'New Tab'; 104 | TabSheet.OnClose := @TabAfterClose; 105 | TabSheet.OnCloseStopped := @TabCloseStopped; 106 | 107 | // Create a dummy tab icon (could be a loading indicator) until we get the real one 108 | TabIcons.AddIcon(Application.Icon); 109 | 110 | Tabs.ActivePageIndex := TabSheet.PageIndex; 111 | 112 | If First then TabSheet.InitializeChromium('fpcef://') 113 | Else TabSheet.InitializeChromium; 114 | 115 | If Tabs.PageCount > 1 then BCloseTab.Enabled := True; 116 | end; 117 | 118 | procedure TFMain.TabAfterClose(const Index: Integer); 119 | Var 120 | i: Integer; 121 | begin 122 | // delete tab icon 123 | TabIcons.Delete(Index); 124 | 125 | // adjust tab icon indices 126 | For i := 0 to Tabs.PageCount - 1 do 127 | begin 128 | With Tabs.Pages[i] do 129 | If ImageIndex <> -1 then ImageIndex := TabIndex; 130 | end; 131 | Tabs.Repaint; 132 | 133 | If fCloseRequested then 134 | begin 135 | If Tabs.PageCount = 0 then 136 | begin 137 | // terminate application if all tabs are closed 138 | Halt; 139 | end 140 | Else 141 | begin 142 | Application.ProcessMessages; 143 | 144 | // continue closing tabs 145 | (Tabs.Page[Tabs.PageCount-1] as TWebPanel).RequestClose; 146 | end 147 | end 148 | Else 149 | begin 150 | // last tab cannot be closed 151 | If Tabs.PageCount < 2 then BCloseTab.Enabled := False; 152 | end; 153 | end; 154 | 155 | procedure TFMain.TabCloseStopped(Sender: TObject); 156 | begin 157 | fCloseRequested := False; 158 | end; 159 | 160 | procedure TFMain.NewTab(const Url: String); 161 | begin 162 | AddTab; 163 | (Tabs.ActivePage as TWebPanel).OpenUrl(Url); 164 | end; 165 | 166 | end. 167 | -------------------------------------------------------------------------------- /Examples/WinMinimal/minimal.lpi: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <CONFIG> 3 | <ProjectOptions> 4 | <Version Value="9"/> 5 | <General> 6 | <Flags> 7 | <MainUnitHasUsesSectionForAllUnits Value="False"/> 8 | <MainUnitHasCreateFormStatements Value="False"/> 9 | <MainUnitHasTitleStatement Value="False"/> 10 | </Flags> 11 | <SessionStorage Value="InProjectDir"/> 12 | <MainUnit Value="0"/> 13 | <Title Value="Minimal"/> 14 | <UseAppBundle Value="False"/> 15 | <ResourceType Value="res"/> 16 | </General> 17 | <i18n> 18 | <EnableI18N LFM="False"/> 19 | </i18n> 20 | <VersionInfo> 21 | <StringTable ProductVersion=""/> 22 | </VersionInfo> 23 | <MacroValues Count="1"> 24 | <Macro1 Name="LCLWidgetType" Value="win32"/> 25 | </MacroValues> 26 | <BuildModes Count="2"> 27 | <Item1 Name="Win32" Default="True"/> 28 | <Item2 Name="Win64"> 29 | <MacroValues Count="1"> 30 | <Macro1 Name="LCLWidgetType" Value="win32"/> 31 | </MacroValues> 32 | <CompilerOptions> 33 | <Version Value="11"/> 34 | <Target> 35 | <Filename Value="minimal64"/> 36 | </Target> 37 | <SearchPaths> 38 | <IncludeFiles Value="$(ProjOutDir)"/> 39 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 40 | </SearchPaths> 41 | <Parsing> 42 | <SyntaxOptions> 43 | <IncludeAssertionCode Value="True"/> 44 | <AllowLabel Value="False"/> 45 | </SyntaxOptions> 46 | </Parsing> 47 | <CodeGeneration> 48 | <Checks> 49 | <IOChecks Value="True"/> 50 | <RangeChecks Value="True"/> 51 | <OverflowChecks Value="True"/> 52 | </Checks> 53 | <TargetCPU Value="x86_64"/> 54 | <TargetOS Value="win64"/> 55 | </CodeGeneration> 56 | <Other> 57 | <CompilerMessages> 58 | <UseMsgFile Value="True"/> 59 | </CompilerMessages> 60 | <CompilerPath Value="$(CompPath)"/> 61 | </Other> 62 | </CompilerOptions> 63 | </Item2> 64 | <SharedMatrixOptions Count="1"> 65 | <Item1 ID="086285476382" Modes="Win32,Win64" Type="IDEMacro" MacroName="LCLWidgetType" Value="win32"/> 66 | </SharedMatrixOptions> 67 | </BuildModes> 68 | <PublishOptions> 69 | <Version Value="2"/> 70 | <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> 71 | <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/> 72 | </PublishOptions> 73 | <RunParams> 74 | <local> 75 | <FormatVersion Value="1"/> 76 | </local> 77 | </RunParams> 78 | <RequiredPackages Count="1"> 79 | <Item1> 80 | <PackageName Value="CEF3"/> 81 | </Item1> 82 | </RequiredPackages> 83 | <Units Count="1"> 84 | <Unit0> 85 | <Filename Value="minimal.lpr"/> 86 | <IsPartOfProject Value="True"/> 87 | </Unit0> 88 | </Units> 89 | </ProjectOptions> 90 | <CompilerOptions> 91 | <Version Value="11"/> 92 | <Target> 93 | <Filename Value="minimal32"/> 94 | </Target> 95 | <SearchPaths> 96 | <IncludeFiles Value="$(ProjOutDir)"/> 97 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 98 | </SearchPaths> 99 | <Parsing> 100 | <SyntaxOptions> 101 | <IncludeAssertionCode Value="True"/> 102 | <AllowLabel Value="False"/> 103 | </SyntaxOptions> 104 | </Parsing> 105 | <CodeGeneration> 106 | <Checks> 107 | <IOChecks Value="True"/> 108 | <RangeChecks Value="True"/> 109 | <OverflowChecks Value="True"/> 110 | <StackChecks Value="True"/> 111 | </Checks> 112 | <TargetCPU Value="i386"/> 113 | <TargetOS Value="win32"/> 114 | </CodeGeneration> 115 | <Other> 116 | <CompilerMessages> 117 | <UseMsgFile Value="True"/> 118 | </CompilerMessages> 119 | <CompilerPath Value="$(CompPath)"/> 120 | </Other> 121 | </CompilerOptions> 122 | <Debugging> 123 | <Exceptions Count="3"> 124 | <Item1> 125 | <Name Value="EAbort"/> 126 | </Item1> 127 | <Item2> 128 | <Name Value="ECodetoolError"/> 129 | </Item2> 130 | <Item3> 131 | <Name Value="EFOpenError"/> 132 | </Item3> 133 | </Exceptions> 134 | </Debugging> 135 | </CONFIG> 136 | -------------------------------------------------------------------------------- /Examples/GTK2Minimal/minimal.lpr: -------------------------------------------------------------------------------- 1 | Program minimal; 2 | 3 | {$MODE objfpc}{$H+} 4 | 5 | Uses 6 | {$IFDEF UNIX}cthreads,{$ENDIF} 7 | Classes, sysutils, 8 | Glib2, Gtk2, gdk2x, xlib, x, 9 | cef3types, cef3lib, cef3api, cef3ref, cef3own; 10 | 11 | Var 12 | Window : PGtkWidget; 13 | VBox : PGtkWidget; 14 | Button : PGtkWidget; 15 | 16 | ButtonHeight: Integer; 17 | 18 | MainArgs : TCefMainArgs; 19 | Settings : TCefSettings; 20 | ExitCode : Integer; 21 | 22 | BrowserSettings : TCefBrowserSettings; 23 | Info : TCefWindowInfo; 24 | 25 | URL : TCefString; 26 | 27 | Client : TCefClientOwn; 28 | 29 | Browser : PCefBrowser; 30 | Frame : PCefFrame; 31 | Host : PCefBrowserHost; 32 | 33 | procedure Release(var base : TCefBaseRefCounted); 34 | begin 35 | base.release(@base); 36 | end; 37 | 38 | procedure size_allocated(widget: PGtkWidget; allocation: PGtkAllocation; data: Pointer); cdecl; 39 | begin 40 | ButtonHeight := allocation^.height; 41 | end; 42 | 43 | procedure vbox_resize(widget: PGtkWidget; allocation: PGtkAllocation; data: Pointer); cdecl; 44 | Var 45 | xdisplay: PXDisplay; 46 | xwindow: TWindow; 47 | changes: TXWindowChanges; 48 | begin 49 | info.x := allocation^.x; 50 | info.y := allocation^.y + ButtonHeight; 51 | info.width := allocation^.width; 52 | info.height := allocation^.height - ButtonHeight; 53 | 54 | If Assigned(Browser) then 55 | begin 56 | Host := Browser^.get_host(Browser); 57 | xwindow := Host^.get_window_handle(Host); 58 | 59 | xdisplay := cef_get_xdisplay(); 60 | 61 | changes.x := info.x; 62 | changes.y := info.y; 63 | changes.width := info.width; 64 | changes.height := info.height; 65 | 66 | XConfigureWindow(xdisplay, xwindow, CWX or CWY or CWHeight or CWWidth, @changes); 67 | 68 | Release(Host^.base); 69 | end; 70 | end; 71 | 72 | function idle(widget: PGtkWidget): gboolean; cdecl; 73 | begin 74 | cef_do_message_loop_work(); 75 | 76 | Result := true; 77 | end; 78 | 79 | procedure destroy(widget: PGtkWidget; data: gpointer); cdecl; 80 | begin 81 | gtk_main_quit; 82 | end; 83 | 84 | procedure bclicked(widget : PGtkWidget; data : gpointer); cdecl; 85 | Var 86 | Dest : TCefString; 87 | begin 88 | WriteLn('Reloading...'); 89 | 90 | Dest := CefString('https://github.com/dliw/fpCEF3'); 91 | Frame := Browser^.get_main_frame(Browser); 92 | Frame^.load_url(Frame, @Dest); 93 | 94 | Release(Frame^.base); 95 | end; 96 | 97 | begin 98 | MainArgs.argc := argc; 99 | MainArgs.argv := argv; 100 | 101 | CefLoadLibrary; 102 | 103 | ExitCode := cef_execute_process(@MainArgs, nil, nil); 104 | If ExitCode >= 0 then Halt(ExitCode); 105 | 106 | gtk_init(nil, nil); 107 | 108 | // Install xlib error handlers so that the application won't be terminated 109 | // on non-fatal errors. 110 | XSetErrorHandler(@XErrorHandler); 111 | XSetIOErrorHandler(@XIOErrorHandler); 112 | 113 | Settings.size := SizeOf(Settings); 114 | Settings.single_process := Ord(False); 115 | Settings.no_sandbox := Ord(True); 116 | Settings.multi_threaded_message_loop := Ord(False); 117 | Settings.log_severity := LOGSEVERITY_INFO; 118 | Settings.uncaught_exception_stack_size := 20; 119 | Settings.context_safety_implementation := 0; 120 | 121 | cef_initialize(@MainArgs, @Settings, nil, nil); 122 | 123 | // Window 124 | Window := gtk_window_new(GTK_WINDOW_TOPLEVEL); 125 | gtk_window_set_title(GTK_WINDOW(window), 'CEF3 Bare Bones'); 126 | gtk_window_set_default_size(GTK_WINDOW(window), 400, 400); 127 | 128 | VBox := gtk_vbox_new(False, 0); 129 | g_signal_connect(G_OBJECT(VBox), 'size-allocate', G_CALLBACK(@vbox_resize), nil); 130 | gtk_container_add(GTK_CONTAINER(window), VBox); 131 | 132 | Button := gtk_button_new_with_label('Go'); 133 | g_signal_connect (G_OBJECT(Button), 'clicked', G_CALLBACK(@bclicked), PChar('go')); 134 | g_signal_connect(G_OBJECT(Button), 'size-allocate', G_CALLBACK(@size_allocated), nil); 135 | gtk_box_pack_start(GTK_BOX(VBox), Button, False, False, 0); 136 | 137 | gtk_widget_show_all(Window); 138 | 139 | info.parent_window := GDK_WINDOW_XID(VBox^.window); 140 | 141 | Client := TCefClientOwn.Create; 142 | URL := CefString('chrome://version'); 143 | Browser := cef_browser_host_create_browser_sync(@info, Client.Wrap, @URL, @BrowserSettings, nil); 144 | 145 | g_signal_connect(G_OBJECT(window), 'destroy', G_CALLBACK(@Destroy), nil); 146 | g_idle_add_full(G_PRIORITY_HIGH_IDLE,TGSourceFunc(@idle), Window, nil); 147 | 148 | // main loop 149 | gtk_main; 150 | 151 | // cleanup 152 | Host := Browser^.get_host(Browser); 153 | Host^.close_browser(Host, 1); 154 | 155 | Release(Host^.base); 156 | Release(Browser^.base); 157 | 158 | cef_shutdown(); 159 | end. 160 | -------------------------------------------------------------------------------- /Examples/WinMinimal/minimal.lpr: -------------------------------------------------------------------------------- 1 | Program minimal; 2 | 3 | Uses 4 | Windows, Messages, LCLProc, 5 | cef3types, cef3api, cef3lib, cef3intf, cef3own; 6 | 7 | Type 8 | TCustomClient = class(TCefClientOwn) 9 | private 10 | FLifeSpan: ICefLifeSpanHandler; 11 | protected 12 | function GetLifeSpanHandler: ICefLifeSpanHandler; override; 13 | public 14 | constructor Create; override; 15 | end; 16 | 17 | TCustomLifeSpan = class(TCefLifeSpanHandlerOwn) 18 | protected 19 | procedure OnAfterCreated(const browser: ICefBrowser); override; 20 | procedure OnBeforeClose(const browser: ICefBrowser); override; 21 | end; 22 | 23 | Var 24 | Window: HWND; 25 | handl: ICefClient = nil; 26 | brows: ICefBrowser = nil; 27 | browserId: Integer = 0; 28 | navigateto: ustring = 'http://www.example.com'; 29 | 30 | function CefWndProc(Wnd: HWND; message: UINT; wParam: Integer; lParam: Integer): Integer; stdcall; 31 | Var 32 | ps: PAINTSTRUCT; 33 | info: TCefWindowInfo; 34 | rect: TRect; 35 | hdwp: THandle; 36 | setting: TCefBrowserSettings; 37 | begin 38 | Case message of 39 | WM_PAINT: 40 | begin 41 | BeginPaint(Wnd, ps); 42 | EndPaint(Wnd, ps); 43 | result := 0; 44 | end; 45 | WM_CREATE: 46 | begin 47 | handl := TCustomClient.Create; 48 | GetClientRect(Wnd, rect); 49 | FillChar(info, SizeOf(info), 0); 50 | info.Style := WS_CHILD or WS_VISIBLE or WS_CLIPCHILDREN or WS_CLIPSIBLINGS or WS_TABSTOP; 51 | info.parent_window := Wnd; 52 | info.x := rect.left; 53 | info.y := rect.top; 54 | info.Width := rect.right - rect.left; 55 | info.Height := rect.bottom - rect.top; 56 | FillChar(setting, sizeof(setting), 0); 57 | setting.size := SizeOf(setting); 58 | CefBrowserHostCreateBrowserSync(@info, handl, navigateto, @setting, nil); 59 | SetTimer(Wnd, 1, 100, nil); 60 | result := 0; 61 | end; 62 | WM_DESTROY: 63 | begin 64 | brows := nil; 65 | PostQuitMessage(0); 66 | result := DefWindowProc(Wnd, message, wParam, lParam); 67 | end; 68 | WM_SETFOCUS: 69 | begin 70 | if brows <> nil then 71 | PostMessage(brows.Host.WindowHandle, WM_SETFOCUS, wParam, 0); 72 | Result := 0; 73 | end; 74 | WM_SIZE: 75 | begin 76 | if(brows <> nil) then 77 | begin 78 | // Resize the browser window and address bar to match the new frame 79 | // window size 80 | GetClientRect(Wnd, rect); 81 | hdwp := BeginDeferWindowPos(1); 82 | hdwp := DeferWindowPos(hdwp, brows.Host.WindowHandle, 0, rect.left, rect.top, 83 | rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER); 84 | EndDeferWindowPos(hdwp); 85 | end; 86 | result := DefWindowProc(Wnd, message, wParam, lParam); 87 | end; 88 | WM_CLOSE: 89 | begin 90 | if brows <> nil then 91 | brows.Host.CloseBrowser(True); 92 | result := DefWindowProc(Wnd, message, wParam, lParam); 93 | end 94 | else 95 | result := DefWindowProc(Wnd, message, wParam, lParam); 96 | end; 97 | end; 98 | 99 | { TCustomClient } 100 | 101 | constructor TCustomClient.Create; 102 | begin 103 | inherited; 104 | FLifeSpan := TCustomLifeSpan.Create; 105 | end; 106 | 107 | function TCustomClient.GetLifeSpanHandler: ICefLifeSpanHandler; 108 | begin 109 | Result := FLifeSpan; 110 | end; 111 | 112 | { TCustomLifeSpan } 113 | 114 | procedure TCustomLifeSpan.OnAfterCreated(const browser: ICefBrowser); 115 | begin 116 | If not browser.IsPopup then 117 | begin 118 | // get the first browser 119 | brows := browser; 120 | browserId := brows.Identifier; 121 | end; 122 | end; 123 | 124 | procedure TCustomLifeSpan.OnBeforeClose(const browser: ICefBrowser); 125 | begin 126 | If browser.Identifier = browserId then brows := nil; 127 | end; 128 | 129 | Var 130 | wndClass : TWndClass; 131 | begin 132 | // multi process 133 | CefSingleProcess := False; 134 | If not CefInitialize then 135 | begin 136 | Debugln('CefInitialize failed.'); 137 | Exit; 138 | end; 139 | try 140 | wndClass.style := CS_HREDRAW or CS_VREDRAW; 141 | wndClass.lpfnWndProc := WNDPROC(@CefWndProc); 142 | wndClass.cbClsExtra := 0; 143 | wndClass.cbWndExtra := 0; 144 | wndClass.hInstance := hInstance; 145 | wndClass.hIcon := LoadIcon(0, IDI_APPLICATION); 146 | wndClass.hCursor := LoadCursor(0, IDC_ARROW); 147 | wndClass.hbrBackground := 0; 148 | wndClass.lpszMenuName := nil; 149 | wndClass.lpszClassName := 'cefapp'; 150 | 151 | RegisterClass(wndClass); 152 | 153 | Window := CreateWindow( 154 | 'cefapp', 155 | 'CEF Application', 156 | WS_OVERLAPPEDWINDOW or WS_CLIPCHILDREN, 157 | Integer(CW_USEDEFAULT), 158 | Integer(CW_USEDEFAULT), 159 | Integer(CW_USEDEFAULT), 160 | Integer(CW_USEDEFAULT), 161 | 0, 162 | 0, 163 | HInstance, 164 | nil); 165 | 166 | ShowWindow(Window, SW_SHOW); 167 | UpdateWindow(Window); 168 | CefRunMessageLoop; 169 | finally 170 | handl := nil; 171 | end; 172 | end. 173 | -------------------------------------------------------------------------------- /Component/cef3context.pas: -------------------------------------------------------------------------------- 1 | (* 2 | * Free Pascal Chromium Embedded 3 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, 6 | * You can obtain one at http://mozilla.org/MPL/2.0/. 7 | * 8 | * Author: dev.dliw@gmail.com 9 | * Repository: https://github.com/dliw/fpCEF3 10 | * 11 | *) 12 | 13 | Unit cef3context; 14 | 15 | {$MODE objfpc}{$H+} 16 | 17 | {$I cef.inc} 18 | 19 | Interface 20 | 21 | Uses 22 | Classes, SysUtils, 23 | cef3types, cef3lib, cef3intf, cef3ref, cef3gui; 24 | 25 | Type 26 | 27 | TCustomChromiumContext = class(TComponent, IChromiumContextEvents) 28 | private 29 | fRequestContextHandler: ICefRequestContextHandler; 30 | fRequestContext: ICefRequestContext; 31 | 32 | fSharedContext: TCustomChromiumContext; 33 | 34 | fOnGetCookieManager: TOnGetCookieManager; 35 | fOnBeforePluginLoad: TOnBeforePluginLoad; 36 | 37 | fCachePath: String; 38 | fPersistSessionCookies: Boolean; 39 | fPersistUserPreferences: Boolean; 40 | fIgnoreCertificateErrors: Boolean; 41 | fAcceptLanguageList: String; 42 | protected 43 | function NewRequestContext: ICefRequestContext; 44 | 45 | function doOnGetCookieManager: ICefCookieManager; 46 | function doOnBeforePluginLoad(const mimeType, pluginUrl: ustring; isMainFrame: Boolean; 47 | const topOriginUrl: ustring; pluginInfo: ICefWebPluginInfo; 48 | pluginPolicy: TCefPluginPolicy): Boolean; 49 | 50 | property SharedContext: TCustomChromiumContext read fSharedContext write fSharedContext default nil; 51 | 52 | property OnGetCookieManager: TOnGetCookieManager read fOnGetCookieManager write fOnGetCookieManager; 53 | property OnBeforePluginLoad: TOnBeforePluginLoad read fOnBeforePluginLoad write fOnBeforePluginLoad; 54 | 55 | property CachePath: String read fCachePath write fCachePath; 56 | property PersistSessionCookies: Boolean read fPersistSessionCookies write fPersistSessionCookies; 57 | property PersistUserPreferences: Boolean read fPersistUserPreferences write fPersistUserPreferences; 58 | property IgnoreCertificateErrors: Boolean read fIgnoreCertificateErrors write fIgnoreCertificateErrors; 59 | property AcceptLanguageList: String read fAcceptLanguageList write fAcceptLanguageList; 60 | public 61 | constructor Create(AOwner: TComponent); override; 62 | 63 | function GetRequestContext: ICefRequestContext; 64 | end; 65 | 66 | TChromiumContext = class(TCustomChromiumContext) 67 | published 68 | property SharedContext; 69 | 70 | property OnGetCookieManager; 71 | property OnBeforePluginLoad; 72 | 73 | property CachePath; 74 | property PersistSessionCookies; 75 | property PersistUserPreferences; 76 | property IgnoreCertificateErrors; 77 | property AcceptLanguageList; 78 | end; 79 | 80 | procedure Register; 81 | 82 | Implementation 83 | 84 | procedure Register; 85 | begin 86 | RegisterComponents('Chromium', [TChromiumContext]); 87 | end; 88 | 89 | 90 | { TCustomChromiumContext } 91 | 92 | function TCustomChromiumContext.NewRequestContext: ICefRequestContext; 93 | Var 94 | settings: TCefRequestContextSettings; 95 | begin 96 | CefInitialize; 97 | 98 | If Assigned(fSharedContext) then 99 | begin 100 | Result := TCefRequestContextRef.Shared(fSharedContext.GetRequestContext, fRequestContextHandler) 101 | end 102 | Else 103 | begin 104 | FillChar(settings, SizeOf(TCefRequestContextSettings), 0); 105 | settings.size := SizeOf(TCefRequestContextSettings); 106 | 107 | settings.cache_path := CefString(fCachePath); 108 | settings.persist_session_cookies := Ord(fPersistSessionCookies); 109 | settings.persist_user_preferences := Ord(fPersistUserPreferences); 110 | settings.ignore_certificate_errors := Ord(fIgnoreCertificateErrors); 111 | settings.accept_language_list := CefString(fAcceptLanguageList); 112 | 113 | Result := TCefRequestContextRef.New(settings, fRequestContextHandler); 114 | end; 115 | end; 116 | 117 | function TCustomChromiumContext.doOnGetCookieManager: ICefCookieManager; 118 | begin 119 | If Assigned(fOnGetCookieManager) then fOnGetCookieManager(Self, Result) 120 | Else Result := nil; 121 | end; 122 | 123 | function TCustomChromiumContext.doOnBeforePluginLoad(const mimeType, pluginUrl: ustring; 124 | isMainFrame: Boolean; const topOriginUrl: ustring; pluginInfo: ICefWebPluginInfo; 125 | pluginPolicy: TCefPluginPolicy): Boolean; 126 | begin 127 | If Assigned(fOnBeforePluginLoad) then 128 | fOnBeforePluginLoad(Self, mimeType, pluginUrl, isMainFrame, topOriginUrl, pluginInfo, 129 | pluginPolicy, Result) 130 | Else Result := False; 131 | end; 132 | 133 | constructor TCustomChromiumContext.Create(AOwner: TComponent); 134 | begin 135 | inherited; 136 | 137 | If not (csDesigning in ComponentState) then 138 | begin 139 | fRequestContextHandler := TCustomRequestContextHandler.Create(Self); 140 | end; 141 | end; 142 | 143 | function TCustomChromiumContext.GetRequestContext: ICefRequestContext; 144 | begin 145 | If not Assigned(fRequestContext) then fRequestContext := NewRequestContext; 146 | 147 | Result := fRequestContext; 148 | end; 149 | 150 | end. 151 | 152 | -------------------------------------------------------------------------------- /Component/cef3cocoa.pas: -------------------------------------------------------------------------------- 1 | (* 2 | * Free Pascal Chromium Embedded 3 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, 6 | * You can obtain one at http://mozilla.org/MPL/2.0/. 7 | * 8 | * Original author: Dmitry Boyarintsev <skalogryz.lists@gmail.com> 9 | * Integrated from: http://github.com/skalogryz/fpCEF3 10 | * Repository: https://github.com/dliw/fpCEF3 11 | * 12 | *) 13 | 14 | Unit cef3cocoa; 15 | 16 | {$MODE objfpc}{$H+} 17 | {$MODESWITCH objectivec1} 18 | 19 | Interface 20 | 21 | Uses 22 | CocoaAll; 23 | 24 | Type 25 | 26 | { *** cef_application_mac.h *** } 27 | 28 | // Copy of definition from base/message_loop/message_pump_mac.h. 29 | CrAppProtocol = objcprotocol 30 | function isHandlingSendEvent: Boolean; message 'isHandlingSendEvent'; 31 | end; 32 | 33 | // Copy of definition from base/mac/scoped_sending_event.h. 34 | CrAppControlProtocol = objcprotocol(CrAppProtocol) 35 | procedure setHandlingSendEvent(handlingSendEvent: Boolean); message 'setHandlingSendEvent:'; 36 | end; 37 | 38 | // All CEF client applications must subclass NSApplication and implement this 39 | // protocol. 40 | CefAppProtocol = objcprotocol(CrAppControlProtocol) 41 | end; 42 | 43 | 44 | { *** cefclient_mac.mm *** } 45 | 46 | ClientApplication = objcclass(NSApplication, CefAppProtocol) 47 | private 48 | handlingSendEvent_: Boolean; 49 | isHandling: Boolean; 50 | public 51 | function isHandlingSendEvent: Boolean; 52 | procedure setHandlingSendEvent(AHandling: Boolean); 53 | procedure sendEvent(aevent: NSEvent); override; 54 | procedure terminate(sender: id); override; 55 | end; 56 | 57 | procedure InitCRApplication; 58 | 59 | Implementation 60 | 61 | procedure InitCRApplication; 62 | begin 63 | ClientApplication.sharedApplication; 64 | end; 65 | 66 | { ClientApplication } 67 | 68 | function ClientApplication.isHandlingSendEvent: Boolean; 69 | begin 70 | Result := handlingSendEvent_; 71 | end; 72 | 73 | procedure ClientApplication.setHandlingSendEvent(AHandling: Boolean); 74 | begin 75 | handlingSendEvent_ := True; 76 | end; 77 | 78 | procedure ClientApplication.sendEvent(aevent: NSEvent); 79 | var 80 | ishse: Boolean; 81 | app_: ClientApplication; 82 | begin 83 | // CEF samples implement this via a C++ class 84 | app_ := ClientApplication(NSApplication.sharedApplication); 85 | ishse := app_.isHandlingSendEvent; 86 | app_.setHandlingSendEvent(true); 87 | 88 | inherited sendEvent(aevent); 89 | 90 | app_.setHandlingSendEvent(ishse); 91 | end; 92 | 93 | // |-terminate:| is the entry point for orderly "quit" operations in Cocoa. This 94 | // includes the application menu's quit menu item and keyboard equivalent, the 95 | // application's dock icon menu's quit menu item, "quit" (not "force quit") in 96 | // the Activity Monitor, and quits triggered by user logout and system restart 97 | // and shutdown. 98 | // 99 | // The default |-terminate:| implementation ends the process by calling exit(), 100 | // and thus never leaves the main run loop. This is unsuitable for Chromium 101 | // since Chromium depends on leaving the main run loop to perform an orderly 102 | // shutdown. We support the normal |-terminate:| interface by overriding the 103 | // default implementation. Our implementation, which is very specific to the 104 | // needs of Chromium, works by asking the application delegate to terminate 105 | // using its |-tryToTerminateApplication:| method. 106 | // 107 | // |-tryToTerminateApplication:| differs from the standard 108 | // |-applicationShouldTerminate:| in that no special event loop is run in the 109 | // case that immediate termination is not possible (e.g., if dialog boxes 110 | // allowing the user to cancel have to be shown). Instead, this method tries to 111 | // close all browsers by calling CloseBrowser(false) via 112 | // ClientHandler::CloseAllBrowsers. Calling CloseBrowser will result in a call 113 | // to ClientHandler::DoClose and execution of |-performClose:| on the NSWindow. 114 | // DoClose sets a flag that is used to differentiate between new close events 115 | // (e.g., user clicked the window close button) and in-progress close events 116 | // (e.g., user approved the close window dialog). The NSWindowDelegate 117 | // |-windowShouldClose:| method checks this flag and either calls 118 | // CloseBrowser(false) in the case of a new close event or destructs the 119 | // NSWindow in the case of an in-progress close event. 120 | // ClientHandler::OnBeforeClose will be called after the CEF NSView hosted in 121 | // the NSWindow is dealloc'ed. 122 | // 123 | // After the final browser window has closed ClientHandler::OnBeforeClose will 124 | // begin actual tear-down of the application by calling CefQuitMessageLoop. 125 | // This ends the NSApplication event loop and execution then returns to the 126 | // main() function for cleanup before application termination. 127 | // 128 | // The standard |-applicationShouldTerminate:| is not supported, and code paths 129 | // leading to it must be redirected. 130 | procedure ClientApplication.terminate(sender: id); 131 | begin 132 | // TODO: see what LCL does 133 | inherited terminate(sender); 134 | 135 | // don't exit and return. The application is responsible for exiting on its own. 136 | end; 137 | 138 | end. 139 | 140 | -------------------------------------------------------------------------------- /Examples/JavaScript/js.lpi: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <CONFIG> 3 | <ProjectOptions> 4 | <Version Value="10"/> 5 | <General> 6 | <SessionStorage Value="InProjectDir"/> 7 | <MainUnit Value="0"/> 8 | <Title Value="js"/> 9 | <ResourceType Value="res"/> 10 | <UseXPManifest Value="True"/> 11 | <Icon Value="0"/> 12 | </General> 13 | <i18n> 14 | <EnableI18N LFM="False"/> 15 | </i18n> 16 | <MacroValues Count="1"> 17 | <Macro1 Name="LCLWidgetType" Value="gtk2"/> 18 | </MacroValues> 19 | <BuildModes Count="3"> 20 | <Item1 Name="Linux" Default="True"/> 21 | <Item2 Name="Win32"> 22 | <MacroValues Count="1"> 23 | <Macro2 Name="LCLWidgetType" Value="win32"/> 24 | </MacroValues> 25 | <CompilerOptions> 26 | <Version Value="11"/> 27 | <Target> 28 | <Filename Value="js32"/> 29 | </Target> 30 | <SearchPaths> 31 | <IncludeFiles Value="$(ProjOutDir)"/> 32 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 33 | </SearchPaths> 34 | <Parsing> 35 | <SyntaxOptions> 36 | <AllowLabel Value="False"/> 37 | </SyntaxOptions> 38 | </Parsing> 39 | <CodeGeneration> 40 | <RelocatableUnit Value="True"/> 41 | <Checks> 42 | <IOChecks Value="True"/> 43 | <RangeChecks Value="True"/> 44 | <OverflowChecks Value="True"/> 45 | </Checks> 46 | <TargetCPU Value="i386"/> 47 | <TargetOS Value="win32"/> 48 | </CodeGeneration> 49 | <Linking> 50 | <Options> 51 | <Win32> 52 | <GraphicApplication Value="True"/> 53 | </Win32> 54 | </Options> 55 | </Linking> 56 | </CompilerOptions> 57 | </Item2> 58 | <Item3 Name="Win64"> 59 | <MacroValues Count="1"> 60 | <Macro2 Name="LCLWidgetType" Value="win32"/> 61 | </MacroValues> 62 | <CompilerOptions> 63 | <Version Value="11"/> 64 | <Target> 65 | <Filename Value="js64"/> 66 | </Target> 67 | <SearchPaths> 68 | <IncludeFiles Value="$(ProjOutDir)"/> 69 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 70 | </SearchPaths> 71 | <Parsing> 72 | <SyntaxOptions> 73 | <AllowLabel Value="False"/> 74 | </SyntaxOptions> 75 | </Parsing> 76 | <CodeGeneration> 77 | <RelocatableUnit Value="True"/> 78 | <Checks> 79 | <IOChecks Value="True"/> 80 | <RangeChecks Value="True"/> 81 | <OverflowChecks Value="True"/> 82 | </Checks> 83 | <TargetCPU Value="x86_64"/> 84 | <TargetOS Value="win64"/> 85 | </CodeGeneration> 86 | <Linking> 87 | <Options> 88 | <Win32> 89 | <GraphicApplication Value="True"/> 90 | </Win32> 91 | </Options> 92 | </Linking> 93 | </CompilerOptions> 94 | </Item3> 95 | <SharedMatrixOptions Count="2"> 96 | <Item1 ID="661871476567" Modes="Linux" Type="IDEMacro" MacroName="LCLWidgetType" Value="gtk2"/> 97 | <Item2 ID="279904151772" Modes="Win32,Win64" Type="IDEMacro" MacroName="LCLWidgetType" Value="win32"/> 98 | </SharedMatrixOptions> 99 | </BuildModes> 100 | <PublishOptions> 101 | <Version Value="2"/> 102 | <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> 103 | <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/> 104 | </PublishOptions> 105 | <RunParams> 106 | <local> 107 | <FormatVersion Value="1"/> 108 | </local> 109 | <environment> 110 | <UserOverrides Count="1"> 111 | <Variable0 Name="LD_LIBRARY_PATH" Value="."/> 112 | </UserOverrides> 113 | </environment> 114 | </RunParams> 115 | <RequiredPackages Count="2"> 116 | <Item1> 117 | <PackageName Value="CEF3"/> 118 | </Item1> 119 | <Item2> 120 | <PackageName Value="LCL"/> 121 | </Item2> 122 | </RequiredPackages> 123 | <Units Count="3"> 124 | <Unit0> 125 | <Filename Value="js.lpr"/> 126 | <IsPartOfProject Value="True"/> 127 | </Unit0> 128 | <Unit1> 129 | <Filename Value="main.pas"/> 130 | <IsPartOfProject Value="True"/> 131 | <ComponentName Value="Mainform"/> 132 | <HasResources Value="True"/> 133 | <ResourceBaseClass Value="Form"/> 134 | <UnitName Value="Main"/> 135 | </Unit1> 136 | <Unit2> 137 | <Filename Value="handler.pas"/> 138 | <IsPartOfProject Value="True"/> 139 | <UnitName Value="Handler"/> 140 | </Unit2> 141 | </Units> 142 | </ProjectOptions> 143 | <CompilerOptions> 144 | <Version Value="11"/> 145 | <Target> 146 | <Filename Value="js"/> 147 | </Target> 148 | <SearchPaths> 149 | <IncludeFiles Value="$(ProjOutDir)"/> 150 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 151 | </SearchPaths> 152 | <Parsing> 153 | <SyntaxOptions> 154 | <AllowLabel Value="False"/> 155 | </SyntaxOptions> 156 | </Parsing> 157 | <CodeGeneration> 158 | <Checks> 159 | <IOChecks Value="True"/> 160 | <RangeChecks Value="True"/> 161 | <OverflowChecks Value="True"/> 162 | </Checks> 163 | <TargetCPU Value="x86_64"/> 164 | <TargetOS Value="linux"/> 165 | </CodeGeneration> 166 | <Linking> 167 | <Options> 168 | <Win32> 169 | <GraphicApplication Value="True"/> 170 | </Win32> 171 | </Options> 172 | </Linking> 173 | </CompilerOptions> 174 | <Debugging> 175 | <Exceptions Count="3"> 176 | <Item1> 177 | <Name Value="EAbort"/> 178 | </Item1> 179 | <Item2> 180 | <Name Value="ECodetoolError"/> 181 | </Item2> 182 | <Item3> 183 | <Name Value="EFOpenError"/> 184 | </Item3> 185 | </Exceptions> 186 | </Debugging> 187 | </CONFIG> 188 | -------------------------------------------------------------------------------- /Examples/DOMAccess/dom.lpi: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <CONFIG> 3 | <ProjectOptions> 4 | <Version Value="10"/> 5 | <General> 6 | <SessionStorage Value="InProjectDir"/> 7 | <MainUnit Value="0"/> 8 | <Title Value="dom"/> 9 | <ResourceType Value="res"/> 10 | <UseXPManifest Value="True"/> 11 | <Icon Value="0"/> 12 | </General> 13 | <i18n> 14 | <EnableI18N LFM="False"/> 15 | </i18n> 16 | <VersionInfo> 17 | <StringTable ProductVersion=""/> 18 | </VersionInfo> 19 | <MacroValues Count="1"> 20 | <Macro1 Name="LCLWidgetType" Value="gtk2"/> 21 | </MacroValues> 22 | <BuildModes Count="3"> 23 | <Item1 Name="Linux" Default="True"/> 24 | <Item2 Name="Win32"> 25 | <MacroValues Count="1"> 26 | <Macro2 Name="LCLWidgetType" Value="win32"/> 27 | </MacroValues> 28 | <CompilerOptions> 29 | <Version Value="11"/> 30 | <Target> 31 | <Filename Value="dom32"/> 32 | </Target> 33 | <SearchPaths> 34 | <IncludeFiles Value="$(ProjOutDir)"/> 35 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 36 | </SearchPaths> 37 | <Parsing> 38 | <SyntaxOptions> 39 | <AllowLabel Value="False"/> 40 | </SyntaxOptions> 41 | </Parsing> 42 | <CodeGeneration> 43 | <RelocatableUnit Value="True"/> 44 | <Checks> 45 | <IOChecks Value="True"/> 46 | <RangeChecks Value="True"/> 47 | <OverflowChecks Value="True"/> 48 | </Checks> 49 | <TargetCPU Value="i386"/> 50 | <TargetOS Value="win32"/> 51 | </CodeGeneration> 52 | <Linking> 53 | <Options> 54 | <Win32> 55 | <GraphicApplication Value="True"/> 56 | </Win32> 57 | </Options> 58 | </Linking> 59 | </CompilerOptions> 60 | </Item2> 61 | <Item3 Name="Win64"> 62 | <MacroValues Count="1"> 63 | <Macro2 Name="LCLWidgetType" Value="win32"/> 64 | </MacroValues> 65 | <CompilerOptions> 66 | <Version Value="11"/> 67 | <Target> 68 | <Filename Value="dom64"/> 69 | </Target> 70 | <SearchPaths> 71 | <IncludeFiles Value="$(ProjOutDir)"/> 72 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 73 | </SearchPaths> 74 | <Parsing> 75 | <SyntaxOptions> 76 | <AllowLabel Value="False"/> 77 | </SyntaxOptions> 78 | </Parsing> 79 | <CodeGeneration> 80 | <RelocatableUnit Value="True"/> 81 | <Checks> 82 | <IOChecks Value="True"/> 83 | <RangeChecks Value="True"/> 84 | <OverflowChecks Value="True"/> 85 | </Checks> 86 | <TargetCPU Value="x86_64"/> 87 | <TargetOS Value="win64"/> 88 | </CodeGeneration> 89 | <Linking> 90 | <Options> 91 | <Win32> 92 | <GraphicApplication Value="True"/> 93 | </Win32> 94 | </Options> 95 | </Linking> 96 | </CompilerOptions> 97 | </Item3> 98 | <SharedMatrixOptions Count="2"> 99 | <Item1 ID="661871476567" Modes="Linux" Type="IDEMacro" MacroName="LCLWidgetType" Value="gtk2"/> 100 | <Item2 ID="279904151772" Modes="Win32,Win64" Type="IDEMacro" MacroName="LCLWidgetType" Value="win32"/> 101 | </SharedMatrixOptions> 102 | </BuildModes> 103 | <PublishOptions> 104 | <Version Value="2"/> 105 | <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> 106 | <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/> 107 | </PublishOptions> 108 | <RunParams> 109 | <local> 110 | <FormatVersion Value="1"/> 111 | </local> 112 | <environment> 113 | <UserOverrides Count="1"> 114 | <Variable0 Name="LD_LIBRARY_PATH" Value="."/> 115 | </UserOverrides> 116 | </environment> 117 | </RunParams> 118 | <RequiredPackages Count="2"> 119 | <Item1> 120 | <PackageName Value="CEF3"/> 121 | </Item1> 122 | <Item2> 123 | <PackageName Value="LCL"/> 124 | </Item2> 125 | </RequiredPackages> 126 | <Units Count="3"> 127 | <Unit0> 128 | <Filename Value="dom.lpr"/> 129 | <IsPartOfProject Value="True"/> 130 | </Unit0> 131 | <Unit1> 132 | <Filename Value="main.pas"/> 133 | <IsPartOfProject Value="True"/> 134 | <ComponentName Value="Mainform"/> 135 | <HasResources Value="True"/> 136 | <ResourceBaseClass Value="Form"/> 137 | <UnitName Value="Main"/> 138 | </Unit1> 139 | <Unit2> 140 | <Filename Value="handler.pas"/> 141 | <IsPartOfProject Value="True"/> 142 | <UnitName Value="Handler"/> 143 | </Unit2> 144 | </Units> 145 | </ProjectOptions> 146 | <CompilerOptions> 147 | <Version Value="11"/> 148 | <Target> 149 | <Filename Value="dom"/> 150 | </Target> 151 | <SearchPaths> 152 | <IncludeFiles Value="$(ProjOutDir)"/> 153 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 154 | </SearchPaths> 155 | <Parsing> 156 | <SyntaxOptions> 157 | <IncludeAssertionCode Value="True"/> 158 | <AllowLabel Value="False"/> 159 | </SyntaxOptions> 160 | </Parsing> 161 | <CodeGeneration> 162 | <Checks> 163 | <IOChecks Value="True"/> 164 | <RangeChecks Value="True"/> 165 | <OverflowChecks Value="True"/> 166 | <StackChecks Value="True"/> 167 | </Checks> 168 | <TargetCPU Value="x86_64"/> 169 | <TargetOS Value="linux"/> 170 | </CodeGeneration> 171 | <Linking> 172 | <Options> 173 | <Win32> 174 | <GraphicApplication Value="True"/> 175 | </Win32> 176 | </Options> 177 | </Linking> 178 | </CompilerOptions> 179 | <Debugging> 180 | <Exceptions Count="3"> 181 | <Item1> 182 | <Name Value="EAbort"/> 183 | </Item1> 184 | <Item2> 185 | <Name Value="ECodetoolError"/> 186 | </Item2> 187 | <Item3> 188 | <Name Value="EFOpenError"/> 189 | </Item3> 190 | </Exceptions> 191 | </Debugging> 192 | </CONFIG> 193 | -------------------------------------------------------------------------------- /Examples/SubProcess/subprocess.lpi: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <CONFIG> 3 | <ProjectOptions> 4 | <Version Value="9"/> 5 | <General> 6 | <Flags> 7 | <MainUnitHasCreateFormStatements Value="False"/> 8 | <MainUnitHasTitleStatement Value="False"/> 9 | </Flags> 10 | <SessionStorage Value="InProjectDir"/> 11 | <MainUnit Value="0"/> 12 | <Title Value="subprocess"/> 13 | <ResourceType Value="res"/> 14 | </General> 15 | <i18n> 16 | <EnableI18N LFM="False"/> 17 | </i18n> 18 | <VersionInfo> 19 | <StringTable ProductVersion=""/> 20 | </VersionInfo> 21 | <BuildModes Count="4"> 22 | <Item1 Name="Linux64" Default="True"/> 23 | <Item2 Name="Win32"> 24 | <CompilerOptions> 25 | <Version Value="11"/> 26 | <Target> 27 | <Filename Value="subprocess32"/> 28 | </Target> 29 | <SearchPaths> 30 | <IncludeFiles Value="$(ProjOutDir)"/> 31 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 32 | </SearchPaths> 33 | <Parsing> 34 | <SyntaxOptions> 35 | <AllowLabel Value="False"/> 36 | </SyntaxOptions> 37 | </Parsing> 38 | <CodeGeneration> 39 | <SmartLinkUnit Value="True"/> 40 | <TargetCPU Value="i386"/> 41 | <TargetOS Value="win32"/> 42 | <Optimizations> 43 | <OptimizationLevel Value="3"/> 44 | </Optimizations> 45 | </CodeGeneration> 46 | <Linking> 47 | <Debugging> 48 | <GenerateDebugInfo Value="False"/> 49 | </Debugging> 50 | <LinkSmart Value="True"/> 51 | <Options> 52 | <Win32> 53 | <GraphicApplication Value="True"/> 54 | </Win32> 55 | </Options> 56 | </Linking> 57 | </CompilerOptions> 58 | </Item2> 59 | <Item3 Name="Win64"> 60 | <CompilerOptions> 61 | <Version Value="11"/> 62 | <Target> 63 | <Filename Value="subprocess64"/> 64 | </Target> 65 | <SearchPaths> 66 | <IncludeFiles Value="$(ProjOutDir)"/> 67 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 68 | </SearchPaths> 69 | <Parsing> 70 | <SyntaxOptions> 71 | <AllowLabel Value="False"/> 72 | </SyntaxOptions> 73 | </Parsing> 74 | <CodeGeneration> 75 | <SmartLinkUnit Value="True"/> 76 | <TargetCPU Value="x86_64"/> 77 | <TargetOS Value="win64"/> 78 | <Optimizations> 79 | <OptimizationLevel Value="3"/> 80 | </Optimizations> 81 | </CodeGeneration> 82 | <Linking> 83 | <Debugging> 84 | <GenerateDebugInfo Value="False"/> 85 | </Debugging> 86 | <LinkSmart Value="True"/> 87 | <Options> 88 | <Win32> 89 | <GraphicApplication Value="True"/> 90 | </Win32> 91 | </Options> 92 | </Linking> 93 | </CompilerOptions> 94 | </Item3> 95 | <Item4 Name="macOS"> 96 | <MacroValues Count="1"> 97 | <Macro1 Name="LCLWidgetType" Value="cocoa"/> 98 | </MacroValues> 99 | <CompilerOptions> 100 | <Version Value="11"/> 101 | <Target> 102 | <Filename Value="subprocess"/> 103 | </Target> 104 | <SearchPaths> 105 | <IncludeFiles Value="$(ProjOutDir)"/> 106 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 107 | </SearchPaths> 108 | <Parsing> 109 | <SyntaxOptions> 110 | <AllowLabel Value="False"/> 111 | </SyntaxOptions> 112 | </Parsing> 113 | <CodeGeneration> 114 | <SmartLinkUnit Value="True"/> 115 | <TargetCPU Value="x86_64"/> 116 | <TargetOS Value="darwin"/> 117 | <Optimizations> 118 | <OptimizationLevel Value="3"/> 119 | </Optimizations> 120 | </CodeGeneration> 121 | <Linking> 122 | <Debugging> 123 | <GenerateDebugInfo Value="False"/> 124 | </Debugging> 125 | <LinkSmart Value="True"/> 126 | <Options> 127 | <Win32> 128 | <GraphicApplication Value="True"/> 129 | </Win32> 130 | </Options> 131 | </Linking> 132 | <Other> 133 | <ExecuteAfter> 134 | <Command Value="cp "$Name($(TargetFile))" "$Name($(TargetFile)).app/Contents/MacOS/""/> 135 | <CompileReasons Run="False"/> 136 | </ExecuteAfter> 137 | </Other> 138 | </CompilerOptions> 139 | </Item4> 140 | <SharedMatrixOptions Count="1"> 141 | <Item1 ID="641057727940" Modes="macOS" Type="IDEMacro" MacroName="LCLWidgetType" Value="cocoa"/> 142 | </SharedMatrixOptions> 143 | </BuildModes> 144 | <PublishOptions> 145 | <Version Value="2"/> 146 | <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> 147 | <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/> 148 | </PublishOptions> 149 | <RunParams> 150 | <local> 151 | <FormatVersion Value="1"/> 152 | </local> 153 | </RunParams> 154 | <RequiredPackages Count="1"> 155 | <Item1> 156 | <PackageName Value="CEF3"/> 157 | </Item1> 158 | </RequiredPackages> 159 | <Units Count="1"> 160 | <Unit0> 161 | <Filename Value="subprocess.lpr"/> 162 | <IsPartOfProject Value="True"/> 163 | </Unit0> 164 | </Units> 165 | </ProjectOptions> 166 | <CompilerOptions> 167 | <Version Value="11"/> 168 | <Target> 169 | <Filename Value="subprocess"/> 170 | </Target> 171 | <SearchPaths> 172 | <IncludeFiles Value="$(ProjOutDir)"/> 173 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 174 | </SearchPaths> 175 | <Parsing> 176 | <SyntaxOptions> 177 | <AllowLabel Value="False"/> 178 | </SyntaxOptions> 179 | </Parsing> 180 | <CodeGeneration> 181 | <SmartLinkUnit Value="True"/> 182 | <TargetCPU Value="x86_64"/> 183 | <TargetOS Value="linux"/> 184 | <Optimizations> 185 | <OptimizationLevel Value="3"/> 186 | </Optimizations> 187 | </CodeGeneration> 188 | <Linking> 189 | <Debugging> 190 | <GenerateDebugInfo Value="False"/> 191 | </Debugging> 192 | <LinkSmart Value="True"/> 193 | <Options> 194 | <Win32> 195 | <GraphicApplication Value="True"/> 196 | </Win32> 197 | </Options> 198 | </Linking> 199 | </CompilerOptions> 200 | <Debugging> 201 | <Exceptions Count="3"> 202 | <Item1> 203 | <Name Value="EAbort"/> 204 | </Item1> 205 | <Item2> 206 | <Name Value="ECodetoolError"/> 207 | </Item2> 208 | <Item3> 209 | <Name Value="EFOpenError"/> 210 | </Item3> 211 | </Exceptions> 212 | </Debugging> 213 | </CONFIG> 214 | -------------------------------------------------------------------------------- /Examples/LCLSimple/simple.lpi: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <CONFIG> 3 | <ProjectOptions> 4 | <Version Value="10"/> 5 | <General> 6 | <SessionStorage Value="InProjectDir"/> 7 | <MainUnit Value="0"/> 8 | <Title Value="Simple"/> 9 | <ResourceType Value="res"/> 10 | <UseXPManifest Value="True"/> 11 | <Icon Value="0"/> 12 | </General> 13 | <i18n> 14 | <EnableI18N LFM="False"/> 15 | </i18n> 16 | <MacroValues Count="1"> 17 | <Macro1 Name="LCLWidgetType" Value="gtk2"/> 18 | </MacroValues> 19 | <BuildModes Count="4"> 20 | <Item1 Name="Linux" Default="True"/> 21 | <Item2 Name="Win32"> 22 | <MacroValues Count="1"> 23 | <Macro2 Name="LCLWidgetType" Value="win32"/> 24 | </MacroValues> 25 | <CompilerOptions> 26 | <Version Value="11"/> 27 | <Target> 28 | <Filename Value="simple32"/> 29 | </Target> 30 | <SearchPaths> 31 | <IncludeFiles Value="$(ProjOutDir)"/> 32 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 33 | </SearchPaths> 34 | <Parsing> 35 | <SyntaxOptions> 36 | <AllowLabel Value="False"/> 37 | </SyntaxOptions> 38 | </Parsing> 39 | <CodeGeneration> 40 | <RelocatableUnit Value="True"/> 41 | <Checks> 42 | <IOChecks Value="True"/> 43 | <RangeChecks Value="True"/> 44 | <OverflowChecks Value="True"/> 45 | </Checks> 46 | <TargetCPU Value="i386"/> 47 | <TargetOS Value="win32"/> 48 | </CodeGeneration> 49 | <Linking> 50 | <Options> 51 | <Win32> 52 | <GraphicApplication Value="True"/> 53 | </Win32> 54 | </Options> 55 | </Linking> 56 | </CompilerOptions> 57 | </Item2> 58 | <Item3 Name="Win64"> 59 | <MacroValues Count="1"> 60 | <Macro2 Name="LCLWidgetType" Value="win32"/> 61 | </MacroValues> 62 | <CompilerOptions> 63 | <Version Value="11"/> 64 | <Target> 65 | <Filename Value="simple64"/> 66 | </Target> 67 | <SearchPaths> 68 | <IncludeFiles Value="$(ProjOutDir)"/> 69 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 70 | </SearchPaths> 71 | <Parsing> 72 | <SyntaxOptions> 73 | <AllowLabel Value="False"/> 74 | </SyntaxOptions> 75 | </Parsing> 76 | <CodeGeneration> 77 | <RelocatableUnit Value="True"/> 78 | <Checks> 79 | <IOChecks Value="True"/> 80 | <RangeChecks Value="True"/> 81 | <OverflowChecks Value="True"/> 82 | </Checks> 83 | <TargetCPU Value="x86_64"/> 84 | <TargetOS Value="win64"/> 85 | </CodeGeneration> 86 | <Linking> 87 | <Options> 88 | <Win32> 89 | <GraphicApplication Value="True"/> 90 | </Win32> 91 | </Options> 92 | </Linking> 93 | </CompilerOptions> 94 | </Item3> 95 | <Item4 Name="macOS"> 96 | <MacroValues Count="1"> 97 | <Macro3 Name="LCLWidgetType" Value="cocoa"/> 98 | </MacroValues> 99 | <CompilerOptions> 100 | <Version Value="11"/> 101 | <Target> 102 | <Filename Value="simple"/> 103 | </Target> 104 | <SearchPaths> 105 | <IncludeFiles Value="$(ProjOutDir)"/> 106 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 107 | </SearchPaths> 108 | <Parsing> 109 | <SyntaxOptions> 110 | <IncludeAssertionCode Value="True"/> 111 | <AllowLabel Value="False"/> 112 | </SyntaxOptions> 113 | </Parsing> 114 | <CodeGeneration> 115 | <Checks> 116 | <IOChecks Value="True"/> 117 | <RangeChecks Value="True"/> 118 | <OverflowChecks Value="True"/> 119 | <StackChecks Value="True"/> 120 | </Checks> 121 | <TargetCPU Value="x86_64"/> 122 | <TargetOS Value="darwin"/> 123 | </CodeGeneration> 124 | <Linking> 125 | <Options> 126 | <Win32> 127 | <GraphicApplication Value="True"/> 128 | </Win32> 129 | </Options> 130 | </Linking> 131 | <Other> 132 | <ExecuteAfter> 133 | <Command Value="cp "$Name($(TargetFile))" "$Name($(TargetFile)).app/Contents/MacOS/""/> 134 | <CompileReasons Run="False"/> 135 | </ExecuteAfter> 136 | </Other> 137 | </CompilerOptions> 138 | </Item4> 139 | <SharedMatrixOptions Count="3"> 140 | <Item1 ID="322204415983" Modes="Linux" Type="IDEMacro" MacroName="LCLWidgetType" Value="gtk2"/> 141 | <Item2 ID="279904151772" Modes="Win32,Win64" Type="IDEMacro" MacroName="LCLWidgetType" Value="win32"/> 142 | <Item3 ID="264896071101" Modes="macOS" Type="IDEMacro" MacroName="LCLWidgetType" Value="cocoa"/> 143 | </SharedMatrixOptions> 144 | </BuildModes> 145 | <PublishOptions> 146 | <Version Value="2"/> 147 | <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> 148 | <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/> 149 | </PublishOptions> 150 | <RunParams> 151 | <local> 152 | <FormatVersion Value="1"/> 153 | </local> 154 | <environment> 155 | <UserOverrides Count="1"> 156 | <Variable0 Name="LD_LIBRARY_PATH" Value="."/> 157 | </UserOverrides> 158 | </environment> 159 | </RunParams> 160 | <RequiredPackages Count="2"> 161 | <Item1> 162 | <PackageName Value="CEF3"/> 163 | </Item1> 164 | <Item2> 165 | <PackageName Value="LCL"/> 166 | </Item2> 167 | </RequiredPackages> 168 | <Units Count="2"> 169 | <Unit0> 170 | <Filename Value="simple.lpr"/> 171 | <IsPartOfProject Value="True"/> 172 | </Unit0> 173 | <Unit1> 174 | <Filename Value="main.pas"/> 175 | <IsPartOfProject Value="True"/> 176 | <ComponentName Value="Mainform"/> 177 | <HasResources Value="True"/> 178 | <ResourceBaseClass Value="Form"/> 179 | <UnitName Value="Main"/> 180 | </Unit1> 181 | </Units> 182 | </ProjectOptions> 183 | <CompilerOptions> 184 | <Version Value="11"/> 185 | <Target> 186 | <Filename Value="simple"/> 187 | </Target> 188 | <SearchPaths> 189 | <IncludeFiles Value="$(ProjOutDir)"/> 190 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 191 | </SearchPaths> 192 | <Parsing> 193 | <SyntaxOptions> 194 | <IncludeAssertionCode Value="True"/> 195 | <AllowLabel Value="False"/> 196 | </SyntaxOptions> 197 | </Parsing> 198 | <CodeGeneration> 199 | <Checks> 200 | <IOChecks Value="True"/> 201 | <RangeChecks Value="True"/> 202 | <OverflowChecks Value="True"/> 203 | <StackChecks Value="True"/> 204 | </Checks> 205 | <TargetOS Value="linux"/> 206 | </CodeGeneration> 207 | <Linking> 208 | <Options> 209 | <Win32> 210 | <GraphicApplication Value="True"/> 211 | </Win32> 212 | </Options> 213 | </Linking> 214 | </CompilerOptions> 215 | <Debugging> 216 | <Exceptions Count="3"> 217 | <Item1> 218 | <Name Value="EAbort"/> 219 | </Item1> 220 | <Item2> 221 | <Name Value="ECodetoolError"/> 222 | </Item2> 223 | <Item3> 224 | <Name Value="EFOpenError"/> 225 | </Item3> 226 | </Exceptions> 227 | </Debugging> 228 | </CONFIG> 229 | -------------------------------------------------------------------------------- /Examples/OSRDemo/osrdemo.lpi: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <CONFIG> 3 | <ProjectOptions> 4 | <Version Value="10"/> 5 | <General> 6 | <SessionStorage Value="InProjectDir"/> 7 | <MainUnit Value="0"/> 8 | <Title Value="osrdemo"/> 9 | <ResourceType Value="res"/> 10 | <UseXPManifest Value="True"/> 11 | <Icon Value="0"/> 12 | </General> 13 | <i18n> 14 | <EnableI18N LFM="False"/> 15 | </i18n> 16 | <MacroValues Count="1"> 17 | <Macro1 Name="LCLWidgetType" Value="gtk2"/> 18 | </MacroValues> 19 | <BuildModes Count="4"> 20 | <Item1 Name="Linux" Default="True"/> 21 | <Item2 Name="Win32"> 22 | <MacroValues Count="1"> 23 | <Macro2 Name="LCLWidgetType" Value="win32"/> 24 | </MacroValues> 25 | <CompilerOptions> 26 | <Version Value="11"/> 27 | <Target> 28 | <Filename Value="osrdemo32"/> 29 | </Target> 30 | <SearchPaths> 31 | <IncludeFiles Value="$(ProjOutDir)"/> 32 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 33 | </SearchPaths> 34 | <Parsing> 35 | <SyntaxOptions> 36 | <AllowLabel Value="False"/> 37 | </SyntaxOptions> 38 | </Parsing> 39 | <CodeGeneration> 40 | <RelocatableUnit Value="True"/> 41 | <Checks> 42 | <IOChecks Value="True"/> 43 | <RangeChecks Value="True"/> 44 | <OverflowChecks Value="True"/> 45 | </Checks> 46 | <TargetCPU Value="i386"/> 47 | <TargetOS Value="win32"/> 48 | </CodeGeneration> 49 | <Linking> 50 | <Options> 51 | <Win32> 52 | <GraphicApplication Value="True"/> 53 | </Win32> 54 | </Options> 55 | </Linking> 56 | </CompilerOptions> 57 | </Item2> 58 | <Item3 Name="Win64"> 59 | <MacroValues Count="1"> 60 | <Macro2 Name="LCLWidgetType" Value="win32"/> 61 | </MacroValues> 62 | <CompilerOptions> 63 | <Version Value="11"/> 64 | <Target> 65 | <Filename Value="osrdemo64"/> 66 | </Target> 67 | <SearchPaths> 68 | <IncludeFiles Value="$(ProjOutDir)"/> 69 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 70 | </SearchPaths> 71 | <Parsing> 72 | <SyntaxOptions> 73 | <AllowLabel Value="False"/> 74 | </SyntaxOptions> 75 | </Parsing> 76 | <CodeGeneration> 77 | <RelocatableUnit Value="True"/> 78 | <Checks> 79 | <IOChecks Value="True"/> 80 | <RangeChecks Value="True"/> 81 | <OverflowChecks Value="True"/> 82 | </Checks> 83 | <TargetCPU Value="x86_64"/> 84 | <TargetOS Value="win64"/> 85 | </CodeGeneration> 86 | <Linking> 87 | <Options> 88 | <Win32> 89 | <GraphicApplication Value="True"/> 90 | </Win32> 91 | </Options> 92 | </Linking> 93 | </CompilerOptions> 94 | </Item3> 95 | <Item4 Name="macOS"> 96 | <MacroValues Count="1"> 97 | <Macro3 Name="LCLWidgetType" Value="cocoa"/> 98 | </MacroValues> 99 | <CompilerOptions> 100 | <Version Value="11"/> 101 | <Target> 102 | <Filename Value="osrdemo"/> 103 | </Target> 104 | <SearchPaths> 105 | <IncludeFiles Value="$(ProjOutDir)"/> 106 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 107 | </SearchPaths> 108 | <Parsing> 109 | <SyntaxOptions> 110 | <IncludeAssertionCode Value="True"/> 111 | <AllowLabel Value="False"/> 112 | </SyntaxOptions> 113 | </Parsing> 114 | <CodeGeneration> 115 | <Checks> 116 | <IOChecks Value="True"/> 117 | <RangeChecks Value="True"/> 118 | <OverflowChecks Value="True"/> 119 | <StackChecks Value="True"/> 120 | </Checks> 121 | <TargetCPU Value="x86_64"/> 122 | <TargetOS Value="darwin"/> 123 | </CodeGeneration> 124 | <Linking> 125 | <Options> 126 | <Win32> 127 | <GraphicApplication Value="True"/> 128 | </Win32> 129 | </Options> 130 | </Linking> 131 | <Other> 132 | <ExecuteAfter> 133 | <Command Value="cp "$Name($(TargetFile))" "$Name($(TargetFile)).app/Contents/MacOS/""/> 134 | <CompileReasons Run="False"/> 135 | </ExecuteAfter> 136 | </Other> 137 | </CompilerOptions> 138 | </Item4> 139 | <SharedMatrixOptions Count="3"> 140 | <Item1 ID="661871476567" Modes="Linux" Type="IDEMacro" MacroName="LCLWidgetType" Value="gtk2"/> 141 | <Item2 ID="279904151772" Modes="Win32,Win64" Type="IDEMacro" MacroName="LCLWidgetType" Value="win32"/> 142 | <Item3 ID="567945758664" Modes="macOS" Type="IDEMacro" MacroName="LCLWidgetType" Value="cocoa"/> 143 | </SharedMatrixOptions> 144 | </BuildModes> 145 | <PublishOptions> 146 | <Version Value="2"/> 147 | <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> 148 | <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/> 149 | </PublishOptions> 150 | <RunParams> 151 | <local> 152 | <FormatVersion Value="1"/> 153 | </local> 154 | <environment> 155 | <UserOverrides Count="1"> 156 | <Variable0 Name="LD_LIBRARY_PATH" Value="."/> 157 | </UserOverrides> 158 | </environment> 159 | </RunParams> 160 | <RequiredPackages Count="3"> 161 | <Item1> 162 | <PackageName Value="LazOpenGLContext"/> 163 | </Item1> 164 | <Item2> 165 | <PackageName Value="CEF3"/> 166 | </Item2> 167 | <Item3> 168 | <PackageName Value="LCL"/> 169 | </Item3> 170 | </RequiredPackages> 171 | <Units Count="2"> 172 | <Unit0> 173 | <Filename Value="osrdemo.lpr"/> 174 | <IsPartOfProject Value="True"/> 175 | </Unit0> 176 | <Unit1> 177 | <Filename Value="main.pas"/> 178 | <IsPartOfProject Value="True"/> 179 | <ComponentName Value="Mainform"/> 180 | <HasResources Value="True"/> 181 | <ResourceBaseClass Value="Form"/> 182 | <UnitName Value="Main"/> 183 | </Unit1> 184 | </Units> 185 | </ProjectOptions> 186 | <CompilerOptions> 187 | <Version Value="11"/> 188 | <Target> 189 | <Filename Value="osrdemo"/> 190 | </Target> 191 | <SearchPaths> 192 | <IncludeFiles Value="$(ProjOutDir)"/> 193 | <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 194 | </SearchPaths> 195 | <Parsing> 196 | <SyntaxOptions> 197 | <IncludeAssertionCode Value="True"/> 198 | <AllowLabel Value="False"/> 199 | </SyntaxOptions> 200 | </Parsing> 201 | <CodeGeneration> 202 | <Checks> 203 | <IOChecks Value="True"/> 204 | <RangeChecks Value="True"/> 205 | <OverflowChecks Value="True"/> 206 | <StackChecks Value="True"/> 207 | </Checks> 208 | <TargetCPU Value="x86_64"/> 209 | <TargetOS Value="linux"/> 210 | </CodeGeneration> 211 | <Linking> 212 | <Options> 213 | <Win32> 214 | <GraphicApplication Value="True"/> 215 | </Win32> 216 | </Options> 217 | </Linking> 218 | </CompilerOptions> 219 | <Debugging> 220 | <Exceptions Count="3"> 221 | <Item1> 222 | <Name Value="EAbort"/> 223 | </Item1> 224 | <Item2> 225 | <Name Value="ECodetoolError"/> 226 | </Item2> 227 | <Item3> 228 | <Name Value="EFOpenError"/> 229 | </Item3> 230 | </Exceptions> 231 | </Debugging> 232 | </CONFIG> 233 | -------------------------------------------------------------------------------- /Examples/OSRDemo/main.pas: -------------------------------------------------------------------------------- 1 | Unit Main; 2 | 3 | {$MODE objfpc}{$H+} 4 | 5 | Interface 6 | 7 | Uses 8 | Classes, SysUtils, FileUtil, OpenGLContext, Forms, Controls, Graphics, Dialogs, StdCtrls, LCLType, 9 | GL, GLext, 10 | cef3types, cef3lib, cef3intf, cef3osr; 11 | 12 | Type 13 | 14 | { TMainform } 15 | 16 | TMainform = class(TForm) 17 | BGo : TButton; 18 | CBAnimate: TCheckBox; 19 | CBShowUpdate: TCheckBox; 20 | Chromium : TChromiumOSR; 21 | EUrl : TEdit; 22 | LUrl : TStaticText; 23 | OSRPanel: TOpenGLControl; 24 | procedure AppOnIdle(Sender: TObject; var Done: Boolean); 25 | procedure BGoClick(Sender : TObject); 26 | procedure CBAnimateChange(Sender: TObject); 27 | procedure ChromiumGetScreenPoint(Sender: TObject; const Browser: ICefBrowser; 28 | viewX, viewY: Integer; screenX, screenY: PInteger; out Result: Boolean); 29 | procedure ChromiumGetViewRect(Sender : TObject; 30 | const Browser : ICefBrowser; rect : PCefRect; out Result : Boolean); 31 | procedure ChromiumPaint(Sender : TObject; const Browser : ICefBrowser; kind : TCefPaintElementType; 32 | dirtyRectsCount : Cardinal; const dirtyRects : TCefRectArray; const buffer : Pointer; 33 | awidth, aheight : Integer); 34 | procedure EUrlKeyDown(Sender : TObject; var Key : Word; 35 | Shift : TShiftState); 36 | procedure FormCreate(Sender : TObject); 37 | procedure FormDestroy(Sender: TObject); 38 | procedure OSRPanelEnter(Sender: TObject); 39 | procedure OSRPanelExit(Sender: TObject); 40 | procedure OSRPanelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; 41 | X, Y: Integer); 42 | procedure OSRPanelMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); 43 | procedure OSRPanelMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; 44 | X, Y: Integer); 45 | procedure OSRPanelMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; 46 | MousePos: TPoint; var Handled: Boolean); 47 | procedure OSRPanelPaint(Sender: TObject); 48 | procedure OSRPanelResize(Sender: TObject); 49 | private 50 | fGLInitialized: Boolean; 51 | fTextureID: GLuint; 52 | fTextureWidth, fTextureHeigth: Integer; 53 | fUpdateRect: TCefRect; 54 | 55 | procedure InitializeGL; 56 | public 57 | { public declarations } 58 | end; 59 | 60 | Var 61 | Mainform : TMainform; 62 | 63 | Implementation 64 | 65 | {$R *.lfm} 66 | 67 | function getModifiers(const Shift: TShiftState): TCefEventFlags; 68 | begin 69 | Result := []; 70 | If ssShift in Shift then Include(Result, EVENTFLAG_SHIFT_DOWN); 71 | If ssCaps in Shift then Include(Result, EVENTFLAG_CAPS_LOCK_ON); 72 | If ssCtrl in Shift then Include(Result, EVENTFLAG_CONTROL_DOWN); 73 | If ssAlt in Shift then Include(Result, EVENTFLAG_ALT_DOWN); 74 | If ssLeft in Shift then Include(Result, EVENTFLAG_LEFT_MOUSE_BUTTON); 75 | If ssMiddle in Shift then Include(Result, EVENTFLAG_MIDDLE_MOUSE_BUTTON); 76 | If ssRight in Shift then Include(Result, EVENTFLAG_RIGHT_MOUSE_BUTTON); 77 | end; 78 | 79 | function getButton(const Button: TMouseButton): TCefMouseButtonType; 80 | begin 81 | Case Button of 82 | TMouseButton.mbLeft: Result := MBT_LEFT; 83 | TMouseButton.mbRight: Result := MBT_RIGHT; 84 | TMouseButton.mbMiddle: Result := MBT_MIDDLE; 85 | end; 86 | end; 87 | 88 | { TMainform } 89 | 90 | procedure TMainform.AppOnIdle(Sender: TObject; var Done: Boolean); 91 | begin 92 | OSRPanel.Invalidate; 93 | end; 94 | 95 | procedure TMainform.BGoClick(Sender : TObject); 96 | begin 97 | Chromium.Load(EUrl.Text); 98 | end; 99 | 100 | procedure TMainform.CBAnimateChange(Sender: TObject); 101 | begin 102 | If CBAnimate.Checked then Application.OnIdle := @AppOnIdle 103 | Else 104 | begin 105 | Application.OnIdle := nil; 106 | OSRPanel.Invalidate; 107 | end; 108 | end; 109 | 110 | procedure TMainform.ChromiumGetScreenPoint(Sender: TObject; const Browser: ICefBrowser; 111 | viewX, viewY: Integer; screenX, screenY: PInteger; out Result: Boolean); 112 | Var 113 | Point: TPoint; 114 | begin 115 | Point.X := viewX; 116 | Point.Y := viewY; 117 | 118 | Point := OSRPanel.ClientToScreen(Point); 119 | 120 | screenX^ := Point.X; 121 | screenY^ := Point.Y; 122 | 123 | Result := True; 124 | end; 125 | 126 | procedure TMainform.ChromiumGetViewRect(Sender : TObject; const Browser : ICefBrowser; 127 | rect : PCefRect; out Result : Boolean); 128 | begin 129 | rect^.x := 0; 130 | rect^.y := 0; 131 | rect^.width := OSRPanel.Width; 132 | rect^.height := OSRPanel.Height; 133 | 134 | Result := True; 135 | end; 136 | 137 | procedure TMainform.ChromiumPaint(Sender: TObject; const Browser: ICefBrowser; 138 | kind: TCefPaintElementType; dirtyRectsCount: Cardinal; const dirtyRects: TCefRectArray; 139 | const buffer: Pointer; awidth, aheight: Integer); 140 | 141 | function RectIsFullView(const Rect: TCefRect): Boolean; 142 | begin 143 | Result := (Rect.x = 0) and (Rect.y = 0) and (Rect.width = awidth) and (Rect.height = aheight); 144 | end; 145 | 146 | Var 147 | i: Integer; 148 | ARect: TCefRect; 149 | 150 | begin 151 | If not fGLInitialized then InitializeGL; 152 | 153 | // enable alpha blending 154 | glEnable(GL_BLEND); 155 | 156 | // enable 2D textures 157 | glEnable(GL_TEXTURE_2D); 158 | glBindTexture(GL_TEXTURE_2D, fTextureID); 159 | 160 | If kind = PET_VIEW then 161 | begin 162 | 163 | If CBShowUpdate.Checked then fUpdateRect := dirtyRects[0]; 164 | 165 | glPixelStorei(GL_UNPACK_ROW_LENGTH, awidth); 166 | 167 | If (fTextureWidth <> awidth) or (fTextureHeigth <> aheight) or 168 | ((dirtyRectsCount = 1) and RectIsFullView(dirtyRects[0])) then 169 | begin 170 | // update / resize the whole texture 171 | 172 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); 173 | glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); 174 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, awidth, aheight, 0, GL_BGRA, 175 | GL_UNSIGNED_INT_8_8_8_8_REV, buffer); 176 | 177 | fTextureWidth := awidth; 178 | fTextureHeigth := aheight; 179 | end 180 | Else 181 | begin 182 | // update just the dirty rectangles 183 | For i := 0 to dirtyRectsCount - 1 do 184 | begin 185 | ARect := dirtyRects[i]; 186 | 187 | Assert(ARect.x + ARect.width <= fTextureWidth); 188 | Assert(Arect.y + ARect.height <= fTextureHeigth); 189 | 190 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, ARect.x); 191 | glPixelStorei(GL_UNPACK_SKIP_ROWS, ARect.y); 192 | glTexSubImage2D(GL_TEXTURE_2D, 0, ARect.x, ARect.y, ARect.width, ARect.height, 193 | GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buffer); 194 | end; 195 | end; 196 | end; 197 | 198 | // disable 2D textures. 199 | glDisable(GL_TEXTURE_2D); 200 | 201 | // disable alpha blending 202 | glDisable(GL_BLEND); 203 | 204 | OSRPanel.Invalidate; 205 | end; 206 | 207 | procedure TMainform.EUrlKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); 208 | begin 209 | If Key = VK_RETURN then BGoClick(Sender); 210 | end; 211 | 212 | procedure TMainform.FormCreate(Sender : TObject); 213 | begin 214 | fTextureWidth := 0; 215 | fTextureHeigth := 0; 216 | 217 | CBAnimateChange(Self); 218 | end; 219 | 220 | procedure TMainform.FormDestroy(Sender: TObject); 221 | begin 222 | If fGLInitialized then glDeleteTextures(1, @fTextureID); 223 | end; 224 | 225 | procedure TMainform.OSRPanelEnter(Sender: TObject); 226 | begin 227 | Chromium.Browser.Host.SendFocusEvent(True); 228 | end; 229 | 230 | procedure TMainform.OSRPanelExit(Sender: TObject); 231 | begin 232 | Chromium.Browser.Host.SendFocusEvent(False); 233 | end; 234 | 235 | procedure TMainform.OSRPanelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; 236 | X, Y: Integer); 237 | Var 238 | MouseEvent: TCefMouseEvent; 239 | begin 240 | OSRPanel.SetFocus; 241 | 242 | MouseEvent.x := X; 243 | MouseEvent.y := Y; 244 | MouseEvent.modifiers := getModifiers(Shift); 245 | 246 | Chromium.Browser.Host.SendMouseClickEvent(MouseEvent, getButton(Button), False, 1); 247 | end; 248 | 249 | procedure TMainform.OSRPanelMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); 250 | Var 251 | MouseEvent: TCefMouseEvent; 252 | begin 253 | MouseEvent.x := X; 254 | MouseEvent.y := Y; 255 | MouseEvent.modifiers := getModifiers(Shift); 256 | 257 | Chromium.Browser.Host.SendMouseMoveEvent(MouseEvent, not OSRPanel.MouseEntered); 258 | end; 259 | 260 | procedure TMainform.OSRPanelMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; 261 | X, Y: Integer); 262 | Var 263 | MouseEvent: TCefMouseEvent; 264 | ClickCount: Integer; 265 | begin 266 | MouseEvent.x := X; 267 | MouseEvent.y := Y; 268 | MouseEvent.modifiers := getModifiers(Shift); 269 | 270 | ClickCount := 1; 271 | If ssDouble in Shift then ClickCount := 2; 272 | If ssTriple in Shift then ClickCount := 3; 273 | If ssQuad in Shift then ClickCount := 4; 274 | 275 | Chromium.Browser.Host.SendMouseClickEvent(MouseEvent, getButton(Button), True, ClickCount); 276 | end; 277 | 278 | procedure TMainform.OSRPanelMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; 279 | MousePos: TPoint; var Handled: Boolean); 280 | Var 281 | MouseEvent: TCefMouseEvent; 282 | begin 283 | MouseEvent.x := MousePos.X; 284 | MouseEvent.y := MousePos.Y; 285 | MouseEvent.modifiers := getModifiers(Shift); 286 | 287 | Chromium.Browser.Host.SendMouseWheelEvent(MouseEvent, 0, WheelDelta); 288 | Handled := True; 289 | end; 290 | 291 | procedure TMainform.OSRPanelPaint(Sender: TObject); 292 | 293 | function RectEmpty(const ARect: TCefRect): Boolean; 294 | begin 295 | Result := (ARect.x = 0) and (ARect.y = 0) and (ARect.width = 0) and (ARect.height = 0); 296 | end; 297 | 298 | Type 299 | TVertex = packed record 300 | tu, tv: Single; 301 | x, y, z: Single; 302 | end; 303 | Const 304 | Vertices : array[0..3] of TVertex = ( 305 | (tu: 0.0; tv: 1.0; x: -1.0; y: -1.0; z: 0.0), 306 | (tu: 1.0; tv: 1.0; x: 1.0; y: -1.0; z: 0.0), 307 | (tu: 1.0; tv: 0.0; x: 1.0; y: 1.0; z: 0.0), 308 | (tu: 0.0; tv: 0.0; x: -1.0; y: 1.0; z: 0.0) 309 | ); 310 | Var 311 | ULeft, URight, UTop, UBottom: Integer; 312 | begin 313 | If not fGLInitialized then Exit; 314 | 315 | glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); 316 | 317 | glMatrixMode(GL_MODELVIEW); 318 | glLoadIdentity(); 319 | 320 | // Match GL units to screen coordinates. 321 | glViewport(0, 0, OSRPanel.Width, OSRPanel.Height); 322 | glMatrixMode(GL_PROJECTION); 323 | glLoadIdentity(); 324 | 325 | // rotate the view 326 | If CBAnimate.Checked then 327 | begin 328 | glRotatef(20 * sin(GetTickCount64 * 0.001), 1, 0, 0); 329 | glRotatef(20 * cos(GetTickCount64 * 0.001), 0, 1, 0); 330 | end; 331 | 332 | // alpha blending style: texture values have premultiplied alpha 333 | glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 334 | 335 | // enable alpha blending 336 | glEnable(GL_BLEND); 337 | 338 | // enable 2D textures. 339 | glEnable(GL_TEXTURE_2D); 340 | 341 | // draw the facets with the texture. 342 | glBindTexture(GL_TEXTURE_2D, fTextureID); 343 | glInterleavedArrays(GL_T2F_V3F, 0, @Vertices); 344 | glDrawArrays(GL_QUADS, 0, 4); 345 | 346 | // disable 2D textures. 347 | glDisable(GL_TEXTURE_2D); 348 | 349 | // disable alpha blending 350 | glDisable(GL_BLEND); 351 | 352 | 353 | If CBShowUpdate.Checked and not RectEmpty(fUpdateRect) then 354 | begin 355 | // draw a rectangle around the update region 356 | ULeft := fUpdateRect.x + 1; 357 | URight := fUpdateRect.x + fUpdateRect.width; 358 | UTop := fUpdateRect.y; 359 | UBottom := fUpdateRect.y + fUpdateRect.height - 1; 360 | 361 | glPushAttrib(GL_ALL_ATTRIB_BITS); 362 | glMatrixMode(GL_PROJECTION); 363 | glPushMatrix(); 364 | glLoadIdentity(); 365 | glOrtho(0, OSRPanel.Width, OSRPanel.Height, 0, 0, 1); 366 | 367 | glLineWidth(1); 368 | glColor3f(1, 0, 0); 369 | 370 | glBegin(GL_LINE_STRIP); 371 | glVertex2i(ULeft, UTop); 372 | glVertex2i(URight, UTop); 373 | glVertex2i(URight, UBottom); 374 | glVertex2i(ULeft, UBottom); 375 | glVertex2i(ULeft, UTop); 376 | glEnd(); 377 | 378 | glPopMatrix(); 379 | glPopAttrib(); 380 | end; 381 | 382 | OSRPanel.SwapBuffers; 383 | end; 384 | 385 | procedure TMainform.OSRPanelResize(Sender: TObject); 386 | begin 387 | Chromium.Browser.Host.WasResized; 388 | end; 389 | 390 | procedure TMainform.InitializeGL; 391 | Var 392 | BC: TColor; 393 | begin 394 | glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); 395 | 396 | BC := Chromium.BackgroundColor; 397 | glClearColor(Red(BC) / 255, Green(BC) / 255, Blue(BC) / 255, 1); 398 | 399 | // necessary for non-power-of-2 textures to render correctly 400 | glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 401 | 402 | // create the texture 403 | glGenTextures(1, @fTextureID); 404 | 405 | glBindTexture(GL_TEXTURE_2D, fTextureID); 406 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 407 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 408 | glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 409 | 410 | fGLInitialized := True; 411 | end; 412 | 413 | Initialization 414 | {$IFNDEF DARWIN} 415 | {$INFO subprocess is set here, uncomment to use a subprocess} 416 | //CefBrowserSubprocessPath := '.' + PathDelim + 'subprocess'{$IFDEF WINDOWS}+'.exe'{$ENDIF}; 417 | {$ENDIF} 418 | 419 | end. 420 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Mozilla Public License Version 2.0 2 | ================================== 3 | 4 | 1. Definitions 5 | -------------- 6 | 7 | 1.1. "Contributor" 8 | means each individual or legal entity that creates, contributes to 9 | the creation of, or owns Covered Software. 10 | 11 | 1.2. "Contributor Version" 12 | means the combination of the Contributions of others (if any) used 13 | by a Contributor and that particular Contributor's Contribution. 14 | 15 | 1.3. "Contribution" 16 | means Covered Software of a particular Contributor. 17 | 18 | 1.4. "Covered Software" 19 | means Source Code Form to which the initial Contributor has attached 20 | the notice in Exhibit A, the Executable Form of such Source Code 21 | Form, and Modifications of such Source Code Form, in each case 22 | including portions thereof. 23 | 24 | 1.5. "Incompatible With Secondary Licenses" 25 | means 26 | 27 | (a) that the initial Contributor has attached the notice described 28 | in Exhibit B to the Covered Software; or 29 | 30 | (b) that the Covered Software was made available under the terms of 31 | version 1.1 or earlier of the License, but not also under the 32 | terms of a Secondary License. 33 | 34 | 1.6. "Executable Form" 35 | means any form of the work other than Source Code Form. 36 | 37 | 1.7. "Larger Work" 38 | means a work that combines Covered Software with other material, in 39 | a separate file or files, that is not Covered Software. 40 | 41 | 1.8. "License" 42 | means this document. 43 | 44 | 1.9. "Licensable" 45 | means having the right to grant, to the maximum extent possible, 46 | whether at the time of the initial grant or subsequently, any and 47 | all of the rights conveyed by this License. 48 | 49 | 1.10. "Modifications" 50 | means any of the following: 51 | 52 | (a) any file in Source Code Form that results from an addition to, 53 | deletion from, or modification of the contents of Covered 54 | Software; or 55 | 56 | (b) any new file in Source Code Form that contains any Covered 57 | Software. 58 | 59 | 1.11. "Patent Claims" of a Contributor 60 | means any patent claim(s), including without limitation, method, 61 | process, and apparatus claims, in any patent Licensable by such 62 | Contributor that would be infringed, but for the grant of the 63 | License, by the making, using, selling, offering for sale, having 64 | made, import, or transfer of either its Contributions or its 65 | Contributor Version. 66 | 67 | 1.12. "Secondary License" 68 | means either the GNU General Public License, Version 2.0, the GNU 69 | Lesser General Public License, Version 2.1, the GNU Affero General 70 | Public License, Version 3.0, or any later versions of those 71 | licenses. 72 | 73 | 1.13. "Source Code Form" 74 | means the form of the work preferred for making modifications. 75 | 76 | 1.14. "You" (or "Your") 77 | means an individual or a legal entity exercising rights under this 78 | License. For legal entities, "You" includes any entity that 79 | controls, is controlled by, or is under common control with You. For 80 | purposes of this definition, "control" means (a) the power, direct 81 | or indirect, to cause the direction or management of such entity, 82 | whether by contract or otherwise, or (b) ownership of more than 83 | fifty percent (50%) of the outstanding shares or beneficial 84 | ownership of such entity. 85 | 86 | 2. License Grants and Conditions 87 | -------------------------------- 88 | 89 | 2.1. Grants 90 | 91 | Each Contributor hereby grants You a world-wide, royalty-free, 92 | non-exclusive license: 93 | 94 | (a) under intellectual property rights (other than patent or trademark) 95 | Licensable by such Contributor to use, reproduce, make available, 96 | modify, display, perform, distribute, and otherwise exploit its 97 | Contributions, either on an unmodified basis, with Modifications, or 98 | as part of a Larger Work; and 99 | 100 | (b) under Patent Claims of such Contributor to make, use, sell, offer 101 | for sale, have made, import, and otherwise transfer either its 102 | Contributions or its Contributor Version. 103 | 104 | 2.2. Effective Date 105 | 106 | The licenses granted in Section 2.1 with respect to any Contribution 107 | become effective for each Contribution on the date the Contributor first 108 | distributes such Contribution. 109 | 110 | 2.3. Limitations on Grant Scope 111 | 112 | The licenses granted in this Section 2 are the only rights granted under 113 | this License. No additional rights or licenses will be implied from the 114 | distribution or licensing of Covered Software under this License. 115 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 116 | Contributor: 117 | 118 | (a) for any code that a Contributor has removed from Covered Software; 119 | or 120 | 121 | (b) for infringements caused by: (i) Your and any other third party's 122 | modifications of Covered Software, or (ii) the combination of its 123 | Contributions with other software (except as part of its Contributor 124 | Version); or 125 | 126 | (c) under Patent Claims infringed by Covered Software in the absence of 127 | its Contributions. 128 | 129 | This License does not grant any rights in the trademarks, service marks, 130 | or logos of any Contributor (except as may be necessary to comply with 131 | the notice requirements in Section 3.4). 132 | 133 | 2.4. Subsequent Licenses 134 | 135 | No Contributor makes additional grants as a result of Your choice to 136 | distribute the Covered Software under a subsequent version of this 137 | License (see Section 10.2) or under the terms of a Secondary License (if 138 | permitted under the terms of Section 3.3). 139 | 140 | 2.5. Representation 141 | 142 | Each Contributor represents that the Contributor believes its 143 | Contributions are its original creation(s) or it has sufficient rights 144 | to grant the rights to its Contributions conveyed by this License. 145 | 146 | 2.6. Fair Use 147 | 148 | This License is not intended to limit any rights You have under 149 | applicable copyright doctrines of fair use, fair dealing, or other 150 | equivalents. 151 | 152 | 2.7. Conditions 153 | 154 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 155 | in Section 2.1. 156 | 157 | 3. Responsibilities 158 | ------------------- 159 | 160 | 3.1. Distribution of Source Form 161 | 162 | All distribution of Covered Software in Source Code Form, including any 163 | Modifications that You create or to which You contribute, must be under 164 | the terms of this License. You must inform recipients that the Source 165 | Code Form of the Covered Software is governed by the terms of this 166 | License, and how they can obtain a copy of this License. You may not 167 | attempt to alter or restrict the recipients' rights in the Source Code 168 | Form. 169 | 170 | 3.2. Distribution of Executable Form 171 | 172 | If You distribute Covered Software in Executable Form then: 173 | 174 | (a) such Covered Software must also be made available in Source Code 175 | Form, as described in Section 3.1, and You must inform recipients of 176 | the Executable Form how they can obtain a copy of such Source Code 177 | Form by reasonable means in a timely manner, at a charge no more 178 | than the cost of distribution to the recipient; and 179 | 180 | (b) You may distribute such Executable Form under the terms of this 181 | License, or sublicense it under different terms, provided that the 182 | license for the Executable Form does not attempt to limit or alter 183 | the recipients' rights in the Source Code Form under this License. 184 | 185 | 3.3. Distribution of a Larger Work 186 | 187 | You may create and distribute a Larger Work under terms of Your choice, 188 | provided that You also comply with the requirements of this License for 189 | the Covered Software. If the Larger Work is a combination of Covered 190 | Software with a work governed by one or more Secondary Licenses, and the 191 | Covered Software is not Incompatible With Secondary Licenses, this 192 | License permits You to additionally distribute such Covered Software 193 | under the terms of such Secondary License(s), so that the recipient of 194 | the Larger Work may, at their option, further distribute the Covered 195 | Software under the terms of either this License or such Secondary 196 | License(s). 197 | 198 | 3.4. Notices 199 | 200 | You may not remove or alter the substance of any license notices 201 | (including copyright notices, patent notices, disclaimers of warranty, 202 | or limitations of liability) contained within the Source Code Form of 203 | the Covered Software, except that You may alter any license notices to 204 | the extent required to remedy known factual inaccuracies. 205 | 206 | 3.5. Application of Additional Terms 207 | 208 | You may choose to offer, and to charge a fee for, warranty, support, 209 | indemnity or liability obligations to one or more recipients of Covered 210 | Software. However, You may do so only on Your own behalf, and not on 211 | behalf of any Contributor. You must make it absolutely clear that any 212 | such warranty, support, indemnity, or liability obligation is offered by 213 | You alone, and You hereby agree to indemnify every Contributor for any 214 | liability incurred by such Contributor as a result of warranty, support, 215 | indemnity or liability terms You offer. You may include additional 216 | disclaimers of warranty and limitations of liability specific to any 217 | jurisdiction. 218 | 219 | 4. Inability to Comply Due to Statute or Regulation 220 | --------------------------------------------------- 221 | 222 | If it is impossible for You to comply with any of the terms of this 223 | License with respect to some or all of the Covered Software due to 224 | statute, judicial order, or regulation then You must: (a) comply with 225 | the terms of this License to the maximum extent possible; and (b) 226 | describe the limitations and the code they affect. Such description must 227 | be placed in a text file included with all distributions of the Covered 228 | Software under this License. Except to the extent prohibited by statute 229 | or regulation, such description must be sufficiently detailed for a 230 | recipient of ordinary skill to be able to understand it. 231 | 232 | 5. Termination 233 | -------------- 234 | 235 | 5.1. The rights granted under this License will terminate automatically 236 | if You fail to comply with any of its terms. However, if You become 237 | compliant, then the rights granted under this License from a particular 238 | Contributor are reinstated (a) provisionally, unless and until such 239 | Contributor explicitly and finally terminates Your grants, and (b) on an 240 | ongoing basis, if such Contributor fails to notify You of the 241 | non-compliance by some reasonable means prior to 60 days after You have 242 | come back into compliance. Moreover, Your grants from a particular 243 | Contributor are reinstated on an ongoing basis if such Contributor 244 | notifies You of the non-compliance by some reasonable means, this is the 245 | first time You have received notice of non-compliance with this License 246 | from such Contributor, and You become compliant prior to 30 days after 247 | Your receipt of the notice. 248 | 249 | 5.2. If You initiate litigation against any entity by asserting a patent 250 | infringement claim (excluding declaratory judgment actions, 251 | counter-claims, and cross-claims) alleging that a Contributor Version 252 | directly or indirectly infringes any patent, then the rights granted to 253 | You by any and all Contributors for the Covered Software under Section 254 | 2.1 of this License shall terminate. 255 | 256 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all 257 | end user license agreements (excluding distributors and resellers) which 258 | have been validly granted by You or Your distributors under this License 259 | prior to termination shall survive termination. 260 | 261 | ************************************************************************ 262 | * * 263 | * 6. Disclaimer of Warranty * 264 | * ------------------------- * 265 | * * 266 | * Covered Software is provided under this License on an "as is" * 267 | * basis, without warranty of any kind, either expressed, implied, or * 268 | * statutory, including, without limitation, warranties that the * 269 | * Covered Software is free of defects, merchantable, fit for a * 270 | * particular purpose or non-infringing. The entire risk as to the * 271 | * quality and performance of the Covered Software is with You. * 272 | * Should any Covered Software prove defective in any respect, You * 273 | * (not any Contributor) assume the cost of any necessary servicing, * 274 | * repair, or correction. This disclaimer of warranty constitutes an * 275 | * essential part of this License. No use of any Covered Software is * 276 | * authorized under this License except under this disclaimer. * 277 | * * 278 | ************************************************************************ 279 | 280 | ************************************************************************ 281 | * * 282 | * 7. Limitation of Liability * 283 | * -------------------------- * 284 | * * 285 | * Under no circumstances and under no legal theory, whether tort * 286 | * (including negligence), contract, or otherwise, shall any * 287 | * Contributor, or anyone who distributes Covered Software as * 288 | * permitted above, be liable to You for any direct, indirect, * 289 | * special, incidental, or consequential damages of any character * 290 | * including, without limitation, damages for lost profits, loss of * 291 | * goodwill, work stoppage, computer failure or malfunction, or any * 292 | * and all other commercial damages or losses, even if such party * 293 | * shall have been informed of the possibility of such damages. This * 294 | * limitation of liability shall not apply to liability for death or * 295 | * personal injury resulting from such party's negligence to the * 296 | * extent applicable law prohibits such limitation. Some * 297 | * jurisdictions do not allow the exclusion or limitation of * 298 | * incidental or consequential damages, so this exclusion and * 299 | * limitation may not apply to You. * 300 | * * 301 | ************************************************************************ 302 | 303 | 8. Litigation 304 | ------------- 305 | 306 | Any litigation relating to this License may be brought only in the 307 | courts of a jurisdiction where the defendant maintains its principal 308 | place of business and such litigation shall be governed by laws of that 309 | jurisdiction, without reference to its conflict-of-law provisions. 310 | Nothing in this Section shall prevent a party's ability to bring 311 | cross-claims or counter-claims. 312 | 313 | 9. Miscellaneous 314 | ---------------- 315 | 316 | This License represents the complete agreement concerning the subject 317 | matter hereof. If any provision of this License is held to be 318 | unenforceable, such provision shall be reformed only to the extent 319 | necessary to make it enforceable. Any law or regulation which provides 320 | that the language of a contract shall be construed against the drafter 321 | shall not be used to construe this License against a Contributor. 322 | 323 | 10. Versions of the License 324 | --------------------------- 325 | 326 | 10.1. New Versions 327 | 328 | Mozilla Foundation is the license steward. Except as provided in Section 329 | 10.3, no one other than the license steward has the right to modify or 330 | publish new versions of this License. Each version will be given a 331 | distinguishing version number. 332 | 333 | 10.2. Effect of New Versions 334 | 335 | You may distribute the Covered Software under the terms of the version 336 | of the License under which You originally received the Covered Software, 337 | or under the terms of any subsequent version published by the license 338 | steward. 339 | 340 | 10.3. Modified Versions 341 | 342 | If you create software not governed by this License, and you want to 343 | create a new license for such software, you may create and use a 344 | modified version of this License if you rename the license and remove 345 | any references to the name of the license steward (except to note that 346 | such modified license differs from this License). 347 | 348 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 349 | Licenses 350 | 351 | If You choose to distribute Source Code Form that is Incompatible With 352 | Secondary Licenses under the terms of this version of the License, the 353 | notice described in Exhibit B of this License must be attached. 354 | 355 | Exhibit A - Source Code Form License Notice 356 | ------------------------------------------- 357 | 358 | This Source Code Form is subject to the terms of the Mozilla Public 359 | License, v. 2.0. If a copy of the MPL was not distributed with this 360 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 361 | 362 | If it is not possible or desirable to put the notice in a particular 363 | file, then You may include the notice in a location (such as a LICENSE 364 | file in a relevant directory) where a recipient would be likely to look 365 | for such a notice. 366 | 367 | You may add additional accurate notices of copyright ownership. 368 | 369 | Exhibit B - "Incompatible With Secondary Licenses" Notice 370 | --------------------------------------------------------- 371 | 372 | This Source Code Form is "Incompatible With Secondary Licenses", as 373 | defined by the Mozilla Public License, v. 2.0. 374 | -------------------------------------------------------------------------------- /Examples/LCLCefClient/webpanel.pas: -------------------------------------------------------------------------------- 1 | Unit WebPanel; 2 | 3 | {$MODE objfpc}{$H+} 4 | 5 | Interface 6 | 7 | Uses 8 | Classes, SysUtils, Controls, ComCtrls, FileUtil, Forms, LCLProc, Graphics, Dialogs, 9 | LazUTF8, LazFileUtils, strutils, 10 | cef3types, cef3lib, cef3intf, cef3own, cef3lcl, 11 | FaviconGetter; 12 | 13 | Type 14 | TWebPanelOnClose = procedure(const Index: Integer) of object; 15 | 16 | TWebPanel = class(TTabSheet) 17 | private 18 | fChromium: TChromium; 19 | fUrl: String; 20 | fIconGetter: TFaviconGetter; 21 | 22 | // callbacks 23 | fTabOnClose: TWebPanelOnClose; 24 | fTabOnCloseStopped: TNotifyEvent; 25 | 26 | procedure ChromiumTakeFocus(Sender: TObject; const Browser: ICefBrowser; next_: Boolean); 27 | procedure ChromiumTitleChange(Sender: TObject; const Browser: ICefBrowser; const title: ustring); 28 | procedure ChromiumAddressChange(Sender: TObject; const Browser: ICefBrowser; 29 | const Frame: ICefFrame; const url: ustring); 30 | procedure ChromiumFaviconUrlchange(Sender: TObject; const Browser: ICefBrowser; iconUrls: TStrings); 31 | procedure ChromiumOpenUrlFromTab(Sender: TObject; browser: ICefBrowser; frame: ICefFrame; 32 | const targetUrl: ustring; targetDisposition: TCefWindowOpenDisposition; useGesture: Boolean; 33 | out Result: Boolean); 34 | procedure ChromiumBeforePopup(Sender: TObject; const browser: ICefBrowser; 35 | const frame: ICefFrame; const targetUrl, targetFrameName: ustring; 36 | targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; 37 | var popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo; var client: ICefClient; 38 | var settings: TCefBrowserSettings; var noJavascriptAccess: Boolean; out Result: Boolean); 39 | 40 | procedure ChromiumBeforeContextMenu(Sender: TObject; const Browser: ICefBrowser; 41 | const Frame: ICefFrame; const params: ICefContextMenuParams; const model: ICefMenuModel); 42 | procedure ChromiumContextMenuCommand(Sender: TObject; const Browser: ICefBrowser; 43 | const Frame: ICefFrame; const params: ICefContextMenuParams; commandId: Integer; 44 | eventFlags: TCefEventFlags; out Result: Boolean); 45 | 46 | procedure ChromiumFileDialog(Sender: TObject; const Browser: ICefBrowser; 47 | mode: TCefFileDialogMode; const title, defaultFileName: ustring; acceptFilters: TStrings; 48 | selectedAcceptFilter: Integer; const callback: ICefFileDialogCallback; out Result: Boolean); 49 | 50 | procedure ChromiumBeforeDownload(Sender: TObject; const Browser: ICefBrowser; 51 | const downloadItem: ICefDownloadItem; const suggestedName: ustring; 52 | const callback: ICefBeforeDownloadCallback); 53 | 54 | procedure ChromiumBeforeUnloadDialog(Sender: TObject; const Browser: ICefBrowser; 55 | const messageText: ustring; isReload: Boolean; const callback: ICefJsDialogCallback; 56 | out Result: Boolean); 57 | procedure ChromiumBeforeClose(Sender: TObject; const Browser: ICefBrowser); 58 | procedure ChromiumClose(Sender: TObject; const Browser: ICefBrowser; out 59 | Result: Boolean); 60 | 61 | procedure PrintToPdf(const Browser: ICefBrowser); 62 | 63 | procedure IconReady(const Success: Boolean; const Icon: TIcon); 64 | public 65 | destructor Destroy; override; 66 | 67 | procedure InitializeChromium(DefaultUrl: String = ''); 68 | procedure RequestClose; 69 | 70 | procedure OpenUrl(AUrl: String); 71 | procedure SetIcon(const Icon: TCustomIcon); 72 | 73 | property Url: String read fUrl write fUrl; 74 | property OnClose: TWebPanelOnClose read fTabOnClose write fTabOnClose; 75 | property OnCloseStopped: TNotifyEvent read fTabOnCloseStopped write fTabOnCloseStopped; 76 | end; 77 | 78 | { custom browser process handler } 79 | TCustomBrowserProcessHandler = class(TCefBrowserProcessHandlerOwn) 80 | private 81 | fPrintHandler: ICefPrintHandler; 82 | protected 83 | function GetPrintHandler: ICefPrintHandler; override; 84 | public 85 | constructor Create; override; 86 | end; 87 | 88 | 89 | Implementation 90 | 91 | Uses Main, cef3ref, cef3scp, SchemeHandler 92 | {$IFDEF LINUX}, PrintHandler{$ENDIF} 93 | {$IFDEF WINDOWS}, Windows{$ENDIF}; 94 | 95 | Const 96 | // client menu IDs 97 | CLIENT_ID_VISIT_COOKIES = MENU_ID_USER_FIRST + 0; 98 | CLIENT_ID_PRINT_TO_PDF = MENU_ID_USER_FIRST + 1; 99 | CLIENT_ID_EXIT = MENU_ID_USER_FIRST + 2; 100 | 101 | Type 102 | 103 | TCefNewTabTask = class(TCefTaskOwn) 104 | protected 105 | fTargetUrl: ustring; 106 | procedure Execute; override; 107 | public 108 | constructor Create(targetURL: ustring); reintroduce; 109 | end; 110 | 111 | TCefCloseTask = class(TCefTaskOwn) 112 | protected 113 | fTab: TWebPanel; 114 | procedure Execute; override; 115 | public 116 | constructor Create(Tab: TWebPanel); reintroduce; 117 | end; 118 | 119 | 120 | Var Path: ustring; 121 | 122 | function VisitCookies(const cookie: TCefCookie; count, total: Integer; 123 | out deleteCookie: Boolean): Boolean; 124 | Var 125 | tmp: TCefString; 126 | begin 127 | Write(count + 1, '/', total, ': '); 128 | 129 | tmp := cookie.path; 130 | Write(CefString(@tmp), ' '); 131 | 132 | tmp := cookie.name; 133 | Write(CefString(@tmp), ' '); 134 | 135 | tmp := cookie.domain; 136 | Write(CefString(@tmp), ' '); 137 | 138 | try 139 | DebugLn(DateTimeToStr(CefTimeToDateTime(cookie.expires))); 140 | except 141 | DebugLn('Invalid datetime.'); 142 | end; 143 | 144 | deleteCookie := False; 145 | Result := True; 146 | end; 147 | 148 | { TCefNewTabTask } 149 | 150 | procedure TCefNewTabTask.Execute; 151 | begin 152 | Assert(CefCurrentlyOn(TID_UI)); 153 | 154 | FMain.NewTab(UTF8Encode(fTargetUrl)); 155 | end; 156 | 157 | constructor TCefNewTabTask.Create(targetURL: ustring); 158 | begin 159 | inherited Create; 160 | 161 | fTargetUrl := targetURL; 162 | end; 163 | 164 | { TCefCloseTask } 165 | 166 | procedure TCefCloseTask.Execute; 167 | begin 168 | Assert(CefCurrentlyOn(TID_UI)); 169 | 170 | fTab.RequestClose; 171 | end; 172 | 173 | constructor TCefCloseTask.Create(Tab: TWebPanel); 174 | begin 175 | inherited Create; 176 | 177 | fTab := Tab; 178 | end; 179 | 180 | { TWebPanel } 181 | 182 | procedure TWebPanel.ChromiumTitleChange(Sender: TObject; const Browser: ICefBrowser; 183 | const title: ustring); 184 | Var 185 | NewTitle: String; 186 | begin 187 | NewTitle := UTF8Encode(title); 188 | 189 | If UTF8Length(NewTitle) < 15 then Caption := NewTitle 190 | Else Caption := UTF8Copy(NewTitle, 1, 12) + '...'; 191 | end; 192 | 193 | procedure TWebPanel.ChromiumTakeFocus(Sender: TObject; const Browser: ICefBrowser; next_: Boolean); 194 | Var 195 | NextPageIndex: Integer; 196 | begin 197 | If next_ then NextPageIndex := PageIndex + 1 198 | Else NextPageIndex := PageIndex - 1; 199 | 200 | If (NextPageIndex >= 0) and (NextPageIndex < PageControl.PageCount) then 201 | begin 202 | // Select next tab if available 203 | PageControl.ActivePageIndex := NextPageIndex; 204 | end 205 | Else 206 | begin 207 | // otherwise select next component on form 208 | FMain.SelectNext(FMain.ActiveControl, next_, True); 209 | end; 210 | end; 211 | 212 | procedure TWebPanel.ChromiumAddressChange(Sender: TObject; const Browser: ICefBrowser; 213 | const Frame: ICefFrame; const url: ustring); 214 | begin 215 | Assert(CefCurrentlyOn(TID_UI)); 216 | 217 | If frame.IsMain then 218 | begin 219 | fUrl := UTF8Encode(Browser.MainFrame.Url); 220 | 221 | If PageControl.ActivePage = Self then FMain.EUrl.Text := fUrl; 222 | end; 223 | end; 224 | 225 | procedure TWebPanel.ChromiumFaviconUrlchange(Sender: TObject; const Browser: ICefBrowser; 226 | iconUrls: TStrings); 227 | Var 228 | i: Integer; 229 | begin 230 | // For simplicity just use the first .ico image 231 | For i := 0 to iconUrls.Count - 1 do 232 | If AnsiEndsText('ico', iconUrls[i]) then 233 | begin 234 | // make sure there is only one 235 | If Assigned(fIconGetter) then fIconGetter.Cancel; 236 | 237 | fIconGetter := TFaviconGetter.Create(iconUrls[i], @IconReady); 238 | Exit; 239 | end; 240 | 241 | // No suitabe icon found 242 | SetIcon(nil); 243 | end; 244 | 245 | procedure TWebPanel.ChromiumBeforePopup(Sender: TObject; const browser: ICefBrowser; 246 | const frame: ICefFrame; const targetUrl, targetFrameName: ustring; 247 | targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; 248 | var popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo; var client: ICefClient; 249 | var settings: TCefBrowserSettings; var noJavascriptAccess: Boolean; out Result: Boolean); 250 | begin 251 | // Called on IO thread, must be executed on the UI thread 252 | CefPostTask(TID_UI, TCefNewTabTask.Create(targetUrl)); 253 | 254 | Result := True; 255 | end; 256 | 257 | procedure TWebPanel.ChromiumOpenUrlFromTab(Sender: TObject; browser: ICefBrowser; frame: ICefFrame; 258 | const targetUrl: ustring; targetDisposition: TCefWindowOpenDisposition; useGesture: Boolean; 259 | out Result: Boolean); 260 | begin 261 | Assert(CefCurrentlyOn(TID_UI)); 262 | 263 | FMain.NewTab(UTF8Encode(targetUrl)); 264 | 265 | Result := True; 266 | end; 267 | 268 | 269 | procedure TWebPanel.ChromiumBeforeContextMenu(Sender: TObject; const Browser: ICefBrowser; 270 | const Frame: ICefFrame; const params: ICefContextMenuParams; const model: ICefMenuModel); 271 | begin 272 | Assert(CefCurrentlyOn(TID_UI)); 273 | 274 | If ([CM_TYPEFLAG_PAGE, CM_TYPEFLAG_FRAME] * params.GetTypeFlags) <> [] then 275 | begin 276 | // Add seperator if the menu already contains items 277 | If model.GetCount > 0 then model.AddSeparator; 278 | 279 | model.AddItem(CLIENT_ID_VISIT_COOKIES, '&Visit Cookies'); 280 | model.AddItem(CLIENT_ID_PRINT_TO_PDF, '&Print to PDF'); 281 | model.AddSeparator; 282 | model.AddItem(CLIENT_ID_EXIT, '&Exit'); 283 | end; 284 | end; 285 | 286 | procedure TWebPanel.ChromiumContextMenuCommand(Sender: TObject; const Browser: ICefBrowser; 287 | const Frame: ICefFrame; const params: ICefContextMenuParams; commandId: Integer; 288 | eventFlags: TCefEventFlags; out Result: Boolean); 289 | begin 290 | Assert(CefCurrentlyOn(TID_UI)); 291 | 292 | Result := True; 293 | 294 | Case commandId of 295 | CLIENT_ID_VISIT_COOKIES: TCefCookieManagerRef.Global(nil).VisitAllCookiesProc(@VisitCookies); 296 | CLIENT_ID_PRINT_TO_PDF: PrintToPdf(Browser); 297 | CLIENT_ID_EXIT: FMain.Close; 298 | Else Result := False; 299 | end; 300 | end; 301 | 302 | procedure TWebPanel.ChromiumFileDialog(Sender: TObject; const Browser: ICefBrowser; 303 | mode: TCefFileDialogMode; const title, defaultFileName: ustring; acceptFilters: TStrings; 304 | selectedAcceptFilter: Integer; const callback: ICefFileDialogCallback; out Result: Boolean); 305 | Var 306 | ModeType: TCefFileDialogMode; 307 | Success: Boolean = False; 308 | Files: TStringList; 309 | InitialDir: ustring; 310 | LCLDialog: TOpenDialog; 311 | 312 | 313 | function GetDescriptionFromMimeType(const mimeType: String): String; 314 | Const 315 | WildCardMimeTypes: array[0..3] of array[0..1] of String = ( 316 | ('audio', 'Audio Files'), 317 | ('image', 'Image Files'), 318 | ('text', 'Text Files'), 319 | ('video', 'Video Files')); 320 | Var 321 | i: Integer; 322 | begin 323 | Result := ''; 324 | 325 | For i := 0 to High(WildCardMimeTypes) do 326 | begin 327 | If AnsiCompareText(mimeType, WildCardMimeTypes[i][0] + '/*') = 0 then 328 | begin 329 | Result := WildCardMimeTypes[i][1]; 330 | Break; 331 | end; 332 | end; 333 | end; 334 | 335 | procedure AddFilters(includeAll: Boolean); 336 | Var 337 | hasFilter: Boolean = False; 338 | Filter, Line, Descr: String; 339 | Ext: TStringList; 340 | sepPos: SizeInt; 341 | i, k: Integer; 342 | begin 343 | Filter := ''; 344 | Ext := TStringList.Create; 345 | Ext.Delimiter := ';'; 346 | 347 | For i := 0 to AcceptFilters.Count - 1 do 348 | begin 349 | Line := AcceptFilters[i]; 350 | 351 | If Line = '' then Continue; 352 | 353 | sepPos := Pos('|', Line); 354 | If sepPos <> 0 then 355 | begin 356 | // treat as a filter of the form "Filter Name|.ext1;.ext2;.ext3" 357 | 358 | Descr := Copy(Line, 1, sepPos - 1); 359 | Line := StringReplace(Copy(Line, sepPos + 1, Length(Line) - sepPos), '.', '*.', [rfReplaceAll]); 360 | end 361 | Else 362 | begin 363 | Ext.Clear; 364 | Descr := ''; 365 | 366 | If AnsiStartsStr('.', Line) then 367 | begin 368 | // treat as an extension beginning with the '.' character 369 | Ext.Add('*' + Line); 370 | end 371 | Else 372 | begin 373 | // convert mime type to one or more extensions 374 | Descr := GetDescriptionFromMimeType(Line); 375 | CefGetExtensionsForMimeType(Line, Ext); 376 | 377 | For k := 0 to Ext.Count - 1 do Ext[k] := '*.' + Ext[k]; 378 | end; 379 | 380 | If Ext.Count = 0 then Continue; 381 | 382 | // combine extensions, reuse Line 383 | Line := Ext.DelimitedText; 384 | end; 385 | 386 | If Descr = '' then Descr := Line 387 | {$IFDEF LCLGTK2} 388 | Else Descr := Descr + ' (' + Line + ')' 389 | {$ENDIF}; 390 | 391 | If Length(Filter) > 0 then Filter := Filter + '|'; 392 | Filter := Filter + Descr + '|' + Line; 393 | 394 | hasFilter := True; 395 | end; 396 | 397 | // if there are filters, add *.* filter 398 | If includeAll and hasFilter then 399 | Filter := Filter + '|All Files' + {$IFDEF LCLGTK2}' (*.*)' +{$ENDIF} '|*.*'; 400 | 401 | LCLDialog.Filter := Filter; 402 | 403 | If hasFilter then LCLDialog.FilterIndex := SelectedAcceptFilter; 404 | 405 | FreeAndNil(Ext); 406 | end; 407 | 408 | begin 409 | // Remove modifier flags 410 | ModeType := TCefFileDialogMode(LongWord(Mode) and LongWord(FILE_DIALOG_TYPE_MASK)); 411 | 412 | Case ModeType of 413 | FILE_DIALOG_OPEN, 414 | FILE_DIALOG_OPEN_MULTIPLE: LCLDialog := FMain.OpenFile; 415 | FILE_DIALOG_OPEN_FOLDER: LCLDialog := FMain.OpenFolder; 416 | FILE_DIALOG_SAVE: LCLDialog := FMain.SaveFile; 417 | Else 418 | raise Exception.Create('Unimpemented dialog type.'); 419 | end; 420 | 421 | If ModeType = FILE_DIALOG_OPEN_MULTIPLE then 422 | LCLDialog.Options := LCLDialog.Options + [ofAllowMultiSelect]; 423 | 424 | If ModeType = FILE_DIALOG_SAVE then 425 | begin 426 | If Boolean(LongWord(Mode) and LongWord(FILE_DIALOG_OVERWRITEPROMPT_FLAG)) then 427 | LCLDialog.Options := LCLDialog.Options + [ofOverwritePrompt]; 428 | 429 | If DefaultFileName <> '' then 430 | begin 431 | InitialDir := ExtractFileDir(DefaultFileName); 432 | 433 | If DirectoryExists(InitialDir) then LCLDialog.InitialDir := InitialDir 434 | Else LCLDialog.InitialDir := GetUserDir; 435 | 436 | LCLDialog.FileName := ExtractFileName(DefaultFileName); 437 | end; 438 | end; 439 | 440 | If Boolean(LongWord(Mode) and LongWord(FILE_DIALOG_HIDEREADONLY_FLAG)) then 441 | LCLDialog.Options := LCLDialog.Options + [ofHideReadOnly]; 442 | 443 | AddFilters(True); 444 | 445 | Success := FMain.SaveFile.Execute; 446 | 447 | If Success then 448 | begin 449 | Files := TStringList.Create; 450 | 451 | If ModeType = FILE_DIALOG_OPEN_MULTIPLE then Files.AddStrings(LCLDialog.Files) 452 | Else Files.Add(LCLDialog.FileName); 453 | 454 | Callback.Cont(FMain.SaveFile.FilterIndex, Files); 455 | 456 | FreeAndNil(Files); 457 | end 458 | Else Callback.Cancel; 459 | 460 | Result := True; 461 | end; 462 | 463 | procedure TWebPanel.ChromiumBeforeDownload(Sender: TObject; const Browser: ICefBrowser; 464 | const downloadItem: ICefDownloadItem; const suggestedName: ustring; 465 | const callback: ICefBeforeDownloadCallback); 466 | begin 467 | // Show "Save As" dialog, download to default temp directory 468 | callback.Cont('', True); 469 | end; 470 | 471 | procedure TWebPanel.ChromiumBeforeUnloadDialog(Sender: TObject; const Browser: ICefBrowser; 472 | const messageText: ustring; isReload: Boolean; const callback: ICefJsDialogCallback; 473 | out Result: Boolean); 474 | Var 475 | AllowClose: Boolean; 476 | begin 477 | // use custom dialog 478 | Result := True; 479 | 480 | // show dialog 481 | AllowClose := MessageDlg('Confirmation', messageText, mtConfirmation, [mbYes,mbNo], 0) = mrYes; 482 | 483 | // execute callback 484 | callback.Cont(AllowClose, ''); 485 | 486 | // notify main form that closing was stopped 487 | If (not AllowClose) and Assigned(fTabOnCloseStopped) then fTabOnCloseStopped(Self); 488 | end; 489 | 490 | procedure TWebPanel.ChromiumBeforeClose(Sender: TObject; const Browser: ICefBrowser); 491 | Var 492 | Callback: TWebPanelOnClose; 493 | Index: Integer; 494 | begin 495 | // save for use after Free 496 | Callback := fTabOnClose; 497 | Index := TabIndex; 498 | 499 | // CEF browser is destroyed -> free tab 500 | Free; 501 | 502 | // callback after tab is removed 503 | If Assigned(Callback) then Callback(Index); 504 | end; 505 | 506 | procedure TWebPanel.ChromiumClose(Sender: TObject; const Browser: ICefBrowser; out Result: Boolean); 507 | begin 508 | {$IFDEF WINDOWS} 509 | Result := True; 510 | // only send destroy message to browser 511 | SendMessage(Browser.Host.WindowHandle, WM_DESTROY, 0, 0); 512 | {$ENDIF} 513 | {$IFDEF LINUX} 514 | Result := True; 515 | // destroy message does not work correctly (on QT) 516 | ChromiumBeforeClose(Sender, Browser); 517 | {$ENDIF} 518 | {$IFDEF DARWIN} 519 | Result := False; 520 | {$ENDIF} 521 | end; 522 | 523 | procedure PdfPrintCallback(const path: ustring; ok: Boolean); 524 | begin 525 | If ok then ShowMessage('Successfully printed to pdf file.' + LineEnding + path) 526 | Else ShowMessage('Failed to print to file.'); 527 | end; 528 | 529 | procedure TWebPanel.PrintToPdf(const Browser: ICefBrowser); 530 | Var 531 | PdfSettings: TCefPdfPrintSettings; 532 | begin 533 | With FMain.SaveFile do 534 | begin 535 | Filter := 'PDF file|*.pdf'; 536 | FileName := 'output.pdf'; 537 | InitialDir := GetUserDir; 538 | end; 539 | 540 | If FMain.SaveFile.Execute then 541 | begin 542 | FillByte(PdfSettings, SizeOf(PdfSettings), 0); 543 | 544 | With PdfSettings do 545 | begin 546 | // default page size is A4 547 | 548 | header_footer_enabled := Ord(True); 549 | backgrounds_enabled := Ord(True); 550 | end; 551 | 552 | Browser.Host.PrintToPdf(FMain.SaveFile.FileName, PdfSettings, TCefFastPdfPrintCallback.Create(@PdfPrintCallback)); 553 | end; 554 | end; 555 | 556 | procedure TWebPanel.IconReady(const Success: Boolean; const Icon: TIcon); 557 | begin 558 | Assert(CefCurrentlyOn(TID_UI)); 559 | 560 | fIconGetter := nil; 561 | 562 | If Success then SetIcon(Icon) 563 | Else SetIcon(nil); 564 | end; 565 | 566 | destructor TWebPanel.Destroy; 567 | begin 568 | // Cancel icon request 569 | If Assigned(fIconGetter) then fIconGetter.Cancel; 570 | 571 | inherited Destroy; 572 | end; 573 | 574 | procedure TWebPanel.InitializeChromium(DefaultUrl: String); 575 | begin 576 | If not Assigned(fChromium) then 577 | begin 578 | fChromium := TChromium.Create(Self); 579 | 580 | If DefaultUrl <> '' then fChromium.DefaultUrl := DefaultUrl; 581 | 582 | fChromium.TabStop := True; 583 | fChromium.Parent := Self; 584 | fChromium.AnchorAsAlign(alClient, 0); 585 | 586 | 587 | // Register callbacks 588 | fChromium.OnTakeFocus := @ChromiumTakeFocus; 589 | fChromium.OnTitleChange := @ChromiumTitleChange; 590 | fChromium.OnAddressChange := @ChromiumAddressChange; 591 | fChromium.OnFaviconUrlchange := @ChromiumFaviconUrlchange; 592 | 593 | fChromium.OnOpenUrlFromTab := @ChromiumOpenUrlFromTab; 594 | fChromium.OnBeforePopup := @ChromiumBeforePopup; 595 | 596 | fChromium.OnBeforeContextMenu := @ChromiumBeforeContextMenu; 597 | fChromium.OnContextMenuCommand := @ChromiumContextMenuCommand; 598 | 599 | {$IFDEF LINUX} 600 | fChromium.OnFileDialog := @ChromiumFileDialog; 601 | {$ENDIF} 602 | 603 | fChromium.OnBeforeDownload := @ChromiumBeforeDownload; 604 | 605 | fChromium.OnBeforeUnloadDialog := @ChromiumBeforeUnloadDialog; 606 | fChromium.OnBeforeClose := @ChromiumBeforeClose; 607 | fChromium.OnClose := @ChromiumClose; 608 | end 609 | Else raise Exception.Create('Chromium already initialized.'); 610 | end; 611 | 612 | procedure TWebPanel.RequestClose; 613 | begin 614 | If PageControl.ActivePage <> Self then 615 | begin 616 | // focus tab 617 | PageControl.ActivePage := Self; 618 | 619 | // wait for focus 620 | CefPostDelayedTask(TID_UI, TCefCloseTask.Create(Self), 100); 621 | end 622 | Else fChromium.Browser.Host.CloseBrowser(False); 623 | end; 624 | 625 | procedure TWebPanel.OpenUrl(AUrl: String); 626 | begin 627 | fChromium.Load(AUrl); 628 | end; 629 | 630 | // Change the icon of the tab 631 | procedure TWebPanel.SetIcon(const Icon: TCustomIcon); 632 | begin 633 | If Assigned(Icon) then 634 | begin 635 | // Replace icon with new one 636 | FMain.TabIcons.Delete(TabIndex); 637 | FMain.TabIcons.InsertIcon(TabIndex, Icon); 638 | 639 | ImageIndex := TabIndex; 640 | end 641 | Else If ImageIndex <> -1 then 642 | begin 643 | // Replace icon with dummy one 644 | FMain.TabIcons.Delete(TabIndex); 645 | FMain.TabIcons.InsertIcon(TabIndex, Application.Icon); 646 | 647 | ImageIndex := -1; 648 | end; 649 | 650 | PageControl.Repaint; 651 | end; 652 | 653 | 654 | { TCustomBrowserProcessHandler } 655 | 656 | function TCustomBrowserProcessHandler.GetPrintHandler: ICefPrintHandler; 657 | begin 658 | Result := fPrintHandler; 659 | end; 660 | 661 | constructor TCustomBrowserProcessHandler.Create; 662 | begin 663 | inherited; 664 | 665 | {$IFDEF LINUX} 666 | fPrintHandler := TCustomPrintHandler.Create; 667 | {$ELSE} 668 | fPrintHandler := nil; 669 | {$ENDIF} 670 | end; 671 | 672 | 673 | procedure RegisterSchemes(const registrar: TCefSchemeRegistrarRef); 674 | begin 675 | registrar.AddCustomScheme('fpcef', False, True, False, False, False, False); 676 | end; 677 | 678 | 679 | Initialization 680 | Path := GetCurrentDirUTF8 + PathDelim; 681 | 682 | CefResourcesDirPath := Path + 'Resources'; 683 | CefLocalesDirPath := Path + 'Resources' + PathDelim + 'locales'; 684 | 685 | // register handler 686 | CefBrowserProcessHandler := TCustomBrowserProcessHandler.Create; 687 | 688 | // scheme handler 689 | CefOnRegisterCustomSchemes := @RegisterSchemes; 690 | CefRegisterSchemeHandlerFactory('fpcef', '', TCustomScheme); 691 | 692 | CefInitialize; 693 | 694 | end. 695 | 696 | -------------------------------------------------------------------------------- /cef3lib.pas: -------------------------------------------------------------------------------- 1 | (* 2 | * Free Pascal Chromium Embedded 3 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, 6 | * You can obtain one at http://mozilla.org/MPL/2.0/. 7 | * 8 | * Author: dev.dliw@gmail.com 9 | * Repository: https://github.com/dliw/fpCEF3 10 | * 11 | * 12 | * Originally based on 'Delphi Chromium Embedded 3' by Henri Gourvest 13 | * <hgourvest@gmail.com> 14 | * 15 | * Embarcadero Technologies, Inc is not permitted to use or redistribute 16 | * this source code without explicit permission. 17 | * 18 | *) 19 | 20 | Unit cef3lib; 21 | 22 | {$MODE objfpc}{$H+} 23 | 24 | {$I cef.inc} 25 | 26 | Interface 27 | 28 | Uses 29 | {$IFDEF CEF_MULTI_THREADED_MESSAGE_LOOP}Messages,{$ENDIF} 30 | {$IFDEF WINDOWS}Windows,{$ENDIF} 31 | {$IFNDEF WINDOWS}cwstring,{$ENDIF} 32 | {$IFDEF LINUX}xlib, x,{$ENDIF} 33 | SysUtils, Classes, LCLProc, Graphics, FPimage, 34 | cef3api, cef3types, cef3intf, cef3ref, cef3own; 35 | 36 | function CefGetObject(ptr: Pointer): TObject; {$IFDEF SUPPORTS_INLINE}inline;{$ENDIF} 37 | function CefGetData(const i: ICefBaseRefCounted): Pointer; {$IFDEF SUPPORTS_INLINE}inline; {$ENDIF} 38 | 39 | function CefTimeToDateTime(const dt: TCefTime): TDateTime; 40 | function DateTimeToCefTime(dt: TDateTime): TCefTime; 41 | {$IFDEF WINDOWS} 42 | function TzSpecificLocalTimeToSystemTime( 43 | lpTimeZoneInformation: PTimeZoneInformation; 44 | lpLocalTime, lpUniversalTime: PSystemTime): BOOL; stdcall; external 'kernel32.dll'; 45 | function SystemTimeToTzSpecificLocalTime( 46 | lpTimeZoneInformation: PTimeZoneInformation; 47 | lpUniversalTime, lpLocalTime: PSystemTime): BOOL; stdcall; external 'kernel32.dll'; 48 | function CefTimeToSystemTime(const dt: TCefTime): TSystemTime; 49 | {$ENDIF} 50 | 51 | function TColorToCefColor(const aColor: TColor): TCefColor; 52 | function FPColorToCefColor(const aColor: TFPColor): TCefColor; 53 | 54 | function CefString(const str: ustring): TCefString; overload; 55 | function CefString(const str: PCefString): ustring; overload; 56 | function CefStringClearAndGet(var str: TCefString): ustring; 57 | function CefStringFreeAndGet(const str: PCefStringUserFree): ustring; 58 | function CefStringAlloc(const str: ustring): TCefString; 59 | procedure CefStringFree(const str: PCefString); 60 | function CefUserFreeString(const str: ustring): PCefStringUserFree; 61 | procedure CefStringSet(const str: PCefString; const value: ustring); 62 | 63 | 64 | { *** API *** } 65 | 66 | function CefInitialize: Boolean; 67 | procedure CefShutDown; 68 | 69 | {$IFNDEF CEF_MULTI_THREADED_MESSAGE_LOOP} 70 | procedure CefDoMessageLoopWork; 71 | procedure CefRunMessageLoop; 72 | procedure CefQuitMessageLoop; 73 | {$ENDIF} 74 | 75 | procedure CefSetOsmodalLoop(osModalLoop: Boolean); 76 | procedure CefEnableHighDPISupport; 77 | 78 | function CefBrowserHostCreateBrowser(windowInfo: PCefWindowInfo; const client: ICefClient; 79 | const url: ustring; const settings: PCefBrowserSettings; const requestContext: ICefRequestContext): Boolean; 80 | function CefBrowserHostCreateBrowserSync(windowInfo: PCefWindowInfo; const client: ICefClient; 81 | const url: ustring; const settings: PCefBrowserSettings; const requestContext: ICefRequestContext): ICefBrowser; 82 | 83 | function CefCrashReportingEnabled: Boolean; 84 | procedure CefSetCrashKeyValue(const key, value: ustring); 85 | 86 | function CefCreateDirectory(const fullPath: ustring): Boolean; 87 | function CefGetTempDirectory(out tempDir: ustring): Boolean; 88 | function CefCreateNewTempDirectory(const prefix: ustring; out newTempPath: ustring): Boolean; 89 | function CefCreateTempDirectoryInDirectory(const baseDir, prefix: ustring; out newDir: ustring): Boolean; 90 | function CefDirectoryExists(const path: ustring): Boolean; 91 | function CefDeleteFile(const path: ustring; recursive: Boolean): Boolean; 92 | function CefZipDirectory(const srcDir, destFile: ustring; includeHiddenFiles: Boolean): Boolean; 93 | 94 | function CefGetGeolocation(const callback: ICefGetGeolocationCallback): Boolean; 95 | function CefGetGeolocationProc(const callback: TCefGetGeolocationCallbackProc): Boolean; 96 | 97 | function CefAddCrossOriginWhitelistEntry(const SourceOrigin, TargetProtocol, TargetDomain: ustring; AllowTargetSubdomains: Boolean): Boolean; 98 | function CefRemoveCrossOriginWhitelistEntry(const SourceOrigin, TargetProtocol, TargetDomain: ustring; AllowTargetSubdomains: Boolean): Boolean; 99 | function CefClearCrossOriginWhitelist: Boolean; 100 | 101 | function CefParseUrl(const url: ustring; var parts: TUrlParts): Boolean; 102 | function CefCreateUrl(var parts: TUrlParts): ustring; 103 | 104 | function CefFormatUrlForSecurityDisplay(const originUrl: ustring): ustring; 105 | 106 | function CefGetMimeType(const extension: ustring): ustring; 107 | procedure CefGetExtensionsForMimeType(const mimeType: ustring; extensions: TStrings); 108 | function CefBase64Encode(const data: Pointer; dataSize: TSize): ustring; 109 | function CefBase64Decode(const data: ustring): ICefBinaryValue; 110 | function CefUriEncode(const text: ustring; usePlus: Boolean): ustring; 111 | function CefUriDecode(const text: ustring; convertToUtf8: Boolean; unescapeRules: TCefUriUnescapeRule): ustring; 112 | function CefParseJson(const jsonString: ustring; options: TCefJsonParserOptions): ICefValue; 113 | function CefParseJsonAndReturnError(const jsonString: ustring; options: TCefJsonParserOptions; out errorCode: TCefJsonParserError; out errorMsg: ustring): ICefValue; 114 | function CefWriteJson(node: ICefValue; options: TCefJsonWriterOptions): ustring; 115 | 116 | function CefGetPath(key: TCefPathKey; out path: ustring): Boolean; 117 | 118 | function CefLaunchProcess(commandLine: ICefCommandLine): Boolean; 119 | 120 | function CefRegisterSchemeHandlerFactory(const SchemeName, HostName: ustring; 121 | const handler: TCefResourceHandlerClass): Boolean; 122 | function CefClearSchemeHandlerFactories: Boolean; 123 | 124 | function CefIsCertStatusError(status: TCefCertStatus): Boolean; 125 | function CefIsCertStatusMinorError(status: TCefCertStatus): Boolean; 126 | 127 | function CefCurrentlyOn(ThreadId: TCefThreadId): Boolean; 128 | procedure CefPostTask(ThreadId: TCefThreadId; const task: ICefTask); 129 | procedure CefPostDelayedTask(ThreadId: TCefThreadId; const task: ICefTask; delayMs: Int64); 130 | 131 | function CefBeginTracing(const categories: ustring; const callback: ICefCompletionCallback): Boolean; 132 | function CefBeginTracingProc(const categories: ustring; const proc: TCefCompletionCallbackProc): Boolean; 133 | function CefEndTracing(const tracingFile: ustring; const callback: ICefEndTracingCallback): Boolean; 134 | function CefEndTracingProc(const tracingFile: ustring; const proc: TCefEndTracingCallbackProc): Boolean; 135 | function CefNowFromSystemTraceTime: Int64; 136 | 137 | function CefRegisterExtension(const name, code: ustring; const Handler: ICefv8Handler): Boolean; 138 | function Cefv8ContextInContext: Boolean; 139 | 140 | procedure CefVisitWebPluginInfo(const visitor: ICefWebPluginInfoVisitor); 141 | procedure CefVisitWebPluginInfoProc(const visitor: TCefWebPluginInfoVisitorProc); 142 | procedure CefRefreshWebPlugins; 143 | procedure CefUnregisterInternalWebPlugin(const path: ustring); 144 | procedure CefRegisterWebPluginCrash(const path: ustring); 145 | procedure CefIsWebPluginUnstable(const path: ustring; const callback: ICefWebPluginUnstableCallback); 146 | procedure CefIsWebPluginUnstableProc(const path: ustring; const callback: TCefWebPluginIsUnstableProc); 147 | procedure CefRegisterWidevineCdm(const path: ustring; const callback: ICefRegisterCdmCallback); 148 | procedure CefRegisterWidevineCdmProc(const path: ustring; const proc: TCefRegisterCdmCallbackProc); 149 | 150 | function CefGetMinLogLevel: Integer; 151 | function CefGetVlogLevel(const fileStart: String; n: TSize): Integer; 152 | procedure CefLog(const file_: String; line, severity: Integer; const message: String); 153 | 154 | function CefGetCurrentPlatformThreadId: TCefPlatformThreadId; 155 | function CefGetCurrentPlatformThreadHandle: TCefPlatformThreadHandle; 156 | 157 | function CefTimeNow(out cefTime: TDateTime): Boolean; 158 | 159 | procedure CefTraceEventInstant(const category, name, arg1_name: String; arg1_val: UInt64; const arg2_name: String; arg2_val: UInt64; copy: Integer); 160 | procedure CefTraceEventBegin(const category, name, arg1_name: String; arg1_val: UInt64; const arg2_name: String; arg2_val: UInt64; copy: Integer); 161 | procedure CefTraceEventEnd(const category, name, arg1_name: String; arg1_val: UInt64; const arg2_name: String; arg2_val: UInt64; copy: Integer); 162 | procedure CefTraceCounter(const category, name, arg1_name: String; arg1_val: UInt64; const arg2_name: String; arg2_val: UInt64; copy: Integer); 163 | procedure CefTraceCounterId(const category, name: String; id: UInt64; const value1_name: String; value1_val: UInt64; const value2_name: String; value2_val: UInt64; copy: Integer); 164 | procedure CefTraceEventAsyncBegin(const category, name: String; id: UInt64; const arg1_name: String; arg1_val: UInt64; const arg2_name: String; arg2_val: UInt64; copy: Integer); 165 | procedure CefTraceEventAsyncStepInto(const category, name: String; id, step: UInt64; const arg1_name: String; arg1_val: UInt64; copy: Integer); 166 | procedure CefTraceEventAsyncStepPast(const category, name: String; id, step: UInt64; const arg1_name: String; arg1_val: UInt64; copy: Integer); 167 | procedure CefTraceEventAsyncEnd(const category, name: String; id: UInt64; const arg1_name: String; arg1_val: UInt64; const arg2_name: String; arg2_val: UInt64; copy: Integer); 168 | 169 | function CefVersionInfo(entry: Integer): Integer; 170 | function CefApiHash(entry: Integer): String; 171 | 172 | {$IFDEF LINUX} 173 | procedure CefXWindowResize(const ABrowser: ICefBrowser; const Top, Left, Width, Height: Integer); 174 | procedure CefXLooseFocus(const ABrowser: ICefBrowser); 175 | procedure CefXSetVisibility(const ABrowser: ICefBrowser; const Value: Boolean); 176 | procedure CefXDestroyWindow(const Handle: TXID); 177 | 178 | function XErrorHandler(display: PDisplay; event: PXErrorEvent): Integer; cdecl; 179 | function XIOErrorHandler(display: PDisplay): Integer; cdecl; 180 | {$ENDIF} 181 | 182 | 183 | Var 184 | CefSingleProcess: Boolean = False; 185 | CefNoSandbox: Boolean = True; 186 | CefBrowserSubprocessPath: ustring = ''; 187 | CefFrameworkDirPath: ustring = ''; 188 | CefExternalMessagePump: Boolean = False; 189 | CefWindowlessRenderingEnabled: Boolean = False; 190 | CefCachePath: ustring = ''; 191 | CefCommandLineArgsDisabled: Boolean = False; 192 | CefUserDataPath: ustring = ''; 193 | CefPersistSessionCookies: Boolean = False; 194 | CefPersistUserPreferences: Boolean = False; 195 | CefUserAgent: ustring = ''; 196 | CefProductVersion: ustring = ''; 197 | CefLocale: ustring = ''; 198 | CefLogFile: ustring = ''; 199 | CefLogSeverity: TCefLogSeverity = LOGSEVERITY_DEFAULT; 200 | CefJavaScriptFlags: ustring = ''; 201 | CefResourcesDirPath: ustring = ''; 202 | CefLocalesDirPath: ustring = ''; 203 | CefPackLoadingDisabled: Boolean = False; 204 | CefRemoteDebuggingPort: Integer = 0; 205 | CefUncaughtExceptionStackSize: Integer = 10; 206 | CefContextSafetyImplementation: Integer = 0; 207 | CefIgnoreCertificateError: Boolean = False; 208 | CefEnableNetSecurityExpiration: Boolean = False; 209 | CefBackgroundColor: TFPColor = (red: 255; green: 255; blue: 255; alpha: 0); 210 | CefAcceptLanguageList: ustring = ''; 211 | 212 | CefGetDataResource: TGetDataResource = nil; 213 | CefGetLocalizedString: TGetLocalizedString = nil; 214 | 215 | CefResourceBundleHandler: ICefResourceBundleHandler = nil; 216 | CefBrowserProcessHandler: ICefBrowserProcessHandler = nil; 217 | CefRenderProcessHandler: ICefRenderProcessHandler = nil; 218 | 219 | CefOnBeforeCommandLineProcessing: TOnBeforeCommandLineProcessing = nil; 220 | CefOnRegisterCustomSchemes: TOnRegisterCustomSchemes = nil; 221 | 222 | // allow custom library location, can be relative 223 | CefLibraryDirPath: String = ''; 224 | 225 | Implementation 226 | 227 | Type 228 | TC = class(TThread) 229 | procedure Execute; override; 230 | end; 231 | 232 | (* 233 | 234 | {$IFDEF WINDOWS} 235 | { TODO : Where are these types defined? } 236 | { 237 | function TzSpecificLocalTimeToSystemTime( 238 | lpTimeZoneInformation: PTimeZoneInformation; 239 | lpLocalTime, lpUniversalTime: PSystemTime): BOOL; cdecl; external 'kernel32.dll'; 240 | 241 | function SystemTimeToTzSpecificLocalTime( 242 | lpTimeZoneInformation: PTimeZoneInformation; 243 | lpUniversalTime, lpLocalTime: PSystemTime): BOOL; cdecl; external 'kernel32.dll'; 244 | } 245 | {$ENDIF} 246 | 247 | *) 248 | 249 | Var 250 | CefIsMainProcess: Boolean = False; 251 | 252 | 253 | function CefGetObject(ptr: Pointer): TObject; {$IFDEF SUPPORTS_INLINE}inline; {$ENDIF} 254 | begin 255 | Dec(ptr, SizeOf(Pointer)); 256 | 257 | Result := TObject(ptr^); 258 | end; 259 | 260 | function CefGetData(const i: ICefBaseRefCounted): Pointer; {$IFDEF SUPPORTS_INLINE}inline; {$ENDIF} 261 | begin 262 | If i <> nil then Result := i.Wrap 263 | Else Result := nil; 264 | end; 265 | 266 | { TODO : Time functions } 267 | {$IFDEF WINDOWS} 268 | function CefTimeToSystemTime(const dt: TCefTime): TSystemTime; 269 | begin 270 | With Result do 271 | begin 272 | wYear := dt.year; 273 | wMonth := dt.month; 274 | wDayOfWeek := dt.day_of_week; 275 | wDay := dt.day_of_month; 276 | wHour := dt.hour; 277 | wMinute := dt.minute; 278 | wSecond := dt.second; 279 | wMilliseconds := dt.millisecond; 280 | end; 281 | end; 282 | 283 | function SystemTimeToCefTime(const dt: TSystemTime): TCefTime; 284 | begin 285 | With Result do 286 | begin 287 | year := dt.wYear; 288 | month := dt.wMonth; 289 | day_of_week := dt.wDayOfWeek; 290 | day_of_month := dt.wDay; 291 | hour := dt.wHour; 292 | minute := dt.wMinute; 293 | second := dt.wSecond; 294 | millisecond := dt.wMilliseconds; 295 | end; 296 | end; 297 | 298 | function CefTimeToDateTime(const dt: TCefTime): TDateTime; 299 | Var 300 | st: TSystemTime; 301 | begin 302 | st := CefTimeToSystemTime(dt); 303 | SystemTimeToTzSpecificLocalTime(nil, @st, @st); 304 | Result := SystemTimeToDateTime(st); 305 | end; 306 | 307 | function DateTimeToCefTime(dt: TDateTime): TCefTime; 308 | Var 309 | st: TSystemTime; 310 | begin 311 | DateTimeToSystemTime(dt, st); 312 | TzSpecificLocalTimeToSystemTime(nil, @st, @st); 313 | Result := SystemTimeToCefTime(st); 314 | end; 315 | 316 | {$ELSE} 317 | 318 | function CefTimeToDateTime(const dt: TCefTime): TDateTime; 319 | begin 320 | Result := EncodeDate(dt.year, dt.month, dt.day_of_month) + EncodeTime(dt.hour, dt.minute, dt.second, dt.millisecond); 321 | end; 322 | 323 | function DateTimeToCefTime(dt: TDateTime): TCefTime; 324 | Var 325 | Year, Month, Day, Hour, Min, Sec, MSec: Word; 326 | begin 327 | DecodeDate(dt, Year, Month, Day); 328 | DecodeTime(dt, Hour, Min, Sec, MSec); 329 | 330 | With Result do 331 | begin 332 | year := Year; 333 | month := Month; 334 | day_of_week := DayOfWeek(dt); 335 | day_of_month := Month; 336 | hour := Hour; 337 | minute := Min; 338 | second := Sec; 339 | millisecond := MSec; 340 | end; 341 | end; 342 | {$ENDIF} 343 | 344 | function TColorToCefColor(const aColor: TColor): TCefColor; 345 | Var 346 | red, green, blue: Byte; 347 | begin 348 | RedGreenBlue(ColorToRGB(aColor), red, green, blue); 349 | Result := CefColorSetARGB(255, red, green, blue); 350 | end; 351 | 352 | function FPColorToCefColor(const aColor: TFPColor): TCefColor; 353 | Const 354 | F = 1 / high(Word) * 255; 355 | begin 356 | With aColor do 357 | Result := CefColorSetARGB(Round(alpha * F), Round(red * F), Round(green * F), Round(blue * F)); 358 | end; 359 | 360 | function CefString(const str: ustring): TCefString; 361 | begin 362 | Result.length := Length(str); 363 | 364 | If Result.length > 0 then Result.str := PCefChar(str) 365 | Else Result.str := nil; 366 | 367 | Result.dtor := nil; 368 | end; 369 | 370 | function CefString(const str: PCefString): ustring; 371 | begin 372 | If str <> nil then SetString(Result, str^.str, str^.length) 373 | Else Result := ''; 374 | end; 375 | 376 | function CefStringClearAndGet(var str: TCefString): ustring; 377 | begin 378 | Result := CefString(@str); 379 | cef_string_clear(@str); 380 | end; 381 | 382 | function CefStringFreeAndGet(const str: PCefStringUserFree): ustring; 383 | begin 384 | If str <> nil then 385 | begin 386 | Result := CefString(PCefString(str)); 387 | cef_string_userfree_free(str); 388 | end 389 | Else Result := ''; 390 | end; 391 | 392 | function CefStringAlloc(const str: ustring): TCefString; 393 | begin 394 | FillChar(Result, SizeOf(Result), 0); 395 | CefStringSet(@Result, str); 396 | end; 397 | 398 | procedure CefStringFree(const str: PCefString); 399 | begin 400 | If str <> nil then cef_string_clear(str); 401 | end; 402 | 403 | procedure _free_string(str: PCefChar); cconv; 404 | begin 405 | If str <> nil then FreeMem(str); 406 | end; 407 | 408 | function CefUserFreeString(const str: ustring): PCefStringUserFree; 409 | begin 410 | Result := cef_string_userfree_alloc(); 411 | Result^.length := Length(str); 412 | Result^.dtor := @_free_string; 413 | 414 | GetMem(Result^.str, Result^.length * SizeOf(TCefChar)); 415 | Move(PCefChar(str)^, Result^.str^, Result^.length * SizeOf(TCefChar)); 416 | end; 417 | 418 | procedure CefStringSet(const str: PCefString; const value: ustring); inline; 419 | begin 420 | If str <> nil then cef_string_set(PCefChar(value), Length(value), str, 1); 421 | end; 422 | 423 | { *** API *** } 424 | 425 | function CefInitialize: Boolean; 426 | Var 427 | Settings: TCefSettings; 428 | App: ICefApp; 429 | ErrCode: Integer; 430 | 431 | Args : TCefMainArgs; 432 | begin 433 | {$IFDEF DEBUG} 434 | Debugln('CefInitialize'); 435 | {$ENDIF} 436 | 437 | If not CefLoadLibrary(CefLibraryDirPath) then 438 | begin 439 | Result := True; 440 | Exit; 441 | end; 442 | 443 | FillChar(Settings, SizeOf(settings), 0); 444 | 445 | Settings.size := SizeOf(Settings); 446 | Settings.single_process := Ord(CefSingleProcess); 447 | Settings.no_sandbox := Ord(CefNoSandbox); 448 | Settings.browser_subprocess_path := CefString(CefBrowserSubprocessPath); 449 | Settings.framework_dir_path := CefString(CefFrameworkDirPath); 450 | {$IFDEF CEF_MULTI_THREADED_MESSAGE_LOOP} 451 | Settings.multi_threaded_message_loop := Ord(True); 452 | {$ELSE} 453 | Settings.multi_threaded_message_loop := Ord(False); 454 | {$ENDIF} 455 | Settings.external_message_pump := Ord(CefExternalMessagePump); 456 | Settings.windowless_rendering_enabled := Ord(CefWindowlessRenderingEnabled); 457 | Settings.cache_path := CefString(CefCachePath); 458 | Settings.command_line_args_disabled := Ord(CefCommandLineArgsDisabled); 459 | Settings.cache_path := CefString(CefCachePath); 460 | Settings.user_data_path := CefString(CefUserDataPath); 461 | Settings.persist_session_cookies := Ord(CefPersistSessionCookies); 462 | Settings.persist_user_preferences := Ord(CefPersistUserPreferences); 463 | Settings.user_agent := CefString(CefUserAgent); 464 | Settings.product_version := CefString(CefProductVersion); 465 | Settings.locale := CefString(CefLocale); 466 | Settings.log_file := CefString(CefLogFile); 467 | Settings.log_severity := CefLogSeverity; 468 | Settings.javascript_flags := CefString(CefJavaScriptFlags); 469 | Settings.resources_dir_path := CefString(CefResourcesDirPath); 470 | Settings.locales_dir_path := CefString(CefLocalesDirPath); 471 | Settings.pack_loading_disabled := Ord(CefPackLoadingDisabled); 472 | Settings.remote_debugging_port := CefRemoteDebuggingPort; 473 | Settings.uncaught_exception_stack_size := CefUncaughtExceptionStackSize; 474 | Settings.context_safety_implementation := CefContextSafetyImplementation; 475 | Settings.ignore_certificate_error := Ord(CefIgnoreCertificateError); 476 | Settings.enable_net_security_expiration := Ord(CefEnableNetSecurityExpiration); 477 | Settings.background_color := FPColorToCefColor(CefBackgroundColor); 478 | Settings.accept_language_list := CefString(CefAcceptLanguageList); 479 | 480 | app := TInternalApp.Create; 481 | 482 | {$IFDEF WINDOWS} 483 | Args.instance := HINSTANCE(); 484 | 485 | ErrCode := cef_execute_process(@Args, CefGetData(app), nil); 486 | {$ELSE} 487 | Args.argc := argc; 488 | Args.argv := argv; 489 | 490 | ErrCode := cef_execute_process(@Args, CefGetData(app), nil); 491 | {$ENDIF} 492 | 493 | If ErrCode >= 0 then Halt(ErrCode); 494 | 495 | ErrCode := cef_initialize(@Args, @settings, CefGetData(app), nil); 496 | If ErrCode <> 1 then 497 | begin 498 | Result := False; 499 | Exit; 500 | end; 501 | 502 | CefIsMainProcess := True; 503 | Result := True; 504 | 505 | {$IFDEF LINUX} 506 | // Install xlib error handlers so that the application won't be terminated 507 | // on non-fatal errors. 508 | XSetErrorHandler(@XErrorHandler); 509 | XSetIOErrorHandler(@XIOErrorHandler); 510 | {$ENDIF} 511 | end; 512 | 513 | procedure CefShutDown; 514 | begin 515 | {$IFDEF DEBUG} 516 | Debugln('CefShutDown'); 517 | {$ENDIF} 518 | 519 | If CefIsMainProcess then 520 | begin 521 | cef_shutdown(); 522 | 523 | CefIsMainProcess := False; 524 | end; 525 | end; 526 | 527 | {$IFNDEF CEF_MULTI_THREADED_MESSAGE_LOOP} 528 | procedure CefDoMessageLoopWork; 529 | begin 530 | cef_do_message_loop_work(); 531 | end; 532 | 533 | procedure CefRunMessageLoop; 534 | begin 535 | cef_run_message_loop(); 536 | end; 537 | 538 | procedure CefQuitMessageLoop; 539 | begin 540 | cef_quit_message_loop(); 541 | end; 542 | {$ENDIF} 543 | 544 | procedure CefSetOsmodalLoop(osModalLoop: Boolean); 545 | begin 546 | cef_set_osmodal_loop(Ord(osModalLoop)); 547 | end; 548 | 549 | procedure CefEnableHighDPISupport; 550 | begin 551 | cef_enable_highdpi_support(); 552 | end; 553 | 554 | function CefBrowserHostCreateBrowser(windowInfo: PCefWindowInfo; const client: ICefClient; 555 | const url: ustring; const settings: PCefBrowserSettings; const requestContext: ICefRequestContext): Boolean; 556 | Var 557 | u : TCefString; 558 | begin 559 | CefInitialize; 560 | u := CefString(url); 561 | Result := cef_browser_host_create_browser(windowInfo, CefGetData(client), @u, settings, CefGetData(requestContext)) <> 0; 562 | end; 563 | 564 | function CefBrowserHostCreateBrowserSync(windowInfo: PCefWindowInfo; const client: ICefClient; 565 | const url: ustring; const settings: PCefBrowserSettings; const requestContext: ICefRequestContext): ICefBrowser; 566 | Var 567 | u: TCefString; 568 | begin 569 | CefInitialize; 570 | u := CefString(url); 571 | Result := TCefBrowserRef.UnWrap(cef_browser_host_create_browser_sync(windowInfo, CefGetData(client), @u, settings, CefGetData(requestContext))); 572 | end; 573 | 574 | function CefCrashReportingEnabled: Boolean; 575 | begin 576 | Result := cef_crash_reporting_enabled() <> 0; 577 | end; 578 | 579 | procedure CefSetCrashKeyValue(const key, value: ustring); 580 | Var 581 | k, v: TCefString; 582 | begin 583 | k := CefString(key); 584 | v := CefString(value); 585 | cef_set_crash_key_value(@k, @v); 586 | end; 587 | 588 | function CefCreateDirectory(const fullPath: ustring): Boolean; 589 | Var 590 | f: TCefString; 591 | begin 592 | f := CefString(fullPath); 593 | Result := cef_create_directory(@f) <> 0; 594 | end; 595 | 596 | function CefGetTempDirectory(out tempDir: ustring): Boolean; 597 | Var 598 | t: TCefString; 599 | begin 600 | FillChar(t, SizeOf(t), 0); 601 | 602 | Result := cef_get_temp_directory(@t) <> 0; 603 | tempDir := CefString(@t); 604 | end; 605 | 606 | function CefCreateNewTempDirectory(const prefix: ustring; out newTempPath: ustring): Boolean; 607 | Var 608 | p, n: TCefString; 609 | begin 610 | p := CefString(prefix); 611 | FillChar(n, SizeOf(n), 0); 612 | 613 | Result := cef_create_new_temp_directory(@p, @n) <> 0; 614 | newTempPath := CefString(@n); 615 | end; 616 | 617 | function CefCreateTempDirectoryInDirectory(const baseDir, prefix: ustring; 618 | out newDir: ustring): Boolean; 619 | Var 620 | b, p, n: TCefString; 621 | begin 622 | b := CefString(baseDir); 623 | p := CefString(prefix); 624 | FillChar(n, SizeOf(n), 0); 625 | 626 | Result := cef_create_temp_directory_in_directory(@b, @p, @n) <> 0; 627 | newDir := CefString(@n); 628 | end; 629 | 630 | function CefDirectoryExists(const path: ustring): Boolean; 631 | Var 632 | p: TCefString; 633 | begin 634 | p := CefString(path); 635 | Result := cef_directory_exists(@p) <> 0; 636 | end; 637 | 638 | function CefDeleteFile(const path: ustring; recursive: Boolean): Boolean; 639 | Var 640 | p: TCefString; 641 | begin 642 | p := CefString(path); 643 | Result := cef_delete_file(@p, Ord(recursive)) <> 0; 644 | end; 645 | 646 | function CefZipDirectory(const srcDir, destFile: ustring; includeHiddenFiles: Boolean): Boolean; 647 | Var 648 | s, d: TCefString; 649 | begin 650 | s := CefString(srcDir); 651 | d := CefString(destFile); 652 | Result := cef_zip_directory(@s, @d, Ord(includeHiddenFiles)) <> 0; 653 | end; 654 | 655 | function CefGetGeolocation(const callback: ICefGetGeolocationCallback): Boolean; 656 | begin 657 | Result := cef_get_geolocation(CefGetData(callback)) <> 0; 658 | end; 659 | 660 | function CefGetGeolocationProc(const callback: TCefGetGeolocationCallbackProc): Boolean; 661 | begin 662 | Result := CefGetGeolocation(TCefFastGetGeolocationCallback.Create(callback)); 663 | end; 664 | 665 | function CefAddCrossOriginWhitelistEntry(const SourceOrigin, TargetProtocol, TargetDomain: ustring; 666 | AllowTargetSubdomains: Boolean): Boolean; 667 | Var 668 | so, tp, td: TCefString; 669 | begin 670 | CefInitialize; 671 | so := CefString(SourceOrigin); 672 | tp := CefString(TargetProtocol); 673 | td := CefString(TargetDomain); 674 | 675 | If TargetDomain <> '' then 676 | Result := cef_add_cross_origin_whitelist_entry(@so, @tp, @td, Ord(AllowTargetSubdomains)) <> 0 677 | Else 678 | Result := cef_add_cross_origin_whitelist_entry(@so, @tp, nil, Ord(AllowTargetSubdomains)) <> 0; 679 | end; 680 | 681 | function CefRemoveCrossOriginWhitelistEntry(const SourceOrigin, TargetProtocol, TargetDomain: ustring; 682 | AllowTargetSubdomains: Boolean): Boolean; 683 | Var 684 | so, tp, td: TCefString; 685 | begin 686 | CefInitialize; 687 | so := CefString(SourceOrigin); 688 | tp := CefString(TargetProtocol); 689 | td := CefString(TargetDomain); 690 | Result := cef_remove_cross_origin_whitelist_entry(@so, @tp, @td, Ord(AllowTargetSubdomains)) <> 0; 691 | end; 692 | 693 | function CefClearCrossOriginWhitelist: Boolean; 694 | begin 695 | CefInitialize; 696 | Result := cef_clear_cross_origin_whitelist() <> 0; 697 | end; 698 | 699 | function CefParseUrl(const url: ustring; var parts: TUrlParts): Boolean; 700 | Var 701 | u: TCefString; 702 | p: TCefUrlParts; 703 | begin 704 | FillChar(p, sizeof(p), 0); 705 | u := CefString(url); 706 | Result := cef_parse_url(@u, @p) <> 0; 707 | If Result then 708 | begin 709 | parts.spec := CefString(@p.spec); 710 | parts.scheme := CefString(@p.scheme); 711 | parts.username := CefString(@p.username); 712 | parts.password := CefString(@p.password); 713 | parts.host := CefString(@p.host); 714 | parts.port := CefString(@p.port); 715 | parts.origin := CefString(@p.origin); 716 | parts.path := CefString(@p.path); 717 | parts.query := CefString(@p.query); 718 | end; 719 | end; 720 | 721 | function CefCreateUrl(var parts: TUrlParts): ustring; 722 | Var 723 | p: TCefUrlParts; 724 | u: TCefString; 725 | begin 726 | FillChar(p, sizeof(p), 0); 727 | 728 | p.spec := CefString(parts.spec); 729 | p.scheme := CefString(parts.scheme); 730 | p.username := CefString(parts.username); 731 | p.password := CefString(parts.password); 732 | p.host := CefString(parts.host); 733 | p.port := CefString(parts.port); 734 | p.origin := CefString(parts.origin); 735 | p.path := CefString(parts.path); 736 | p.query := CefString(parts.query); 737 | 738 | FillChar(u, SizeOf(u), 0); 739 | If cef_create_url(@p, @u) <> 0 then Result := CefString(@u) 740 | Else Result := ''; 741 | end; 742 | 743 | function CefFormatUrlForSecurityDisplay(const originUrl: ustring): ustring; 744 | Var 745 | o: TCefString; 746 | begin 747 | o := CefString(originUrl); 748 | 749 | Result := CefStringFreeAndGet(cef_format_url_for_security_display(@o)); 750 | end; 751 | 752 | function CefGetMimeType(const extension: ustring): ustring; 753 | Var 754 | e: TCefString; 755 | begin 756 | e := CefString(extension); 757 | Result := CefStringFreeAndGet(cef_get_mime_type(@e)); 758 | end; 759 | 760 | procedure CefGetExtensionsForMimeType(const mimeType: ustring; extensions: TStrings); 761 | Var 762 | m, str: TCefString; 763 | i: Integer; 764 | list: TCefStringList; 765 | begin 766 | m := CefString(mimeType); 767 | 768 | list := cef_string_list_alloc(); 769 | try 770 | cef_get_extensions_for_mime_type(@m, list); 771 | 772 | FillChar(str, SizeOf(str), 0); 773 | For i := 0 to cef_string_list_size(list) - 1 do 774 | begin 775 | cef_string_list_value(list, i, @str); 776 | extensions.Add(CefStringClearAndGet(str)); 777 | end; 778 | finally 779 | cef_string_list_free(list); 780 | end; 781 | end; 782 | 783 | function CefBase64Encode(const data: Pointer; dataSize: TSize): ustring; 784 | begin 785 | Result := CefStringFreeAndGet(cef_base64encode(data, dataSize)); 786 | end; 787 | 788 | function CefBase64Decode(const data: ustring): ICefBinaryValue; 789 | Var 790 | u: TCefString; 791 | begin 792 | u := CefString(data); 793 | Result := TCefBinaryValueRef.UnWrap(cef_base64decode(@u)); 794 | end; 795 | 796 | function CefUriEncode(const text: ustring; usePlus: Boolean): ustring; 797 | Var 798 | t: TCefString; 799 | begin 800 | t := CefString(text); 801 | Result := CefStringFreeAndGet(cef_uriencode(@t, Ord(usePlus))); 802 | end; 803 | 804 | function CefUriDecode(const text: ustring; convertToUtf8: Boolean; 805 | unescapeRules: TCefUriUnescapeRule): ustring; 806 | Var 807 | t: TCefString; 808 | begin 809 | t := CefString(text); 810 | Result := CefStringFreeAndGet(cef_uridecode(@t, Ord(convertToUtf8), unescapeRules)); 811 | end; 812 | 813 | function CefParseJson(const jsonString: ustring; options: TCefJsonParserOptions): ICefValue; 814 | Var 815 | j: TCefString; 816 | begin 817 | j := CefString(jsonString); 818 | Result := TCefValueRef.UnWrap(cef_parse_json(@j, options)); 819 | end; 820 | 821 | function CefParseJsonAndReturnError(const jsonString: ustring; options: TCefJsonParserOptions; 822 | out errorCode: TCefJsonParserError; out errorMsg: ustring): ICefValue; 823 | Var 824 | j: TCefString; 825 | e: TCefString; 826 | begin 827 | j := CefString(jsonString); 828 | Result := TCefValueRef.UnWrap(cef_parse_jsonand_return_error(@j, options, @errorCode, @e)); 829 | errorMsg := CefStringClearAndGet(e); 830 | end; 831 | 832 | function CefWriteJson(node: ICefValue; options: TCefJsonWriterOptions): ustring; 833 | begin 834 | Result := CefStringFreeAndGet(cef_write_json(CefGetData(node), options)); 835 | end; 836 | 837 | function CefGetPath(key: TCefPathKey; out path: ustring): Boolean; 838 | Var 839 | p: TCefString; 840 | begin 841 | p := CefString(''); 842 | Result := cef_get_path(key, @p) <> 0; 843 | path := CefStringClearAndGet(p); 844 | end; 845 | 846 | function CefLaunchProcess(commandLine: ICefCommandLine): Boolean; 847 | begin 848 | Result := cef_launch_process(CefGetData(commandLine)) <> 0; 849 | end; 850 | 851 | function CefRegisterSchemeHandlerFactory(const SchemeName, HostName: ustring; 852 | const handler: TCefResourceHandlerClass): Boolean; 853 | Var 854 | s, h: TCefString; 855 | begin 856 | CefInitialize; 857 | s := CefString(SchemeName); 858 | h := CefString(HostName); 859 | Result := cef_register_scheme_handler_factory( 860 | @s, @h, CefGetData(TCefSchemeHandlerFactoryOwn.Create(handler) as ICefBaseRefCounted)) <> 0; 861 | end; 862 | 863 | function CefClearSchemeHandlerFactories: Boolean; 864 | begin 865 | CefInitialize; 866 | Result := cef_clear_scheme_handler_factories() <> 0; 867 | end; 868 | 869 | function CefIsCertStatusError(status: TCefCertStatus): Boolean; 870 | begin 871 | Result := cef_is_cert_status_error(status) <> 0; 872 | end; 873 | 874 | function CefIsCertStatusMinorError(status: TCefCertStatus): Boolean; 875 | begin 876 | Result := cef_is_cert_status_minor_error(status) <> 0; 877 | end; 878 | 879 | function CefCurrentlyOn(ThreadId: TCefThreadId): Boolean; 880 | begin 881 | Result := cef_currently_on(ThreadId) <> 0; 882 | end; 883 | 884 | procedure CefPostTask(ThreadId: TCefThreadId; const task: ICefTask); 885 | begin 886 | cef_post_task(ThreadId, CefGetData(task)); 887 | end; 888 | 889 | procedure CefPostDelayedTask(ThreadId: TCefThreadId; const task: ICefTask; delayMs: Int64); 890 | begin 891 | cef_post_delayed_task(ThreadId, CefGetData(task), delayMs); 892 | end; 893 | 894 | function CefBeginTracing(const categories: ustring; 895 | const callback: ICefCompletionCallback): Boolean; 896 | Var 897 | c: TCefString; 898 | begin 899 | c := CefString(categories); 900 | Result := cef_begin_tracing(@c, CefGetData(callback)) <> 0; 901 | end; 902 | 903 | function CefBeginTracingProc(const categories: ustring; 904 | const proc: TCefCompletionCallbackProc): Boolean; 905 | begin 906 | Result := CefBeginTracing(categories, TCefFastCompletionCallback.Create(proc)); 907 | end; 908 | 909 | function CefEndTracing(const tracingFile: ustring; const callback: ICefEndTracingCallback): Boolean; 910 | Var 911 | t: TCefString; 912 | begin 913 | t := CefString(tracingFile); 914 | Result := cef_end_tracing(@t, CefGetData(callback)) <> 0; 915 | end; 916 | 917 | function CefEndTracingProc(const tracingFile: ustring; 918 | const proc: TCefEndTracingCallbackProc): Boolean; 919 | begin 920 | Result := CefEndTracing(tracingFile, TCefFastEndTracingCallback.Create(proc)); 921 | end; 922 | 923 | function CefNowFromSystemTraceTime: Int64; 924 | begin 925 | Result := cef_now_from_system_trace_time(); 926 | end; 927 | 928 | function CefRegisterExtension(const name, code: ustring; const Handler: ICefv8Handler): Boolean; 929 | Var 930 | n, c: TCefString; 931 | begin 932 | n := CefString(name); 933 | c := CefString(code); 934 | Result := cef_register_extension(@n, @c, CefGetData(handler)) <> 0; 935 | end; 936 | 937 | function Cefv8ContextInContext: Boolean; 938 | begin 939 | Result := cef_v8context_in_context() <> 0; 940 | end; 941 | 942 | procedure CefVisitWebPluginInfo(const visitor: ICefWebPluginInfoVisitor); 943 | begin 944 | cef_visit_web_plugin_info(CefGetData(visitor)); 945 | end; 946 | 947 | procedure CefVisitWebPluginInfoProc(const visitor: TCefWebPluginInfoVisitorProc); 948 | begin 949 | CefVisitWebPluginInfo(TCefFastWebPluginInfoVisitor.Create(visitor)); 950 | end; 951 | 952 | procedure CefRefreshWebPlugins; 953 | begin 954 | cef_refresh_web_plugins(); 955 | end; 956 | 957 | procedure CefUnregisterInternalWebPlugin(const path: ustring); 958 | Var 959 | p: TCefString; 960 | begin 961 | p := CefString(path); 962 | cef_unregister_internal_web_plugin(@p); 963 | end; 964 | 965 | procedure CefRegisterWebPluginCrash(const path: ustring); 966 | Var 967 | p: TCefString; 968 | begin 969 | p := CefString(path); 970 | cef_register_web_plugin_crash(@p); 971 | end; 972 | 973 | procedure CefIsWebPluginUnstable(const path: ustring; const callback: ICefWebPluginUnstableCallback); 974 | Var 975 | p: TCefString; 976 | begin 977 | p := CefString(path); 978 | cef_is_web_plugin_unstable(@p, CefGetData(callback)); 979 | end; 980 | 981 | procedure CefIsWebPluginUnstableProc(const path: ustring; const callback: TCefWebPluginIsUnstableProc); 982 | begin 983 | CefIsWebPluginUnstable(path, TCefFastWebPluginUnstableCallback.Create(callback)); 984 | end; 985 | 986 | procedure CefRegisterWidevineCdm(const path: ustring; const callback: ICefRegisterCdmCallback); 987 | Var 988 | p: TCefString; 989 | begin 990 | p := CefString(path); 991 | cef_register_widevine_cdm(@p, CefGetData(callback)); 992 | end; 993 | 994 | procedure CefRegisterWidevineCdmProc(const path: ustring; const proc: TCefRegisterCdmCallbackProc); 995 | begin 996 | CefRegisterWidevineCdm(path, TCefFastRegisterCdmCallback.Create(proc)); 997 | end; 998 | 999 | function CefGetMinLogLevel: Integer; 1000 | begin 1001 | Result := cef_get_min_log_level(); 1002 | end; 1003 | 1004 | function CefGetVlogLevel(const fileStart: String; n: TSize): Integer; 1005 | begin 1006 | Result := cef_get_vlog_level(PChar(fileStart), n); 1007 | end; 1008 | 1009 | procedure CefLog(const file_: String; line, severity: Integer; const message: String); 1010 | begin 1011 | cef_log(PChar(file_), line, severity, PChar(message)); 1012 | end; 1013 | 1014 | function CefGetCurrentPlatformThreadId: TCefPlatformThreadId; 1015 | begin 1016 | Result := cef_get_current_platform_thread_id(); 1017 | end; 1018 | 1019 | function CefGetCurrentPlatformThreadHandle: TCefPlatformThreadHandle; 1020 | begin 1021 | Result := cef_get_current_platform_thread_handle(); 1022 | end; 1023 | 1024 | function CefTimeNow(out cefTime: TDateTime): Boolean; 1025 | Var 1026 | ct: TCefTime; 1027 | begin 1028 | Result := cef_time_now(@ct) <> 0; 1029 | cefTime := CefTimeToDateTime(ct); 1030 | end; 1031 | 1032 | procedure CefTraceEventInstant(const category, name, arg1_name: String; arg1_val: UInt64; 1033 | const arg2_name: String; arg2_val: UInt64; copy: Integer); 1034 | begin 1035 | cef_trace_event_instant(PChar(category), PChar(name), PChar(arg1_name), arg1_val, PChar(arg2_name), 1036 | arg2_val, copy); 1037 | end; 1038 | 1039 | procedure CefTraceEventBegin(const category, name, arg1_name: String; arg1_val: UInt64; 1040 | const arg2_name: String; arg2_val: UInt64; copy: Integer); 1041 | begin 1042 | cef_trace_event_begin(PChar(category), PChar(name), PChar(arg1_name), arg1_val, PChar(arg2_name), 1043 | arg2_val, copy); 1044 | end; 1045 | 1046 | procedure CefTraceEventEnd(const category, name, arg1_name: String; arg1_val: UInt64; 1047 | const arg2_name: String; arg2_val: UInt64; copy: Integer); 1048 | begin 1049 | cef_trace_event_end(PChar(category), PChar(name), PChar(arg1_name), arg1_val, PChar(arg2_name), 1050 | arg2_val, copy); 1051 | end; 1052 | 1053 | procedure CefTraceCounter(const category, name, arg1_name: String; arg1_val: UInt64; 1054 | const arg2_name: String; arg2_val: UInt64; copy: Integer); 1055 | begin 1056 | cef_trace_counter(PChar(category), PChar(name), PChar(arg1_name), arg1_val, PChar(arg2_name), 1057 | arg2_val, copy); 1058 | end; 1059 | 1060 | procedure CefTraceCounterId(const category, name: String; id: UInt64; const value1_name: String; 1061 | value1_val: UInt64; const value2_name: String; value2_val: UInt64; copy: Integer); 1062 | begin 1063 | cef_trace_counter_id(PChar(category), PChar(name), id, PChar(value1_name), value1_val, 1064 | PChar(value2_name), value2_val, copy); 1065 | end; 1066 | 1067 | procedure CefTraceEventAsyncBegin(const category, name: String; id: UInt64; 1068 | const arg1_name: String; arg1_val: UInt64; const arg2_name: String; arg2_val: UInt64; 1069 | copy: Integer); 1070 | begin 1071 | cef_trace_event_async_begin(PChar(category), PChar(name), id, PChar(arg1_name), arg1_val, 1072 | PChar(arg2_name), arg2_val, copy); 1073 | end; 1074 | 1075 | procedure CefTraceEventAsyncStepInto(const category, name: String; id, step: UInt64; 1076 | const arg1_name: String; arg1_val: UInt64; copy: Integer); 1077 | begin 1078 | cef_trace_event_async_step_into(PChar(category), PChar(name), id, step, PChar(arg1_name), 1079 | arg1_val, copy); 1080 | end; 1081 | 1082 | procedure CefTraceEventAsyncStepPast(const category, name: String; id, step: UInt64; 1083 | const arg1_name: String; arg1_val: UInt64; copy: Integer); 1084 | begin 1085 | cef_trace_event_async_step_past(PChar(category), PChar(name), id, step, PChar(arg1_name), 1086 | arg1_val, copy); 1087 | end; 1088 | 1089 | procedure CefTraceEventAsyncEnd(const category, name: String; id: UInt64; const arg1_name: String; 1090 | arg1_val: UInt64; const arg2_name: String; arg2_val: UInt64; copy: Integer); 1091 | begin 1092 | cef_trace_event_async_end(PChar(category), PChar(name), id, PChar(arg1_name), arg1_val, 1093 | PChar(arg2_name), arg2_val, copy); 1094 | end; 1095 | 1096 | function CefVersionInfo(entry: Integer): Integer; 1097 | begin 1098 | Result := cef_version_info(entry); 1099 | end; 1100 | 1101 | function CefApiHash(entry: Integer): String; 1102 | begin 1103 | Result := cef_api_hash(entry); 1104 | end; 1105 | 1106 | {$IFDEF LINUX} 1107 | procedure CefXWindowResize(const ABrowser: ICefBrowser; const Top, Left, Width, Height: Integer); 1108 | Var 1109 | changes: TXWindowChanges; 1110 | TheHost: ICefBrowserHost; 1111 | begin 1112 | TheHost := ABrowser.Host; 1113 | 1114 | changes.x := Left; 1115 | changes.y := Top; 1116 | changes.width := Width; 1117 | changes.height := Height; 1118 | 1119 | XConfigureWindow(cef_get_xdisplay(), TheHost.WindowHandle, CWX or CWY or CWHeight or CWWidth, @changes); 1120 | end; 1121 | 1122 | procedure CefXLooseFocus(const ABrowser: ICefBrowser); 1123 | begin 1124 | XSetInputFocus(cef_get_xdisplay(), X.None, RevertToNone, CurrentTime); 1125 | 1126 | ABrowser.Host.SendCaptureLostEvent; 1127 | end; 1128 | 1129 | procedure CefXSetVisibility(const ABrowser: ICefBrowser; const Value: Boolean); 1130 | begin 1131 | If Value then XMapWindow(cef_get_xdisplay(), ABrowser.Host.WindowHandle) 1132 | Else XUnmapWindow(cef_get_xdisplay(), ABrowser.Host.WindowHandle); 1133 | end; 1134 | 1135 | procedure CefXDestroyWindow(const Handle: TXID); 1136 | begin 1137 | XDestroyWindow(cef_get_xdisplay(), Handle); 1138 | end; 1139 | 1140 | function XErrorHandler(display: PDisplay; event: PXErrorEvent): Integer; cdecl; 1141 | Var 1142 | error_msg: array[0..100] of Char; 1143 | begin 1144 | {$IFDEF DEBUG} 1145 | WriteLn('X error received: '); 1146 | WriteLn(' type: ', event^._type); 1147 | WriteLn(' serial: ', event^.serial); 1148 | WriteLn(' error code: ', event^.error_code); 1149 | WriteLn(' request code: ', event^.request_code); 1150 | WriteLn(' minor code: ', event^.minor_code); 1151 | 1152 | XGetErrorText(display, event^.error_code, @error_msg, Length(error_msg)); 1153 | 1154 | WriteLn(PChar(@error_msg)); 1155 | {$ENDIF} 1156 | 1157 | Result := 0; 1158 | end; 1159 | 1160 | function XIOErrorHandler(display: PDisplay): Integer; cdecl; 1161 | begin 1162 | {$IFDEF DEBUG} 1163 | WriteLn('XIOErrorHandler'); 1164 | {$ENDIF} 1165 | 1166 | Result := 0; 1167 | end; 1168 | {$ENDIF} 1169 | 1170 | { TC } 1171 | 1172 | procedure TC.Execute; 1173 | begin 1174 | { empty } 1175 | end; 1176 | 1177 | Initialization 1178 | 1179 | // initialize threading system 1180 | With TC.Create(False) do 1181 | begin 1182 | WaitFor; 1183 | Free; 1184 | end; 1185 | 1186 | Finalization 1187 | CefShutDown; 1188 | 1189 | end. 1190 | --------------------------------------------------------------------------------