TEdgeBrowser(WebView2)でブラウザの位置情報機能(GPS)をDelphiから使用して緯度経度を取得する
Delphi 11.3(Community Edition)でTEdgeBrowserを使ってブラウザの位置情報機能(GPS)を使用します。
パソコンにGPS機能が搭載されていなくても、インターネットに接続していればおおよその位置情報(緯度経度)が取得できます。
(1)はじめに
Windows10の場合はMicrosoft WebView2 ランタイムのインストールを以下のURLを参照してインストールしてください。
https://mam-mam.net/delphi/tedgebrowser.html
「WebView2Loader.dll」も、
https://mam-mam.net/delphi/tedgebrowser.html
を参照してください。
また、以下URLにある「WebView2_TLB.pas」を、本プロジェクトのフォルダに配置してください、
https://mam-mam.net/delphi/tedgebrowser_webview2.html
(2)プロジェクトの作成と保存
Delphi IDEを起動し、「ファイル」⇒「Windows VCLアプリケーション -Delphi」をクリックします「ファイル」⇒「すべて保存 Ctrl+Shift+S」をクリックして、プロジェクト保存用フォルダを作成して ユニット(Unit1)とプロジェクト(Project1)を保存します
上述のように「WebView2_TLB.pas」をプロジェクトフォルダ内に配置してください。
次に、「プロジェクト」⇒「Project1をビルト Shift+F9」をクリックして事前に一度コンパイルしておきます。(フォルダが生成される)
プロジェクトフォルダ内の「win32\degub」フォルダに「files」フォルダを作成します。
「win32\degub\files」フォルダ内に、以下のHTMLファイル「index.html」を作成してUTF-8で保存してください。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> </head> <body> <script> window.addEventListener("load",function(){ console.log("event:loaded");//■HTMLがロード完了 }); function get_location_gps(){ if(navigator.geolocation){ //現在の位置情報取得 navigator.geolocation.getCurrentPosition( function(pos){ //成功時に呼ばれる関数 var posLatitude=pos.coords.latitude; var posLongitude=pos.coords.longitude; console.log("gps:"+posLatitude+","+posLongitude);//■位置情報取得成功 }, function(err){ //敗時に呼ばれる関数 //位置情報取得を拒否された場合 "User denied Geolocation"、 //インターネット接続が無い場合 "Network error. Check DevTools console for more information." console.log("error:"+err.message);//■エラー }, //位置情報取得オプション { //何ミリ秒以前にキャッシュされた位置を返してもよいか。0を指定すると現在の位置情報を取得 maximumAge:0, //位置情報取得に要してよい最大時間(ミリ秒) timeout:3000, //true:なるべく正確な情報を返してほしい場合 false:正確でない場合 enableHighAccuracy:true, } ); }else{ console.log("error:disabled");//■GPS取得未対応 } } </script> </body> </html>
(3)フォームの設計
フォームに、TEdgeBrowser×1個、TButton×1個と、TMemo1×1個をドラッグ&ドロップします

(4)ソースコードの記述
フォームのButton1をダブルクリックしてソースコードを記述します。
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Winapi.WebView2, Winapi.ActiveX, Vcl.StdCtrls, Vcl.Edge, WebView2_TLB; type TForm1 = class(TForm) EdgeBrowser1: TEdgeBrowser; Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure EdgeBrowser1DevToolsProtocolEventReceived( Sender: TCustomEdgeBrowser; const CDPEventName, AParameterObjectAsJson: string); private { Private 宣言 } public { Public 宣言 } end; //クラスヘルパーでプロパティFWebViewを読めるようにする TMyCustomEdgeBrowser = class helper for TCustomEdgeBrowser function GetCoreWebView():ICoreWebView2_3; end; var Form1: TForm1; implementation {$R *.dfm} uses System.JSON.Serializers, System.IOUtils; { TMyCustomEdgeBrowser } //クラスヘルパーでプロパティFWebViewを読めるようにする function TMyCustomEdgeBrowser.GetCoreWebView: ICoreWebView2_3; begin with self do result:=WebView2_TLB.ICoreWebView2_3(FWebView); end; { TForm1 } procedure TForm1.Button1Click(Sender: TObject); begin Button1.Enabled:=False; //Javascriptの位置情報取得を開始する EdgeBrowser1.ExecuteScript('get_location_gps()'); end; procedure TForm1.EdgeBrowser1DevToolsProtocolEventReceived( Sender: TCustomEdgeBrowser; const CDPEventName, AParameterObjectAsJson: string); type TJsonMsg=record column:Integer; level:String; line:Integer; source:String; text:String; url:String; end; TJsonMessage=record message:TJsonMsg; end; var s:TJsonSerializer; res:TJsonMessage; begin s:=TJsonSerializer.Create; try res:=s.Deserialize<TJsonMessage>(AParameterObjectAsJson); if res.message.text='event:disabled' then begin Memo1.Lines.Add('この端末は位置情報を取得できません'); Button1.Enabled:=False; end else if res.message.text='event:loaded' then begin Button1.Enabled:=True; end else if pos('error:',res.message.text,1)=1 then begin Memo1.Lines.Add('エラー:'+res.message.text.Substring(6)); Button1.Enabled:=True; end else if pos('gps:',res.message.text,1)=1 then begin Memo1.Lines.Add('緯度経度:'+res.message.text.Substring(4)); //ar:=res.message.text.Substring(4).split([',']); Memo1.Lines.Add( 'https://www.google.co.jp/maps/@'+ res.message.text.Substring(4)+',18z?hl=ja&entry=ttu' ); Button1.Enabled:=True; end finally s.Free; end; end; procedure TForm1.FormCreate(Sender: TObject); var wb:ICoreWebView2_3; cachepath:string; begin Button1.Enabled:=False; Button1.Caption:='位置情報取得'; Memo1.Lines.Clear; cachepath:=ExtractFilePath(Application.ExeName)+'cache'; //キャッシュを削除する if DirectoryExists(cachepath) then TDirectory.Delete(cachepath,true); //キャッシュのフォルダを指定する //ここに作成される「EBWebView」フォルダを削除すればキャッシュを消せる EdgeBrowser1.UserDataFolder:=cachepath; if not EdgeBrowser1.WebViewCreated then begin EdgeBrowser1.CreateWebView; while not EdgeBrowser1.WebViewCreated do begin sleep(100); application.ProcessMessages; end; end; //コンソールの使用を申請する EdgeBrowser1.DefaultInterface.CallDevToolsProtocolMethod( 'Console.enable', '{}', nil); //コンソールにメッセージが出力された時に //[DevToolsProtocolEventReceived]イベンを発生させる EdgeBrowser1.SubscribeToCDPEvent('Console.messageAdded'); //WebView2の取得 wb:=EdgeBrowser1.GetCoreWebView; // https://demo/ を .\filesフォルダに割り当てます wb.SetVirtualHostNameToFolderMapping( 'demo', PWideChar(ExtractFilePath(Application.ExeName)+'files'), COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_ALLOW ); //ローカルファイル \files\index.htmlを読みます EdgeBrowser1.Navigate('https://demo/index.html'); end; end.
(5)「WebView2Loader.dll」ファイルを実行ファイルと同じフォルダ内にコピーする
「C:\Program Files (x86)\Embarcadero\Studio\22.0\Redist\win32\WebView2Loader.dll」
ファイルを、実行ファイルと同じフォルダ内(プロジェクト保存フォルダ\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 |
(6)実行する
「実行」⇒「実行」をクリックすると実行します。
しばらく待つと「位置情報取得(Button1)」ボタンが有効になります。

「位置情報取得(Button1)」ボタンをクリックします
現在地情報の使用を求めるダイアログが表示された場合は「許可」をクリックしてください。
成功した場合は緯度経度がMemo1に表示されます。

