web-dev-qa-db-ja.com

Delphi / C ++ BuilderでのWebView(EdgeHTML)の使用

EdgeHTMLがWindows10のデスクトップ(Win32/Win64アプリケーション)で利用できるようになったことを正しく理解していますか?これらのブログ投稿によると:

https://blogs.windows.com/msedgedev/2018/05/09/modern-webview-winforms-wpf-apps/https://blogs.windows.com/msedgedev/2018/10/04/edgehtml-18-october-2018-update /https://docs.Microsoft.com/en-us/windows/communitytoolkit/controls/wpf-winforms/webview

Microsoftは、これまでデスクトップアプリでは利用できなかったEdgeHTML WebViewControl for Windowsデスクトップ(Win32)アプリを追加したようです(デスクトップアプリではTridentベースのMSHTMLコントロールのみが利用可能でした)。

これが当てはまる場合、Delphi/C++ Builderでこれを利用する可能性はありますか、それとも新しい更新で新しいTWebViewコントロールを待つ必要がありますか? of RAD Studio?可能であれば-見るべきコードサンプルはありますか(C++ BuilderまたはDelphi)?そして.NETの要件は、通常のWin32では利用できないことを意味しますか?/Win64アプリはRAD Studio?

8
Coder12345

WebViewコントロールはWinRTを介して提供され、.netに依存しません。通常のWin32アプリケーションから使用できます。

WinRT(Windowsランタイム)は、現在Windows 10でUWP(ユニバーサルWindowsプラットフォーム)としてブランド名が変更されており、COMの後継のようなものです。

COMと同様に、インターフェイスに大きく基づいており、使用可能なインターフェイスはタイプライブラリで定義されています。 WinRTの場合、タイプライブラリはWindowsシステムディレクトリの* .WinMDファイルに保存されます。 Edgeブラウザーを埋め込むために必要な機能を含むタイプライブラリはWindows.Web.winmdです。

DelphiはWinRTコンポーネントの使用をサポートしており、いくつかのタイプライブラリの翻訳と、WinRTで動作するいくつかの追加のヘルパー関数およびクラスが付属しています。

ただし、現在、WinMDファイルまたはWinMDファイルから派生したIDLファイルをDelphiコードに自動的に変換するツールはありません。 Delphiに付属していないWinRT機能を使用する場合は、タイプ定義をDelphiコードに手動で変換する必要があります。

WinRTは、Delphiでのジェネリックインターフェイスの動作方法と互換性のないジェネリックインターフェイス(型パラメータを持つインターフェイス)を多用します。これには、タイプ定義を変換するときに手動で調整する必要があります。

Windows Platform SDKをインストールすると、WinRTタイプライブラリのIDLおよびC++変換がDrive:\Windows Kits\10\Include\10.0.17134.0\winrtのようなディレクトリにあります。

これらのファイルをテンプレートとして使用して、組み込みEdgeブラウザーを使用する非常に基本的な概念実証Delphiプロジェクト(Delphi 10.2用)を作成しました。以下のコードを見つけることができます。これをテストするには、新しいVCLプロジェクトを作成し、コードを貼り付けて、FormCreateFormDestroy、およびFormResizeイベントをフォームに接続します。

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
  System.Types,
  Winapi.Winrt,
  System.Win.WinRT,
  WinAPI.Foundation,
  WinAPI.Foundation.Types;

const
  SWebViewControlProcess = 'Windows.Web.UI.Interop.WebViewControlProcess';

