# pdfviewer — `u_pbt_pdfviewer` #

← Component reference · Guide contents

> Built-in PDF viewer: displays a local document or one published on the web, straight inside your window, with pagination, zoom and printing.

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

## At a glance #

Userobject | `u_pbt_pdfviewer`
Item class | — (component without items)
Used for | Displaying an invoice, a purchase order, a contract or a manual without launching an external application
Opt-in options | —

The component replaces the classic "save the PDF to a temporary file, then call `ShellExecute`": the document stays inside your application, and the user never leaves the current screen.

## Quick start #

    // window open event : display a document stored on disk
    uo_pdf.is_source = "C:\factures\FA-2026-0142.pdf"

    // ue_load_completed event of uo_pdf : (string as_source)
    uo_statut.of_item("main").is_text = "Document displayed"

That is all: setting `is_source` is enough to load and display the document.

## Properties #

Property | Type | Default | Purpose
--- | --- | --- | ---
`is_source` | string | `""` | Document to display: a file path on disk (absolute or relative to the application) or a web address (`https://…`). Setting the value triggers the load; setting `""` clears the viewer
`ii_page` | integer | `0` | Page displayed, counted from 1 (`0` = the document's first page). Loading another document resets it: keeping the previous page would land the reader in the middle of a file they have just opened. Write only: reading it back gives the last page you asked for, not the one on screen. The reader is the one built into the web engine, and it reports nothing.
`ii_zoom` | integer | `0` | Zoom in percent (`0` = left to the viewer). Setting a zoom cancels `is_fit`, which contradicts it. Write only, like `ii_page`: if the user zooms with the reader's own toolbar, this property does not follow.
`is_fit` | string | `""` | Fit mode: `FIT_PAGE`, `FIT_WIDTH`, `FIT_HEIGHT`, or `""` for none. Cancels `ii_zoom`
`ib_viewer_toolbar` | boolean | `true` | Shows the viewer's own toolbar (page number, zoom, print, download). Hide it when your window carries those commands itself
`is_theme_style` | string | `fluent` | Visual style of the component (`THEME_STYLE_*` constants)
`is_theme_mode` | string | `light` | Light or dark variant (`THEME_MODE_*` constants)
`il_theme_accent` | long | `-1` | Accent color of this component (`-1` = the theme accent)

## Methods #

Method | Purpose
--- | ---
`of_refresh ( )` | Reloads the current document — for example after the file has been regenerated on disk
`of_reset ( )` | Clears the viewer and resets every property to its default
`of_set_redraw (boolean)` | Groups a burst of changes into a single render
`of_save_as_png (string)` · `of_save_as_jpg (string)` | Exports the rendering as an image

## Events #

Event | Raised when
--- | ---
`ue_load_completed (string as_source)` | The document has finished loading; `as_source` reminds you what was displayed
`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`)

## What the user can do, without a single line of code #

The viewer displays its built-in toolbar above the document. There is nothing for you to program: it is provided and localized by the system.

Action | How
--- | ---
Pagination | Mouse wheel and scroll bar, or type the page number directly in the `n / total` counter
Zoom | `+` / `−` buttons, `Ctrl` + wheel, fit to page or fit to width
Search | `Ctrl+F` within the text of the document
Printing | Printer button on the toolbar, or `Ctrl+P`
Saving | Download button, to save a copy of the document
Rotation | Page rotation from the toolbar menu

## Examples #

### Opening a local document #

    // Absolute path, or relative to the application directory
    uo_pdf.is_source = "doc\conditions-generales.pdf"

### Opening a document published on the web #

    // A web address loads exactly like a local file
    uo_pdf.is_source = "https://www.monsite.fr/tarifs/catalogue-2026.pdf"

An internet connection is of course required; the load is asynchronous, and `ue_load_completed` tells you when it is done.

### Displaying the PDF a DataWindow has just produced #

    string ls_fichier

    ls_fichier = "C:\temp\etat_" + String(Today(), "yyyymmdd") + ".pdf"

    // The DataWindow produces the file...
    dw_etat.SaveAs(ls_fichier, PDF!, false)

    // ...and the viewer displays it immediately
    uo_pdf.is_source = ls_fichier

### Refreshing after the file has been regenerated #

    // The file was rewritten in the same location : reload without touching is_source
    uo_pdf.of_refresh()

### Chaining several documents in the same viewer #

    // ue_row_changed event of dw_liste : display the attachment of the current row
    string ls_pdf

    ls_pdf = dw_liste.GetItemString(dw_liste.GetRow(), "chemin_pdf")

    if ls_pdf = "" then
        uo_pdf.of_reset()          // no attachment : empty viewer
    else
        uo_pdf.is_source = ls_pdf
    end if

### Tracking the end of the load #

    // ue_load_completed event of uo_pdf : (string as_source)
    uo_attente.Hide()
    uo_imprimer.ib_enabled = true

### Preview in a tab, next to data entry #

    // open event : the viewer takes one tab page, data entry the other
    uo_tab.of_add_page("saisie",  "Entry",   uo_page_saisie)
    uo_tab.of_add_page("apercu",  "Preview",   uo_page_apercu)

    // The viewer sits inside uo_page_apercu like any other control
    uo_pdf.is_source = is_document_courant

The component is hosted with no special precautions inside a tab or a dockcontainer panel.

### Checking the file before displaying it #

    string ls_chemin

    ls_chemin = "C:\factures\" + is_numero + ".pdf"

    if not FileExists(ls_chemin) then
        // Nothing to show : clear the viewer rather than leave the previous document
        uo_pdf.of_reset()
        uo_statut.of_item("main").is_text = "Invoice not found"
        return
    end if

    uo_pdf.is_source = ls_chemin

## Accepted formats and paths #

Form of `is_source` | Example | Note
--- | --- | ---
Absolute path | `"C:\docs\contrat.pdf"` | The most reliable
Relative path | `"doc\notice.pdf"` | Relative to the application directory
Network path | `"\\serveur\partage\bon.pdf"` | The user must have read permissions
Web address | `"https://…/catalogue.pdf"` | Asynchronous load, connection required
Empty | `""` | Clears the viewer

This component only supports PDF: for an image, use picture; for an HTML page, webbrowser.

## Best practices #

- Check that the file exists before assigning `is_source`: an invalid path simply leaves the viewer empty, with no blocking error.
- Call `of_reset()` when no document should be displayed any more (moving to a row without an attachment): otherwise the previous document stays visible.
- Prefer `of_refresh()` over reassigning `is_source` to reload the same document: it is faster and the reading position is restored cleanly.
- Provide a waiting indicator for remote or large documents, and hide it on `ue_load_completed`.
- Give the component a comfortable area (at least half the window): the built-in toolbar and the document both need room to stay readable.
- To display a web page rather than a PDF, use webbrowser; for an image, picture.

← Component reference · Guide contents