12. Migrer de la 4.0 à la 5.0 #
← Migrer de la 3.0 à la 4.0 · Sommaire · Notes de version →
La 5.0 ne change aucune signature des trente-sept composants de la 4.0, ni aucun événement — sauf la barre de boutons (buttonbar, 12.7) et l'événement ue_link_clicked du visualiseur Markdown (markdownview), qui reçoit un second argument, as_kind (12.5). Trois composants changent de mots. La barre de progression (progressbar) prend ceux des jauges — ib_label, il_color et is_label_format disparaissent au profit de ib_show_value, il_value_color, is_format et is_unit (12.1). Le graphique cartésien (chartcartesian) écrit ses nombres par is_format, comme les jauges et le camembert : of_set_value_format et of_clear_value_format disparaissent, et ii_point_count d’une série devient il_point_count (12.4). Le croisé (crosstab) suit le même chemin : of_set_value_format et of_clear_value_format disparaissent au profit de is_format — sur le champ, ou sur une seule valeur par of_value — et de ib_negative_red (12.8). Le compilateur vous montre chaque ligne à reprendre. La barre latérale (listbar) change un événement : ue_item_rclicked reçoit en plus le point d'écran du clic, al_x et al_y (12.9). Le panneau de tuiles (tilesbox) renomme un événement : ue_tile_context(as_keys) devient ue_tile_rclicked(as_keys, al_x, al_y), et la position d'of_move_tile et d'of_insert_tile passe en long al_position (12.12). Le menu radial (radialmenu) perd quatre propriétés d'infobulle qu'il n'a jamais montrées — is_tooltip, is_super_tooltip_title, is_super_tooltip_text et is_super_tooltip_image (12.5). Le calendrier (scheduler) change trois événements de geste : ue_appointment_changing reçoit as_kind, ue_appointment_moved et ue_appointment_resized reçoivent les valeurs d'avant (12.10). L'explorateur du shell (shellexplorer) change un événement : ue_error reçoit en plus le chemin et une raison constante, as_path et as_reason (12.11). Le bloc de texte riche (statictext) change un événement : ue_hyperlink reçoit en plus ab_opened, si le lien s'est vraiment ouvert (12.5). L'onglet (tab) change un événement : ue_tab_rclicked reçoit en plus le point d'écran du clic, al_x et al_y (12.13). Le lecteur de sons (soundplayer) change trois événements : ue_started, ue_ended et ue_failed reçoivent en plus le numéro du son, al_sound (12.14). Le toaster (toaster) change un événement : ue_toast_dismissed reçoit en plus la raison de la fermeture, as_reason (12.15). Le navigateur web (webbrowser) : of_go_back, of_go_forward et of_stop rendent un long, et sous ib_veto_navigation une adresse tapée par l'utilisateur est demandée à ue_navigating (12.17). La barre d'outils (toolbar) change un événement : ue_item_rclicked reçoit en plus le point d'écran du clic, al_x et al_y (12.18). Le lecteur vidéo (video) change une signature : of_stop devient une fonction qui rend un long (12.16) — un appel écrit comme une instruction compile toujours. Trois composants changent un événement de clic droit d'item, qui reçoit en plus son point d'écran al_x, al_y : la barre de boutons (ue_button_rclicked), le fil d'Ariane (breadcrumb, ue_item_rclicked) et le graphique cartésien (ue_point_rclicked) ; la barre d'état (statusbar) donne ce point comme les autres, sans plus le multiplier par l'échelle de l'écran (12.19). Le socle (12.20) : la raison d'un échec d'un composant non visuel se lit par of_get_last_error() — la propriété is_last_error disparaît de crypto, restclient, soundplayer, speechout, xml, u_pbt_regex et u_pbt_zip —, et of_stop, of_close et of_reset des non visuels rendent un long.
Le reste ne demande rien à votre code : la grille de données (datagrid) et le ruban (ribbon) gagnent des masques de saisie numériques, et l'éditeur d'une colonne numérique de la grille s'ouvre désormais sur le texte du masque (12.2, 12.3). Les nouveaux composants de la 5.0 sont présentés dans les notes de version.
12.1 progressbar : les mots des jauges #
La 5.0 apporte deux jauges, linéaire (gauge) et à cadran (angulargauge). Une barre de progression montre elle aussi une valeur sur une échelle : la bibliothèque ne parle plus qu'une langue pour cela, et la barre, qui disait autrement la même chose, prend les mots des jauges. Aucun ancien nom ne survit : ni propriété, ni nom accepté par of_set_property.
| Quoi | 4.0 | 5.0 |
|---|---|---|
| Afficher la lecture | uo.ib_label = true | uo.ib_show_value = true |
| Couleur de la valeur (-1 = le thème, inchangé) | uo.il_color = RGB(…) | uo.il_value_color = RGB(…) |
| Une lecture qui écrit la valeur | uo.is_label_format = "{value} of {max} rows" | uo.is_format = "#,##0" + uo.is_unit = "of 500 rows" |
| Le pourcentage (défaut, inchangé) | uo.is_label_format = "" | uo.is_format = "" |
| Piloter par nom | of_set_property("label", …), ("label_format", …), ("color", …) | ("show_value", …), ("format", …), ("unit", …), ("value_color", …) |
is_formatest un format d'affichage PowerBuilder appliqué à la valeur ("#,##0","$#,##0.00"), avec les séparateurs de la langue d'affichage, exactement comme pour les jauges. Vide, la barre montre le pourcentage, comme avant.- Les jetons
{percent},{value},{min}et{max}n'existent plus. Un libellé qui mêlait valeur et pourcentage ("{value} of {max} rows ({percent})") n'a pas d'équivalent exact : choisissez la valeur (format et unité) ou le pourcentage (et une unité). Le maximum, que votre code connaît, s'écrit dans l'unité. is_unitest nouveau : un texte brut écrit après la lecture, séparé d'une espace — après la valeur comme après le pourcentage.of_resetle vide.- Un masque qui contient
%écrit la part accomplie, pas la valeur :is_format = "0.0%"donne « 35.0% » pour 1 687 lignes sur 4 820, arrondi vers le bas comme le pourcentage — le pourcentage à décimales que{percent}ne savait pas écrire. - Une attente en pause ou en erreur devient une barre pleine. En 4.0, une barre en attente (
ib_indeterminate) qui recevaitSTATE_PAUSEDouSTATE_ERRORse figeait dans son glissement, souvent hors de sa piste : l'échec ne se voyait pas. En 5.0 elle s'arrête en barre (en anneau) pleine à la couleur de l'état, comme la barre des tâches de Windows, et le lecteur d'écran ne l'annonce plus « occupée » mais dit son état. of_set_property("tooltip", …)etsuper_tooltip_*rendent-5: la barre ne publie pas d'info-bulle, et la porte par nom, qui en posait une, est fermée comme les propriétés.- Nouveau, sans rien à reprendre :
is_orientation(ORIENTATION_VERTICAL: une barre debout, à la place d'unVProgressBar),is_accessible_name(le nom que dit le lecteur d'écran), et le texte d'une attente (is_unitseul quand la barre est en attente).
// 4.0 : the label wrote the value through placeholders
uo_progress.ib_label = true
uo_progress.il_color = RGB(/*red*/ 0, /*green*/ 120, /*blue*/ 215)
uo_progress.is_label_format = "{value} of {max} rows"
// 5.0 : the words of the gauges - a display format for the value, then a unit
uo_progress.ib_show_value = true
uo_progress.il_value_color = RGB(/*red*/ 0, /*green*/ 120, /*blue*/ 215)
uo_progress.is_format = "#,##0"
uo_progress.is_unit = "of 500 rows"
La recette : compilez ; chaque ib_label, il_color et is_label_format d'une barre de progression est signalé. Remplacez les deux premiers par ib_show_value et il_value_color. Pour le troisième : un texte vide reste vide dans is_format ; un libellé qui écrivait la valeur devient un format ("#,##0") et une unité ; un libellé qui écrivait le pourcentage garde is_format vide et met son texte dans is_unit. Un of_set_property qui nommait label, label_format ou color rend désormais -5 et ne fait rien (of_get_last_error nomme la propriété) : cherchez ces noms dans votre code.
12.2 datagrid : un éditeur numérique qui tape au masque #
Aucune signature ne change, et ue_cell_edited reçoit toujours le nombre nu (1234.5). Ce qui change se voit à l'écran : la saisie d'une colonne numérique suit désormais un masque de saisie, dans la syntaxe du DataWindow — celui que vous donnez par la nouvelle propriété is_mask de la colonne, sinon son format d'affichage dépouillé de ses littéraux.
| Quoi | 4.0 | 5.0 |
|---|---|---|
L'éditeur d'une cellule affichée $1,234.50 | s'ouvrait sur le nombre nu 1234.5 ; tout caractère était accepté | s'ouvre sur 1,234.50 ; le groupement apparaît au fil des chiffres, les décimales sont bornées au masque, les lettres refusées ; un nombre collé est lu dans la langue d'affichage |
| Un nombre de quatre chiffres sous un format numérique | non groupé dans certaines langues (1234 en espagnol) | groupé dans toutes les langues (1.234 en espagnol) |
| Un négatif arrondi à zéro | -0 | 0 |
| Ouvrir puis fermer l'éditeur sans rien taper | pouvait changer une valeur que le format arrondit | ne change rien |
Une cellule de notation (rating) lue par un lecteur d'écran | cinq signes étoile | 4 / 5 |
// 5.0 : the input mask of a numeric column - the cell still receives the bare number
uo_grid.of_column(/*key*/ "revenue").is_mask = "#,##0.00"
La recette : rien à changer. Un code qui lisait le texte tapé ne le voit pas : ue_cell_edited rend toujours le nombre. Une colonne dont la saisie doit rester libre (un code, un numéro de pièce) est une colonne texte, pas numérique.
12.3 ribbon : les masques d'un compteur #
Rien ne change pour un compteur qui n'a pas de masque. Deux propriétés nouvelles de sa poignée, dans la syntaxe de PowerBuilder : is_mask, le masque de saisie ("#,##0.00", "0%"), et is_format, le format d'affichage avec ses littéraux (0 "pt" montre 11 pt, qui se tape 11). id_value et ue_value_changed gardent le nombre nu, la bascule entre les deux ne lève aucun événement, et les masques suivent le compteur dans le panneau d'un groupe replié.
// 5.0 : a font size shown "11 pt", typed "11"
uo_ribbon.of_item(/*keys*/ "home/font/size").is_format = "0 ~"pt~""
La recette : rien à changer.
12.4 chartcartesian : le format des nombres par is_format #
Le graphique cartésien écrivait ses nombres par une fonction à quatre arguments (décimales, préfixe, suffixe, séparateur de milliers). La 5.0 range les graphiques et les jauges sous une seule langue : un format d'affichage PowerBuilder, celui d'une colonne de DataWindow, dans la propriété is_format — du graphique entier, et d'un axe par sa poignée. Les sections positif;négatif;zéro, les littéraux et le pourcentage viennent avec, et les séparateurs restent ceux de la langue d'affichage. Aucun ancien nom ne survit.
| Quoi | 4.0 | 5.0 |
|---|---|---|
| Le format du graphique | uo.of_set_value_format(0, "$", "", true) | uo.is_format = "$#,##0" |
| Le format d'un axe | uo.of_set_value_format(AXIS_VALUE2, 1, "", " u", false) | uo.of_axis(AXIS_VALUE2).is_format = '0.0" u"' |
| Revenir au nombre tel quel | uo.of_clear_value_format() | uo.is_format = "" (et "" sur chaque axe qui a le sien) |
| Piloter par nom | — | of_set_property("format", "#,##0") |
| Le nombre de points d'une série (lecture seule) | uo.of_item("k").ii_point_count (integer) | uo.of_item("k").il_point_count (long) |
- Le format d'un axe passe devant celui du graphique, et le reste. Poser le format du graphique n'efface plus celui des axes (la forme sans axe de
of_set_value_formatle faisait) : un axe revient au format du graphique paris_format = "". - Sans format (vide, ou un format qui n'est pas numérique), le nombre s'écrit tel quel, au millième, avec la virgule ou le point de la langue d'affichage — comme le faisait le format par défaut.
// 4.0 : decimals, prefix, suffix and thousands as four arguments
uo_chart.of_set_value_format(/*decimals*/ 0, /*prefix*/ "$", /*suffix*/ "K", /*thousands*/ true)
uo_chart.of_set_value_format(/*axis*/ u_pbt_chartcartesian.AXIS_VALUE2, /*decimals*/ 1, /*prefix*/ "", /*suffix*/ " u", /*thousands*/ false)
// 5.0 : a display format, written as in a DataWindow - for the chart, then for one axis
uo_chart.is_format = "$#,##0K"
uo_chart.of_axis(/*axis*/ u_pbt_chartcartesian.AXIS_VALUE2).is_format = '0.0" u"'
La recette : compilez ; chaque of_set_value_format et of_clear_value_format est signalé. Écrivez le format comme dans une DataWindow : decimals donne le nombre de 0 après le point (-1 = #,##0.###), thousands le , du groupement, le préfixe et le suffixe s'écrivent devant et derrière (entre guillemets s'ils contiennent des chiffres ou des espaces). Le format d'un axe va dans of_axis(<axe>).is_format.
12.5 Autres comportements que vous pouvez voir #
| Quoi | 4.0 | 5.0 | ||
|---|---|---|---|---|
Menus natifs d'un composant qui a son propre accent (il_theme_accent) | l'accent ne se voyait que dans la case d'une entrée cochée | l'entrée pointée le montre aussi, par un liseré au bord de départ (à droite en RTL) | ||
button : Ctrl, Alt ou Maj + Entrée (et Ctrl / Alt + Espace, Ctrl + Échap) sur le bouton qui a le focus | cliquaient ce bouton | vont à la fenêtre, comme depuis tout autre contrôle : le raccourci d'un autre bouton (is_shortcut = "Ctrl+Enter") part, le bouton focalisé non ; Entrée et Espace seuls le cliquent toujours | ||
button grisé ib_default (ou ib_cancel), le plus proche du focus, dans une feuille MDI | Entrée (Échap) partait au bouton par défaut d'une autre feuille | la touche reste dans sa feuille : le champ, ou le CommandButton PB par défaut, la reçoit | ||
breadcrumb : ii_max_visible posé | un nombre exact de segments en OVERFLOW_COLLAPSE (la largeur ne repliait plus rien), ignoré en OVERFLOW_SCROLL et OVERFLOW_SHRINK | un plafond dans les trois modes ; en OVERFLOW_COLLAPSE la largeur replie encore davantage quand la barre est trop étroite, et le lieu courant ne sort plus de la barre | ||
breadcrumb : of_add_child avec un texte vide | une ligne vide dans le menu | la clé de la branche, comme of_add_children | ||
breadcrumb : Ctrl+S, F5 et les autres raccourcis de la fenêtre pendant la saisie du chemin | ne partaient pas | partent, comme depuis un SingleLineEdit ; Entrée et Échap restent au champ | ||
breadcrumb : ue_children_needed qui ne rend jamais la main | plus aucun chevron ne s'ouvrait jusqu'au prochain of_reset | un clic sur un autre chevron abandonne la question, et le fil la laisse tomber au bout de 10 secondes | ||
chartcartesian : une bande ou un seuil sans couleur (-1 ou NULL) | un bloc plein de la couleur du texte | un lavis pâle de l'accent du thème (la ligne d'un seuil : l'accent) ; une borne NULL est refusée (-5) | ||
chartcartesian : un poids NULL dans une carte de chaleur | la case peinte de la couleur la plus chaude, étiquetée « NaN » | une case vide : rien n'y est dessiné, étiqueté ni cliquable ; une bulle sans poids garde la taille par défaut, hors de l'échelle | ||
chartcartesian : of_remove_series | les séries suivantes changeaient de couleur ; l'info-bulle de la série retirée habillait la prochaine série de même clé | chaque série garde la couleur prise à son ajout ; l'info-bulle et les couleurs d'item partent avec la série | ||
chartcartesian : of_append_values / of_append_categories avec ib_animated | tout le graphique retombait sur l'axe et remontait à chaque ajout, tant que la fenêtre n'était pas pleine | seule la forme ajoutée monte, les autres glissent ; l'arrivée entière ne se rejoue qu'à l'ajout d'une série | ||
chartcartesian : barres empilées sur les deux axes de valeurs | les deux piles se superposaient | côte à côte dans la catégorie | ||
chartcartesian : une balise dans une catégorie ou un libellé de valeur | écrite telle quelle sur l'axe, interprétée dans le panneau | du texte partout : la balise est retirée (l'axe, le panneau, #x#, #label#) | ||
chartcartesian : Échap sans rien d'ouvert, Entrée sur un trou | gardés par le graphique | vont à la fenêtre : son bouton Annuler, son bouton par défaut | ||
codeeditor : Ctrl+Tab ou Alt+Tab dans l'éditeur | indentaient le code : le clavier ne sortait plus de l'éditeur | vont à la fenêtre (la page suivante d'un onglet) ; Échap puis Tab sort de l'éditeur, Ctrl+M ou ib_tab_moves_focus font sortir Tab | ||
codeeditor : of_find sur une expression régulière invalide | rendait 0 | rend -5, comme of_replace | ||
codeeditor : un nouvel is_text pendant une recherche | la barre restait ouverte et levait ue_find_result | la barre se ferme, sans rien lever (une valeur est muette) | ||
codeeditor : is_syntax = "SQL" relu | "sql" | "SQL", tel qu'écrit | ||
codeeditor replié : #regionopen, la copie et of_selected_text | affiché #region ; la copie rendait l'affichage, sans les lignes des régions fermées | affiché tel qu'écrit ; la copie et of_selected_text rendent la source de la plage, régions fermées comprises | ||
codeeditor : marqueurs et il_doc_line quand des lignes sont ajoutées ou retirées au-dessus | restaient sur le même numéro de ligne | suivent leur ligne ; une ligne supprimée emporte ses marqueurs | ||
codeeditor : le curseur après « Tout remplacer » (of_replace_all) | sur le dernier remplacement | reste où il était, décalé de ce qui a été inséré avant lui | ||
codeeditor : Ctrl+Z, Ctrl+Y | l'historique du navigateur, perdu quand le texte était écrit focus ailleurs | l'historique du composant (of_undo, of_redo) : il compte aussi ce que fait votre code, un nouvel is_text le vide | ||
crypto : of_totp_verify(secret, code, ref al_step) d'un code tapé avec des espaces (« 864 010 ») | refusé, pas 0 | accepté, comme par la forme à deux arguments ; les espaces sont ignorés | ||
crypto : of_base64_encode_file d'un fichier de 32 à 64 Mo dans une application 32 bits | promis jusqu'à 64 Mo ; la mémoire du processus pouvait manquer | "" et of_get_last_error() (32 Mo au plus en 32 bits) ; of_base64_encode_file_to_file encode un fichier de toute taille dans un autre fichier | ||
crypto : of_totp_uri d'un secret tapé à la main (« gezd gnbv », un « 0 ») | écrit tel quel dans l'URI | écrit en base32 majuscule, sans espaces ni = ; un autre caractère : "" et of_get_last_error() | ||
crypto : un argument NULL | is_last_error pouvait revenir NULL | compte pour un argument vide ; of_get_last_error() n'est jamais NULL | ||
crypto : une cible \x ou C:x (of_base64_decode_to_file, of_encrypt_file, of_decrypt_file) | -5 et un message faux (« not a base64 value », « all needed ») | -5, et of_get_last_error() dit que le chemin dépend du dossier courant d'un lecteur | ||
commandpalette : une recherche et les commandes récentes (is_recent) | une commande récente gagnait jusqu'à il_max_recent × 4 points : avec une grande limite, elle passait devant une meilleure correspondance | elle ne fait que départager des résultats qui correspondent à peu près aussi bien | ||
commandpalette : une commande sans groupe (as_group = "") déclarée entre deux groupes | rangé sous l'en-tête du groupe déclaré avant lui | en tête de la liste, sans en-tête | ||
commandpalette : Début / Fin dans le champ qui contient du texte, Maj+Début | déplaçaient la sélection dans la liste ; Maj+Début ne sélectionnait rien | déplacent le curseur dans le champ ; Ctrl+Début / Ctrl+Fin vont à la liste ; Maj sélectionne dans le champ | ||
commandpalette : un clic droit ou du milieu sur une ligne | lançait la commande | ne fait rien | ||
commandpalette : of_command sur une clé qu'aucune commande ne porte | ib_enabled / ib_visible se relisaient true, une écriture se perdait en silence | ils se relisent false ; une écriture est perdue et of_get_last_error le dit | ||
commandpalette : un second objet palette qui avait repris un accord est détruit | la touche ne répondait plus à personne jusqu'à ce que le premier la repose | l'accord revient au premier | ||
commandpalette : is_recent avec des espaces ou des clés répétées, il_max_recent abaissé | "a, b" ne gardait que a ; un doublon s'affichait deux fois ; is_recent restait long | nettoyé, coupé à la limite et rendu propre à is_recent à l'ouverture | ||
dockcontainer : construire le dock, restaurer une disposition | ue_layout_changed à chaque ajout, le premier ne connaissant qu'un panneau : une disposition enregistrée dans l'événement était écrasée par une disposition à moitié construite | une fois pour une rafale encadrée par of_set_redraw(false) … (true), à la reprise (et pour des changements à moins de 40 ms) ; of_set_layout le lève une fois. Lisez le réglage enregistré avant de créer les panneaux | ||
dockcontainer : le panneau au premier plan d'une pile change sans clic sur son onglet | rien n'était levé (un panneau empilé par of_add_panel ou of_move_panel, celui de devant fermé, détaché ou retiré, un panneau raccroché) | ue_panel_selected du panneau passé devant, après ue_panel_closed, ue_panel_floated ou ue_panel_docked ; une disposition restaurée n'en lève pas. n_pbt_dock_panel.ib_front le relit | ||
dockcontainer : ib_visible = true sur un panneau fermé d'une pile | il revenait derrière l'onglet actif | il passe devant, et ue_panel_selected suit ; dans un groupe replié il reste sur le rail | ||
dockcontainer : of_move_panel vers le panneau lui-même (as_target = as_key) | rendait 0 sans rien faire, ou scindait sa pile | rend -5 ; pour scinder une pile, visez un autre panneau de la pile (of_move_panel("b", "a", POSITION_BOTTOM)) | ||
dockcontainer : un panneau déplacé dans un groupe replié, ou hors de lui | ib_pinned changeait sans événement | ue_panel_pinned suit | ||
dockcontainer : un clic sans déplacement sur un séparateur | levait ue_layout_changed | ne lève rien : rien n'a changé | ||
dockcontainer : of_keys_at avec des clés numériques | les clés entières d'abord (2, 10, zeta) | l'ordre d'ajout (zeta, 10, 2) | ||
dockcontainer détruit à l'exécution (CloseUserObject) | ses contrôles revenaient sur la fenêtre, masqués | ils retrouvent la visibilité qu'ils avaient avant of_add_panel | ||
dockcontainer : of_add_panel d'un contrôle qui CONTIENT le dock | les fenêtres se bouclaient | rend -5, le contrôle reste où il était | ||
crosstab : AGG_COUNT | comptait les lignes | compte les valeurs non vides, comme le Nombre d'Excel ; AGG_COUNT_ROWS, nouveau, compte les lignes | ||
crosstab : une somme sans aucune valeur ; une « différence avec la précédente » à côté d'une cellule vide | 0 | une cellule vide (of_get_cell_value rend NULL) | ||
crosstab : Top N ou Bottom N (of_set_value_filter, ou le menu) sur un champ placé sous un autre de sa zone | classés sur tout le tableau | classés à l'intérieur de chaque parent (la meilleure ville de chaque région) ; au premier niveau, inchangé ; les ex-aequo du N-ième restent tous | ||
crosstab : aucun champ en Colonnes | une colonne de total qui doublait la colonne unique (`Nord | 650 | 650`) | plus de colonne de total ; ib_col_grand_total garde sa valeur |
crosstab : plusieurs mesures et des champs en Colonnes | une colonne Total par mesure, sans nom de mesure, et qui ne se triait pas | un en-tête « Total » puis un en-tête par mesure, triable | ||
crosstab : ue_layout_changed | levé par les gestes de l'utilisateur, et par is_thousands et of_remove_field seulement | levé aussi par tout ordre du code qui change ce que rend of_get_layout (of_set_layout compris), une fois par ordre ; une seule fois à la fin d'une construction encadrée par of_set_redraw(false) … (true) ; jamais si rien ne change, ni pour of_reset | ||
crosstab : un pourcentage (SHOW_PCT_*) | 57.9 % dans toutes les langues | écrit comme la langue d'affichage l'écrit : 57.9% en anglais, 57,9 % en français | ||
crosstab : le filtre de libellé | proposé par le menu de la puce d'un champ numérique seulement ; sur une date, of_set_label_filter comparait l'année (2025-03-15 valait 2025) | proposé pour tout champ ; sur une date, la surcharge texte prend des jours : LABEL_BEFORE, LABEL_AFTER, LABEL_BETWEEN ("yyyy-mm-dd", jours compris) ; la surcharge numérique, ou LABEL_CONTAINS / LABEL_BEGINS / LABEL_ENDS, sur une date : -5 | ||
crosstab : of_group_date_field sur un champ qui ne contient pas de dates | 0, et un seul membre « (vide) » | -5 | ||
crosstab : of_add_calc_field / of_add_calc_measure refusés par la grille (nom déjà pris, formule qui ne se compile pas) | 0 ; seul ue_calc_field_error le disait | -5 et la raison dans of_get_last_error (ue_calc_field_error est toujours levé) ; un nom qui contient / ou ` | : -5 ; une formule accepte .5 et 1e3` | |
crosstab : of_set_value_filter Top ou Bottom de moins de 1 membre ; of_expand_to_level sous 1 | ramenés à 1 | -5 | ||
crosstab : of_get_cell_value appelé depuis un événement levé pendant un ordre de ce script | -2, comme un composant non créé | -4, et of_get_last_error dit pourquoi : lisez après l'événement | ||
crosstab : le menu Options de la grille (la roue dentée) | « Total général » et « Sous-totaux » basculaient les deux axes d'après celui des lignes | une entrée par axe : ligne et colonne de total général, sous-totaux des lignes et des colonnes | ||
crosstab : of_from_datastore — une colonne CHAR, un décimal, le Format d'une colonne | les blancs de remplissage restaient dans le membre ; le Format était ignoré | les blancs de remplissage sont retirés ; un décimal se lit avec le séparateur du poste ; le Format de la colonne est le format par défaut de ses valeurs | ||
datagrid : une ligne sélectionnée que la recherche ou un filtre masque, ou que of_remove_row retire | restait sélectionnée en silence (of_selected_keys et ue_row_menu_clicked la portaient) | quitte la sélection, et ue_selection_changed le dit ; of_select_rows ne prend pas une ligne masquée | ||
datagrid : ib_hidden, is_pin, ii_index posés à la valeur qu'ils ont déjà ; un clic sur la poignée sans la tirer | levaient ue_layout_changed | ne lèvent rien : rien n'a changé | ||
datagrid : des changements de disposition entre of_set_redraw(false) et of_set_redraw(true) | un ue_layout_changed par changement | un seul, à la reprise, avec la disposition finale | ||
datagrid : un type ou un rendu hors des constantes (of_add_column, is_renderer, is_selection_mode) ; of_add_row_menu_item sans composant créé | acceptés et relus tels quels, sans effet ; 0 | of_add_column rend -5 (of_get_last_error dit lequel) ; un rendu inconnu se relit "", un mode inconnu SELECT_NONE ; -2 | ||
datagrid : of_reload_row ou of_update_row d'une cellule modifiée | la marque « modifiée » restait | elle part : la ligne tient de nouveau ce que tient le DataStore | ||
datagrid : éditer une colonne à liste de codes, une date ; une colonne time d'un DataStore | le <select> et le champ de date du moteur ; une heure était du texte | la liste et le calendrier de la bibliothèque (une date se TAPE aussi, dans l'ordre de la langue) ; une heure (TYPE_TIME) : tri, filtre > 09:00, format, saisie 9:5 | ||
datagrid : un filtre > 3 sur une note sans type ou sur une colonne à codes | cherchait le texte « > 3 » : aucune ligne | compare la donnée (le nombre, le code) | ||
datagrid : arbre sous une recherche ; une ligne dont le parent n'est pas dans la grille | l'enfant trouvé restait caché ; la ligne n'apparaissait jamais | ses ancêtres sont montrés, ouverts ; la ligne est à la racine | ||
datagrid : of_from_datastore / of_load_rows après of_open_source ; of_append_rows sans clé après of_from_datastore ; une valeur CHAR | la grille restait en squelettes ; la ligne était refusée (-5) ; gardait son remplissage d'espaces | la source est quittée ; la clé suit le plus grand RowID ; rognée | ||
datagrid : of_export_xlsx | les dates partaient en texte ; aucun plafond | de vraies dates Excel ; un classeur trop lourd (au-delà d'environ 18 Mo) est refusé, ue_xlsx_saved dit pourquoi | ||
messagebox : Échap ou Alt+F4 sur une boîte sans bouton d'annulation | fermaient la boîte et rendaient 0 — of_info aussi, qui promettait 1 | comme Windows : une boîte à un seul bouton se ferme par ce bouton (of_info rend 1), une boîte Oui / Non ne se ferme pas — il faut répondre ; ib_closable = true rend le 0 de la 4.0. Un test = 2 migré d'un MessageBox ne laisse plus passer une suppression | ||
messagebox : un raccourci (of_info, of_error, of_confirm, of_prompt…) après avoir posé il_accent, is_position, ib_movable, une taille ou ib_input_password | tout était effacé en silence : le mot de passe de of_prompt s'affichait en clair | le raccourci ne remplace que le contenu (titre, message, icône, boutons, case, choix) ; l'apparence et les réglages du champ restent. of_reset() efface tout | ||
messagebox : of_reset() après une boîte | of_get_last_error, of_checked, of_action et of_input_value parlaient encore de l'ancienne boîte | ils sont remis à zéro | ||
messagebox : un champ obligatoire rempli d'espaces | accepté | vide : le bouton par défaut attend (la valeur tapée revient telle quelle) | ||
messagebox : une zone [action] dans le titre, un libellé ou le pied ; un lien dans un choix ; deux boutons au même mnémonique | la zone ne faisait rien ; le lien ouvrait le navigateur ET choisissait ; Alt+lettre répondait par le premier bouton | la zone répond comme dans le message (of_action) ; le lien s'ouvre sans choisir ; Alt+lettre passe le focus d'un bouton à l'autre, Entrée choisit | ||
messagebox : Ctrl+C | perdait le & de &&, copiait les balises d'un bouton, ignorait la saisie | les libellés tels qu'affichés, « libellé : valeur » du champ (jamais un mot de passe), les détails et le pied de page | ||
messagebox : un descendant qui appelait xx_set_style_override ou xx_clear_style_override (protégées) | surchargeait un jeton de thème de la boîte | elles ont disparu : il_accent colore la boîte | ||
json et jsontree : un niveau de chemin qui contient ~0 ou ~1 | lu tel quel ; une clé qui contient / n'avait pas de chemin | ~1 est un / de la clé, ~0 un ~ (JSON Pointer, RFC 6901) : paths/~1users lit la clé /users ; une clé qui contient un ~ s'écrit ~0 dans un chemin | ||
json : un niveau de chemin vide (a//b, a/) ou un chemin qui commence par / | refusé par -5, lu absent | un niveau vide est la clé "", un / en tête est la forme complète du pointeur : /name vaut name, / désigne la clé "" de la racine | ||
json : of_get_number, of_get_decimal, of_get_longlong sur une chaîne comme "12 kg" ou "1,5" | lisait le début : 12, 1 | 0 : une chaîne ne compte que si elle est tout entière un nombre JSON — "12.50" vaut toujours 12,5 | ||
json : of_set_members d'une clé que le document porte déjà | la clé était écrite une seconde fois : n_pbt_json lisait la première, un navigateur ou un serveur la dernière | la valeur est remplacée en place ; une clé que le fragment répète garde sa dernière valeur | ||
json : of_pretty d'un document qui porte une valeur of_set_raw imbriquée sur plus de 512 niveaux | un autre document, coupé à 512 niveaux | un texte vide | ||
jsontree : clic sur une clé qui contient /, une clé vide, ou sous une clé en double | un chemin qui lisait une AUTRE valeur dans n_pbt_json | x~1y pour la clé x/y, a//b pour une clé vide ; of_selected_addressable rend false sous la seconde de deux clés identiques | ||
jsontree : Ctrl+C avec un morceau de texte surligné à la souris | le nœud entier | le morceau surligné | ||
jsontree : un JSON qui commence par un BOM | refusé (ue_error) | affiché, comme n_pbt_json le lit ; is_json se relit tel quel | ||
jsontree : le message de ue_error en anglais | Invalid JSON : … | Invalid JSON: … (chaque langue garde sa ponctuation) ; 01, 1., 1e disent Bad number | ||
jsontree : of_expand_path pendant une recherche | replié de nouveau au pas suivant de la recherche, sans ue_node_toggled | reste ouvert, avec les blocs ouverts au-dessus de lui | ||
jsontree : Espace sur une valeur sélectionnée | faisait défiler l'arbre d'une page | ne fait rien (un bloc se plie toujours) | ||
xmltree : un blanc entre deux enfants (<b>x</b> <i>y</i>) | n'avait pas de ligne : /p/text()[1] rendait -5 | une ligne à lui, montrée ␠, avec son chemin : les numéros de ligne d'un contenu mixte changent | ||
xmltree : un texte entre deux enfants (Hello <b>x</b> again) | Hello, again : ses blancs de bord rognés | Hello , again : seuls les retours à la ligne de mise en page partent | ||
xmltree : of_select_path d'un XPath dont le premier nœud est un blanc de mise en page (//text()) | -5 | le premier nœud que l'arbre MONTRE est sélectionné | ||
xmltree : of_selected_value d'un élément qui ne contient que des retours à la ligne (affiché <x/>) | "" | ces retours à la ligne, comme n_pbt_xml les lit | ||
xmltree : Ctrl+C avec un morceau de texte surligné à la souris | le XML du nœud entier | le morceau surligné | ||
xmltree : le message de ue_error en anglais | Invalid XML : … | Invalid XML: … (chaque langue garde sa ponctuation) | ||
xmltree : of_expand_path pendant une recherche | replié de nouveau au pas suivant de la recherche, sans ue_node_toggled | reste ouvert, avec les éléments ouverts au-dessus de lui | ||
xmltree : Espace sur une feuille sélectionnée | faisait défiler l'arbre d'une page | ne fait rien (un élément à enfants se plie toujours) | ||
jsontree, xmltree : une recherche qui se ferme (Échap dans la boîte, of_clear_search, of_reset, ib_search_enabled = false) | aucun événement : une ligne « 3 / 12 » de l'application restait fausse | ue_search_result(0, 0), une fois ; rien quand aucune recherche ne tournait | ||
PBT_SetDefaultFont avec une taille : codeeditor, jsontree, xmltree, ribbon, toolbar, crosstab, datagrid, tilesbox, stepbar, listbar, dockcontainer, video, picture, les menus et info-bulles | le code, le document, le ruban (sa taille de thème) et bien des textes secondaires gardaient leur taille | ils suivent la taille de l'application, dans leurs proportions ; la taille de l'application passe devant celle du ruban du thème ; un ii_font_size du codeeditor passe devant les deux | ||
markdownview : ue_link_clicked | (string as_url) | (string as_url, string as_kind) : un script déjà écrit pour l'événement reste valable ; as_kind (LINK_WEB, LINK_MAIL, LINK_DOCUMENT, LINK_FILE, LINK_OTHER) dit ce qu'est le lien — triez sur lui plutôt que sur le texte de l'adresse | ||
markdownview : une image d'un document posée sur un partage réseau | chargée | refusée, sauf si elle est sur le partage d'où le document a été lu, ou avec ib_network_pictures ; un document lu sur le Web n'affiche aucun fichier du poste | ||
markdownview : un nouvel is_markdown du même document, of_refresh | la vue remontait en haut | la position de lecture est gardée ; un nouvel is_source part toujours du haut | ||
markdownview : of_toc, of_scroll_to et une recherche juste après is_source | agissaient sur le document précédent | le fichier se lit en arrière-plan : of_toc rend 0, of_scroll_to et la recherche l'attendent ; lisez la table dans ue_loaded | ||
markdownview : une colonne alignée par l'auteur (:--, --:) dans une application de droite à gauche | changeait de côté | garde son côté ; seul l'alignement par défaut suit le sens | ||
markdownview : ue_load_failed pour un texte posé par is_markdown | jamais levé | levé (REASON_FAILED, as_source vide) pour un texte que le composant ne sait pas lire ; le document précédent reste affiché | ||
menubar : un raccourci d'entrée (is_shortcut) | agissait sur l'état laissé par la dernière ouverture du menu | lève d'abord ue_menu_opening de son menu, comme Windows : une entrée que cet événement grise ne répond pas, et ue_menu_closed le dit | ||
menubar : une ouverture abandonnée avant de s'afficher (glissement rapide, Échap ou Alt pendant ue_menu_opening, perte du focus) | ue_menu_opening sans ue_menu_closed ; après Échap, le déroulant s'ouvrait quand même | rien ne s'ouvre, et ue_menu_closed suit : chaque ue_menu_opening reçoit exactement un ue_item_selected ou un ue_menu_closed | ||
menubar : Alt puis Échap, F10 puis Échap | Échap partait aussi à la fenêtre : son bouton Annuler | Échap quitte le mode menu et reste à la barre | ||
menubar : un menu ouvert au clavier (Alt+lettre, F10 puis Entrée) | aucune entrée en surbrillance : Entrée ne choisissait rien | la première entrée est en surbrillance, Entrée la choisit | ||
menubar : Alt quand la barre a déjà le focus | le mode menu basculait à l'appui : Alt+Maj (disposition du clavier) l'allumait | au relâchement d'un Alt seul, comme Windows | ||
menubar : un clic sur un titre grisé ou sur le vide de la barre | la barre gardait le clavier, le champ en saisie le perdait | le clavier reste au contrôle où l'on tapait | ||
menubar : is_shortcut posé sur une adresse qui ne nomme aucune entrée | la touche était prise dans toute la fenêtre, même après of_clear | rien n'est armé : posez-le après of_add_item | ||
pdfviewer : ib_allow_save / ib_allow_print d'une visionneuse | valaient pour toutes les visionneuses de l'application ; un of_reset ailleurs rendait Enregistrer à un document confidentiel | chaque visionneuse garde son réglage | ||
pdfviewer : ib_allow_save / ib_allow_print posés avant is_source | trois chargements, trois ue_load_completed ; un document en échec était retenté à chaque changement | un seul chargement ; un document en échec n'est pas retenté | ||
pdfviewer : ii_page posé pendant qu'un document est affiché, puis un autre is_source | le document suivant s'ouvrait à cette page | la page était celle du document affiché : le suivant s'ouvre à sa première page ; pour ouvrir un document sur une page, posez is_source puis ii_page | ||
pdfviewer : la même valeur reposée (ii_page, ii_zoom, is_fit, ib_viewer_toolbar) | rechargeait le document et relevait ue_load_completed | ne fait rien | ||
pdfviewer : ii_zoom hors de 25 à 500 | transmis tel quel au lecteur | ramené dans 25 à 500, relu tel qu'appliqué | ||
pdfviewer : une adresse https://nom:secret@… ; une source faite d'espaces | posée dans le lecteur, qui la refusait sous une raison approximative, le secret repartant dans les événements ; relue telle quelle, of_refresh rendait 0 | refusée tout de suite par ue_load_failed (REASON_UNSUPPORTED) : téléchargez le document par le restclient ; relue "", of_refresh rend -4 | ||
picture : id_max_zoom sur une image plus grande que son cadre | la molette, + et id_zoom montaient jusqu'à la taille réelle | ils s'arrêtent au plafond ; seule la touche 1 va au-delà | ||
picture : une nouvelle is_source, ou ib_zoomable = false, sur une image zoomée | le zoom revenait à 1.0 sans rien dire | ue_zoom_changed(1.0) est levé (of_reset reste muet) ; posez id_zoom après is_source | ||
picture : un chemin entouré de blancs (colonne CHAR) | refusé, REASON_UNSUPPORTED | affiché ; is_source se relit tel qu'écrit | ||
picture : touches du zoom avec Ctrl, Alt ou Windows enfoncé | Ctrl++ zoomait, Alt+1 montrait la taille réelle | laissées à votre application (raccourcis, mnémoniques) | ||
picture : une image recolorée (mono:, tint:) d'un autre site, dont le serveur refuse les requêtes d'une autre origine | ue_loaded et un cadre vide | ue_error avec REASON_FAILED, le message dit pourquoi | ||
radialmenu : is_tooltip, is_super_tooltip_title, is_super_tooltip_text, is_super_tooltip_image | existaient, ne montraient jamais rien : le lanceur n'a pas de surface | retirées : le compilateur montre la ligne, supprimez-la | ||
radialmenu : of_close, un second of_show, of_clear ou of_reset pendant qu'une roue est ouverte | ue_dismissed venait quand la roue quittait l'écran ; of_is_open restait vrai jusque-là | ue_dismissed aussitôt, une fois par ouverture ; of_is_open faux dès le retour de l'appel | ||
radialmenu : of_remove_item d'une branche que la roue ouverte ne montre pas (masquée) | la roue se fermait (ue_dismissed) | la roue reste ouverte ; elle ne se ferme que si elle montrait la branche | ||
radialmenu : of_remove_item avec une clé nue ("csv") | -5 | résolue comme par of_item (la seule branche qui la porte) ; -5 si deux branches la partagent | ||
radialmenu : of_show d'une roue sans rien à montrer pendant qu'une autre est ouverte | ue_dismissed, et l'ancienne roue restait à l'écran | l'ancienne roue se ferme aussi : un ue_dismissed pour chaque ouverture | ||
radialmenu : il_back_color_hover d'une branche sans il_text_color_hover | le libellé pointé gardait le texte du thème (blanc sur rose pâle en thème sombre) | un texte lisible sur cette teinte est choisi ; une couleur que vous posez n'est jamais changée | ||
restclient : ib_windows_auth ou is_client_certificate, et une redirection vers un autre hôte | les identifiants Windows et le certificat suivaient la redirection | seuls l'hôte et le port de la requête les reçoivent : l'autre hôte reçoit la requête sans eux | ||
restclient : une valeur d'en-tête au-delà du Latin-1 (grec, japonais…) | acceptée par of_set_header (0), puis chaque requête de l'objet rendait -5 | refusée dès of_set_header (-5, of_get_last_error() dit pourquoi) ; of_set_basic les accepte : sa paire part en base64 de son UTF-8 | ||
restclient : une méthode mal formée ("GE T"), des identifiants dans l'URL (https://user:mdp@…), un nom de champ d'of_upload qui contient un guillemet | -4 « request failed: 0 » ; les identifiants disparaissaient sans un mot ; le corps multipart était cassé | -5, et la raison dans of_get_last_error() (pour des identifiants : prenez of_set_basic) | ||
restclient : une 303, ou une 301 ou 302 après un POST, qui repart en GET | gardait le Content-Type du corps de départ | part sans Content-Type | ||
restclient : ue_progress | levé pour tout corps asynchrone, sans jamais atteindre le total : une barre restait à 39 % | levé pour tout corps asynchrone (la doc le dit), et le dernier, juste avant ue_response, vaut le total | ||
restclient : of_response_header d'un en-tête envoyé plusieurs fois (Link, Set-Cookie) | la première valeur seulement | toutes, jointes par , — Set-Cookie par un saut de ligne | ||
restclient : le User-Agent envoyé | PBToolboxAI/4.0, écrit en dur | la version de la bibliothèque ; of_set_header("User-Agent", …) le remplace toujours | ||
restclient : une requête quand le client HTTP n'a pas pu être créé | partait sur une session jetable, sans authentification Windows, certificat client ni cookies | -2, et il_status le dit | ||
restclient : of_set_header("Authorization", …) après of_set_basic | les deux authentifications partaient | une seule authentification : l'Authorization posée remplace le Basic | ||
ribbon : une valeur écrite par le code (is_text, id_value) pendant que le champ d'un combo ou d'un compteur a le focus | le champ gardait l'ancien texte ; en le quittant, ue_combo_changed / ue_value_changed partait avec l'ancienne valeur, qui remplaçait la vôtre | le champ l'affiche aussitôt, sauf si l'utilisateur est en train de taper (sa saisie gagne) ; quitter le champ sans avoir tapé ne lève rien | ||
ribbon : un libellé à balises (is_label, titre d'onglet, de groupe, de bandeau, bouton applicatif) | affiché tel quel, balises comprises (le panneau d'un groupe replié, lui, les interprétait) | le balisage riche est interprété partout ; un texte de l'utilisateur passe par of_escape_markup | ||
ribbon : la molette au-dessus du ruban | chaque petit mouvement d'un pavé tactile changeait d'onglet ; un ruban replié changeait aussi d'onglet sans rien montrer | un onglet par cran de molette (les petits mouvements se cumulent) ; rien sur un ruban replié | ||
ribbon : of_add_spinner avec un pas de 0 ou moins, ou un minimum au-dessus du maximum ; id_min / id_max / id_step incohérents | acceptés : flèches mortes ou inversées, une valeur hors de la plage affichée | of_add_spinner rend -5 et borne la valeur à la plage ; un pas de 0 ou moins est refusé (of_get_last_error dit pourquoi) ; une borne posée au-delà de l'autre l'emmène avec elle, comme dans un NumericUpDown — l'ordre des deux écritures ne compte plus | ||
ribbon : un is_keytip qui n'est pas fait de lettres A-Z et de chiffres ("É", "-") | gardé et relu, jamais atteignable au clavier | refusé : rien ne change, of_get_last_error dit pourquoi | ||
ribbon : Échap au second niveau des touches d'accès (les commandes d'un onglet) | fermait toutes les touches | remonte aux lettres des onglets, comme dans Office ; un second Échap ferme | ||
speechout : of_speak_from(0) ou un nombre négatif | lisait depuis la première phrase | -5, rien n'est lu (les positions comptent à partir de 1) | ||
speechout : ii_rate, ii_pitch, ii_volume posés hors de leur intervalle (ii_rate = 1000) | se relisaient tels que posés (1000) alors que la voix appliquait la borne | se relisent tels qu'appliqués (400) | ||
speechout : un morceau [rate]…[/rate] dans une phrase | une phrase à lui : son ue_sentence, son numéro, et un point après [/rate] devenait une « phrase » | reste dans sa phrase : un seul ue_sentence au texte entier, un seul numéro, ue_word compte dans ce texte, of_spoken_text une ligne par phrase ; la ponctuation part avec le morceau | ||
speechout : [rate=0] | lu à 100 % | le débit le plus lent, 10 % | ||
speechout : une règle de of_add_replacement sur un mot qui est aussi le nom ou la valeur d'une balise (total avec [mark=total], rate, un mot dans [spell]) | réécrivait la balise : la marque changeait de nom, la balise était lue à voix haute, le texte épelé changeait | la règle ne réécrit que le texte entre les balises | ||
speechout : un poste sans aucune voix | ue_error, puis une lecture « en cours » : ue_started, chaque ue_sentence, ue_stopped ; of_speak_sync rendait 0 | ue_error et rien d'autre : aucune lecture, pas de ue_started ; of_speak_sync rend -4 | ||
speechout : is_lang sans région ("fr", "en") | ue_voice_fallback à chaque lecture | aucun repli pour une voix de cette langue, quelle que soit sa région | ||
speechout : of_clear_queue derrière un of_speak (la lecture en cours n'est pas un texte de la file) | ue_queue_done à la fin de la lecture | pas de ue_queue_done : aucun texte de la file n'a été lu | ||
speechout : une initiale (John F. Kennedy), un mois abrégé (Oct. 10), un sigle à points (U.S.) | terminait la phrase | reste dans la phrase (un mois ou un sigle la termine devant une majuscule, comme etc.) : les numéros de phrase peuvent changer | ||
statusbar : un panneau cliquable grisé qui porte une infobulle | l'infobulle ne s'affichait jamais | elle s'affiche, pour dire pourquoi le panneau est grisé | ||
statusbar : of_count, of_keys_at, of_has sur l'adresse d'un panneau ("enc") | 0, "", false : les entrées de sa liste n'étaient pas vues | les entrées de sa liste, séparateurs exclus | ||
statusbar : une position dans une liste déroulante (of_insert_menu_item, of_move_menu_item) | comptait les séparateurs | compte les entrées seulement, comme les positions des panneaux | ||
statusbar : une clé de panneau ou d'entrée qui commence par __ | acceptée | refusée, -5 : elle est réservée au composant | ||
statusbar : is_tooltip et les cinq couleurs sur une entrée de liste (of_menu_item) | gardés et relus, sans effet | ignorés, relus vides (-1 pour une couleur) : le menu natif ne les montre pas | ||
statusbar : la poignée (ib_show_resize_grip) dans une feuille MDI, ou une barre qui n'est pas au bas de sa fenêtre | elle redimensionnait le cadre, par son coin | elle redimensionne la feuille ; pas de poignée quand la barre n'occupe pas le coin bas | ||
statusbar : la touche Menu ou Maj+F10 sur un panneau qui a le focus | rien | ue_panel_rclicked, au coin bas-gauche du panneau | ||
stepbar : Entrée ou Espace sur une étape, dans une fenêtre qui a un bouton par défaut | ue_step_clicked et le bouton par défaut (« Suivant ») se déclenchait | ue_step_clicked seulement : la touche reste à la barre | ||
stepbar : of_clear_steps quand la barre se tient sur une étape | ne levait rien | ue_step_changed(rang quitté, clé quittée, 1, ""), comme le retrait de l'étape en cours ; of_reset, lui, ne lève rien | ||
stepbar : ii_current au-delà de « tout terminé » (plus loin que le nombre d'étapes + 1) | ue_step_changed annonçait tout de suite un rang qui n'existait pas ; l'arrivée de l'étape était muette | rien n'est levé tant que la barre attend ; ue_step_changed est levé quand l'étape arrive | ||
stepbar : of_move_step sur une barre « tout terminé » | pouvait rouvrir la barre : une étape repassait en cours, avec ue_step_changed | la barre reste « tout terminé », rien n'est levé | ||
stepbar : NAV_VISITED, une étape insérée ou déplacée devant l'étape en cours | cliquable | affichée terminée, mais pas cliquable : elle n'a jamais été atteinte | ||
stepbar : une étape en avertissement (STATE_WARNING) | une pastille ambre | une pastille ambre et un second anneau ambre : elle ne ressemble plus à une étape faite là où l'accent est ambre | ||
statictext : ue_hyperlink | (string as_url) | (string as_url, boolean ab_opened) : un script déjà écrit pour l'événement reste valable ; ab_opened vaut FALSE quand le lien ne s'est pas ouvert (schéma autre que http, https, mailto — of_get_last_error() dit pourquoi —, ou gardé fermé par ue_hyperlink_opening) | ||
statictext désactivé sur un fond à lui (il_back_color, une portion [bk]) | le texte prenait le gris du thème, illisible sur un fond foncé ou coloré | ses couleurs sont gardées et atténuées ; sur la surface du thème, le gris du thème, comme avant | ||
statictext : PBT_SetDefaultFont avec une taille | la taille restait à 11 pt | la taille donnée s'applique (11 pt sans elle, inchangé) | ||
statictext : ii_font_size hors de 6 à 200 | appliquée telle quelle | ramenée à la borne la plus proche, comme la balise [size], et relue telle qu'appliquée | ||
statictext : double-clic sur un mot avec ib_selectable | un seul ue_clicked avant ue_double_clicked | deux ue_clicked puis ue_double_clicked, comme le StaticText de PowerBuilder ; relâcher après un glisser qui sélectionne reste sans clic | ||
statictext : of_reset d'un texte annoncé coupé | rien | ue_text_overflow(false) | ||
statictext : is_text relu après of_append_text, quand une ligne laissait une balise ouverte | [b]Start[br]two : reposé, le gras courait sur la ligne suivante | [b]Start[/b][br]two, ce que l'écran montre ; une ligne vide garde sa hauteur ; sous ib_marquee, les lignes défilent sur une seule ligne | ||
statictext : ib_auto_width et un texte vidé | gardait la largeur du texte précédent | se resserre à sa marge ; un changement de thème remesure aussi la largeur | ||
xml : of_count, of_get_values, of_get_attrs, of_get_attr_names quand rien n'est chargé, qu'un élément bâti est encore ouvert ou que le moteur refuse l'XPath | rendaient 0, comme une recherche sans résultat | rendent -4 (-2 si la page ne répond pas), of_get_last_error() dit pourquoi ; 0 est toujours un vrai zéro. Un test > 0 ne change pas ; un test = 0 qui voulait dire « rien trouvé » voit désormais le refus à part | ||
xml : of_get_attr et of_remove_attr d'un attribut absent, of_get_attrs avec un nom vide | vide sans raison, 0 (« fait »), 0 | vide et « no such attribute » dans of_get_last_error() (un attribut écrit vide reste sans raison), -4, -5 | ||
xml : of_set_value, of_set_attr, of_add_child d'un texte qui porte un caractère de contrôle (Char(1)) ou un CR | écrit tel quel : le document ne se rechargeait plus, le CR revenait en LF | le caractère interdit est retiré, comme par le builder ; le CR s'écrit et se relit | ||
xml : builder — un second élément au sommet, un texte sans élément ouvert, un attribut après un enfant | écrit (deux racines) ou ignoré sans un mot | laissé de côté, et of_get_last_error() dit pourquoi | ||
xml : of_get_value("sum(//qty)") sur un texte non numérique ; of_get_value("/") | le texte NaN ; vide | vide et « the expression is not a number » ; le texte du document |
La recette : rien à changer.
12.6 Ce qui a été ajouté #
Rien de ce qui suit ne demande de modifier votre code. Les huit nouveaux composants de la 5.0 sont présentés dans les notes de version.
| Objet | Ajouté |
|---|---|
| progressbar | is_unit : un texte écrit après la lecture ("of 500 rows", "MB") |
| datagrid | is_mask d'une colonne (n_pbt_datagrid_column) : le masque de saisie d'une colonne numérique ; une colonne sans format d'affichage montre son is_mask |
| datagrid | le clavier des en-têtes (Flèche haut depuis la première ligne ; Entrée trie, Maj+Entrée ajoute au tri ; Alt+Bas ou la touche Menu ouvre le menu de la colonne ; Ctrl+Maj+flèches la déplacent, Alt+flèches changent sa largeur) ; TYPE_TIME ; of_get_last_error dit pourquoi un appel a rendu -5 |
| ribbon | is_mask et is_format d'un compteur (n_pbt_ribbon_item) ; is_group : bascules exclusives d'un groupe (n_pbt_ribbon_item) et entrées radio d'un menu (n_pbt_ribbon_menu_item) ; ue_item_rclicked (clic droit sur un contrôle, un groupe, un onglet ou un bouton de la barre d'accès rapide, avec le point d'écran al_x, al_y ; touche Menu et Maj+F10 aussi) et ue_rclicked (hors item) ; is_title d'un groupe contextuel (n_pbt_ribbon_ctx_group), dont l'info-bulle s'affiche sur le bandeau ; touches d'accès des boutons de la barre d'accès rapide ; couleurs d'item des entrées de menu et des boutons de la barre d'accès rapide ; noms accessibles de tous les contrôles |
| breadcrumb | la saisie du chemin devient une barre d'adresse : ib_auto_complete, ue_path_typing et of_add_suggestion (complétion pendant la frappe), ib_veto_path, ue_path_entering et is_path_error (un chemin refusé garde la saisie) |
| chartcartesian | of_from_datastore (DataStore, DataWindow, DataWindowChild), of_map et les constantes ROLE_*, of_reload : le graphique d'un DataWindow (lignes sommées par catégorie et série, relu en place) ; of_set_point_color / of_get_point_color ; ue_point_rclicked, ue_rclicked ; of_get_categories ; of_remove_axis_section |
| codeeditor | of_undo, of_redo, ib_can_undo, ib_can_redo et ue_undo_state_changed (l'historique d'annulation pilotable) ; ue_modified_changed ; of_toggle_comment (Ctrl+/) ; of_next_marker (F8) ; ib_match_brackets ; ib_tab_moves_focus (Ctrl+M) |
| crypto | les blobs (of_base64_encode_blob, of_base64_decode_blob, of_hash_blob, of_hmac_blob, of_crc32_blob, of_encrypt_blob, of_decrypt_blob) ; of_base64_encode_file_to_file ; of_jwt_verify_jwks, of_jwk_to_pem, of_pem_to_jwk ; les claims attendues de of_jwt_verify et il_jwt_leeway_seconds ; JWT_HS384/HS512, JWT_RS384/RS512, JWT_PS256/PS384/PS512, JWT_ES384 et KEY_EC_P384 ; le schéma et le hachage de of_sign / of_verify (SIGN_PKCS1, SIGN_PSS) ; les données associées de of_encrypt_with_key / of_decrypt_with_key ; le hachage de of_rsa_encrypt / of_rsa_decrypt ; les réglages de of_totp_code, of_totp_verify, of_totp_uri et of_hotp_code ; of_password_needs_rehash |
| buttonbar | is_style d'un bouton (STYLE_PRIMARY, STYLE_FLAT, STYLE_DANGER), is_badge (une pastille de texte), il_badge_color, is_mnemonic, ii_image_size et ii_badge_size de la barre, ib_enabled de la barre entière, ue_button_rclicked et ue_rclicked, of_clear_shortcuts |
| commandpalette | of_load_menu(menu) : la palette remplie depuis un menu PowerBuilder, relu à chaque ouverture ; of_loaded_item(as_key) rend l'item d'une commande ; of_get_last_error() |
| dockcontainer | ib_front d'un panneau (n_pbt_dock_panel, lecture seule) : le panneau que sa pile montre ; l'entrée Masquage automatique du menu de panneau, aussi sur la languette du rail ; Maj+F10 et la touche Menu ouvrent ce menu sous l'onglet ; le panneau actif, celui qui a le clavier : of_active_panel() et ue_active_panel_changed(as_key) |
| crosstab | of_value(position) et sa poignée n_pbt_crosstab_value (une valeur de la zone Valeurs : is_agg, is_show, is_conditional_formatting, is_format, ib_negative_red, is_label, of_field()) ; of_value_count, of_remove_value, of_move_value ; of_get_cell_rows (les lignes du DataStore derrière une cellule) ; is_format d'un champ ; AGG_COUNT_ROWS, LABEL_BEFORE, LABEL_AFTER |
| messagebox | of_messagebox (les arguments de MessageBox(), Question!, YesNo! compris) et les constantes BUTTONS_* ; of_retry_cancel ; le bouton par défaut de of_confirm, of_yes_no, of_yes_no_cancel (al_default) ; Réessayer, Abandonner, Ignorer, Fermer traduits ; ib_closable, ib_sound ; is_details, is_details_label ; is_footer, is_footer_icon ; ib_input_multiline, il_input_max_length, is_input_pattern, is_input_error ; of_prompt qui masque et exige ; un choix désactivé (of_add_choice, ab_enabled) |
| jsontree | of_get_layout, of_set_layout et ue_layout_changed (les plis, la sélection, la ligne du haut) ; of_selected_addressable, of_selected_type, of_selected_count, of_copy_path ; ue_node_rclicked (clic droit, touche Menu) ; ib_find_decoded (la recherche dans les valeurs décodées, bascule &) |
| xmltree | of_find_xpath (chaque nœud d'un XPath, parcouru par of_search_next) ; of_get_layout, of_set_layout et ue_layout_changed (les plis, la sélection, la ligne du haut) ; of_selected_kind (constantes KIND_*), of_selected_name, of_selected_namespace, of_copy_path ; ue_node_rclicked (clic droit, touche Menu) ; ib_find_decoded (la recherche dans les valeurs décodées, bascule &) |
| json | of_from_datastore et of_to_datastore (DataStore, DataWindow, DataWindowChild) : un DataStore en tableau d'objets typés, et retour ; dates ISO 8601 (of_set_date, of_set_datetime, of_set_time, of_add_date, of_add_datetime, of_add_time, of_get_date, of_get_datetime, of_get_time) ; of_get_last_error et of_error_position (où un texte n'est pas du JSON) ; of_escape_key |
| listbar | ue_item_invoked (un clic sur l'entrée, déjà sélectionnée comprise) ; ib_search, is_filter, ue_filter_changed (une recherche) ; of_from_datastore (DataStore, DataWindow, DataWindowChild), of_map et les constantes ROLE_* (une ligne = une entrée) |
| markdownview | is_base_path, ib_allow_html (une courte liste de balises HTML inertes), ib_network_pictures, ib_remote_pictures, ib_tasks_editable et ue_task_toggled, ib_track_heading et ue_heading_visible, is_position, ii_zoom, of_selected_text, of_copy et Ctrl+Inser, les constantes LINK_* ; les alertes GitHub, les adresses e-mail nues et les émojis |
| menubar | of_load_menu(menu) : toute la barre depuis le menu PowerBuilder d'une fenêtre, relu à chaque ouverture, ses Clicked exécutés ; of_loaded_item ; of_insert_item (une entrée à un rang) et of_clear_items (vider une cascade en gardant l'entrée) ; of_open, of_close, of_is_open |
| pdfviewer | of_load_blob(blob) et of_load_blob(blob, string) : un PDF tenu dans un blob (lu par SELECTBLOB), affiché sans fichier, quelle que soit sa taille ; is_find (un texte surligné à l'ouverture) ; ib_navigation_pane (le panneau latéral du lecteur) ; is_destination (ouvrir sur une destination nommée du PDF) ; ib_allow_search, ib_allow_rotate et ib_allow_fullscreen (les commandes Rechercher, Faire pivoter et Plein écran de la barre du lecteur) |
| picture | of_set_picture(blob) : une image tenue en mémoire (SelectBlob), comme SetPicture du Picture natif ; ib_clickable : l'image devient un bouton au clavier (Tab, Entrée, Espace) ; les formats TIFF, WMF, EMF et RLE, convertis à la volée ; un nom pour les lecteurs d'écran qui dit la pastille et l'échec |
| radialmenu | of_show_over(dragobject ado_control {, boolean ab_keyboard}) : la roue centrée sur un contrôle, sa première branche allumée quand elle vient du clavier ; sur la poignée de branche, is_image (icône changée en place), is_tone (constantes TONE_* de u_pbt_radialmenu) et is_group (groupe radio) |
| restclient | of_url et of_url_encode (une requête d'URL encodée) ; of_post_form et of_post_form_async (un formulaire HTML) ; of_oauth_client_credentials (un jeton OAuth2 renouvelé de lui-même) ; of_retrieve (DataStore, DataWindow, DataWindowChild : un tableau JSON en lignes) ; les en-têtes d'une seule requête (of_request et of_request_async, quatrième argument as_headers) ; is_last_request ; ib_check_revocation |
| statusbar | ib_spring (et une largeur de -1 dans of_add_panel, of_insert_panel) : un panneau qui prend la place libre ; of_dock_bottom (la barre au bas de sa fenêtre) ; is_help et is_help_panel (la MicroHelp d'un cadre PowerBuilder) ; ib_announce (lecteurs d'écran) ; l'infobulle d'un texte élidé |
| tilesbox | of_move_tile(as_keys, as_to_key, al_position) : une tuile envoyée par le code dans un autre groupe, avec ses couleurs, sa pastille et ses faces ; Échap annule un glisser, le panneau défile quand le pointeur approche de son bord ; un lecteur d'écran entend la pastille et le bandeau d'une tuile ; une icône SVG reste nette sur une grande tuile ; l'entête d'un groupe s'éclaire au survol ; « moins d'animations » de Windows respecté |
| statictext | ib_mnemonic (le & d'un libellé PowerBuilder), ii_max_lines (au plus N lignes, « … »), il_max_log_lines et of_clear (un journal borné, vidé), ii_max_width (plafond de ib_auto_width), ib_veto_links et ue_hyperlink_opening (décider si un lien s'ouvre) ; un journal est annoncé ligne à ligne aux lecteurs d'écran ; désactivé, les zones du balisage sortent de l'ordre de Tab |
| xml | of_get_number, of_get_decimal, of_get_longlong, of_get_boolean, of_get_date, of_get_datetime : la valeur à l'XPath vérifiée contre son type XML Schema et lue pareil sur tout poste (NULL et of_get_last_error() si elle n'est pas de ce type) |
| xml | surcharges decimal, date, datetime, boolean de of_leaf, of_element_attr et of_set_value : écrites avec un point et en ISO 8601 quel que soit le poste |
12.7 buttonbar : la clé, le libellé puis l'icône ; le « & » et l'accord #
La barre de boutons parlait autrement que le reste de la bibliothèque : l'icône avant le libellé, la position en deuxième argument, et un is_shortcut qui voulait dire « lettre Alt » là où il veut dire « accord » partout ailleurs — is_shortcut = "Ctrl+S" armait Alt+C. La 5.0 l'aligne sur button, la barre d'outils et le CommandButton de PowerBuilder.
| Quoi | 4.0 | 5.0 |
|---|---|---|
| Ajouter un bouton | uo.of_add_button("save", "img\save.png", "Save") | uo.of_add_button("save", "&Save", "img\save.png") |
| Un bouton texte seul | uo.of_add_button("ok", "", "OK") | uo.of_add_button("ok", "OK") |
| Insérer un bouton | uo.of_insert_button("mid", 2, "", "Mid") | uo.of_insert_button("mid", "Mid", "", 2) |
| La lettre Alt d'un bouton | is_shortcut ← "S" (Alt+S) | le libellé "&Save", ou uo.of_button("save").is_mnemonic = "S" |
| Un accord sur un bouton | uo.of_register_shortcut("Ctrl+S", "save") | le même, ou uo.of_button("save").is_shortcut = "Ctrl+S" — affiché dans l'info-bulle |
| Un « & » dans un libellé | affiché tel quel | marque la lettre Alt ; && pour un « & » écrit |
| La pastille | uo.of_button("inbox").il_badge = 3 | uo.of_button("inbox").is_badge = "3" (un texte : "New", "!") ; il_badge reste accepté |
Le bouton focalisé, sans is_default | peint en accent plein | son anneau de focus seulement |
is_shortcutd'un bouton est un accord. Pendant la 5.0, une lettre seule y est encore lue comme la lettre Alt de la 4.0 (elle passe dansis_mnemonic) ; écrivez plutôt le « & » dans le libellé. Un accord que la fenêtre ne peut jamais lever (une lettre seule,Ctrl+Shift) est refusé :is_shortcutse relit vide,of_register_shortcutrend-5.- Un bouton grisé ne vole plus de touche. Le bouton par défaut grisé d'une barre, ou la lettre Alt d'un bouton grisé, laisse Entrée et la lettre à la fenêtre — elles ne partent plus au bouton d'une AUTRE barre (deux feuilles MDI) ; l'accord d'un bouton grisé laisse sa touche à la fenêtre (un accélérateur de menu, par exemple). Les flèches sautent un bouton grisé.
// 4.0 : the icon before the label
uo_bar.of_add_button(/*key*/ "save", /*image_file*/ "img\save.png", /*text*/ "Save")
// The Alt letter went to is_shortcut (the letter S alone), the chord to of_register_shortcut
uo_bar.of_register_shortcut(/*chord*/ "Ctrl+S", /*key*/ "save")
// 5.0 : key, label, icon - the "&" of the label gives Alt+S
uo_bar.of_add_button(/*key*/ "save", /*text*/ "&Save", /*image*/ "img\save.png")
// The chord is a property of the button, shown in its tooltip
uo_bar.of_button(/*key*/ "save").is_shortcut = "Ctrl+S"
La recette : compilez ; un appel d'of_insert_button est signalé (la position passe en dernier). Un of_add_button à trois arguments compile toujours : échangez les deux derniers (le libellé, puis l'icône) — un bouton dont le libellé est un chemin de fichier vous montre ceux qui restent. Remplacez chaque is_shortcut d'une lettre par un « & » dans le libellé, et doublez tout « & » qui doit s'afficher (R&&D).
12.8 crosstab : le format des valeurs par is_format #
Le croisé écrivait les nombres d'une mesure par une fonction à quatre ou cinq arguments (décimales, séparateur de milliers, symbole, symbole devant), qui valait pour toutes les valeurs d'un champ : le même champ deux fois en Valeurs — le montant, et sa part du total — ne pouvait pas avoir deux formats. La 5.0 le range sous la langue des graphiques et des jauges : un format d'affichage PowerBuilder dans is_format, sur la poignée du champ (of_field) pour toutes ses valeurs, ou sur la poignée d'une valeur (of_value(position), nouvelle) pour elle seule. Vide, une valeur prend le Format de la colonne du DataWindow. Aucun ancien nom ne survit.
| Quoi | 4.0 | 5.0 |
|---|---|---|
| Le format de toutes les valeurs d'un champ | uo.of_set_value_format("amount", 2, "locale", "$", true) | uo.of_field("amount").is_format = "$#,##0.00" |
| Un symbole après le nombre | uo.of_set_value_format("amount", 0, "", " EUR") | uo.of_field("amount").is_format = '#,##0" EUR"' |
| Le format d'une valeur (le même champ deux fois) | — | uo.of_value(2).is_format = "#,##0.00" |
| Les négatifs en rouge | le menu de la puce seulement | uo.of_value(1).ib_negative_red = true |
| Revenir au format par défaut | uo.of_clear_value_format("amount") | uo.of_field("amount").is_format = "" (le Format de la colonne du DataWindow) |
- Le séparateur de milliers d'une valeur sans format reste
is_thousands, comme le menu Options de la grille : c'est ce que faisait unof_set_value_formatau séparateur vide. La devise que propose le menu de la puce resteis_currency_symbol. - Une valeur sans format montre désormais le Format de sa colonne du DataWindow, lu par
of_from_datastore: un montant dont la colonne porte#,##0.00s'affiche avec deux décimales sans une ligne de code.
// 4.0 : decimals, thousands, symbol and its side as arguments - for every value of the field
uo_cross.of_set_value_format(/*field*/ "amount", /*decimals*/ 2, /*thousands*/ "locale", /*suffix*/ "$", /*symbol_before*/ true)
// 5.0 : a display format, written as in a DataWindow - for the field, then for its second value alone
uo_cross.of_field(/*field*/ "amount").is_format = "$#,##0.00"
uo_cross.of_value(/*position*/ 2).is_format = "#,##0"
La recette : compilez ; chaque of_set_value_format et of_clear_value_format est signalé. Écrivez le format comme dans une DataWindow : ai_decimals donne le nombre de 0 après le point, un séparateur de milliers donne le , du groupement ("none" : aucun), le symbole s'écrit devant ou derrière (entre guillemets s'il contient des chiffres ou des espaces). Le format d'une seule valeur va dans of_value(<position>).is_format.
12.9 listbar : le clic droit porte son point, une disposition s'annonce #
La barre latérale rejoint la bibliothèque sur trois points : le clic droit d'une entrée donne son point d'écran comme celui des arbres, des grilles et du kanban ; un ordre du code qui change la disposition l'annonce comme un geste ; une entrée grisée ne devient plus la sélection. Elle gagne aussi un événement pour le clic sur l'entrée déjà sélectionnée, une recherche et la construction depuis un DataStore (12.6).
| Quoi | 4.0 | 5.0 |
|---|---|---|
ue_item_rclicked | (string as_keys) | (string as_keys, long al_x, long al_y) : le point en pixels d'écran ; la touche Menu et Maj+F10 le lèvent aussi |
of_set_layout qui change la disposition | aucun événement | un ue_layout_changed (jamais ue_section_toggled) |
of_move_item / of_move_section vers le rang déjà tenu | ue_layout_changed | rien : rien n'a bougé |
of_select_item d'une entrée grisée | 0, elle devenait la sélection | -5, sans poser ue_selection_changing ; griser l'entrée déjà sélectionnée la garde |
ib_auto_width relu pendant que la barre est en rail | true | ce que l'application a posé |
of_item d'une adresse à un seul niveau ("nav") | atteignait la section | une poignée qui ne nomme rien ; une section s'atteint par of_section |
| La même lettre tapée deux fois | un préfixe dd, souvent sans correspondance | la ligne suivante qui commence par elle ; un Espace au milieu d'un préfixe lui appartient |
| Une entrée grisée sous le pointeur | sans info-bulle | son info-bulle s'affiche ; le clic ne fait toujours rien |
// 4.0 : PointerX() of the userobject - the menu opened too high under a ribbon
m_entry.PopMenu(PointerX(), PointerY())
// 5.0 : the pointer of the WINDOW for a PowerBuilder menu (al_x, al_y serve a menu of the library)
m_entry.PopMenu(parent.PointerX(), parent.PointerY())
La recette : rien ne refuse de compiler — un script de ue_item_rclicked garde as_keys. Ouvrez votre menu au pointeur de la fenêtre (parent.PointerX()), ou passez al_x, al_y à of_show d'un contextmenu. Posez la sélection initiale avant d'armer ib_veto_selection, et vérifiez que votre ue_layout_changed accepte l'appel que lève désormais of_set_layout.
12.10 scheduler : la nature d'un changement et les valeurs d'avant #
Le calendrier rejoint le diagramme de Gantt : la question posée avant un geste dit s'il s'agit d'un déplacement ou d'un redimensionnement, et les événements qui suivent donnent les valeurs d'avant — un journal, une annulation ou une confirmation n'ont plus à garder leur copie de chaque rendez-vous. Une sélection que votre code retire est annoncée, et quatre appels refusent désormais ce qu'ils acceptaient en silence.
| Quoi | 4.0 | 5.0 |
|---|---|---|
ue_appointment_changing | (string as_key, string as_start, string as_end, string as_resource) | (string as_key, string as_kind, string as_start, string as_end, string as_resource) : as_kind vaut CHANGE_MOVE ou CHANGE_RESIZE |
ue_appointment_moved | (string as_key, string as_start, string as_end, string as_resource) | (string as_key, string as_start, string as_end, string as_resource, string as_old_start, string as_old_end, string as_old_resource) |
ue_appointment_resized | (string as_key, string as_start, string as_end) | (string as_key, string as_start, string as_end, string as_old_start, string as_old_end) |
| Votre code retire, vide ou recharge le rendez-vous sélectionné | aucun événement | ue_selection_changed("") ; of_reset reste muet |
of_add_appointment dont la fin précède le début | 0, la fin devenait début + 30 min | -5, of_get_last_error dit pourquoi |
of_scroll_to_time("abc") | 0, rien ne défilait | -5 |
of_set_field sur la colonne qui joue ROLE_KEY | 0, deux rendez-vous d'une même clé | -5 : une clé change en rechargeant |
of_show_appointment d'un rendez-vous masqué, filtré ou sur une ressource masquée | 0, la vue partait vers un jour où rien ne se voyait | -5, rien ne bouge |
is_now posé après une navigation de l'utilisateur | ramenait la vue à son jour | la vue reste où l'utilisateur est allé |
of_clear_appointments | gardait les colonnes du DataStore pour of_map | oublie le DataStore : of_map accepte les colonnes du suivant |
// 5.0 : ue_appointment_changing event of uo_sched : (string as_key, string as_kind, string as_start, string as_end, string as_resource) returns boolean
// A resize keeps the day : only a move is checked
if as_kind = u_pbt_scheduler.CHANGE_RESIZE then return true
// Nothing on a Saturday or a Sunday : returning false puts the appointment back
if DayNumber(Date(Left(as_start, 10))) = 1 or DayNumber(Date(Left(as_start, 10))) = 7 then return false
return true
La recette : rien ne refuse de compiler — un script de ue_appointment_changing, ue_appointment_moved ou ue_appointment_resized garde ses arguments, les nouveaux s'y ajoutent. Si votre ue_selection_changed active des boutons, il reçoit maintenant "" quand le rendez-vous sélectionné part ; relisez les codes retour d'of_add_appointment, of_scroll_to_time, of_set_field et of_show_appointment, qui peuvent désormais rendre -5. Pour enregistrer les gestes sans code, voyez ib_write_back.
12.11 shellexplorer : l'erreur dit sa raison #
L'explorateur du shell donne désormais, dans ue_error comme dans ue_path_not_found, une raison que votre code peut tester — une constante REASON_* de u_pbt_shellexplorer, la même dans toutes les langues de Windows. Il ne lève plus ue_selected pour le dossier déjà sélectionné, et annonce par ue_collapsed une branche qu'il referme de lui-même. Il gagne aussi le clic droit sur un dossier (ue_node_rclicked) et l'adresse de la racine.
| Quoi | 4.0 | 5.0 |
|---|---|---|
ue_error | (string as_message) | (string as_path, string as_reason, string as_message) : le chemin ("" pour le Bureau), une constante REASON_*, le texte du shell |
as_reason de ue_path_not_found | une phrase anglaise (not found, outside the root, not a branch…) | une constante REASON_* (not_found, outside_root, not_a_branch…) ; not_shown pour un chemin qui existe mais que l'arbre ne montre pas |
| Re-sélectionner le dossier déjà sélectionné (clic, Début sur la première ligne) | ue_selected | rien |
| Une branche que l'arbre referme de lui-même (revenue vide, refusée par le shell) | aucun événement | ue_collapsed |
ib_show_files, ib_show_hidden, is_file_filter, is_root écrits avec leur valeur | l'arbre est relu | rien n'est relu ; is_file_filter posé sans les fichiers attend qu'ils soient montrés |
of_collapse d'un chemin dessiné deux fois | chaque ligne, un ue_collapsed chacune | la ligne qu'atteint of_select, un ue_collapsed |
of_count(""), of_keys_at("", i) | les lignes affichées, comme of_count() | le premier niveau (la racine), comme of_count(is_root) |
// 5.0 : ue_error event of uo_tree : (string as_path, string as_reason, string as_message)
// Test the reason, never the text of the shell
if as_reason = u_pbt_shellexplorer.REASON_TIMEOUT then
st_status.text = "The network folder " + as_path + " does not answer"
else
st_status.text = as_message
end if
La recette : rien ne refuse de compiler — un script de ue_error garde as_message, les nouveaux arguments s'y ajoutent. Un test sur le TEXTE de as_reason dans ue_path_not_found ("not found", "outside the root") se réécrit avec une constante REASON_* ; une application qui rechargeait un volet à chaque ue_selected le fait désormais une fois par changement.
12.12 tilesbox : le clic droit porte son point, un ordre du code s'annonce, la disposition laisse les droits à l'application #
Le panneau de tuiles rejoint la bibliothèque : son clic droit donne le point d'écran comme celui des arbres, des grilles et du kanban ; un ordre du code qui déplace une tuile, replie un groupe ou change une taille lève les mêmes événements qu'un geste ; la disposition ne porte plus la visibilité, qui reste l'affaire de l'application. Il gagne aussi le déplacement d'une tuile vers un autre groupe par le code (12.6).
| Quoi | 4.0 | 5.0 |
|---|---|---|
ue_tile_context | (string as_keys) | ue_tile_rclicked (string as_keys, long al_x, long al_y) : le point en pixels d'écran ; la touche Menu et Maj+F10 le lèvent aussi, au coin bas-gauche de la tuile |
of_move_tile, of_insert_tile | integer ai_index | long al_position ; une surcharge of_move_tile(as_keys, as_to_key, al_position) envoie la tuile dans un autre groupe |
of_move_tile vers une autre place | rien | ue_tile_moved, ue_layout_changed |
ib_collapsed d'un groupe posé par le code | ue_group_toggled | ue_group_toggled, ue_layout_changed |
is_size posé par le code | rien | ue_layout_changed (jamais ue_tile_resized, qui dit que l'utilisateur l'a choisie) |
is_size d'une taille inconnue ("huge") | la tuile passait en medium | refusé : rien n'est écrit, of_get_last_error dit pourquoi ; of_add_tile / of_insert_tile rendent -5 |
La disposition (of_get_layout, ue_layout_changed) | portait la visibilité des groupes et des tuiles | ne la porte plus : of_set_layout ne ré-affiche jamais ce que votre code a masqué ; une disposition 4.0 se relit sans elle |
of_set_layout qui change la disposition | aucun événement | un ue_layout_changed ; -5 sur un JSON qui n'est pas une disposition ({}) |
of_tile / of_group d'une adresse qui ne nomme rien | une poignée par appel, gardée | la poignée inerte, la même pour toutes : elle n'écrit rien et se relit vide |
// 4.0 : the right click of a tile
// ue_tile_context event of uo_tiles : (string as_keys)
// 5.0 : the same script, under the new name, with the screen point
// ue_tile_rclicked event of uo_tiles : (string as_keys, long al_x, long al_y)
La recette : compilez ; votre script de ue_tile_context reste sur un événement qui n'existe plus — déplacez-le dans ue_tile_rclicked, qui garde as_keys. Si votre ue_layout_changed enregistre la disposition, il voit désormais aussi ce que votre code change ; un ue_tile_moved qui ne doit réagir qu'à l'utilisateur ignore les déplacements que votre code vient de faire. Si vous rangiez la visibilité dans la disposition, posez-la par le code à l'ouverture (ib_visible), selon les droits.
12.13 tab : le clic droit porte son point, une disposition appliquée s'annonce #
L'onglet rejoint la bibliothèque : le clic droit d'un onglet, menu intégré coupé, donne son point d'écran comme celui des arbres, des grilles et du kanban, et of_set_layout qui change la disposition l'annonce comme un geste. Un glisser rendu à sa place n'annonce plus rien. Il gagne aussi des pages créées à la demande (ue_page_needed, of_supply_page), le double-clic (ue_tab_double_clicked), ib_cycle_keys, is_close_mode, ii_strip_width et, sur une page, ib_modified et is_badge — voir la page de l'onglet.
| Quoi | 4.0 | 5.0 |
|---|---|---|
ue_tab_rclicked | (string as_key) | (string as_key, long al_x, long al_y) : le point en pixels d'écran ; la touche Menu et Maj+F10 le lèvent aussi, au coin bas-gauche de l'onglet |
of_set_layout qui change la disposition | aucun événement | ue_layout_changed, une fois |
un glisser rendu à sa place, of_move_page à sa propre place | ue_tab_reordered et ue_layout_changed | rien : l'ordre n'a pas changé |
plusieurs déplacements sous of_set_redraw(false) | un ue_layout_changed par déplacement | un seul, à la reprise |
| Maj+F10 sur un onglet, menu intégré | le menu s'ouvrait sous la souris | sous l'onglet |
| bande verticale et titre long | la bande prenait la largeur du titre | 40 % du composant au plus, points de suspension ; ii_strip_width la fixe |
il_accent d'une page | l'anneau de focus seulement | souligne aussi l'onglet actif |
is_shortcut sur la poignée d'une clé sans page | inscrit : la touche était prise pour rien | rien n'est inscrit, of_get_last_error dit pourquoi |
of_insert_page dont le déplacement échoue | code négatif, la page restait | code négatif, la page est retirée |
// 4.0 : the right click of a tab, built-in menu off
// ue_tab_rclicked event of uo_tabs : (string as_key)
// 5.0 : the same script, with the screen point
// ue_tab_rclicked event of uo_tabs : (string as_key, long al_x, long al_y)
La recette : rien ne refuse de compiler — un script de ue_tab_rclicked garde as_key. Ouvrez votre menu au pointeur de la fenêtre (parent.PointerX()), ou passez al_x, al_y à of_show d'un contextmenu. Vérifiez que votre ue_layout_changed accepte l'appel que lève désormais of_set_layout.
12.14 soundplayer : le numéro d'un son, un refus rendu tout de suite #
Le lecteur de sons change trois choses que votre code peut voir. Ses événements portent le numéro du son : ue_started, ue_ended et ue_failed reçoivent un dernier argument, al_sound — le numéro que rendent désormais of_play_over et of_enqueue (ils rendaient 0), et que prend le nouveau of_stop_sound. Une source refusée d'emblée est un code : of_play, of_play_over, of_crossfade et of_preload rendent -5, la raison dans of_get_last_error(), pour une source vide, une adresse http://, une adresse file:// mal formée ou un format refusé par son nom — et ne lèvent plus ue_failed ; le son en cours continue. Dans la file (of_enqueue), le refus arrive toujours par ue_failed, à son tour. D'autres -5 : of_pause et of_resume sans rien à suspendre ou reprendre, of_beep et of_beep_sync à 0 Hz ou 0 ms, of_meter hors de 1 à 64 barres.
// Local variables
string ls_url
long ll_rc
// The address of the sound, typed by the user
ls_url = sle_url.text
// 4.0 : of_play returned 0, and an http:// address came back later through ue_failed
// 5.0 : the refusal is a code, at once ; of_get_last_error() gives the reason
ll_rc = inv_sound.of_play(/*source*/ ls_url)
if ll_rc = -5 then
MessageBox("Sound", inv_sound.of_get_last_error())
end if
Ce qui change sans rien demander à votre code : of_stop s'éteint désormais sur il_fade_ms, comme la documentation le promettait (ue_stopped arrive toujours tout de suite) ; à l'échéance de il_timeout_ms, seul le son de l'appel synchrone est coupé — le fond, les superpositions et la file continuent ; of_crossfade vers une source refusée garde la piste en cours ; of_level vaut 0 et of_spectrum ne rend aucune barre, vumètre éteint ; of_equalizer(ab_on, ai_gains[]) remet à 0 une bande que le tableau n'atteint pas ; of_clear_queue oublie aussi les sons que la file a déjà joués ; les messages de ue_failed suivent la langue d'affichage (as_reason reste le mot à tester). Le lecteur gagne aussi la file navigable (of_next, of_previous, of_queue_index, ue_source_changed, ib_queue_repeat), la boucle sans blanc (ib_gapless_loop, REASON_TOO_LONG), le segment (of_play_range), le muet (ib_muted) et la mise en mémoire tampon (ue_buffering, of_is_buffering) — voir la page du lecteur de sons.
La recette : rien ne refuse de compiler — un script de ue_started, ue_ended ou ue_failed garde ses arguments, al_sound s'y ajoute. Relisez les tests de code retour d'of_play_over et d'of_enqueue (un = 0 devient > 0), et le code qui attendait ue_failed pour une adresse http:// ou une source vide : il teste maintenant le -5 de l'appel.
12.15 toaster : la raison d'une fermeture, un toast fermé par le code s'annonce toujours #
Le toaster dit pourquoi un toast s'est fermé : ue_toast_dismissed reçoit un dernier argument, as_reason — REASON_TIMEOUT, REASON_USER (sa croix), REASON_CODE (of_close, of_close_all) ou REASON_OWNER_CLOSED (sa fenêtre s'est fermée). Et tout toast fermé par le code l'annonce, même fermé juste après of_show, avant d'être dessiné, ou pendant qu'il attendait sa place : une application qui attendait ue_toast_dismissed pour libérer son état ne dépend plus d'une course.
| Quoi | 4.0 | 5.0 |
|---|---|---|
ue_toast_dismissed | (long al_id, string as_key) | (long al_id, string as_key, string as_reason), constants REASON_* |
of_close d'un toast pas encore dessiné, ou en attente de place | rien n'était levé | ue_toast_dismissed, REASON_CODE |
of_close d'un toast d'un autre toaster | le fermait, l'annonce partait chez l'autre | -5, rien n'est fermé, of_get_last_error dit pourquoi |
la fenêtre d'ipo_owner se ferme | ses toasts disparaissaient sans rien dire | ue_toast_dismissed, REASON_OWNER_CLOSED |
| un toaster détruit, toasts à l'écran | ils restaient, muets | les persistants et ceux à boutons se ferment avec lui ; les autres finissent seuls |
of_show avant que le moteur d'affichage soit prêt | -6 : « runtime absent » | -4 : réessayer ; of_get_last_error dit pourquoi |
| coin d'un toast ancré à la fenêtre | la fenêtre entière : le toast couvrait la barre de titre et ses boutons | la zone cliente (celle du cadre en MDI) |
| un titre très long | poussait la croix et les boutons hors de la fenêtre | plafonné, il défile |
// 4.0
// event ue_toast_dismissed de inv_toaster : (long al_id, string as_key)
// 5.0 : le meme script, avec la raison
// event ue_toast_dismissed de inv_toaster : (long al_id, string as_key, string as_reason)
La recette : rien ne refuse de compiler — un script de ue_toast_dismissed garde al_id et as_key, as_reason s'y ajoute. Relisez le code qui supposait qu'un toast fermé tout de suite par of_close ne dirait rien : il l'annonce maintenant. Les toasts restent accrochés au toaster qui les a montrés : un of_close sur l'identifiant d'un autre toaster rend -5. Le toaster gagne aussi of_close_all (fermer tous ses toasts) et of_get_last_error — voir la page du toaster.
12.16 video : un refus rendu tout de suite, un film et ses sous-titres d'un seul appel, le même film repris #
Le lecteur vidéo change cinq choses que votre code peut voir. Un refus est rendu tout de suite, comme au lecteur de sons (12.14) : of_play(), of_play(source) et of_play_range rendent -5, la raison dans of_get_last_error(), pour une source vide, une adresse http:// ou un format refusé par son nom (avi, wmv, flv) — et ne lèvent plus ue_failed ; le film en cours continue. La propriété is_source garde son ue_failed : une propriété n'a pas de code retour. Le même film n'est pas rechargé : of_play(source) ou is_source sur le film déjà chargé le reprend où il est (ue_resumed), au lieu de le faire repartir du début ; of_seek(0) le fait repartir. Une recherche reste dans le segment de of_play_range, celle de l'utilisateur comme of_seek : Début mène au début du segment, un clic au-delà de sa fin à sa fin — avant, Début sortait de l'extrait et un clic au-delà arrêtait le film. Une entrée de liste qui ne peut pas jouer lève ue_source_changed d'abord, puis un seul ue_failed — il venait avant, et deux fois. of_stop devient une fonction : il rendait rien (subroutine), il rend 0, ou -2 quand le composant n'est pas créé — comme of_stop du navigateur web.
// Local variables
string ls_path
long ll_rc
// The film chosen by the user
ls_path = sle_film.text
// 4.0 : of_play returned 0, and an http:// address or an .avi came back later through ue_failed
// 5.0 : the refusal is a code, at once ; the reason is in of_get_last_error
ll_rc = uo_video.of_play(/*source*/ ls_path)
if ll_rc = -5 then
MessageBox("Video", uo_video.of_get_last_error())
end if
Ce qui change sans rien demander à votre code : un marqueur atteint par une recherche EN PAUSE ne lève plus ue_marker_reached (seulement ue_seeked) ; Espace et le bouton Lecture d'un lecteur sans film ne font plus rien (ils levaient ue_failed(REASON_NO_SOURCE)) ; la langue de sous-titres choisie par l'utilisateur suit au film suivant de la liste ; une affiche http:// est refusée et is_poster se relit vide ; is_subtitles refusé se relit vide ; un sous-titre du poste introuvable lève ue_subtitles_failed(REASON_NOT_FOUND) ; le menu de vitesse se pilote au clavier et ses flèches ne changent plus le volume ; en plein écran la barre se montre au clavier ; la position retenue (ib_remember_position) ne dépend plus de l'écriture du chemin, et seuls les 200 derniers films sont gardés (une position de la 4.0 est relue une fois). Le lecteur gagne of_play(source, subtitles) (le film et SES sous-titres : posés avant un deuxième film, ils partaient avec le premier), ib_forward_seek, of_watched_ms, of_watched_percent, ue_watched_completely et ib_skip_failed — voir la page du lecteur vidéo.
La recette : rien ne refuse de compiler. Relisez le code qui attendait ue_failed après of_play pour une adresse http://, une source vide ou un .avi : il teste désormais le -5 de l'appel. Relisez aussi un bouton « Lire » qui comptait sur of_play(source) pour repartir du début : ajoutez of_seek(0).
12.17 webbrowser : un geste de l'utilisateur est demandé, une page d'of_show_html n'a pas d'adresse #
Avec ib_veto_navigation = true, ue_navigating est désormais demandé aussi pour un geste de l'utilisateur : une adresse tapée dans la barre, Ouvrir le lien du menu contextuel, une nouvelle fenêtre ouverte par un clic. En 4.0, ces trois chemins ne posaient pas la question. Seule une adresse posée par votre code n'est jamais demandée, et une redirection du serveur ne l'est pas non plus : pour une liste de serveurs qui vaut aussi pour les redirections, posez la nouvelle propriété is_allowed_hosts.
| Quoi | 4.0 | 5.0 |
|---|---|---|
ue_navigating sous véto : adresse tapée, Ouvrir le lien, nouvelle fenêtre | la page s'ouvrait sans question | la question est posée ; false laisse la page |
is_address, la barre, ue_load_completed après of_show_html | toute la page encodée (data:text/html;charset=utf-8,…, jusqu'à 2 Mo) | "" |
is_title d'une page sans <title> | son adresse | "" |
of_go_back, of_go_forward, of_stop | sans retour | long : 0 une fois demandé, -2 composant non créé |
ib_private changé après une page | is_address, is_title, la barre et les flèches gardaient la page d'avant | tout se relit vide : la vue est neuve |
| Entrée sur une barre d'adresse vide | la page devenait blanche | rien |
| Une page du site se charge, barre d'adresse affichée | Recharger reste Recharger | Recharger devient Arrêter, et revient une fois la page chargée |
La recette : rien ne refuse de compiler, un long ignoré compile. Un script de ue_navigating écrit pour les liens du site voit désormais aussi les adresses tapées par l'utilisateur : s'il décide sur l'adresse, qu'il compare son hôte, comme l'exemple de la page du composant — ou confiez la liste à is_allowed_hosts. Le code qui lisait as_url de ue_load_completed, ou is_address, après of_show_html reçoit une chaîne vide.
12.18 toolbar : le clic droit porte son point, un ordre du code s'annonce #
La barre d'outils rejoint la bibliothèque : le clic droit d'un outil donne son point d'écran, comme celui des arbres, des grilles et de l'onglet, et déplacer une barre par ii_band / ii_index lève ue_bar_reordered comme le geste. Deux ajouts refusent ce qu'ils acceptaient en silence, et un raccourci posé là où rien ne vit n'est plus inscrit. Elle gagne aussi is_text sur une barre, un nom pour chaque outil et chaque champ lu par un lecteur d'écran, et un clavier qui traverse les champs — voir la page de la barre d'outils.
| Quoi | 4.0 | 5.0 |
|---|---|---|
ue_item_rclicked | (string as_keys) | (string as_keys, long al_x, long al_y) : le point en pixels d'écran ; la touche Menu et Maj+F10 le lèvent aussi, au coin bas-gauche de l'outil, et le clic droit d'un champ aussi |
ii_band / ii_index qui déplacent une barre | ue_layout_changed | ue_bar_reordered, ue_layout_changed |
of_add_datepicker avec une date qui n'est pas aaaa-mm-jj ("31/12/2026") | 0, la date affichée telle quelle | -5, rien n'est ajouté |
of_add_menu_separator sur une entrée qui n'a aucune sous-entrée | 0 : l'entrée devenait grise et ne se choisissait plus | -5 |
is_shortcut ou of_register_shortcut sur une adresse où rien ne vit, une entrée à cascade ou le choix d'une liste | inscrit : la touche était prise dans toute la fenêtre | rien d'inscrit ; of_register_shortcut rend -5, of_get_last_error dit pourquoi |
| Ctrl+A, Ctrl+C, Ctrl+V, Ctrl+X, Ctrl+Z, Ctrl+Y dans un champ de la barre | l'outil qui portait l'accord partait | le champ édite son texte |
is_text d'un sélecteur de date | gardé et relu, jamais affiché | ignoré, relit "" |
// 4.0 : the right click of a tool
// ue_item_rclicked event of uo_toolbar : (string as_keys)
// 5.0 : the same script, with the screen point
// ue_item_rclicked event of uo_toolbar : (string as_keys, long al_x, long al_y)
La recette : rien ne refuse de compiler — un script de ue_item_rclicked garde as_keys. Ouvrez votre menu au point al_x, al_y (passez-le à of_show d'un contextmenu). Vérifiez qu'un script de ue_bar_reordered accepte aussi les déplacements que fait votre code, testez le code retour d'of_add_datepicker si la date vient d'un champ régional, et posez is_shortcut après l'ajout de l'outil ou de l'entrée.
12.19 Le clic droit d'un item porte son point : buttonbar, breadcrumb, chartcartesian, statusbar #
Une seule règle pour tout clic droit sur un item de la bibliothèque : l'événement reçoit la clé (ou l'adresse) de l'item, puis al_x, al_y, le point où ouvrir un menu, en pixels d'écran — le pointeur, ou, au clavier (touche Menu, Maj+F10), le coin bas-gauche de l'item (bas-droit en lecture de droite à gauche ; le milieu d'une forme qui n'est pas un rectangle : un point de graphique). Un contextmenu de la bibliothèque s'y ouvre tel quel : uo_menu.of_show(al_x, al_y). Trois événements qui ne le portaient pas le reçoivent ; la barre d'état multipliait le sien par l'échelle de l'écran, et un menu ouvert à ce point tombait loin du pointeur sur un écran à 125 % ou 150 %.
| Quoi | 4.0 | 5.0 |
|---|---|---|
buttonbar · ue_button_rclicked | (string as_key) | (string as_key, long al_x, long al_y) |
breadcrumb · ue_item_rclicked | (string as_keys) | (string as_keys, long al_x, long al_y) |
chartcartesian · ue_point_rclicked | (string as_key, long al_index, double ad_value) | (string as_key, long al_index, double ad_value, long al_x, long al_y) |
statusbar · al_x, al_y de ue_panel_rclicked | multipliés par l'échelle de l'écran | le point tel que la page le lit, comme tous les clics droits |
// 5.0 : the menu of a button, opened where the user right-clicked it
// ue_button_rclicked event of uo_buttons : (string as_key, long al_x, long al_y)
is_menu_button = as_key
uo_menu.of_show(/*x*/ al_x, /*y*/ al_y)
La recette : rien ne refuse de compiler — un script de ces événements garde ses arguments. Ouvrez votre menu au point al_x, al_y (passez-le à of_show d'un contextmenu) ; un menu PowerBuilder garde PopMenu(PointerX(), PointerY()) de votre fenêtre. Un script qui corrigeait lui-même l'échelle des coordonnées de ue_panel_rclicked ne doit plus le faire.
12.20 Le socle : l'erreur d'un composant est la sienne, chaque verbe rend un code #
Cinq changements touchent toute la bibliothèque, ou toute une famille de composants. Un seul refuse de compiler : is_last_error d'un composant non visuel, devenu of_get_last_error().
| Quoi | 4.0 | 5.0 |
|---|---|---|
of_get_last_error() d'un composant visuel | le dernier message de la DLL, un seul pour tout le processus — souvent celui d'un autre composant | ce qui est arrivé à ce composant : un nom refusé, ou un appel de ce composant à la DLL, dont la raison est lue au moment de l'échec ; vide sinon |
La raison d'un échec d'un non visuel (crypto, restclient, soundplayer, speechout, xml, u_pbt_regex, u_pbt_zip) | inv.is_last_error | inv.of_get_last_error() |
of_stop, of_close, of_reset des non visuels (commandpalette, crypto, messagebox, restclient, soundplayer, speechout, toaster, xml) | sans valeur de retour | un long, 0 une fois fait — comme les composants visuels |
of_set_property("tooltip", …) et super_tooltip_* sur un composant sans info-bulle (webbrowser, pdfviewer, radialmenu, progressbar) | posait une info-bulle que la doc dit inexistante | -5, et of_get_last_error() dit pourquoi |
Le raccourci d'un menu PowerBuilder repris (of_load_menu de menubar et de commandpalette) | Ctrl++, PageUp, Insert (menubar) ; rien au-delà de F12 (palette) | une seule écriture, celle du contextmenu : Ctrl+Plus, PgUp, Ins, F13 à F24, Num 0 à Num 9, Num + |
// Local variables
string ls_why
// 4.0 : ls_why = inv_crypto.is_last_error
// 5.0 : the reason of a failure, by the same method as every component
ls_why = inv_crypto.of_get_last_error()
La recette : le compilateur montre chaque .is_last_error à remplacer par .of_get_last_error(). Un appel à of_stop, of_close ou of_reset écrit comme une instruction compile toujours. Un script qui lisait of_get_last_error() d'un composant pour connaître l'échec d'un autre appel (un export de la DLL appelé directement, un autre composant) lit désormais la raison de ce composant-là, ou rien : demandez-la à celui qui a échoué.
Ajouté, sans rien à reprendre : is_accessible_name et is_accessible_description sur tous les composants visuels — le nom et la description que dit un lecteur d'écran (3.4) ; of_from_datastore d'un DataWindow ou d'un DataWindowChild sur crosstab et datagrid, comme sur les autres composants liés à des données ; la forme complète d'of_insert_command (commandpalette), qui prend l'indication, le raccourci et les mots-clés comme of_add_command, avec une position en long.