6. Fonctions transverses #
← Langue et RTL · Sommaire · FAQ →
Ce chapitre regroupe les services disponibles quel que soit le composant : info-bulles, hébergement de contrôles PowerBuilder, glisser-déposer depuis l'Explorateur, focus clavier, export image, et les objets utilitaires non visuels.
6.1 Info-bulles simples et enrichies #
Info-bulle du composant #
uo_button.is_tooltip = "Enregistrer le dossier (Ctrl+S)"
Le texte accepte le balisage riche : [b], [br], [color=…], [picture=…]…
Super info-bulle (titre + texte + image) #
Pour une aide contextuelle façon ruban Office :
uo_button.is_super_tooltip_title = "Enregistrer"
uo_button.is_super_tooltip_text = "Écrit les modifications sur le serveur." &
+ "[br][br][size-=15]Raccourci : Ctrl+S[/size-=15]"
uo_button.is_super_tooltip_image = "img\help_save.png"
Les trois propriétés sont indépendantes : un titre seul, ou un titre + texte sans image, sont valides. Dès qu'une propriété is_super_tooltip_* est posée, elle prend le pas sur is_tooltip.
Info-bulle d'un item #
Toute classe d'item (n_pbt_item et ses descendants) porte les quatre mêmes propriétés :
uo_toolbar.of_item(/*keys*/ "main/save").is_tooltip = "Enregistrer"
uo_tab.of_page(/*key*/ "clients").is_super_tooltip_title = "Clients"
uo_tab.of_page(/*key*/ "clients").is_super_tooltip_text = "128 fiches, dernière synchro à 09:12"
Comportement #
- L'info-bulle est une fenêtre native thémée, identique dans tous les composants (elle n'est pas limitée par les frontières du webview).
- Elle ne s'affiche pas si votre application n'a pas le focus : passer la souris au-dessus d'une fenêtre en arrière-plan ne déclenche rien.
- Elle disparaît quand vous basculez sur une autre application, et au plus tard au bout de 10 secondes.
of_reset()supprime les info-bulles posées sur l'instance et sur ses items.
6.2 Héberger de vrais contrôles PowerBuilder #
Les composants conteneurs n'affichent pas du HTML à la place de vos écrans : ils accueillent de vrais contrôles PowerBuilder (userobjects, DataWindows, groupes de contrôles), reparentés comme fenêtres Win32 enfants. Vos écrans existants sont réutilisés tels quels.
// Onglets : chaque page est un userobject PB
uo_tab.of_add_page(/*key*/ "clients", /*title*/ "Clients", /*page*/ uo_page_clients)
uo_tab.of_add_page(/*key*/ "invoices", /*title*/ "Factures", /*page*/ uo_page_invoices, /*closable*/ true)
// Panneaux dockables : idem
uo_dock.is_main = "doc" // zone centrale
uo_dock.of_add_panel(/*key*/ "doc", /*position*/ uo_dock.POSITION_STACK, /*relative_to*/ "", /*size*/ 0, /*title*/ "Document", /*content*/ uo_editor)
uo_dock.of_add_panel(/*key*/ "explorer", /*position*/ uo_dock.POSITION_START, /*relative_to*/ "", /*size*/ 240, /*title*/ "Explorateur", /*content*/ uo_tree)
uo_dock.of_add_panel(/*key*/ "props", /*position*/ uo_dock.POSITION_END, /*relative_to*/ "", /*size*/ 260, /*title*/ "Propriétés", /*content*/ uo_props)
Ce qui est pris en charge pour vous :
- le positionnement et le redimensionnement du contrôle hébergé quand l'onglet ou le panneau change de taille ;
- l'affichage / masquage au changement d'onglet ou de panneau actif ;
- les panneaux flottants, dockés ou masqués automatiquement (dockcontainer) ;
- la destruction propre à la fermeture de la fenêtre.
⚠️ Un contrôle hébergé est une fenêtre native : il se dessine au-dessus de la couche web. C'est voulu (votre DataWindow reste nette et rapide), mais cela signifie qu'aucun effet web — ombre, transparence, animation — ne peut passer par-dessus lui.
6.3 Recevoir des fichiers depuis l'Explorateur Windows #
Un composant peut devenir cible de dépôt pour des fichiers glissés depuis l'Explorateur. La bibliothèque installe une cible de dépôt native : vous recevez les chemins complets, ce qu'un dépôt HTML ne permet pas.
uo_editor.ib_allow_drop = true
// event ue_drop_files de uo_editor : (string as_files[])
long ll_i
for ll_i = 1 to UpperBound(as_files)
of_open_file(as_files[ll_i])
next
| Event | Déclenché quand |
|---|---|
ue_drag_enter ( ) | Un glisser de fichiers entre dans le composant |
ue_drag_leave ( ) | Il en sort sans déposer |
ue_drop_files (string as_files[]) | Les fichiers sont déposés — chemins complets |
Le composant fournit lui-même le retour visuel de survol (surbrillance de la zone de dépôt). Publié par les composants où le dépôt a du sens : statictext, codeeditor.
6.4 Clavier et focus #
Un composant PBToolboxAI participe à la navigation clavier de votre fenêtre comme un contrôle natif :
- la touche Tab l'atteint dans l'ordre de tabulation de la fenêtre ;
- les touches (flèches, Entrée, Échap, saisie) sont traitées par le composant qui a le focus ;
- les raccourcis de fenêtre (Entrée = bouton par défaut, Échap = annuler) continuent de fonctionner même quand le focus est dans un composant.
Pour donner explicitement le focus au contenu d'un composant (par exemple après avoir ouvert un panneau de recherche) :
uo_editor.of_focus_webview()
6.5 Exporter le rendu en image #
Rappel du socle commun : tout composant s'exporte tel qu'affiché.
uo_tiles.of_save_as_png(/*path*/ "C:\temp\accueil.png")
uo_tiles.of_save_as_jpg(/*path*/ "C:\temp\accueil.jpg")
Utile pour joindre un écran à un e-mail, alimenter un état, ou tracer un incident utilisateur.
6.6 Boîtes de dialogue et notifications #
Deux services sans contrôle à poser dans la fenêtre :
// Boite de dialogue modale themee (retour synchrone)
n_pbt_messagebox lnv_mb
lnv_mb = create n_pbt_messagebox
lnv_mb.is_title = "Suppression"
lnv_mb.is_message = "Supprimer définitivement [b]12 dossiers[/b] ?"
lnv_mb.is_icon = lnv_mb.ICON_QUESTION
lnv_mb.of_add_button(/*text*/ "Supprimer", /*default*/ false, /*cancel*/ false)
lnv_mb.of_add_button(/*text*/ "Annuler", /*default*/ true, /*cancel*/ true)
if lnv_mb.of_show(/*hwnd*/ Handle(this)) = 1 then of_delete()
destroy lnv_mb
// Notification "toast" en coin d'ecran, non bloquante
n_pbt_toaster lnv_toast
lnv_toast = create n_pbt_toaster
lnv_toast.is_title = "Import terminé"
lnv_toast.is_text = "1 240 lignes intégrées."
lnv_toast.is_kind = lnv_toast.KIND_SUCCESS
lnv_toast.of_show()
destroy lnv_toast
Détails complets : messagebox et toaster.
6.7 Objets utilitaires non visuels #
Livrés dans la même PBL, sans webview ni rendu : ce sont de simples enveloppes autour de la DLL. Créez-les, utilisez-les, détruisez-les.
Base64, empreintes, identifiants — n_pbt_crypto #
Le base64 (texte ou fichier), les empreintes SHA et les identifiants uniques vivent dans le composant crypto : of_base64_encode, of_base64_encode_file, of_sha256, of_hash_file, of_uuid… Une seule page pour tout ce qui se calcule sans rien afficher.
Expressions régulières — u_pbt_regex #
Syntaxe ECMAScript, absente de PowerScript.
Sans clé qui la couvre, u_pbt_regex est en mode démo : le texte fouillé fait 2048 caractères au plus, au-delà l'appel échoue et is_last_error le dit. Pour que la clé qui couvre votre application s'applique, posez ipo_owner sur l'objet qui l'utilise (lnv_re.ipo_owner = this), comme pour crypto.
u_pbt_regex lnv_re
string ls_found[]
lnv_re = create u_pbt_regex
if lnv_re.of_is_match(/*pattern*/ "^[\w.]+@[\w.]+\.\w{2,}$", /*input*/ ls_email) then …
ls_year = lnv_re.of_match(/*pattern*/ "(\d{4})-(\d{2})-(\d{2})", /*input*/ ls_date, /*group*/ 1)
ls_clean = lnv_re.of_replace(/*pattern*/ "\s+", /*input*/ ls_input, /*replacement*/ " ")
ll_nb = lnv_re.of_match_all(/*pattern*/ "[A-Z]{2}\d{6}", /*input*/ ls_text, /*matches*/ ls_found)
destroy lnv_re
| Méthode | Rôle |
|---|---|
of_is_match (motif, texte [, ab_ignore_case | al_flags]) | Le texte correspond-il ? |
of_match (motif, texte, ai_groupe [, al_flags]) | Première correspondance (0 = tout, 1.. = groupe capturant) |
of_match_all (motif, texte [, ai_groupe, al_flags], ref as_res[]) | Toutes les correspondances ; renvoie le nombre |
of_replace (motif, texte, remplacement) | Remplace toutes les occurrences ($1… autorisés) |
Options combinables : FLAG_IGNORE_CASE (1), FLAG_SINGLELINE (2, le . traverse les sauts de ligne).
Archives ZIP — u_pbt_zip #
u_pbt_zip lnv_zip
lnv_zip = create u_pbt_zip
lnv_zip.of_compress(/*zip*/ "C:\temp\livraison.zip", /*src*/ "C:\appli\export") // fichier OU dossier
lnv_zip.of_extract(/*zip*/ "C:\temp\livraison.zip", /*dest*/ "C:\appli\import") // dossier cree si absent
destroy lnv_zip
Les deux méthodes renvoient un boolean.
Sans clé qui la couvre, u_pbt_zip est en mode démo : ce qu'il compresse (fichier ou dossier, au total) et l'archive qu'il extrait font 2048 octets au plus ; au-delà la méthode rend false et is_last_error le dit. Posez ipo_owner sur l'objet qui l'utilise (lnv_zip.ipo_owner = this) pour que la clé de votre application s'applique.
6.8 Informations sur la bibliothèque #
// Version de la DLL : un long, majeure x 10000 + mineure x 100 + correctif
long ll_version
ll_version = PBT_GetVersion() // 40000 = 4.00.00
| Fonction globale | Rôle |
|---|---|
PBT_GetVersion ( ) → long | Version de la bibliothèque : 40000 = 4.00.00 (majeure × 10000 + mineure × 100 + correctif) |
PBT_CheckRuntime (ref string, long) | Version du runtime WebView2 installé (≤ 0 = absent) |
PBT_GetLastErrorMessage (ref string, long) | Dernier message d'erreur du processus |
PBT_LicenseStatus ( ) | État de la licence — voir Licence |
6.9 Imprimer #
Tout composant sait s'imprimer, tel qu'affiché, sans DataWindow intermédiaire.
// Silencieux : un PDF sur disque, rien à cliquer
uo_grid.of_print_to_pdf(/*path*/ "C:\etats\ventes.pdf")
// Paysage, pour une grille large
uo_grid.of_print_to_pdf(/*path*/ "C:\etats\ventes.pdf", /*landscape*/ true)
// Avec dialogue : l'utilisateur choisit son imprimante et voit l'aperçu
uo_grid.of_print()
// Directement le dialogue système d'impression
uo_grid.of_print(/*system_dialog*/ /*dialogue systeme*/ true)
| Méthode | Rôle |
|---|---|
of_print_to_pdf (string as_path) · of_print_to_pdf (string, boolean ab_paysage) | Écrit un PDF sans rien afficher. Ne rend la main qu'une fois le fichier écrit (0 = fait) |
of_print ( ) · of_print (boolean ab_dialogue_systeme) | Ouvre le dialogue d'impression. Rend la main dès que le dialogue est ouvert : ce que l'utilisateur en fait ensuite lui appartient |
⚠️ Ce qui est imprimé est ce qui est RENDU. Une grille virtualisée n'imprime que les lignes qu'elle détient : pour un état complet, passez d'abord par une mise en page qui les affiche toutes (pagination), ou exportez les données plutôt que le rendu.
Le code retour -6 signale un runtime WebView2 trop ancien pour imprimer (1.0.1108 pour le PDF, 1.0.1587 pour le dialogue). Tout le reste suit les codes retour communs.