2025/01/09 多機能画像スクリーンセーバー KScrn32/KScrn64(フリー版、シェアウェア版)をVectorで公開

TEdgeBrowser コンポーネント

C++Builder

RAD Studio 10.4 Sydney から新たに追加された TEdgeBrowser コンポーネントにより、VCL アプリケーションで Chromium ベースの Edge WebView2 ブラウザ コントロールを使用して Web コンテンツを扱うことが可能になりました。

2022年6月16日、Internet Explorer(IE)のサポートが終了しました。長くWindowsの標準ブラウザ機能として利用されてきたIEのエンジンは、Delphi/C++Builderアプリケーション内でも、TWebBrowserとして利用されてきました。IEのサポートの終了により、TWebBrowserコンポーネントを使用したDelphi/C++Builderアプリケーションは、修正が必要になります。以下のエンバカデロ・デベロッパーTVに詳細な説明があります。

エンバカデロ・デベロッパーTV(2022年6月)より

以下、エンバカデロ・デベロッパーTV(2022年6月)よりの抜粋情報です。

「IE終了、Delphiアプリの対応は?」 – エンバカデロ・デベロッパーTV(2022年6月)

概要

2022年6月16日、Internet Explorer(IE)のサポートが終了しました。長くWindowsの標準ブラウザ機能として利用されてきたIEのエンジンは、Delphi/C++Builderアプリケーション内でも、TWebBrowserとして利用されてきました。IE終了は、Delphi/C++Builderアプリケーションにどのような影響を与えるのか?そして、その対応方法は?

主なトピック:

  • IE終了!Delphi/C++Builderへの影響は?
  • Delphi/C++BuilderでIE終了に対応すべきこと
  • DelphiアプリでEdgeを使おう!
  • その他のニュース  ‐StackOverflow 2022デベロッパーサーベイ

VCL埋め込みブラウザの対応方針

  • 既存アプリケーションの移行
    • TWebBrowserの「SelectedEngine」プロパティを変更
    • ブラウザエンジンの違いに対処
  • 既存アプリケーションからの拡張/新規開発
    • TEdgeBrowserを使用
    • 明示的に「Edge」のみを使用
    • TEdgeBrowserの新機能も活用し、機能拡張/拡充を図る

Edgeエンジンを使うには

  • Windows 10の場合
    • Edgeエンジンを利用するためのモジュールWebView2Loader.dllを任意の実行パスに配置
      • Win32の場合:
        • copy /y “$(BDS) ¥Redist\win32\WebView2Loader.dll” “$(OUTPUTDIR)”
      • Win64の場合:
        • copy/y “$(BDS)\Redist\win64 ¥ WebView2Loader.dll “$(OUTPUTDIR)”
  • Windows 11の場合
    • WebView2は標準でインストールされているので、 セットアップは不要

TEdgeBrowserの追加機能 (例)

  • Capture Preview
    • 指定したファイルまたはストリームにWebViewのキャプチャーを保存
      EdgeBrowser1-> CapturePreview(“capture.png’);
  • ExecuteScript
    • 引数に指定したJavaScriptを実行できる
      EdgeBrowser1-> ExecuteScript (Memo1.Text); // Memoに記述されたスクリプトを実行
  • NavigateToString
    • 引数に指定したHTMLを表示する
      EdgeBrowser1-> NavigateToString (Memo1.Text); // Memo に記述されたHTMLを表示

CDP を使ってみる – VCL 編

  • TEdgeBrowser->DefaultInterface プロパティ
    ICore WebView2 インターフェースを返します
  • ICore WebVlew2->Call DevToolsProtocolMethod
    CDP の機能を呼び出します
    第1引数: API の名前
    第2引数: 引数 (JSON形式)
    第3引数: 第1引数がイベントの場合、 イベントハンドラ

ICoreWebView2/Chrome DevTools Protocol

  • ICore Web View2 インターフェース
    • Edge にアクセスするためのインターフェース
      IWebBrowser に代わるインターフェースです
    • 他にも ICoreWebView2 に関係するインターフェースがあります
      ICoreWebView2Settings, ICore WebView2Controller など
  • Chrome DevTools Protocol (CDP)
    • Chromium の DevTools にアクセスする仕組みです
      IE には無かった Chromium ブラウザの独自の機能です
    • ICore WebView2 インターフェース経由で CDP を使えます

