-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathEdge2.pas
More file actions
2507 lines (2328 loc) · 102 KB
/
Copy pathEdge2.pas
File metadata and controls
2507 lines (2328 loc) · 102 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
{*******************************************************}
{ }
{ CodeGear Delphi Runtime Library }
{ }
{ Copyright(c) 1995-2024 Embarcadero Technologies, Inc. }
{ All rights reserved }
{ }
{ Copyright and license exceptions noted in source }
{ }
{*******************************************************}
unit Edge2;
interface
uses
System.Classes, System.Win.ComObj, System.Generics.Collections, System.SyncObjs,
Vcl.Controls, Winapi.Windows, Winapi.Messages, Winapi.WebView2, WebView2Extended;
type
TCustomEdgeBrowser = class;
// Microsoft's default implementation of ICoreWebView2EnvironmentOptions et al is in WebView2EnvironmentOptions.h
TCoreWebView2EnvironmentOptionsExtended = class(TInterfacedObject, ICoreWebView2EnvironmentOptions, ICoreWebView2EnvironmentOptions6)
private
FAdditionalBrowserArguments: string;
FLanguage: string;
FTargetCompatibleBrowserVersion: string;
FAllowSingleSignOnUsingOSPrimaryAccount: BOOL;
FAreBrowserExtensionsEnabled: BOOL;
class function AllocCOMString(const DelphiString: string): PChar; static;
class function BOOLToInt(Value: BOOL): Integer; inline; static;
public
// ICoreWebView2EnvironmentOptions
function Get_AdditionalBrowserArguments(out value: PWideChar): HResult; stdcall;
function Set_AdditionalBrowserArguments(value: PWideChar): HResult; stdcall;
function Get_Language(out value: PWideChar): HResult; stdcall;
function Set_Language(value: PWideChar): HResult; stdcall;
function Get_TargetCompatibleBrowserVersion(out value: PWideChar): HResult; stdcall;
function Set_TargetCompatibleBrowserVersion(value: PWideChar): HResult; stdcall;
function Get_AllowSingleSignOnUsingOSPrimaryAccount(out allow: Integer): HResult; stdcall;
function Set_AllowSingleSignOnUsingOSPrimaryAccount(allow: Integer): HResult; stdcall;
// ICoreWebView2EnvironmentOptions6
function Get_AreBrowserExtensionsEnabled(out AreBrowserExtensionsEnabled: Integer): HResult; stdcall;
function Set_AreBrowserExtensionsEnabled(AreBrowserExtensionsEnabled: Integer): HResult; stdcall;
end;
/// <summary>
/// Event handler type for the OnContainsFullScreenElementChanged event
/// </summary>
TContainsFullScreenElementChangedEvent = procedure (Sender: TCustomEdgeBrowser; ContainsFullScreenElement: Boolean) of object;
// For C++Builder Classic compiler's benefit
TUInt64 = type UInt64;
/// <summary>
/// Event handler type for the OnContentLoading event
/// </summary>
TContentLoadingEvent = procedure (Sender: TCustomEdgeBrowser; IsErrorPage: Boolean; NavigationID: TUInt64) of object;
/// <summary>
/// Event handler type for the OnDevToolsProtocolEventReceived event
/// </summary>
TDevToolsProtocolEventReceivedEvent = procedure (Sender: TCustomEdgeBrowser; const CDPEventName, AParameterObjectAsJson: string) of object;
/// <summary>
/// Event handler type for the OnDocumentTitleChanged event
/// </summary>
TDocumentTitleChangedEvent = procedure (Sender: TCustomEdgeBrowser; const ADocumentTitle: string) of object;
/// <summary>
/// Type to wrap the WebView ICoreWebView2DownloadStartingEventArgs interface for the OnDownloadStarting event
/// </summary>
TDownloadStartingEventArgs = class(TInterfacedObject, ICoreWebView2DownloadStartingEventArgs)
private
FArgsInterface: ICoreWebView2DownloadStartingEventArgs;
public
constructor Create(const Args: ICoreWebView2DownloadStartingEventArgs);
property ArgsInterface: ICoreWebView2DownloadStartingEventArgs
read FArgsInterface implements ICoreWebView2DownloadStartingEventArgs;
end;
/// <summary>
/// Event handler type for the OnDownloadStarting event
/// </summary>
TDownloadStartingEvent = procedure (Sender: TCustomEdgeBrowser; Args: TDownloadStartingEventArgs) of object;
/// <summary>
/// Event handler type for the OnExecuteScript event
/// </summary>
TExecuteScriptEvent = procedure (Sender: TCustomEdgeBrowser; AResult: HResult; const AResultObjectAsJson: string) of object;
/// <summary>
/// Event handler type for the OnDocumentTitleChanged event
/// </summary>
THistoryChangedEvent = procedure (Sender: TCustomEdgeBrowser) of object;
/// <summary>
/// Type to wrap the WebView ICoreWebView2NavigationStartingEventArgs interface for the OnNavigationStarting and OnFrameNavigationStarting events
/// </summary>
TNavigationStartingEventArgs = class(TInterfacedObject, ICoreWebView2NavigationStartingEventArgs)
private
FArgsInterface: ICoreWebView2NavigationStartingEventArgs;
public
constructor Create(const Args: ICoreWebView2NavigationStartingEventArgs);
property ArgsInterface: ICoreWebView2NavigationStartingEventArgs
read FArgsInterface implements ICoreWebView2NavigationStartingEventArgs;
end;
/// <summary>
/// Event handler type for the OnNavigationStarting and OnFrameNavigationStarting events
/// </summary>
TNavigationStartingEvent = procedure (Sender: TCustomEdgeBrowser; Args: TNavigationStartingEventArgs) of object;
/// <summary>
/// Event handler type for the OnNavigationCompleted and OnFrameNavigationCompleted events
/// </summary>
TNavigationCompletedEvent = procedure (Sender: TCustomEdgeBrowser; IsSuccess: Boolean; WebErrorStatus: COREWEBVIEW2_WEB_ERROR_STATUS) of object;
/// <summary>
/// Type to wrap the WebView ICoreWebView2NewWindowRequestedEventArgs interface for the OnNewWindowRequested event
/// </summary>
TNewWindowRequestedEventArgs = class(TInterfacedObject, ICoreWebView2NewWindowRequestedEventArgs)
private
FArgsInterface: ICoreWebView2NewWindowRequestedEventArgs;
public
constructor Create(const Args: ICoreWebView2NewWindowRequestedEventArgs);
property ArgsInterface: ICoreWebView2NewWindowRequestedEventArgs
read FArgsInterface implements ICoreWebView2NewWindowRequestedEventArgs;
end;
/// <summary>
/// Event handler type for the OnNewWindowRequested event
/// </summary>
TNewWindowRequestedEvent = procedure (Sender: TCustomEdgeBrowser; Args: TNewWindowRequestedEventArgs) of object;
/// <summary>
/// Type to wrap the WebView ICoreWebView2PermissionRequestedEventArgs interface for the OnPermissionRequested event
/// </summary>
TPermissionRequestedEventArgs = class(TInterfacedObject, ICoreWebView2PermissionRequestedEventArgs)
private
FArgsInterface: ICoreWebView2PermissionRequestedEventArgs;
public
constructor Create(const Args: ICoreWebView2PermissionRequestedEventArgs);
property ArgsInterface: ICoreWebView2PermissionRequestedEventArgs
read FArgsInterface implements ICoreWebView2PermissionRequestedEventArgs;
end;
/// <summary>
/// Event handler type for the OnPermissionRequested event
/// </summary>
TPermissionRequestedEvent = procedure (Sender: TCustomEdgeBrowser; Args: TPermissionRequestedEventArgs) of object;
/// <summary>
/// Event handler type for the OnPrintCompleted event
/// </summary>
TPrintCompletedEvent = procedure (Sender: TCustomEdgeBrowser; ErrorCode: HResult; PrintStatus: COREWEBVIEW2_PRINT_STATUS) of object;
/// <summary>
/// Event handler type for the OnPrintToPDFCompleted event
/// </summary>
TPrintToPDFCompletedEvent = procedure (Sender: TCustomEdgeBrowser; ErrorCode: HResult; IsSuccessful: Boolean) of object;
/// <summary>
/// Event handler type for the OnProcessFailed event
/// </summary>
TProcessFailedEvent = procedure (Sender: TCustomEdgeBrowser; ProcessFailedKind: COREWEBVIEW2_PROCESS_FAILED_KIND) of object;
/// <summary>
/// Type to wrap the WebView ICoreWebView2ScriptDialogOpeningEventArgs interface for the OnScriptDialogOpening event
/// </summary>
TScriptDialogOpeningEventArgs = class(TInterfacedObject, ICoreWebView2ScriptDialogOpeningEventArgs)
private
FArgsInterface: ICoreWebView2ScriptDialogOpeningEventArgs;
public
constructor Create(const Args: ICoreWebView2ScriptDialogOpeningEventArgs);
property ArgsInterface: ICoreWebView2ScriptDialogOpeningEventArgs
read FArgsInterface implements ICoreWebView2ScriptDialogOpeningEventArgs;
end;
/// <summary>
/// Event handler type for the OnScriptDialogOpening event
/// </summary>
TScriptDialogOpeningEvent = procedure (Sender: TCustomEdgeBrowser; Args: TScriptDialogOpeningEventArgs) of object;
/// <summary>
/// Event handler type for the OnSourceChanged event
/// </summary>
TSourceChangedEvent = procedure (Sender: TCustomEdgeBrowser; IsNewDocument: Boolean) of object;
/// <summary>
/// Event handler type for the OnCreateWebViewCompleted and OnCapturePreviewCompleted events
/// </summary>
TWebViewStatusEvent = procedure (Sender: TCustomEdgeBrowser; AResult: HResult) of object;
/// <summary>
/// Type to wrap the WebView ICoreWebView2WebMessageReceivedEventArgs interface for the OnWebMessageReceived event
/// </summary>
TWebMessageReceivedEventArgs = class(TInterfacedObject, ICoreWebView2WebMessageReceivedEventArgs)
private
FArgsInterface: ICoreWebView2WebMessageReceivedEventArgs;
public
constructor Create(const Args: ICoreWebView2WebMessageReceivedEventArgs);
property ArgsInterface: ICoreWebView2WebMessageReceivedEventArgs
read FArgsInterface implements ICoreWebView2WebMessageReceivedEventArgs;
end;
/// <summary>
/// Event handler type for the OnWebMessageReceived event
/// </summary>
TWebMessageReceivedEvent = procedure (Sender: TCustomEdgeBrowser; Args: TWebMessageReceivedEventArgs) of object;
/// <summary>
/// Type to wrap the WebView ICoreWebView2WebResourceRequestedEventArgs interface for the OnWebResourceRequested event
/// </summary>
TWebResourceRequestedEventArgs = class(TInterfacedObject, ICoreWebView2WebResourceRequestedEventArgs)
private
FArgsInterface: ICoreWebView2WebResourceRequestedEventArgs;
public
constructor Create(const Args: ICoreWebView2WebResourceRequestedEventArgs);
property ArgsInterface: ICoreWebView2WebResourceRequestedEventArgs
read FArgsInterface implements ICoreWebView2WebResourceRequestedEventArgs;
end;
/// <summary>
/// Event handler type for the OnWebResourceRequested event
/// </summary>
TWebResourceRequestedEvent = procedure (Sender: TCustomEdgeBrowser; Args: TWebResourceRequestedEventArgs) of object;
/// <summary>
/// Event handler type for the OnZoomFactorChanged event
/// </summary>
TZoomFactorChangedEvent = procedure (Sender: TCustomEdgeBrowser; AZoomFactor: Double) of object;
/// <summary>
/// VCL component base class to allow browsing by use of the Edge WebView2 browser control
/// </summary>
TCustomEdgeBrowser = class(TWinControl, ICoreWebView2PrintCompletedHandler, ICoreWebView2PrintToPdfCompletedHandler)
public
type
/// <summary>
/// Enumerated type to represent the possible life cycle stages of the underlying Edge WebView control
/// </summary>
TBrowserControlState = (None, Creating, Created, Failed);
/// <summary>
/// Enumerated type to represent the possible print dialog shown by ShowPrintUI
/// </summary>
TPrintUIDialogKind = (Browser, System);
private
FBrowserControlState: TBrowserControlState;
FWebViewEnvironment: ICoreWebView2Environment;
FWebViewController: ICoreWebView2Controller;
FWebView: ICoreWebView2;
FWebView2: ICoreWebView2_2;
FWebView3: ICoreWebView2_3;
FWebView4: ICoreWebView2_4;
FCoreWebViewProfile: ICoreWebView2Profile;
FCoreWebViewProfile7: ICoreWebView2Profile7;
FWebViewSettings: ICoreWebView2Settings;
FSizeRatio: Double;
FLastErrorCode: HResult;
FWebViewFocusEventActive: Boolean;
FLastURI: string;
FCritSec: TCriticalSection;
FBrowserExecutableFolder: string;
FUserDataFolder: string;
FInternalClose: Boolean;
FAdditionalBrowserArguments: string;
FLanguage: string;
FTargetCompatibleBrowserVersion: string;
FAllowSingleSignOnUsingOSPrimaryAccount: Boolean;
FAreBrowserExtensionsEnabled: Boolean;
// WebView event tokens
FAcceleratorKeyPressedToken: EventRegistrationToken;
FContainsFullScreenElementChangedToken: EventRegistrationToken;
FContentLoadingToken: EventRegistrationToken;
FDocumentTitleChangedToken: EventRegistrationToken;
FDownloadStartingToken: EventRegistrationToken;
FFrameNavigationStartingToken: EventRegistrationToken;
FFrameNavigationCompletedToken: EventRegistrationToken;
FGotFocusToken: EventRegistrationToken;
FHistoryChangedToken: EventRegistrationToken;
FLostFocusToken: EventRegistrationToken;
FMoveFocusRequestedToken: EventRegistrationToken;
FNavigationStartingToken: EventRegistrationToken;
FNavigationCompletedToken: EventRegistrationToken;
FNewWindowRequestedToken: EventRegistrationToken;
FPermissionRequestedToken: EventRegistrationToken;
FProcessFailedToken: EventRegistrationToken;
FScriptDialogOpeningToken: EventRegistrationToken;
FSourceChangedToken: EventRegistrationToken;
FWebResourceRequestedToken: EventRegistrationToken;
FWebMessageReceivedToken: EventRegistrationToken;
FWindowCloseRequestedToken: EventRegistrationToken;
FZoomFactorChangedToken: EventRegistrationToken;
FDevToolsProtocolEventReceivedTokenMap: TDictionary<string, EventRegistrationToken>;
// Events
FOnCapturePreviewCompleted: TWebViewStatusEvent;
FOnContainsFullScreenElementChanged: TContainsFullScreenElementChangedEvent;
FOnContentLoading: TContentLoadingEvent;
FOnCreateWebViewCompleted: TWebViewStatusEvent;
FOnDevToolsProtocolEventReceived: TDevToolsProtocolEventReceivedEvent;
FOnDocumentTitleChanged: TDocumentTitleChangedEvent;
FOnDownloadStarting: TDownloadStartingEvent;
FOnExecuteScript: TExecuteScriptEvent;
FOnFrameNavigationStarting: TNavigationStartingEvent;
FOnFrameNavigationCompleted: TNavigationCompletedEvent;
FOnHistoryChanged: THistoryChangedEvent;
FOnNavigationStarting: TNavigationStartingEvent;
FOnNavigationCompleted: TNavigationCompletedEvent;
FOnNewWindowRequested: TNewWindowRequestedEvent;
FOnPermissionRequested: TPermissionRequestedEvent;
FOnPrintCompleted: TPrintCompletedEvent;
FOnPrintToPDFCompleted: TPrintToPDFCompletedEvent;
FOnProcessFailed: TProcessFailedEvent;
FOnScriptDialogOpening: TScriptDialogOpeningEvent;
FOnSourceChanged: TSourceChangedEvent;
FOnWebMessageReceived: TWebMessageReceivedEvent;
FOnWebResourceRequested: TWebResourceRequestedEvent;
FOnWindowCloseRequested: TNotifyEvent;
FOnZoomFactorChanged: TZoomFactorChangedEvent;
function CreateEnvironmentCompleted(AResult: HResult; const AEnvironment: ICoreWebView2Environment): HResult; stdcall;
function CreateCoreWebView2ControllerCompleted(AResult: HResult; const ACreatedController: ICoreWebView2Controller): HResult; stdcall;
function GetBrowserProcessID: DWORD;
function GetBrowserVersionInfo: string;
function GetCanGoBack: Boolean;
function GetCanGoForward: Boolean;
function GetContainsFullScreenElement: Boolean;
function GetDocumentTitle: string;
function GetLocationURL: string;
function GetWebViewCreated: Boolean;
function GetZoomFactor: Double;
function ProcessHResult(AHResult: HResult): Boolean;
procedure SetSizeRatio(const Value: Double);
procedure SetZoomFactor(const Value: Double);
// WebView2 settings property getters/setters
function GetBuiltInErrorPageEnabled: Boolean;
function GetDefaultContextMenusEnabled: Boolean;
function GetDefaultScriptDialogsEnabled: Boolean;
function GetDevToolsEnabled: Boolean;
function GetScriptEnabled: Boolean;
function GetStatusBarEnabled: Boolean;
function GetWebMessageEnabled: Boolean;
function GetZoomControlEnabled: Boolean;
procedure SetBuiltInErrorPageEnabled(const Value: Boolean);
procedure SetDefaultContextMenusEnabled(const Value: Boolean);
procedure SetDefaultScriptDialogsEnabled(const Value: Boolean);
procedure SetDevToolsEnabled(const Value: Boolean);
procedure SetScriptEnabled(const Value: Boolean);
procedure SetStatusBarEnabled(const Value: Boolean);
procedure SetWebMessageEnabled(const Value: Boolean);
procedure SetZoomControlEnabled(const Value: Boolean);
procedure WaitForWebViewEvent(var EndSignal: boolean; Timeout: integer=-1);
// Implemented interface methods
function ICoreWebView2PrintCompletedHandler.Invoke = ICoreWebView2PrintCompletedHandlerInvoke;
function ICoreWebView2PrintCompletedHandlerInvoke(errorCode: HResult; printStatus: COREWEBVIEW2_PRINT_STATUS): HResult; stdcall;
function ICoreWebView2PrintToPdfCompletedHandler.Invoke = ICoreWebView2PrintToPdfCompletedHandlerInvoke;
function ICoreWebView2PrintToPdfCompletedHandlerInvoke(errorCode: HResult; isSuccessful: Integer): HResult; stdcall;
protected
procedure InitializeWebView;
procedure CreateWnd; override;
procedure DoEnter; override;
procedure Resize; override;
procedure CMSysCommand(var &Message: TWMSysCommand); message CM_SYSCOMMAND;
procedure CMParentVisibleChanged(var &Message: TMessage); message CM_PARENTVISIBLECHANGED;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
// Extensions
procedure AddExtension(ExtensionDirectoryPath: string);
procedure RemoveExtensionByName(ExtensionName: string);
procedure RemoveExtensionById(ExtensionName: string);
procedure DeleteAllExtensions;
function GetAllExtensions: TArray<string>;
function GetAllExtensionIDs: TArray<string>;
// Virtual hosts (used for setting local "site directories" as in a web server
function SetVirtualHostNameToFolderMapping(HostName: string; FolderPath: string;
AccessKind: COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND): boolean;
function ClearVirtualHostNameToFolderMapping(HostName: string): boolean;
/// <summary>
/// Adds a URI and resource context filter to the OnWebResourceRequested event
/// </summary>
procedure AddWebResourceRequestedFilter(const URL: string; ResourceContext: COREWEBVIEW2_WEB_RESOURCE_CONTEXT);
type
/// <summary>
/// The image format in which to save the captured preview (screenshot)
/// </summary>
TPreviewFormat = (PNG, JPEG);
/// <summary>
/// Capture an image of what the WebView control is displaying and save it in a file of a specified image format
/// </summary>
procedure CapturePreview(const AFilename: string; PreviewFormat: TPreviewFormat = PNG); overload;
/// <summary>
/// Capture an image of what the WebView control is displaying and write it to a stream
/// </summary>
procedure CapturePreview(Stream: TStream; PreviewFormat: TPreviewFormat = PNG); overload;
/// <summary>
/// Creates a print settings object for Print and printToPDF
/// </summary>
function CreatePrintSettings: ICoreWebView2PrintSettings;
/// <summary>
/// Starts the asynchronous exercise of creating the WebView control. Use the OnCreateWebViewCompleted event to
/// be notified of successful or unsuccessful completion.
/// </summary>
procedure CreateWebView;
/// <summary>
/// Close down the current WebView control
/// </summary>
procedure CloseWebView;
/// <summary>
/// Close down the current WebView control and ensure its process exits (either of its own accord within 2
/// seconds, otherwise by force)
/// </summary>
procedure CloseBrowserProcess;
/// <summary>
/// Execute JavaScript code from the javascript parameter in the current top level document rendered in the
/// WebView, even if ScriptEnabled is False
/// </summary>
procedure ExecuteScript(const JavaScript: string);
/// <summary>
/// Navigates to the previous page in the navigation history
/// </summary>
procedure GoBack;
/// <summary>
/// Navigates to the next page in the navigation history
/// </summary>
procedure GoForward;
/// <summary>
/// Cause a navigation of the top level document to the specified URI. If the underlying WebView2 control
/// has not yet been created then this call will initiate creation and then navigate to the URI.
/// </summary>
function Navigate(const AUri: string): Boolean;
/// <summary>
/// Initiates a navigation to AHTMLContent as source HTML of a new document
/// </summary>
function NavigateToString(const AHTMLContent: string): Boolean;
/// <summary>
/// Lets you provide post data or additional request headers during navigation. The headers in ARequest
/// override headers added by the WebView2 runtime except for Cookie headers.
/// The web resource request method must be GET or POST.
/// Any post data will be sent only if the method is POST and the URI scheme is HTTP or HTTPS
/// </summary>
function NavigateWithWebResourceRequest(const ARequest: ICoreWebView2WebResourceRequest): Boolean;
/// <summary>
/// Print the current web page asynchronously to the specified printer with the provided settings
/// </summary>
function Print(const PrintSettings: ICoreWebView2PrintSettings): Boolean;
/// <summary>
/// Print the current page to PDF asynchronously with the provided settings
/// </summary>
function PrintToPDF(const ResultFilePath: string; const PrintSettings: ICoreWebView2PrintSettings): Boolean;
/// <summary>
/// Opens the print dialog to print the current web page, where the parameter lets
/// you choose between the browser print preview dialog and the system print dialog
/// </summary>
function ShowPrintUI(PrintUIDialogKind: TPrintUIDialogKind): Boolean;
/// <summary>
/// Close down the current WebView control and initialise a new one
/// </summary>
procedure ReinitializeWebView;
/// <summary>
/// Close down the current WebView control along with the browser process behind it and initialise a new one
/// </summary>
procedure ReinitializeWebViewWithNewBrowser;
/// <summary>
/// Reload the current page
/// </summary>
procedure Refresh;
/// <summary>
/// Removes a matching WebResource filter that was previously added for the OnWebResourceRequested event
/// </summary>
procedure RemoveWebResourceRequestedFilter(const URL: string; ResourceContext: COREWEBVIEW2_WEB_RESOURCE_CONTEXT);
/// <summary>
/// Gives the input focus to the browser control if it has been created.
/// </summary>
procedure SetFocus; override;
/// <summary>
/// Stop all navigations and pending resource fetches
/// </summary>
procedure Stop;
/// <summary>
/// Subscribe to a Chrome DevTools Protocol event
/// </summary>
/// <remarks>
/// See <see href="https://chromedevtools.github.io/devtools-protocol/tot/" />
/// </remarks>
procedure SubscribeToCDPEvent(const CDPEventName: string);
/// <summary>
/// Indicates which place in the life cycle the underlying WebView control is at
/// </summary>
property BrowserControlState: TBrowserControlState read FBrowserControlState;
/// <summary>
/// Browser version info including channel name if it is not the stable channel
/// </summary>
property BrowserVersionInfo: string read GetBrowserVersionInfo;
/// <summary>
/// Returns the underlying process ID of the Edge browser if the WebView control has been set up, otherwise 0
/// </summary>
property BrowserProcessID: DWORD read GetBrowserProcessID;
/// <summary>
/// Returns the underlying ICoreWebView2 interface if the WebView control has been set up, otherwise nil
/// </summary>
property DefaultInterface: ICoreWebView2 read FWebView;
/// <summary>
/// Returns the underlying ICoreWebView2Controller interface if the WebView control has been set up, otherwise nil
/// </summary>
property ControllerInterface: ICoreWebView2Controller read FWebViewController;
/// <summary>
/// Returns the underlying ICoreWebView2Environment interface if the WebView control has been set up, otherwise
/// nil
/// </summary>
property EnvironmentInterface: ICoreWebView2Environment read FWebViewEnvironment;
/// <summary>
/// Returns the underlying ICoreWebView2Settings interface if the WebView control has been set up, otherwise nil
/// </summary>
property SettingsInterface: ICoreWebView2Settings read FWebViewSettings;
/// <summary>
/// If set this specifies the location of msedgewebview2.exe, used with WebView2 Fixed Version Distribution mode:
/// https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#fixed-version-distribution-mode
/// The value can contain environment variables surrounded by % signs, e.g. %LOCALAPPDATA%.
/// If not set this defaults to looking for an installed version of the WebView2 runtime or alternatively an
/// installation of Edge Canary.
/// Note that setting this property affects the next creation of the underlying WebView2 control. If this
/// component has already created a WebView2 control then setting this property will have no effect unless the
/// WebView2 control gets recreated (e.g. by ReinitializeWebView or ReinitializeWebViewWithNewBrowser).
/// If the path contains \Edge\Application\ then the WebView2 creation will fail.
/// </summary>
property BrowserExecutableFolder: string read FBrowserExecutableFolder write FBrowserExecutableFolder;
/// <summary>
/// If set this specifies the location of the user data folder, where Edge/WebView2 stores e.g. cookies,
/// permissions and cached resources.
/// The value can contain environment variables surrounded by % signs, e.g. %LOCALAPPDATA%.
/// If not set this defaults to the folder {your_exe_name}.WebView2 in the local app data folder.
/// If folder creation permission is not available to the process where the user data folder needs to be created
/// then the creation of the underlying WebView2 control can fail.
/// The application will need to take responsibility for cleaning up the user data folder when it is no longer
/// required.
/// Note that setting this property affects the next creation of the underlying WebView2 control. If this
/// component has already created a WebView2 control then setting this property will have no effect unless the
/// WebView2 control gets recreated (e.g. by ReinitializeWebView or ReinitializeWebViewWithNewBrowser).
/// </summary>
property UserDataFolder: string read FUserDataFolder write FUserDataFolder;
/// <summary>
/// Can we navigate to a previous page in the navigation history?
/// </summary>
property CanGoBack: Boolean read GetCanGoBack;
/// <summary>
/// Can we navigate to a next page in the navigation history?
/// </summary>
property CanGoForward: Boolean read GetCanGoForward;
/// <summary>
/// Indicates if the WebView contains a fullscreen HTML element
/// </summary>
property ContainsFullScreenElement: Boolean read GetContainsFullScreenElement;
/// <summary>
/// The title for the current top level document
/// </summary>
property DocumentTitle: string read GetDocumentTitle;
/// <summary>
/// The HResult code of the last internal WebView2 operation
/// </summary>
property LastErrorCode: HResult read FLastErrorCode;
/// <summary>
/// The URI of the current top level document
/// </summary>
property LocationURL: string read GetLocationURL;
/// <summary>
/// The size ratio for the WebView
/// </summary>
property SizeRatio: Double read FSizeRatio write SetSizeRatio;
/// <summary>
/// Indicates if the WebView control has been created
/// </summary>
property WebViewCreated: Boolean read GetWebViewCreated;
/// <summary>
/// The zoom factor for the WebView
/// </summary>
property ZoomFactor: Double read GetZoomFactor write SetZoomFactor;
// WebView2 creation environment options
/// <summary>
/// Command-line arguments passed to the browser process to change its behaviour. These are
/// Chromium command line switches to use during browser construction in a space-separated string,
/// e.g. for a proxy server and show a startup browser dialog:
/// --proxy-server=http://1.2.3.4:8888 --browser-startup-dialog
/// e.g. to run browser diagnostics:
/// --diagnostics
/// </summary>
/// <remarks>
/// For information on Chromium command-line switches see:
/// https://www.chromium.org/developers/how-tos/run-chromium-with-flags
/// </remarks>
property AdditionalBrowserArguments: string read FAdditionalBrowserArguments write FAdditionalBrowserArguments;
/// <summary>
/// Enable single sign on with Azure Active Directory (AAD) and personal Microsoft Account (MSA) resources inside
/// WebView
/// </summary>
property AllowSingleSignOnUsingOSPrimaryAccount: Boolean read FAllowSingleSignOnUsingOSPrimaryAccount write FAllowSingleSignOnUsingOSPrimaryAccount;
/// <summary>
/// Enable extensions support in the WebView.
/// </summary>
property AreBrowserExtensionsEnabled: Boolean read FAreBrowserExtensionsEnabled write FAreBrowserExtensionsEnabled;
/// <summary>
/// The default display language for WebView.
/// It is in the format of language[-country] where language is the 2-letter code from ISO 639
/// and country is the 2-letter code from ISO 3166
/// </summary>
property Language: string read FLanguage write FLanguage;
/// <summary>
/// The version of the WebView2 Runtime binaries required to be compatible with your app.
/// This is in the same format as the BrowserVersionInfo property.
/// The version of the WebView2 Runtime binaries actually used may be different from the specified
/// TargetCompatibleBrowserVersion. Verify the actual version using the BrowserVersionInfo property.
/// </summary>
/// <remarks>
/// Defaults to '117.0.2045.28', the minimum version for WebView2 SDK 1.0.2045.28, the SDK imported into
/// RAD Studio 12.0
/// </remarks>
property TargetCompatibleBrowserVersion: string read FTargetCompatibleBrowserVersion write FTargetCompatibleBrowserVersion;
// WebView2 settings - these properties cause an exception if the WebView control has not yet been instantiated
/// <summary>
/// Used to disable built in error page for navigation failure and render process failure.
/// </summary>
/// <remarks>
/// Causes an exception if the WebView control has not yet been instantiated
/// </remarks>
property BuiltInErrorPageEnabled: Boolean read GetBuiltInErrorPageEnabled write SetBuiltInErrorPageEnabled;
/// <summary>
/// Controls whether default context menus will be shown to user in WebView
/// </summary>
/// <remarks>
/// Causes an exception if the WebView control has not yet been instantiated
/// </remarks>
property DefaultContextMenusEnabled: Boolean read GetDefaultContextMenusEnabled write SetDefaultContextMenusEnabled;
/// <summary>
/// Controls whether OnScriptDialogOpening will fire when a JavaScript dialog shows
/// </summary>
/// <remarks>
/// Causes an exception if the WebView control has not yet been instantiated
/// </remarks>
property DefaultScriptDialogsEnabled: Boolean read GetDefaultScriptDialogsEnabled write SetDefaultScriptDialogsEnabled;
/// <summary>
/// Controls whether the user is able to use the context menu or keyboard shortcuts to open the DevTools window
/// </summary>
/// <remarks>
/// Causes an exception if the WebView control has not yet been instantiated
/// </remarks>
property DevToolsEnabled: Boolean read GetDevToolsEnabled write SetDevToolsEnabled;
/// <summary>
/// Controls if JavaScript execution is enabled in all future navigations in the WebView
/// </summary>
/// <remarks>
/// Causes an exception if the WebView control has not yet been instantiated
/// </remarks>
property ScriptEnabled: Boolean read GetScriptEnabled write SetScriptEnabled;
/// <summary>
/// Controls whether the status bar will be displayed
/// </summary>
/// <remarks>
/// Causes an exception if the WebView control has not yet been instantiated
/// </remarks>
property StatusBarEnabled: Boolean read GetStatusBarEnabled write SetStatusBarEnabled;
/// <summary>
/// Controls whether WebMessages will be received when loading a new HTML document
/// </summary>
/// <remarks>
/// Causes an exception if the WebView control has not yet been instantiated
/// </remarks>
property WebMessageEnabled: Boolean read GetWebMessageEnabled write SetWebMessageEnabled;
/// <summary>
/// Controls whether the user can impact the zoom of the WebView.
/// </summary>
/// <remarks>
/// Causes an exception if the WebView control has not yet been instantiated
/// </remarks>
property ZoomControlEnabled: Boolean read GetZoomControlEnabled write SetZoomControlEnabled;
// WebView2 events
property OnCapturePreviewCompleted: TWebViewStatusEvent read FOnCapturePreviewCompleted write FOnCapturePreviewCompleted;
property OnContainsFullScreenElementChanged: TContainsFullScreenElementChangedEvent read FOnContainsFullScreenElementChanged write FOnContainsFullScreenElementChanged;
property OnContentLoading: TContentLoadingEvent read FOnContentLoading write FOnContentLoading;
property OnCreateWebViewCompleted: TWebViewStatusEvent read FOnCreateWebViewCompleted write FOnCreateWebViewCompleted;
property OnDevToolsProtocolEventReceived: TDevToolsProtocolEventReceivedEvent read FOnDevToolsProtocolEventReceived write FOnDevToolsProtocolEventReceived;
property OnDocumentTitleChanged: TDocumentTitleChangedEvent read FOnDocumentTitleChanged write FOnDocumentTitleChanged;
property OnDownloadStarting: TDownloadStartingEvent read FOnDownloadStarting write FOnDownloadStarting;
property OnExecuteScript: TExecuteScriptEvent read FOnExecuteScript write FOnExecuteScript;
property OnFrameNavigationStarting: TNavigationStartingEvent read FOnFrameNavigationStarting write FOnFrameNavigationStarting;
property OnFrameNavigationCompleted: TNavigationCompletedEvent read FOnFrameNavigationCompleted write FOnFrameNavigationCompleted;
property OnHistoryChanged: THistoryChangedEvent read FOnHistoryChanged write FOnHistoryChanged;
property OnNavigationStarting: TNavigationStartingEvent read FOnNavigationStarting write FOnNavigationStarting;
property OnNavigationCompleted: TNavigationCompletedEvent read FOnNavigationCompleted write FOnNavigationCompleted;
property OnNewWindowRequested: TNewWindowRequestedEvent read FOnNewWindowRequested write FOnNewWindowRequested;
property OnPermissionRequested: TPermissionRequestedEvent read FOnPermissionRequested write FOnPermissionRequested;
property OnPrintCompleted: TPrintCompletedEvent read FOnPrintCompleted write FOnPrintCompleted;
property OnPrintToPDFCompleted: TPrintToPDFCompletedEvent read FOnPrintToPDFCompleted write FOnPrintToPDFCompleted;
property OnProcessFailed: TProcessFailedEvent read FOnProcessFailed write FOnProcessFailed;
property OnScriptDialogOpening: TScriptDialogOpeningEvent read FOnScriptDialogOpening write FOnScriptDialogOpening;
property OnSourceChanged: TSourceChangedEvent read FOnSourceChanged write FOnSourceChanged;
property OnWebMessageReceived: TWebMessageReceivedEvent read FOnWebMessageReceived write FOnWebMessageReceived;
property OnWebResourceRequested: TWebResourceRequestedEvent read FOnWebResourceRequested write FOnWebResourceRequested;
property OnWindowCloseRequested: TNotifyEvent read FOnWindowCloseRequested write FOnWindowCloseRequested;
property OnZoomFactorChanged: TZoomFactorChangedEvent read FOnZoomFactorChanged write FOnZoomFactorChanged;
end;
/// <summary>
/// VCL component to allow browsing by use of the Edge WebView2 browser control
/// </summary>
/// <remarks>
/// Be aware that many of the events are called from the Edge WebView2 control and
/// as such may well be called on a thread other than the main User Interface thread
/// </remarks>
TEdgeBrowser = class(TCustomEdgeBrowser)
published
property Align;
property Anchors;
property TabOrder;
property TabStop;
property OnEnter;
property OnExit;
// WebView2 creation environment options
/// <summary>
/// Command-line arguments passed to the browser process to change its behaviour. These are
/// Chromium command line switches to use during browser construction in a space-separated string,
/// e.g. for a proxy server and show a startup browser dialog:
/// --proxy-server=http://1.2.3.4:8888 --browser-startup-dialog
/// e.g. to run browser diagnostics:
/// --diagnostics
/// </summary>
/// <remarks>
/// For information on Chromium command-line switches see:
/// https://www.chromium.org/developers/how-tos/run-chromium-with-flags
/// </remarks>
property AdditionalBrowserArguments;
/// <summary>
/// Enable single sign on with Azure Active Directory (AAD) and personal Microsoft Account (MSA) resources inside
/// WebView
/// </summary>
property AllowSingleSignOnUsingOSPrimaryAccount;
/// <summary>
/// The default display language for WebView.
/// It is in the format of language[-country] where language is the 2-letter code from ISO 639
/// and country is the 2-letter code from ISO 3166
/// </summary>
property Language;
/// <summary>
/// The version of the WebView2 Runtime binaries required to be compatible with your app.
/// This is in the same format as the BrowserVersionInfo property.
/// The version of the WebView2 Runtime binaries actually used may be different from the specified
/// TargetCompatibleBrowserVersion. Verify the actual version using the BrowserVersionInfo property.
/// </summary>
/// <remarks>
/// Defaults to '117.0.2045.28', the minimum version for WebView2 SDK 1.0.2045.28, the SDK imported into
/// RAD Studio 12.0
/// </remarks>
property TargetCompatibleBrowserVersion;
/// <summary>
/// If set this specifies the location of msedgewebview2.exe, used with WebView2 Fixed Version Distribution mode:
/// https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#fixed-version-distribution-mode
/// The value can contain environment variables surrounded by % signs, e.g. %LOCALAPPDATA%.
/// If not set this defaults to looking for an installed version of the WebView2 runtime or alternatively an
/// installation of Edge Canary.
/// Note that setting this property affects the next creation of the underlying WebView2 control. If this
/// component has already created a WebView2 control then setting this property will have no effect unless the
/// WebView2 control gets recreated (e.g. by ReinitializeWebView or ReinitializeWebViewWithNewBrowser).
/// If the path contains \Edge\Application\ then the WebView2 creation will fail.
/// </summary>
property BrowserExecutableFolder;
/// <summary>
/// If set this specifies the location of the user data folder, where Edge/WebView2 stores e.g. cookies,
/// permissions and cached resources.
/// The value can contain environment variables surrounded by % signs, e.g. %LOCALAPPDATA%.
/// If not set this defaults to the folder {your_exe_name}.WebView2 in the local app data folder.
/// If folder creation permission is not available to the process where the user data folder needs to be created
/// then the creation of the underlying WebView2 control can fail.
/// The application will need to take responsibility for cleaning up the user data folder when it is no longer
/// required.
/// Note that setting this property affects the next creation of the underlying WebView2 control. If this
/// component has already created a WebView2 control then setting this property will have no effect unless the
/// WebView2 control gets recreated (e.g. by ReinitializeWebView or ReinitializeWebViewWithNewBrowser).
/// </summary>
property UserDataFolder;
/// <summary>
/// Fired when the captured screenshot of the WebView has been saved
/// </summary>
property OnCapturePreviewCompleted;
/// <summary>
/// Fired when the ContainsFullScreenElement property changes, which means that an HTML element inside the
/// WebView is entering or leaving fullscreen. The event handler can make the control larger or smaller as
/// required.
/// </summary>
property OnContainsFullScreenElementChanged;
/// <summary>
/// Fired before any content is loaded. This follows the OnNavigationStarting and OnSourceChanged events
/// and precedes the OnHistoryChanged and OnNavigationCompleted events.
/// </summary>
property OnContentLoading;
/// <summary>
/// Fired when the WebView control creation has completed, either successfully or unsuccessfully (for example
/// Edge is not installed or the WebView2 control cannot loaded)
/// </summary>
property OnCreateWebViewCompleted;
/// <summary>
/// Fired when a Chrome DevTools Protocol event, previously subscribed to with SubscribeToCDPEvent, occurs
/// </summary>
property OnDevToolsProtocolEventReceived;
/// <summary>
/// Fired when the DocumentTitle property of the WebView changes and may fire before or after the
/// OnNavigationCompleted event
/// </summary>
property OnDocumentTitleChanged;
/// <summary>
/// Fires when a download has begun, blocking the default download dialog but not blocking the download progress
/// </summary>
property OnDownloadStarting;
/// <summary>
/// Fires when script as invoked by ExecuteScript completes
/// </summary>
property OnExecuteScript;
/// <summary>
/// Fired when a child frame in the WebView requests permission to navigate to a different URI. This will fire
/// for redirects as well.
/// </summary>
property OnFrameNavigationStarting;
/// <summary>
/// Fired when a child frame in the WebView has completely loaded or loading stopped with error.
/// </summary>
property OnFrameNavigationCompleted;
/// <summary>
/// Fired on change of navigation history for the top level document. OnHistoryChanged fires after
/// OnSourceChanged and OnContentLoading
/// </summary>
property OnHistoryChanged;
/// <summary>
/// Fired when the WebView main frame requests permission to navigate to a different URI. This will fire for
/// redirects as well.
/// </summary>
property OnNavigationStarting;
/// <summary>
/// Fired when the WebView has completely loaded or loading stopped with error.
/// </summary>
property OnNavigationCompleted;
/// <summary>
/// OnNewWindowRequested fires when content inside the WebView requested to open a new window, such as through
/// window.open or through a context menu
/// </summary>
property OnNewWindowRequested;
/// <summary>
/// Fired when content in a WebView requests permission to access a privileged resource
/// </summary>
property OnPermissionRequested;
/// <summary>
/// Fired when a call to Print completes
/// </summary>
property OnPrintCompleted;
/// <summary>
/// Fired when a call to PrintToPDF completes
/// </summary>
property OnPrintToPDFCompleted;
/// <summary>
/// Fired when a WebView process terminated unexpectedly or become unresponsive
/// </summary>
property OnProcessFailed;
/// <summary>
/// Fired when a JavaScript dialog (alert, confirm, or prompt) will show for the Webview. This event only
/// fires if the DefaultScriptDialogsEnabled property is False. The ScriptDialogOpening event can be used
/// to suppress dialogs or replace default dialogs with custom dialogs.
/// </summary>
property OnScriptDialogOpening;
/// <summary>
/// Fired for navigating to a different site or fragment navigations. It will not fires for other types of
/// navigations such as page reloads. OnSourceChanged fires before OnContentLoading for navigation to a new
/// document.
/// </summary>
property OnSourceChanged;
/// <summary>
/// Fired when the WebMessageEnabled property is True and the top level document of the W webView calls
/// window.chrome.webview.postMessage
/// </summary>
property OnWebMessageReceived;
/// <summary>
/// Fired when the WebView is performing an HTTP request to a matching URL and resource context filter that was
/// added with AddWebResourceRequestedFilter. At least one filter must be added for the event to fire.
/// </summary>
property OnWebResourceRequested;
/// <summary>
/// Fires when content inside the WebView requested to close the window, such as after window.close is called.
/// The app should close the WebView and related app window if that makes sense to the app.
/// </summary>
property OnWindowCloseRequested;
/// <summary>
/// Fired when the ZoomFactor property of the WebView changes. The event could fire because the caller modified
/// the ZoomFactor property, or due to the user manually modifying the zoom, but not from a programmatic change.
/// </summary>
property OnZoomFactorChanged;
end;
/// <summary>
/// Exception type used to indicate an exceptional circumstance from within the TEdgeBrowser component
/// </summary>
EEdgeError = class(EOleSysError)
public
constructor Create(const Message: UnicodeString; ErrorCode: HRESULT);
constructor CreateRes(ResStringRec: PResStringRec; ErrorCode: HRESULT);
end;
implementation
uses
System.SysUtils, System.IOUtils, Winapi.ShLwApi, Winapi.ActiveX, Vcl.Forms,
Vcl.EdgeConst, Winapi.EdgeUtils;
type
TApplicationClass = class(TApplication);
{ TCustomEdgeBrowser }
constructor TCustomEdgeBrowser.Create(AOwner: TComponent);
const
CLocalAppData = '%LOCALAPPDATA%'; // Do not localize
CUserDatafolderSuffix = '.WebView2'; // Do not localize
// From WebView2EnvironmentOptions.h
CORE_WEBVIEW_TARGET_PRODUCT_VERSION =
//'84.0.488.0'; // minimum version for WebView2 SDK 0.9.488 - the Edge import for RAD Studio 10.4
//'101.0.1210.39'; // minimum version for WebView2 SDK 1.0.1210.39 - the Edge import in GetIT for RAD Studio 11
'117.0.2045.28'; // minimum version for WebView2 SDK 1.0.2045.28 - the Edge import for RAD Studio 12
begin
inherited;
FBrowserControlState := TBrowserControlState.None;
FCritSec := TCriticalSection.Create;
FDevToolsProtocolEventReceivedTokenMap := TDictionary<string, EventRegistrationToken>.Create;
FUserDataFolder := TPath.Combine(CLocalAppData, TPath.GetFileName(ParamStr(0) + CUserDatafolderSuffix));
FTargetCompatibleBrowserVersion := CORE_WEBVIEW_TARGET_PRODUCT_VERSION;
end;
procedure TCustomEdgeBrowser.DeleteAllExtensions;
begin
if FCoreWebViewProfile7 = nil then
Exit;
FCoreWebViewProfile7.GetBrowserExtensions(Callback<HResult, ICoreWebView2BrowserExtensionList>.CreateAs<ICoreWebView2ProfileGetBrowserExtensionsCompletedHandler>(
function(ErrorCode: HResult; List: ICoreWebView2BrowserExtensionList): HResult stdcall
begin
Result := S_OK;
var ACount: cardinal;
var Ext: ICoreWebView2BrowserExtension;
List.Get_Count(ACount);
for var I := 0 to ACount-1 do begin
List.GetValueAtIndex(I, Ext);
Ext.Remove(nil);
end;
end));
end;
destructor TCustomEdgeBrowser.Destroy;
begin
CloseWebView;
FDevToolsProtocolEventReceivedTokenMap.Free;
inherited;
FCritSec.Free;
end;
procedure TCustomEdgeBrowser.DoEnter;
begin
inherited;
if not FWebViewFocusEventActive and (FWebViewController <> nil) then
ProcessHResult(FWebViewController.MoveFocus(COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC));
end;
procedure TCustomEdgeBrowser.AddExtension(ExtensionDirectoryPath: string);
begin
if FCoreWebViewProfile7 = nil then
Exit;
FCoreWebViewProfile7.AddBrowserExtension(PChar(ExtensionDirectoryPath), Callback<HResult, ICoreWebView2BrowserExtension>.CreateAs<ICoreWebView2ProfileAddBrowserExtensionCompletedHandler>(
function(ErrorCode: HResult; Extension: ICoreWebView2BrowserExtension): HResult stdcall
begin
Result := S_OK;
end));
end;
procedure TCustomEdgeBrowser.AddWebResourceRequestedFilter(const URL: string;
ResourceContext: COREWEBVIEW2_WEB_RESOURCE_CONTEXT);
begin
if FWebView <> nil then
ProcessHResult(FWebView.AddWebResourceRequestedFilter(PChar(URL), ResourceContext));
end;
procedure TCustomEdgeBrowser.CapturePreview(const AFilename: string; PreviewFormat: TPreviewFormat);
begin
if FWebView = nil then
Exit;
var Stream: IStream;
if ProcessHResult(SHCreateStreamOnFile(PChar(AFilename), STGM_READWRITE or STGM_CREATE, Stream)) then
begin
var handler :=
function(AResult: HResult): HResult stdcall
begin