2018-04-18 10:25:38 +02:00
unit uCEFMiscFunctions;
2021-06-24 17:47:22 +02:00
{$I cef.inc}
2018-05-12 14:50:54 +02:00
{$IFDEF FPC}
{$MODE OBJFPC} {$H+}
2021-06-24 17:47:22 +02:00
{$IFDEF MACOSX}
{$ModeSwitch objectivec1}
{$ENDIF}
2018-05-12 14:50:54 +02:00
{$ENDIF}
2022-02-19 18:56:41 +01:00
{$IFNDEF TARGET_64BITS} {$ALIGN ON} {$ENDIF}
2018-11-22 15:02:21 +01:00
{$MINENUMSIZE 4}
2018-04-18 10:25:38 +02:00
2021-01-05 11:44:41 +01:00
{$IFNDEF FPC} {$IFNDEF DELPHI12_UP}
// Workaround for "Internal error" in old Delphi versions caused by uint64 handling
{$R-}
{$ENDIF} {$ENDIF}
2018-04-18 10:25:38 +02:00
interface
uses
{$IFDEF DELPHI16_UP}
2020-01-28 11:36:34 +01:00
{$IFDEF MSWINDOWS}
2023-06-07 13:05:04 +02:00
WinApi . Windows, WinApi . ActiveX, Winapi . ShellApi, System. Win. Registry,
2020-01-28 11:36:34 +01:00
{$ELSE}
2021-06-24 17:47:22 +02:00
{$IFDEF MACOSX} Macapi. Foundation, FMX. Helpers. Mac, Macapi. AppKit, {$ENDIF}
2020-01-28 11:36:34 +01:00
{$ENDIF}
2021-06-24 17:47:22 +02:00
{$IFDEF FMX} FMX. Types, FMX. Platform , {$ENDIF} System. Types, System. IOUtils,
System. Classes, System. SysUtils, System. UITypes, System. Math,
2018-04-18 10:25:38 +02:00
{$ELSE}
2023-06-07 13:05:04 +02:00
{$IFDEF MSWINDOWS} Windows, ActiveX, ShellApi, Registry, {$ENDIF}
2020-04-03 17:57:52 +02:00
{$IFDEF DELPHI14_UP} Types, IOUtils, {$ENDIF} Classes, SysUtils, Math,
2021-01-31 16:53:07 +01:00
{$IFDEF FPC} LCLType, LazFileUtils, {$IFNDEF MSWINDOWS} InterfaceBase, Forms, {$ENDIF} {$ENDIF}
2020-12-31 12:15:10 +01:00
{$IFDEF LINUX} {$IFDEF FPC}
ctypes, keysym, xf86keysym, x, xlib,
{$IFDEF LCLGTK2} gtk2, glib2, gdk2, gtk2proc, gtk2int, Gtk2Def, gdk2x, Gtk2Extra, {$ENDIF}
2022-06-25 16:41:34 +02:00
{$IFDEF LCLGTK3} LazGdk3, LazGtk3, LazGLib2, gtk3widgets, {$ENDIF}
2020-12-31 12:15:10 +01:00
{$ENDIF} {$ENDIF}
2018-04-18 10:25:38 +02:00
{$ENDIF}
2022-06-25 16:41:34 +02:00
uCEFTypes, uCEFInterfaces, uCEFLibFunctions, uCEFResourceHandler,
{$IFDEF LINUX} {$IFDEF FPC} uCEFLinuxFunctions, {$ENDIF} {$ENDIF} uCEFConstants;
2018-04-18 10:25:38 +02:00
const
Kernel32DLL = 'kernel32.dll' ;
SHLWAPIDLL = 'shlwapi.dll' ;
2021-01-08 16:01:06 +01:00
NTDLL = 'ntdll.dll' ;
User32DLL = 'User32.dll' ;
2023-04-15 14:59:17 +02:00
Netapi32DLL = 'Netapi32.dll' ;
2020-01-13 15:39:44 +01:00
2023-07-30 18:47:35 +02:00
/// <summary>Return the alpha byte from a cef_color_t value.</summary>
2018-04-18 10:25:38 +02:00
function CefColorGetA( color: TCefColor) : Byte ;
2023-07-30 18:47:35 +02:00
/// <summary>Return the red byte from a cef_color_t value.</summary>
2018-04-18 10:25:38 +02:00
function CefColorGetR( color: TCefColor) : byte ;
2023-07-30 18:47:35 +02:00
/// <summary>Return the green byte from a cef_color_t value.</summary>
2018-04-18 10:25:38 +02:00
function CefColorGetG( color: TCefColor) : Byte ;
2023-07-30 18:47:35 +02:00
/// <summary>Return the blue byte from a cef_color_t value.</summary>
2018-04-18 10:25:38 +02:00
function CefColorGetB( color: TCefColor) : Byte ;
2023-07-30 18:47:35 +02:00
/// <summary>Return an cef_color_t value with the specified byte component values.</summary>
2018-04-18 10:25:38 +02:00
function CefColorSetARGB( a, r, g, b: Byte ) : TCefColor;
2023-07-30 18:47:35 +02:00
/// <summary>Return an int64_t value with the specified low and high int32_t component values.</summary>
2018-04-18 10:25:38 +02:00
function CefInt64Set( int32_low, int32_high: Integer ) : Int64 ;
2023-07-30 18:47:35 +02:00
/// <summary>Return the low int32_t value from an int64_t value.</summary>
2018-04-18 10:25:38 +02:00
function CefInt64GetLow( const int64_val: Int64 ) : Integer ;
2023-07-30 18:47:35 +02:00
/// <summary>Return the high int32_t value from an int64_t value.</summary>
2018-04-18 10:25:38 +02:00
function CefInt64GetHigh( const int64_val: Int64 ) : Integer ;
2021-05-16 19:42:25 +02:00
function CefGetObject( ptr: Pointer ) : TObject; {$IFNDEF CEF4DELHI_ALLOC_DEBUG} {$IFDEF SUPPORTS_INLINE} inline ; {$ENDIF} {$ENDIF}
2021-01-18 11:12:01 +01:00
function CefGetData( const i: ICefBaseRefCounted) : Pointer ; {$IFDEF SUPPORTS_INLINE} inline ; {$ENDIF}
2018-04-18 10:25:38 +02:00
function CefStringAlloc( const str: ustring) : TCefString;
2019-11-24 18:19:49 +01:00
function CefStringClearAndGet( str: PCefString) : ustring;
2018-04-18 10:25:38 +02:00
2023-11-16 16:58:47 +01:00
/// <summary>Converts ustring to TCefString.</summary>
2018-04-18 10:25:38 +02:00
function CefString( const str: ustring) : TCefString; overload ;
2023-11-16 16:58:47 +01:00
/// <summary>Converts PCefString to ustring.</summary>
2018-04-18 10:25:38 +02:00
function CefString( const str: PCefString) : ustring; overload ;
function CefUserFreeString( const str: ustring) : PCefStringUserFree;
procedure CefStringFree( const str: PCefString) ;
function CefStringFreeAndGet( const str: PCefStringUserFree) : ustring;
procedure CefStringSet( const str: PCefString; const value: ustring) ;
2021-01-18 11:12:01 +01:00
procedure CefStringInitialize( const aCefString : PCefString) ; {$IFDEF SUPPORTS_INLINE} inline ; {$ENDIF}
2018-04-18 10:25:38 +02:00
2023-11-16 16:58:47 +01:00
/// <summary>
/// Register a new V8 extension with the specified JavaScript extension code and
/// handler. Functions implemented by the handler are prototyped using the
/// keyword 'native'. The calling of a native function is restricted to the
/// scope in which the prototype of the native function is defined. This
/// function may only be called on the render process main thread.
///
/// Example JavaScript extension code: <pre>
/// // create the 'example' global object if it doesn't already exist.
/// if (!example)
/// example = {};
/// // create the 'example.test' global object if it doesn't already exist.
/// if (!example.test)
/// example.test = {};
/// (function() {
/// // Define the function 'example.test.myfunction'.
/// example.test.myfunction = function() {
/// // Call CefV8Handler::Execute() with the function name 'MyFunction'
/// // and no arguments.
/// native function MyFunction();
/// return MyFunction();
/// };
/// // Define the getter function for parameter 'example.test.myparam'.
/// example.test.__defineGetter__('myparam', function() {
/// // Call CefV8Handler::Execute() with the function name 'GetMyParam'
/// // and no arguments.
/// native function GetMyParam();
/// return GetMyParam();
/// });
/// // Define the setter function for parameter 'example.test.myparam'.
/// example.test.__defineSetter__('myparam', function(b) {
/// // Call CefV8Handler::Execute() with the function name 'SetMyParam'
/// // and a single argument.
/// native function SetMyParam();
/// if(b) SetMyParam(b);
/// });
///
/// // Extension definitions can also contain normal JavaScript variables
/// // and functions.
/// var myint = 0;
/// example.test.increment = function() {
/// myint += 1;
/// return myint;
/// };
/// })();
/// </pre>
///
/// Example usage in the page: <pre>
/// // Call the function.
/// example.test.myfunction();
/// // Set the parameter.
/// example.test.myparam = value;
/// // Get the parameter.
/// value = example.test.myparam;
/// // Call another function.
/// example.test.increment();
/// </pre>
/// </summary>
2019-10-19 10:58:34 +02:00
function CefRegisterExtension( const name , code: ustring; const Handler: ICefv8Handler) : Boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Post a task for execution on the specified thread. Equivalent to using
/// TCefTaskRunnerRef.GetForThread(threadId).PostTask(task).
/// </summary>
2019-10-19 10:58:34 +02:00
function CefPostTask( aThreadId : TCefThreadId; const aTask: ICefTask) : boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Post a task for delayed execution on the specified thread. Equivalent to
/// using TCefTaskRunnerRef.GetForThread(threadId).PostDelayedTask(task,
/// delay_ms).
/// </summary>
2019-10-19 10:58:34 +02:00
function CefPostDelayedTask( aThreadId : TCefThreadId; const aTask : ICefTask; aDelayMs : Int64 ) : boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Returns true (1) if called on the specified thread. Equivalent to using
/// TCefTaskRunnerRef.GetForThread(threadId).BelongsToCurrentThread().
/// </summary>
2019-10-19 10:58:34 +02:00
function CefCurrentlyOn( aThreadId : TCefThreadId) : boolean ;
2018-04-18 10:25:38 +02:00
2020-12-18 16:51:02 +01:00
{$IFDEF MSWINDOWS}
2023-11-16 16:58:47 +01:00
/// <summary>
/// Converts a TCefTime value to TSystemTime.
/// </summary>
2018-04-18 10:25:38 +02:00
function CefTimeToSystemTime( const dt: TCefTime) : TSystemTime;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Converts a TSystemTime value to TCefTime.
/// </summary>
2018-04-18 10:25:38 +02:00
function SystemTimeToCefTime( const dt: TSystemTime) : TCefTime;
2020-12-18 16:51:02 +01:00
{$ELSE}
{$IFDEF LINUX}
{$IFDEF FPC}
2023-11-16 16:58:47 +01:00
/// <summary>
/// Converts a TCefTime value to TSystemTime.
/// </summary>
2020-12-18 16:51:02 +01:00
function CefTimeToSystemTime( const dt: TCefTime) : TSystemTime;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Converts a TSystemTime value to TCefTime.
/// </summary>
2020-12-18 16:51:02 +01:00
function SystemTimeToCefTime( const dt: TSystemTime) : TCefTime;
{$ENDIF}
{$ENDIF}
2020-01-28 11:36:34 +01:00
{$ENDIF}
2023-11-16 16:58:47 +01:00
/// <summary>
/// Returns a new TCefTime with a valid time in case the original has errors.
/// </summary>
2021-01-18 11:12:01 +01:00
function FixCefTime( const dt : TCefTime) : TCefTime;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Converts a TCefTime value to TDateTime.
/// </summary>
2018-04-18 10:25:38 +02:00
function CefTimeToDateTime( const dt: TCefTime) : TDateTime;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Converts a TDateTime value to TCefTime.
/// </summary>
2018-04-18 10:25:38 +02:00
function DateTimeToCefTime( dt: TDateTime) : TCefTime;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Converts a TDateTime value to TCefBaseTime.
/// </summary>
2022-09-04 19:18:07 +02:00
function DateTimeToCefBaseTime( dt: TDateTime) : TCefBaseTime;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Converts TCefTime to a double which is the number of seconds since
/// epoch (Jan 1, 1970). Webkit uses this format to represent time. A value of 0
/// means "not initialized".
/// </summary>
/// <remarks>
/// <para><see href="https://bitbucket.org/chromiumembedded/cef/src/master/include/internal/cef_time.h">CEF source file: /include/internal/cef_time.h (cef_time_to_doublet)</see></para>
/// </remarks>
2022-06-14 11:27:45 +02:00
function CefTimeToDouble( const dt: TCefTime) : double ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Converts TCefTime from a double which is the number of seconds since
/// epoch (Jan 1, 1970). Webkit uses this format to represent time. A value of 0
/// means "not initialized".
/// </summary>
/// <remarks>
/// <para><see href="https://bitbucket.org/chromiumembedded/cef/src/master/include/internal/cef_time.h">CEF source file: /include/internal/cef_time.h (cef_time_from_doublet)</see></para>
/// </remarks>
2022-06-14 11:27:45 +02:00
function DoubleToCefTime( const dt: double ) : TCefTime;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Converts cef_time_t to time_t. time_t is almost always an integral value holding the number of seconds (not counting leap seconds) since 00:00, Jan 1 1970 UTC, corresponding to POSIX time.
/// </summary>
/// <remarks>
/// <para><see href="https://bitbucket.org/chromiumembedded/cef/src/master/include/internal/cef_time.h">CEF source file: /include/internal/cef_time.h (cef_time_to_timet)</see></para>
/// </remarks>
2022-06-14 11:27:45 +02:00
function CefTimeToUnixTime( const dt: TCefTime) : int64 ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Converts cef_time_t from time_t. time_t is almost always an integral value holding the number of seconds (not counting leap seconds) since 00:00, Jan 1 1970 UTC, corresponding to POSIX time.
/// </summary>
/// <remarks>
/// <para><see href="https://bitbucket.org/chromiumembedded/cef/src/master/include/internal/cef_time.h">CEF source file: /include/internal/cef_time.h (cef_time_from_timet)</see></para>
/// </remarks>
2022-06-14 11:27:45 +02:00
function UnixTimeToCefTime( const dt: int64 ) : TCefTime;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Retrieve the current system time in a TCefTime type.
/// </summary>
/// <remarks>
/// <para><see href="https://bitbucket.org/chromiumembedded/cef/src/master/include/internal/cef_time.h">CEF source file: /include/internal/cef_time.h (cef_time_now)</see></para>
/// </remarks>
2022-06-14 11:27:45 +02:00
function CefTimeNow: TCefTime;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Retrieve the current system time in a double type.
/// </summary>
/// <remarks>
/// <para><see href="https://bitbucket.org/chromiumembedded/cef/src/master/include/internal/cef_time.h">CEF source file: /include/internal/cef_time.h (cef_time_now)</see></para>
/// </remarks>
2022-06-14 11:27:45 +02:00
function DoubleTimeNow: double ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Retrieve the delta in milliseconds between two time values.
/// </summary>
/// <remarks>
/// <para><see href="https://bitbucket.org/chromiumembedded/cef/src/master/include/internal/cef_time.h">CEF source file: /include/internal/cef_time.h (cef_time_delta)</see></para>
/// </remarks>
2022-06-14 11:27:45 +02:00
function CefTimeDelta( const cef_time1, cef_time2: TCefTime) : int64 ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Retrieve the current system time in a TCefBaseTime type.
/// </summary>
/// <remarks>
/// <para><see href="https://bitbucket.org/chromiumembedded/cef/src/master/include/internal/cef_time.h">CEF source file: /include/internal/cef_time.h (cef_basetime_now)</see></para>
/// </remarks>
2022-09-04 19:18:07 +02:00
function CefBaseTimeNow: TCefBaseTime;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Converts TCefTime to TCefBaseTime.
/// </summary>
/// <remarks>
/// <para><see href="https://bitbucket.org/chromiumembedded/cef/src/master/include/internal/cef_time.h">CEF source file: /include/internal/cef_time.h (cef_time_to_basetime)</see></para>
/// </remarks>
2022-09-04 19:18:07 +02:00
function CetTimeToCefBaseTime( const ct: TCefTime) : TCefBaseTime;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Converts TCefBaseTime to TCefTime.
/// </summary>
/// <remarks>
/// <para><see href="https://bitbucket.org/chromiumembedded/cef/src/master/include/internal/cef_time.h">CEF source file: /include/internal/cef_time.h (cef_time_from_basetime)</see></para>
/// </remarks>
2022-09-04 19:18:07 +02:00
function CetTimeFromCefBaseTime( const cbt: TCefBaseTime) : TCefTime;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Converts TCefBaseTime to TDateTime.
/// </summary>
/// <remarks>
/// <para><see href="https://bitbucket.org/chromiumembedded/cef/src/master/include/internal/cef_time.h">CEF source file: /include/internal/cef_time.h (cef_time_from_basetime)</see></para>
/// </remarks>
2022-09-04 19:18:07 +02:00
function CefBaseTimeToDateTime( const cbt: TCefBaseTime) : TDateTime;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Returns the time interval between now and from_ in milliseconds.
/// This funcion should only be used by TCEFTimerWorkScheduler.
/// </summary>
2022-06-14 11:27:45 +02:00
function GetTimeIntervalMilliseconds( const from_: TCefTime) : integer ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Initialize a TCefTime variable.
/// </summary>
2022-06-14 11:27:45 +02:00
procedure InitializeCefTime( var aTime : TCefTime) ;
2018-04-18 10:25:38 +02:00
function cef_string_wide_copy( const src: PWideChar ; src_len: NativeUInt ; output: PCefStringWide) : Integer ;
function cef_string_utf8_copy( const src: PAnsiChar ; src_len: NativeUInt ; output: PCefStringUtf8) : Integer ;
function cef_string_utf16_copy( const src: PChar16; src_len: NativeUInt ; output: PCefStringUtf16) : Integer ;
function cef_string_copy( const src: PCefChar; src_len: NativeUInt ; output: PCefString) : Integer ;
2018-05-24 19:15:41 +02:00
{$IFDEF MSWINDOWS}
2020-09-10 11:21:39 +02:00
procedure WindowInfoAsChild( var aWindowInfo : TCefWindowInfo; aParent : TCefWindowHandle; aRect : TRect; const aWindowName : ustring = '' ; aExStyle : DWORD = 0 ) ;
procedure WindowInfoAsPopUp( var aWindowInfo : TCefWindowInfo; aParent : TCefWindowHandle; const aWindowName : ustring = '' ; aExStyle : DWORD = 0 ) ;
procedure WindowInfoAsWindowless( var aWindowInfo : TCefWindowInfo; aParent : TCefWindowHandle; const aWindowName : ustring = '' ; aExStyle : DWORD = 0 ) ;
2018-05-24 19:15:41 +02:00
{$ENDIF}
2021-01-31 16:53:07 +01:00
{$IFDEF MACOSX}
2020-01-28 11:36:34 +01:00
procedure WindowInfoAsChild( var aWindowInfo : TCefWindowInfo; aParent : TCefWindowHandle; aRect : TRect; const aWindowName : ustring = '' ; aHidden : boolean = False ) ;
procedure WindowInfoAsPopUp( var aWindowInfo : TCefWindowInfo; aParent : TCefWindowHandle; const aWindowName : ustring = '' ; aHidden : boolean = False ) ;
procedure WindowInfoAsWindowless( var aWindowInfo : TCefWindowInfo; aParent : TCefWindowHandle; const aWindowName : ustring = '' ; aHidden : boolean = False ) ;
2018-05-24 19:15:41 +02:00
{$ENDIF}
{$IFDEF LINUX}
2019-03-15 17:17:14 +01:00
procedure WindowInfoAsChild( var aWindowInfo : TCefWindowInfo; aParent : TCefWindowHandle; aRect : TRect; const aWindowName : ustring = '' ) ;
procedure WindowInfoAsPopUp( var aWindowInfo : TCefWindowInfo; aParent : TCefWindowHandle; const aWindowName : ustring = '' ) ;
procedure WindowInfoAsWindowless( var aWindowInfo : TCefWindowInfo; aParent : TCefWindowHandle; const aWindowName : ustring = '' ) ;
2018-05-24 19:15:41 +02:00
{$ENDIF}
2018-04-18 10:25:38 +02:00
2018-06-03 17:18:54 +02:00
{$IFDEF MSWINDOWS}
2021-10-27 12:18:33 +02:00
function ProcessUnderWow64( hProcess: THandle; Wow64Process: PBOOL) : BOOL; stdcall ; external Kernel32DLL name 'IsWow64Process' ;
2018-04-18 10:25:38 +02:00
function PathIsRelativeAnsi( pszPath: LPCSTR) : BOOL; stdcall ; external SHLWAPIDLL name 'PathIsRelativeA' ;
function PathIsRelativeUnicode( pszPath: LPCWSTR) : BOOL; stdcall ; external SHLWAPIDLL name 'PathIsRelativeW' ;
2021-10-27 12:18:33 +02:00
function GetGlobalMemoryStatusEx( lpBuffer: LPMEMORYSTATUSEX) : BOOL; stdcall ; external Kernel32DLL name 'GlobalMemoryStatusEx' ;
2019-09-21 11:37:13 +02:00
function PathCanonicalizeAnsi( pszBuf: LPSTR; pszPath: LPCSTR) : BOOL; stdcall ; external SHLWAPIDLL name 'PathCanonicalizeA' ;
function PathCanonicalizeUnicode( pszBuf: LPWSTR; pszPath: LPCWSTR) : BOOL; stdcall ; external SHLWAPIDLL name 'PathCanonicalizeW' ;
2019-09-23 12:01:39 +02:00
function PathIsUNCAnsi( pszPath: LPCSTR) : BOOL; stdcall ; external SHLWAPIDLL name 'PathIsUNCA' ;
2019-09-23 11:42:20 +02:00
function PathIsUNCUnicode( pszPath: LPCWSTR) : BOOL; stdcall ; external SHLWAPIDLL name 'PathIsUNCW' ;
2019-09-23 12:01:39 +02:00
function PathIsURLAnsi( pszPath: LPCSTR) : BOOL; stdcall ; external SHLWAPIDLL name 'PathIsURLA' ;
2019-09-23 11:42:20 +02:00
function PathIsURLUnicode( pszPath: LPCWSTR) : BOOL; stdcall ; external SHLWAPIDLL name 'PathIsURLW' ;
2021-10-26 10:29:58 +02:00
function ShutdownBlockReasonCreate( hWnd: HWND; Reason: LPCWSTR) : Bool; stdcall ; external User32DLL;
function ShutdownBlockReasonDestroy( hWnd: HWND) : Bool; stdcall ; external User32DLL;
2023-04-15 14:59:17 +02:00
function NetServerGetInfo( servername: LPWSTR; level: DWORD; out bufptr: Pointer ) : DWORD; stdcall ; external Netapi32DLL;
function NetApiBufferFree( Buffer: Pointer ) : DWORD; stdcall ; external Netapi32DLL;
2018-04-18 10:25:38 +02:00
{$IFNDEF DELPHI12_UP}
2019-11-10 18:23:39 +01:00
const
2021-01-28 19:29:04 +01:00
GWLP_WNDPROC = GWL_WNDPROC;
2019-11-11 21:21:14 +01:00
GWLP_HWNDPARENT = GWL_HWNDPARENT;
2018-06-03 17:18:54 +02:00
{$IFDEF WIN64}
function SetWindowLongPtr( hWnd: HWND; nIndex: Integer ; dwNewLong: int64 ) : int64 ; stdcall ; external user32 name 'SetWindowLongPtrW' ;
{$ELSE}
function SetWindowLongPtr( hWnd: HWND; nIndex: Integer ; dwNewLong: LongInt ) : LongInt ; stdcall ; external user32 name 'SetWindowLongW' ;
{$ENDIF}
2018-04-18 10:25:38 +02:00
{$ENDIF}
2018-06-03 17:18:54 +02:00
2018-04-18 10:25:38 +02:00
{$ENDIF}
2023-11-16 16:58:47 +01:00
/// <summary>
/// Returns true if aPath is a relative path.
/// </summary>
/// <remarks>
/// <para><see href="https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathisrelativew">See the PathIsRelativeW article.</see></para>
/// </remarks>
2018-04-18 10:25:38 +02:00
function CustomPathIsRelative( const aPath : string ) : boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Simplifies a path by removing navigation elements such as "." and ".." to produce a direct, well-formed path.
/// </summary>
/// <remarks>
/// <para><see href="https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathcanonicalizew">See the PathCanonicalizeW article.</see></para>
/// </remarks>
2019-09-21 11:37:13 +02:00
function CustomPathCanonicalize( const aOriginalPath : string ; var aCanonicalPath : string ) : boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Returns the absolute path version of aPath.
/// </summary>
2019-09-21 11:37:13 +02:00
function CustomAbsolutePath( const aPath : string ; aMustExist : boolean = False ) : string ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Tests aPath to determine if it conforms to a valid URL format.
/// </summary>
/// <remarks>
/// <para><see href="https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathisurlw">See the PathIsURLW article.</see></para>
/// </remarks>
2019-09-23 11:42:20 +02:00
function CustomPathIsURL( const aPath : string ) : boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Determines if aPath is a valid Universal Naming Convention (UNC) path, as opposed to a path based on a drive letter.
/// </summary>
/// <remarks>
/// <para><see href="https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathisuncw">See the PathIsUNCW article.</see></para>
/// </remarks>
2019-09-23 11:42:20 +02:00
function CustomPathIsUNC( const aPath : string ) : boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Retrieves the fully qualified path for the current module.
/// </summary>
/// <remarks>
/// <para><see href="https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulefilenamew">See the GetModuleFileNameW article.</see></para>
/// </remarks>
2018-04-18 10:25:38 +02:00
function GetModulePath : string ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Returns true (1) if the certificate status represents an error.
/// </summary>
2018-04-18 10:25:38 +02:00
function CefIsCertStatusError( Status : TCefCertStatus) : boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Crash reporting is configured using an INI-style config file named
/// "crash_reporter.cfg". On Windows and Linux this file must be placed next to
/// the main application executable. On macOS this file must be placed in the
/// top-level app bundle Resources directory (e.g.
/// "<appname>.app/Contents/Resources"). File contents are as follows:
///
/// <pre>
/// # Comments start with a hash character and must be on their own line.
///
/// [Config]
/// ProductName=<Value of the "prod" crash key; defaults to "cef">
/// ProductVersion=<Value of the "ver" crash key; defaults to the CEF version>
/// AppName=<Windows only; App-specific folder name component for storing crash
/// information; default to "CEF">
/// ExternalHandler=<Windows only; Name of the external handler exe to use
/// instead of re-launching the main exe; default to empty>
/// BrowserCrashForwardingEnabled=<macOS only; True if browser process crashes
/// should be forwarded to the system crash
/// reporter; default to false>
/// ServerURL=<crash server URL; default to empty>
/// RateLimitEnabled=<True if uploads should be rate limited; default to true>
/// MaxUploadsPerDay=<Max uploads per 24 hours, used if rate limit is enabled;
/// default to 5>
/// MaxDatabaseSizeInMb=<Total crash report disk usage greater than this value
/// will cause older reports to be deleted; default to 20>
/// MaxDatabaseAgeInDays=<Crash reports older than this value will be deleted;
/// default to 5>
///
/// [CrashKeys]
/// my_key1=<small|medium|large>
/// my_key2=<small|medium|large>
/// </pre>
///
/// <b>Config section:</b>
///
/// If "ProductName" and/or "ProductVersion" are set then the specified values
/// will be included in the crash dump metadata. On macOS if these values are
/// set to NULL then they will be retrieved from the Info.plist file using the
/// "CFBundleName" and "CFBundleShortVersionString" keys respectively.
///
/// If "AppName" is set on Windows then crash report information (metrics,
/// database and dumps) will be stored locally on disk under the
/// "C:\Users\[CurrentUser]\AppData\Local\[AppName]\User Data" folder. On other
/// platforms the cef_settings_t.root_cache_path value will be used.
///
/// If "ExternalHandler" is set on Windows then the specified exe will be
/// launched as the crashpad-handler instead of re-launching the main process
/// exe. The value can be an absolute path or a path relative to the main exe
/// directory. On Linux the cef_settings_t.browser_subprocess_path value will be
/// used. On macOS the existing subprocess app bundle will be used.
///
/// If "BrowserCrashForwardingEnabled" is set to true (1) on macOS then browser
/// process crashes will be forwarded to the system crash reporter. This results
/// in the crash UI dialog being displayed to the user and crash reports being
/// logged under "~/Library/Logs/DiagnosticReports". Forwarding of crash reports
/// from non-browser processes and Debug builds is always disabled.
///
/// If "ServerURL" is set then crashes will be uploaded as a multi-part POST
/// request to the specified URL. Otherwise, reports will only be stored locally
/// on disk.
///
/// If "RateLimitEnabled" is set to true (1) then crash report uploads will be
/// rate limited as follows:
/// 1. If "MaxUploadsPerDay" is set to a positive value then at most the
/// specified number of crashes will be uploaded in each 24 hour period.
/// 2. If crash upload fails due to a network or server error then an
/// incremental backoff delay up to a maximum of 24 hours will be applied
/// for retries.
/// 3. If a backoff delay is applied and "MaxUploadsPerDay" is > 1 then the
/// "MaxUploadsPerDay" value will be reduced to 1 until the client is
/// restarted. This helps to avoid an upload flood when the network or
/// server error is resolved.
/// Rate limiting is not supported on Linux.
///
/// If "MaxDatabaseSizeInMb" is set to a positive value then crash report
/// storage on disk will be limited to that size in megabytes. For example, on
/// Windows each dump is about 600KB so a "MaxDatabaseSizeInMb" value of 20
/// equates to about 34 crash reports stored on disk. Not supported on Linux.
///
/// If "MaxDatabaseAgeInDays" is set to a positive value then crash reports
/// older than the specified age in days will be deleted. Not supported on
/// Linux.
///
/// <b>CrashKeys section:</b>
///
/// A maximum of 26 crash keys of each size can be specified for use by the
/// application. Crash key values will be truncated based on the specified size
/// (small = 64 bytes, medium = 256 bytes, large = 1024 bytes). The value of
/// crash keys can be set from any thread or process using the
/// CefSetCrashKeyValue function. These key/value pairs will be sent to the
/// crash server along with the crash dump file.
/// </summary>
2018-04-18 10:25:38 +02:00
function CefCrashReportingEnabled : boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Sets or clears a specific key-value pair from the crash metadata.
/// </summary>
2018-04-18 10:25:38 +02:00
procedure CefSetCrashKeyValue( const aKey, aValue : ustring) ;
2023-07-30 18:47:35 +02:00
/// <summary>
/// Add a log message. See the LogSeverity defines for supported |severity|
/// values.
/// </summary>
2023-11-16 16:58:47 +01:00
/// <remarks>
/// <para><see href="https://bitbucket.org/chromiumembedded/cef/src/master/include/base/cef_logging.h">CEF source file: /include/base/cef_logging.h (cef_log)</see></para>
/// <para><see href="https://bitbucket.org/chromiumembedded/cef/src/master/include/base/cef_logging.h">CEF source file: /include/base/cef_logging.h (LogSeverity)</see></para>
/// </remarks>
2018-04-18 10:25:38 +02:00
procedure CefLog( const aFile : string ; aLine, aSeverity : integer ; const aMessage : string ) ;
2018-10-12 12:21:43 +02:00
procedure CefDebugLog( const aMessage : string ; aSeverity : integer = CEF_LOG_SEVERITY_ERROR) ;
2020-04-23 11:11:53 +02:00
procedure CefKeyEventLog( const aEvent : TCefKeyEvent) ;
procedure CefMouseEventLog( const aEvent : TCefMouseEvent) ;
2018-04-18 10:25:38 +02:00
procedure OutputDebugMessage( const aMessage : string ) ;
function CustomExceptionHandler( const aFunctionName : string ; const aException : exception) : boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Gets the current log verbose level (LogSeverity).
/// </summary>
/// <remarks>
/// <para><see href="https://bitbucket.org/chromiumembedded/cef/src/master/include/base/cef_logging.h">CEF source file: /include/base/cef_logging.h (cef_get_min_log_level)</see></para>
/// <para><see href="https://bitbucket.org/chromiumembedded/cef/src/master/include/base/cef_logging.h">CEF source file: /include/base/cef_logging.h (LogSeverity)</see></para>
/// </remarks>
function CefGetMinLogLevel: integer ;
/// <summary>
/// Gets the current vlog level for the given file.
/// </summary>
/// <remarks>
/// <para><see href="https://bitbucket.org/chromiumembedded/cef/src/master/include/base/cef_logging.h">CEF source file: /include/base/cef_logging.h (cef_get_vlog_level)</see></para>
/// </remarks>
function CefGetVLogLevel( const file_start : string ) : integer ;
/// <summary>
/// Gets the log severity name.
/// </summary>
/// <remarks>
/// <para><see href="https://bitbucket.org/chromiumembedded/cef/src/master/include/base/cef_logging.h">CEF source file: /include/base/cef_logging.h (LogSeverity)</see></para>
/// </remarks>
function CefGetLogSeverityName( aSeverity: integer ) : ustring;
/// <summary>
/// Register a scheme handler factory with the global request context. An NULL
/// |DomainName| value for a standard scheme will cause the factory to match
/// all domain names. The |DomainName| value will be ignored for non-standard
/// schemes. If |SchemeName| is a built-in scheme and no handler is returned by
/// |factory| then the built-in scheme handler factory will be called. If
/// |SchemeName| is a custom scheme then you must also implement the
/// ICefApp.OnRegisterCustomSchemes function in all processes. This
/// function may be called multiple times to change or remove the factory that
/// matches the specified |SchemeName| and optional |DomainName|. Returns
/// false (0) if an error occurs. This function may be called on any thread in
/// the browser process. Using this function is equivalent to calling cef_reques
/// t_context_t::cef_request_context_get_global_context()->register_scheme_handl
/// er_factory().
/// </summary>
2018-06-11 18:38:51 +02:00
function CefRegisterSchemeHandlerFactory( const SchemeName, DomainName : ustring; const handler: TCefResourceHandlerClass = nil ) : Boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Clear all scheme handler factories registered with the global request
/// context. Returns false (0) on error. This function may be called on any
/// thread in the browser process. Using this function is equivalent to calling
/// cef_request_context_t::cef_request_context_get_global_context()->clear_schem
/// e_handler_factories().
/// </summary>
2018-04-18 10:25:38 +02:00
function CefClearSchemeHandlerFactories : boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// <para>Add an entry to the cross-origin access whitelist.</para>
/// <para>The same-origin policy restricts how scripts hosted from different origins
/// (scheme + domain + port) can communicate. By default, scripts can only
/// access resources with the same origin. Scripts hosted on the HTTP and HTTPS
/// schemes (but no other schemes) can use the "Access-Control-Allow-Origin"
/// header to allow cross-origin requests. For example,
/// https://source.example.com can make XMLHttpRequest requests on
/// http://target.example.com if the http://target.example.com request returns
/// an "Access-Control-Allow-Origin: https://source.example.com" response
/// header.</para>
/// <para>Scripts in separate frames or iframes and hosted from the same protocol and
/// domain suffix can execute cross-origin JavaScript if both pages set the
/// document.domain value to the same domain suffix. For example,
/// scheme://foo.example.com and scheme://bar.example.com can communicate using
/// JavaScript if both domains set document.domain="example.com".</para>
/// <para>This function is used to allow access to origins that would otherwise
/// violate the same-origin policy. Scripts hosted underneath the fully
/// qualified |source_origin| URL (like http://www.example.com) will be allowed
/// access to all resources hosted on the specified |target_protocol| and
/// |target_domain|. If |target_domain| is non-NULL and
/// |allow_target_subdomains| is false (0) only exact domain matches will be
/// allowed. If |target_domain| contains a top- level domain component (like
/// "example.com") and |allow_target_subdomains| is true (1) sub-domain matches
/// will be allowed. If |target_domain| is NULL and |allow_target_subdomains| if
/// true (1) all domains and IP addresses will be allowed.</para>
/// <para>This function cannot be used to bypass the restrictions on local or display
/// isolated schemes. See the comments on CefRegisterCustomScheme for more
/// information.</para>
/// <para>This function may be called on any thread. Returns false (0) if
/// |source_origin| is invalid or the whitelist cannot be accessed.</para>
/// </summary>
2018-04-18 10:25:38 +02:00
function CefAddCrossOriginWhitelistEntry( const SourceOrigin, TargetProtocol, TargetDomain: ustring; AllowTargetSubdomains: Boolean ) : Boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Remove an entry from the cross-origin access whitelist. Returns false (0) if
/// |source_origin| is invalid or the whitelist cannot be accessed.
/// </summary>
2018-04-18 10:25:38 +02:00
function CefRemoveCrossOriginWhitelistEntry( const SourceOrigin, TargetProtocol, TargetDomain: ustring; AllowTargetSubdomains: Boolean ) : Boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Remove all entries from the cross-origin access whitelist. Returns false (0)
/// if the whitelist cannot be accessed.
/// </summary>
2018-04-18 10:25:38 +02:00
function CefClearCrossOriginWhitelist: Boolean ;
procedure UInt64ToFileVersionInfo( const aVersion : uint64 ; var aVersionInfo : TFileVersionInfo) ;
2019-01-08 19:15:25 +01:00
{$IFDEF MSWINDOWS}
2020-06-13 17:24:22 +02:00
function GetExtendedFileVersion( const aFileName : ustring) : uint64 ;
function GetDLLVersion( const aDLLFile : ustring; var aVersionInfo : TFileVersionInfo) : boolean ;
procedure OutputLastErrorMessage;
2023-06-07 13:05:04 +02:00
function GetRegistryWindowsVersion( var aMajor, aMinor: cardinal ) : boolean ;
2023-04-15 14:59:17 +02:00
function GetRealWindowsVersion( var aMajor, aMinor: cardinal ) : boolean ;
function CheckRealWindowsVersion( aMajor, aMinor: cardinal ) : boolean ;
2019-01-08 19:15:25 +01:00
{$ENDIF}
2018-04-18 10:25:38 +02:00
function SplitLongString( aSrcString : string ) : string ;
function GetAbsoluteDirPath( const aSrcPath : string ; var aRsltPath : string ) : boolean ;
2018-10-12 12:21:43 +02:00
function CheckSubprocessPath( const aSubprocessPath : string ; var aMissingFiles : string ) : boolean ;
2018-04-18 10:25:38 +02:00
function CheckLocales( const aLocalesDirPath : string ; var aMissingFiles : string ; const aLocalesRequired : string = '' ) : boolean ;
2021-04-18 19:36:20 +02:00
function CheckResources( const aResourcesDirPath : string ; var aMissingFiles : string ) : boolean ;
2018-04-18 10:25:38 +02:00
function CheckDLLs( const aFrameworkDirPath : string ; var aMissingFiles : string ) : boolean ;
2019-01-08 19:15:25 +01:00
{$IFDEF MSWINDOWS}
2020-06-13 17:24:22 +02:00
function CheckDLLVersion( const aDLLFile : ustring; aMajor, aMinor, aRelease, aBuild : uint16 ) : boolean ;
function GetDLLHeaderMachine( const aDLLFile : ustring; var aMachine : integer ) : boolean ;
2019-01-08 19:15:25 +01:00
{$ENDIF}
2021-12-23 19:10:47 +01:00
function GetFileTypeDescription( const aExtension : ustring) : ustring;
2018-04-18 10:25:38 +02:00
function FileVersionInfoToString( const aVersionInfo : TFileVersionInfo) : string ;
function CheckFilesExist( var aList : TStringList; var aMissingFiles : string ) : boolean ;
2018-09-02 13:11:43 +02:00
function Is32BitProcess : boolean ;
2018-04-18 10:25:38 +02:00
2023-11-16 16:58:47 +01:00
/// <summary>
/// Combines specified |base_url| and |relative_url| into a ustring.
/// </summary>
2022-12-16 11:29:15 +01:00
function CefResolveUrl( const base_url, relative_url: ustring) : ustring;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Parse the specified |url| into its component parts. Returns false (0) if the
/// URL is invalid.
/// </summary>
2018-04-18 10:25:38 +02:00
function CefParseUrl( const url: ustring; var parts: TUrlParts) : Boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Creates a URL from the specified |parts|, which must contain a non-NULL spec
/// or a non-NULL host and path (at a minimum), but not both.
/// </summary>
2018-04-18 10:25:38 +02:00
function CefCreateUrl( var parts: TUrlParts) : ustring;
2023-11-16 16:58:47 +01:00
/// <summary>
/// This is a convenience function for formatting a URL in a concise and human-
/// friendly way to help users make security-related decisions (or in other
/// circumstances when people need to distinguish sites, origins, or otherwise-
/// simplified URLs from each other). Internationalized domain names (IDN) may
/// be presented in Unicode if the conversion is considered safe. The returned
/// value will (a) omit the path for standard schemes, excepting file and
/// filesystem, and (b) omit the port if it is the default for the scheme. Do
/// not use this for URLs which will be parsed or sent to other applications.
/// </summary>
2018-04-18 10:25:38 +02:00
function CefFormatUrlForSecurityDisplay( const originUrl: string ) : string ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Returns the mime type for the specified file extension or an NULL string if
/// unknown.
/// </summary>
2018-04-18 10:25:38 +02:00
function CefGetMimeType( const extension: ustring) : ustring;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Get the extensions associated with the given mime type. This should be
/// passed in lower case. There could be multiple extensions for a given mime
/// type, like "html,htm" for "text/html", or "txt,text,html,..." for "text/*".
/// Any existing elements in the provided vector will not be erased.
/// </summary>
2018-04-18 10:25:38 +02:00
procedure CefGetExtensionsForMimeType( const mimeType: ustring; var extensions: TStringList) ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Encodes |data| as a base64 string.
/// </summary>
2018-04-18 10:25:38 +02:00
function CefBase64Encode( const data: Pointer ; dataSize: NativeUInt ) : ustring;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Decodes the base64 encoded string |data|. The returned value will be NULL if
/// the decoding fails.
/// </summary>
2018-04-18 10:25:38 +02:00
function CefBase64Decode( const data: ustring) : ICefBinaryValue;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Escapes characters in |text| which are unsuitable for use as a query
/// parameter value. Everything except alphanumerics and -_.!~*'() will be
/// converted to "%XX". If |use_plus| is true (1) spaces will change to "+". The
/// result is basically the same as encodeURIComponent in Javacript.
/// </summary>
2018-04-18 10:25:38 +02:00
function CefUriEncode( const text : ustring; usePlus: Boolean ) : ustring;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Unescapes |text| and returns the result. Unescaping consists of looking for
/// the exact pattern "%XX" where each X is a hex digit and converting to the
/// character with the numerical value of those digits (e.g. "i%20=%203%3b"
/// unescapes to "i = 3;"). If |convert_to_utf8| is true (1) this function will
/// attempt to interpret the initial decoded result as UTF-8. If the result is
/// convertable into UTF-8 it will be returned as converted. Otherwise the
/// initial decoded result will be returned. The |unescape_rule| parameter
/// supports further customization the decoding process.
/// </summary>
2018-04-18 10:25:38 +02:00
function CefUriDecode( const text : ustring; convertToUtf8: Boolean ; unescapeRule: TCefUriUnescapeRule) : ustring;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Retrieve the path associated with the specified |aPathKey|.
/// Can be called on any thread in the browser process.
/// </summary>
2019-11-24 18:19:49 +01:00
function CefGetPath( const aPathKey : TCefPathKey) : ustring;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Returns true (1) if the application text direction is right-to-left.
/// </summary>
2021-09-27 12:04:33 +02:00
function CefIsRTL : boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Creates a directory and all parent directories if they don't already exist.
/// Returns true (1) on successful creation or if the directory already exists.
/// The directory is only readable by the current user. Calling this function on
/// the browser process UI or IO threads is not allowed.
/// </summary>
2018-04-18 10:25:38 +02:00
function CefCreateDirectory( const fullPath: ustring) : Boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Get the temporary directory provided by the system.
/// WARNING: In general, you should use the temp directory variants below
/// instead of this function. Those variants will ensure that the proper
/// permissions are set so that other users on the system can't edit them while
/// they're open (which could lead to security issues).
/// </summary>
2018-04-18 10:25:38 +02:00
function CefGetTempDirectory( out tempDir: ustring) : Boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Creates a new directory. On Windows if |prefix| is provided the new
/// directory name is in the format of "prefixyyyy". Returns true (1) on success
/// and sets |newTempPath| to the full path of the directory that was created.
/// The directory is only readable by the current user. Calling this function on
/// the browser process UI or IO threads is not allowed.
/// </summary>
2018-04-18 10:25:38 +02:00
function CefCreateNewTempDirectory( const prefix: ustring; out newTempPath: ustring) : Boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Creates a directory within another directory. Extra characters will be
/// appended to |prefix| to ensure that the new directory does not have the same
/// name as an existing directory. Returns true (1) on success and sets
/// |newDir| to the full path of the directory that was created. The directory
/// is only readable by the current user. Calling this function on the browser
/// process UI or IO threads is not allowed.
/// </summary>
2018-04-18 10:25:38 +02:00
function CefCreateTempDirectoryInDirectory( const baseDir, prefix: ustring; out newDir: ustring) : Boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Returns true (1) if the given path exists and is a directory. Calling this
/// function on the browser process UI or IO threads is not allowed.
/// </summary>
2018-04-18 10:25:38 +02:00
function CefDirectoryExists( const path: ustring) : Boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Deletes the given path whether it's a file or a directory. If |path| is a
/// directory all contents will be deleted. If |recursive| is true (1) any sub-
/// directories and their contents will also be deleted (equivalent to executing
/// "rm -rf", so use with caution). On POSIX environments if |path| is a
/// symbolic link then only the symlink will be deleted. Returns true (1) on
/// successful deletion or if |path| does not exist. Calling this function on
/// the browser process UI or IO threads is not allowed.
/// </summary>
2018-04-18 10:25:38 +02:00
function CefDeleteFile( const path: ustring; recursive: Boolean ) : Boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Writes the contents of |srcDir| into a zip archive at |destFile|. If
/// |includeHiddenFiles| is true (1) files starting with "." will be included.
/// Returns true (1) on success. Calling this function on the browser process
/// UI or IO threads is not allowed.
/// </summary>
2018-04-18 10:25:38 +02:00
function CefZipDirectory( const srcDir, destFile: ustring; includeHiddenFiles: Boolean ) : Boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Loads the existing "Certificate Revocation Lists" file that is managed by
/// Google Chrome. This file can generally be found in Chrome's User Data
/// directory (e.g. "C:\Users\[User]\AppData\Local\Google\Chrome\User Data\" on
/// Windows) and is updated periodically by Chrome's component updater service.
/// Must be called in the browser process after the context has been
/// initialized. See https://dev.chromium.org/Home/chromium-security/crlsets for
/// background.
/// </summary>
2018-04-18 10:25:38 +02:00
procedure CefLoadCRLSetsFile( const path : ustring) ;
2019-01-08 19:15:25 +01:00
{$IFDEF MSWINDOWS}
2020-04-10 09:49:34 +02:00
function CefIsKeyDown( aWparam : WPARAM) : boolean ;
function CefIsKeyToggled( aWparam : WPARAM) : boolean ;
function GetCefMouseModifiers : TCefEventFlags; overload ;
function GetCefMouseModifiers( awparam : WPARAM) : TCefEventFlags; overload ;
function GetCefKeyboardModifiers( aWparam : WPARAM; aLparam : LPARAM) : TCefEventFlags;
procedure CefCheckAltGrPressed( aWparam : WPARAM; var aEvent : TCefKeyEvent) ;
2018-04-18 10:25:38 +02:00
procedure DropEffectToDragOperation( aEffect : Longint ; var aAllowedOps : TCefDragOperations) ;
procedure DragOperationToDropEffect( const aDragOperations : TCefDragOperations; var aEffect: Longint ) ;
2020-01-13 15:39:44 +01:00
function GetWindowsMajorMinorVersion( var wMajorVersion, wMinorVersion : DWORD) : boolean ;
2020-10-31 14:23:06 +01:00
function RunningWindows10OrNewer : boolean ;
function GetDPIForHandle( aHandle : HWND; var aDPI : UINT) : boolean ;
2020-01-13 15:39:44 +01:00
function GetDefaultCEFUserAgent : string ;
2020-02-04 11:50:38 +01:00
{$IFDEF DELPHI14_UP}
2020-02-03 12:02:30 +01:00
function TouchPointToPoint( aHandle : HWND; const TouchPoint: TTouchInput) : TPoint;
2020-02-05 14:40:22 +01:00
function GetDigitizerStatus( var aDigitizerStatus : TDigitizerStatus; aDPI : cardinal = 0 ) : boolean ;
function HasTouchOrPen( aDPI : cardinal = 0 ) : boolean ;
2019-01-08 19:15:25 +01:00
{$ENDIF}
2020-02-03 16:14:31 +01:00
{$ENDIF}
2018-04-18 10:25:38 +02:00
function DeviceToLogical( aValue : integer ; const aDeviceScaleFactor : double ) : integer ; overload ;
2020-02-03 12:02:30 +01:00
function DeviceToLogical( aValue : single ; const aDeviceScaleFactor : double ) : single ; overload ;
2018-04-18 10:25:38 +02:00
procedure DeviceToLogical( var aEvent : TCEFMouseEvent; const aDeviceScaleFactor : double ) ; overload ;
2020-02-03 12:02:30 +01:00
procedure DeviceToLogical( var aEvent : TCefTouchEvent; const aDeviceScaleFactor : double ) ; overload ;
2018-04-18 10:25:38 +02:00
procedure DeviceToLogical( var aPoint : TPoint; const aDeviceScaleFactor : double ) ; overload ;
function LogicalToDevice( aValue : integer ; const aDeviceScaleFactor : double ) : integer ; overload ;
procedure LogicalToDevice( var aRect : TCEFRect; const aDeviceScaleFactor : double ) ; overload ;
function GetScreenDPI : integer ;
function GetDeviceScaleFactor : single ;
2019-06-19 16:53:26 +02:00
function DeleteDirContents( const aDirectory : string ; const aExcludeFiles : TStringList = nil ) : boolean ;
function DeleteFileList( const aFileList : TStringList) : boolean ;
function MoveFileList( const aFileList : TStringList; const aSrcDirectory, aDstDirectory : string ) : boolean ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Returns a URI with a DATA scheme using |aString| as the URI's data.
/// </summary>
2019-10-13 18:50:23 +02:00
function CefGetDataURI( const aString, aMimeType : ustring) : ustring; overload ;
2023-11-16 16:58:47 +01:00
/// <summary>
/// Returns a URI with a DATA scheme encoding |aData| as a base64 string.
/// </summary>
2019-10-13 18:50:23 +02:00
function CefGetDataURI( aData : pointer ; aSize : integer ; const aMimeType : ustring; const aCharset : ustring = '' ) : ustring; overload ;
2020-04-03 17:57:52 +02:00
function ValidCefWindowHandle( aHandle : TCefWindowHandle) : boolean ;
2020-05-05 18:10:33 +02:00
procedure InitializeWindowHandle( var aHandle : TCefWindowHandle) ;
2020-01-02 20:02:47 +01:00
2021-05-17 10:10:00 +02:00
function GetCommandLineSwitchValue( const aKey : string ; var aValue : ustring) : boolean ;
2021-05-16 19:42:25 +02:00
2018-04-18 10:25:38 +02:00
implementation
uses
2021-06-24 17:47:22 +02:00
{$IFDEF LINUX} {$IFDEF FMX} uCEFLinuxFunctions, Posix. Unistd, Posix. Stdio, {$ENDIF} {$ENDIF}
2022-01-15 13:04:21 +01:00
{$IFDEF MACOSX} {$IFDEF FPC} CocoaAll, {$ELSE} Posix. Unistd, Posix. Stdio, {$ENDIF} {$ENDIF}
2019-11-08 23:15:53 +01:00
uCEFApplicationCore, uCEFSchemeHandlerFactory, uCEFValue,
2018-04-18 10:25:38 +02:00
uCEFBinaryValue, uCEFStringList;
function CefColorGetA( color: TCefColor) : Byte ;
begin
Result : = ( color shr 2 4 ) and $FF ;
end ;
function CefColorGetR( color: TCefColor) : byte ;
begin
Result : = ( color shr 1 6 ) and $FF ;
end ;
function CefColorGetG( color: TCefColor) : Byte ;
begin
Result : = ( color shr 8 ) and $FF ;
end ;
function CefColorGetB( color: TCefColor) : Byte ;
begin
Result : = color and $FF ;
end ;
function CefColorSetARGB( a, r, g, b: Byte ) : TCefColor;
begin
Result : = ( a shl 2 4 ) or ( r shl 1 6 ) or ( g shl 8 ) or b;
end ;
function CefInt64Set( int32_low, int32_high: Integer ) : Int64 ;
begin
Result : = int32_low or ( int32_high shl 3 2 ) ;
end ;
function CefInt64GetLow( const int64_val: Int64 ) : Integer ;
begin
Result : = Integer( int64_val) ;
end ;
function CefInt64GetHigh( const int64_val: Int64 ) : Integer ;
begin
Result : = ( int64_val shr 3 2 ) and $FFFFFFFF ;
end ;
2019-11-24 18:19:49 +01:00
function CefStringClearAndGet( str: PCefString) : ustring;
2018-04-18 10:25:38 +02:00
begin
2019-11-24 18:19:49 +01:00
if ( str < > nil ) and ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
2018-06-11 09:01:38 +02:00
begin
2019-11-24 18:19:49 +01:00
Result : = CefString( str) ;
cef_string_utf16_clear( str) ;
2018-06-11 09:01:38 +02:00
end
else
Result : = '' ;
2018-04-18 10:25:38 +02:00
end ;
2021-05-16 19:42:25 +02:00
{$IFDEF CEF4DELHI_ALLOC_DEBUG}
function CefGetObject( ptr: Pointer ) : TObject;
var
TempPointer : pointer ;
begin
Result : = nil ;
if ( ptr < > nil ) then
begin
Dec( PByte( ptr) , SizeOf( Pointer ) ) ;
TempPointer : = ptr;
if ( PPointer( ptr) ^ < > nil ) then
begin
Dec( PByte( TempPointer) , SizeOf( Pointer ) * 2 ) ;
if ( PPointer( TempPointer) ^ = CEF4DELPHI_ALLOC_PADDING) then
Result : = TObject( PPointer( ptr) ^ )
else
CefDebugLog( 'Pointer to an unknown memory address!' , CEF_LOG_SEVERITY_INFO) ;
end
else
CefDebugLog( 'Object pointer is NIL!' , CEF_LOG_SEVERITY_INFO) ;
end ;
end ;
{$ELSE}
2018-04-18 10:25:38 +02:00
function CefGetObject( ptr: Pointer ) : TObject; {$IFDEF SUPPORTS_INLINE} inline ; {$ENDIF}
begin
if ( ptr < > nil ) then
begin
Dec( PByte( ptr) , SizeOf( Pointer ) ) ;
Result : = TObject( PPointer( ptr) ^ ) ;
end
else
Result : = nil ;
end ;
2021-05-16 19:42:25 +02:00
{$ENDIF}
2018-04-18 10:25:38 +02:00
function CefGetData( const i: ICefBaseRefCounted) : Pointer ; {$IFDEF SUPPORTS_INLINE} inline ; {$ENDIF}
begin
if ( i < > nil ) then
Result : = i. Wrap
else
Result : = nil ;
end ;
function CefString( const str: PCefString) : ustring;
begin
2020-07-14 15:50:23 +02:00
if ( str < > nil ) and ( str^ . str < > nil ) and ( str^ . length > 0 ) and ( str^ . length < nativeuint( high( integer ) ) ) then
2018-05-12 14:50:54 +02:00
SetString( Result , str^ . str, str^ . length )
2018-04-18 10:25:38 +02:00
else
Result : = '' ;
end ;
function CefString( const str: ustring) : TCefString;
begin
Result . str : = PChar16( PWideChar( str) ) ;
Result . length : = Length( str) ;
Result . dtor : = nil ;
end ;
procedure CefStringFree( const str: PCefString) ;
begin
2018-06-11 09:01:38 +02:00
if ( str < > nil ) and ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
cef_string_utf16_clear( str) ;
2018-04-18 10:25:38 +02:00
end ;
procedure CefStringSet( const str: PCefString; const value: ustring) ;
begin
2018-06-11 09:01:38 +02:00
if ( str < > nil ) and ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
2019-11-24 18:19:49 +01:00
cef_string_utf16_set( PWideChar( value) , Length( value) , str, Ord( True ) ) ;
end ;
procedure CefStringInitialize( const aCefString : PCefString) ; {$IFDEF SUPPORTS_INLINE} inline ; {$ENDIF}
begin
if ( aCefString < > nil ) then
begin
aCefString^ . str : = nil ;
aCefString^ . length : = 0 ;
aCefString^ . dtor : = nil ;
end ;
2018-04-18 10:25:38 +02:00
end ;
function CefStringFreeAndGet( const str: PCefStringUserFree) : ustring;
begin
2018-06-11 09:01:38 +02:00
if ( str < > nil ) and ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
2018-04-18 10:25:38 +02:00
begin
Result : = CefString( PCefString( str) ) ;
cef_string_userfree_utf16_free( str) ;
end
else
Result : = '' ;
end ;
function CefStringAlloc( const str: ustring) : TCefString;
begin
2019-11-24 18:19:49 +01:00
CefStringInitialize( @ Result ) ;
2018-06-11 09:01:38 +02:00
if ( str < > '' ) and ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
cef_string_wide_to_utf16( PWideChar( str) , Length( str) , @ Result ) ;
2018-04-18 10:25:38 +02:00
end ;
2020-06-21 21:27:55 +02:00
2018-04-18 10:25:38 +02:00
procedure _free_string( str: PChar16) ; stdcall ;
begin
if ( str < > nil ) then FreeMem( str) ;
end ;
function CefUserFreeString( const str: ustring) : PCefStringUserFree;
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
Result : = cef_string_userfree_utf16_alloc( ) ;
Result ^ . length : = Length( str) ;
GetMem( Result ^ . str, Result ^ . length * SizeOf( TCefChar) ) ;
Move( PCefChar( str) ^ , Result ^ . str^ , Result ^ . length * SizeOf( TCefChar) ) ;
Result ^ . dtor : = @ _free_string;
end
else
Result : = nil ;
2018-04-18 10:25:38 +02:00
end ;
function CefRegisterExtension( const name , code: ustring; const Handler: ICefv8Handler) : Boolean ;
var
2018-06-11 09:01:38 +02:00
TempName, TempCode : TCefString;
2018-04-18 10:25:38 +02:00
begin
2019-09-12 11:40:52 +02:00
if ( GlobalCEFApp < > nil ) and
2018-07-24 18:18:54 +02:00
GlobalCEFApp. LibLoaded and
2020-01-05 15:15:48 +01:00
( ( GlobalCEFApp. ProcessType = ptRenderer) or GlobalCEFApp. SingleProcess) and
2019-09-12 11:40:52 +02:00
( length( name ) > 0 ) and
( length( code) > 0 ) then
2018-06-11 09:01:38 +02:00
begin
TempName : = CefString( name ) ;
TempCode : = CefString( code) ;
Result : = cef_register_extension( @ TempName, @ TempCode, CefGetData( handler) ) < > 0 ;
end
else
Result : = False ;
2018-04-18 10:25:38 +02:00
end ;
2019-10-19 10:58:34 +02:00
function CefPostTask( aThreadId : TCefThreadId; const aTask : ICefTask) : boolean ;
2018-04-18 10:25:38 +02:00
begin
2019-10-19 10:58:34 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded and ( aTask < > nil ) then
Result : = cef_post_task( aThreadId, aTask. Wrap) < > 0
else
Result : = False ;
end ;
function CefPostDelayedTask( aThreadId : TCefThreadId; const aTask : ICefTask; aDelayMs : Int64 ) : boolean ;
begin
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded and ( aTask < > nil ) then
Result : = cef_post_delayed_task( aThreadId, aTask. Wrap, aDelayMs) < > 0
else
Result : = False ;
2018-04-18 10:25:38 +02:00
end ;
2019-10-19 10:58:34 +02:00
function CefCurrentlyOn( aThreadId : TCefThreadId) : boolean ;
2018-04-18 10:25:38 +02:00
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
2019-10-19 10:58:34 +02:00
Result : = cef_currently_on( aThreadId) < > 0
else
Result : = False ;
2018-04-18 10:25:38 +02:00
end ;
2020-12-18 16:51:02 +01:00
{$IFDEF MSWINDOWS}
2018-04-18 10:25:38 +02:00
function CefTimeToSystemTime( const dt: TCefTime) : TSystemTime;
begin
Result . wYear : = dt. year;
Result . wMonth : = dt. month;
Result . wDayOfWeek : = dt. day_of_week;
Result . wDay : = dt. day_of_month;
Result . wHour : = dt. hour;
Result . wMinute : = dt. minute;
Result . wSecond : = dt. second;
Result . wMilliseconds : = dt. millisecond;
end ;
function SystemTimeToCefTime( const dt: TSystemTime) : TCefTime;
begin
Result . year : = dt. wYear;
Result . month : = dt. wMonth;
Result . day_of_week : = dt. wDayOfWeek;
Result . day_of_month : = dt. wDay;
Result . hour : = dt. wHour;
Result . minute : = dt. wMinute;
Result . second : = dt. wSecond;
Result . millisecond : = dt. wMilliseconds;
2020-12-18 16:51:02 +01:00
end ;
{$ELSE}
{$IFDEF LINUX}
{$IFDEF FPC}
function CefTimeToSystemTime( const dt: TCefTime) : TSystemTime;
begin
Result . Year : = dt. year;
Result . Month : = dt. month;
Result . DayOfWeek : = dt. day_of_week;
Result . Day : = dt. day_of_month;
Result . Hour : = dt. hour;
Result . Minute : = dt. minute;
Result . Second : = dt. second;
Result . Millisecond : = dt. millisecond;
end ;
function SystemTimeToCefTime( const dt: TSystemTime) : TCefTime;
begin
2019-01-08 19:15:25 +01:00
Result . year : = dt. Year;
Result . month : = dt. Month;
Result . day_of_week : = dt. DayOfWeek;
Result . day_of_month : = dt. Day;
Result . hour : = dt. Hour;
Result . minute : = dt. Minute;
Result . second : = dt. Second;
Result . millisecond : = dt. Millisecond;
2018-04-18 10:25:38 +02:00
end ;
2020-12-18 16:51:02 +01:00
{$ENDIF}
{$ENDIF}
2020-01-28 11:36:34 +01:00
{$ENDIF}
2018-04-18 10:25:38 +02:00
2021-01-18 11:12:01 +01:00
function FixCefTime( const dt : TCefTime) : TCefTime;
2018-04-18 10:25:38 +02:00
var
2021-01-18 11:12:01 +01:00
DayTable : PDayTable;
2018-04-18 10:25:38 +02:00
begin
2021-01-18 11:12:01 +01:00
Result : = dt;
2018-10-25 12:50:01 +02:00
2021-01-18 11:12:01 +01:00
Result . year : = min( 9 9 9 9 , max( 1 , Result . year) ) ;
Result . month : = min( 1 2 , max( 1 , Result . month) ) ;
2021-01-18 11:48:23 +01:00
Result . hour : = min( 2 3 , max( 0 , Result . hour) ) ;
Result . minute : = min( 5 9 , max( 0 , Result . minute) ) ;
Result . second : = min( 5 9 , max( 0 , Result . second) ) ;
Result . millisecond : = min( 9 9 9 , max( 0 , Result . millisecond) ) ;
2021-01-18 11:12:01 +01:00
DayTable : = @ MonthDays[ IsLeapYear( Result . year) ] ;
Result . day_of_month : = min( DayTable^ [ Result . month] , max( 1 , Result . day_of_month) ) ;
end ;
function CefTimeToDateTime( const dt: TCefTime) : TDateTime;
var
TempFixedCefTime : TCefTime;
begin
TempFixedCefTime : = FixCefTime( dt) ;
Result : = EncodeDate( TempFixedCefTime. year, TempFixedCefTime. month, TempFixedCefTime. day_of_month) +
EncodeTime( TempFixedCefTime. hour, TempFixedCefTime. minute, TempFixedCefTime. second, TempFixedCefTime. millisecond) ;
2018-04-18 10:25:38 +02:00
end ;
function DateTimeToCefTime( dt: TDateTime) : TCefTime;
var
2019-01-08 19:15:25 +01:00
TempYear, TempMonth, TempDay, TempHour, TempMin, TempSec, TempMSec : Word ;
2018-04-18 10:25:38 +02:00
begin
2019-01-08 19:15:25 +01:00
DecodeDate( dt, TempYear, TempMonth, TempDay) ;
DecodeTime( dt, TempHour, TempMin, TempSec, TempMSec) ;
Result . year : = TempYear;
Result . month : = TempMonth;
Result . day_of_week : = DayOfWeek( dt) ;
2021-09-28 16:39:21 +02:00
Result . day_of_month : = TempDay;
2019-01-08 19:15:25 +01:00
Result . hour : = TempHour;
Result . minute : = TempMin;
Result . second : = TempSec;
Result . millisecond : = TempMSec;
2018-04-18 10:25:38 +02:00
end ;
2022-09-04 19:18:07 +02:00
function DateTimeToCefBaseTime( dt: TDateTime) : TCefBaseTime;
begin
Result : = CetTimeToCefBaseTime( DateTimeToCefTime( dt) ) ;
end ;
2022-06-14 11:27:45 +02:00
function CefTimeToDouble( const dt: TCefTime) : double ;
begin
Result : = 0 ;
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
cef_time_to_doublet( @ dt, Result ) ;
end ;
function DoubleToCefTime( const dt: double ) : TCefTime;
begin
FillChar( Result , SizeOf( TCefTime) , #0 ) ;
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
cef_time_from_doublet( dt, Result ) ;
end ;
function CefTimeToUnixTime( const dt: TCefTime) : int64 ;
begin
Result : = 0 ;
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
cef_time_to_timet( @ dt, Result ) ;
end ;
function UnixTimeToCefTime( const dt: int64 ) : TCefTime;
begin
FillChar( Result , SizeOf( TCefTime) , #0 ) ;
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
cef_time_from_timet( dt, Result ) ;
end ;
function CefTimeNow: TCefTime;
begin
FillChar( Result , SizeOf( TCefTime) , #0 ) ;
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
cef_time_now( Result ) ;
end ;
function DoubleTimeNow: double ;
var
TempTime : TCefTime;
begin
Result : = 0 ;
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
FillChar( TempTime, SizeOf( TCefTime) , #0 ) ;
if ( cef_time_now( TempTime) < > 0 ) then
cef_time_to_doublet( @ TempTime, Result ) ;
end ;
end ;
function CefTimeDelta( const cef_time1, cef_time2: TCefTime) : int64 ;
begin
Result : = 0 ;
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
cef_time_delta( @ cef_time1, @ cef_time2, Result ) ;
end ;
2022-09-04 19:18:07 +02:00
function CefBaseTimeNow: TCefBaseTime;
begin
Result : = 0 ;
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
Result : = cef_basetime_now( ) ;
end ;
function CetTimeToCefBaseTime( const ct: TCefTime) : TCefBaseTime;
var
TempResult : TCefBaseTime;
begin
Result : = 0 ;
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded and ( cef_time_to_basetime( @ ct, @ TempResult) < > 0 ) then
Result : = TempResult;
end ;
function CetTimeFromCefBaseTime( const cbt: TCefBaseTime) : TCefTime;
var
TempResult : TCefTime;
begin
FillChar( Result , SizeOf( TCefTime) , #0 ) ;
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded and ( cef_time_from_basetime( cbt, @ TempResult) < > 0 ) then
Result : = TempResult;
end ;
function CefBaseTimeToDateTime( const cbt: TCefBaseTime) : TDateTime;
var
TempResult : TCefTime;
begin
Result : = 0 ;
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded and ( cef_time_from_basetime( cbt, @ TempResult) < > 0 ) then
Result : = CefTimeToDateTime( TempResult) ;
end ;
2022-06-14 11:27:45 +02:00
function GetTimeIntervalMilliseconds( const from_: TCefTime) : integer ;
var
TempFrom : double ;
TempDelay : integer ;
begin
Result : = - 1 ;
TempFrom : = CefTimeToDouble( from_) ;
if ( TempFrom = 0 ) then exit;
TempDelay : = ceil( ( TempFrom - DoubleTimeNow) * 1 0 0 0 ) ;
Result : = max( 0 , TempDelay) ;
end ;
procedure InitializeCefTime( var aTime : TCefTime) ;
begin
aTime. year : = 0 ;
aTime. month : = 0 ;
aTime. day_of_week : = 0 ;
aTime. day_of_month : = 0 ;
aTime. hour : = 0 ;
aTime. minute : = 0 ;
aTime. second : = 0 ;
aTime. millisecond : = 0 ;
end ;
2018-04-18 10:25:38 +02:00
function cef_string_wide_copy( const src: PWideChar ; src_len: NativeUInt ; output: PCefStringWide) : Integer ;
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
Result : = cef_string_wide_set( src, src_len, output, ord( True ) )
else
Result : = 0 ;
2018-04-18 10:25:38 +02:00
end ;
function cef_string_utf8_copy( const src: PAnsiChar ; src_len: NativeUInt ; output: PCefStringUtf8) : Integer ;
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
Result : = cef_string_utf8_set( src, src_len, output, ord( True ) )
else
Result : = 0 ;
2018-04-18 10:25:38 +02:00
end ;
function cef_string_utf16_copy( const src: PChar16; src_len: NativeUInt ; output: PCefStringUtf16) : Integer ;
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
Result : = cef_string_utf16_set( src, src_len, output, ord( True ) )
else
Result : = 0 ;
2018-04-18 10:25:38 +02:00
end ;
function cef_string_copy( const src: PCefChar; src_len: NativeUInt ; output: PCefString) : Integer ;
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
Result : = cef_string_utf16_set( src, src_len, output, ord( True ) )
else
Result : = 0 ;
2018-04-18 10:25:38 +02:00
end ;
2018-05-24 19:15:41 +02:00
{$IFDEF MSWINDOWS}
2020-09-10 11:21:39 +02:00
procedure WindowInfoAsChild( var aWindowInfo : TCefWindowInfo; aParent : TCefWindowHandle; aRect : TRect; const aWindowName : ustring; aExStyle : DWORD) ;
2018-04-18 10:25:38 +02:00
begin
2018-10-26 10:32:10 +02:00
aWindowInfo. ex_style : = aExStyle;
2018-04-18 10:25:38 +02:00
aWindowInfo. window_name : = CefString( aWindowName) ;
aWindowInfo. style : = WS_CHILD or WS_VISIBLE or WS_CLIPCHILDREN or WS_CLIPSIBLINGS or WS_TABSTOP;
2021-10-22 19:19:57 +02:00
aWindowInfo. bounds. x : = aRect. left;
aWindowInfo. bounds. y : = aRect. top;
aWindowInfo. bounds. width : = aRect. right - aRect. left;
aWindowInfo. bounds. height : = aRect. bottom - aRect. top;
2018-04-18 10:25:38 +02:00
aWindowInfo. parent_window : = aParent;
aWindowInfo. menu : = 0 ;
aWindowInfo. windowless_rendering_enabled : = ord( False ) ;
2018-12-12 17:13:23 +01:00
aWindowInfo. shared_texture_enabled : = ord( False ) ;
aWindowInfo. external_begin_frame_enabled : = ord( False ) ;
2018-04-18 10:25:38 +02:00
aWindowInfo. window : = 0 ;
end ;
2020-09-10 11:21:39 +02:00
procedure WindowInfoAsPopUp( var aWindowInfo : TCefWindowInfo; aParent : TCefWindowHandle; const aWindowName : ustring; aExStyle : DWORD) ;
2018-04-18 10:25:38 +02:00
begin
2018-10-26 10:32:10 +02:00
aWindowInfo. ex_style : = aExStyle;
2018-04-18 10:25:38 +02:00
aWindowInfo. window_name : = CefString( aWindowName) ;
aWindowInfo. style : = WS_OVERLAPPEDWINDOW or WS_CLIPCHILDREN or WS_CLIPSIBLINGS or WS_VISIBLE;
2021-10-22 19:19:57 +02:00
aWindowInfo. bounds. x : = integer( CW_USEDEFAULT) ;
aWindowInfo. bounds. y : = integer( CW_USEDEFAULT) ;
aWindowInfo. bounds. width : = integer( CW_USEDEFAULT) ;
aWindowInfo. bounds. height : = integer( CW_USEDEFAULT) ;
2018-04-18 10:25:38 +02:00
aWindowInfo. parent_window : = aParent;
aWindowInfo. menu : = 0 ;
aWindowInfo. windowless_rendering_enabled : = ord( False ) ;
2018-12-12 17:13:23 +01:00
aWindowInfo. shared_texture_enabled : = ord( False ) ;
aWindowInfo. external_begin_frame_enabled : = ord( False ) ;
2018-04-18 10:25:38 +02:00
aWindowInfo. window : = 0 ;
end ;
2020-09-10 11:21:39 +02:00
procedure WindowInfoAsWindowless( var aWindowInfo : TCefWindowInfo; aParent : TCefWindowHandle; const aWindowName : ustring; aExStyle : DWORD) ;
2018-04-18 10:25:38 +02:00
begin
2018-10-26 10:32:10 +02:00
aWindowInfo. ex_style : = aExStyle;
2018-04-18 10:25:38 +02:00
aWindowInfo. window_name : = CefString( aWindowName) ;
aWindowInfo. style : = 0 ;
2021-10-22 19:19:57 +02:00
aWindowInfo. bounds. x : = 0 ;
aWindowInfo. bounds. y : = 0 ;
aWindowInfo. bounds. width : = 0 ;
aWindowInfo. bounds. height : = 0 ;
2018-04-18 10:25:38 +02:00
aWindowInfo. parent_window : = aParent;
aWindowInfo. menu : = 0 ;
aWindowInfo. windowless_rendering_enabled : = ord( True ) ;
2018-12-12 17:13:23 +01:00
aWindowInfo. shared_texture_enabled : = ord( False ) ;
aWindowInfo. external_begin_frame_enabled : = ord( False ) ;
2018-04-18 10:25:38 +02:00
aWindowInfo. window : = 0 ;
end ;
2018-05-24 19:15:41 +02:00
{$ENDIF}
2021-01-31 16:53:07 +01:00
{$IFDEF MACOSX}
2020-01-28 11:36:34 +01:00
procedure WindowInfoAsChild( var aWindowInfo : TCefWindowInfo; aParent : TCefWindowHandle; aRect : TRect; const aWindowName : ustring; aHidden : boolean ) ;
2018-05-24 19:15:41 +02:00
begin
aWindowInfo. window_name : = CefString( aWindowName) ;
2021-10-22 19:19:57 +02:00
aWindowInfo. bounds. x : = aRect. left;
aWindowInfo. bounds. y : = aRect. top;
aWindowInfo. bounds. width : = aRect. right - aRect. left;
aWindowInfo. bounds. height : = aRect. bottom - aRect. top;
2018-05-24 19:15:41 +02:00
aWindowInfo. hidden : = Ord( aHidden) ;
aWindowInfo. parent_view : = aParent;
aWindowInfo. windowless_rendering_enabled : = ord( False ) ;
2018-12-12 17:13:23 +01:00
aWindowInfo. shared_texture_enabled : = ord( False ) ;
aWindowInfo. external_begin_frame_enabled : = ord( False ) ;
2021-02-21 18:41:25 +01:00
{$IFDEF FPC}
2018-05-24 19:15:41 +02:00
aWindowInfo. view : = 0 ;
2021-02-21 18:41:25 +01:00
{$ELSE}
aWindowInfo. view : = nil ;
{$ENDIF}
2018-05-24 19:15:41 +02:00
end ;
2020-01-28 11:36:34 +01:00
procedure WindowInfoAsPopUp( var aWindowInfo : TCefWindowInfo; aParent : TCefWindowHandle; const aWindowName : ustring; aHidden : boolean ) ;
2018-05-24 19:15:41 +02:00
begin
aWindowInfo. window_name : = CefString( aWindowName) ;
2021-10-22 19:19:57 +02:00
aWindowInfo. bounds. x : = 0 ;
aWindowInfo. bounds. y : = 0 ;
aWindowInfo. bounds. width : = 0 ;
aWindowInfo. bounds. height : = 0 ;
2018-05-24 19:15:41 +02:00
aWindowInfo. hidden : = Ord( aHidden) ;
aWindowInfo. parent_view : = aParent;
aWindowInfo. windowless_rendering_enabled : = ord( False ) ;
2018-12-12 17:13:23 +01:00
aWindowInfo. shared_texture_enabled : = ord( False ) ;
aWindowInfo. external_begin_frame_enabled : = ord( False ) ;
2021-02-21 18:41:25 +01:00
{$IFDEF FPC}
2018-05-24 19:15:41 +02:00
aWindowInfo. view : = 0 ;
2021-02-21 18:41:25 +01:00
{$ELSE}
aWindowInfo. view : = nil ;
{$ENDIF}
2018-05-24 19:15:41 +02:00
end ;
2020-01-28 11:36:34 +01:00
procedure WindowInfoAsWindowless( var aWindowInfo : TCefWindowInfo; aParent : TCefWindowHandle; const aWindowName : ustring; aHidden : boolean ) ;
2018-05-24 19:15:41 +02:00
begin
aWindowInfo. window_name : = CefString( aWindowName) ;
2021-10-22 19:19:57 +02:00
aWindowInfo. bounds. x : = 0 ;
aWindowInfo. bounds. y : = 0 ;
aWindowInfo. bounds. width : = 0 ;
aWindowInfo. bounds. height : = 0 ;
2018-05-24 19:15:41 +02:00
aWindowInfo. hidden : = Ord( aHidden) ;
aWindowInfo. parent_view : = aParent;
aWindowInfo. windowless_rendering_enabled : = ord( True ) ;
2018-12-12 17:13:23 +01:00
aWindowInfo. shared_texture_enabled : = ord( False ) ;
aWindowInfo. external_begin_frame_enabled : = ord( False ) ;
2021-02-21 18:41:25 +01:00
{$IFDEF FPC}
2018-05-24 19:15:41 +02:00
aWindowInfo. view : = 0 ;
2021-02-21 18:41:25 +01:00
{$ELSE}
aWindowInfo. view : = nil ;
{$ENDIF}
2018-05-24 19:15:41 +02:00
end ;
{$ENDIF}
{$IFDEF LINUX}
2021-01-08 16:01:06 +01:00
procedure WindowInfoAsChild( var aWindowInfo : TCefWindowInfo; aParent : TCefWindowHandle; aRect : TRect; const aWindowName : ustring = '' ) ;
2021-01-06 12:18:14 +01:00
var
TempParent : TCefWindowHandle;
2018-05-24 19:15:41 +02:00
begin
2021-01-08 16:01:06 +01:00
TempParent : = aParent;
{$IFDEF FPC}
2022-06-25 16:41:34 +02:00
{$IFDEF LCLGTK2}
if ValidCefWindowHandle( aParent) and ( PGtkWidget( aParent) ^ . window < > nil ) then
TempParent : = gdk_window_xwindow( PGtkWidget( aParent) ^ . window) ;
{$ENDIF}
{$IFDEF LCLGTK3}
2023-01-22 09:15:40 +01:00
if ValidCefWindowHandle( aParent) then
TempParent : = gdk_x11_window_get_xid( TGtk3Container( aParent) . Widget^ . window) ;
2022-06-25 16:41:34 +02:00
{$ENDIF}
2021-01-08 16:01:06 +01:00
{$ENDIF}
2021-01-06 12:18:14 +01:00
2019-05-04 09:53:50 +02:00
aWindowInfo. window_name : = CefString( aWindowName) ;
2021-10-22 19:19:57 +02:00
aWindowInfo. bounds. x : = aRect. left;
aWindowInfo. bounds. y : = aRect. top;
aWindowInfo. bounds. width : = aRect. right - aRect. left;
aWindowInfo. bounds. height : = aRect. bottom - aRect. top;
2021-01-06 12:18:14 +01:00
aWindowInfo. parent_window : = TempParent;
2018-05-24 19:15:41 +02:00
aWindowInfo. windowless_rendering_enabled : = ord( False ) ;
2018-12-12 17:13:23 +01:00
aWindowInfo. shared_texture_enabled : = ord( False ) ;
aWindowInfo. external_begin_frame_enabled : = ord( False ) ;
2018-05-24 19:15:41 +02:00
aWindowInfo. window : = 0 ;
end ;
2021-01-06 12:18:14 +01:00
// WindowInfoAsPopUp only exists for Windows. The Linux version of cefclient
// calls WindowInfoAsChild with aParent set to NULL to create a popup window.
2019-03-15 17:17:14 +01:00
procedure WindowInfoAsPopUp( var aWindowInfo : TCefWindowInfo; aParent : TCefWindowHandle; const aWindowName : ustring = '' ) ;
2018-05-24 19:15:41 +02:00
begin
2019-05-04 09:53:50 +02:00
aWindowInfo. window_name : = CefString( aWindowName) ;
2021-10-22 19:19:57 +02:00
aWindowInfo. bounds. x : = 0 ;
aWindowInfo. bounds. y : = 0 ;
aWindowInfo. bounds. width : = 0 ;
aWindowInfo. bounds. height : = 0 ;
2021-01-06 12:18:14 +01:00
aWindowInfo. parent_window : = aParent;
2018-05-24 19:15:41 +02:00
aWindowInfo. windowless_rendering_enabled : = ord( False ) ;
2018-12-12 17:13:23 +01:00
aWindowInfo. shared_texture_enabled : = ord( False ) ;
aWindowInfo. external_begin_frame_enabled : = ord( False ) ;
2018-05-24 19:15:41 +02:00
aWindowInfo. window : = 0 ;
end ;
2019-03-15 17:17:14 +01:00
procedure WindowInfoAsWindowless( var aWindowInfo : TCefWindowInfo; aParent : TCefWindowHandle; const aWindowName : ustring = '' ) ;
2018-05-24 19:15:41 +02:00
begin
2019-05-04 09:53:50 +02:00
aWindowInfo. window_name : = CefString( aWindowName) ;
2021-10-22 19:19:57 +02:00
aWindowInfo. bounds. x : = 0 ;
aWindowInfo. bounds. y : = 0 ;
aWindowInfo. bounds. width : = 0 ;
aWindowInfo. bounds. height : = 0 ;
2018-05-24 19:15:41 +02:00
aWindowInfo. parent_window : = aParent;
2019-12-18 15:10:30 +01:00
aWindowInfo. windowless_rendering_enabled : = ord( True ) ;
2018-12-12 17:13:23 +01:00
aWindowInfo. shared_texture_enabled : = ord( False ) ;
aWindowInfo. external_begin_frame_enabled : = ord( False ) ;
2018-05-24 19:15:41 +02:00
aWindowInfo. window : = 0 ;
end ;
{$ENDIF}
2018-04-18 10:25:38 +02:00
function CefIsCertStatusError( Status : TCefCertStatus) : boolean ;
begin
2018-06-11 09:01:38 +02:00
Result : = ( GlobalCEFApp < > nil ) and
GlobalCEFApp. LibLoaded and
( cef_is_cert_status_error( Status) < > 0 ) ;
2018-04-18 10:25:38 +02:00
end ;
function CefCrashReportingEnabled : boolean ;
begin
2018-06-11 09:01:38 +02:00
Result : = ( GlobalCEFApp < > nil ) and
GlobalCEFApp. LibLoaded and
( cef_crash_reporting_enabled( ) < > 0 ) ;
2018-04-18 10:25:38 +02:00
end ;
procedure CefSetCrashKeyValue( const aKey, aValue : ustring) ;
var
TempKey, TempValue : TCefString;
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
TempKey : = CefString( aKey) ;
TempValue : = CefString( aValue) ;
cef_set_crash_key_value( @ TempKey, @ TempValue) ;
end ;
2018-04-18 10:25:38 +02:00
end ;
procedure CefLog( const aFile : string ; aLine, aSeverity : integer ; const aMessage : string ) ;
var
TempFile, TempMessage : AnsiString ;
begin
if ( length( aFile) > 0 ) and ( length( aMessage) > 0 ) then
begin
TempFile : = AnsiString( aFile) ;
TempMessage : = AnsiString( aMessage) ;
cef_log( @ TempFile[ 1 ] , aLine, aSeverity, @ TempMessage[ 1 ] ) ;
end ;
end ;
2023-11-16 16:58:47 +01:00
function CefGetMinLogLevel: integer ;
begin
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
Result : = cef_get_min_log_level( )
else
Result : = 0 ;
end ;
function CefGetVLogLevel( const file_start : string ) : integer ;
var
TempFile : AnsiString ;
begin
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded and ( length( file_start) > 0 ) then
begin
TempFile : = AnsiString( file_start + #0 ) ;
Result : = cef_get_vlog_level( @ TempFile[ 1 ] , length( file_start) + 1 ) ;
end
else
Result : = 0 ;
end ;
function CefGetLogSeverityName( aSeverity: integer ) : ustring;
begin
case aSeverity of
CEF_LOG_SEVERITY_VERBOSE : Result : = 'VERBOSE' ;
CEF_LOG_SEVERITY_INFO : Result : = 'INFO' ;
CEF_LOG_SEVERITY_WARNING : Result : = 'WARNING' ;
CEF_LOG_SEVERITY_ERROR : Result : = 'ERROR' ;
CEF_LOG_SEVERITY_FATAL : Result : = 'FATAL' ;
else Result : = 'UNKNOWN' ;
end ;
end ;
2018-10-12 12:21:43 +02:00
procedure CefDebugLog( const aMessage : string ; aSeverity : integer ) ;
2018-04-18 10:25:38 +02:00
const
DEFAULT_LINE = 1 ;
var
TempString : string ;
begin
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
2019-01-08 19:15:25 +01:00
{$IFDEF MSWINDOWS}
2020-01-28 11:36:34 +01:00
TempString : = 'PID: ' + IntToStr( GetCurrentProcessID) + ', TID: ' + IntToStr( GetCurrentThreadID) ;
2021-01-31 16:53:07 +01:00
{$ENDIF}
{$IFDEF LINUX}
{$IFDEF FPC}
TempString : = 'PID: ' + IntToStr( GetProcessID( ) ) + ', TID: ' + IntToStr( GetCurrentThreadID( ) ) ;
2020-01-28 11:36:34 +01:00
{$ELSE}
2021-01-31 16:53:07 +01:00
// TO-DO: Find the equivalent function to get the process ID in Delphi FMX for Linux
{$ENDIF}
{$ENDIF}
{$IFDEF MACOSX}
{$IFDEF FPC}
// TO-DO: Find the equivalent function to get the process ID in Lazarus/FPC for MacOS
{$ELSE}
TempString : = 'PID: ' + IntToStr( TNSProcessInfo. Wrap( TNSProcessInfo. OCClass. processInfo) . processIdentifier) +
', TID: ' + IntToStr( TThread. Current. ThreadID) ;
2020-01-28 11:36:34 +01:00
{$ENDIF}
2019-01-08 19:15:25 +01:00
{$ENDIF}
2018-04-18 10:25:38 +02:00
2018-03-29 20:02:04 +02:00
case GlobalCEFApp. ProcessType of
ptBrowser : TempString : = TempString + ', PT: Browser' ;
ptRenderer : TempString : = TempString + ', PT: Renderer' ;
ptZygote : TempString : = TempString + ', PT: Zygote' ;
ptGPU : TempString : = TempString + ', PT: GPU' ;
2020-04-25 16:47:16 +02:00
ptUtility : TempString : = TempString + ', PT: Utility' ;
ptOther : TempString : = TempString + ', PT: Other' ;
2018-03-29 20:02:04 +02:00
end ;
2018-10-12 12:21:43 +02:00
CefLog( 'CEF4Delphi' , DEFAULT_LINE, aSeverity, TempString + ' - ' + aMessage) ;
2018-03-29 20:02:04 +02:00
end ;
2018-04-18 10:25:38 +02:00
end ;
2020-04-23 11:11:53 +02:00
procedure CefKeyEventLog( const aEvent : TCefKeyEvent) ;
const
DEFAULT_LINE = 1 ;
var
TempString : string ;
begin
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
case aEvent. kind of
KEYEVENT_RAWKEYDOWN : TempString : = 'kind: KEYEVENT_RAWKEYDOWN' ;
KEYEVENT_KEYDOWN : TempString : = 'kind: KEYEVENT_KEYDOWN' ;
KEYEVENT_KEYUP : TempString : = 'kind: KEYEVENT_KEYUP' ;
KEYEVENT_CHAR : TempString : = 'kind: KEYEVENT_CHAR' ;
end ;
TempString : = TempString + ', modifiers: $' + inttohex( aEvent. modifiers, SizeOf( aEvent. modifiers) * 2 ) ;
TempString : = TempString + ', windows_key_code: $' + inttohex( aEvent. windows_key_code, SizeOf( aEvent. windows_key_code) * 2 ) ;
TempString : = TempString + ', native_key_code: $' + inttohex( aEvent. native_key_code, SizeOf( aEvent. native_key_code) * 2 ) ;
TempString : = TempString + ', is_system_key: ' + BoolToStr( ( aEvent. is_system_key < > 0 ) , true ) ;
TempString : = TempString + ', character: $' + inttohex( ord( aEvent. character) , SizeOf( aEvent. character) * 2 ) ;
TempString : = TempString + ', unmodified_character: $' + inttohex( ord( aEvent. unmodified_character) , SizeOf( aEvent. unmodified_character) * 2 ) ;
TempString : = TempString + ', focus_on_editable_field: ' + BoolToStr( ( aEvent. focus_on_editable_field < > 0 ) , true ) ; ;
CefLog( 'CEF4Delphi' , DEFAULT_LINE, CEF_LOG_SEVERITY_INFO, TempString) ;
end ;
end ;
procedure CefMouseEventLog( const aEvent : TCefMouseEvent) ;
const
DEFAULT_LINE = 1 ;
var
TempString : string ;
begin
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
TempString : = TempString + ', x: $' + inttohex( aEvent. x, SizeOf( aEvent. x) * 2 ) ;
TempString : = TempString + ', y: $' + inttohex( aEvent. y, SizeOf( aEvent. y) * 2 ) ;
TempString : = TempString + ', modifiers: $' + inttohex( aEvent. modifiers, SizeOf( aEvent. modifiers) * 2 ) ;
CefLog( 'CEF4Delphi' , DEFAULT_LINE, CEF_LOG_SEVERITY_INFO, TempString) ;
end ;
end ;
2018-04-18 10:25:38 +02:00
procedure OutputDebugMessage( const aMessage : string ) ;
const
DEFAULT_LINE = 1 ;
begin
{$IFDEF DEBUG}
2020-06-13 17:24:22 +02:00
{$IFDEF MSWINDOWS}
2021-01-19 19:14:25 +01:00
{$IFDEF FMX}
FMX. Types. Log. d( aMessage) ;
{$ELSE}
OutputDebugString( {$IFDEF DELPHI12_UP} PWideChar {$ELSE} PAnsiChar {$ENDIF} ( aMessage + chr( 0 ) ) ) ;
{$ENDIF}
2020-01-28 11:36:34 +01:00
{$ENDIF}
2018-04-18 10:25:38 +02:00
2021-05-18 16:40:37 +02:00
{$IFDEF LINUX}
{$IFDEF FPC}
2021-05-27 14:29:30 +02:00
// TO-DO: Find a way to write in the error console using Lazarus in Linux
2021-05-18 16:40:37 +02:00
{$ELSE}
2021-05-27 14:29:30 +02:00
FMX. Types. Log. d( aMessage) ;
2021-05-18 16:40:37 +02:00
{$ENDIF}
{$ENDIF}
{$IFDEF MACOSX}
{$IFDEF FPC}
2022-04-06 12:13:07 +02:00
// TO-DO: Find a way to write in the error console using Lazarus in MacOS
2021-05-18 16:40:37 +02:00
{$ELSE}
2021-05-27 14:29:30 +02:00
FMX. Types. Log. d( aMessage) ;
2021-05-18 16:40:37 +02:00
{$ENDIF}
{$ENDIF}
2018-04-18 10:25:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
CefLog( 'CEF4Delphi' , DEFAULT_LINE, CEF_LOG_SEVERITY_ERROR, aMessage) ;
{$ENDIF}
end ;
function CustomExceptionHandler( const aFunctionName : string ; const aException : exception) : boolean ;
begin
OutputDebugMessage( aFunctionName + ' error : ' + aException. message ) ;
Result : = ( GlobalCEFApp < > nil ) and GlobalCEFApp. ReRaiseExceptions;
end ;
function CefRegisterSchemeHandlerFactory( const SchemeName : ustring;
2018-06-11 18:38:51 +02:00
const DomainName : ustring;
2018-04-18 10:25:38 +02:00
const handler : TCefResourceHandlerClass) : boolean ;
var
2018-06-11 18:38:51 +02:00
TempScheme, TempDomainName : TCefString;
2018-04-18 10:25:38 +02:00
TempFactory : ICefSchemeHandlerFactory;
2018-06-11 18:38:51 +02:00
TempDomainNamePtr : PCefString;
2018-04-18 10:25:38 +02:00
begin
2018-06-11 09:01:38 +02:00
Result : = False ;
try
2018-06-11 18:38:51 +02:00
if ( GlobalCEFApp < > nil ) and
GlobalCEFApp. LibLoaded and
( length( SchemeName) > 0 ) then
2018-06-11 09:01:38 +02:00
begin
2018-06-11 18:38:51 +02:00
if ( length( DomainName) > 0 ) then
begin
TempDomainName : = CefString( DomainName) ;
TempDomainNamePtr : = @ TempDomainName;
end
else
TempDomainNamePtr : = nil ;
TempScheme : = CefString( SchemeName) ;
TempFactory : = TCefSchemeHandlerFactoryOwn. Create( handler) ;
Result : = cef_register_scheme_handler_factory( @ TempScheme, TempDomainNamePtr, TempFactory. Wrap) < > 0 ;
2018-06-11 09:01:38 +02:00
end ;
finally
TempFactory : = nil ;
end ;
2018-04-18 10:25:38 +02:00
end ;
function CefClearSchemeHandlerFactories : boolean ;
begin
2018-06-11 09:01:38 +02:00
Result : = ( GlobalCEFApp < > nil ) and
GlobalCEFApp. LibLoaded and
( cef_clear_scheme_handler_factories( ) < > 0 ) ;
2018-04-18 10:25:38 +02:00
end ;
function CefAddCrossOriginWhitelistEntry( const SourceOrigin : ustring;
const TargetProtocol : ustring;
const TargetDomain : ustring;
AllowTargetSubdomains : Boolean ) : Boolean ;
var
TempSourceOrigin, TempTargetProtocol, TempTargetDomain : TCefString;
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
TempSourceOrigin : = CefString( SourceOrigin) ;
TempTargetProtocol : = CefString( TargetProtocol) ;
TempTargetDomain : = CefString( TargetDomain) ;
Result : = cef_add_cross_origin_whitelist_entry( @ TempSourceOrigin,
@ TempTargetProtocol,
@ TempTargetDomain,
Ord( AllowTargetSubdomains) ) < > 0 ;
end
else
Result : = False ;
2018-04-18 10:25:38 +02:00
end ;
function CefRemoveCrossOriginWhitelistEntry( const SourceOrigin : ustring;
const TargetProtocol : ustring;
const TargetDomain : ustring;
AllowTargetSubdomains : Boolean ) : Boolean ;
var
TempSourceOrigin, TempTargetProtocol, TempTargetDomain : TCefString;
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
TempSourceOrigin : = CefString( SourceOrigin) ;
TempTargetProtocol : = CefString( TargetProtocol) ;
TempTargetDomain : = CefString( TargetDomain) ;
Result : = cef_remove_cross_origin_whitelist_entry( @ TempSourceOrigin,
@ TempTargetProtocol,
@ TempTargetDomain,
Ord( AllowTargetSubdomains) ) < > 0 ;
end
else
Result : = False ;
2018-04-18 10:25:38 +02:00
end ;
function CefClearCrossOriginWhitelist: Boolean ;
begin
2018-05-12 14:50:54 +02:00
Result : = cef_clear_cross_origin_whitelist( ) < > 0 ;
2018-04-18 10:25:38 +02:00
end ;
function SplitLongString( aSrcString : string ) : string ;
const
MAXLINELENGTH = 5 0 ;
begin
2019-11-10 18:23:39 +01:00
Result : = '' ;
2018-04-18 10:25:38 +02:00
while ( length( aSrcString) > 0 ) do
begin
2019-11-10 18:23:39 +01:00
if ( Result < > '' ) then
2018-04-18 10:25:38 +02:00
Result : = Result + CRLF + copy( aSrcString, 1 , MAXLINELENGTH)
else
Result : = Result + copy( aSrcString, 1 , MAXLINELENGTH) ;
aSrcString : = copy( aSrcString, succ( MAXLINELENGTH) , length( aSrcString) ) ;
end ;
end ;
function GetAbsoluteDirPath( const aSrcPath : string ; var aRsltPath : string ) : boolean ;
begin
Result : = True ;
if ( length( aSrcPath) > 0 ) then
begin
2019-09-21 11:37:13 +02:00
aRsltPath : = IncludeTrailingPathDelimiter( CustomAbsolutePath( aSrcPath) ) ;
Result : = DirectoryExists( aRsltPath) ;
2018-04-18 10:25:38 +02:00
end
else
aRsltPath : = '' ;
end ;
function CheckLocales( const aLocalesDirPath : string ; var aMissingFiles : string ; const aLocalesRequired : string ) : boolean ;
const
LOCALES_REQUIRED_DEFAULT =
'am,' +
'ar,' +
'bg,' +
'bn,' +
'ca,' +
'cs,' +
'da,' +
'de,' +
'el,' +
'en-GB,' +
'en-US,' +
'es,' +
'es-419,' +
'et,' +
'fa,' +
'fi,' +
'fil,' +
'fr,' +
'gu,' +
'he,' +
'hi,' +
'hr,' +
'hu,' +
'id,' +
'it,' +
'ja,' +
'kn,' +
'ko,' +
'lt,' +
'lv,' +
'ml,' +
'mr,' +
'ms,' +
'nb,' +
'nl,' +
'pl,' +
'pt-BR,' +
'pt-PT,' +
'ro,' +
'ru,' +
'sk,' +
'sl,' +
'sr,' +
'sv,' +
'sw,' +
'ta,' +
'te,' +
'th,' +
'tr,' +
'uk,' +
'vi,' +
'zh-CN,' +
'zh-TW' ;
var
i : integer ;
TempDir : string ;
TempList : TStringList;
begin
Result : = False ;
TempList : = nil ;
try
try
if ( length( aLocalesDirPath) > 0 ) then
TempDir : = IncludeTrailingPathDelimiter( aLocalesDirPath)
else
2019-11-10 18:23:39 +01:00
TempDir : = 'locales' + PathDelim;
2018-04-18 10:25:38 +02:00
TempList : = TStringList. Create;
if ( length( aLocalesRequired) > 0 ) then
TempList. CommaText : = aLocalesRequired
else
TempList. CommaText : = LOCALES_REQUIRED_DEFAULT;
i : = 0 ;
2017-12-18 19:38:56 +01:00
while ( i < TempList. Count) do
begin
TempList[ i] : = TempDir + TempList[ i] + '.pak' ;
inc( i) ;
2018-04-18 10:25:38 +02:00
end ;
if DirectoryExists( TempDir) then
Result : = CheckFilesExist( TempList, aMissingFiles)
else
aMissingFiles : = trim( aMissingFiles) + CRLF + TempList. Text ;
except
on e : exception do
if CustomExceptionHandler( 'CheckLocales' , e) then raise ;
end ;
2017-12-18 19:38:56 +01:00
finally
if ( TempList < > nil ) then FreeAndNil( TempList) ;
2018-04-18 10:25:38 +02:00
end ;
end ;
2021-04-18 19:36:20 +02:00
function CheckResources( const aResourcesDirPath : string ; var aMissingFiles : string ) : boolean ;
2018-04-18 10:25:38 +02:00
var
TempDir : string ;
TempList : TStringList;
TempExists : boolean ;
begin
Result : = False ;
try
try
TempExists : = GetAbsoluteDirPath( aResourcesDirPath, TempDir) ;
TempList : = TStringList. Create;
TempList. Add( TempDir + 'snapshot_blob.bin' ) ;
TempList. Add( TempDir + 'v8_context_snapshot.bin' ) ;
2021-04-18 19:36:20 +02:00
TempList. Add( TempDir + 'resources.pak' ) ;
TempList. Add( TempDir + 'chrome_100_percent.pak' ) ;
TempList. Add( TempDir + 'chrome_200_percent.pak' ) ;
2018-04-18 10:25:38 +02:00
if TempExists then
Result : = CheckFilesExist( TempList, aMissingFiles)
else
aMissingFiles : = trim( aMissingFiles) + CRLF + TempList. Text ;
except
on e : exception do
if CustomExceptionHandler( 'CheckResources' , e) then raise ;
end ;
2017-12-18 19:38:56 +01:00
finally
if ( TempList < > nil ) then FreeAndNil( TempList) ;
2018-04-18 10:25:38 +02:00
end ;
end ;
2018-10-12 12:21:43 +02:00
function CheckSubprocessPath( const aSubprocessPath : string ; var aMissingFiles : string ) : boolean ;
begin
Result : = False ;
try
if ( length( aSubprocessPath) = 0 ) or FileExists( aSubprocessPath) then
Result : = True
else
aMissingFiles : = trim( aMissingFiles) + CRLF + ExtractFileName( aSubprocessPath) ;
except
on e : exception do
if CustomExceptionHandler( 'CheckSubprocessPath' , e) then raise ;
end ;
end ;
2018-04-18 10:25:38 +02:00
function CheckDLLs( const aFrameworkDirPath : string ; var aMissingFiles : string ) : boolean ;
var
TempDir : string ;
TempList : TStringList;
TempExists : boolean ;
begin
Result : = False ;
TempList : = nil ;
try
try
TempExists : = GetAbsoluteDirPath( aFrameworkDirPath, TempDir) ;
// The icudtl.dat file must be placed next to libcef.dll
// http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=14503#p32263
TempList : = TStringList. Create;
TempList. Add( TempDir + LIBCEF_DLL) ;
2019-11-10 18:23:39 +01:00
{$IFDEF MSWINDOWS}
2020-07-21 12:41:03 +02:00
TempList. Add( TempDir + CHROMEELF_DLL) ;
2018-04-18 10:25:38 +02:00
TempList. Add( TempDir + 'd3dcompiler_47.dll' ) ;
2021-10-02 16:22:10 +02:00
TempList. Add( TempDir + 'vk_swiftshader.dll' ) ;
TempList. Add( TempDir + 'vk_swiftshader_icd.json' ) ;
TempList. Add( TempDir + 'vulkan-1.dll' ) ;
2018-04-18 10:25:38 +02:00
TempList. Add( TempDir + 'libEGL.dll' ) ;
TempList. Add( TempDir + 'libGLESv2.dll' ) ;
2019-11-10 18:23:39 +01:00
{$ENDIF}
{$IFDEF LINUX}
TempList. Add( TempDir + 'libEGL.so' ) ;
TempList. Add( TempDir + 'libGLESv2.so' ) ;
2021-10-02 16:22:10 +02:00
TempList. Add( TempDir + 'libvk_swiftshader.so' ) ;
TempList. Add( TempDir + 'vk_swiftshader_icd.json' ) ;
TempList. Add( TempDir + 'libvulkan.so.1' ) ;
2019-11-10 18:23:39 +01:00
{$ENDIF}
2018-04-18 10:25:38 +02:00
TempList. Add( TempDir + 'icudtl.dat' ) ;
if TempExists then
Result : = CheckFilesExist( TempList, aMissingFiles)
else
aMissingFiles : = trim( aMissingFiles) + CRLF + TempList. Text ;
except
on e : exception do
if CustomExceptionHandler( 'CheckDLLs' , e) then raise ;
end ;
2017-12-18 19:38:56 +01:00
finally
if ( TempList < > nil ) then FreeAndNil( TempList) ;
2018-04-18 10:25:38 +02:00
end ;
end ;
function CheckFilesExist( var aList : TStringList; var aMissingFiles : string ) : boolean ;
var
i : integer ;
begin
2017-12-18 19:38:56 +01:00
Result : = True ;
try
if ( aList < > nil ) then
begin
i : = 0 ;
while ( i < aList. Count) do
begin
if ( length( aList[ i] ) > 0 ) and not( FileExists( aList[ i] ) ) then
begin
Result : = False ;
aMissingFiles : = aMissingFiles + aList[ i] + CRLF;
end ;
inc( i) ;
end ;
end ;
except
2018-04-18 10:25:38 +02:00
on e : exception do
if CustomExceptionHandler( 'CheckFilesExist' , e) then raise ;
2017-12-18 19:38:56 +01:00
end ;
2018-04-18 10:25:38 +02:00
end ;
procedure UInt64ToFileVersionInfo( const aVersion : uint64 ; var aVersionInfo : TFileVersionInfo) ;
begin
aVersionInfo. MajorVer : = uint16( aVersion shr 4 8 ) ;
aVersionInfo. MinorVer : = uint16( ( aVersion shr 3 2 ) and $FFFF ) ;
aVersionInfo. Release : = uint16( ( aVersion shr 1 6 ) and $FFFF ) ;
aVersionInfo. Build : = uint16( aVersion and $FFFF ) ;
end ;
2019-01-08 19:15:25 +01:00
{$IFDEF MSWINDOWS}
2020-06-13 17:24:22 +02:00
function GetExtendedFileVersion( const aFileName : ustring) : uint64 ;
2018-04-18 10:25:38 +02:00
var
TempSize : DWORD;
TempBuffer : pointer ;
TempLen : UINT;
TempHandle : cardinal ;
TempInfo : PVSFixedFileInfo;
begin
Result : = 0 ;
TempBuffer : = nil ;
2021-11-28 20:16:49 +01:00
TempHandle : = 0 ;
TempLen : = 0 ;
2018-04-18 10:25:38 +02:00
try
try
2020-06-13 17:24:22 +02:00
TempSize : = GetFileVersionInfoSizeW( PWideChar( aFileName) , TempHandle) ;
2018-04-18 10:25:38 +02:00
if ( TempSize > 0 ) then
begin
GetMem( TempBuffer, TempSize) ;
2020-06-13 17:24:22 +02:00
if GetFileVersionInfoW( PWideChar( aFileName) , TempHandle, TempSize, TempBuffer) and
2018-04-18 10:25:38 +02:00
VerQueryValue( TempBuffer, '\' , Pointer( TempInfo) , TempLen) then
begin
2018-05-12 14:50:54 +02:00
Result : = TempInfo^ . dwFileVersionMS;
2018-04-18 10:25:38 +02:00
Result : = Result shl 3 2 ;
2018-05-12 14:50:54 +02:00
Result : = Result or TempInfo^ . dwFileVersionLS;
2018-04-18 10:25:38 +02:00
end ;
2020-06-13 17:24:22 +02:00
end
else
OutputLastErrorMessage;
2018-04-18 10:25:38 +02:00
except
on e : exception do
if CustomExceptionHandler( 'GetExtendedFileVersion' , e) then raise ;
end ;
finally
if ( TempBuffer < > nil ) then FreeMem( TempBuffer) ;
end ;
end ;
2017-10-24 20:44:51 +02:00
2020-06-13 17:24:22 +02:00
procedure OutputLastErrorMessage;
begin
{$IFDEF DEBUG}
OutputDebugString( {$IFDEF DELPHI12_UP} PWideChar {$ELSE} PAnsiChar {$ENDIF} ( SysErrorMessage( GetLastError( ) ) + chr( 0 ) ) ) ;
{$ENDIF}
end ;
2023-06-07 13:05:04 +02:00
function GetRegistryWindowsVersion( var aMajor, aMinor: cardinal ) : boolean ;
const
SUBKEY = '\SOFTWARE\Microsoft\Windows NT\CurrentVersion' ;
var
TempRegKey : TRegistry;
TempBuild : integer ;
begin
Result : = False ;
aMajor : = 0 ;
aMinor : = 0 ;
TempRegKey : = nil ;
try
try
TempRegKey : = TRegistry. Create( KEY_READ) ;
TempRegKey. RootKey : = HKEY_LOCAL_MACHINE;
if TempRegKey. KeyExists( SUBKEY) and
TempRegKey. OpenKeyReadOnly( SUBKEY) then
try
if TempRegKey. ValueExists( 'CurrentMajorVersionNumber' ) and
TempRegKey. ValueExists( 'CurrentMinorVersionNumber' ) then
begin
aMajor : = TempRegKey. ReadInteger( 'CurrentMajorVersionNumber' ) ;
aMinor : = TempRegKey. ReadInteger( 'CurrentMinorVersionNumber' ) ;
Result : = True ;
end
else
if TempRegKey. ValueExists( 'CurrentBuildNumber' ) then
begin
TempBuild : = StrToIntDef( TempRegKey. ReadString( 'CurrentBuildNumber' ) , 0 ) ;
2023-06-09 15:13:45 +02:00
if ( TempBuild > = 2 2 0 0 0 ) then // Windows 11
2023-06-07 13:05:04 +02:00
begin
aMajor : = 1 0 ;
aMinor : = 0 ;
Result : = True ;
end
else
2023-06-09 15:13:45 +02:00
if ( TempBuild > = 1 0 2 4 0 ) then // Windows 10
2023-06-07 13:05:04 +02:00
begin
aMajor : = 1 0 ;
aMinor : = 0 ;
Result : = True ;
end
else
2023-06-09 15:13:45 +02:00
if ( TempBuild > = 9 6 0 0 ) then // Windows 8.1
2023-06-07 13:05:04 +02:00
begin
aMajor : = 6 ;
aMinor : = 3 ;
Result : = True ;
end
else
2023-06-09 15:13:45 +02:00
if ( TempBuild > = 9 2 0 0 ) then // Windows 8
2023-06-07 13:05:04 +02:00
begin
aMajor : = 6 ;
aMinor : = 2 ;
Result : = True ;
end
else
2023-06-09 15:13:45 +02:00
if ( TempBuild > = 7 6 0 0 ) then // Windows 7
2023-06-07 13:05:04 +02:00
begin
aMajor : = 6 ;
aMinor : = 1 ;
Result : = True ;
end
else
2023-06-09 15:13:45 +02:00
if ( TempBuild > = 6 0 0 0 ) then // Windows Vista
2023-06-07 13:05:04 +02:00
begin
aMajor : = 6 ;
aMinor : = 0 ;
Result : = True ;
end
else
2023-06-09 15:13:45 +02:00
if ( TempBuild > = 3 7 9 0 ) then // Windows Server 2003
2023-06-07 13:05:04 +02:00
begin
aMajor : = 5 ;
aMinor : = 2 ;
Result : = True ;
end
else
2023-06-09 15:13:45 +02:00
if ( TempBuild > = 2 6 0 0 ) then // Windows XP
2023-06-07 13:05:04 +02:00
begin
aMajor : = 5 ;
aMinor : = 1 ;
Result : = True ;
end
else
2023-06-09 15:13:45 +02:00
if ( TempBuild > = 2 1 9 5 ) then // Windows 2000
2023-06-07 13:05:04 +02:00
begin
aMajor : = 5 ;
aMinor : = 0 ;
Result : = True ;
end ;
end ;
finally
TempRegKey. CloseKey;
end ;
except
on e : exception do
if CustomExceptionHandler( 'GetRegistryWindowsVersion' , e) then raise ;
end ;
finally
if assigned( TempRegKey) then
FreeAndNil( TempRegKey) ;
end ;
end ;
2023-04-15 14:59:17 +02:00
function GetRealWindowsVersion( var aMajor, aMinor: cardinal ) : boolean ;
type
SERVER_INFO_101 = record
sv101_platform_id : DWORD;
sv101_name : LPWSTR;
sv101_version_major : DWORD;
sv101_version_minor : DWORD;
sv101_type : DWORD;
sv101_comment : LPWSTR;
end ;
PSERVER_INFO_101 = ^ SERVER_INFO_101;
const
MAJOR_VERSION_MASK = $0F ;
NO_ERROR = 0 ;
var
TempBuffer : PSERVER_INFO_101;
begin
2023-06-07 13:05:04 +02:00
Result : = False ;
aMajor : = 0 ;
aMinor : = 0 ;
2023-04-15 14:59:17 +02:00
TempBuffer : = nil ;
if ( NetServerGetInfo( nil , 1 0 1 , Pointer( TempBuffer) ) = NO_ERROR) then
try
2023-04-15 19:03:59 +02:00
aMajor : = TempBuffer^ . sv101_version_major and MAJOR_VERSION_MASK;
aMinor : = TempBuffer^ . sv101_version_minor;
2023-04-15 14:59:17 +02:00
Result : = True ;
finally
NetApiBufferFree( TempBuffer) ;
end ;
end ;
function CheckRealWindowsVersion( aMajor, aMinor: cardinal ) : boolean ;
var
2023-06-07 13:05:04 +02:00
TempMajor, TempMinor : cardinal ;
TempResultAPI, TempResultReg : boolean ;
2023-04-15 14:59:17 +02:00
begin
2023-06-07 13:05:04 +02:00
TempResultAPI : = GetRealWindowsVersion( TempMajor, TempMinor) and
( ( TempMajor > aMajor) or
( ( TempMajor = aMajor) and ( TempMinor > = aMinor) ) ) ;
TempResultReg : = GetRegistryWindowsVersion( TempMajor, TempMinor) and
( ( TempMajor > aMajor) or
( ( TempMajor = aMajor) and ( TempMinor > = aMinor) ) ) ;
Result : = TempResultAPI or TempResultReg;
2023-04-15 14:59:17 +02:00
end ;
2020-06-13 17:24:22 +02:00
function GetDLLVersion( const aDLLFile : ustring; var aVersionInfo : TFileVersionInfo) : boolean ;
2018-04-18 10:25:38 +02:00
var
TempVersion : uint64 ;
begin
Result : = False ;
try
if FileExists( aDLLFile) then
begin
TempVersion : = GetExtendedFileVersion( aDLLFile) ;
2020-06-13 17:24:22 +02:00
if ( TempVersion < > 0 ) then
begin
UInt64ToFileVersionInfo( TempVersion, aVersionInfo) ;
Result : = True ;
end ;
2018-04-18 10:25:38 +02:00
end ;
except
on e : exception do
if CustomExceptionHandler( 'GetDLLVersion' , e) then raise ;
end ;
2019-01-08 19:15:25 +01:00
end ;
2018-04-18 10:25:38 +02:00
2020-06-13 17:24:22 +02:00
function CheckDLLVersion( const aDLLFile : ustring; aMajor, aMinor, aRelease, aBuild : uint16 ) : boolean ;
2018-04-18 10:25:38 +02:00
var
TempVersionInfo : TFileVersionInfo;
begin
Result : = GetDLLVersion( aDLLFile, TempVersionInfo) and
( TempVersionInfo. MajorVer = aMajor) and
( TempVersionInfo. MinorVer = aMinor) and
( TempVersionInfo. Release = aRelease) and
( TempVersionInfo. Build = aBuild) ;
end ;
2018-09-02 13:11:43 +02:00
// This function is based on the answer given by 'Alex' in StackOverflow
// https://stackoverflow.com/questions/2748474/how-to-determine-if-dll-file-was-compiled-as-x64-or-x86-bit-using-either-delphi
2020-06-13 17:24:22 +02:00
function GetDLLHeaderMachine( const aDLLFile : ustring; var aMachine : integer ) : boolean ;
2018-09-02 13:11:43 +02:00
var
TempHeader : TImageDosHeader;
TempImageNtHeaders : TImageNtHeaders;
TempStream : TFileStream;
begin
Result : = False ;
aMachine : = IMAGE_FILE_MACHINE_UNKNOWN;
TempStream : = nil ;
try
try
if FileExists( aDLLFile) then
begin
2020-09-30 12:43:48 +02:00
TempStream : = TFileStream. Create( aDLLFile, fmOpenRead or fmShareDenyWrite) ;
2018-09-02 13:11:43 +02:00
TempStream. seek( 0 , soFromBeginning) ;
TempStream. ReadBuffer( TempHeader, SizeOf( TempHeader) ) ;
if ( TempHeader. e_magic = IMAGE_DOS_SIGNATURE) and
( TempHeader. _lfanew < > 0 ) then
begin
TempStream. Position : = TempHeader. _lfanew;
TempStream. ReadBuffer( TempImageNtHeaders, SizeOf( TempImageNtHeaders) ) ;
if ( TempImageNtHeaders. Signature = IMAGE_NT_SIGNATURE) then
begin
aMachine : = TempImageNtHeaders. FileHeader. Machine;
Result : = True ;
end ;
end ;
end ;
except
on e : exception do
2018-09-02 15:40:56 +02:00
if CustomExceptionHandler( 'GetDLLHeaderMachine' , e) then raise ;
2018-09-02 13:11:43 +02:00
end ;
finally
if ( TempStream < > nil ) then FreeAndNil( TempStream) ;
end ;
2021-11-28 20:16:49 +01:00
end ;
function GetFileTypeDescription( const aExtension : ustring) : ustring;
var
TempInfo : SHFILEINFOW;
TempExt : ustring;
begin
Result : = '' ;
if ( length( aExtension) > 0 ) then
begin
if ( aExtension[ 1 ] = '.' ) then
TempExt : = aExtension
else
TempExt : = '.' + aExtension;
if ( SHGetFileInfoW( @ TempExt[ 1 ] ,
FILE_ATTRIBUTE_NORMAL,
TempInfo,
SizeOf( SHFILEINFO) ,
SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES) < > 0 ) then
Result : = TempInfo. szTypeName;
end ;
end ;
2021-12-23 19:10:47 +01:00
{$ELSE}
function GetFileTypeDescription( const aExtension : ustring) : ustring;
begin
Result : = uppercase( aExtension) + ' files' ;
end ;
2019-01-08 19:15:25 +01:00
{$ENDIF}
2018-09-02 13:11:43 +02:00
2020-06-13 17:24:22 +02:00
function FileVersionInfoToString( const aVersionInfo : TFileVersionInfo) : string ;
begin
Result : = IntToStr( aVersionInfo. MajorVer) + '.' +
IntToStr( aVersionInfo. MinorVer) + '.' +
IntToStr( aVersionInfo. Release) + '.' +
IntToStr( aVersionInfo. Build) ;
end ;
2018-09-02 13:11:43 +02:00
{$IFDEF MSWINDOWS}
2020-07-28 20:04:25 +02:00
function Is32BitProcessRunningIn64BitOS : boolean ;
2018-09-02 13:11:43 +02:00
var
TempResult : BOOL;
begin
2021-10-27 12:18:33 +02:00
Result : = ProcessUnderWow64( GetCurrentProcess, @ TempResult) and
TempResult;
2020-07-28 20:04:25 +02:00
end ;
{$ENDIF}
2018-09-02 13:11:43 +02:00
2020-07-28 20:04:25 +02:00
function Is32BitProcess : boolean ;
begin
{$IFDEF TARGET_32BITS}
Result : = True ;
2018-09-02 13:11:43 +02:00
{$ELSE}
2020-07-28 20:04:25 +02:00
{$IFDEF MSWINDOWS}
Result : = Is32BitProcessRunningIn64BitOS;
{$ELSE}
{$IFDEF DELPHI17_UP}
Result : = TOSVersion. Architecture in [ arIntelX86, arARM32] ;
{$ELSE}
Result : = False ;
{$ENDIF}
{$ENDIF}
2018-09-02 13:11:43 +02:00
{$ENDIF}
end ;
2018-04-18 10:25:38 +02:00
function CustomPathIsRelative( const aPath : string ) : boolean ;
begin
2020-01-28 11:36:34 +01:00
{$IFDEF MSWINDOWS}
{$IFDEF DELPHI12_UP}
Result : = PathIsRelativeUnicode( PChar( aPath) ) ;
2019-01-08 19:15:25 +01:00
{$ELSE}
2020-01-28 11:36:34 +01:00
Result : = PathIsRelativeAnsi( PChar( aPath) ) ;
2019-01-08 19:15:25 +01:00
{$ENDIF}
2020-01-28 11:36:34 +01:00
{$ELSE}
Result : = ( length( aPath) > 0 ) and ( aPath[ 1 ] < > '/' ) ;
2018-04-18 10:25:38 +02:00
{$ENDIF}
end ;
2019-09-23 11:42:20 +02:00
function CustomPathIsURL( const aPath : string ) : boolean ;
begin
{$IFDEF MSWINDOWS}
{$IFDEF DELPHI12_UP}
Result : = PathIsURLUnicode( PChar( aPath + #0 ) ) ;
{$ELSE}
Result : = PathIsURLAnsi( PChar( aPath + #0 ) ) ;
{$ENDIF}
{$ELSE}
Result : = False ;
{$ENDIF}
end ;
function CustomPathIsUNC( const aPath : string ) : boolean ;
begin
{$IFDEF MSWINDOWS}
{$IFDEF DELPHI12_UP}
Result : = PathIsUNCUnicode( PChar( aPath + #0 ) ) ;
{$ELSE}
Result : = PathIsUNCAnsi( PChar( aPath + #0 ) ) ;
{$ENDIF}
{$ELSE}
Result : = False ;
{$ENDIF}
end ;
2019-09-21 11:37:13 +02:00
function CustomPathCanonicalize( const aOriginalPath : string ; var aCanonicalPath : string ) : boolean ;
var
TempBuffer: array [ 0 .. pred( MAX_PATH) ] of Char ;
begin
Result : = False ;
aCanonicalPath : = '' ;
2019-09-23 11:42:20 +02:00
if ( length( aOriginalPath) > MAX_PATH) or
( Copy( aOriginalPath, 1 , 4 ) = '\\?\' ) or
CustomPathIsUNC( aOriginalPath) then
exit;
2019-09-21 11:37:13 +02:00
FillChar( TempBuffer, MAX_PATH * SizeOf( Char ) , 0 ) ;
{$IFDEF MSWINDOWS}
{$IFDEF DELPHI12_UP}
2019-09-23 11:42:20 +02:00
if PathCanonicalizeUnicode( @ TempBuffer[ 0 ] , PChar( aOriginalPath + #0 ) ) then
2019-09-21 11:37:13 +02:00
begin
aCanonicalPath : = TempBuffer;
Result : = True ;
end ;
{$ELSE}
2019-09-23 11:42:20 +02:00
if PathCanonicalizeAnsi( @ TempBuffer[ 0 ] , PChar( aOriginalPath + #0 ) ) then
2019-09-21 11:37:13 +02:00
begin
aCanonicalPath : = TempBuffer;
Result : = True ;
end ;
{$ENDIF}
{$ENDIF}
end ;
function CustomAbsolutePath( const aPath : string ; aMustExist : boolean ) : string ;
2019-11-10 18:23:39 +01:00
var
2019-09-25 17:23:16 +02:00
TempNewPath, TempOldPath : string ;
2019-09-21 11:37:13 +02:00
begin
if ( length( aPath) > 0 ) then
begin
2019-09-23 11:42:20 +02:00
if CustomPathIsRelative( aPath) then
2019-09-25 17:23:16 +02:00
TempOldPath : = GetModulePath + aPath
2019-09-23 11:42:20 +02:00
else
2019-09-25 17:23:16 +02:00
TempOldPath : = aPath;
if not( CustomPathCanonicalize( TempOldPath, TempNewPath) ) then
TempNewPath : = TempOldPath;
2019-09-23 11:42:20 +02:00
2019-09-25 17:23:16 +02:00
if aMustExist and not( DirectoryExists( TempNewPath) ) then
2019-11-10 18:23:39 +01:00
Result : = ''
else
2019-09-25 17:23:16 +02:00
Result : = TempNewPath;
2019-09-21 11:37:13 +02:00
end
else
Result : = '' ;
end ;
2018-04-18 10:25:38 +02:00
function GetModulePath : string ;
2021-01-31 16:53:07 +01:00
{$IFDEF MACOSX}
const
MAC_APP_POSTFIX = '.app/' ;
MAC_APP_SUBPATH = 'Contents/MacOS/' ;
{$ENDIF}
2018-04-18 10:25:38 +02:00
begin
2019-11-10 18:23:39 +01:00
{$IFDEF MSWINDOWS}
2018-05-14 16:12:21 +02:00
Result : = IncludeTrailingPathDelimiter( ExtractFileDir( GetModuleName( HINSTANCE{$IFDEF FPC} ( ) {$ENDIF} ) ) ) ;
2021-01-31 16:53:07 +01:00
{$ENDIF}
{$IFDEF LINUX}
2019-11-10 18:23:39 +01:00
Result : = IncludeTrailingPathDelimiter( ExtractFileDir( ParamStr( 0 ) ) ) ;
2021-01-31 16:53:07 +01:00
{$ENDIF}
{$IFDEF MACOSX}
Result : = IncludeTrailingPathDelimiter( ExtractFileDir( ParamStr( 0 ) ) ) ;
2021-02-21 18:41:25 +01:00
{$IFDEF FPC}
2021-01-31 16:53:07 +01:00
if copy( Result , Length( Result ) + 1 - Length( MAC_APP_POSTFIX) - Length( MAC_APP_SUBPATH) ) = MAC_APP_POSTFIX + MAC_APP_SUBPATH then
SetLength( Result , Length( Result ) - Length( MAC_APP_SUBPATH) ) ;
Result : = CreateAbsolutePath( Result , GetCurrentDirUTF8) ;
2021-02-21 18:41:25 +01:00
{$ELSE}
if Result . Contains( MAC_APP_POSTFIX + MAC_APP_SUBPATH) then
2021-02-24 10:57:59 +01:00
Result : = Result . Remove( Result . IndexOf( MAC_APP_SUBPATH) ) ;
2021-02-21 18:41:25 +01:00
{$ENDIF}
2021-01-31 16:53:07 +01:00
{$ENDIF}
2018-04-18 10:25:38 +02:00
end ;
2022-12-16 11:29:15 +01:00
function CefResolveUrl( const base_url, relative_url: ustring) : ustring;
var
TempBaseURL, TempRelativeURL, TempResolvedURL : TCefString;
begin
Result : = '' ;
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
TempBaseURL : = CefString( base_url) ;
TempRelativeURL : = CefString( relative_url) ;
CefStringInitialize( @ TempResolvedURL) ;
if ( cef_resolve_url( @ TempBaseURL, @ TempRelativeURL, @ TempResolvedURL) < > 0 ) then
Result : = CefStringClearAndGet( @ TempResolvedURL) ;
end ;
end ;
2018-04-18 10:25:38 +02:00
function CefParseUrl( const url: ustring; var parts: TUrlParts) : Boolean ;
var
2018-06-11 09:01:38 +02:00
TempURL : TCefString;
TempParts : TCefUrlParts;
begin
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
FillChar( TempParts, sizeof( TempParts) , 0 ) ;
TempURL : = CefString( url) ;
Result : = cef_parse_url( @ TempURL, TempParts) < > 0 ;
if Result then
begin
2020-04-10 09:49:34 +02:00
parts. spec : = CefString( @ TempParts. spec) ;
2018-06-11 09:01:38 +02:00
parts. scheme : = CefString( @ TempParts. scheme) ;
parts. username : = CefString( @ TempParts. username) ;
parts. password : = CefString( @ TempParts. password) ;
parts. host : = CefString( @ TempParts. host) ;
parts. port : = CefString( @ TempParts. port) ;
parts. origin : = CefString( @ TempParts. origin) ;
parts. path : = CefString( @ TempParts. path) ;
parts. query : = CefString( @ TempParts. query) ;
2020-04-10 09:49:34 +02:00
parts. fragment : = CefString( @ TempParts. fragment) ;
2018-06-11 09:01:38 +02:00
end ;
end
else
Result : = False ;
2018-04-18 10:25:38 +02:00
end ;
function CefCreateUrl( var parts: TUrlParts) : ustring;
var
2018-06-11 09:01:38 +02:00
TempURL : TCefString;
TempParts : TCefUrlParts;
begin
Result : = '' ;
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
TempParts. spec : = CefString( parts. spec) ;
TempParts. scheme : = CefString( parts. scheme) ;
TempParts. username : = CefString( parts. username) ;
TempParts. password : = CefString( parts. password) ;
TempParts. host : = CefString( parts. host) ;
TempParts. port : = CefString( parts. port) ;
TempParts. origin : = CefString( parts. origin) ;
TempParts. path : = CefString( parts. path) ;
TempParts. query : = CefString( parts. query) ;
2020-06-21 21:27:55 +02:00
TempParts. fragment : = CefString( parts. fragment) ;
2018-06-11 09:01:38 +02:00
2019-11-24 18:19:49 +01:00
CefStringInitialize( @ TempURL) ;
if ( cef_create_url( @ TempParts, @ TempURL) < > 0 ) then
Result : = CefStringClearAndGet( @ TempURL) ;
2018-06-11 09:01:38 +02:00
end ;
2018-04-18 10:25:38 +02:00
end ;
function CefFormatUrlForSecurityDisplay( const originUrl: string ) : string ;
var
2018-06-11 09:01:38 +02:00
TempOrigin : TCefString;
2018-04-18 10:25:38 +02:00
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
TempOrigin : = CefString( originUrl) ;
Result : = CefStringFreeAndGet( cef_format_url_for_security_display( @ TempOrigin) ) ;
end
else
Result : = '' ;
2018-04-18 10:25:38 +02:00
end ;
function CefGetMimeType( const extension: ustring) : ustring;
var
2018-06-11 09:01:38 +02:00
TempExt : TCefString;
2018-04-18 10:25:38 +02:00
begin
2018-06-11 09:01:38 +02:00
TempExt : = CefString( extension) ;
Result : = CefStringFreeAndGet( cef_get_mime_type( @ TempExt) ) ;
2018-04-18 10:25:38 +02:00
end ;
procedure CefGetExtensionsForMimeType( const mimeType: ustring; var extensions: TStringList) ;
var
TempSL : ICefStringList;
TempMimeType : TCefString;
begin
2018-06-11 09:01:38 +02:00
if ( extensions < > nil ) and ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
2018-04-18 10:25:38 +02:00
begin
TempSL : = TCefStringListOwn. Create;
TempMimeType : = CefString( mimeType) ;
cef_get_extensions_for_mime_type( @ TempMimeType, TempSL. Handle) ;
TempSL. CopyToStrings( extensions) ;
end ;
end ;
function CefBase64Encode( const data: Pointer ; dataSize: NativeUInt ) : ustring;
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
Result : = CefStringFreeAndGet( cef_base64encode( data, dataSize) )
else
Result : = '' ;
2018-04-18 10:25:38 +02:00
end ;
function CefBase64Decode( const data: ustring) : ICefBinaryValue;
var
2018-06-11 09:01:38 +02:00
TempData : TCefString;
2018-04-18 10:25:38 +02:00
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
TempData : = CefString( data) ;
Result : = TCefBinaryValueRef. UnWrap( cef_base64decode( @ TempData) ) ;
end
else
Result : = nil ;
2018-04-18 10:25:38 +02:00
end ;
function CefUriEncode( const text : ustring; usePlus: Boolean ) : ustring;
var
2018-06-11 09:01:38 +02:00
TempText : TCefString;
2018-04-18 10:25:38 +02:00
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
TempText : = CefString( text ) ;
Result : = CefStringFreeAndGet( cef_uriencode( @ TempText, Ord( usePlus) ) ) ;
end
else
Result : = '' ;
2018-04-18 10:25:38 +02:00
end ;
2018-06-11 09:01:38 +02:00
function CefUriDecode( const text : ustring; convertToUtf8: Boolean ; unescapeRule: TCefUriUnescapeRule) : ustring;
2018-04-18 10:25:38 +02:00
var
2018-06-11 09:01:38 +02:00
TempText : TCefString;
2018-04-18 10:25:38 +02:00
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
TempText : = CefString( text ) ;
Result : = CefStringFreeAndGet( cef_uridecode( @ TempText, Ord( convertToUtf8) , unescapeRule) ) ;
end
else
Result : = '' ;
2018-04-18 10:25:38 +02:00
end ;
2019-11-24 18:19:49 +01:00
function CefGetPath( const aPathKey : TCefPathKey) : ustring;
var
TempPath : TCefString;
begin
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
CefStringInitialize( @ TempPath) ;
if ( cef_get_path( aPathKey, @ TempPath) < > 0 ) then
Result : = CefStringClearAndGet( @ TempPath) ;
end
else
Result : = '' ;
end ;
2021-09-27 12:04:33 +02:00
function CefIsRTL : boolean ;
begin
Result : = ( GlobalCEFApp < > nil ) and
GlobalCEFApp. LibLoaded and
( cef_is_rtl( ) < > 0 ) ;
end ;
2018-04-18 10:25:38 +02:00
function CefCreateDirectory( const fullPath: ustring) : Boolean ;
var
2018-06-11 09:01:38 +02:00
TempPath : TCefString;
2018-04-18 10:25:38 +02:00
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
TempPath : = CefString( fullPath) ;
Result : = cef_create_directory( @ TempPath) < > 0 ;
end
else
Result : = False ;
2018-04-18 10:25:38 +02:00
end ;
function CefGetTempDirectory( out tempDir: ustring) : Boolean ;
var
2018-06-11 09:01:38 +02:00
TempPath : TCefString;
2018-04-18 10:25:38 +02:00
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
2019-11-24 18:19:49 +01:00
CefStringInitialize( @ TempPath) ;
2018-06-11 09:01:38 +02:00
Result : = cef_get_temp_directory( @ TempPath) < > 0 ;
2019-11-24 18:19:49 +01:00
tempDir : = CefStringClearAndGet( @ TempPath) ;
2018-06-11 09:01:38 +02:00
end
else
begin
Result : = False ;
tempDir : = '' ;
end ;
2018-04-18 10:25:38 +02:00
end ;
function CefCreateNewTempDirectory( const prefix: ustring; out newTempPath: ustring) : Boolean ;
var
2018-06-11 09:01:38 +02:00
TempPath, TempPref : TCefString;
2018-04-18 10:25:38 +02:00
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
2019-11-24 18:19:49 +01:00
CefStringInitialize( @ TempPath) ;
2018-06-11 09:01:38 +02:00
TempPref : = CefString( prefix) ;
Result : = cef_create_new_temp_directory( @ TempPref, @ TempPath) < > 0 ;
2019-11-24 18:19:49 +01:00
newTempPath : = CefStringClearAndGet( @ TempPath) ;
2018-06-11 09:01:38 +02:00
end
else
begin
Result : = False ;
newTempPath : = '' ;
end ;
2018-04-18 10:25:38 +02:00
end ;
2018-06-11 09:01:38 +02:00
function CefCreateTempDirectoryInDirectory( const baseDir, prefix: ustring; out newDir: ustring) : Boolean ;
2018-04-18 10:25:38 +02:00
var
2018-06-11 09:01:38 +02:00
TempBase, TempPath, TempPref: TCefString;
2018-04-18 10:25:38 +02:00
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
2019-11-24 18:19:49 +01:00
CefStringInitialize( @ TempPath) ;
2018-06-11 09:01:38 +02:00
TempPref : = CefString( prefix) ;
TempBase : = CefString( baseDir) ;
Result : = cef_create_temp_directory_in_directory( @ TempBase, @ TempPref, @ TempPath) < > 0 ;
2019-11-24 18:19:49 +01:00
newDir : = CefStringClearAndGet( @ TempPath) ;
2018-06-11 09:01:38 +02:00
end
else
begin
Result : = False ;
newDir : = '' ;
end ;
2018-04-18 10:25:38 +02:00
end ;
function CefDirectoryExists( const path: ustring) : Boolean ;
var
2018-06-11 09:01:38 +02:00
TempPath : TCefString;
2018-04-18 10:25:38 +02:00
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
TempPath : = CefString( path) ;
Result : = cef_directory_exists( @ TempPath) < > 0 ;
end
else
Result : = False ;
2018-04-18 10:25:38 +02:00
end ;
function CefDeleteFile( const path: ustring; recursive: Boolean ) : Boolean ;
var
2018-06-11 09:01:38 +02:00
TempPath : TCefString;
2018-04-18 10:25:38 +02:00
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
TempPath : = CefString( path) ;
Result : = cef_delete_file( @ TempPath, Ord( recursive) ) < > 0 ;
end
else
Result : = False ;
2018-04-18 10:25:38 +02:00
end ;
function CefZipDirectory( const srcDir, destFile: ustring; includeHiddenFiles: Boolean ) : Boolean ;
var
2018-06-11 09:01:38 +02:00
TempSrc, TempDst : TCefString;
2018-04-18 10:25:38 +02:00
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
TempSrc : = CefString( srcDir) ;
TempDst : = CefString( destFile) ;
Result : = cef_zip_directory( @ TempSrc, @ TempDst, Ord( includeHiddenFiles) ) < > 0 ;
end
else
Result : = False ;
2018-04-18 10:25:38 +02:00
end ;
procedure CefLoadCRLSetsFile( const path : ustring) ;
var
TempPath : TCefString;
begin
2018-06-11 09:01:38 +02:00
if ( GlobalCEFApp < > nil ) and GlobalCEFApp. LibLoaded then
begin
TempPath : = CefString( path) ;
cef_load_crlsets_file( @ TempPath) ;
end ;
2018-04-18 10:25:38 +02:00
end ;
2019-01-08 19:15:25 +01:00
{$IFDEF MSWINDOWS}
2018-04-18 10:25:38 +02:00
function CefIsKeyDown( aWparam : WPARAM) : boolean ;
begin
Result : = ( GetKeyState( aWparam) < 0 ) ;
end ;
function CefIsKeyToggled( aWparam : WPARAM) : boolean ;
begin
Result : = ( GetKeyState( aWparam) and $1 ) < > 0 ;
end ;
function GetCefMouseModifiers( aWparam : WPARAM) : TCefEventFlags;
begin
Result : = EVENTFLAG_NONE;
if ( ( aWparam and MK_CONTROL) < > 0 ) then Result : = Result or EVENTFLAG_CONTROL_DOWN;
if ( ( aWparam and MK_SHIFT) < > 0 ) then Result : = Result or EVENTFLAG_SHIFT_DOWN;
if ( ( aWparam and MK_LBUTTON) < > 0 ) then Result : = Result or EVENTFLAG_LEFT_MOUSE_BUTTON;
if ( ( aWparam and MK_MBUTTON) < > 0 ) then Result : = Result or EVENTFLAG_MIDDLE_MOUSE_BUTTON;
if ( ( aWparam and MK_RBUTTON) < > 0 ) then Result : = Result or EVENTFLAG_RIGHT_MOUSE_BUTTON;
if CefIsKeyDown( VK_MENU) then Result : = Result or EVENTFLAG_ALT_DOWN;
if CefIsKeyToggled( VK_NUMLOCK) then Result : = Result or EVENTFLAG_NUM_LOCK_ON;
if CefIsKeyToggled( VK_CAPITAL) then Result : = Result or EVENTFLAG_CAPS_LOCK_ON;
end ;
function GetCefMouseModifiers : TCefEventFlags;
begin
Result : = EVENTFLAG_NONE;
if CefIsKeyDown( MK_CONTROL) then Result : = Result or EVENTFLAG_CONTROL_DOWN;
if CefIsKeyDown( MK_SHIFT) then Result : = Result or EVENTFLAG_SHIFT_DOWN;
if CefIsKeyDown( MK_LBUTTON) then Result : = Result or EVENTFLAG_LEFT_MOUSE_BUTTON;
if CefIsKeyDown( MK_MBUTTON) then Result : = Result or EVENTFLAG_MIDDLE_MOUSE_BUTTON;
if CefIsKeyDown( MK_RBUTTON) then Result : = Result or EVENTFLAG_RIGHT_MOUSE_BUTTON;
if CefIsKeyDown( VK_MENU) then Result : = Result or EVENTFLAG_ALT_DOWN;
if CefIsKeyToggled( VK_NUMLOCK) then Result : = Result or EVENTFLAG_NUM_LOCK_ON;
if CefIsKeyToggled( VK_CAPITAL) then Result : = Result or EVENTFLAG_CAPS_LOCK_ON;
end ;
function GetCefKeyboardModifiers( aWparam : WPARAM; aLparam : LPARAM) : TCefEventFlags;
begin
Result : = EVENTFLAG_NONE;
if CefIsKeyDown( VK_SHIFT) then Result : = Result or EVENTFLAG_SHIFT_DOWN;
if CefIsKeyDown( VK_CONTROL) then Result : = Result or EVENTFLAG_CONTROL_DOWN;
if CefIsKeyDown( VK_MENU) then Result : = Result or EVENTFLAG_ALT_DOWN;
if CefIsKeyToggled( VK_NUMLOCK) then Result : = Result or EVENTFLAG_NUM_LOCK_ON;
if CefIsKeyToggled( VK_CAPITAL) then Result : = Result or EVENTFLAG_CAPS_LOCK_ON;
case aWparam of
VK_RETURN:
2021-09-05 10:49:20 +02:00
if ( ( ( aLparam shr 1 6 ) and KF_EXTENDED) < > 0 ) then
Result : = Result or EVENTFLAG_IS_KEY_PAD;
2018-04-18 10:25:38 +02:00
VK_INSERT,
VK_DELETE,
VK_HOME,
VK_END,
VK_PRIOR,
VK_NEXT,
VK_UP,
VK_DOWN,
VK_LEFT,
VK_RIGHT :
2021-09-05 10:49:20 +02:00
if ( ( ( aLparam shr 1 6 ) and KF_EXTENDED) = 0 ) then
Result : = Result or EVENTFLAG_IS_KEY_PAD;
2018-04-18 10:25:38 +02:00
VK_NUMLOCK,
VK_NUMPAD0,
VK_NUMPAD1,
VK_NUMPAD2,
VK_NUMPAD3,
VK_NUMPAD4,
VK_NUMPAD5,
VK_NUMPAD6,
VK_NUMPAD7,
VK_NUMPAD8,
VK_NUMPAD9,
VK_DIVIDE,
VK_MULTIPLY,
VK_SUBTRACT,
VK_ADD,
VK_DECIMAL,
VK_CLEAR :
Result : = Result or EVENTFLAG_IS_KEY_PAD;
VK_SHIFT :
if CefIsKeyDown( VK_LSHIFT) then
Result : = Result or EVENTFLAG_IS_LEFT
else
if CefIsKeyDown( VK_RSHIFT) then
Result : = Result or EVENTFLAG_IS_RIGHT;
VK_CONTROL :
if CefIsKeyDown( VK_LCONTROL) then
Result : = Result or EVENTFLAG_IS_LEFT
else
if CefIsKeyDown( VK_RCONTROL) then
Result : = Result or EVENTFLAG_IS_RIGHT;
VK_MENU :
if CefIsKeyDown( VK_LMENU) then
Result : = Result or EVENTFLAG_IS_LEFT
else
if CefIsKeyDown( VK_RMENU) then
Result : = Result or EVENTFLAG_IS_RIGHT;
VK_LWIN :
Result : = Result or EVENTFLAG_IS_LEFT;
VK_RWIN :
Result : = Result or EVENTFLAG_IS_RIGHT;
end ;
end ;
2020-04-10 09:49:34 +02:00
procedure CefCheckAltGrPressed( aWparam : WPARAM; var aEvent : TCefKeyEvent) ;
const
EITHER_SHIFT_KEY_PRESSED = $01 ;
EITHER_CONTROL_KEY_PRESSED = $02 ;
EITHER_ALT_KEY_PRESSED = $04 ;
EITHER_HANKAKU_KEY_PRESSED = $08 ;
EITHER_RESERVED1_KEY_PRESSED = $10 ;
EITHER_RESERVED2_KEY_PRESSED = $20 ;
var
TempKBLayout : HKL;
TempTranslatedChar : SHORT;
TempShiftState : byte ;
begin
if ( aEvent. kind = KEYEVENT_CHAR) and CefIsKeyDown( VK_RMENU) then
begin
TempKBLayout : = GetKeyboardLayout( 0 ) ;
TempTranslatedChar : = VkKeyScanEx( char( aWparam) , TempKBLayout) ;
TempShiftState : = byte( TempTranslatedChar shr 8 ) ;
if ( ( TempShiftState and EITHER_CONTROL_KEY_PRESSED) < > 0 ) and
( ( TempShiftState and EITHER_ALT_KEY_PRESSED) < > 0 ) then
begin
aEvent. modifiers : = aEvent. modifiers and not( EVENTFLAG_CONTROL_DOWN or EVENTFLAG_ALT_DOWN) ;
aEvent. modifiers : = aEvent. modifiers or EVENTFLAG_ALTGR_DOWN;
end ;
end ;
end ;
2018-04-18 10:25:38 +02:00
procedure DropEffectToDragOperation( aEffect: Longint ; var aAllowedOps : TCefDragOperations) ;
begin
aAllowedOps : = DRAG_OPERATION_NONE;
if ( ( aEffect and DROPEFFECT_COPY) < > 0 ) then aAllowedOps : = aAllowedOps or DRAG_OPERATION_COPY;
if ( ( aEffect and DROPEFFECT_LINK) < > 0 ) then aAllowedOps : = aAllowedOps or DRAG_OPERATION_LINK;
if ( ( aEffect and DROPEFFECT_MOVE) < > 0 ) then aAllowedOps : = aAllowedOps or DRAG_OPERATION_MOVE;
end ;
procedure DragOperationToDropEffect( const aDragOperations : TCefDragOperations; var aEffect: Longint ) ;
begin
aEffect : = DROPEFFECT_NONE;
if ( ( aDragOperations and DRAG_OPERATION_COPY) < > 0 ) then aEffect : = aEffect or DROPEFFECT_COPY;
if ( ( aDragOperations and DRAG_OPERATION_LINK) < > 0 ) then aEffect : = aEffect or DROPEFFECT_LINK;
if ( ( aDragOperations and DRAG_OPERATION_MOVE) < > 0 ) then aEffect : = aEffect or DROPEFFECT_MOVE;
2020-01-02 20:02:47 +01:00
end ;
2020-01-13 15:39:44 +01:00
function GetWindowsMajorMinorVersion( var wMajorVersion, wMinorVersion : DWORD) : boolean ;
2020-05-09 11:41:20 +02:00
type
TRtlGetVersionFunc = function( var lpVersionInformation : TOSVersionInfoEx) : LongInt ; stdcall ;
2020-01-13 15:39:44 +01:00
var
2020-05-09 11:41:20 +02:00
TempHandle : THandle;
2020-01-13 15:39:44 +01:00
TempInfo : TOSVersionInfoEx;
2020-05-09 11:41:20 +02:00
TempRtlGetVersionFunc : TRtlGetVersionFunc;
2020-01-13 15:39:44 +01:00
begin
Result : = False ;
wMajorVersion : = 0 ;
wMinorVersion : = 0 ;
2020-05-09 11:41:20 +02:00
try
TempHandle : = LoadLibrary( NTDLL) ;
2020-01-13 15:39:44 +01:00
2020-05-09 11:41:20 +02:00
if ( TempHandle < > 0 ) then
try
{$IFDEF FPC} Pointer( {$ENDIF} TempRtlGetVersionFunc{$IFDEF FPC} ) {$ENDIF} : = GetProcAddress( TempHandle, 'RtlGetVersion' ) ;
if assigned( TempRtlGetVersionFunc) then
begin
ZeroMemory( @ TempInfo, SizeOf( TOSVersionInfoEx) ) ;
if ( TempRtlGetVersionFunc( TempInfo) = 0 ) then
begin
Result : = True ;
wMajorVersion : = TempInfo. dwMajorVersion;
wMinorVersion : = TempInfo. dwMinorVersion;
end ;
end ;
finally
FreeLibrary( TempHandle) ;
end ;
except
on e : exception do
if CustomExceptionHandler( 'GetWindowsMajorMinorVersion' , e) then raise ;
end ;
2020-01-13 15:39:44 +01:00
end ;
2020-10-31 14:23:06 +01:00
// GetDpiForWindow is only available in Windows 10 (version 1607) or newer
function GetDPIForHandle( aHandle : HWND; var aDPI : UINT) : boolean ;
type
TGetDpiForWindow = function( hwnd: HWND) : UINT; stdcall ;
var
TempHandle : THandle;
TempGetDpiForWindowFunc : TGetDpiForWindow;
begin
Result : = False ;
aDPI : = 0 ;
if ( aHandle = 0 ) then exit;
try
TempHandle : = LoadLibrary( User32DLL) ;
if ( TempHandle < > 0 ) then
try
{$IFDEF FPC} Pointer( {$ENDIF} TempGetDpiForWindowFunc{$IFDEF FPC} ) {$ENDIF} : = GetProcAddress( TempHandle, 'GetDpiForWindow' ) ;
if assigned( TempGetDpiForWindowFunc) then
begin
aDPI : = TempGetDpiForWindowFunc( aHandle) ;
Result : = ( aDPI < > 0 ) ;
end ;
finally
FreeLibrary( TempHandle) ;
end ;
except
on e : exception do
if CustomExceptionHandler( 'GetDPIForHandle' , e) then raise ;
end ;
end ;
function RunningWindows10OrNewer : boolean ;
var
TempMajorVer, TempMinorVer : DWORD;
begin
Result : = GetWindowsMajorMinorVersion( TempMajorVer, TempMinorVer) and ( TempMajorVer > = 1 0 ) ;
end ;
2020-01-13 15:39:44 +01:00
function GetDefaultCEFUserAgent : string ;
var
TempOS, TempChromiumVersion : string ;
TempMajorVer, TempMinorVer : DWORD;
Temp64bit : BOOL;
begin
if GetWindowsMajorMinorVersion( TempMajorVer, TempMinorVer) and
( TempMajorVer > = 4 ) then
TempOS : = 'Windows NT'
else
TempOS : = 'Windows' ;
TempOS : = TempOS + ' ' + inttostr( TempMajorVer) + '.' + inttostr( TempMinorVer) ;
2021-10-27 12:18:33 +02:00
if ProcessUnderWow64( GetCurrentProcess( ) , @ Temp64bit) and Temp64bit then
2020-01-13 15:39:44 +01:00
TempOS : = TempOS + '; WOW64' ;
if ( GlobalCEFApp < > nil ) then
TempChromiumVersion : = GlobalCEFApp. ChromeVersion
else
TempChromiumVersion : = inttostr( CEF_CHROMEELF_VERSION_MAJOR) + '.' +
inttostr( CEF_CHROMEELF_VERSION_MINOR) + '.' +
inttostr( CEF_CHROMEELF_VERSION_RELEASE) + '.' +
inttostr( CEF_CHROMEELF_VERSION_BUILD) ;
Result : = 'Mozilla/5.0' + ' (' + TempOS + ') ' +
'AppleWebKit/537.36 (KHTML, like Gecko) ' +
'Chrome/' + TempChromiumVersion + ' Safari/537.36' ;
end ;
2020-02-03 16:14:31 +01:00
2020-02-04 11:50:38 +01:00
{$IFDEF DELPHI14_UP}
2020-02-03 16:14:31 +01:00
function TouchPointToPoint( aHandle : HWND; const TouchPoint: TTouchInput) : TPoint;
2020-02-03 12:02:30 +01:00
begin
Result : = Point( TouchPoint. X div 1 0 0 , TouchPoint. Y div 1 0 0 ) ;
PhysicalToLogicalPoint( aHandle, Result ) ;
end ;
2020-02-05 14:40:22 +01:00
function GetDigitizerStatus( var aDigitizerStatus : TDigitizerStatus; aDPI : cardinal ) : boolean ;
var
TempStatus : integer ;
begin
2020-02-06 10:37:54 +01:00
{$IFDEF DELPHI26_UP}
2020-02-05 14:40:22 +01:00
if ( aDPI > 0 ) then
TempStatus : = GetSystemMetricsForDpi( SM_DIGITIZER, aDPI)
else
2020-02-06 10:37:54 +01:00
{$ENDIF}
2020-02-05 14:40:22 +01:00
TempStatus : = GetSystemMetrics( SM_DIGITIZER) ;
aDigitizerStatus. IntegratedTouch : = ( ( TempStatus and NID_INTEGRATED_TOUCH) < > 0 ) ;
aDigitizerStatus. ExternalTouch : = ( ( TempStatus and NID_EXTERNAL_TOUCH) < > 0 ) ;
aDigitizerStatus. IntegratedPen : = ( ( TempStatus and NID_INTEGRATED_PEN) < > 0 ) ;
aDigitizerStatus. ExternalPen : = ( ( TempStatus and NID_EXTERNAL_PEN) < > 0 ) ;
aDigitizerStatus. MultiInput : = ( ( TempStatus and NID_MULTI_INPUT) < > 0 ) ;
aDigitizerStatus. Ready : = ( ( TempStatus and NID_READY) < > 0 ) ;
Result : = ( TempStatus < > 0 ) ;
end ;
function HasTouchOrPen( aDPI : cardinal ) : boolean ;
var
TempStatus : TDigitizerStatus;
begin
Result : = GetDigitizerStatus( TempStatus, aDPI) ;
end ;
2020-02-06 10:37:54 +01:00
{$ENDIF}
2019-01-08 19:15:25 +01:00
{$ENDIF}
2018-04-18 10:25:38 +02:00
function DeviceToLogical( aValue : integer ; const aDeviceScaleFactor : double ) : integer ;
begin
Result : = floor( aValue / aDeviceScaleFactor) ;
end ;
2020-02-03 12:02:30 +01:00
function DeviceToLogical( aValue : single ; const aDeviceScaleFactor : double ) : single ;
begin
Result : = aValue / aDeviceScaleFactor;
end ;
2018-04-18 10:25:38 +02:00
procedure DeviceToLogical( var aEvent : TCEFMouseEvent; const aDeviceScaleFactor : double ) ;
2020-02-03 12:02:30 +01:00
begin
aEvent. x : = DeviceToLogical( aEvent. x, aDeviceScaleFactor) ;
aEvent. y : = DeviceToLogical( aEvent. y, aDeviceScaleFactor) ;
end ;
procedure DeviceToLogical( var aEvent : TCefTouchEvent; const aDeviceScaleFactor : double ) ;
2018-04-18 10:25:38 +02:00
begin
aEvent. x : = DeviceToLogical( aEvent. x, aDeviceScaleFactor) ;
aEvent. y : = DeviceToLogical( aEvent. y, aDeviceScaleFactor) ;
end ;
procedure DeviceToLogical( var aPoint : TPoint; const aDeviceScaleFactor : double ) ;
begin
aPoint. x : = DeviceToLogical( aPoint. x, aDeviceScaleFactor) ;
aPoint. y : = DeviceToLogical( aPoint. y, aDeviceScaleFactor) ;
end ;
function LogicalToDevice( aValue : integer ; const aDeviceScaleFactor : double ) : integer ;
begin
Result : = floor( aValue * aDeviceScaleFactor) ;
end ;
procedure LogicalToDevice( var aRect : TCEFRect; const aDeviceScaleFactor : double ) ;
begin
aRect. x : = LogicalToDevice( aRect. x, aDeviceScaleFactor) ;
aRect. y : = LogicalToDevice( aRect. y, aDeviceScaleFactor) ;
aRect. width : = LogicalToDevice( aRect. width, aDeviceScaleFactor) ;
aRect. height : = LogicalToDevice( aRect. height, aDeviceScaleFactor) ;
end ;
function GetScreenDPI : integer ;
2019-01-08 19:15:25 +01:00
{$IFDEF MSWINDOWS}
2018-04-18 10:25:38 +02:00
var
TempDC : HDC;
2021-06-24 17:47:22 +02:00
{$ELSE}
{$IFDEF FMX}
var
2022-06-26 17:53:54 +02:00
TempService : IFMXScreenService;
TempWidth, TempWidthMM : integer ;
2021-06-24 17:47:22 +02:00
{$ENDIF}
2019-01-08 19:15:25 +01:00
{$ENDIF}
2018-04-18 10:25:38 +02:00
begin
2019-01-08 19:15:25 +01:00
{$IFDEF MSWINDOWS}
2018-04-18 10:25:38 +02:00
TempDC : = GetDC( 0 ) ;
Result : = GetDeviceCaps( TempDC, LOGPIXELSX) ;
ReleaseDC( 0 , TempDC) ;
2021-01-31 16:53:07 +01:00
{$ENDIF}
{$IFDEF LINUX}
{$IFDEF FPC}
2020-12-28 18:11:27 +01:00
if ( Application < > nil ) and
( Application. MainForm < > nil ) and
( Application. MainForm. Monitor < > nil ) then
Result : = Application. MainForm. Monitor. PixelsPerInch
else
if ( screen < > nil ) then
begin
if ( WidgetSet < > nil ) and ( screen. PrimaryMonitor < > nil ) then
Result : = screen. PrimaryMonitor. PixelsPerInch
else
Result : = screen. PixelsPerInch;
end
else
Result : = USER_DEFAULT_SCREEN_DPI;
2021-01-31 16:53:07 +01:00
{$ELSE}
2022-06-26 17:53:54 +02:00
Result : = - 1 ;
2021-06-24 17:47:22 +02:00
if TPlatformServices. Current. SupportsPlatformService( IFMXScreenService, TempService) then
2022-06-26 17:53:54 +02:00
Result : = round( TempService. GetScreenScale * USER_DEFAULT_SCREEN_DPI) ;
if ( Result < 0 ) then
2021-06-24 17:47:22 +02:00
begin
Result : = round( gdk_screen_get_resolution( gdk_screen_get_default) ) ;
2022-06-26 17:53:54 +02:00
2021-06-24 17:47:22 +02:00
if ( Result < 0 ) then
2022-06-26 17:53:54 +02:00
begin
TempWidthMM : = gdk_screen_width_mm;
TempWidth : = gdk_screen_width;
if ( TempWidthMM > 0 ) and ( TempWidth > 0 ) then
Result : = round( TempWidth / ( TempWidthMM / 25.4 ) )
else
Result : = USER_DEFAULT_SCREEN_DPI;
end ;
2021-06-24 17:47:22 +02:00
end ;
2021-01-31 16:53:07 +01:00
{$ENDIF}
{$ENDIF}
{$IFDEF MACOSX}
{$IFDEF FPC}
2021-06-24 17:47:22 +02:00
Result : = round( NSScreen. mainScreen. backingScaleFactor * USER_DEFAULT_SCREEN_DPI) ;
2021-05-16 19:42:25 +02:00
{$ELSE}
2021-06-24 17:47:22 +02:00
if TPlatformServices. Current. SupportsPlatformService( IFMXScreenService, TempService) then
Result : = round( TempService. GetScreenScale * USER_DEFAULT_SCREEN_DPI)
else
Result : = round( TNSScreen. Wrap( TNSScreen. OCClass. mainScreen) . backingScaleFactor * USER_DEFAULT_SCREEN_DPI) ;
2020-01-28 11:36:34 +01:00
{$ENDIF}
2019-01-08 19:15:25 +01:00
{$ENDIF}
2018-04-18 10:25:38 +02:00
end ;
function GetDeviceScaleFactor : single ;
2021-06-24 17:47:22 +02:00
{$IFDEF MACOSX} {$IFDEF FMX}
var
TempService: IFMXScreenService;
{$ENDIF} {$ENDIF}
2018-04-18 10:25:38 +02:00
begin
2021-06-24 17:47:22 +02:00
{$IFDEF MACOSX}
{$IFDEF FPC}
Result : = NSScreen. mainScreen. backingScaleFactor;
{$ELSE}
if TPlatformServices. Current. SupportsPlatformService( IFMXScreenService, TempService) then
Result : = TempService. GetScreenScale
else
Result : = TNSScreen. Wrap( TNSScreen. OCClass. mainScreen) . backingScaleFactor;
{$ENDIF}
2021-02-24 10:57:59 +01:00
{$ELSE}
2020-10-31 14:23:06 +01:00
Result : = GetScreenDPI / USER_DEFAULT_SCREEN_DPI;
2021-02-24 10:57:59 +01:00
{$ENDIF}
2018-04-18 10:25:38 +02:00
end ;
2019-06-19 16:53:26 +02:00
function DeleteDirContents( const aDirectory : string ; const aExcludeFiles : TStringList) : boolean ;
2018-09-18 16:19:21 +02:00
var
TempRec : TSearchRec;
TempPath : string ;
2019-06-19 16:53:26 +02:00
TempIdx : integer ;
2018-09-18 16:19:21 +02:00
begin
Result : = True ;
try
if ( length( aDirectory) > 0 ) and
DirectoryExists( aDirectory) and
( FindFirst( aDirectory + '\*' , faAnyFile, TempRec) = 0 ) then
try
repeat
TempPath : = aDirectory + PathDelim + TempRec. Name ;
if ( ( TempRec. Attr and faDirectory) < > 0 ) then
begin
if ( TempRec. Name < > '.' ) and ( TempRec. Name < > '..' ) then
begin
2019-06-19 16:53:26 +02:00
if DeleteDirContents( TempPath, aExcludeFiles) then
2022-07-21 14:11:32 +02:00
Result : = ( ( TempRec. Name = 'Network' ) or RemoveDir( TempPath) ) and Result
2018-09-18 16:19:21 +02:00
else
Result : = False ;
end ;
end
else
2019-06-19 16:53:26 +02:00
if ( aExcludeFiles < > nil ) then
begin
TempIdx : = aExcludeFiles. IndexOf( TempRec. Name ) ;
Result : = ( ( TempIdx > = 0 ) or
( ( TempIdx < 0 ) and DeleteFile( TempPath) ) ) and
Result ;
end
else
Result : = DeleteFile( TempPath) and Result ;
2018-09-18 16:19:21 +02:00
until ( FindNext( TempRec) < > 0 ) or not( Result ) ;
finally
FindClose( TempRec) ;
end ;
except
on e : exception do
if CustomExceptionHandler( 'DeleteDirContents' , e) then raise ;
end ;
2018-09-18 15:19:44 +02:00
end ;
2019-06-19 16:53:26 +02:00
function DeleteFileList( const aFileList : TStringList) : boolean ;
var
i, TempCount : integer ;
begin
Result : = False ;
try
if ( aFileList < > nil ) then
begin
i : = 0 ;
TempCount : = 0 ;
while ( i < aFileList. Count) do
begin
if FileExists( aFileList[ i] ) and DeleteFile( aFileList[ i] ) then inc( TempCount) ;
inc( i) ;
end ;
Result : = ( aFileList. Count = TempCount) ;
end ;
except
on e : exception do
if CustomExceptionHandler( 'DeleteFileList' , e) then raise ;
end ;
end ;
function MoveFileList( const aFileList : TStringList; const aSrcDirectory, aDstDirectory : string ) : boolean ;
var
i, TempCount : integer ;
TempSrcPath, TempDstPath : string ;
begin
Result : = False ;
try
if ( aFileList < > nil ) and
( length( aSrcDirectory) > 0 ) and
2019-11-10 18:23:39 +01:00
( length( aDstDirectory) > 0 ) and
DirectoryExists( aSrcDirectory) and
2019-06-19 16:53:26 +02:00
( DirectoryExists( aDstDirectory) or CreateDir( aDstDirectory) ) then
begin
i : = 0 ;
TempCount : = 0 ;
while ( i < aFileList. Count) do
begin
2019-11-10 18:23:39 +01:00
TempSrcPath : = IncludeTrailingPathDelimiter( aSrcDirectory) + aFileList[ i] ;
TempDstPath : = IncludeTrailingPathDelimiter( aDstDirectory) + aFileList[ i] ;
2019-06-19 16:53:26 +02:00
if FileExists( TempSrcPath) and RenameFile( TempSrcPath, TempDstPath) then inc( TempCount) ;
inc( i) ;
end ;
Result : = ( aFileList. Count = TempCount) ;
end ;
except
on e : exception do
if CustomExceptionHandler( 'MoveFileList' , e) then raise ;
end ;
end ;
2019-10-13 18:50:23 +02:00
function CefGetDataURI( const aString, aMimeType : ustring) : ustring;
var
TempUTF : AnsiString ;
begin
TempUTF : = UTF8Encode( aString) ;
if ( length( TempUTF) > 0 ) then
Result : = CefGetDataURI( @ TempUTF[ 1 ] , length( TempUTF) , aMimeType, 'utf-8' )
else
Result : = '' ;
end ;
function CefGetDataURI( aData : pointer ; aSize : integer ; const aMimeType, aCharset : ustring) : ustring;
begin
Result : = 'data:' + aMimeType;
if ( length( aCharset) > 0 ) then Result : = Result + ';charset=' + aCharset;
Result : = Result + ';base64,' + CefURIEncode( CefBase64Encode( aData, aSize) , false ) ;
end ;
2020-02-03 16:14:31 +01:00
2020-04-03 17:57:52 +02:00
function ValidCefWindowHandle( aHandle : TCefWindowHandle) : boolean ;
begin
2021-02-07 17:44:43 +01:00
{$IFDEF MACOS}
2020-04-03 17:57:52 +02:00
Result : = ( aHandle < > nil ) ;
{$ELSE}
Result : = ( aHandle < > 0 ) ;
{$ENDIF}
end ;
2020-05-05 18:10:33 +02:00
procedure InitializeWindowHandle( var aHandle : TCefWindowHandle) ;
begin
2021-02-07 17:44:43 +01:00
{$IFDEF MACOS}
2020-05-05 18:10:33 +02:00
aHandle : = nil ;
{$ELSE}
aHandle : = 0 ;
{$ENDIF}
end ;
2021-05-17 10:10:00 +02:00
function GetCommandLineSwitchValue( const aKey : string ; var aValue : ustring) : boolean ;
2021-05-16 19:42:25 +02:00
var
i, TempLen : integer ;
2021-05-17 10:10:00 +02:00
TempKey : string ;
2021-05-16 19:42:25 +02:00
begin
Result : = False ;
TempKey : = '--' + aKey + '=' ;
TempLen : = length( TempKey) ;
i : = paramCount;
while ( i > = 1 ) do
if ( CompareText( copy( paramstr( i) , 1 , TempLen) , TempKey) = 0 ) then
begin
2021-05-17 10:10:00 +02:00
{$IFDEF FPC}
aValue : = UTF8Decode( copy( paramstr( i) , succ( TempLen) , length( paramstr( i) ) ) ) ;
{$ELSE}
2021-05-16 19:42:25 +02:00
aValue : = copy( paramstr( i) , succ( TempLen) , length( paramstr( i) ) ) ;
2021-05-17 10:10:00 +02:00
{$ENDIF}
2021-05-16 19:42:25 +02:00
Result : = True ;
break;
end
else
dec( i) ;
end ;
2020-02-03 16:14:31 +01:00
end .