PBToolboxAI v4 ← Site

pdfviewer — u_pbt_pdfviewer #

← Référence des composants · Sommaire du guide

Visionneuse PDF intégrée : affiche un document local ou publié sur le web, directement dans votre fenêtre, avec pagination, zoom et impression.

▶ Le voir en vrai — Application de démonstration, tuile PDF viewer : l'aperçu, le code qui le produit et cette page, côte à côte.


En bref #

Userobjectu_pbt_pdfviewer
Classe d'items— (composant sans items)
Sert àAfficher une facture, un bon de commande, un contrat ou une notice sans lancer d'application externe
Options opt-in—

Le composant remplace le classique « enregistrer le PDF dans un fichier temporaire puis appeler ShellExecute » : le document reste dans votre application, l'utilisateur ne quitte jamais l'écran en cours.


Démarrage rapide #

// event open de la fenetre : afficher un document present sur le disque
uo_pdf.is_source = "C:\factures\FA-2026-0142.pdf"
// event ue_load_completed de uo_pdf : (string as_source)
uo_status.of_panel(/*key*/ "main").is_text = "Document affiche"

C'est tout : poser is_source suffit à charger et afficher le document.


Propriétés #

PropriétéTypeDéfautRôle
is_sourcestring""Document à afficher : un chemin de fichier (absolu, relatif à l'application ou réseau ; un # fait partie du nom), une adresse file:///, une adresse web https://… servie en application/pdf, ou une adresse data:application/pdf. Poser la valeur déclenche le chargement ; poser "" vide la visionneuse. Tout le reste est refusé et signalé par ue_load_failed — http:// compris. Se relit tel que vous l'avez écrit
ii_pageinteger0Page affichée, comptée à partir de 1 (0 = la première page du document). Une page posée avant is_source vaut pour ce document ; sinon un nouveau document s'ouvre à sa première page. Chaque changement recharge le document et relève ue_load_completed : le lecteur ne lit sa page qu'au chargement. En écriture seule : la relire donne la dernière page demandée, pas celle affichée. Le lecteur est celui du moteur web, il ne rend compte de rien.
ii_zoominteger0Zoom en pourcentage (0 = laissé au lecteur). Poser un zoom annule is_fit, qui le contredit. En écriture seule, comme ii_page : si l'utilisateur zoome avec la barre du lecteur, cette propriété ne suit pas.
is_fitstring""Ajustement : FIT_PAGE, FIT_WIDTH, FIT_HEIGHT, ou "" pour aucun. Annule ii_zoom
ib_viewer_toolbarbooleantrueAffiche la barre du lecteur (numéro de page, zoom, impression, téléchargement). Masquez-la quand votre fenêtre porte elle-même ces commandes
ib_allow_savebooleantrueOffre les commandes Enregistrer et Enregistrer sous de la barre du lecteur et de son menu. À false, le document est montré sans proposer d'en sauver une copie. Ce n'est pas une protection : le fichier reste lisible sur le disque. Chaque changement recharge le document affiché
ib_allow_printbooleantrueOffre la commande Imprimer de la barre du lecteur et de son menu. of_print imprime toujours : c'est votre application qui décide. Chaque changement recharge le document affiché
is_theme_stylestring""Style visuel du composant (constantes THEME_STYLE_*) ; vide = celui de l'application, suivi à chaque changement
is_theme_modestring""Variante claire ou sombre (constantes THEME_MODE_*) ; vide = celle de l'application, suivie à chaque changement
il_theme_accentlong-1Couleur d'accent de ce composant (-1 = l'accent de l'application, ou celui du thème)

Méthodes #

MéthodeRôle
of_refresh ( )Relit le document courant (sur le disque ou le réseau) sans toucher aux réglages : le moyen d'afficher un fichier régénéré au même chemin. La position de défilement n'est pas gardée : le lecteur repart à ii_page. Après un échec, retente le même document. Un document refusé est jugé de nouveau : ue_load_failed est relevé. Renvoie 0 une fois demandé, -4 sans document (is_source vide), -2 si le composant n'est pas créé
of_print ( ) · of_print (boolean)Ouvre l'aperçu d'impression du document — pas de la page qui l'encadre. Renvoie 0 une fois l'aperçu demandé, -4 quand aucun document n'est affiché, -2 si le composant n'est pas créé. L'argument est sans effet ici : c'est toujours l'aperçu du lecteur PDF
of_print_to_pdf (string)Rend -4 sur ce composant, sans rien écrire : la page imprimée ne serait que le cadre du lecteur, jamais le document. Le document est déjà un PDF : copiez le fichier de is_source
of_reset ( )Vide la visionneuse et remet toutes les propriétés à leur défaut. Renvoie 0 une fois appliqué, -2 si le composant n'est pas créé
of_set_redraw (boolean)Regroupe une rafale de modifications en un seul rendu. Renvoie 0 une fois appliqué, -2 si le composant n'est pas créé
of_save_as_png (string) · of_save_as_jpg (string)Exporte le rendu en image. Renvoie 0 une fois l'image écrite, -4 si l'écriture échoue, -2 si le composant n'est pas créé

Événements #

ÉvénementDéclenché quand
ue_load_completed (string as_source)Le document est affiché ; as_source est is_source tel que vous l'avez écrit. Relevé aussi par of_refresh et par chaque changement de page, de zoom, d'ajustement ou de barre du lecteur. Jamais levé sur un échec
ue_load_failed (string as_source, string as_reason)Le document n'a pas pu être affiché ; as_reason est l'une des constantes REASON_* ci-dessous. La visionneuse reste vide
ue_link_clicked (string as_url)L'utilisateur a suivi un lien du document. La visionneuse reste sur le document : ouvrez as_url où vous voulez (navigateur du poste, webbrowser…). as_url est l'adresse du lien telle quelle (https://…, mailto:…) ; un lien vers un fichier local — relatif au document compris — arrive en chemin disque
ue_ready ( )Le composant a fini de charger ; tout ce qui a été envoyé avant a été rejoué
ue_runtime_missing ( )Le runtime WebView2 est absent : le composant reste vide
ue_bg_color (long al_color)Le composant a calculé sa couleur de fond de thème ; l'userobject l'a déjà adoptée (backcolor)

Pourquoi un document n'est pas affiché #

as_reason de ue_load_failed est l'une de ces constantes de u_pbt_pdfviewer. Un PDF se reconnaît ainsi : un fichier local porte l'extension .pdf et commence par la signature %PDF- ; un document distant est servi avec le type application/pdf (le seul que le moteur remet à son lecteur) ; une adresse data: annonce application/pdf.

ConstanteValeurCause
REASON_NOT_FOUND"notfound"Fichier absent ou illisible, adresse qui répond 404
REASON_NOT_PDF"notpdf"Ce n'est pas un PDF : fichier local sans la signature %PDF-, réponse distante qui n'est pas application/pdf, data: d'un autre type
REASON_TOO_LARGE"toolarge"Fichier trop gros pour ce processus (au-delà de 64 Mo en 32 bits, 512 Mo en 64 bits), ou adresse data: de plus de 2 Mo de caractères (environ 1,5 Mo de PDF)
REASON_INSECURE"insecure"http:// : non pris en charge, servez le document en https://
REASON_UNSUPPORTED"unsupported"Une autre sorte d'adresse (ftp:, blob:…)
REASON_NETWORK"network"Serveur injoignable, nom inconnu, connexion coupée
REASON_CERTIFICATE"certificate"Certificat du site invalide, expiré ou révoqué
REASON_AUTH"auth"Le site ou le proxy demande une authentification
REASON_HTTP"http"Une autre erreur du serveur (403, 500…)
REASON_REFUSED"refused"Le site refuse d'être affiché dans un cadre, ou envoie le PDF en téléchargement — le fichier n'est pas téléchargé pour autant
REASON_FAILED"failed"Toute autre cause

Ce que l'utilisateur peut faire, sans une ligne de code #

La visionneuse affiche sa barre d'outils intégrée au-dessus du document. Vous n'avez rien à programmer : elle est fournie et localisée par le système.

ActionComment
PaginationMolette et barre de défilement, ou saisie directe du numéro de page dans le compteur n / total
ZoomBoutons + / −, ajustement à la page ou à la largeur
RechercheBouton de recherche de la barre d'outils, dans le texte du document
ImpressionBouton imprimante de la barre d'outils (masquable par ib_allow_print), ou of_print depuis votre code
EnregistrementBouton de téléchargement, pour sauver une copie du document (masquable par ib_allow_save)
RotationRotation des pages depuis le menu de la barre d'outils
ClavierDès que le composant a le focus (Tab ou of_focus_webview) : PageDown, flèches, Début / Fin font défiler le document, sans clic préalable

Les raccourcis du navigateur — Ctrl+F, Ctrl+P, Ctrl + molette — sont coupés dans tous les composants, celui-ci compris : passez par les boutons de la barre du lecteur.

Ce que le lecteur ne dit pas #

Le lecteur est celui qui est intégré au moteur web : aucune dépendance à installer, l'impression, la recherche, les formulaires PDF et le plein écran fournis. En contrepartie, il ne rend compte de rien à votre application : ni la page affichée, ni le nombre de pages, ni le zoom réel, ni le texte sélectionné, et la recherche ne se pilote pas par code. ii_page et ii_zoom disent où ouvrir le document, pas où l'utilisateur se trouve. Ce choix est délibéré pour la 4.0 ; un rendu scriptable demanderait une bibliothèque externe.


Exemples #

Ouvrir un document local #

// Chemin absolu, ou relatif au repertoire de l'application
uo_pdf.is_source = "doc\conditions-generales.pdf"

Ouvrir un document publié sur le web #

// Une adresse web se charge exactement comme un fichier local
uo_pdf.is_source = "https://www.monsite.fr/tarifs/catalogue-2026.pdf"

Une connexion internet est évidemment nécessaire ; le chargement est asynchrone, ue_load_completed vous signale la fin.

Afficher le PDF que vient de produire une DataWindow #

// Local variables
string ls_file

// Un fichier par jour, dans le dossier temporaire
ls_file = "C:\temp\report_" + String(Today(), "yyyymmdd") + ".pdf"

// La DataWindow produit le fichier...
dw_report.SaveAs(ls_file, PDF!, false)

// ...et la visionneuse l'affiche immediatement
uo_pdf.is_source = ls_file

Rafraîchir après régénération du fichier #

// Le fichier a ete reecrit au meme emplacement : recharger sans retoucher is_source
uo_pdf.of_refresh()

Enchaîner plusieurs documents dans la même visionneuse #

// event ue_row_changed de dw_list : afficher la piece jointe de la ligne courante
string ls_pdf

// Le chemin du PDF de la ligne courante
ls_pdf = dw_list.GetItemString(dw_list.GetRow(), "pdf_path")

// Sans piece, la visionneuse se vide ; sinon elle l'affiche
if ls_pdf = "" then
    uo_pdf.of_reset()          // aucune piece : visionneuse vide
else
    uo_pdf.is_source = ls_pdf
end if

Suivre la fin du chargement #

// event ue_load_completed de uo_pdf : (string as_source)
uo_wait.Hide()

// of_print imprime le document affiche
uo_print_button.ib_enabled = true

Dire pourquoi le document n'est pas là #

// event ue_load_failed de uo_pdf : (string as_source, string as_reason)
uo_wait.Hide()
choose case as_reason
	case uo_pdf.REASON_NOT_FOUND
		uo_status.of_panel(/*key*/ "main").is_text = "Document introuvable : " + as_source
	case uo_pdf.REASON_NOT_PDF
		uo_status.of_panel(/*key*/ "main").is_text = "Ce fichier n'est pas un PDF"
	case else
		uo_status.of_panel(/*key*/ "main").is_text = "Document indisponible (" + as_reason + ")"
end choose

Ouvrir ailleurs un lien du document #

// event ue_link_clicked de uo_pdf : (string as_url)
// La visionneuse reste sur le document : le lien s'ouvre dans le navigateur de la fenetre
uo_web.is_address = as_url

Imprimer le document #

// clicked du bouton Imprimer : l'apercu du lecteur PDF, sur le document lui-meme
if uo_pdf.of_print() = -4 then
	uo_status.of_panel(/*key*/ "main").is_text = "Aucun document a imprimer"
end if

Montrer sans laisser enregistrer ni imprimer #

// Un document confidentiel : ni Enregistrer ni Imprimer dans la barre du lecteur
uo_pdf.ib_allow_save = false
uo_pdf.ib_allow_print = false
uo_pdf.is_source = is_current_document

Posez-les avant is_source : chaque changement recharge le document. Ce n'est pas une protection : le fichier reste lisible sur le disque, et of_print imprime toujours.

Aperçu dans un onglet, à côté de la saisie #

// event open : la visionneuse occupe une page d'onglet, la saisie l'autre
uo_tab.of_add_page(/*key*/ "entry",  /*title*/ "Saisie",   /*page*/ uo_page_entry)
uo_tab.of_add_page(/*key*/ "preview",  /*title*/ "Apercu",   /*page*/ uo_page_preview)

// La visionneuse est posee dans uo_page_preview comme n'importe quel controle
uo_pdf.is_source = is_current_document

Le composant s'héberge sans précaution particulière dans un tab ou un panneau dockcontainer.

Vérifier le fichier avant de l'afficher #

// Local variables
string ls_path

// Le fichier de la facture affichee
ls_path = "C:\factures\" + is_number + ".pdf"

// Pas de fichier, rien a montrer : on vide la visionneuse plutot que de laisser l'ancien document
if not FileExists(ls_path) then
    uo_pdf.of_reset()
    uo_status.of_panel(/*key*/ "main").is_text = "Facture introuvable"
    return
end if

// Sinon, la facture s'affiche
uo_pdf.is_source = ls_path

Formats et chemins acceptés #

Forme de is_sourceExempleRemarque
Chemin absolu"C:\docs\contrat.pdf"Le plus fiable
Chemin relatif"doc\notice.pdf"Relatif au répertoire de l'application
Chemin réseau"\\serveur\partage\bon.pdf"L'utilisateur doit avoir les droits de lecture
Nom avec #"C:\devis\Devis #12.pdf"Le # fait partie du nom du fichier
Adresse file:"file:///C:/docs/contrat.pdf"Convertie en chemin, comme un chemin absolu ; file://localhost/C:/… et la forme UNC à quatre barres file:////serveur/partage/… aussi
Adresse web"https://…/catalogue.pdf"Servie en application/pdf, chargement asynchrone. Un #page=… écrit dans l'adresse est ignoré : utilisez ii_page
Document en mémoire"data:application/pdf;base64,…"Rien n'est écrit sur le disque. Au-delà de 2 Mo de caractères (environ 1,5 Mo de PDF), ue_load_failed avec REASON_TOO_LARGE : écrivez le fichier et donnez son chemin
Adresse http://"http://intranet/bon.pdf"Non prise en charge : ue_load_failed avec REASON_INSECURE. Servez le document en https://
Vide""Vide la visionneuse

Seul le PDF est pris en charge par ce composant : ce qui n'en est pas un est refusé et signalé par ue_load_failed (REASON_NOT_PDF). Pour une image, utilisez picture ; pour une page HTML, webbrowser.


Bonnes pratiques #

Hérité du socle commun #

Ces membres existent sur tous les composants visuels — ils ne sont pas propres à celui-ci. Ils sont détaillés une seule fois, dans les chapitres transverses ; cette table dit seulement où les lire.

MembresRôleDétaillé dans
of_resetRemettre le composant à zéro3.6 Remettre un composant à zéro : of_reset()
of_register_shortcut · of_clear_shortcutsRaccourcis clavier du composant3.5 Les raccourcis clavier
of_is_created · of_is_ready · of_get_last_errorS'il est né, s'il est prêt, ce qui a échoué3.7 Diagnostic
of_save_as_png · of_save_as_jpgExporter le rendu en image3.8 Exporter le rendu en image
of_set_redrawGrouper les modifications en un seul repaint3.10 Bonnes pratiques
of_preload_iconsIcônes affichées sans délaiAffichage instantané : of_icon
of_set_translationTraduire un libellé du composant5.2 Adapter un libellé : of_set_translation
of_focus_webviewDonner le focus au composant6.4 Clavier et focus
of_print · of_print_to_pdfImprimer, ou écrire un PDF6.9 Imprimer
of_set_property · of_get_property · of_component_namePiloter une propriété par son nom3.1 Le moteur de propriétés

Deux aides ne sont pas héritées : of_icon et of_escape_markup vivent sur n_pbt_utils. Déclarez-en une — n_pbt_utils lnv_utils, rien à créer — et appelez-les dessus.


← Référence des composants · Sommaire du guide