CEF4Delphi/source/uCEFMiscFunctions.pas
Salvador Diaz Fau 6178ab49a5 Update to CEF3.2924.1575
MiniBrowser : Addition of a preferences form, replacement of URLEdt by
URLCbx, addition of a custom scheme
TCEFApplication : Addition of 3 new properties : EnableSpellingService,
EnableMediaStream, EnableSpeechInput
TCEFChromium : Renamed internal procedures, addition of
UppdatePreferences and SavePreferences procedures, more checks in
doOnBeforeClose and doOnClose.
TCefChromiumWindow : WebBrowser_OnClose returns False by default
2017-03-15 14:53:45 +01:00

516 lines
17 KiB
ObjectPascal

// ************************************************************************
// ***************************** CEF4Delphi *******************************
// ************************************************************************
//
// CEF4Delphi is based on DCEF3 which uses CEF3 to embed a chromium-based
// browser in Delphi applications.
//
// The original license of DCEF3 still applies to CEF4Delphi.
//
// For more information about CEF4Delphi visit :
// https://www.briskbard.com/index.php?lang=en&pageid=cef
//
// Copyright © 2017 Salvador Díaz Fau. All rights reserved.
//
// ************************************************************************
// ************ vvvv Original license and comments below vvvv *************
// ************************************************************************
(*
* Delphi Chromium Embedded 3
*
* Usage allowed under the restrictions of the Lesser GNU General Public License
* or alternatively the restrictions of the Mozilla Public License 1.1
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
*
* Unit owner : Henri Gourvest <hgourvest@gmail.com>
* Web site : http://www.progdigy.com
* Repository : http://code.google.com/p/delphichromiumembedded/
* Group : http://groups.google.com/group/delphichromiumembedded
*
* Embarcadero Technologies, Inc is not permitted to use or redistribute
* this source code without explicit permission.
*
*)
unit uCEFMiscFunctions;
{$IFNDEF CPUX64}
{$ALIGN ON}
{$MINENUMSIZE 4}
{$ENDIF}
{$I cef.inc}
interface
uses
{$IFDEF DELPHI16_UP}
WinApi.Windows, System.Classes, System.SysUtils,
{$ELSE}
Windows, Classes, SysUtils,
{$ENDIF}
uCEFTypes, uCEFInterfaces, uCEFLibFunctions, uCEFResourceHandler;
const
Kernel32DLL = 'kernel32.dll';
procedure CefStringListToStringList(var aSrcSL : TCefStringList; var aDstSL : TStringList); overload;
procedure CefStringListToStringList(var aSrcSL : TCefStringList; var aDstSL : TStrings); overload;
function CefColorGetA(color: TCefColor): Byte;
function CefColorGetR(color: TCefColor): byte;
function CefColorGetG(color: TCefColor): Byte;
function CefColorGetB(color: TCefColor): Byte;
function CefColorSetARGB(a, r, g, b: Byte): TCefColor;
function CefInt64Set(int32_low, int32_high: Integer): Int64;
function CefInt64GetLow(const int64_val: Int64): Integer;
function CefInt64GetHigh(const int64_val: Int64): Integer;
function CefGetObject(ptr: Pointer): TObject;
function CefGetData(const i: ICefBase): Pointer;
function CefStringAlloc(const str: ustring): TCefString;
function CefStringClearAndGet(var str: TCefString): ustring;
function CefString(const str: ustring): TCefString; overload;
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);
function CefExecuteProcess(var app : ICefApp; aWindowsSandboxInfo : Pointer = nil) : integer;
function CefRegisterExtension(const name, code: ustring; const Handler: ICefv8Handler): Boolean;
procedure CefPostTask(ThreadId: TCefThreadId; const task: ICefTask);
procedure CefPostDelayedTask(ThreadId: TCefThreadId; const task: ICefTask; delayMs: Int64);
function CefTimeToSystemTime(const dt: TCefTime): TSystemTime;
function SystemTimeToCefTime(const dt: TSystemTime): TCefTime;
function CefTimeToDateTime(const dt: TCefTime): TDateTime;
function DateTimeToCefTime(dt: TDateTime): TCefTime;
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;
procedure WindowInfoAsChild(var aWindowInfo : TCefWindowInfo; aParent : THandle; aRect : TRect; const aWindowName : string = '');
procedure WindowInfoAsPopUp(var aWindowInfo : TCefWindowInfo; aParent : THandle; const aWindowName : string = '');
procedure WindowInfoAsWindowless(var aWindowInfo : TCefWindowInfo; aParent : THandle; aTransparent : boolean; const aWindowName : string = '');
function TzSpecificLocalTimeToSystemTime(lpTimeZoneInformation: PTimeZoneInformation; lpLocalTime, lpUniversalTime: PSystemTime): BOOL; stdcall; external Kernel32DLL;
function SystemTimeToTzSpecificLocalTime(lpTimeZoneInformation: PTimeZoneInformation; lpUniversalTime, lpLocalTime: PSystemTime): BOOL; stdcall; external Kernel32DLL;
function CefIsCertStatusError(Status : TCefCertStatus) : boolean;
function CefIsCertStatusMinorError(Status : TCefCertStatus) : boolean;
function CefCrashReportingEnabled : boolean;
procedure CefSetCrashKeyValue(const aKey, aValue : ustring);
procedure CefLog(const aFile : string; aLine, aSeverity : integer; const aMessage : string);
procedure OutputDebugMessage(const aMessage : string);
function CefRegisterSchemeHandlerFactory(const SchemeName, HostName: ustring; const handler: TCefResourceHandlerClass): Boolean; overload;
function CefRegisterSchemeHandlerFactory(const SchemeName, HostName: ustring; const factory: ICefSchemeHandlerFactory): Boolean; overload;
function CefClearSchemeHandlerFactories: Boolean;
function CefAddCrossOriginWhitelistEntry(const SourceOrigin, TargetProtocol, TargetDomain: ustring; AllowTargetSubdomains: Boolean): Boolean;
function CefRemoveCrossOriginWhitelistEntry(const SourceOrigin, TargetProtocol, TargetDomain: ustring; AllowTargetSubdomains: Boolean): Boolean;
function CefClearCrossOriginWhitelist: Boolean;
implementation
uses
uCEFConstants, uCEFApplication, uCEFSchemeHandlerFactory;
function CefColorGetA(color: TCefColor): Byte;
begin
Result := (color shr 24) and $FF;
end;
function CefColorGetR(color: TCefColor): byte;
begin
Result := (color shr 16) 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 24) or (r shl 16) or (g shl 8) or b;
end;
function CefInt64Set(int32_low, int32_high: Integer): Int64;
begin
Result := int32_low or (int32_high shl 32);
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 32) and $FFFFFFFF;
end;
procedure CefStringListToStringList(var aSrcSL : TCefStringList; var aDstSL : TStringList);
begin
CefStringListToStringList(aSrcSL, TStrings(aDstSL));
end;
procedure CefStringListToStringList(var aSrcSL : TCefStringList; var aDstSL : TStrings);
var
i, j : NativeUInt;
TempString : TCefString;
begin
if (aSrcSL <> nil) and (aDstSL <> nil) then
begin
i := 0;
j := pred(cef_string_list_size(aSrcSL));
while (i < j) do
begin
FillChar(TempString, SizeOf(TempString), 0);
cef_string_list_value(aSrcSL, i, @TempString);
aDstSL.Add(CefStringClearAndGet(TempString));
inc(i);
end;
end;
end;
function CefStringClearAndGet(var str: TCefString): ustring;
begin
Result := CefString(@str);
cef_string_utf16_clear(@str);
end;
function CefGetObject(ptr: Pointer): TObject; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF}
begin
Dec(PByte(ptr), SizeOf(Pointer));
Result := TObject(PPointer(ptr)^);
end;
function CefGetData(const i: ICefBase): 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
if (str <> nil) then
SetString(Result, str.str, str.length)
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
if (str <> nil) then cef_string_utf16_clear(str);
end;
procedure CefStringSet(const str: PCefString; const value: ustring);
begin
if (str <> nil) then cef_string_utf16_set(PWideChar(value), Length(value), str, 1);
end;
function CefStringFreeAndGet(const str: PCefStringUserFree): ustring;
begin
if (str <> nil) then
begin
Result := CefString(PCefString(str));
cef_string_userfree_utf16_free(str);
end
else
Result := '';
end;
function CefStringAlloc(const str: ustring): TCefString;
begin
FillChar(Result, SizeOf(Result), 0);
if (str <> '') then cef_string_wide_to_utf16(PWideChar(str), Length(str), @Result);
end;
procedure _free_string(str: PChar16); stdcall;
begin
if (str <> nil) then FreeMem(str);
end;
function CefUserFreeString(const str: ustring): PCefStringUserFree;
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;
function CefExecuteProcess(var app : ICefApp; aWindowsSandboxInfo : Pointer) : integer;
begin
Result := cef_execute_process(@HInstance, CefGetData(app), aWindowsSandboxInfo);
end;
function CefRegisterExtension(const name, code: ustring; const Handler: ICefv8Handler): Boolean;
var
n, c : TCefString;
begin
n := CefString(name);
c := CefString(code);
Result := cef_register_extension(@n, @c, CefGetData(handler)) <> 0;
end;
procedure CefPostTask(ThreadId: TCefThreadId; const task: ICefTask);
begin
cef_post_task(ThreadId, CefGetData(task));
end;
procedure CefPostDelayedTask(ThreadId: TCefThreadId; const task: ICefTask; delayMs: Int64);
begin
cef_post_delayed_task(ThreadId, CefGetData(task), delayMs);
end;
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;
end;
function CefTimeToDateTime(const dt: TCefTime): TDateTime;
var
st: TSystemTime;
begin
st := CefTimeToSystemTime(dt);
SystemTimeToTzSpecificLocalTime(nil, @st, @st);
Result := SystemTimeToDateTime(st);
end;
function DateTimeToCefTime(dt: TDateTime): TCefTime;
var
st: TSystemTime;
begin
DateTimeToSystemTime(dt, st);
TzSpecificLocalTimeToSystemTime(nil, @st, @st);
Result := SystemTimeToCefTime(st);
end;
function cef_string_wide_copy(const src: PWideChar; src_len: NativeUInt; output: PCefStringWide): Integer;
begin
Result := cef_string_wide_set(src, src_len, output, ord(True));
end;
function cef_string_utf8_copy(const src: PAnsiChar; src_len: NativeUInt; output: PCefStringUtf8): Integer;
begin
Result := cef_string_utf8_set(src, src_len, output, ord(True));
end;
function cef_string_utf16_copy(const src: PChar16; src_len: NativeUInt; output: PCefStringUtf16): Integer;
begin
Result := cef_string_utf16_set(src, src_len, output, ord(True));
end;
function cef_string_copy(const src: PCefChar; src_len: NativeUInt; output: PCefString): Integer;
begin
Result := cef_string_utf16_set(src, src_len, output, ord(True));
end;
procedure WindowInfoAsChild(var aWindowInfo : TCefWindowInfo; aParent : THandle; aRect : TRect; const aWindowName : string);
begin
aWindowInfo.ex_style := 0;
aWindowInfo.window_name := CefString(aWindowName);
aWindowInfo.style := WS_CHILD or WS_VISIBLE or WS_CLIPCHILDREN or WS_CLIPSIBLINGS or WS_TABSTOP;
aWindowInfo.x := aRect.left;
aWindowInfo.y := aRect.top;
aWindowInfo.width := aRect.right - aRect.left;
aWindowInfo.height := aRect.bottom - aRect.top;
aWindowInfo.parent_window := aParent;
aWindowInfo.menu := 0;
aWindowInfo.windowless_rendering_enabled := ord(False);
aWindowInfo.transparent_painting_enabled := ord(False);
aWindowInfo.window := 0;
end;
procedure WindowInfoAsPopUp(var aWindowInfo : TCefWindowInfo; aParent : THandle; const aWindowName : string);
begin
aWindowInfo.ex_style := 0;
aWindowInfo.window_name := CefString(aWindowName);
aWindowInfo.style := WS_OVERLAPPEDWINDOW or WS_CLIPCHILDREN or WS_CLIPSIBLINGS or WS_VISIBLE;
aWindowInfo.x := integer(CW_USEDEFAULT);
aWindowInfo.y := integer(CW_USEDEFAULT);
aWindowInfo.width := integer(CW_USEDEFAULT);
aWindowInfo.height := integer(CW_USEDEFAULT);
aWindowInfo.parent_window := aParent;
aWindowInfo.menu := 0;
aWindowInfo.windowless_rendering_enabled := ord(False);
aWindowInfo.transparent_painting_enabled := ord(False);
aWindowInfo.window := 0;
end;
procedure WindowInfoAsWindowless(var aWindowInfo : TCefWindowInfo; aParent : THandle; aTransparent : boolean; const aWindowName : string);
begin
aWindowInfo.ex_style := 0;
aWindowInfo.window_name := CefString(aWindowName);
aWindowInfo.style := 0;
aWindowInfo.x := 0;
aWindowInfo.y := 0;
aWindowInfo.width := 0;
aWindowInfo.height := 0;
aWindowInfo.parent_window := aParent;
aWindowInfo.menu := 0;
aWindowInfo.windowless_rendering_enabled := ord(True);
aWindowInfo.transparent_painting_enabled := ord(aTransparent);
aWindowInfo.window := 0;
end;
function CefIsCertStatusError(Status : TCefCertStatus) : boolean;
begin
Result := (cef_is_cert_status_error(Status) <> 0);
end;
function CefIsCertStatusMinorError(Status : TCefCertStatus) : boolean;
begin
Result := (cef_is_cert_status_minor_error(Status) <> 0);
end;
function CefCrashReportingEnabled : boolean;
begin
Result := (cef_crash_reporting_enabled <> 0);
end;
procedure CefSetCrashKeyValue(const aKey, aValue : ustring);
var
TempKey, TempValue : TCefString;
begin
TempKey := CefString(aKey);
TempValue := CefString(aValue);
cef_set_crash_key_value(@TempKey, @TempValue);
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;
procedure OutputDebugMessage(const aMessage : string);
const
DEFAULT_LINE = 1;
begin
{$IFDEF DEBUG}
OutputDebugString({$IFDEF DELPHI12_UP}PWideChar{$ELSE}PAnsiChar{$ENDIF}(aMessage + chr(0)));
if (GlobalCEFApp <> nil) and GlobalCEFApp.LibLoaded then
CefLog('CEF4Delphi', DEFAULT_LINE, CEF_LOG_SEVERITY_ERROR, aMessage);
{$ENDIF}
end;
function CefRegisterSchemeHandlerFactory(const SchemeName, HostName: ustring;
const handler: TCefResourceHandlerClass): Boolean;
var
s, h: TCefString;
begin
s := CefString(SchemeName);
h := CefString(HostName);
Result := cef_register_scheme_handler_factory(
@s,
@h,
CefGetData(TCefSchemeHandlerFactoryOwn.Create(handler) as ICefBase)) <> 0;
end;
function CefRegisterSchemeHandlerFactory(const SchemeName, HostName: ustring;
const factory: ICefSchemeHandlerFactory): Boolean;
var
s, h: TCefString;
begin
s := CefString(SchemeName);
h := CefString(HostName);
Result := cef_register_scheme_handler_factory(
@s,
@h,
CefGetData(factory as ICefBase)) <> 0;
end;
function CefClearSchemeHandlerFactories: Boolean;
begin
Result := cef_clear_scheme_handler_factories <> 0;
end;
function CefAddCrossOriginWhitelistEntry(const SourceOrigin, TargetProtocol,
TargetDomain: ustring; AllowTargetSubdomains: Boolean): Boolean;
var
so, tp, td: TCefString;
begin
so := CefString(SourceOrigin);
tp := CefString(TargetProtocol);
td := CefString(TargetDomain);
Result := cef_add_cross_origin_whitelist_entry(@so, @tp, @td, Ord(AllowTargetSubdomains)) <> 0;
end;
function CefRemoveCrossOriginWhitelistEntry(
const SourceOrigin, TargetProtocol, TargetDomain: ustring;
AllowTargetSubdomains: Boolean): Boolean;
var
so, tp, td: TCefString;
begin
so := CefString(SourceOrigin);
tp := CefString(TargetProtocol);
td := CefString(TargetDomain);
Result := cef_remove_cross_origin_whitelist_entry(@so, @tp, @td, Ord(AllowTargetSubdomains)) <> 0;
end;
function CefClearCrossOriginWhitelist: Boolean;
begin
Result := cef_clear_cross_origin_whitelist <> 0;
end;
end.