Chrome DevTools Protocol

  • Chrome DevTools Protocol (CDP)
    • https://chromedevtools.github.io/devtools-protocol/
      Chromium、Chrome、 その他のBlinkベースのブラウザの計測、検査、デバッグ、 プロファイルを行うためのツール を提供するもの
  • Microsoft による解説です
    https://docs.microsoft.com/ja-jp/microsoft-edge/webview2/how-to/chromium-devtools-protocol

Web(Edge)View2 SDKのインストール

必要であれば、Edge(Web)View2 SDKをインストールしてください。

GetItパッケージマネージャ経由でインストールするのが簡単です。こちらのWebページも参考にしてください。

TEdgeBrowserのサンプルコード

TEdgeBrowserのサンプルコードは、RAD Studio / Delphi / C++Builder のSamplesフォルダ内にあります。

  • Samplesフォルダ
    • 筆者の環境では、以下のフォルダです。
      • C:\Users\Public\Documents\Embarcadero\Studio\23.0\Samples\
  • サンプルプロジェクト(C++Builder:1個、Delphi:2個)

TEdgeBrowserのヘルプ

TEdgeBrowserのヘルプです。

WebView2Loader.dll

サンプルコードのプロジェクトをコンパイルし、実行したところ以下のエラーダイアログが表示されました。ここにも、記述があるのですが、TEdgeBrowserコンポネントを使用したプリグラムを実行するには、WebView2Loader.dll が必要です。

RAD Studio 12.2では、以下のフォルダにあります。このファイルを作成した実行ファイルと同じフォルダにコピーしておけばプログラムを実行できます。

  • 32bit
    C:\Program Files (x86)\Embarcadero\Studio\23.0\Redist\win32\WebView2Loader.dll
  • 64bit
    C:\Program Files (x86)\Embarcadero\Studio\23.0\Redist\win64\WebView2Loader.dll

TEdgeBrowserのサンプルプロジェクトへの機能追加

以下のC++Builder用のサンプルプロジェクトに、Webページ「TEdgeBrowserを使用してスクリプトを実行する方法」を参考に新たな機能を追加してみます。

  • 機能追加するサンプルプロジェクト

C:\Users\Public\Documents\Embarcadero\Studio\23.0\Samples\CPP\VCL\WebBrowser\Edge\

コンポーネントの追加

先ず、以下のコンポーネントを追加します。

  • TMemo: Memo1
    • 動作確認用のログ表示用
  • TEdit: EdOutpFolder
    • 出力フォルダの設定用(Dropに対応)

任意のHTMLを表示する

任意のHTMLをTEdgeBrowserに読み込むには、HTMLの文字列を渡してNavigateToStringメソッドを呼び出します。

EdgeBrowser->NavigateToString(L"http://bing.com");

任意のJavaScriptを実行する

TEdgeBrowserでは、ExecuteScriptメソッドでJavaScriptを実行できます。

EdgeBrowser->ExecuteScript(L"alert(\"hello Delphi!\");")

HTMLソースを表示する

ページのソースを表示するための基本は、ExecuteScriptメソッドを実行することは同じですが、もう少し複雑です。スクリプトは非同期に実行されるため、スクリプトの実行終了時のイベントハンドラが用意されています。このイベントを利用して、JSONオブジェクトを返すこともできます。この場合、JSONオブジェクトとはHTMLソースのことを指します。

EdgeBrowser->ExecuteScript(L"encodeURI(document.documentElement.outerHTML)");

スクリプト(ExecuteScript によって呼び出される)が完了した際に発生する、OnExecuteScriptイベントで、HTMLのソーソコードを取得します。

void __fastcall TEdgeBrowserMainForm::EdgeBrowserExecuteScript(TCustomEdgeBrowser* Sender, HRESULT AResult, const System::UnicodeString AResultObjectAsJson)
{

    if( AResultObjectAsJson != "")
	{
		String decodedString	= TNetEncoding::URL->Decode(AResultObjectAsJson);
		Memo1->Text = decodedString;
	}
}

表示している画像のURLを取得する

querySelectorを使用して、最初に見つけた imgタグ src 部分を取得します。

	String jsCode = L"document.querySelector(\"img\").src;";
	EdgeBrowser->ExecuteScript(jsCode);

OnExecuteScriptイベントで、画像のURLを取得します。

