古いDelphiでEdgeブラウザをWebViewで使う ~Delphiソースコード集
WebView4Delphiは、ChromiumベースのEdgeをWebViewで使用できるコンポーネントです。
Delphi XE10.4以降はTEdgeBrowserがありますが、このコンポーネントを使うと、WebViewをDelphi XE4 以上で使用可能になるようです。(Delphi XE10.2 Tokyoで使えるのを確認しました。)
(1)Microsoft WebView2 ランタイムのインストール
(※Windows11は既にインストール済みなのでインストール不要)https://developer.microsoft.com/ja-jp/microsoft-edge/webview2/
から[エバーグリーン ブートストラップ]の[ダウンロード]ボタンを押すと 「MicrosoftEdgeWebview2Setup.exe」ファイルがダウンロードできます。
(2)WebView4Delphiのダウンロード
https://github.com/salvadordf/WebView4Delphiから[Code]⇒[Download Zip]をクリックしてダウンロードします。
ダウンロードした「WebView4Delphi-main.zip」ファイルを解凍します。
(3)「WebView2Loader.dll」ファイルの準備
ダウンロードした「WebView4Delphi-main.zip」ファイルを解凍したフォルダ内に「WebView2Loader.dll」ファイルがあります。- 32ビットアプリで、実行ファイルと同じフォルダ内に配置しなければならないファイル
- WebView4Delphi-main\bin32\WebView2Loader.dll
- 64ビットアプリで、実行ファイルと同じフォルダ内に配置しなければならないファイル
- WebView4Delphi-main\bin64\WebView2Loader.dll
(4)WebView2Delphiのインストール
(4)ー1.ライブラリパスの追加
Delphiを起動します。[ツール]⇒[オプション]を開きます。
[言語]⇒[Delphi]⇒[ライブラリ]を選択します。
[ライブラリパス]の右にある「...」ボタンをクリックします。
[フォルダの参照]ボタンを押します。
「WebView4Delphi-main.zip」ファイルを解凍したフォルダ内の「source」フォルダを選択し、[フォルダーの選択]ボタンをクリックします。
[追加]ボタンを押して追加し、[OK]ボタンを押します。
選択したプラットフォームを[Windows 64 ビット]に切り替えて、同じように「ライブラリパス」に追加します。
追加したら[保存]ボタンを押します。
(4)ー2.コンポーネントのインストール
[ファイル]⇒[プロジェクトを開く]をクリックします。解凍先フォルダの「\WebView4Delphi-main\packages\WebView4Delphi_group.groupproj」を選択して開きます。
右ペインの「webview4delphi_designtime.bpl」を右クリックして「インストール」をクリックします。
インストールが完了したので、[ファイル]⇒[すべて保存]を押し、[ファイル]⇒[すべて閉じる]を押して閉じます。
(3)プログラムの作成
(3)-①フォームの作成
Delphi IDEを起動し、「ファイル」⇒「Windows VCLアプリケーション -Delphi」をクリックします
フォームに、TPanelをドラッグ&ドロップし、プロパティ[align=alTop]に設定します。
Panel1にTEditを1つ、TButtonを7つドラッグ&ドロップします。
フォームにTMemoをドラッグ&ドロップし、プロパティ[align=alBottom]に設定します。
フォームにTWVBrowserをドラッグ&ドロップします。
フォームにTWVWindowParentをドラッグしてプロパティ[align=alClient]に設定します。
(3)-②ソースコードの記述
以下ソースコードを入力します
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls,
System.DateUtils,
uWVWinControl, uWVWindowParent, uWVBrowserBase, uWVBrowser,
uWVTypes, uWVConstants, uWVTypeLibrary, uWVLoader, uWVInterfaces,
uWVCoreWebView2Args, uWVLibFunctions,
uWVCoreWebView2CookieList, uWVCoreWebView2Cookie,
uWVCoreWebView2HttpRequestHeaders,
uWVCoreWebView2, System.Json;
type
TForm1 = class(TForm)
Panel1: TPanel;
Edit1: TEdit;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
Button6: TButton;
Button7: TButton;
WVBrowser1: TWVBrowser;
WVWindowParent1: TWVWindowParent;
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure WVBrowser1AfterCreated(Sender: TObject);
procedure WVBrowser1BasicAuthenticationRequested(Sender: TObject;
const aWebView: ICoreWebView2;
const aArgs: ICoreWebView2BasicAuthenticationRequestedEventArgs);
procedure WVBrowser1DOMContentLoaded(Sender: TObject;
const aWebView: ICoreWebView2;
const aArgs: ICoreWebView2DOMContentLoadedEventArgs);
procedure WVBrowser1GetCookiesCompleted(Sender: TObject; aResult: HRESULT;
const aCookieList: ICoreWebView2CookieList);
procedure WVBrowser1WebResourceRequested(Sender: TObject;
const aWebView: ICoreWebView2;
const aArgs: ICoreWebView2WebResourceRequestedEventArgs);
procedure WVBrowser1NewWindowRequested(Sender: TObject;
const aWebView: ICoreWebView2;
const aArgs: ICoreWebView2NewWindowRequestedEventArgs);
procedure Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure Button6Click(Sender: TObject);
procedure Button7Click(Sender: TObject);
procedure WVBrowser1DevToolsProtocolEventReceived(Sender: TObject;
const aWebView: ICoreWebView2;
const aArgs: ICoreWebView2DevToolsProtocolEventReceivedEventArgs;
const aEventName: wvstring; aEventID: Integer);
procedure FormDestroy(Sender: TObject);
procedure WVBrowser1CapturePreviewCompleted(Sender: TObject;
aErrorCode: HRESULT);
private
{ Private 宣言 }
//ブラウザ内スクリーンショット用のストリーム
istrm:TStreamAdapter;
strm:TMemoryStream;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
//戻るボタン
if WVBrowser1.CanGoBack then WVBrowser1.GoBack;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
//進むボタン
if WVBrowser1.CanGoForward then WVBrowser1.GoForward;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
//再読み込み
WVBrowser1.Refresh;
end;
procedure TForm1.Button4Click(Sender: TObject);
var cookie:ICoreWebView2Cookie;
begin
//クッキーを扱う
//クッキーの全削除
//WVBrowser1.DeleteAllCookies;
//クッキーを追加または更新する場合
cookie:=WVBrowser1.CreateCookie('name','value','mam-mam.net','/');
//クッキーの有効期限設定
cookie.Set_Expires(
DateTimeToUnix(EncodeDateTime(2030,12,31,23,59,59,999),false)
);
cookie.Set_IsHttpOnly(-1);//HttpOnlyフラグ設定
cookie.Set_IsSecure(-1);//Secureフラグ設定
WVBrowser1.AddOrUpdateCookie(cookie);
//クッキーの一覧を取得する
// ⇒WVBrowser1.OnGetCookiesCompletedイベントで取得
WVBrowser1.GetCookies();
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
//指定URLを開く場合
WVBrowser1.Navigate('https://mam-mam.net/');
end;
procedure TForm1.Button6Click(Sender: TObject);
begin
//スクリプトの実行(コンソールにログを出力)
WVBrowser1.ExecuteScript('console.log("Hello");',1);
end;
procedure TForm1.Button7Click(Sender: TObject);
begin
//ブラウザ内スクリーンショットをPNG画像キャプチャする
strm.Size:=0;
istrm:=TStreamAdapter.Create(strm,soReference);
WVBrowser1.CapturePreview(COREWEBVIEW2_CAPTURE_PREVIEW_IMAGE_FORMAT_PNG,istrm);
end;
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
//URLをキーボー入力してエンターキーを押した場合
if Key = VK_RETURN then
begin
//入力されたURIを開く
WVBrowser1.Navigate(Trim(Edit1.Text));
Key := 0;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var ct:integer;
begin
//ブラウザ内スナップショット用ストリームの作成
strm:=TMemoryStream.Create;
WVWindowParent1.Browser:=WVBrowser1;
if GlobalWebView2Loader.InitializationError then
begin
ShowMessage(GlobalWebView2Loader.ErrorMessage);
end
else
begin
ct:=0;
while (ct<20) and (not GlobalWebView2Loader.Initialized) do
begin
sleep(500);
Application.ProcessMessages;
inc(ct);
end;
if GlobalWebView2Loader.Initialized then
begin
WVBrowser1.CreateBrowser(WVWindowParent1.Handle);
//参考:
//ユーザーエージェントをWebView以外に変更するとGoogleログインも可能
WVBrowser1.UserAgent:=
'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'+
' AppleWebKit/537.36 (KHTML, like Gecko)'+
' Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.53';
//デフォルトのURLを設定
Edit1.Text:='https://www.google.co.jp/';
WVBrowser1.DefaultURL:=Edit1.Text;
end
else
begin
ShowMessage('WebView2初期化失敗');
end;
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
//ブラウザ内スクリーンショット用のストリームの破棄
strm.Free;
end;
procedure TForm1.WVBrowser1AfterCreated(Sender: TObject);
begin
//以下必須
WVWindowParent1.UpdateSize;
//カスタムヘッダーを送り込む場合
//WVBrowser1.OnWebResourceRequestedイベントが発火するようになる
WVBrowser1.AddWebResourceRequestedFilter(
'*',COREWEBVIEW2_WEB_RESOURCE_CONTEXT_ALL);
//コンソールの使用を申請する
WVBrowser1.CallDevToolsProtocolMethod(
'Console.enable',
'{}', 0
);
//コンソールにメッセージが出力された時に
//[OnDevToolsProtocolEventReceived]イベントEventID=1としてを発生させる
WVBrowser1.SubscribeToDevToolsProtocolEvent('Console.messageAdded',1);
end;
procedure TForm1.WVBrowser1BasicAuthenticationRequested(Sender: TObject;
const aWebView: ICoreWebView2;
const aArgs: ICoreWebView2BasicAuthenticationRequestedEventArgs);
var r:ICoreWebView2BasicAuthenticationResponse;
pwc:PChar;
begin
//基本認証(ベーシック認証)の要求があった場合
aWebView.Get_Source(pwc);
if pwc='特定のURL' then
begin
aArgs.Get_Response(r);
r.Set_UserName(PChar('基本認証ユーザー名'));
r.Set_Password(PChar('基本認証パスワード'));
end;
end;
procedure TForm1.WVBrowser1CapturePreviewCompleted(Sender: TObject;
aErrorCode: HRESULT);
begin
//ブラウザ内スクリーンショットを取得したのでファイルとして保存する
strm.SaveToFile(FormatDateTime('yyyymmdd-hhnnss',now())+'.png');
end;
procedure TForm1.WVBrowser1DevToolsProtocolEventReceived(Sender: TObject;
const aWebView: ICoreWebView2;
const aArgs: ICoreWebView2DevToolsProtocolEventReceivedEventArgs;
const aEventName: wvstring; aEventID: Integer);
var pwc:PChar;
json1,json2:TJsonValue;
begin
if aEventID=1 then
begin
//「コンソール」にメッセージが出力されたイベントが発生
Memo1.Lines.Add('■console.logイベントが発生');
//イベント名"Console.messageAdded"が出力
Memo1.Lines.Add(aEventName);
aArgs.Get_ParameterObjectAsJson(pwc);//jsonの値をそのまま出力
Memo1.Lines.Add(pwc);
//jsonの値(message.text)を取り出す
json1:=TJSONObject.ParseJSONValue(pwc);
json2:=json1.GetValue('message');
Memo1.Lines.Add(json2.GetValue('text'));
end;
end;
procedure TForm1.WVBrowser1DOMContentLoaded(Sender: TObject;
const aWebView: ICoreWebView2;
const aArgs: ICoreWebView2DOMContentLoadedEventArgs);
var pUri:PChar;
begin
//URLを移動した時にURLを表示する
aWebView.Get_Source(pUri);
Edit1.Text:=pUri;
end;
procedure TForm1.WVBrowser1GetCookiesCompleted(Sender: TObject;
aResult: HRESULT; const aCookieList: ICoreWebView2CookieList);
var cookies:TCoreWebView2CookieList;
cookie :TCoreWebView2Cookie;
i:integer;
begin
//クッキーの取得
if assigned(aCookieList) then
begin
cookies:=TCoreWebView2CookieList.Create(aCookieList);
cookie:=TCoreWebView2Cookie.Create(nil);
try
for i:=0 to cookies.Count-1 do
begin
cookie.BaseIntf:=cookies.Items[i];
Memo1.Lines.Add(
cookie.Domain+' '+cookie.Path+' '+
//クッキー有効期限のUnixTimeをローカル時間に変換して表示する
FormatDateTime('yyyy/mm/dd hh:nn:ss',UnixtoDateTime(trunc(cookie.Expires),false))+' '+
cookie.Name+'='+
cookie.Value
);
end;
finally
FreeAndNil(cookie);
freeandnil(cookies);
end;
end;
end;
procedure TForm1.WVBrowser1NewWindowRequested(Sender: TObject;
const aWebView: ICoreWebView2;
const aArgs: ICoreWebView2NewWindowRequestedEventArgs);
var pUri:PChar;
begin
//<a target="_blank" rel="noreferrer">をクリックし、
//新しいブラウザWindowを開こうとした場合
//とりあえず、新しいブラウザウィンドウを開かせないようにキャンセルする
aArgs.Set_Handled(-1);
//キャンセルしない場合は別ウィンドウが開く
//aArgs.Set_Handled(0);
//新しいブラウザウィンドウの要求URLを取得する
aArgs.Get_uri(pUri);
showmessage(
'新しいブラウザウィンドウを開こうとしました'+
#13#10+pUri
);
end;
procedure TForm1.WVBrowser1WebResourceRequested(Sender: TObject;
const aWebView: ICoreWebView2;
const aArgs: ICoreWebView2WebResourceRequestedEventArgs);
var rq:ICoreWebView2WebResourceRequest;
rh:ICoreWebView2HttpRequestHeaders;
pUri:PChar;
begin
//常時カスタムヘッダーを送り込む場合
aArgs.Get_Request(rq);
rq.Get_Headers(rh);
rh.SetHeader('X-Test-Always','username');
//特定URIリクエスト時にカスタムヘッダーを送り込む場合
aArgs.Get_Request(rq);
rq.Get_uri(pUri);
if pUri='https://hoge.hoge/' then
begin
rq.Get_Headers(rh);
rh.SetHeader('X-Test','username');
end;
end;
initialization
// GlobalWebView2Loaderをロードして初期化
GlobalWebView2Loader := TWVLoader.Create(nil);
//キャッシュやクッキー等の保存場所を指定する
GlobalWebView2Loader.UserDataFolder :=
ExtractFilePath(Application.ExeName) + 'CustomCache';
GlobalWebView2Loader.StartWebView2;
end.
(3)-③ユニットとプロジェクトの保存
「ファイル」⇒「すべて保存 Ctrl+Shift+S」をクリックして、ユニット(Unit1)とプロジェクト(Project1)を保存します
(3)-④プロジェクトのビルト
次に、「プロジェクト」⇒「Project1をビルト Shift+F9」をクリックします
(4)「WebView2Loader.dll」ファイルを実行ファイルと同じフォルダ内にコピーする
ダウンロードした「WebView4Delphi-main.zip」ファイルを解凍したフォルダ内に「bin32」と「bin64」フォルダがあり、その中に「WebView2Loader.dll」ファイルがあります。
「bin32\WebView2Loader.dll」
ファイルを、(3)-④でビルトした実行ファイルと同じフォルダ内(プロジェクト保存フォルダ\Win32\Debug)にコピーします
(A)「Debug」ビルトで 「Windows 32ビット」 |
プロジェクト保存フォルダ\Win32\Debug |
(B)「Debug」ビルトで 「Windows 64ビット」 |
プロジェクト保存フォルダ\Win64\Debug |
(C)「Release」ビルトで 「Windows 32ビット」 |
プロジェクト保存フォルダ\Win32\Release |
(D)「Release」ビルトで 「Windows 64ビット」 |
プロジェクト保存フォルダ\Win64\Release |
(5)実行する
「実行」⇒「実行」をクリックすると実行します。- Button1は「戻る」
- Button2は「進む」
- Button3は「再読み込み
- Button4は「クッキーを設定してクッキー一覧を取得」
- Button5は「https://mam-mam.net」を開く
- Button6は「スクリプト colsole.log("Hello");を実行し、コンソールにメッセージが出力されたイベントで"Hello"を取得する」
- Button7は「ブラウザ内のスクリーンショットをPNG画像ファイルとして保存する」
配布時について
配布時に必要なファイルは、- 作成した実行ファイル「Project1.exe」
- ビット数にあわせた「WebView2Loader.dll」(Project1.exeと同じフォルダ内に入れる)
-
「MicrosoftEdgeWebview2Setup.exe」を配布先パソコンで実行してインストール
(※Windows11は既にインストール済みなのでインストール不要)