トップへ(mam-mam.net/)

Using the Browser Geolocation (GPS) API from Delphi with WebView4Delphi (WebView2) – Delphi Source Code Collection

Japanese

Using the Browser Geolocation (GPS) Feature from Delphi with WebView4Delphi (WebView2)

This article explains how to use the browser’s Geolocation (GPS) feature (navigator.geolocation.getCurrentPosition) from Delphi XE4 and later by integrating WebView4Delphi (WebView2).

(1)Introduction

On Windows 10, install the Microsoft WebView2 Runtime from https://developer.microsoft.com/microsoft-edge/webview2/.

This guide assumes that WebView4Delphi has already been downloaded (https://github.com/salvadordf/WebView4Delphi) and installed.
The file WebView2Loader.dll is also required (included with WebView4Delphi).

(2)Creating and Saving the Project

Launch the Delphi IDE and select "File" → "Windows VCL Application – Delphi".
Then choose "File" → "Save All (Ctrl+Shift+S)" to create a folder for the project and save both the unit (Unit1) and the project (Project1).
Next, select "Project" → "Build Project1 (Shift+F9)" to compile it once in advance (this generates the necessary output folders).
Inside the project folder, create a files directory under win32\debug.
In win32\debug\files, create an HTML file named index.html and save it in UTF‑8 encoding.

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
</head>
<body>
<script>
  window.addEventListener("load",function(){
    console.log("event:loaded");
  });
  function get_location_gps(){
    if(navigator.geolocation){
      //Get the current geolocation
      navigator.geolocation.getCurrentPosition(
        function(pos){
          //Called when geolocation is successfully obtained
          var posLatitude=pos.coords.latitude;
          var posLongitude=pos.coords.longitude;
          console.log("gps:"+posLatitude+","+posLongitude);
        },
        function(err){
          // Called when geolocation fails
          // If the user denies permission → "User denied Geolocation"
          // If there is no internet connection → "Network error. Check DevTools console for more information."
          console.log("error:"+err.message);
        },
        //Geolocation options
        {
          //Maximum age (ms) of a cached position. 0 = always get the current position.
          maximumAge:0,
          //Maximum time (ms) allowed to obtain the position
          timeout:3000,
          //true = request high‑accuracy location, false = lower accuracy is acceptable
          enableHighAccuracy:true,
        }
      );
    }else{
      console.log("error:disabled");
    }
  }
</script>
</body>
</html>

(3)Designing the Form

Place the following components on the form by dragging and dropping them from the Tool Palette:
one TButton, one TMemo, one TWVBrowser, and one TWVWindowParent.

Designing a Delphi application that retrieves latitude and longitude

(4)Writing the Source Code

Double‑click Button1 on the form to open its event handler and add the source code.

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
  uWVWinControl, uWVWindowParent, uWVBrowserBase, uWVBrowser,
  uWVTypes, uWVConstants, uWVTypeLibrary, uWVLoader, uWVInterfaces,
  uWVCoreWebView2Args, uWVLibFunctions, uWVCoreWebView2CookieList,
  uWVCoreWebView2Cookie, uWVCoreWebView2HttpRequestHeaders,
  uWVCoreWebView2, System.Json;

type
  TForm1 = class(TForm)
    WVBrowser1: TWVBrowser;
    WVWindowParent1: TWVWindowParent;
    Button1: TButton;
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure WVBrowser1AfterCreated(Sender: TObject);
    procedure WVBrowser1DevToolsProtocolEventReceived(Sender: TObject;
      const aWebView: ICoreWebView2;
      const aArgs: ICoreWebView2DevToolsProtocolEventReceivedEventArgs;
      const aEventName: wvstring; aEventID: Integer);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses System.JSON.Serializers, System.IOUtils;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Button1.Enabled:=False;
  //Start JavaScript geolocation retrieval
  WVBrowser1.ExecuteScript('get_location_gps()',1);
end;

procedure TForm1.FormCreate(Sender: TObject);
var ct:integer;
begin
  Button1.Enabled:=False;
  Button1.Caption:='Get Location';
  Memo1.Lines.Clear;

  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);
      // Note:
      // Changing the User-Agent to a non-WebView value allows Google login.
      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';
    end
    else
    begin
      ShowMessage('WebView2 initialization failed');
    end;
  end;