void __fastcall TEdgeBrowserMainForm::EdgeBrowserExecuteScript(TCustomEdgeBrowser* Sender, HRESULT AResult, const System::UnicodeString AResultObjectAsJson)
{

	if (!AResultObjectAsJson.IsEmpty())
	{
	    String wstr = AResultObjectAsJson;

	    wstr 		= DeQuotedString(wstr);  // 最初と、最後の’”’を削除
	    Memo1->Lines->Add(wstr);

	    SaveImageData(wstr);    
}

複数の画像のURLを取得する

複数の画像を取得するには、querySelectorAll を使用します。

	String jsCode = L"Array.from(document.querySelectorAll('img')).map(img => img.src);";
	EdgeBrowser->ExecuteScript(jsCode);
  • OnExecuteScriptイベント

イベント内で、TJSONArrayオブジェクトに取得したURLを格納します。以下の例では, “http”を含む場合のみ処理しています。

void __fastcall TEdgeBrowserMainForm::EdgeBrowserExecuteScript(TCustomEdgeBrowser* Sender, HRESULT AResult, const System::UnicodeString AResultObjectAsJson)
{
    // 結果をJSONとして解析
    TJSONArray *jsonArray = (TJSONArray *)TJSONObject::ParseJSONValue(AResultObjectAsJson);
    if (jsonArray)
    {
        // 各URLをメモに追加
        for (int i = 0; i < jsonArray->Count; i++) 
        {
            String url  = jsonArray->Items[i]->Value();
            if(url.Pos("http") == 1)
            {
                Memo1->Lines->Add(url);
                SaveImageData(url);
            }
        }
    delete jsonArray; // メモリ解放
}

画像の保存

画像のURLが判ったら、HTTPプロトコルを使用して画像データを取得できます。(著作権等は、ご注意ください。)VCLで、HTTPプロトコルを処理するコントーネントは幾つかありますが、以下のサンプルコードでは、TNetHTTPClient、TNetHTTPRequestの2つのコンポーネントを使用しています。

以下の2つのコンポーネントを、メインフォームにDropします。

  • TNetHTTPClient: NetHTTPClient1
  • TNetHTTPRequest: NetHTTPRequest1

NetHTTPRequest1 を使用する為に、NetHTTPRequest1 のClientプロパティに、NetHTTPClient1を設定します。

NetHTTPRequest1 のGetメソッドを使用して、HTTP リクエストを指定された URL に送信し、サーバーからのレスポンスをストリームに受信します。

void __fastcall TEdgeBrowserMainForm::SaveImageData(String ImageUrl)
{
	// NetHTTPRequest1のみ使用
	try
	{
		// ダウンロード用のストリームを準備
		std::unique_ptr<TMemoryStream> memoryStream(new TMemoryStream());

		// HTTPリクエストで画像をダウンロード
		String url = ImageUrl;
		NetHTTPRequest1->Get(url, memoryStream.get());
		memoryStream->Position = 0; // ストリームの位置を先頭にリセット

		String fname	= "";
		if( (EdOutpFolder->Text != "") && (TDirectory::Exists(EdOutpFolder->Text)) )
		{
			fname 	= EdOutpFolder->Text;
			fname	= IncludeTrailingPathDelimiter(fname) + imageName;

		} else {
			fname 	= TPath::GetDirectoryName(Application->ExeName);
			fname	= IncludeTrailingPathDelimiter(fname) + imageName;
		}
		memoryStream->SaveToFile(fname);
		
		Memo1->Lines->Add(L"画像をダウンロードして保存しました: ");
		Memo1->Lines->Add(fname);

	} catch (const Exception &e) {
		ShowMessage(L"エラー: " + e.Message);
	}
}

サンプルプロジェクト:EdgeBrowser1.exe

上記の説明に一部のURL解析処理を追加した「EdgeBrowser1.exe」を作成しました。

ソースファイルのダウンロード

TEdgeBrowserのサンプルプロジェクトのソースファイル

実行ファイル

ダウンロード
EdgeBrowser1の実行ファイル
使用方法
  1. 表示したいURLを設定し、リターンキーを押すか「Go」ボタンをクリックします。
  2. 画像を保存するフォルダを設定します。ここが、空欄の時は、実行ファイルと同じフォルダに画像を保存します。

Toolメニューを追加し、その下に、3つのメニューを追加しました。

  • ソースを表示
    表示しているWebページのソースを取得して、Memo1に表示します。
  • 表示画像を保存する
    Xで、画像を大きく表示している時に、その画像を保存できます。複数画像に対応しています。
    ショートカットキー: Ctrl+X
  • 複数画像の取得
    Instgram等で、表示している複数の画像を保存できます。
    ショートカットキー: Ctrl+I

参考URL

タイトルとURLをコピーしました