PBToolboxAI v4 ← Site

webbrowser — u_pbt_webbrowser #

← Component reference · Guide contents

A web browser built into your window: page display, address bar, Back / Forward history, navigation context menu.

▶ See it live — Demo application, Web browser tile: the preview, the code behind it and this page, side by side.


At a glance #

Userobjectu_pbt_webbrowser
Item class— (component without items)
Used forDisplaying a web page, an internal portal, online documentation or generated HTML content without leaving the application

Quick start #

// open event of the window
uo_browser.ib_address_bar = true    // address bar + navigation buttons
uo_browser.is_address = "https://fr.wikipedia.org/wiki/PowerBuilder"

Setting is_address is the act of navigating: every assignment opens the requested page. An address without a protocol ("example.com") automatically receives https://. A disk path (C:\folder\page.html, \\server\share\page.html) becomes a file:/// address. Words that are not an address ("invoice 2026") go to the search engine of is_search_url; without one, they are refused and ue_error says so. A one-word server name followed by /, ? or # (office/, intranet/home) is an address, and so is an IPv6 address in brackets ([::1]/x); the word alone (intranet) stays free text. A server without HTTPS is written with an explicit http://.


Properties #

PropertyTypeDefaultPurpose
is_addressstring""Displayed address. Assigning this property triggers navigation. Reading it back gives the page actually displayed: if the user follows a link or goes back, it follows too (ue_load_completed tells you). Accepted schemes: http(s):, file: (a disk path too), about:, data:, mailto:, tel:; javascript: is refused
ib_address_barbooleanfalseShows the built-in address bar: URL field, Back / Forward / Refresh buttons
ib_context_menubooleanfalseTurns on the right-click context menu: Back, Forward, Reload, plus Copy on a selection, Open link and Copy link address on a link, Copy image on an image. Opened from the keyboard (Shift+F10), it comes up on the element. In an input field, the Cut / Copy / Paste menu stays
is_search_urlstring""Search engine for words that are not an address, %s = the encoded text (e.g. https://www.bing.com/search?q=%s). Empty by default: such a text is refused and ue_error is raised — a business application does not send what its users type to an engine it has not chosen. Only an http(s) address holding %s is accepted: any other raises ue_error and the engine in force stays
ib_veto_new_windowbooleanfalseAsks ue_new_window before opening a new window in the view; returning false keeps the current page
ib_veto_downloadsbooleanfalseAsks ue_download_starting before each download; returning false cancels it
ib_veto_navigationbooleanfalseAsks ue_navigating before the site leaves for another page (a link, a form, a script); returning false keeps the current page. An allowed page is opened again at the address asked for: a form sent by POST loses its data
ib_privatebooleanfalsePrivate browsing: cookies, storage and cache of the sites are never written to the disk and vanish with the view. Set it before is_address: changing it reopens the view empty (no page, no history); setting it to true again opens a new private session
is_titlestring""Title of the page on screen, read live (ue_title_changed tells you when it changes). Read-only: writing it changes nothing
is_theme_stylestring""Visual style of the component (THEME_STYLE_* constants); empty = the application's, followed at every change
is_theme_modestring""Light or dark variant (THEME_MODE_* constants); empty = the application's, followed at every change
il_theme_accentlong-1Accent colour of this component (-1 = the application accent, or the theme's)

Methods #

MethodPurpose
of_refresh ( )Reloads the current page. Returns 0 once asked, -4 if no page is shown (is_address empty), -2 if the component is not created
of_go_back ( )Goes back to the previous page. Follows the order of your code: is_address then of_go_back() play in that order
of_go_forward ( )Moves on to the next page
of_can_go_back ( ) → booleantrue if a previous page exists — to enable or gray out your own Back button. Read live from the page; read it after a load (ue_load_completed)
of_can_go_forward ( ) → booleantrue if a next page exists
of_stop ( )Stops the current loading and drops the pages still waiting; the interrupted load raises ue_load_failed
of_execute_javascript (string as_script)Runs a script inside the displayed page and returns its value as JSON: a text comes back quoted, a number does not (42), a script that throws or returns nothing gives null. A long answer comes back whole. One condition, and it is structural: the page must be loaded, so call it from ue_load_completed, never right after setting is_address. Returns an empty string when there is no page yet or no answer within 5 seconds: of_get_last_error() says why
of_show_html (string as_html) → longShows a page built by the application (an invoice, a letter). The page is encoded: a colour #c00, an anchor, a % or an accent is shown as written. At most 2 MB once encoded: beyond, ue_error and nothing changes. Returns 0 once sent, -2 if the component is not created
of_clear_browsing_data ( ) → longClears what the sites stored: cookies (a signed-in session), local storage, cache, granted permissions. It takes its place after the addresses already set: the next page opens clean. Every webbrowser of the application shares this data. Returns 0 once sent, -2 if the component is not created
of_reset ( )Resets the component: page cleared, navigation history erased, address bar hidden, context menu off, search engine emptied, questions (ib_veto_*) off, private browsing off. Cookies and sessions of the sites stay: that is of_clear_browsing_data. Returns 0 once applied, -2 if the component is not created
of_save_as_png (string) · of_save_as_jpg (string)Exports the displayed site as an image. Returns 0 once the image is written, -4 when writing fails, -2 when the component is not created

Events #

EventRaised when
ue_load_completed (string as_url)A page has finished loading (yours, a link, Back, of_refresh); as_url is the address actually reached, redirections included. Not raised for an empty address (about:blank) nor for a failed load
ue_load_failed (string as_url, long al_status)A page could not be loaded: unknown host, no network, certificate, or a load cancelled by of_stop or by a newer address. al_status says why: see Why a page did not load
ue_error (string as_message)A text set in is_address (or typed in the bar) is not an address and no is_search_url is set, an address could not be opened at all, or the page's process stopped. Nothing else is held: the next address loads normally
ue_new_window (string as_url) → booleanThe page asks for a new window after a click (target=_blank link, window.open): it opens in this view. Cancelable when ib_veto_new_window = true: returning false keeps the current page. A window opened by a script alone, with no click, is ignored. Only http and https addresses open: a site asking for a file, a data: page or a mail link gets ue_error. A file: link in a web page (http, https, data:) is refused by the engine itself, before the component: nothing opens and no event is raised
ue_download_starting (string as_url, string as_path) → booleanA download is starting: as_url is what is downloaded, as_path the file that will be written. Cancelable when ib_veto_downloads = true: returning false cancels it; otherwise it goes on as in Edge
ue_navigating (string as_url) → booleanThe site is leaving for another page: a link, a form, a script — never an address set by your application. Cancelable when ib_veto_navigation = true: returning false keeps the current page
ue_title_changed (string as_title)The title of the page on screen changed (is_title reads it any time)
ue_permission_requested (string as_url, string as_kind) → booleanThe site asks for the camera, the microphone, the position… (as_kind = a PERMISSION_* constant). Refused unless the event returns true: the one question of the library where silence means NO
ue_ready ( )The component has finished loading; everything sent beforehand has been replayed
ue_runtime_missing ( )The WebView2 runtime is missing: the component stays empty
ue_bg_color (long al_color)The component has computed its theme background color; the userobject has already adopted it (backcolor)
ue_script_error (string as_message, string as_stack)A JavaScript error happened in the component's address bar (never in the displayed site)

The built-in address bar #

This is the fastest option: one property, and the user gets a URL field and Back / Forward / Refresh buttons, themed like the rest of the application.

// The address bar, then the page to open
uo_browser.ib_address_bar = true
uo_browser.is_address = "https://fr.wikipedia.org/wiki/PowerBuilder"

The buttons gray themselves out when there is nowhere to go. In the address field, F5 (or Ctrl+R) reloads, Alt+← / Alt+→ go back and forward (swapped in right-to-left writing), Esc brings back the current address after an abandoned edit, and the first click selects the whole address.

Your own buttons #

If you would rather drive navigation from your own toolbar, hide the built-in bar and use the methods:

// Back / Forward buttons of your window
uo_browser.of_go_back()
uo_browser.of_go_forward()
// ue_load_completed event of uo_browser : (string as_url)
// Update the state of your buttons after each page
uo_toolbar.of_item(/*keys*/ "main/back").ib_enabled = uo_browser.of_can_go_back()
uo_toolbar.of_item(/*keys*/ "main/forward").ib_enabled   = uo_browser.of_can_go_forward()

// And reflect the real address (redirections included)
sle_url.text = as_url

The navigation context menu #

ib_context_menu adds a small Back / Forward / Refresh menu on right-click, themed and rendered by the application. It follows what is under the mouse: Copy on selected text, Open link and Copy link address on a link, Copy image on an image. Opened from the keyboard (Shift+F10, Menu key), it comes up on the element. It shares exactly the same history as the address bar, so the two always stay consistent.

// A small menu on a right click : back, forward, refresh
uo_browser.ib_context_menu = true

Stopping a load #

// Stop button : interrupts a page that is taking too long
uo_browser.of_stop()

Words instead of an address #

By default, a text that is not an address is refused (ue_error), without holding anything: the next address loads normally. To turn it into a search, choose the engine:

// Words typed in the address bar go to this engine (%s = the text)
uo_browser.is_search_url = "https://www.bing.com/search?q=%s"
uo_browser.is_address = "PowerBuilder WebView2"

New windows and downloads #

An "open in a new tab" link or a sign-in window opened after a click is shown in the view, and ue_new_window tells you. A download goes on as in Edge, and ue_download_starting gives you the address and the file. Both turn into a question when you ask for it:

// Ask before each download
uo_browser.ib_veto_downloads = true
// ue_download_starting event of uo_browser : (string as_url, string as_path)
// Only PDF files may be downloaded
return Lower(Right(as_path, 4)) = ".pdf"

Staying on your own servers #

ue_navigating is raised each time the site leaves for another page — a link, a form, a script —, never for an address set by your code. With ib_veto_navigation it is a question: returning false keeps the current page. An allowed page is opened again at the address the site asked for; a form sent by POST loses its data.

// Ask before the site leaves for another page
uo_browser.ib_veto_navigation = true
// ue_navigating event of uo_browser : (string as_url)
// Only the company servers may be opened
return Pos(Lower(as_url), "://intranet.example.com/") > 0

Camera, microphone, position #

When a site asks for the camera, the microphone, the position, notifications or reading the clipboard, ue_permission_requested decides, and the default answer is no: a site does not switch a camera on through a prompt the user does not understand. It is the one question of the library where silence means refusal. Nothing is remembered: the question comes back at each request.

// ue_permission_requested event of uo_browser : (string as_url, string as_kind)
// The video-call page of the company may use the camera and the microphone
if Pos(Lower(as_url), "://visio.example.com/") = 0 then return false
return as_kind = uo_browser.PERMISSION_CAMERA or as_kind = uo_browser.PERMISSION_MICROPHONE

Values of as_kind: PERMISSION_CAMERA, PERMISSION_MICROPHONE, PERMISSION_GEOLOCATION, PERMISSION_NOTIFICATIONS, PERMISSION_CLIPBOARD, PERMISSION_SENSORS, PERMISSION_DOWNLOADS (several downloads in a row), PERMISSION_FILES, PERMISSION_AUTOPLAY, PERMISSION_FONTS, PERMISSION_MIDI, PERMISSION_WINDOWS, PERMISSION_UNKNOWN.

Why a page did not load #

al_status of ue_load_failed is compared with the LOADSTATUS_* constants of the component:

ConstantMeans
LOADSTATUS_HOST_NOT_RESOLVEDUnknown host (misspelt name, DNS)
LOADSTATUS_DISCONNECTED · LOADSTATUS_CANNOT_CONNECT · LOADSTATUS_SERVER_UNREACHABLENo network, server unreachable
LOADSTATUS_TIMEOUTThe server did not answer in time
LOADSTATUS_CERT_INVALID · LOADSTATUS_CERT_EXPIRED · LOADSTATUS_CERT_NAME_INCORRECT · LOADSTATUS_CERT_REVOKED · LOADSTATUS_CLIENT_CERT_ERRORCertificate refused
LOADSTATUS_CANCELEDLoad cancelled by of_stop or by a newer address
LOADSTATUS_AUTH_REQUIRED · LOADSTATUS_PROXY_AUTH_REQUIREDCredentials required (server, proxy)
LOADSTATUS_CONNECTION_ABORTED · LOADSTATUS_CONNECTION_RESET · LOADSTATUS_INVALID_RESPONSE · LOADSTATUS_REDIRECT_FAILED · LOADSTATUS_UNEXPECTED_ERROR · LOADSTATUS_UNKNOWNOther connection or response failures
// ue_load_failed event of uo_browser : (string as_url, long al_status)
if al_status = uo_browser.LOADSTATUS_HOST_NOT_RESOLVED then
	st_message.text = "Unknown address : " + as_url
end if

Running a script in the page #

of_execute_javascript reads or changes the displayed page (its title, a field, a counter). It is not restricted by the licence, including on an about:blank or data: page: running a script in the page is what a browser is for, and the component is free.

// ue_load_completed event of uo_browser : (string as_url)
// The page title, as JSON : "PowerBuilder - Wikipedia" (quotes included)
sle_title.text = uo_browser.of_execute_javascript(/*script*/ "document.title")

Sites that refuse embedded display #

Some sites — Google, most banks, many SaaS applications — send security headers that forbid being displayed inside another page. The component is not affected: it never shows a site in a frame. The page is opened as a top-level document, exactly as your own browser does, and those headers no longer apply.

So there is nothing to set, and no special case to handle in your code.

// A site that refuses to be embedded in a page : nothing special to do
uo_browser.ib_address_bar = true
uo_browser.is_address = "https://www.google.com"

In exchange, the page fills the whole component below the address bar: anything you would draw over it (banners, themed overlays) is not visible while browsing.


HTML content with no network #

of_show_html shows an HTML page built by your application: previewing a letter, a ticket, an invoice or a report, with no network call and no temporary file. The page is encoded for you: a colour #c00, an anchor, a % or an accent is shown as written (2 MB at most).

// Local variables
string ls_html

// An order summary built by the application : the colour and the "%" come out as written
ls_html = "<html><body>" &
        + "<h1 style='color:#1f6feb'>Order #4152</h1>" &
        + "<p>Discount : 10%</p>" &
        + "</body></html>"
uo_browser.of_show_html(/*html*/ ls_html)

Set straight into is_address, a data:text/html, address is not encoded: a # cuts the page there (everything after it is taken as an anchor) and a % garbles it. Prefer of_show_html, or encode it yourself (# → %23, % → %25).

A local file opens the same way with file:///C:/temp/report.html, or simply its path C:\temp\report.html.


Starting over #

of_reset() does more than clear the page: it erases the navigation history too. A user therefore cannot use the Back button to return to a page viewed by the previous user or in another file. It does not touch what the sites stored: cookies, signed-in sessions, local storage, permissions. On a shared workstation, the next user would arrive signed in as the previous one — of_clear_browsing_data() is what clears it. The sites live in a browsing profile of their own, separate from the components of the application.

// Switching to another file : start again from a clean browser, with no history
uo_browser.of_reset()

// Then the file, with its address bar
uo_browser.ib_address_bar = true
uo_browser.is_address = ls_folder_url
// The user of the workstation changes : no page, no history, no signed-in session left
uo_browser.of_reset()
uo_browser.of_clear_browsing_data()

For nothing to ever be written to the disk, set ib_private = true before the first address: cookies and storage vanish with the view.

This is the reflex to have whenever a single component is used to display content from different contexts.


Complete example #

// open event of the window : home page of the internal portal
uo_browser.of_reset()                  // start clean (history included)

// The navigation tools, then the home page
uo_browser.ib_address_bar  = true      // URL field + Back / Forward / Refresh
uo_browser.ib_context_menu = true      // same navigation on right-click
uo_browser.is_address = "https://intranet.example.com/home"
// ue_load_completed event of uo_browser : (string as_url)
uo_status.of_panel(/*key*/ "main").is_text = "Page loaded: " + as_url

Best practices #

Inherited from the common base #

These members exist on every visual component — they are not specific to this one. They are detailed once, in the transverse chapters; this table only says where to read them.

MembersRoleDetailed in
of_resetPut the component back to zero3.6 Resetting a component: of_reset()
of_register_shortcut · of_clear_shortcutsThe component's keyboard chords3.5 Keyboard shortcuts
of_is_created · of_is_ready · of_get_last_errorWhether it was born, whether it is ready, what failed3.7 Diagnostics
of_save_as_png · of_save_as_jpgExport the rendering as an image3.8 Exporting the rendering as an image
of_set_redrawGroup changes into a single repaint3.10 Best practices
of_preload_iconsIcons shown with no delayInstant display: of_icon
of_set_translationTranslate one of the component's labels5.2 Adapting a label: of_set_translation
of_focus_webviewGive the component the focus6.4 Keyboard and focus
of_print · of_print_to_pdfPrint, or write a PDF6.9 Printing
of_set_property · of_get_property · of_component_nameDriving a property by its name3.1 The property engine

Two helpers are not inherited: of_icon and of_escape_markup live on n_pbt_utils. Declare one — n_pbt_utils lnv_utils, nothing to create — and call them on it.


← Component reference · Guide contents