type
  // Interface with functionality to interact with WebBrowser Control
  // https://docs.Microsoft.com/en-us/uwp/api/windows.web.ui.iwebviewcontrol
  IWebViewControl = interface(IInspectable)
  ['{3F921316-BC70-4BDA-9136-C94370899FAB}']
    procedure Placeholder_SourceGet; safecall;
    procedure Placeholder_SourcePut; safecall;
    procedure Placeholder_DocumentTitle; safecall;
    procedure Placeholder_CanGoBack; safecall;
    procedure Placeholder_CanGoForward; safecall;
    procedure Placeholder_DefaultBackgroundColorPut; safecall;
    procedure Placeholder_DefaultBackgroundColorGet; safecall;
    procedure Placeholder_ContainsFullScreenElement; safecall;
    procedure Placeholder_Settings; safecall;
    procedure Placeholder_DeferredPermissionRequests; safecall;
    procedure Placeholder_GoForward; safecall;
    procedure Placeholder_GoBack; safecall;
    procedure Placeholder_Refresh; safecall;
    procedure Placeholder_Stop; safecall;
    procedure Navigate(source: IUriRuntimeClass); stdcall;
    procedure NavigateToString(text: HString); stdcall;
    // TODO: Declare further properties and functions of IWebViewControl
  end;

  IWebViewControlProcess = interface;

  // Declare  IWebViewControlSite
  IWebViewControlSite = interface(IInspectable)
  ['{133F47C6-12DC-4898-BD47-04967DE648BA}']
    function get_Process: IWebViewControlProcess; safecall;
    procedure put_Scale(value: Double); safecall;
    function get_Scale: Double; safecall;
    procedure put_Bounds(value: TRectF); safecall;
    function get_Bounds: TRectF; safecall;
    procedure put_IsVisible(value: Boolean); safecall;
    function get_IsVisible: Boolean; safecall;

    // TODO: Declare further properties and functions of IWebViewControlSite

    property Process: IWebViewControlProcess read get_Process;
    property Scale: Double read get_Scale write put_Scale;
    property Bounds: TRectF read get_Bounds write put_Bounds;
    property IsVisible: Boolean read get_IsVisible write put_IsVisible;
  end;

  // types for reacting to when the WebView has finished initialization
  IAsyncOperation_1__IWebViewControl = interface;

  IAsyncOperationCompletedHandler_1__IWebViewControl = interface(IUnknown)
  ['{d61963d6-806d-50a8-a81c-75d9356ad5d7}']
    procedure Invoke(asyncInfo: IAsyncOperation_1__IWebViewControl; asyncStatus: AsyncStatus); safecall;
  end;

  IAsyncOperation_1__IWebViewControl = interface(IInspectable)
  ['{ac3d28ac-8362-51c6-b2cc-16f3672758f1}']
    procedure put_Completed(handler: IAsyncOperationCompletedHandler_1__IWebViewControl); safecall;
    function get_Completed: IAsyncOperationCompletedHandler_1__IWebViewControl; safecall;
    function GetResults: IWebViewControl; safecall;
    property Completed: IAsyncOperationCompletedHandler_1__IWebViewControl read get_Completed write put_Completed;
  end;

  TWebViewControlCompleted = procedure(asyncInfo: IAsyncOperation_1__IWebViewControl; aasyncStatus: AsyncStatus) of object;

  TWebViewControlCompletedHandler = class(TInspectableObject,
      IAsyncOperationCompletedHandler_1__IWebViewControl
      )
  private
    FEvent: TWebViewControlCompleted;
  public
    procedure Invoke(asyncInfo: IAsyncOperation_1__IWebViewControl; aasyncStatus: AsyncStatus); safecall;
    constructor Create(AEvent: TWebViewControlCompleted);
  end;

   // The interface for interacting with the process hosting the web view control
   // https://docs.Microsoft.com/en-us/uwp/api/windows.web.ui.interop.webviewcontrolprocess
  [WinRTClassNameAttribute(SWebViewControlProcess)]
  IWebViewControlProcess = interface(IInspectable)
  ['{02C723EC-98D6-424A-B63E-C6136C36A0F2}']
    function get_ProcessId: Cardinal; safecall;
    function get_EnterpriseId: HSTRING; safecall;
    function get_IsPrivateNetworkClientServerCapabilityEnabled: Boolean; safecall;
    function CreateWebViewControlAsync(hostWindowHandle: Int64; bounds: TRectF): IAsyncOperation_1__IWebViewControl; safecall;
    procedure Placeholder_GetWebViewControls; safecall;
    procedure Terminate; safecall;

    property ProcessId: Cardinal read get_ProcessId;
    property EnterpriseId: HSTRING read get_EnterpriseId;
    property IsPrivateNetworkClientServerCapabilityEnabled: Boolean read get_IsPrivateNetworkClientServerCapabilityEnabled;

    // TODO:
    //[eventadd] HRESULT ProcessExited([in] Windows.Foundation.TypedEventHandler<Windows.Web.UI.Interop.WebViewControlProcess*, IInspectable*>* handler, [out] [retval] EventRegistrationToken* token);
    //[eventremove] HRESULT ProcessExited([in] EventRegistrationToken token);
  end;

  // The CoClass to create an IWebViewControlProcess instance
  TWebViewControlProcess = class(TWinRTGenericImportI<IWebViewControlProcess>)
  end;

type

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormResize(Sender: TObject);
  private
    { Private declarations }
    FProcess: IWebViewControlProcess;
    FBrowser: IWebViewControl;
    FBrowserSite: IWebViewControlSite;
    procedure WebViewCompleted(asyncInfo: IAsyncOperation_1__IWebViewControl; aasyncStatus: AsyncStatus);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  Rect: TRectF;
  AsyncOperation: IAsyncOperation_1__IWebViewControl;
    CompletedHandler: IAsyncOperationCompletedHandler_1__IWebViewControl;
begin
  CompletedHandler:=TWebViewControlCompletedHandler.Create(WebViewCompleted);

  // Size for browser
  Rect:= TRectF.Create(0, 0, ClientWidth, ClientHeight);

  // Create hosting process
  FProcess:= TWebViewControlProcess.Create();

  // Create WebView Control
  AsyncOperation:= FProcess.CreateWebViewControlAsync(self.Handle, Rect);

  // We will get notified when the control creation is finished
  AsyncOperation.Completed:= CompletedHandler;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  // If there is a hosting process, then terminate it
  if Assigned(FProcess) then
  begin
    FProcess.Terminate;
  end;
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  if Assigned(FBrowserSite) then
  begin
    FBrowserSite.Bounds := TRectF.Create(0,0,ClientWidth, ClientHeight);
  end;
end;

procedure TForm1.WebViewCompleted(
  asyncInfo: IAsyncOperation_1__IWebViewControl;
  aasyncStatus: AsyncStatus);
var
  WinS: TWindowsString;
  Uri: IUriRuntimeClass;
begin
  // Initializing the WebView control was successful

  // Remember reference to control
  FBrowser:= asyncInfo.GetResults();
  FBrowserSite := FBrowser as IWebViewControlSite;

  // Load web page into control
  WinS:= TWindowsString.Create('http://www.whatismybrowser.com');
  Uri:= TUri.CreateUri(WinS);
  FBrowser.Navigate(Uri);
end;

{ TWebViewControlCompletedHandler }

constructor TWebViewControlCompletedHandler.Create(
  AEvent: TWebViewControlCompleted);
begin
  FEvent := AEvent;
end;

procedure TWebViewControlCompletedHandler.Invoke(
  asyncInfo: IAsyncOperation_1__IWebViewControl;
  aasyncStatus: AsyncStatus);
begin
  FEvent(asyncInfo, aasyncStatus);
end;

end.

enter image description here

11
NineBerry