end;


procedure TForm1.WVBrowser1AfterCreated(Sender: TObject);
begin
  //Required
  WVWindowParent1.UpdateSize;

  //Map the local "files" directory to the virtual host "https://demo"
  WVBrowser1.CoreWebView2.SetVirtualHostNameToFolderMapping(
    'demo',
    PWideChar(ExtractFilePath(Application.ExeName)+'files'),
    COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_ALLOW
  );

  //Enable console usage
  WVBrowser1.CallDevToolsProtocolMethod(
    'Console.enable',
    '{}', 0
  );
  // When a console message is output,
  // trigger OnDevToolsProtocolEventReceived with EventID = 1
  WVBrowser1.SubscribeToDevToolsProtocolEvent('Console.messageAdded',1);

  //Display the local ".\files\index.html"
  WVBrowser1.Navigate('https://demo/index.html');
end;


procedure TForm1.WVBrowser1DevToolsProtocolEventReceived(Sender: TObject;
  const aWebView: ICoreWebView2;
  const aArgs: ICoreWebView2DevToolsProtocolEventReceivedEventArgs;
  const aEventName: wvstring; aEventID: Integer);
type
  TJsonMsg=record
    column:Integer;
    level:String;
    line:Integer;
    source:String;
    text:String;
    url:String;
  end;
  TJsonMessage=record
    message:TJsonMsg;
  end;
var pwc:PWideChar;
    s:TJsonSerializer;
    res:TJsonMessage;
begin
  if aEventID=1 then
  begin
    aArgs.Get_ParameterObjectAsJson(pwc);
    s:=TJsonSerializer.Create;
    res:=s.Deserialize<TJsonMessage>(pwc);
    if res.message.text='event:disabled' then
    begin
      Memo1.Lines.Add('This device cannot retrieve geolocation.');
      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('Error:'+res.message.text.Substring(6));
      Button1.Enabled:=True;
    end
    else if pos('gps:',res.message.text,1)=1 then
    begin
      Memo1.Lines.Add('Latitude / Longitude:'+res.message.text.Substring(4));
      //ar:=res.message.text.Substring(4).split([',']);
      Memo1.Lines.Add(
        'https://www.google.com/maps/@'+
        res.message.text.Substring(4)+',18z?hl=ja&entry=ttu'
      );
      Button1.Enabled:=True;
    end
  end;
end;

initialization
var cachepath:string;
begin
  cachepath:=ExtractFilePath(Application.ExeName) + 'cache';
  // Delete cache
  if DirectoryExists(cachepath) then TDirectory.Delete(cachepath,true);
  // Load and initialize GlobalWebView2Loader
  GlobalWebView2Loader := TWVLoader.Create(nil);
  //Specify the folder for cache, cookies, etc.
  GlobalWebView2Loader.UserDataFolder := cachepath;
  GlobalWebView2Loader.StartWebView2;
end;

end.

(5)Copying "WebView2Loader.dll" to the Executable Folder

Copy the file:
C:\Program Files (x86)\Embarcadero\Studio\22.0\Redist\win32\WebView2Loader.dll
into the same folder as your application’s executable (Project Folder → Win32\Debug).

(A) "Debug" build
"Windows 32‑bit"
ProjectFolder\Win32\Debug
(B) "Debug" build
"Windows 64‑bit"
ProjectFolder\Win64\Debug
(C) "Release" build
"Windows 32‑bit"
ProjectFolder\Win32\Release
(D) "Release" build
"Windows 64‑bit"
ProjectFolder\Win64\Release

(6)Running the Application

If your PC does not have a built‑in GPS module, make sure it is connected to the Internet.
In that case, the browser will provide an approximate location based on network information.

Select “Run” → “Run” to start the application.
After a short moment, the “Get Location (Button1)” button will become enabled.

Running the application to retrieve latitude and longitude

Click the "Get Location (Button1)" button.
If a dialog appears asking for permission to access your current location, click "Allow".
When the geolocation request succeeds, the latitude and longitude will be displayed.

Dialog requesting permission to access your current location
Latitude and longitude displayed after successful geolocation