Smartpoint Desktop v12.0 – WebView2 SDK Integration Guide

Summary: Smartpoint Desktop v12.0 integrates WebView2 as a browser control. You can open any webpage URL within the application. Follow these guidelines to launch URLs and enable SDK communication.

Opening a Non-Interactive Webpage

To open a non-interactive webpage (i.e., no communication between the Smartpoint SDK and the webpage), use one of the methods below:

Method 1: Using SmartWebView2BrowserControl

Copy
var window = UIHelper.Instance.CreateNewSmartBrowserWindow("BrowserWindow1");
var browser = new SmartWebView2BrowserControl();
window.Content = browser;
browser.NavigateTo("http://travelport.com");
window.ShowDialog();

Method 2: Modeless Browser Launch

Copy
UIHelper.Instance.LaunchWebBrowser(new Uri("http://travelport.com"));

Method 3: Modal Browser Launch

Copy

UIHelper.Instance.LaunchWebBrowser(new Uri("http://travelport.com"), true);

Opening an Interactive Webpage

An interactive webpage communicates with the Smartpoint SDK by sending and receiving instructions. For example, a booking tool webpage may request:

  • Current Work Area Code

  • Record Locator

  • Serialized Itinerary (JSON)

  • Host Command Submission

Sample Methods (C#)

Copy
public string GetCurrentWorkarea()    
{
    return UIHelper.Instance.CurrentTEControl?.Connection?.HostUserSettings?.CurrentWorkArea ?? string.Empty;
}

public string GetCurrentRecordLocator()
{
    return PnrHelper.Instance?.CurrentPnrViewerControl?.BookingFile?.RecordLocator;
}

public string GetCurrentItinerary()
{
    var segments = PnrHelper.Instance?.CurrentPnrViewerControl?.BookingFile?.Segments;
    return segments?.Any() == true ? Serializer.Serialize(segments) : string.Empty;
}

public void SubmitToTerminal(string command)
{
    CoreHelper.Instance.SendHostCommand(command, UIHelper.Instance.CurrentTEControl, true);
}

Steps to Enable SDK-Webpage Communication with WebView2

  1. Create a new plugin project.

  2. Add a Plugin.cs file inheriting from HostPlugin.

  3. Define a JsCallBack class with attributes [ClassInterface(ClassInterfaceType.AutoDual)] and [ComVisible(true)].

  4. Instantiate SmartWebView2BrowserControl and ISmartPointWindow.

  5. Create a WebView2HostObject with a name and an instance of JsCallBack.

  6. Pass the webpage URL to the NavigateTo method.

  7. Call the Show method to launch the window and load the URL.

If an existing plugin uses CefSharp, it must follow the same approach to migrate to WebView2.

Example: HTML Page (gsp.html)

  • Fetches current work area

  • Fetches current record locator

  • Fetches current itinerary

  • Sends terminal command

JavaScript uses window.callbackobj to invoke SDK methods.

gsp.html code

Copy
<html>
    <head>
        <title>Index</title>
        <script type="text/javascript" >
            document.addEventListener('DOMContentLoaded', function() {
                refresh();
            });

            function refresh(){
                refreshCurrentWorkArea();
                refreshCurrentRecordLocator();
                refreshCurrentItineraries();
            }

            function refreshCurrentWorkArea() {
                // get current work area
                var currentWorkArea = invoke(window.callbackobj, 'getCurrentWorkarea');
                document.getElementById('currentWorkArea').value = currentWorkArea;
            }

            function refreshCurrentRecordLocator() {
                // get current record locator
                var currentRecordLocator = invoke(window.callbackobj, 'getCurrentRecordLocator');
                document.getElementById('currentRecordLocator').value = currentRecordLocator;
            }

            function refreshCurrentItineraries() {
                // get current itineraries
                var currentItineraries = invoke(window.callbackobj, 'getCurrentItinerary');
                document.getElementById('currentItineraries').value = currentItineraries;
            }

            function executeTerminalCommand() {
                // get terminal command
                var terminalCommand = document.getElementById('terminalCommand').value;
                invoke(window.callbackobj, 'submitToTerminal', terminalCommand);
            }

            function invoke(obj, method, args) {
                // invoke method
                if (!obj) return;
                if (!obj[method]) return;

                if (!args) return obj[method]();

                return obj[method](args);
            }
        </script>
    </head>
    <body>
        <h1>SPD Info</h1>
        <!-- Table to display - 
         columns: name, empty
         rows: [current work area in readonly textbox, refresh button,
         current record locator in readonly textbox, refresh button,
         current itineraries in readonly textaread, refresh button,
         terminal command in textbox, execute button]
         -->
        <table border="1">
            <tr>
                <td>Current Work Area</td>
                <td><input type="text" readonly="readonly" id="currentWorkArea" /></td>
                <td><input type="button" value="Refresh" onclick="refreshCurrentWorkArea()" /></td>
            </tr>
            <tr>
                <td>Current Record Locator</td>
                <td><input type="text" readonly="readonly" id="currentRecordLocator" /></td>
                <td><input type="button" value="Refresh" onclick="refreshCurrentRecordLocator()" /></td>
            </tr>
            <tr>
                <td>Current Itineraries</td>
                <td><textarea readonly="readonly" id="currentItineraries"></textarea></td>
                <td><input type="button" value="Refresh" onclick="refreshCurrentItineraries()" /></td>
            </tr>
            <tr>
                <td>Terminal Command</td>
                <td><input type="text" id="terminalCommand" /></td>
                <td><input type="button" value="Execute" onclick="executeTerminalCommand()" /></td>
            </tr>
        </table>
    </body>
</html>

Sample Plugin Project

  • 0805.CustomSDKPlugin: Launches the gsp.html page (code provided above) and handles SDK-webpage communication.
    • Plugin.cs: Contains ShowWindow method to create and launch the WebView2 browser.

      Copy
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      using Travelport.Smartpoint.Common;
      using Travelport.Smartpoint.Controls;
      using Travelport.Smartpoint.Helpers.Core;
      using Travelport.Smartpoint.Helpers.UI;

      namespace CustomSDKPlugin
      {
          /// <summary>
          /// Plugin for extending Smartpoint application
          /// </summary>
          [SmartPointPlugin(Developer = "Smartpoint Desktop Team",
                            Company = "Travelport",
                            Description = "Custom plugin for communicating with Smartpoint SDK and Webpage",
                            Id = "35221a98-7da5-49dc-9704-80694cc97933",
                            Version = "1.0.0.0")]
          public class Plugin : HostPlugin
          {
              private ISmartDialogWindow window = null;
              /// <summary>
              /// Constructor
              /// </summary>
              public Plugin()
              {
                  
              }

              public override void Execute()
              {
                  // Attach a handler to execute when the Smartpoint application is ready and all windows are loaded.
                  CoreHelper.Instance.OnSmartpointReady += this.OnSmasrtpointReady;
              }

              private void OnSmasrtpointReady(object sender, CoreHelperEventArgs e)
              {
                  CoreHelper.Instance.TerminalCommunication.OnTerminalPreSend += TerminalCommunication_OnTerminalPreSend;
              }

              private void TerminalCommunication_OnTerminalPreSend(object sender, TerminalEventArgs e)
              {
                  if (e.TerminalEntry.Equals("#OpenWebPage", StringComparison.InvariantCultureIgnoreCase))
                  {
                      ShowWindow();
                      UIHelper.Instance.ShowMessageInTerminal("if any message to be didplayed in terminal", UIHelper.Instance.CurrentTEControl);
                      e.Handled = true;
                  }
              }

              private void ShowWindow()
              {
                  var objCallBack = new JsCallBack();
                  var hostObject = new WebView2HostObject() { Name = "callbackobj", Object = objCallBack };
                  var owner = UIHelper.Instance.GetOwnerWindow(UIHelper.Instance.CurrentSmartTerminalWindow);
                  var browserWindow = UIHelper.Instance.CreateNewSmartpointWindow("CustomSDK");
                  browserWindow.Title = "Custom SDK";
                  browserWindow.NoClose = false;
                  var wb = browserWindow.Content as SmartWebView2BrowserControl;
                  if (wb == null)
                  {
                      wb = new SmartWebView2BrowserControl();
                      browserWindow.Closed += delegate
                      {
                          wb.Close();
                      };

                      browserWindow.Content = wb;
                  }

                  browserWindow.Owner = owner;
                  //pass the host object values to the browser control
                  wb.HostObject = hostObject;
                  var url = $"{Environment.CurrentDirectory}\\gsp.html";
                  wb.NavigateTo(url);
                  browserWindow.Show();
              }
          }
      }
    • JsCallBack.cs: Contains methods for SDK-Webpage communication.

      Copy
      using Newtonsoft.Json;
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Runtime.InteropServices;
      using System.Text;
      using System.Threading.Tasks;
      using System.Windows.Threading;
      using Travelport.Smartpoint.Helpers.Core;
      using Travelport.Smartpoint.Helpers.PNR;
      using Travelport.Smartpoint.Helpers.UI;

      namespace CustomSDKPlugin
      {
          [ClassInterface(ClassInterfaceType.AutoDual)]
          [ComVisible(true)]
          public class JsCallBack
          {       

              /// <summary>
              /// Refresh Pnr Viewer
              /// </summary>
              public void RefreshPnrViewer()
              {
                  UIHelper.Instance.CurrentTEControl.Dispatcher.BeginInvoke(
                              System.Windows.Threading.DispatcherPriority.Background,
                              new System.Action(() =>
                              {
                                  string recordLocator = PnrHelper.Instance.LastPnrRecordLocator;
                                  PnrHelper.Instance.RefreshCurrentBookingFile();
                              }));
              }

              public string GetCurrentWorkarea()
              {
                  var workarea = string.Empty;
                  workarea = UIHelper.Instance.CurrentTEControl?.Connection?.HostUserSettings?.CurrentWorkArea ?? string.Empty;
                  return workarea;
              }

              public string GetCurrentRecordLocator()
              {
                  var recordLocator = string.Empty;          
                  recordLocator = PnrHelper.Instance?.CurrentPnrViewerControl?.BookingFile?.RecordLocator;
                  return recordLocator;
              }

              public string GetCurrentItinerary()
              {
                  var itinerary = string.Empty;            

                  var segments = PnrHelper.Instance?.CurrentPnrViewerControl?.BookingFile?.Segments;

                  if (segments?.Any() == true)
                  {
                      itinerary = JsonConvert.SerializeObject(segments);
                  }

                  return itinerary;
              }

              public void SubmitToTerminal(string command)
              {
                  UIHelper.Instance.CurrentTEControl.Dispatcher.BeginInvoke(
                              System.Windows.Threading.DispatcherPriority.Background,
                              new System.Action(() =>
                              {
                                  var segments = PnrHelper.Instance?.CurrentPnrViewerControl?.BookingFile?.Segments;

                                  if (segments?.Any() == true)
                                  {
                                      CoreHelper.Instance.SendHostCommand(command, UIHelper.Instance.CurrentTEControl, true);
                                  }
                              }));
              }        

              /// <summary>
              /// Closes the Ndc Window.
              /// </summary>
              public void CloseNdcWindow()
              {
                  UIHelper.Instance.CurrentTEControl.Dispatcher.BeginInvoke(
                              System.Windows.Threading.DispatcherPriority.Background,
                              new System.Action(() =>
                              {
                                  string recordLocator = PnrHelper.Instance.LastPnrRecordLocator;
                                  PnrHelper.Instance.RefreshCurrentBookingFile();
                              }));
              }

          }
      }

Deployment Instructions

  1. Build the 0805.CustomSDKPlugin project.
  2. Place the DLL in:
    C:\Program Files (x86)\Travelport\Smartpoint
  3. Copy gsp.html to the same location.
  4. Launch Smartpoint and enter #OpenWebPage in the terminal.

The working solution (CustomSDKPlugin.zip) is available to download.