2017-01-27 17:29:37 +01:00
|
|
|
unit uCEFApplication;
|
|
|
|
|
2018-05-12 14:50:54 +02:00
|
|
|
{$IFDEF FPC}
|
|
|
|
{$MODE OBJFPC}{$H+}
|
|
|
|
{$ENDIF}
|
|
|
|
|
2017-02-05 20:56:46 +01:00
|
|
|
{$I cef.inc}
|
|
|
|
|
2022-02-19 18:56:41 +01:00
|
|
|
{$IFNDEF TARGET_64BITS}{$ALIGN ON}{$ENDIF}
|
|
|
|
{$MINENUMSIZE 4}
|
|
|
|
|
2017-01-27 17:29:37 +01:00
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
2017-02-05 20:56:46 +01:00
|
|
|
{$IFDEF DELPHI16_UP}
|
2019-03-20 15:56:14 +01:00
|
|
|
{$IFDEF MSWINDOWS}
|
2020-12-18 16:51:02 +01:00
|
|
|
WinApi.Windows, WinApi.ActiveX,
|
|
|
|
{$IFDEF FMX}
|
|
|
|
FMX.Forms,
|
|
|
|
{$ELSE}
|
|
|
|
Vcl.Forms,
|
|
|
|
{$ENDIF}
|
2019-03-20 15:56:14 +01:00
|
|
|
{$ENDIF}
|
|
|
|
System.Classes, System.UITypes,
|
2017-02-05 20:56:46 +01:00
|
|
|
{$ELSE}
|
2021-03-21 01:15:00 +01:00
|
|
|
Forms,
|
|
|
|
{$IFDEF MSWINDOWS}Windows, ActiveX,{$ENDIF} Classes, Controls, {$IFDEF FPC}dynlibs,{$ENDIF}
|
|
|
|
{$ENDIF}
|
|
|
|
{$IFDEF FPC}
|
|
|
|
LCLProc,
|
2017-02-05 20:56:46 +01:00
|
|
|
{$ENDIF}
|
2019-11-08 23:15:53 +01:00
|
|
|
uCEFApplicationCore, uCEFTypes;
|
2017-03-16 19:09:42 +01:00
|
|
|
|
|
|
|
const
|
2019-11-08 23:15:53 +01:00
|
|
|
CEF_SUPPORTED_VERSION_MAJOR = uCefApplicationCore.CEF_SUPPORTED_VERSION_MAJOR;
|
|
|
|
CEF_SUPPORTED_VERSION_MINOR = uCefApplicationCore.CEF_SUPPORTED_VERSION_MINOR;
|
|
|
|
CEF_SUPPORTED_VERSION_RELEASE = uCefApplicationCore.CEF_SUPPORTED_VERSION_RELEASE;
|
|
|
|
CEF_SUPPORTED_VERSION_BUILD = uCefApplicationCore.CEF_SUPPORTED_VERSION_BUILD;
|
2017-03-16 19:09:42 +01:00
|
|
|
|
2019-11-08 23:15:53 +01:00
|
|
|
CEF_CHROMEELF_VERSION_MAJOR = uCefApplicationCore.CEF_CHROMEELF_VERSION_MAJOR;
|
|
|
|
CEF_CHROMEELF_VERSION_MINOR = uCefApplicationCore.CEF_CHROMEELF_VERSION_MINOR;
|
|
|
|
CEF_CHROMEELF_VERSION_RELEASE = uCefApplicationCore.CEF_CHROMEELF_VERSION_RELEASE;
|
|
|
|
CEF_CHROMEELF_VERSION_BUILD = uCefApplicationCore.CEF_CHROMEELF_VERSION_BUILD;
|
2017-04-26 15:38:50 +02:00
|
|
|
|
2019-11-08 23:15:53 +01:00
|
|
|
LIBCEF_DLL = uCefApplicationCore.LIBCEF_DLL;
|
|
|
|
CHROMEELF_DLL = uCefApplicationCore.CHROMEELF_DLL;
|
2017-04-26 15:38:50 +02:00
|
|
|
|
2017-01-27 17:29:37 +01:00
|
|
|
type
|
2023-07-19 11:59:20 +02:00
|
|
|
/// <summary>
|
|
|
|
/// Main class used to simplify the CEF initialization and destruction.
|
|
|
|
/// </summary>
|
2019-11-08 23:15:53 +01:00
|
|
|
TCefApplication = class(TCefApplicationCore)
|
2017-01-27 17:29:37 +01:00
|
|
|
protected
|
2019-11-08 20:52:44 +01:00
|
|
|
FDestroyApplicationObject : boolean;
|
2018-11-15 19:08:16 +01:00
|
|
|
FDestroyAppWindows : boolean;
|
2021-03-21 01:15:00 +01:00
|
|
|
{$IFDEF FPC}
|
2021-04-29 17:00:54 +02:00
|
|
|
FContextInitializedHandlers : TMethodList;
|
2021-03-21 01:15:00 +01:00
|
|
|
|
|
|
|
procedure CallContextInitializedHandlers(Data: PtrInt);
|
2023-08-03 15:50:13 +02:00
|
|
|
procedure doOnContextInitialized; override;
|
2021-03-21 01:15:00 +01:00
|
|
|
{$ENDIF}
|
2017-02-04 18:53:29 +01:00
|
|
|
|
2019-11-08 23:15:53 +01:00
|
|
|
procedure BeforeInitSubProcess; override;
|
2020-11-10 15:02:49 +01:00
|
|
|
|
2017-01-27 17:29:37 +01:00
|
|
|
public
|
2017-11-01 09:38:38 +01:00
|
|
|
constructor Create;
|
2017-01-27 17:29:37 +01:00
|
|
|
destructor Destroy; override;
|
2020-10-31 14:23:06 +01:00
|
|
|
procedure UpdateDeviceScaleFactor; override;
|
2019-10-15 18:09:22 +02:00
|
|
|
|
2021-04-18 19:36:20 +02:00
|
|
|
property DestroyApplicationObject : boolean read FDestroyApplicationObject write FDestroyApplicationObject;
|
|
|
|
property DestroyAppWindows : boolean read FDestroyAppWindows write FDestroyAppWindows;
|
2021-03-21 01:15:00 +01:00
|
|
|
|
|
|
|
{$IFDEF FPC}
|
|
|
|
Procedure AddContextInitializedHandler(AHandler: TNotifyEvent);
|
|
|
|
Procedure RemoveContextInitializedHandler(AHandler: TNotifyEvent);
|
|
|
|
{$ENDIF}
|
2017-01-27 17:29:37 +01:00
|
|
|
end;
|
|
|
|
|
2019-11-08 23:15:53 +01:00
|
|
|
TCEFDirectoryDeleterThread = uCEFApplicationCore.TCEFDirectoryDeleterThread;
|
2018-09-18 15:19:44 +02:00
|
|
|
|
2017-01-27 17:29:37 +01:00
|
|
|
var
|
2017-02-04 18:53:29 +01:00
|
|
|
GlobalCEFApp : TCefApplication = nil;
|
2017-01-27 17:29:37 +01:00
|
|
|
|
2019-11-08 23:15:53 +01:00
|
|
|
function CefCursorToWindowsCursor(aCefCursor : TCefCursorType) : TCursor;
|
2018-06-17 14:18:11 +02:00
|
|
|
procedure DestroyGlobalCEFApp;
|
|
|
|
|
2019-10-21 11:17:47 +02:00
|
|
|
// *********************************************************
|
|
|
|
// ********************** ATTENTION ! **********************
|
|
|
|
// *********************************************************
|
|
|
|
// ** **
|
|
|
|
// ** MANY OF THE EVENTS IN CEF4DELPHI COMPONENTS LIKE **
|
|
|
|
// ** TCHROMIUM, TFMXCHROMIUM OR TCEFAPPLICATION ARE **
|
|
|
|
// ** EXECUTED IN A CEF THREAD BY DEFAULT. **
|
|
|
|
// ** **
|
|
|
|
// ** WINDOWS CONTROLS MUST BE CREATED AND DESTROYED IN **
|
|
|
|
// ** THE SAME THREAD TO AVOID ERRORS. **
|
|
|
|
// ** SOME OF THEM RECREATE THE HANDLERS IF THEY ARE **
|
|
|
|
// ** MODIFIED AND CAN CAUSE THE SAME ERRORS. **
|
|
|
|
// ** **
|
|
|
|
// ** DON'T CREATE, MODIFY OR DESTROY WINDOWS CONTROLS **
|
|
|
|
// ** INSIDE THE CEF4DELPHI EVENTS AND USE **
|
|
|
|
// ** SYNCHRONIZATION OBJECTS TO PROTECT VARIABLES AND **
|
|
|
|
// ** FIELDS IF THEY ARE ALSO USED IN THE MAIN THREAD. **
|
|
|
|
// ** **
|
|
|
|
// ** READ THIS FOR MORE INFORMATION : **
|
|
|
|
// ** https://www.briskbard.com/index.php?pageid=cef **
|
|
|
|
// ** **
|
|
|
|
// ** USE OUR FORUMS FOR MORE QUESTIONS : **
|
|
|
|
// ** https://www.briskbard.com/forum/ **
|
|
|
|
// ** **
|
|
|
|
// *********************************************************
|
|
|
|
// *********************************************************
|
|
|
|
|
2017-01-27 17:29:37 +01:00
|
|
|
implementation
|
|
|
|
|
|
|
|
uses
|
2017-02-05 20:56:46 +01:00
|
|
|
{$IFDEF DELPHI16_UP}
|
2019-11-08 20:52:44 +01:00
|
|
|
System.Math, System.IOUtils, System.SysUtils, {$IFDEF MSWINDOWS}WinApi.TlHelp32, WinApi.PSAPI,{$ENDIF}
|
2017-02-05 20:56:46 +01:00
|
|
|
{$ELSE}
|
2018-05-12 14:50:54 +02:00
|
|
|
Math, {$IFDEF DELPHI14_UP}IOUtils,{$ENDIF} SysUtils,
|
|
|
|
{$IFDEF FPC}
|
2018-10-25 12:50:01 +02:00
|
|
|
{$IFDEF MSWINDOWS}jwatlhelp32, jwapsapi,{$ENDIF}
|
2018-05-12 14:50:54 +02:00
|
|
|
{$ELSE}
|
2018-10-25 12:50:01 +02:00
|
|
|
TlHelp32, {$IFDEF MSWINDOWS}PSAPI,{$ENDIF}
|
2018-05-12 14:50:54 +02:00
|
|
|
{$ENDIF}
|
2017-02-05 20:56:46 +01:00
|
|
|
{$ENDIF}
|
2020-10-31 14:23:06 +01:00
|
|
|
uCEFConstants, uCEFMiscFunctions;
|
2019-11-08 23:15:53 +01:00
|
|
|
|
|
|
|
function CefCursorToWindowsCursor(aCefCursor : TCefCursorType) : TCursor;
|
|
|
|
begin
|
|
|
|
case aCefCursor of
|
|
|
|
CT_POINTER : Result := crArrow;
|
|
|
|
CT_CROSS : Result := crCross;
|
|
|
|
CT_HAND : Result := crHandPoint;
|
|
|
|
CT_IBEAM : Result := crIBeam;
|
|
|
|
CT_WAIT : Result := crHourGlass;
|
|
|
|
CT_HELP : Result := crHelp;
|
|
|
|
CT_EASTRESIZE : Result := crSizeWE;
|
|
|
|
CT_NORTHRESIZE : Result := crSizeNS;
|
|
|
|
CT_NORTHEASTRESIZE : Result := crSizeNESW;
|
|
|
|
CT_NORTHWESTRESIZE : Result := crSizeNWSE;
|
|
|
|
CT_SOUTHRESIZE : Result := crSizeNS;
|
|
|
|
CT_SOUTHEASTRESIZE : Result := crSizeNWSE;
|
|
|
|
CT_SOUTHWESTRESIZE : Result := crSizeNESW;
|
|
|
|
CT_WESTRESIZE : Result := crSizeWE;
|
|
|
|
CT_NORTHSOUTHRESIZE : Result := crSizeNS;
|
|
|
|
CT_EASTWESTRESIZE : Result := crSizeWE;
|
|
|
|
CT_NORTHEASTSOUTHWESTRESIZE : Result := crSizeNESW;
|
|
|
|
CT_NORTHWESTSOUTHEASTRESIZE : Result := crSizeNWSE;
|
|
|
|
CT_COLUMNRESIZE : Result := crHSplit;
|
|
|
|
CT_ROWRESIZE : Result := crVSplit;
|
|
|
|
CT_MOVE : Result := crSizeAll;
|
|
|
|
CT_PROGRESS : Result := crAppStart;
|
|
|
|
CT_NONE : Result := crNone;
|
|
|
|
CT_NODROP,
|
|
|
|
CT_NOTALLOWED : Result := crNo;
|
|
|
|
CT_GRAB,
|
|
|
|
CT_GRABBING : Result := crDrag;
|
|
|
|
|
|
|
|
else Result := crDefault;
|
|
|
|
end;
|
|
|
|
end;
|
2017-02-26 16:23:01 +01:00
|
|
|
|
2018-06-17 14:18:11 +02:00
|
|
|
procedure DestroyGlobalCEFApp;
|
|
|
|
begin
|
|
|
|
if (GlobalCEFApp <> nil) then FreeAndNil(GlobalCEFApp);
|
|
|
|
end;
|
|
|
|
|
2017-11-01 09:38:38 +01:00
|
|
|
constructor TCefApplication.Create;
|
2017-01-27 17:29:37 +01:00
|
|
|
begin
|
2021-03-21 01:15:00 +01:00
|
|
|
{$IFDEF FPC}
|
|
|
|
FContextInitializedHandlers := TMethodList.Create;
|
|
|
|
{$ENDIF}
|
|
|
|
|
2017-01-27 17:29:37 +01:00
|
|
|
inherited Create;
|
2021-04-18 19:36:20 +02:00
|
|
|
|
|
|
|
if (GlobalCEFApp = nil) then
|
2019-11-08 23:15:53 +01:00
|
|
|
GlobalCEFApp := Self;
|
2017-01-27 17:29:37 +01:00
|
|
|
|
2021-04-18 19:36:20 +02:00
|
|
|
FDestroyApplicationObject := False;
|
|
|
|
FDestroyAppWindows := True;
|
2017-01-27 17:29:37 +01:00
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TCefApplication.Destroy;
|
|
|
|
begin
|
2021-04-18 19:36:20 +02:00
|
|
|
if (GlobalCEFApp = Self) then
|
2019-11-08 23:15:53 +01:00
|
|
|
GlobalCEFApp := nil;
|
2021-04-18 19:36:20 +02:00
|
|
|
|
2021-03-21 01:15:00 +01:00
|
|
|
{$IFDEF FPC}
|
2021-04-29 17:00:54 +02:00
|
|
|
FreeAndNil(FContextInitializedHandlers);
|
2021-03-21 01:15:00 +01:00
|
|
|
{$ENDIF}
|
2021-04-29 17:00:54 +02:00
|
|
|
|
|
|
|
inherited Destroy;
|
2017-02-12 19:53:06 +01:00
|
|
|
end;
|
|
|
|
|
2020-10-31 14:23:06 +01:00
|
|
|
procedure TCefApplication.UpdateDeviceScaleFactor;
|
|
|
|
{$IFDEF MSWINDOWS}
|
|
|
|
{$IFNDEF FMX}
|
|
|
|
var
|
|
|
|
TempHandle : HWND;
|
|
|
|
TempDPI : UINT;
|
|
|
|
{$ENDIF}
|
|
|
|
{$ENDIF}
|
|
|
|
begin
|
|
|
|
{$IFDEF MSWINDOWS}
|
|
|
|
{$IFNDEF FMX}
|
|
|
|
if RunningWindows10OrNewer then
|
|
|
|
begin
|
|
|
|
if assigned(screen.ActiveForm) and
|
|
|
|
screen.ActiveForm.HandleAllocated then
|
|
|
|
TempHandle := screen.ActiveForm.Handle
|
|
|
|
else
|
|
|
|
if assigned(Application.MainForm) and
|
|
|
|
Application.MainForm.HandleAllocated then
|
|
|
|
TempHandle := Application.MainForm.Handle
|
|
|
|
else
|
|
|
|
TempHandle := Application.Handle;
|
|
|
|
|
|
|
|
if GetDPIForHandle(TempHandle, TempDPI) then
|
|
|
|
FDeviceScaleFactor := TempDPI / USER_DEFAULT_SCREEN_DPI
|
|
|
|
else
|
|
|
|
inherited UpdateDeviceScaleFactor;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
{$ENDIF}
|
|
|
|
inherited UpdateDeviceScaleFactor;
|
|
|
|
{$ELSE}
|
|
|
|
inherited UpdateDeviceScaleFactor;
|
|
|
|
{$ENDIF}
|
|
|
|
end;
|
|
|
|
|
2021-03-21 01:15:00 +01:00
|
|
|
{$IFDEF FPC}
|
2023-08-03 15:50:13 +02:00
|
|
|
procedure TCefApplication.doOnContextInitialized;
|
2021-03-21 01:15:00 +01:00
|
|
|
begin
|
2023-08-03 15:50:13 +02:00
|
|
|
inherited doOnContextInitialized;
|
2021-04-29 17:00:54 +02:00
|
|
|
|
2021-03-21 01:15:00 +01:00
|
|
|
Application.QueueAsyncCall(@CallContextInitializedHandlers, 0);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TCefApplication.AddContextInitializedHandler(AHandler: TNotifyEvent);
|
|
|
|
begin
|
2021-04-29 17:00:54 +02:00
|
|
|
if FGlobalContextInitialized then
|
|
|
|
AHandler(Self)
|
|
|
|
else
|
|
|
|
if (FContextInitializedHandlers <> nil) then
|
|
|
|
FContextInitializedHandlers.Add(TMethod(AHandler));
|
2021-03-21 01:15:00 +01:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TCefApplication.RemoveContextInitializedHandler(AHandler: TNotifyEvent);
|
|
|
|
begin
|
2021-04-29 17:00:54 +02:00
|
|
|
if (FContextInitializedHandlers <> nil) then
|
|
|
|
FContextInitializedHandlers.Remove(TMethod(AHandler));
|
2021-03-21 01:15:00 +01:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TCefApplication.CallContextInitializedHandlers(Data: PtrInt);
|
|
|
|
begin
|
2021-04-29 17:00:54 +02:00
|
|
|
if (FContextInitializedHandlers <> nil) then
|
|
|
|
FContextInitializedHandlers.CallNotifyEvents(Self);
|
2021-03-21 01:15:00 +01:00
|
|
|
end;
|
|
|
|
{$ENDIF}
|
|
|
|
|
2019-11-08 23:15:53 +01:00
|
|
|
procedure TCefApplication.BeforeInitSubProcess;
|
|
|
|
{$IFNDEF FPC}
|
|
|
|
{$IFNDEF FMX}
|
2017-10-03 14:38:37 +02:00
|
|
|
var
|
2019-11-08 23:15:53 +01:00
|
|
|
AppDestroy: procedure(Obj: TApplication; ReleaseMemoryFlag: Byte);
|
|
|
|
{$ENDIF}
|
|
|
|
{$ENDIF}
|
2017-01-27 17:29:37 +01:00
|
|
|
begin
|
2019-11-08 20:52:44 +01:00
|
|
|
{$IFNDEF FPC}
|
|
|
|
{$IFNDEF FMX}
|
2021-04-18 19:36:20 +02:00
|
|
|
if (Application <> nil) then
|
2017-12-05 10:02:07 +01:00
|
|
|
begin
|
2019-11-08 23:15:53 +01:00
|
|
|
if FDestroyApplicationObject then
|
2017-09-07 10:58:09 +02:00
|
|
|
begin
|
2019-11-08 23:15:53 +01:00
|
|
|
// Call the destructor in "inherited Destroy" mode. This makes it possible to undo
|
|
|
|
// all the code that TApplication.Create did without actually releasing the Application
|
|
|
|
// object so that TControl.Destroy and DoneApplication dont't crash.
|
|
|
|
//
|
|
|
|
// Undoing also includes destroying the "AppWindows" and calling OleUninitialize what
|
|
|
|
// allows CEF to initialize the COM thread model the way it is required in the
|
|
|
|
// sub-processes (debug assertion).
|
|
|
|
AppDestroy := @TApplication.Destroy;
|
|
|
|
AppDestroy(Application, 0);
|
|
|
|
// Set all sub-objects to nil (we destroyed them already). This prevents the second
|
|
|
|
// TApplication.Destroy call in DoneApplication from trying to release already released
|
|
|
|
// objects.
|
|
|
|
TApplication.InitInstance(Application);
|
2017-12-05 10:02:07 +01:00
|
|
|
end
|
|
|
|
else
|
2018-03-29 20:02:04 +02:00
|
|
|
begin
|
2019-11-08 23:15:53 +01:00
|
|
|
if FDestroyAppWindows then
|
2018-03-29 20:02:04 +02:00
|
|
|
begin
|
2019-11-08 23:15:53 +01:00
|
|
|
// This is the fix for the issue #139
|
|
|
|
// https://github.com/salvadordf/CEF4Delphi/issues/139
|
|
|
|
// Subprocesses will never use these window handles but TApplication creates them
|
|
|
|
// before executing the code in the DPR file. Any other application trying to
|
|
|
|
// initiate a DDE conversation will use SendMessage or SendMessageTimeout to
|
|
|
|
// broadcast the WM_DDE_INITIATE to all top-level windows. The subprocesses never
|
|
|
|
// call Application.Run so the SendMessage freezes the other applications.
|
|
|
|
if (Application.Handle <> 0) then DestroyWindow(Application.Handle);
|
|
|
|
{$IFDEF DELPHI9_UP}
|
|
|
|
if (Application.PopupControlWnd <> 0) then DeallocateHWnd(Application.PopupControlWnd);
|
|
|
|
{$ENDIF}
|
|
|
|
end;
|
2021-04-18 19:36:20 +02:00
|
|
|
|
|
|
|
if not(IsLibrary) then
|
2019-11-08 23:15:53 +01:00
|
|
|
begin
|
|
|
|
// Undo the OleInitialize from TApplication.Create. The sub-processes want a different
|
|
|
|
// COM thread model and fail with an assertion if the Debug-DLLs are used.
|
|
|
|
OleUninitialize;
|
2018-03-29 20:02:04 +02:00
|
|
|
end;
|
2017-12-18 19:38:56 +01:00
|
|
|
end;
|
2018-01-25 21:34:04 +01:00
|
|
|
end;
|
2019-11-08 23:15:53 +01:00
|
|
|
{$ELSE} // FMX
|
|
|
|
{$IFDEF MSWINDOWS}
|
|
|
|
// Undo the OleInitialize from FMX.Platform.Win::initialization. The sub-processes want a different
|
|
|
|
// COM thread model and fail with an assertion if the Debug-DLLs are used.
|
|
|
|
OleUninitialize;
|
|
|
|
{$ENDIF MSWINDOWS}
|
2018-05-24 19:15:41 +02:00
|
|
|
{$ENDIF}
|
|
|
|
{$ENDIF}
|
|
|
|
end;
|
|
|
|
|
2017-01-27 17:29:37 +01:00
|
|
|
end.
|