PBToolboxAI v4 ← Site

11. Migrar de la 3.0 a la 4.0 #

← Migrar de la 2.0 a la 3.0 · Índice · Notas de la versión →


La 4.0 retira dos métodos de los treinta y dos componentes de la 3.0 — of_set_data de la tabla cruzada, renombrado of_from_datastore (11.33), y of_transform de n_pbt_xml, que se va con XSLT (11.31) — y cambia firmas que el compilador le muestra línea a línea: tres propiedades renombradas (id_minimum e id_maximum de la barra de progreso, 11.6; il_doc_line del editor de código, 11.28), argumentos de evento añadidos o renombrados (ue_tile_moved, 11.6; ue_failed del cliente REST, 11.6, y del vídeo, 11.26; ue_error de la imagen, 11.25; ue_cell_double_clicked, 11.33; ue_closed de la paleta de comandos, 11.36; ue_toast_clicked, ue_toast_action y ue_toast_dismissed del toaster, 11.38), of_count y of_keys_at en long (11.34) y métodos que ahora devuelven un código (of_refresh, of_select, of_show, of_scroll_to_end, of_set_header…). La 11.6 alinea además dos recuentos, un evento y la ruta del árbol JSON con el resto de la biblioteca: es ahí, con las secciones citadas, donde hay que retocar código que compilaba. Lo que cambia se concentra en la cinta (ribbon), que ha sido revisada por completo. Dos cambios piden releer su código: la pregunta planteada antes de un mosaico de galería (11.1) y los handles liberados por una eliminación (11.2). Los demás corrigen comportamientos que quizá haya sorteado (11.3) — entre ellos el clic derecho en un elemento, que ya solo produce un evento en todos los componentes, y la ruta de navegación (breadcrumb), cuyas direcciones y rechazos se han revisado. Vienen después el generador n_pbt_menu2ribbon (11.4) y lo que se ha añadido (11.5). La barra lateral (listbar) sigue también la regla del 11.1: su pregunta antes de una selección es ahora opcional. Las pestañas (tab) siguen la misma regla: sus dos preguntas, antes de un cambio de pestaña y antes de un cierre, son ahora opcionales (11.1). Por último, los temas siguen a la aplicación (11.7): el acento de la aplicación sobrevive a un cambio de tema, y un eje de tema dejado vacío sigue el de la aplicación. La revisión de seguridad de crypto (11.8) cierra una confusión de algoritmo de los tokens JWT, sustituye varios silencios por un rechazo que dice su motivo y fija la regla de las rutas relativas de los archivos.

La revisión completa del 28/09/2026 releyó cada componente entregado; lo que cambia tiene una sección por componente: restclient (11.9), speechout (11.10), statictext y el texto enriquecido (11.11), breadcrumb (11.12), buttonbar y el teclado de ventana (11.13), button (11.14), menubar (11.15), ribbon (11.16), toolbar (11.17), statusbar (11.18), dockcontainer (11.19), tab (11.20), listbar (11.21), tilesbox (11.22), stepbar (11.23), progressbar (11.24), picture (11.25), video (11.26), pdfviewer (11.27), codeeditor (11.28), jsontree y xmltree (11.29, 11.30), xml (11.31), json (11.32), crosstab (11.33), shellexplorer (11.35), commandpalette (11.36), radialmenu (11.37), toaster (11.38) y messagebox (11.39); la base común tiene dos secciones, 11.34 y 11.40. Una regla las atraviesa, la de PowerBuilder (SelectTab lanza SelectionChanged): un cambio pedido por su código lanza el mismo evento que un gesto del usuario, y plantea la pregunta del veto si la ha activado; el método devuelve -4 si usted la rechaza. Vale para una selección (of_select_*), una apertura o un plegado (of_expand, of_collapse, of_open), un zoom, una pantalla completa, un capítulo; no se lanza nada cuando nada cambia, y of_reset sigue en silencio. Asignar un VALOR (una marca, un texto, un volumen, un filtro) sigue en silencio, como SetItem. ue_layout_changed se lanza en ambos casos: dice que ha cambiado una disposición que guardar.

11.1 Las preguntas antes de un cambio son ahora opcionales #

En la 3.0 la cinta planteaba de oficio la pregunta ue_gallery_selection_changing antes de retener un mosaico: ib_veto_gallery valía true. En la 4.0 vale false, como todo evento cancelable de la biblioteca: cada pregunta cuesta una ida y vuelta hasta PowerBuilder, y solo una aplicación que responde debe pagarla. Una aplicación que no programaba el evento no ve ninguna diferencia. Novedad: of_select_gallery_item lanza ue_gallery_selection_changed como un clic y, con la pregunta activada, también la plantea; un rechazo le hace devolver -4, el mosaico no cambia.

// 4.0 : the question is only asked on request. If your ue_gallery_selection_changing
// returns false for some tiles, switch it on where the ribbon is built.
uo_ribbon.ib_veto_gallery = true

La receta: busque ue_gallery_selection_changing en sus descendientes de la cinta; donde esté programado, añada ib_veto_gallery = true a la construcción. Donde escribía ib_veto_gallery = false para desactivar la pregunta, la línea ya no sirve y puede quitarse.

La barra lateral (listbar): ib_veto_selection #

Misma regla: en la 3.0 la listbar planteaba de oficio ue_selection_changing antes de cada cambio de selección (ib_veto_selection valía true). En la 4.0 vale false. Si programaba ue_selection_changing para rechazar un cambio, ponga ib_veto_selection = true: sin ello, el evento ya no se dispara y la selección pasa sin preguntarle. Activada, la pregunta se plantea también para una selección pedida por su código (of_select_item, of_clear_selection), como en la 3.0; un rechazo les hace devolver ahora -4, y la selección no se mueve. ue_selection_changed se dispara como antes.

// 4.0 : the listbar only asks on request. If your ue_selection_changing
// returns false (unsaved changes), switch the question on where the bar is built.
uo_nav.ib_veto_selection = true

La receta: busque ue_selection_changing en sus descendientes de u_pbt_listbar; donde devuelva false, añada ib_veto_selection = true a la construcción. Donde escribía ib_veto_selection = false para desactivar la pregunta, la línea ya no sirve y puede quitarse.

Las pestañas (tab): ib_veto_selection e ib_veto_close #

Misma regla, dos preguntas: en la 3.0 el componente tab planteaba de oficio ue_selection_changing antes de cada cambio de pestaña y ue_tab_closing antes de cada cierre (ib_veto_selection e ib_veto_close valían true). En la 4.0 ambos valen false. Si programaba ue_selection_changing o ue_tab_closing para rechazar, ponga ib_veto_selection = true o ib_veto_close = true: sin ello, el evento ya no se dispara y la pestaña cambia o se cierra sin preguntarle. Activada, la pregunta se plantea también para of_select_page, como en la 3.0, pero antes de que la pestaña cambie: un rechazo le hace devolver -4 y nada se mueve; una aceptación cambia la pestaña de inmediato, ue_selection_changed se dispara como antes, y of_selected_key() leído justo después ya devuelve la nueva clave.

// 4.0 : the tab only asks on request. If your ue_selection_changing or
// ue_tab_closing returns false (unsaved changes), switch the questions on.
uo_tabs.ib_veto_selection = true
uo_tabs.ib_veto_close     = true

La receta: busque ue_selection_changing y ue_tab_closing en sus descendientes de u_pbt_tab; donde uno devuelva false, añada la línea correspondiente a la construcción. Donde escribía = false para desactivar una pregunta, la línea ya no sirve y puede eliminarse.

11.2 Las adiciones dicen lo que rechazan, las eliminaciones liberan sus handles #

En la 3.0, una adición que la cinta ignoraba — una clave ya ocupada, una entrada de menú bajo un simple botón — devolvía igualmente 0, y no aparecía nada. En la 4.0 devuelve -5, y el código del envío (-2 si el componente no está creado) en lugar de un 0 fijo. Y una eliminación libera los handles de lo que se va: una variable que guardaba el handle de un control eliminado deja de ser válida.

Qué3.04.0
Añadir una clave ya ocupada (pestaña, grupo, control)0, ignorada-5
Entrada de menú, opción de combo o mosaico bajo un control de otra naturaleza0, ignorada-5
of_add_tab, of_insert_tab, of_add_group, of_add_contextual_*, of_add_qat sobre un componente no creado0-2
Un handle guardado tras of_remove_tab, of_remove_group, of_remove_item u of_clearseguía en memoria hasta la destrucción de la cintaliberado: IsValid() devuelve false
// 4.0 : after a removal or of_clear, ask the component for the handle again
uo_ribbon.of_clear()
uo_ribbon.of_add_tab(/*key*/ "home", /*title*/ "Home")
uo_ribbon.of_add_group(/*keys*/ "home/clip", /*title*/ "Clipboard")
uo_ribbon.of_add_button(/*keys*/ "home/clip/paste", /*label*/ "Paste", /*image*/ "")
uo_ribbon.of_item(/*keys*/ "home/clip/paste").ib_enabled = false

La receta: no guarde un handle más allá de una eliminación o de un of_clear — vuelva a pedirlo con of_tab, of_group, of_item u of_menu_item, lo que no cuesta nada. Donde un error de construcción le importe, compruebe el código que devuelve la adición.

11.3 Otros comportamientos que puede notar #

Cuando la ventana es estrecha, la cinta pliega sus grupos en un botón que abre un panel. De ese panel vienen las diferencias más visibles:

Qué3.04.0
Botón, o parte principal de un split, pulsado en el panel de un grupo plegadoue_menu_selected("", false)ue_clicked(dirección)
Entrada de menú elegida en ese paneldirección incompletadirección completa, cascada incluida
Control atenuado, o entrada oculta, en ese panelrespondía / se mostrabano responde / no se muestra
Split grande reducido por falta de espacioun clic solo abría el menúdos partes: el comando y la flecha del menú
Entrada de menú con la clave de su control (home/clip/paste/paste)ue_clicked("home/clip/paste")ue_menu_selected("home/clip/paste/paste", …)
of_menu_item("…/exp/pdf") cuando una cascada también contiene pdfpodía apuntar a …/exp/more/pdfapunta a la entrada que nombra la dirección
as_from_keys de ue_gallery_selection_changed sin mosaico anteriorla dirección de la galería""
Releer un handle de la barra de acceso rápido, il_color de un selector de color, ii_visible_items, is_keytip de una pestaña, il_color de un grupo contextual, of_count() de una galeríavacío, -1 o 0el valor en pantalla
of_keys_at de un combo"home/font/cb/cb:Arial""home/font/cb/Arial": la clave de una opción es su etiqueta
of_ctx_group(k).il_color cuando una pestaña también lleva la clave kcoloreaba la pestañacolorea solo el banner
Colores de elemento (il_back_color…) e is_tooltip de una pestaña o de un gruposin efectoaplicados; la información sobre herramientas de un grupo aparece en su título
of_remove_item("save") sobre un botón de la barra de acceso rápido-5el botón se retira
of_add_app_menu_separator("saveas/s1")una línea en la raíz del menúla línea en el submenú de saveas; una clave sin / no cambia
of_clear() mientras una pestaña estaba activaningún eventoue_selection_changed("")
Spinner con paso decimal (0.1)0.300000000000000040.3
Atajo Alt (keytip) sobre un control atenuado, cinta minimizadala cinta seguía abiertase cierra, no se ejecuta nada
toolbar: combo, spinner o galería atenuados en el panel del chevronrespondíanno responden
Todos: clic derecho en un elemento (ue_item_rclicked, ue_panel_rclicked, ue_row_rclicked…)la página enviaba también el evento del componente, que ningún componente con elementos transmitía a PowerBuilderun solo evento, el del elemento; un ue_rclicked de componente, donde existe, solo se lanza fuera de los elementos
Todos: soltar archivos (ib_allow_drop)ue_drag_leave y luego ue_drop_files; rutas cortadas a 260 caracteressolo ue_drop_files, rutas completas; of_reset quita el destino de soltar
breadcrumb: of_path() con un segmento oculto, o en la versión de demostraciónlas claves mostradas: el oculto omitido, los primeros segmentos cortadosla dirección completa del lugar actual: of_truncate(of_path()) acierta; el campo de escritura parte de la misma
breadcrumb: of_keys_at(n); of_has("computer/C:")la clave simple; buscaba entre las ramas del menúla dirección del segmento; busca entre los segmentos
breadcrumb: leer un handle de dirección profunda, of_item("a/b/c").is_textleía solo el último nivel: vacío en una clave repetidael segmento de esa dirección
breadcrumb: of_truncate, of_remove_item, of_clear_children, of_remove_child sobre una dirección desconocida o una clave simple repetida; of_add_child bajo un segmento ausente o sobre una rama ya ocupada; of_add_item de una dirección que acabaría en otro sitio0, ignorado (o solo la última clave retenida)-5
breadcrumb: un handle guardado tras of_clear, of_remove_item, of_truncate, of_clear_children u of_remove_childseguía en memorialiberado: IsValid() devuelve false
breadcrumb: campo de escritura abandonado sin cambios, o ventana cambiada (Alt+Tab) mientras se escribeue_path_entered lanzadonada; lo escrito se mantiene al cambiar de ventana
breadcrumb: segmento atenuado; Intro sobre un segmentosu chevron se abría y recibía un soltar; Intro pulsaba también el botón predeterminado de la ventanatotalmente inerte; Intro solo pulsa el segmento
buttonbar: Intro mientras otro botón de la barra tiene el foco del tecladoactivaba el botón predeterminado (is_default)activa el botón que tiene el foco, como Windows; el predeterminado se activa cuando ningún botón de la barra tiene el foco
buttonbar: botón predeterminado o cancelar atenuado u oculto; is_shortcut de un botón atenuado u ocultoIntro, Esc o Alt+letra tragados sin efecto, incluso en un control PowerBuilder de la ventanala tecla se queda en la ventana
buttonbar: is_shortcut de varias letras ("Save")Alt+S solo funcionaba si la barra tenía el focoAlt+S funciona desde cualquier lugar de la ventana (la primera letra, como está documentado)
buttonbar: of_add_button / of_insert_button con una clave ya usada o que contiene / o una barra vertical; of_remove_button / of_move_button con una clave desconocida0, ignorado-5
buttonbar: of_remove_button, of_clear_buttonsel atajo Alt+letra, los colores y el tooltip del botón se quedaban (un botón recreado con la misma clave los recuperaba); el handle seguía en memoriase van con el botón; el handle se libera: IsValid() devuelve false
codeeditor: releer is_text de un texto en CRLFen LF (en CRLF solo si el editor estaba plegado): is_text = ls_original era falsocon los finales de línea recibidos, plegado o no
codeeditor: releer is_syntax tras SYNTAX_CSHARP, SYNTAX_CPP, SYNTAX_JAVA, SYNTAX_XMLla gramática usada ("c", "html")el valor escrito
codeeditor: of_insert_text en solo lectura o plegadoinsertado en solo lectura; rechazado plegado, pero 0-4, no se inserta nada
codeeditor: ii_doc_linesolo una banda, a menudo fuera de la vista, ausente con el ajuste de línea; un integerla línea llega al centro de la vista (una región plegada que la oculta se abre), banda también con ajuste de línea; cursor y selección intactos; un long — renombrado il_doc_line en la 4.0 (sección 11.28)
codeeditor: #regionopen con ib_foldingreescrito #region en el texto (is_text, y tras el plegado)nunca se toca; solo la vista plegada muestra #region
codeeditor: ue_find_resultdos veces por of_find, en cada pulsación y (0, 0) al cerrar la barra; lanzado incluso con ib_search_enabled = falseuna vez por búsqueda o paso; al escribir si cambia el recuento; nunca al cerrar; of_find sin efecto con la búsqueda desactivada
codeeditor: ue_caret_changedmudo al escribir; plegado, la línea MOSTRADAlanzado también al escribir; plegado, la línea del margen
codeeditor: Ctrl+Z tras Intro o Tab; Intro / Tab en modo plegadoel historial de deshacer se vaciaba; plegado, la tecla modificaba la vista y luego se perdíacada pulsación se deshace; plegado, la tecla no tiene efecto
codeeditor: ib_folding = true con ib_line_numbers = falselas regiones seguían cerradas, sin marcador para abrirlasun margen estrecho conserva los marcadores
commandpalette: of_add_command con una clave ya usada o que contiene / o una barra vertical; of_remove_command con una clave desconocida0 (una clave usada daba dos comandos gemelos)-5
commandpalette: of_open / of_register_shortcut sin ipo_owner ni ipo_receiver0, y ningún evento llegaba nunca-5
commandpalette: el atajo pulsado mientras la paleta está abiertasin efectocierra la paleta
commandpalette: un objeto paleta destruido (página o ventana cerrada)su atajo seguía registrado y se tragaba la tecla en la ventana, sin ningún eventoel atajo se va con el objeto, y una paleta que había abierto se cierra
commandpalette: atajo mostrado en una fila, en un teclado no latino, con una cifra y Mayús, Ctrl+Space, Ctrl+Up, Ctrl+Del, o una tecla F solano respondía; Win + la letra lanzaba el comando cuyo atajo era esa sola letraresponde: la tecla física, leída como la lee la DLL; Win nunca es un modificador
commandpalette: un comando cuyo atajo es Ctrl+C, Ctrl+V, Ctrl+Z o Ctrl+A, al escribirse lanzaba el comando en lugar de copiar, pegar…el cuadro de búsqueda conserva estas cuatro teclas
commandpalette: of_resetconservaba is_recent, una paleta abierta y el atajo ya registradolos vacía, la cierra y devuelve el atajo registrado a SHORTCUT_DEFAULT
commandpalette: pbm_custom02 de la ventana ipo_ownerdisparado en cada evento de la paletanunca: solo un ipo_receiver definido lo sigue recibiendo
Todos: releer un valor de texto largo (is_text de un script grande)cada vez más lento con el tamaño (varios segundos); cortado sin aviso más allá de un millón de caracteresproporcional al tamaño; entero
n_pbt_utils.of_dir_has_subfolderscontaba las carpetas ocultas, de sistema y las uniones; ilegible más allá de 260 caractereslas ignora, como el Explorador (la sobrecarga ab_include_hidden las cuenta); lee rutas largas
crosstab: separador de miles de of_set_value_formatvalía para TODAS las medidas; "," no reconocido ($1 234 en francés)ajuste de ESTA medida; ",", ".", " " reconocidos; "" = predeterminado del menú Opciones
crosstab: of_set_member_filter(campo, "")ningún miembro conservado: tabla vacíaquita el filtro, como of_set_member_order("")
crosstab: is_show, is_conditional_formatting, of_set_value_format antes de of_add_value_fieldperdidos sin avisoconservados, releídos tal cual, aplicados cuando el campo entra en Valores
crosstab: ordenar una columna o plegar un grupo con el ratónningún eventoue_layout_changed, como todo lo que of_get_layout guarda
crosstab: fechas de un DataStore en un equipo no francés (3/15/2025, 15.03.2025)agrupadas en un mes erróneo o vacío; fechas ordenadas solo por el añoel mes correcto; la columna releída como aaaa-mm-dd, ordenada en el tiempo
crosstab: números mostrados en alemán, italiano, español, portuguésa la americana (1,234.5)en el idioma de visualización (1.234,5 en alemán)
crosstab: of_export_csvnúmeros con punto (1436.5), leídos como texto por un Excel francés; una etiqueta =… se ejecutaba al abrirseparador decimal del idioma de visualización; un apóstrofo delante de = + - @
crosstab: of_export_xlsxtotales y subtotales ocultos exportados igualmente; total arriba ignorado; símbolo « delante » pasado detrásla tabla tal como en pantalla
crosstab: « Añadir a los valores » del menú de un campo ya en Valoressustituía sus valoresañade un valor, como el arrastre
crosstab: « Quitar » del menú de un campo filtradoel filtro seguía activo, invisibleel filtro se va con el campo
crosstab: AGG_DISTINCT_COUNT en una columna con celdas vacíasel vacío contaba como un valorignorado, como en Excel
crosstab: fórmula que cita una medida calculadaaceptada, valía 0rechazada mediante ue_calc_field_error; sus mensajes están en inglés
crosstab: ue_layout_changed con una llave en un miembro; ad_value de ue_cell_double_clickeddisposición truncada; valor 0 si un campo en filas se llama value, exponente perdidoleídas enteras
crosstab: ib_enabled = false, con el tecladoIntro abría el menú de un chip, Ctrl+C copiabamudo
crosstab: tecladoel foco volvía arriba de la página tras cada acción; ninguna forma de mover un campoel foco se queda en el elemento accionado; el menú de un chip lo mueve (otra zona, izquierda, derecha)
crosstab: tema oscuronegativos y flechas de iconos poco legibles; celda de escala de colores seleccionada ilegibleuna paleta propia en modo oscuro
crypto: of_jwt_sign con JWT_EDDSAla cabecera decía "alg":"EDDSA", que las demás bibliotecas (jose, PyJWT, jjwt) rechazan"alg":"EdDSA", el nombre registrado; un token 3.0 sigue verificándose
crypto: of_generate_keypair de un tipo o tamaño desconocido ("ec_p256", 1024)0 y un par RSA 2048, sin decir nada-5, ambos PEM vacíos, is_last_error nombra las KEY_* admitidas
crypto: of_hash_file("SHA-256", …); algoritmo desconocidovacío, e is_last_error decía « archivo ilegible » de un archivo perfectoel nombre se lee como lo lee of_hash (SHA-256 = HASH_SHA256); un algoritmo desconocido se dice como tal, aparte de un archivo ilegible
crypto: of_base64_encode_file de un archivo demasiado grande (más de 64 MB en 32 bits, 512 MB en 64 bits); de un archivo ausente en demo« archivo ilegible »; « límite de la demo »« demasiado grande para este proceso »; « archivo ilegible » — is_last_error da la razón real
crypto: is_last_error tras una llamada nativa correcta (of_crc32, of_hash en MD5, of_hash_file…)conservaba el error de la llamada anteriorvacío
crypto: clave HMAC vacía; exp/nbf no numérico de un JWT; of_password_verify de un valor de más de 10 000 000 rondas; of_random_password de un juego desconocidoerror oscuro del motor; token válido para siempre; minutos de cálculo; CHARSET_ALL tomado sin decir nadarechazados de inmediato, is_last_error dice por qué
crypto: of_base64_decode_to_file("", ruta)-50, un archivo vacío
dockcontainer: of_add_panel con un as_relative_to desconocido, un control ya alojado, una clave con / o una barra vertical, o POSITION_STACK sobre el panel principal0: el panel se acoplaba a la raíz, el control se alojaba dos veces, o el panel apilado sobre el principal quedaba invisible-5, y el control no se toca
dockcontainer: of_move_panel hacia un destino desconocido, o POSITION_STACK sobre el panel principal0: el panel iba contra la raíz, o nada se movía-5
dockcontainer: of_remove_panel, of_resetel control volvía a su ventana oculto, en la posición y con el tamaño del dockvuelve a su sitio, con su tamaño y con la visibilidad que tenía antes de of_add_panel
dockcontainer: is_main asignado antes de of_add_panel; is_main = ""; is_main de un panel apiladoignorado en silencio; no se transmitía nada; sus vecinos de pila se volvían invisiblesse conserva y se aplica al añadir el panel; se quita el panel principal; sale de su pila, los demás siguen visibles
dockcontainer: of_set_layout de una disposición que no conoce ninguno de los paneles, o de un texto que no es una disposiciónel dock se vaciaba, o se rechazaba el mensaje entero; 0los paneles permanecen, colocados junto a los demás (nunca sobre el principal); -5 para un texto que no es una disposición
dockcontainer: ue_layout_changedlanzado solo al arrastrar, redimensionar y acoplar: una disposición guardada en este evento olvidaba un panel cerrado o la pestaña activatambién se lanza cuando un panel se cierra, se oculta, se selecciona o se renombra, y cuando cambia el panel principal
dockcontainer: clic en la pestaña (o encabezado) del panel ya activoue_panel_selected en cada clicnada: el evento indica un CAMBIO de panel activo
dockcontainer: panel desfijado (ib_pinned = false)su lengüeta solo se abría con un clic (la doc decía « al pasar el cursor »)se abre al pasar el cursor (400 ms) o con un clic; abierta al pasar el cursor, se repliega cuando el ratón la abandona
dockcontainer: control PB estándar (MultiLineEdit, botón…) en un panel flotantesus notificaciones (modified, clicked, colores) ya no llegabanllegan como cuando está acoplado
dockcontainer: ocultar un panel flotante (ib_visible = false)su ventana seguía abiertase cierra; al volver a mostrarse, el panel vuelve acoplado a su sitio
dockcontainer: ventana flotantesu zona útil era más pequeña que el panel (barra de título descontada), podía salirse de la pantalla, y un título con etiquetas las mostrabala zona útil tiene el tamaño del panel, la ventana se queda en la pantalla, el título es texto
dockcontainer: divisor con el tecladola primera flecha lo hacía saltar al 50 %parte de su posición mostrada
json: valor nulo dado a of_set_number, of_add_number, of_set_boolean, of_add_boolean, o valor nulo o vacío dado a of_set_raw / of_add_rawtodo el documento se volvía nulo (of_text devolvía null) o dejaba de ser JSON; un booleano nulo se escribía falsese escribe null, el resto del documento queda intacto
json: escribir en un documento CARGADO cuya clave se escribe "k" : v o con un carácter escapado, seguido de un salto de línea, o cuya raíz es un array; of_set_members sobre tal documentola clave se añadía dos veces (la relectura devolvía el valor antiguo), la escritura devolvía -4 sin razón, o el documento se sustituía por el fragmentoel valor se sustituye o se añade como en un documento construido; of_set_members devuelve -4 si la raíz no es un objeto
json: of_set_*("items/1/qty", …) — una clave NUEVA en un objeto situado en un array-40: la clave se añade al primer elemento; un array se atraviesa con un índice existente, solo se crea una clave de objeto
json: ruta con un segmento vacío (/name, a//b, a/)se creaban claves llamadas ""; of_remove podía quitar otro valor-5, no se escribe nada; un lector responde "ausente"
json: of_load de un número mal escrito (-, 01, +1, .5, 1., 1e)0, y of_is_valid verdadero-4, como todo JSON no válido
json: of_get_number de un número con exponente (1e-7, 2.5E+3) o con más de 9 decimalesexponente ignorado (2.5E+3 leído 2,5), decimales cortados a 9exponente resuelto, 17 cifras significativas conservadas
json: leer o modificar un documento grande (una respuesta de API de 80 KB, 2000 filas)segundos por llamada (20 s para of_count), la aplicación parecía congeladaun tiempo proporcional al tamaño; leer las filas una a una (rows/1, rows/2…) o recorrer las claves con of_name ya no vuelve a empezar desde el principio
listbar: of_add_section / of_insert_section con una clave ocupada o que contiene / o una barra vertical; of_add_item / of_insert_item con una dirección ocupada o bajo una sección que la barra no añadió; of_remove_item, of_move_item, of_select_item, of_remove_section, of_move_section con una dirección desconocida0, ignorado; una entrada bajo una sección desconocida aparecía bajo la última sección-5; of_add_section devuelve también -2 cuando el componente no está creado
listbar: un handle conservado tras of_remove_item, of_remove_section u of_clearquedaba en memorialiberado: IsValid() devuelve false
listbar: quitar o vaciar lo que lleva la selección (of_remove_item, of_remove_section, of_clear)la selección desaparecía sin evento; tras of_clear, of_selected_key devolvía aún la antiguaue_selection_changed(antigua, "")
listbar: ue_layout_changedmudo al plegar una sección y al quitar una entrada; disparado al entrar en el rieldisparado al plegar (clic o ib_collapsed de una sección) y al quitar; ya no para el riel, que no forma parte de la disposición
listbar: riel (ib_collapsed = true)las entradas de una sección plegada desaparecían; una entrada sin icono mostraba un cuadro vacío; of_reset dejaba la barra estrechatodas las entradas, un filete entre secciones, la inicial de una entrada sin icono, la etiqueta al pasar el ratón; of_reset devuelve a la barra su ancho
listbar: is_image de una sección; un color puesto en la sección k cuando una entrada tiene también la clave ksin efecto; la entrada tomaba también el colorel icono se dibuja delante del título; solo la sección toma el color
listbar: tecladotras un cambio de etiqueta o una selección, las flechas dejaban de responder; sin selección la barra quedaba fuera de la tabulación; los títulos de sección solo se plegaban con el ratónel foco se queda en la entrada; una parada de tabulación; los títulos se alcanzan con las flechas y se pliegan con Intro o Espacio
listbar: entrada desactivada (ib_enabled = false); ib_auto_width en una barra desplegadaetiqueta atenuada, poco legible en temas claros; informaba del ancho ya dadoel color « desactivado » del tema; el ancho que pide la línea más larga
listbar: arrastrar una entrada (ib_reorderable)botón soltado fuera de la ventana: la entrada seguía al ratón; el clic final podía seleccionar la entrada soltadael gesto termina al volver el ratón; el final de un arrastre no selecciona nada
menubar: ue_menu_openinglanzado junto al desplegable: lo que cambiaba (atenuar Pegar…) solo se veía en la apertura siguienteel desplegable espera a que el evento vuelva: el cambio se ve en esta apertura
menubar: of_item, of_remove_item sobre una entrada cuya clave existe también en otra cascada (file/export/pdf, file/print/pdf)podían alcanzar la otra entrada (la primera encontrada); el atajo mostrado en una disparaba la otraalcanzan la entrada que nombra la dirección; una clave sola ya no busca en las cascadas
menubar: of_add_menu, of_add_item, of_add_separator sobre una clave ocupada, con / o una barra vertical, o bajo un menú o un padre desconocidos; of_remove_item / of_remove_menu de una dirección desconocida0; una entrada con el padre mal escrito iba a la raíz del menú, una clave ocupada daba entradas gemelas-5
menubar: un handle o un atajo tras of_remove_item, of_remove_menu u of_clearel handle se quedaba en memoria; el atajo seguía armado y se tragaba la tecla, que ya no llegaba a la aplicaciónhandle liberado: IsValid() devuelve false; atajo desarmado
menubar: entrada atenuada, oculta o quitada mientras su desplegable está abierto; atajo de una entrada bajo una cascada atenuadael clic o la tecla aún lanzaban ue_item_selectednada
menubar: colores de ítem (il_back_color…) de un menú o de una entrada; is_tooltip de un menúsin efecto; un color se releía -1aplicados: en el título del menú, en la entrada del desplegable; la información de un menú se muestra en su título, una entrada del desplegable no muestra ninguna
menubar: tecladolas flechas se quedaban bloqueadas en un menú atenuado; en RTL, izquierda y derecha invertidas; Alt+letra de un menú oculto tapaba la misma letra de otro menú; tras Alt+letra y una elección, el Alt siguiente apagabalos menús atenuados se saltan; las flechas siguen el sentido de escritura; solo un menú visible responde a su letra; el Alt siguiente vuelve a encender la barra
menubar: una cascada cuyas entradas están todas ocultas; of_count("file"), of_keys_atse elegía como un comando (file/export); los separadores se contaban (__sep0)atenuada; solo se cuentan las entradas
menubar: of_item("file") — una dirección de un nivelreleía el menú, y escribía en una entrada «file» inexistenteno designa nada: use of_menu("file")
Todo texto leído de un componente o de un JSON: escapes \b y \fquedaban escritos tal cualdecodificados (retroceso, salto de página)
messagebox: un cuadro que no se pudo abrir (runtime de WebView2 ausente, motor no listo)of_show y los atajos (of_info…) devolvían 0, como un cierre: of_info hacía creer que se había mostrado un cuadro-4 (-6 si falta el runtime), el motivo con of_get_last_error(); of_choose y of_prompt devuelven "" y of_get_last_error lo dice. Una prueba = 1 para «confirmado» sigue siendo correcta
messagebox: Esc o Alt+F4 mientras un botón de cancelación sigue en cuenta atrás (of_add_button_timed)cerraban el cuadro (0)no hacen nada hasta el final de la espera: está para hacer leer
messagebox: el texto del mensaje y de la instrucciónno se podía seleccionar; pulsar sobre él movía el cuadrose selecciona y se copia (Ctrl+C copia la selección, o todo el cuadro sin selección); el cuadro se mueve por su título, su icono, sus márgenes
messagebox: una entrada de más de unos 900 caracteres (of_prompt, ib_input)volvía vacía, como una cancelaciónvuelve entera
messagebox: al_hwnd = 0, un cuadro abierto desde otro, un cuadro movido y luego agrandadose desactivaba todo el escritorio; la ventana se reactivaba mientras el primer cuadro seguía esperando; el cuadro volvía al centrosin propietario no se desactiva nada; la ventana sigue desactivada mientras un cuadro la espera; el cuadro conserva su sitio
progressbar: rango vacío o invertido (id_maximum = 0 y luego id_value = 0)0 % sea cual sea el valor100 % en cuanto el valor alcanza el máximo (un lote vacío está terminado), 0 % antes
progressbar: el porcentaje mostrado, el anilloredondeado al más cercano (99,5 % mostraba «100%»); anillo fijo de 128 px; en espera, el anillo giraba con el arco del valor (vacío a 0: nada se movía)redondeado hacia abajo: 100 % significa terminado; el anillo sigue el tamaño del control; en espera gira un arco fijo; si Windows pide menos animaciones, la espera pulsa
Cualquier propiedad double releída (id_value…) en un equipo con coma decimalla parte decimal se leía mal (0,5 no se releía como 0,5)se relee exactamente, sea cual sea el separador del equipo
speechout: un nuevo of_speak (u of_close) durante una lecturala lectura cortada no levantaba ningún ue_stoppedtoda lectura empezada termina con un ue_stopped
speechout: il_timeout_ms = 0cortaba la lectura síncrona a los 5 ssin límite (24 horas como máximo)
speechout: una voz que no pudo crearse (runtime WebView2 ausente, página rechazada)of_speak, of_speak_from, of_pause, of_resume, of_enqueue, of_clear_queue devolvían -1, of_open el código bruto de la DLL-2 (componente no creado, como en todas partes), is_last_error dice por qué; -4 si la página no respondió
speechout: of_speak_sync llamado desde un evento levantado durante otro of_speak_synccortaba la lectura de la llamada exterior, que devolvía 0 de todos modosrechazado: -4, is_last_error = "already speaking synchronously"
speechout: of_speak_from más allá de la última frase0, no se leía nada-5
speechout: of_is_speaking() justo después de of_speakfalse mientras no había llegado la lista de vocestrue desde of_speak
speechout: of_pick_voice("", género), o lista de voces ilegibleelegía en el idioma de la página; un fallo vaciaba is_voice"" = is_lang; un fallo conserva is_voice y rellena is_last_error
speechout: of_voice_used, of_duration, of_spoken_text justo después de cambiar is_lang o el diccionariopodían responder con los ajustes anterioresresponden con los ajustes recién puestos
speechout: error de script en la página de la vozsilenciosoue_error("script error: …")
statictext: il_back_color con ii_corner_radiusel fondo llenaba todo el rectángulo, solo el trazo del borde se redondeabael fondo sigue el redondeo; fuera de las esquinas, el color del objeto sobre el que está el bloque, que también toma el userobject
statictext: is_marquee_direction con lectura de derecha a izquierdainvertido: MARQUEE_START se desplazaba hacia el final, "left" hacia la derechaMARQUEE_START se desplaza hacia el inicio de la lectura; "left" / "right" siguen siendo físicos
statictext: releer il_back_color, ii_marquee_speed, is_marquee_direction, ib_marquee_overflow_only, ib_marquee_pause_on_hover, is_font_family-1, 0, "", false fuera cual fuera el valor; una familia con espacio entre comillasel valor asignado
statictext: ii_marquee_speed = 0mantenía la velocidad anteriorvelocidad por defecto (60)
statictext: of_reset tras un bordecolor y grosor conservados: el borde siguiente los heredababorrados
statictext: ib_track_mouse, componente desactivado durante el paso del cursorue_mouse_leave nunca lanzadoue_mouse_leave lanzado al salir
statictext: desplazamiento (ib_marquee)un [foldarea] ya no se plegaba después; con ib_marquee_overflow_only, un cambio de ALTURA volvía a empezar; con ib_wrap = false, un ue_text_overflow(true) erróneocorregido: el texto ya no se copia, solo una ANCHURA realmente nueva se vuelve a medir, y el desplazamiento muestra todo el texto
statictext: ib_hover_effect y enlaces con el cursor encima en un tema oscurooscurecidos (menos contraste)aclarados
Texto enriquecido: [symbol=clock]se mostraba tal cualun glifo monocromo; un nombre desconocido sigue siendo texto
statusbar: of_add_panel / of_insert_panel con una clave ocupada o que contiene / o una barra vertical; of_move_panel, of_remove_panel, of_clear_menu, of_add_menu_separator con un panel desconocido; of_add_menu_item / of_insert_menu_item bajo un panel desconocido o con una entrada ocupada; of_remove_menu_item, of_move_menu_item con una dirección desconocida0, ignorado-5
statusbar: of_insert_panel(…, 0)añadido al final de la barrael primero, como toda posición (0 o menos = el primero)
statusbar: un separador (of_add_sep) en of_count, of_keys_at y las posiciones de of_insert_panel / of_move_panelcontado como un panel de clave vacíaignorado: una posición cuenta paneles
statusbar: un separador entre dos paneles ALIGN_ENDdibujado al final del grupo de inicioentre los dos: abre el grupo del panel que lo sigue
statusbar: clic derecho en un panel no clicableningún eventoue_panel_rclicked (un panel desactivado sigue mudo)
statusbar: of_panel(k).ii_progress leído en un panel sin barra0, como una barra al 0 %-1
statusbar: of_menu_item("k"), una dirección de un solo nivelescribía en el panel k (ib_enabled lo atenuaba)no designa nada: no escribe en ningún sitio, se relee vacío
statusbar: colores e información sobre herramientas de un panel tras of_clear, y luego un panel añadido con la misma claveretomados por el nuevo panelolvidados: el panel empieza limpio
statusbar: is_state en un tema oscuro; panel desactivadocolores del tema claro, poco legibles; atenuado por transparencia, fondo perdido al pasar el ratónuna paleta oscura legible; atenuado con el color del tema, fondo conservado
statusbar: un panel cuyas entradas de lista están todas ocultasmano y flecha, clic sin efectoun panel normal, clicable o no según ib_clickable
statusbar, toolbar: flechas Izquierda / Derecha en lectura de derecha a izquierda (RTL)al revés: Derecha iba hacia la izquierda de la pantallaen el sentido de la pantalla, como la pestaña y la cinta
stepbar: asignar ii_currentno se lanzaba nadaue_step_changed cuando la barra se mueve, como prometía la documentación
stepbar: retirar, insertar o desplazar un paso antes del paso en cursoel paso en curso cambiaba sin avisar (era un rango)el mismo paso sigue en curso; si es él el que se retira, la barra pasa al siguiente alcanzable y lanza ue_step_changed
stepbar: ii_current asignado antes de los pasos; of_clear_stepsdevuelto al primer paso; el paso en curso sobrevivía al vaciadose conserva y se aplica en cuanto el paso existe; el vaciado vuelve a empezar en el primer paso
stepbar: of_add_step / of_insert_step con una clave ocupada o que contiene / o una barra vertical; of_move_step, of_remove_step con una clave desconocida0, ignorado-5
stepbar: of_insert_step(…, 0)añadido al final de la barrainsertado al principio, como toda posición de la biblioteca (of_add_step añade al final)
stepbar: flechas izquierda / derecha en un idioma de derecha a izquierdala flecha derecha iba al paso siguiente, dibujado a la izquierdainvertidas: la flecha izquierda va al paso siguiente
tab: of_add_page / of_insert_page con una clave que contiene / o una barra vertical; un envío fallido0; la página seguía alojada y su clave ocupada-5; un envío fallido devuelve su código, la página vuelve a su ventana y la clave queda libre
tab: of_select_page de una página oculta, desactivada o más allá del límite de la demo0, y la página se mostraba bajo una barra sin pestaña activa-5, nada se mueve
tab: cruz, atajo (is_shortcut), «Cerrar todas / las demás / a la derecha» en una pestaña desactivada u ocultala pestaña se activaba o se cerraba, y PB liberaba su páginasin efecto: una pestaña que no se puede ver ni alcanzar no se activa ni se cierra
tab: la pestaña activa se cierra, se retira o se ocultatomaba el relevo la siguiente o la primera, aunque estuviera oculta o desactivada; el as_from_key de ue_selection_changed estaba vacíotoma el relevo la vecina seleccionable (derecha, si no izquierda); as_from_key nombra la pestaña realmente abandonada, aunque haya desaparecido
tab: ninguna pestaña visible (todas ocultas, o una disposición que las oculta)la página de la antigua pestaña seguía visible, sin eventola página se oculta y se lanza ue_selection_changed(antigua, ""); volver a mostrar una pestaña la selecciona
tab: un handle conservado tras of_remove_page o un cierre; su atajose quedaban; una página reabierta con la misma clave recuperaba color, tooltip y antiguo atajoliberados: IsValid() devuelve false, la página vuelve nueva
tab: of_set_layout con un texto que no es JSON0, y el mensaje salía roto-5, no se envía nada
tab: teclado en la barra de pestañasIntro perdía el foco; las flechas se detenían en las pestañas desactivadas o desbordadas; ni Arriba/Abajo en barra vertical ni inversión en escritura de derecha a izquierdael foco se queda en la pestaña; las flechas siguen el eje de la barra y saltan lo que no responde; Supr cierra una pestaña que se puede cerrar
tab: texto de una pestaña desactivada; tooltip de una pestaña con el título truncadoatenuado en bloque (ilegible al pasar el ratón en office2007 oscuro); el nombre completo nativo ocultaba su tooltiptexto en el color desactivado del tema, legible; su tooltip tiene prioridad
tilesbox: of_get_layoutdevolvía siempre "": una disposición guardada nunca se restaurabala disposición entera, el mismo texto que ue_layout_changed; también conserva el tamaño y la visibilidad de cada mosaico y la visibilidad de cada grupo
tilesbox: of_set_layout que nombra un mosaico bajo otro grupo distinto del suyo; un texto que no es JSONel primer mosaico con esa clave, en cualquier grupo, se movía allí; 0un mosaico se encuentra por su grupo y su clave: la entrada se ignora; -5 ante un texto que no es JSON
tilesbox: of_add_group con una clave ya ocupada; of_add_tile / of_insert_tile con una clave ocupada o bajo un grupo nunca añadido; una clave vacía, o con / o ``0; un grupo añadido de nuevo se renombraba, un mosaico bajo un grupo desconocido lo creaba con su clave-5, no se añade nada: añada primero el grupo con of_add_group
tilesbox: of_move_tile, of_remove_tile, of_add_live_item, of_clear_live_items sobre un mosaico inexistente; of_remove_group sobre un grupo inexistente0-5
tilesbox: un handle conservado tras of_remove_tile, of_remove_group, of_clear, o un mosaico arrastrado a otro grupoquedaba en memoria; un mosaico recreado en la misma dirección recuperaba colores e información sobre herramientas del antiguo, un mosaico arrastrado los perdíael handle se libera (vuelva a pedirlo con of_tile / of_group); colores e información sobre herramientas siguen al mosaico arrastrado y se van con lo que se elimina
statusbar, stepbar, crosstab: un handle conservado tras of_remove_panel, of_remove_menu_item, of_clear_menu, of_clear (statusbar), of_remove_step, of_clear_steps (stepbar), of_remove_calc_field u of_remove_calc_measure (crosstab)seguía en memoria hasta la destrucción del componenteliberado: IsValid() devuelve false; vuelva a pedirlo con of_panel, of_menu_item, of_step u of_field
Todos los componentes con elementos: releer il_back_color_hover / il_text_color_hover de un elemento nunca coloreado0, el negro-1, «el color del tema», como los otros tres colores del elemento
tilesbox: releer ib_enabled / ib_visible de un grupo, o ii_badge_sizefalse, false, 0 fuera lo que fuera lo puestoel valor vigente
tilesbox: grupo desactivado (ib_enabled = false)su encabezado aún lo plegaba (clic, Intro) y lanzaba ue_group_toggled; un mosaico arrastrado podía caer en élinerte: ni pliegue, ni evento, ni soltar
tilesbox: colores de item (il_back_color, il_text_color, il_accent…) puestos en un gruposin efecto; el color de un grupo a podía pintar un mosaico a de otro grupopintan el encabezado del grupo (fondo, título, paso del ratón, filete de acento), nunca sus mosaicos
tilesbox: of_tile(""), o una dirección de uno o tres nivelesponer una propiedad detenía la aplicación («Array boundary exceeded») o escribía en el grupoun handle inerte: no escribe nada y se lee vacío
tilesbox: teclado y lector de pantallael foco se perdía en cada actualización venida de PB (un distintivo) y el menú de tamaño se cerraba; menú de tamaño solo con el ratón; en RTL, flechas al revés; etiquetas leídas con sus etiquetas de formatofoco y menú conservados; menú de tamaño con el teclado (flechas, Intro, Esc); flechas en el sentido de lectura; texto sin formato
toaster: il_max_visiblepredeterminado 5, enviado por CADA toaster: un toaster que había establecido 10 volvía a 5 en cuanto otro mostraba un toastpredeterminado 0 = no se envía nada; el límite es COMÚN a la aplicación y gana el último valor establecido (5 mientras nadie lo establezca)
toaster: of_show de un toast que espera sitiodevolvía 0: el toast no se podía cerrar con of_close, y sus eventos llevaban un id nunca recibido; cola llena (200): 0 también, toast perdido sin decir nadaun identificador real, enseguida; of_close lo retira de la cola; cola llena: -4
toaster: dos toasts sin is_key con un botón de la misma claveel segundo REEMPLAZABA al primero (la clave del botón se tomaba por la del toast) y of_show devolvía el id del primerodos toasts, dos identificadores; solo is_key actualiza en su sitio
toaster: eventos de varios toastersarchivados por VENTANA: dos toasters anclados a la misma ventana se robaban los eventos, y los de un toaster destruido iban al siguientecada toaster recibe los de SUS toasts; un toaster destruido ya no recibe nada, sus toasts siguen en pantalla, mudos
toaster: pbm_custom02 de la ventana ipo_ownerla ventana de anclaje recibía un pbm_custom02 en cada evento de toast, incluso sin ipo_receiversolo una ventana establecida en ipo_receiver lo recibe; si había mapeado pbm_custom02 de su ventana para los toasts, establezca ipo_receiver, o mejor, retire ese código: los eventos llegan solos
toaster: visualizaciónun toast se quedaba quieto cuando su ventana se movía; un toast de más de 800 px (una larga traza de error) NUNCA aparecía; anchura sin escalar (180 px al 200 %); actualizar un toast sobrevolado reiniciaba toda la pilasigue a su ventana; el texto se desplaza dentro del toast limitado; anchura a escala de la pantalla; la pila sigue en pausa bajo el puntero
toolbar: adiciones, of_add_separator, of_move_item, of_remove_* con una clave ocupada, con / o ``, una barra desconocida o una dirección desconocida0, ignorado — una errata en el nombre de una barra creaba una barra fantasma-5; solo main no necesita of_add_bar
toolbar: of_clear, of_remove_bar, of_remove_itemlos handles se quedaban, los atajos seguían activos, y una herramienta recreada con la misma clave recuperaba los colores de la anteriorhandles liberados, atajos desactivados, colores y tooltips olvidados; vuelva a pedir un handle tras una retirada
toolbar: of_item con una dirección de tres niveles (una entrada de menú)actuaba sobre la HERRAMIENTA de la barra que llevaba el nombre de la entradano designa nada; una entrada se controla con of_menu_item(dirección)
toolbar: entrada elegida en un desplegable plegado en el chevrónue_menu_selected sin el padre de la cascada, bajo otro desplegable, o vacíola dirección completa, como en la barra
toolbar: ii_index de una barranunca movía una barra hacia la derechala barra toma el rango pedido
toolbar: of_add_bar(clave, banda, rango) en un rango ya ocupado, o una banda más allá de las demásorden indefinido; la banda se releía tal cual (5 para la segunda fila)se inserta delante de la barra que ocupaba el rango; las bandas se reagrupan
toolbar: of_count, of_keys_at de una barra, rango de of_move_itemcontaban los separadores, con una clave vacíasolo las herramientas: un separador no tiene ni clave ni rango
toolbar: Intro en un cuadro de textovalidaba el campo Y pulsaba el botón predeterminado de la ventanavalida solo el campo; Escape le devuelve su texto validado
toolbar: is_shortcut releído; ii_band / ii_index de una barra desconocidactrl+s (normalizado); 1Ctrl+S, tal como se escribió; 0
toolbar: color o tooltip puesto en una BARRA (of_bar)sin efecto, o pintaba la herramienta del mismo nombreaplicado a la barra, y solo a ella
toolbar: atajo de una herramienta oculta o más allá del límite de la demose tragaba la teclala tecla va a la siguiente herramienta con el mismo atajo
webbrowser: una página que no se carga (host desconocido, red, certificado, of_stop)lanzaba ue_load_completed, como un éxitolanza ue_load_failed(as_url, al_status) en su lugar
webbrowser: palabras en is_address («factura 2026»)salían como https://factura 2026 y después ya no se navegabarechazadas con ue_error, lo siguiente se carga; una búsqueda si is_search_url está definido
webbrowser: una ruta de disco (C:\temp\x.html) o //host/x en is_addressprecedido de https://, por tanto introuvablefile:///C:/temp/x.html; https://host/x; javascript: rechazado
webbrowser: is_address releído tras seguir un enlace o Atrásla última dirección asignadala página mostrada
webbrowser: of_go_back, of_go_forward, of_stop justo después de is_addresspodían ejecutarse ANTES de la dirección; of_stop dejaba reanudar las páginas en esperase ejecutan en el orden escrito; of_stop también descarta las páginas en espera
webbrowser: of_save_as_png, of_save_as_jpg, of_print_to_pdf, of_printcapturaban o imprimían la barra de direccionesel sitio mostrado
webbrowser: enlace target=_blank, window.open tras un clicno pasaba nadala página se abre en la vista, ue_new_window lo indica
webbrowser: respuesta de of_execute_javascript de más de 4.095 caracterescortada sin avisarentera
webbrowser: F5, Ctrl+R, Ctrl+rueda en la barra de direccionesrecargaban o ampliaban la propia barrasin efecto en la barra; activos en el sitio
webbrowser: clic derecho en un campo de texto con ib_context_menuAtrás / Adelante / RecargarCortar / Copiar / Pegar
webbrowser: Tab u of_focus_webview sin barra de direcciones; archivo soltado en el sitio con ib_allow_dropfoco perdido en una barra de 0 px; archivo abierto por el navegadorel foco va al sitio, Tab sale de él hacia su ventana; ue_drop_files
pdfviewer: is_source releído, y as_source de ue_load_completedla dirección interna /_file/?p=…lo que usted escribió (doc\notice.pdf)
pdfviewer: fichero ausente, no es un PDF, sitio inaccesible o que rechaza el marcoue_load_completed sobre una página de error, o ningún eventoue_load_failed(as_source, as_reason) (constantes REASON_*), el visor permanece vacío
pdfviewer: http://, data: de un tipo distinto de PDF, página web en https://mostrados (o marco vacío para http://)rechazados: ue_load_failed con REASON_INSECURE o REASON_NOT_PDF
pdfviewer: un # en is_sourcecortaba la ruta (Presupuesto #12.pdf no encontrado); el fragmento de una URL se mezclaba con ii_page / ii_zoomun # forma parte del nombre del fichero; el fragmento de una URL se ignora, página y zoom pasan por las propiedades
pdfviewer: ii_page asignado antes de is_sourceperdido: el documento se abría en la página 1conservado para ese documento; sin página asignada desde el último is_source, un documento nuevo se abre en la página 1
pdfviewer: PDF regenerado en la misma ruta y luego of_refresh; PDF de 32 MB o más; ruta de más de 260 caracteresla versión anterior durante 5 minutos; nada; no encontradoel fichero tal como está en el disco; mostrado (servido por partes); mostrado
pdfviewer: enlace seguido en el documento; of_printel sitio reemplazaba el documento, sin vuelta atrás; imprimía la página que enmarca el documentoel documento permanece, ue_link_clicked(as_url) le da la dirección; of_print imprime el documento (-4 sin documento)
picture, button, tilesbox: il_badge_color0 = el color del tema; el negro era inalcanzable; sin fijar, se releía 0-1 = sin fijar (el color del tema), como cualquier otro color; 0 es el negro. Sustituya il_badge_color = 0 por -1
picture: id_zoom fijado antes de ib_zoomablese releía como se fijó, mientras la imagen seguía encuadradaignorado: id_zoom se queda en 1.0 mientras ib_zoomable sea falso; fije primero ib_zoomable
picture: ib_mirror sobre una imagen girada un cuarto de vuelta; is_align / is_valign con una rotaciónvolteo vertical en pantalla; la colocación giraba con la imagenespejo y colocación se leen en pantalla, sea cual sea la rotación
picture: arrastrar la imagen ampliada; rueda; imagen desactivada (statictext desactivado también)ue_clicked en cada desplazamiento; zoom hacia el centro, la imagen podía salir del marco; los archivos soltados seguían aceptándoseningún clic tras un desplazamiento; zoom hacia el puntero, la imagen cubre siempre su marco; desactivada, rechaza cualquier depósito; ue_error nombra la fuente
xml: una lectura (of_get_value, of_count, of_is_valid…) o un cambio tras una construcciónactuaba sobre el último documento CARGADO, o sobre nadael documento construido se carga y pasa a ser EL documento; el of_start_element siguiente empieza uno nuevo
xml: of_load fallido (vacío, mal formado), of_start_element tras una cargael documento anterior seguía legible y modificable (of_is_valid verdadero); un documento a medio construir seguía en of_xmlno queda nada
xml: of_xml, of_pretty, of_get_values de un documento grandecortado sin avisar más allá de unos MBentero
xml: of_get_value de un XPath de valor (count(//line), sum(//@qty))vacíoel valor como texto (3, true)
xml: un XPath cuyo prefijo se declara por debajo de la raíz (respuesta SOAP)vacío sin of_register_namespaceresuelto
xml: is_last_error tras un XPath no válido, una página que no responde, un rechazo; códigos de of_register_namespace / of_clear_namespacesvacío, o «no node matched» fuera cual fuera la causa; los cambios devolvían -4 cuando faltaba la página; siempre 0; una página sin respuesta devolvía el texto nullla verdadera razón; -2 cuando la página no responde; un URI vacío se rechaza (-5); vacío en lugar de null
xml: of_prettyperdía CDATA, comentarios, instrucciones de procesamiento y la declaración XML, y rehacía el texto mixtotodo se conserva; un elemento que contiene texto queda en una línea
xml: construcción — salto de línea o tabulación en un atributo, CR en un texto, carácter de control, nombre no válidoreleídos alterados; documento mal formado; nombre escrito tal cualreleídos idénticos; carácter de control eliminado; nombre rechazado (is_last_error), el elemento se omite
xml: un documento que contiene un elemento <parsererror>; mensaje de un XML mal formadorechazado como mal formado; mensaje enmarcado por «This page contains the following errors»cargado; solo la línea de error
xml: of_remove de nodos anidados, de la raíz, de un atributo; of_set_value("/"); of_add_child bajo un atributocontaba dos veces; vaciaba el documento; el atributo seguía; 0 sin efecto; «parent not found»el recuento real; la raíz se queda (0 e is_last_error); el atributo se quita; -4; «the node cannot have children»
xml: of_close y luego una lectura; ipo_owner fijado tras la primera lecturael documento cargado se perdía; ignorado hasta of_closeel documento se conserva y se vuelve a cargar; transmitido en la lectura siguiente
temas metro-light y metro-dark: texto sobre el color de acentoblanco sobre el azul #25a0da en ambos temas (cabeceras de panel, pestaña activa, botón de aplicación de la cinta, mosaicos): poco legiblemetro-light: el acento pasa al azul más profundo #1b76a1, texto siempre blanco; metro-dark: el acento sigue siendo #25a0da, el texto encima pasa a casi negro (#1b1b1b)
temas office-dark, office2003-dark, office2003-light, office2007-light: colores de acento y de cabeceraen modo oscuro, el acento se leía mal sobre la página (viñeta de paso, insignia), igual que el texto blanco sobre el acento al pasar el ratón y sobre las cabeceras de columna del crosstab; en modo claro, la parte alta de los degradados del botón de aplicación y de las cabeceras de panel era demasiado pálida para el texto blancooffice-dark: acento #1178d1, paso del ratón #0f6cbd; office2003-dark: acento #4574cb, paso del ratón #2f5aa8; cabeceras del crosstab más oscuras al pasar el ratón y en los totales; office2003-light y office2007-light: inicio del degradado más profundo (#3e73cf, #4275c5), cabeceras de panel de office2007-light más opacas. Texto siempre blanco, al menos 4,5:1
texto sobre un color elegido por la aplicación (il_accent, color de un elemento, cabecera de panel, insignia)blanco hasta un color bastante claro: un azul medio como #25a0da recibía texto blanco a 2,95:1blanco o casi negro (#1b1b1b), el que mejor se lea (relación de contraste WCAG): #25a0da recibe ahora texto oscuro
jsontree: of_clearvaciaba el árbol Y devolvía ib_wrap e ib_search_enabled a sus valores por defectosolo vacía el árbol; los ajustes se mantienen (es of_reset el que lo restablece todo)
jsontree: is_json = ""lanzaba ue_error «Invalid JSON»vacía el árbol sin error, como prometía la documentación
jsontree: números y claves mostrados, is_json releídoreescritos por el motor: 12345678901234567890 mostrado 12345678901234567000, 1.10 → 1.1, la primera de dos claves idénticas perdida; is_json se releía compactado, y vacío tras un JSON inválidotal como se recibieron, las dos claves incluidas; is_json se relee tal como se fijó
jsontree: of_match_count, al_count de ue_search_resultcontaban LÍNEAS; dos ocurrencias en una línea eran ambas «actuales»cuentan OCURRENCIAS, solo una es la actual y of_search_next pasa de una a otra
jsontree: bloques abiertos por una búsquedaTODOS los que contenían una coincidencia, para siempre: buscar «e» abría todo el documentosolo los que ocultan la ocurrencia ACTUAL; of_clear_search devuelve los pliegues de antes de la búsqueda
jsontree: of_select_pathuna línea oculta en un bloque plegado seguía invisible; una ruta desconocida devolvía 0los bloques que la ocultan se abren; una ruta desconocida devuelve -5 y la selección no se mueve
jsontree: plegar el bloque que contiene la selecciónla selección se volvía invisible, y la flecha siguiente volvía a empezar desde arribala selección pasa al bloque plegado; con un gesto del usuario, ue_selection_changed lo indica
xmltree: of_clearvaciaba el árbol Y devolvía ib_wrap e ib_search_enabled a sus valores por defectosolo vacía el árbol; los ajustes se quedan (es of_reset el que restablece todo)
xmltree: is_xml = ""lanzaba ue_error «Invalid XML» y mostraba un error rojovacía el árbol sin error, como la documentación prometía
xmltree: is_xml relureserializado por el motor: comillas cambiadas, saltos de línea perdidos, vacío tras un XML inválidose relee tal como se asignó, incluso un texto inválido
xmltree: ce qui s'afficheun CDATA era invisible (el elemento aparecía vacío), faltaban comentarios, instrucciones de procesamiento y declaración, el texto de un contenido mixto se pegaba antes de los hijos, un texto perdía sus espacios, un valor de atributo con comillas se mostraba tal cualcada nodo en su sitio, en el orden del documento; la línea sigue siendo XML (comilla elegida o &quot;, &#10;, &amp;, &lt;); los espacios significativos se quedan
xmltree: of_match_count, al_count de ue_search_resultcontaban LÍNEAS; una coincidencia a caballo entre dos trozos (id="4152") se contaba sin resaltarsecuentan APARICIONES, cada una resaltada, solo una es la actual
xmltree: éléments ouverts par une rechercheTODOS los que contenían una coincidencia, para siempresolo los que ocultan la aparición ACTUAL; of_clear_search devuelve los pliegues de antes de la búsqueda
xmltree: of_select_pathuna línea oculta en un elemento plegado seguía invisible; una ruta desconocida devolvía 0los elementos que la ocultan se abren; una ruta desconocida devuelve -5 y la selección no se mueve
xmltree: ue_selection_changedse lanzaba también sin cambio (Fin en la última línea); plegar el elemento que contenía la selección la volvía invisible, sin avisose lanza solo cuando la selección cambia; al plegar, la selección pasa al elemento plegado y el evento lo dice
xmltree: ue_errorel texto bruto de la página de error del motor; un elemento <parsererror> del documento pasaba por un errorsolo la línea del error («error on line N at column M: …»); un <parsererror> del documento es un elemento como otro
restclient: cookies de una petición síncronaninguna guardada: cada of_get / of_post abría su propia sesión; ib_keep_cookies solo valía para lo asíncronouna sesión por objeto, común a lo síncrono y lo asíncrono: un inicio de sesión síncrono le mantiene conectado para las llamadas siguientes
restclient: ib_keep_cookies cambiado tras la primera peticiónsin efecto hasta of_closese aplica de inmediato; a false, las cookies ya guardadas se olvidan
restclient: redirección hacia otro host o puertosolo caían Authorization, Cookie y la autenticación Basic: una clave de API (X-Api-Key…) iba al terceroninguna cabecera puesta con of_set_header sigue, solo queda Content-Type
restclient: of_set_bearer("") tras of_set_basic; of_set_basic y luego of_set_bearer; of_set_basic("", "")la contraseña Basic seguía enviándose; dos Authorization a la vez; se enviaba Basic Og==una sola autenticación a la vez: cada una reemplaza a la otra, un token o un usuario vacío la retira
restclient: HEAD, o respuesta 204 / 304 que anuncia un tamaño-4 «connection lost», y repetida en asíncronoel estado (200, 304…)
restclient: cuerpo con un byte no válido; charset=iso-8859-1 o utf-16todo el cuerpo releído en Windows-1252; charset ignoradosolo el byte no válido se vuelve un carácter de reemplazo; se lee el charset anunciado
restclient: cuerpo de texto de varios cientos de MBguardado tres veces en memoria: un proceso de 32 bits podía morir-4 «body too large : use of_download» más allá de 64 MB
restclient: cien peticiones asíncronas lanzadas de golpecien hilos en paraleloseis como máximo a la vez, las siguientes esperan su turno
restclient: una petición asíncrona enviada más a menudo que cada 50 ms (un temporizador de telemetría)ninguna respuesta entregada mientras duraba el flujolas respuestas llegan a medida que vienen
restclient: of_cancel de un id desconocido; de una petición cuya respuesta ha llegado-1; 0 (pero llegaba ue_response)-5; -4, demasiado tarde
restclient: of_response_text() tras of_download; tras un of_download(url, "")el número de bytes escritos; la respuesta anteriorvacío: ese cuerpo está en el archivo; vacío
restclient: leer una respuesta asíncrona durante ue_progressuna memoria en escritura: posible cierrevacío, of_status(id) = 0 mientras la petición está en curso
video: cambiar de película (is_source, of_play(source))el segmento, los subtítulos, marcadores y capítulos de la película anterior se quedabanse van con ella (fijados antes de cualquier película, esperan a la primera); una película de la lista conserva sus subtítulos. Fíjelos después de is_source
video: of_go_chapter, of_next_chapter, of_previous_chapterlanzaban ue_seeked; of_go_chapter más allá del número de capítulos devolvía 0 sin hacer nadaue_seeked y ue_chapter_changed, como un clic en la barra; -5
video: of_add_source con un is_source fijadola lista nunca empezaba, of_next iba a la primera películala primera entrada se carga enseguida (salvo que la película fijada SE ESTÉ REPRODUCIENDO: la lista la sigue al terminar)
video: ue_started tras of_stop o el final de la película, luego of_playnunca: una vez por fuenteen cada nueva reproducción (no al reanudar una pausa)
video: of_play sobre una película en error; of_reset; ii_rate en la película siguiente«en curso» para siempre, sin evento; la película anterior seguía cargada (of_duration, of_capture); vuelta a la velocidad normalue_failed de nuevo; la película se descarga; la velocidad se mantiene
video: of_capture a un archivo que no se puede escribir; a «\x» o «C:x»-4 (la doc decía -5); escritos según la carpeta actual-4, y no queda ningún archivo truncado; -5: dé una ruta completa
video: pantalla completa y luego Alt+Tab a otra aplicaciónla película seguía por encima de todola otra aplicación pasa delante; volver a la suya pone de nuevo la película por encima de todo
pdfviewer: un clic simple en un enlace del PDFnada: solo Ctrl+clic lanzaba ue_link_clickedue_link_clicked(url), el documento sigue mostrado
webbrowser: una página data: (is_address = "data:text/html,…")mostrada, pero ningún ue_load_completedue_load_completed con la dirección pedida
webbrowser: una nueva ventana pedida por el sitio hacia file:, data: o mailto:abierta en la vista, ue_new_window lanzadorechazada: ue_error, sin ue_new_window; solo se abren http y https
webbrowser: un sitio que pide la cámara, el micrófono, la ubicación, las notificacionesaviso del navegador al usuario, respuesta recordadarechazado salvo que ue_permission_requested devuelva true; no se recuerda nada
webbrowser: cookies, sesiones y almacenamiento de los sitiosen el perfil compartido con los componentesen un perfil de navegación propio: una sesión iniciada en 3.0 no se conserva (volver a conectarse una vez); of_clear_browsing_data la borra
webbrowser: is_search_url sin %s, sin http(s):// o en javascript:aceptado: cada búsqueda fallaba o perdía el texto escritorechazado: ue_error, el motor vigente se mantiene
webbrowser: gestion/ o [::1]/x en is_address«no es una dirección» (o una búsqueda)https://gestion/, https://[::1]/x; la palabra sola sigue siendo texto
webbrowser: clic derecho sobre una selección, un vínculo, una imagen con ib_context_menusolo Atrás / Adelante / Recargarademás: Copiar, Abrir vínculo, Copiar dirección del vínculo, Copiar imagen
tab: pestaña cerrable desactivada (ib_enabled = false)la cruz desaparecía pero su hueco quedaba vacíoni cruz ni hueco: la pestaña mide como una no cerrable
video: of_chapters con un título que contiene `` o un tabuladorpartido en dos capítulosleído tal cual
video: un .srt en Windows-1252 o UTF-16acentos ilegibles; ningún subtítuloleído correctamente
commandpalette: of_open sin runtime WebView2; toaster: of_show sin runtime-1-6, como el cuadro de mensaje
crypto, xml, restclient: of_open cuando la página o el cliente no puede crearseel código bruto de la DLL (-1, -3…)-2, e is_last_error dice por qué

Si había sorteado alguno de estos defectos — por ejemplo tratando ue_menu_selected con una dirección vacía para recuperar los clics de un grupo plegado —, retire el rodeo: el evento documentado llega ahora.

11.4 El generador n_pbt_menu2ribbon #

En la 3.0, el código escrito por n_pbt_menu2ribbon usaba métodos de handle que ya no existían: no compilaba sin retoques. En la 4.0 escribe la API actual — cada adición por su dirección, desde el componente —, retoma los submenús a cualquier profundidad, conserva los elementos atenuados y marcados, y su enrutador cubre ue_clicked, ue_toggled y ue_menu_selected. Las claves cambian: cada una es ahora el ClassName del elemento de menú (m_fichier/g1/m_ouvrir) en lugar de la ruta con puntos (m_principal.m_fichier.m_ouvrir).

La receta: una cinta ya construida a mano, o a partir de un código generado y luego corregido, no tiene nada que cambiar. Para partir de nuevo del generador, vuelva a lanzarlo y pegue también el nuevo enrutador: el antiguo leía claves con puntos.

11.5 Lo que se ha añadido #

Nada de lo siguiente pide modificar su código. Los nuevos componentes de la 4.0 se presentan en las notas de la versión.

ObjetoAñadido
ribbonof_add_menu_separator acepta la dirección de una entrada: la línea va a la cascada situada debajo
ribbonof_add_menu_item y of_add_menu_check aceptan una cascada de cualquier profundidad, y cada nivel se gobierna con of_menu_item(dirección)
menubarof_add_separator acepta la dirección de una entrada (file/export): la línea va a su cascada; of_menu(...) lleva los colores (il_accent, il_back_color…) y la información del título
crosstabof_set_label_filter(as_field, as_type, as_a, as_b) sobre texto (LABEL_CONTAINS, LABEL_BEGINS, LABEL_ENDS) y las constantes LABEL_GT, LABEL_LT, LABEL_BETWEEN: la forma con dos double solo podía pasar un número
cryptoKEYFORMAT_TEXT, KEYFORMAT_HEX, KEYFORMAT_BASE64 y una sobrecarga de of_hmac, of_jwt_sign y of_jwt_verify que los toma (una clave en BYTES: secreto entregado codificado, AWS SigV4); una entropía opcional para of_protect y of_unprotect
cryptoof_hmac_verify (un HMAC recibido — webhook — comparado en tiempo constante); of_jwt_header y una sobrecarga de of_jwt_sign que añade miembros a la cabecera (kid); of_totp_verify(…, ref al_step), el paso aceptado, para rechazar un código ya usado; il_password_hash_rounds
messageboxof_get_last_error(): por qué no se pudo abrir el último cuadro (cadena vacía si se abrió)
n_pbt_utilsof_dir_has_subfolders(as_dir, ab_include_hidden): la misma pregunta, contando también las carpetas ocultas, de sistema y las uniones
n_pbt_utilsof_dw_date_order(): el orden en que un DataWindow escribe una fecha en este equipo (dmy, mdy, ymd)
speechoutof_is_paused(): verdadero mientras la lectura está en pausa
Texto enriquecidola etiqueta [symbol=nombre]: dieciocho glifos monocromos que siguen el color del texto (capítulo 4)
toolbarof_menu_item(dirección) → n_pbt_toolbar_menu_item: cada entrada de menú desplegable tiene su estado (ib_enabled, ib_visible, ib_checked, is_text, is_shortcut), designada por su dirección completa
toolbaris_date en un selector de fecha; of_clear_menu; of_remove_item de una entrada de menú; of_add_menu_separator en una entrada (cascada); cascadas de cualquier profundidad
pdfviewerue_load_failed(as_source, as_reason) y las constantes REASON_*; ue_link_clicked(as_url); las direcciones file:///; ib_allow_save e ib_allow_print: los comandos Guardar e Imprimir de la barra del lector
pictureis_alt_text (texto alternativo que lee un lector de pantalla); un teclado para el zoom: +, -, 0 y las flechas para desplazarse; n_pbt_utils.of_json_get_str_array
webbrowseris_search_url (motor de búsqueda para las palabras que no son una dirección); ib_veto_new_window y ue_new_window; ib_veto_downloads y ue_download_starting; ue_load_failed; ue_error; of_show_html; of_clear_browsing_data e ib_private; ib_veto_navigation y ue_navigating; is_title y ue_title_changed; ue_permission_requested y las constantes PERMISSION_*; las constantes LOADSTATUS_* de ue_load_failed; F5, Ctrl+R, Alt+flechas y Esc en la barra de direcciones
jsontreeof_selected_text devuelve el valor DECODIFICADO de la hoja seleccionada (una cadena sin comillas ni escapes); of_has_selection distingue la raíz, cuya ruta es "", de «nada seleccionado»; el teclado salta las llaves de cierre (ya no se seleccionan)
xmltreecada atributo es un objetivo: un clic da su ruta (/order/@id), of_select_path lo selecciona, of_selected_value devuelve su valor; un documento grande solo dibuja las líneas en pantalla (8.000 elementos hermanos: 12 s → 0,15 s, una flecha en pocos ms)
videoue_muted_changed(ab_on): el usuario silenció o devolvió el sonido (el altavoz de la barra, la tecla M), como el volumen y la velocidad ya tenían su evento
ribbonof_remove_menu_item, of_clear_menu, of_remove_combo_item, of_clear_combo, of_remove_gallery_item, of_remove_app_menu_item, of_remove_contextual_group: las retiradas bajo un control — una lista «Archivos recientes» se actualiza sin volver a crear el control
ribbonof_app_menu_item(dirección): el handle de una entrada del menú de aplicación (is_label, is_image, ib_enabled, ib_checked, ib_visible); of_app_menu_item("") recorre el menú
ribbonteclas de acceso rápido de varias letras (is_keytip = "FP"), tecleadas una tras otra; nombres accesibles (barra de acceso rápido, mosaicos) para los lectores de pantalla
toolbarof_add_split_button: un botón dividido (acción + menú); is_group: conmutadores exclusivos (alineación); is_image en una herramienta y en una entrada de menú; ue_item_rclicked(dirección): el clic derecho de una herramienta

11.6 Nombres y recuentos alineados con el resto de la biblioteca #

Siete lugares hablaban de otra manera que el resto de la biblioteca. La 4.0 los alinea en lugar de mantener la diferencia: cambian dos nombres — el compilador le muestra cada línea que retocar —, la ruta que devuelve el árbol JSON pasa a ser la de n_pbt_json, la del árbol XML bajo un espacio de nombres por defecto un XPath que funciona, dos recuentos empiezan ahora en 1, como toda posición del producto, y un evento ambiental pasa a ser opcional. Son los únicos cambios de la 4.0 que piden retocar código que compilaba.

Qué3.04.0
progressbar: límites de la escalail_minimum, il_maximum, unos longid_minimum, id_maximum, unos double: una escala 0..1 o un número de bytes superior a 2 GB es válido; el prefijo dice el tipo
json: índice de arreglo en una rutadesde 0: lines/0 es la primera líneadesde 1: lines/1 es la primera línea; lines/0 no designa nada — una lectura lo da por ausente, una escritura devuelve -5
jsontree: ruta de un nodo (ue_node_clicked, ue_selection_changed, of_selected_path, of_select_path)niveles unidos por un punto, índice de array desde 0: lines.0.sku — un dialecto que n_pbt_json no leíala ruta de n_pbt_json: niveles unidos por /, índice desde 1 (lines/1/sku), "" para la raíz — para pasarla tal cual a of_get_string sobre el mismo texto
xmltree: ruta de un elemento bajo un espacio de nombres POR DEFECTO (xmlns="urn:…")/Envelope/Body — un XPath que no encuentra nada/*[local-name()='Envelope']/*[local-name()='Body'] — para pasar tal cual a n_pbt_xml.of_get_value; un elemento sin espacio de nombres o con prefijo conserva su ruta
toolbar: band y index de la disposición (of_get_layout, of_set_layout, ue_layout_changed)desde 0, una cadena llamada «opaca» mientras ii_band, ii_index y ue_bar_reordered contaban desde 1desde 1, como ii_band, ii_index y ue_bar_reordered; una ida y vuelta lectura → restauración devuelve la misma cadena
statictext: ue_cyclelanzado en cada bucle del desplazamiento, sin suscripción — y también por una animación dentro del textoun evento ambiental, por tanto opcional: lanzado solo cuando ib_track_cycle = true, como ue_mouse_enter con ib_track_mouse; solo en cada pasada completa del texto
tilesbox: 2.º argumento de ue_tile_movedas_to_keys, aunque lleva UNA clave: el grupo de destinoas_to_key: el nombre dice lo que lleva, como en todas partes (as_key = un nivel, as_keys = una dirección)
restclient: ue_failedue_failed (long al_id, string as_error)ue_failed (long al_id, long al_code, string as_error): -4 fallo, -5 URL o archivo — ya no hace falta analizar el texto
restclient: of_json_valueuna clave, primera aparición a cualquier profundidad; solo un valor de texto — un número devolvía el nombre de la clave siguienteuna ruta n_pbt_json ("json/customer", "items/1/qty"), cualquier valor: "4152", "true". Una clave anidada se nombra con sus padres

La receta: (1) recompile — el compilador señala il_minimum, il_maximum y as_to_keys: renómbrelos id_minimum, id_maximum y as_to_key; (2) busque las rutas json que apuntan a un arreglo y sume 1 a cada índice — un bucle for i = 0 to n - 1 sobre "lines/" + String(i) pasa a for i = 1 to n; (3) una disposición de toolbar guardada por la 3.0 cuenta desde 0: sume 1 a band y a index de cada barra antes de pasarla a of_set_layout, o deje que el usuario reorganice una vez — releída tal cual, juntaría sus dos primeras bandas; (4) donde ue_cycle esté programado, ponga ib_track_cycle = true en la construcción; (5) donde leía una ruta del árbol JSON (ue_node_clicked, of_selected_path) o daba una (of_select_path), sustituya los puntos por / y sume 1 a cada índice de array — lines.0.sku pasa a ser lines/1/sku, que va tal cual a n_pbt_json.of_get_string.


11.7 Los temas siguen a la aplicación #

La revisión de los temas ha hecho cumplir a cada componente la regla que el capítulo 4 ya anunciaba: la aplicación decide el tema y el acento, un componente solo se aparta de ellos en lo que se le pide. No se renombra ningún método; lo que cambia se ve en pantalla, al releer las propiedades y en dos códigos de retorno.

Qué3.04.0
PBT_SetDefaultThemecambiar de tema borraba el acento fijado con PBT_SetDefaultThemeAccent — incluso al volver a fijar el mismo tema — y aplanaba el fondo degradado de office2007 y office2003el acento de la aplicación se mantiene de un tema a otro; cada tema conserva su fondo
PBT_GetDefaultThemeAccentel acento del tema cuando la aplicación no había fijado ninguno-1 mientras la aplicación no haya fijado un acento
códigos de retorno nativosPBT_SetDefaultTheme con un nombre desconocido devolvía 0 y dejaba sin tema a los componentes siguientes; PBT_SetDefaultThemeAccent con un color de sistema de PowerBuilder lo pintaba de negro-5 en ambos casos; el tema o el acento anterior se mantiene
un eje de tema fijado solocongelaba el otro eje en el tema de la aplicación del momentoel eje vacío sigue el tema de la aplicación en cada uno de sus cambios; los dos ejes vacíos = el tema de la aplicación, por completo
is_theme_style · is_theme_mode · il_theme_accentse releían "", "" y -1, se hubiera fijado lo que fuerael estilo y el modo mostrados, y el acento propio del componente (-1 si no tiene)
un valor de eje desconocido ("office2010") o mal escrito (" Metro ")el componente perdía su tema y dejaba de escuchar el de la aplicación hasta el of_reset()espacios y mayúsculas ignorados; un valor desconocido se ignora y el eje conserva su valor
acento de un componente con tema localconservaba el acento de su tema, incluso cuando la aplicación fijaba unosigue el acento de la aplicación mientras no tenga el suyo
un acento personalizadosolo cambiaba el acento: el paso y la pulsación de los botones de acento, las selecciones teñidas, los botones marcados de la cinta conservaban el acento del tematodo lo que deriva del acento lo sigue
tilesbox : il_badge_color0 y -1 = el color del tema; releído 0 sin color fijado; el negro era inalcanzable-1 = el color del tema (releído -1); 0 es el negro, como en todos los colores
un color de sistema de PowerBuilder (ButtonFace…) en il_theme_accentpintado de negrocontado como -1: el acento de la aplicación
webbrowser · pdfviewerel contenido de terceros seguía el modo claro/oscuro de Windows, y un rectángulo blanco precedía su primera visualizaciónsigue el tema predeterminado de la aplicación, sobre el fondo del tema (4.11)
acento de office-dark y office2003-darkun azul oscuro, legible a 3:1 cuando coloreaba un texto (enlaces, [accent])un azul más claro (#479ef5, #7ea1e8), con un texto oscuro encima
datagrid: líneas entre filasausentes en ocho temas de diezpresentes en los diez temas, con el color de cuadrícula del tema
contraste alto de Windowslos iconos monocromos y los anillos dibujados como sombra desaparecíanadmitido (4.10)

La receta: (1) si volvía a fijar el acento después de cada PBT_SetDefaultTheme, ya no hace falta — y si contaba con un cambio de tema para borrar el acento, llame a PBT_SetDefaultThemeAccent(-1); (2) compruebe el código de retorno de PBT_SetDefaultTheme cuando el nombre venga de una entrada o de un archivo; (3) donde fijaba los dos ejes en cada componente para seguir a la aplicación, déjelos vacíos; (4) un mosaico cuyo distintivo volvía «al tema» con il_badge_color = 0 se escribe ahora -1.


11.8 crypto: lo que la seguridad rechaza ahora, y adónde van las rutas relativas #

La revisión de seguridad de crypto cierra una puerta real — un JWT falsificado con la clave PÚBLICA pasaba cuando faltaba el algoritmo — y sustituye varios silencios por un rechazo que dice su motivo. No se retira ningún método; una firma ECDSA cambia de forma, y las rutas relativas de los archivos siguen una sola regla.

Qué3.04.0
of_jwt_verify, of_jwt_signun algoritmo VACÍO valía JWT_HS256, y una clave PEM se aceptaba como secreto HS256: verificado con la clave PÚBLICA como secreto, un token falsificado pasaba; el algoritmo de la cabecera se comparaba sin mayúsculas, una cabecera crit se ignorabael algoritmo es OBLIGATORIO y se compara EXACTAMENTE; una clave PEM nunca es un secreto HMAC (of_hmac también); crit se rechaza — cadena vacía e is_last_error
of_jwt_signun exp dado en los claims se sustituía en silencio por la duración al_expires_secondsambos a la vez se rechazan: quédese con uno u otro
of_encrypt, of_decryptuna contraseña VACÍA cifraba — cualquiera releía el valorrechazada, como ya hacía of_encrypt_file; of_password_hash("") sigue permitido
il_pbkdf2_roundsun valor fuera de 1.000 a 10.000.000 volvía en silencio a 100.000la llamada se RECHAZA: cadena vacía para un texto, -5 para un archivo, e is_last_error dice los límites
of_password_hashil_pbkdf2_rounds (100.000 rondas)il_password_hash_rounds, 600.000 por defecto (la cifra de OWASP); los valores ya almacenados llevan sus rondas y siguen verificándose
of_base64_decode, of_base64url_decode, of_hex_decode, of_decrypt…bytes que no son un texto (un PDF, una imagen) volvían como caracteres de sustitución, sin errorcadena vacía e is_last_error, que remite a of_base64_decode_to_file o of_decrypt_file
of_sign (clave EC)una firma IEEE-P1363 (64 bytes), que openssl dgst y Java rechazanuna firma DER; of_verify lee ambas formas, una firma ya almacenada sigue verificándose; el JWT ES256 sigue en P1363
of_totp_code, of_totp_verifyun carácter no base32 en el secreto (un 0 tecleado por una O) se quitaba en silencio: OTRO secreto, códigos que nunca coincidíanrechazado (espacios y = tolerados)
of_encrypt_file«cualquiera que sea su tamaño»hasta 64 GB, el límite de un contenedor AES-GCM: más allá, -7
rutas relativas: n_pbt_crypto, u_pbt_zip, of_capture del reproductor de vídeoleídas en la carpeta ACTUAL (que se mueve tras un DirList o un cuadro de archivos), escritas junto al EXE (en el IDE: la carpeta de PowerBuilder)LEÍDAS en la carpeta actual, luego en la carpeta en la que arrancó la aplicación, luego junto al EXE; ESCRITAS en la carpeta en la que arrancó la aplicación — la misma en el IDE y compilada

La receta: (1) pase SIEMPRE el algoritmo de un JWT como constante (n_pbt_crypto.JWT_RS256), nunca leído del token ni de un INI al que le puede faltar; (2) si un servidor verificaba sus firmas EC en P1363 (.NET VerifyData por defecto), conviértalas o verifíquelas en DER (DSASignatureFormat.Rfc3279DerSequence); (3) un il_pbkdf2_rounds fijado fuera de límites debe volver entre 1.000 y 10.000.000; (4) un archivo que una ruta relativa escribía junto al EXE está ahora en la carpeta de arranque de la aplicación — dé una ruta completa si quiere otra.


11.9 restclient: cabeceras que dicen su rechazo, redirecciones que conservan la petición #

La revisión de restclient sustituye dos pérdidas silenciosas — una modificación nunca hecha tras una redirección, una autenticación nunca enviada tras una cabecera mal formada — por el comportamiento correcto o un rechazo que dice su motivo. No se retira ningún método; tres pasan a ser funciones, llegan dos propiedades, y la autenticación de Windows solo sale si usted la pide. Un punto vale para los cinco componentes no visuales que lanzan eventos: un error en su código de evento ahora se ve.

Qué3.04.0
of_set_header, of_set_bearer, of_set_basicsubrutinas: no se devolvía nada, un valor mal formado se guardaba tal cualfunciones long: 0, o -5 y nada cambia — nombre vacío, nombre con un espacio, dos puntos o un carácter de control, valor con un salto de línea; un valor vacío retira la cabecera
una petición con una cabecera mal formadasalía SIN NINGUNA cabecera — Authorization incluida —, sin error-5, e is_last_error = «invalid header: <nombre>»; no sale nada
redirección 301 / 302 de un PUT, PATCH o DELETEseguía en GET sin cuerpo: la modificación nunca se hacía, y la llamada devolvía 200método y cuerpo conservados; solo un POST se convierte en GET; un 303 sigue en GET sin cuerpo (salvo HEAD)
una conexión reutilizada (la de una redirección) que el servidor cierra en el mismo instante-4 y «request failed: 12152», de vez en cuandola petición se reenvía UNA vez, cuerpo incluido, por una conexión nueva: el servidor no había respondido nada
of_response_text ( ), of_response_headers ( ), of_response_header, of_json_valuela última respuesta síncrona del PROCESO: un segundo n_pbt_restclient la sobrescribíala del OBJETO; of_close la olvida
cuerpo leído como texto, aplicación de 32 bitslimitado a 64 MBlimitado a 16 MB (64 MB en 64 bits): más allá, -4 «body too large» — léalo con of_download
of_get_async, of_request_async… con una URL o una cabecera no válidaun id de petición, luego un ue_failed-5 al instante, no sigue ningún evento; is_last_error dice por qué («invalid URL: …»)
autenticación de Windows (Negotiate / NTLM)el sistema respondía por sí solo al desafío de un servidor de la intranet con las credenciales de la sesióndesactivada por defecto: las credenciales no van a ningún servidor sin ib_windows_auth = true (propiedad nueva); is_client_certificate (nueva) pone un certificado de cliente
of_cancel (long al_id), of_status (long al_id), of_response_text (long al_id)…el id de una petición de OTRO objeto alcanzaba esa peticiónsolo las peticiones del objeto: of_cancel devuelve -5 y no cancela nada, los lectores devuelven 0 / ""
of_status (long al_id) en ue_failedpodía devolver 200: el estado de una respuesta recibida y luego perdida0 para toda petición fallida
ue_failed-4 fallo, -5 URL o archivo-4 fallo, -5 archivo o certificado de cliente, -6 petición de rango rechazada en demo
error de ejecución en un evento de la aplicación — restclient, speechout, soundplayer, toaster, commandpalettetragado sin decir nada, y los eventos siguientes dejaban de entregarsellega al evento SystemError de la aplicación como cualquier error de script; los eventos siguientes se entregan
il_max_retriesreintentaba también un fallo que se repite de forma idéntica (demasiadas redirecciones, redirección no válida o HTTPS → HTTP, TLS, archivo imposible de escribir)esos fallos ya no se reintentan; 429, 503 y un fallo de red siguen haciéndolo
URL y rutasel fragmento #… iba al servidor; una Location relativa ?page=2 perdía el último segmento; una ruta relativa de of_download seguía la carpeta actual del momentoel fragmento ya no se envía; Location resuelta como lo hace un navegador (RFC 3986); una ruta relativa se resuelve en la llamada, en la carpeta actual de la aplicación al cargar la biblioteca

La receta: (1) pruebe lo que devuelven of_set_header, of_set_bearer y of_set_basic cuando el valor viene de una entrada, de un INI o de una base de datos — una llamada que ignora el retorno sigue compilando, pero el -5 es ahora la única huella de una cabecera rechazada; (2) una API de intranet con autenticación de Windows que respondía 200 ahora responde 401: ponga ib_windows_auth = true en ESE cliente; (3) una aplicación de 32 bits que lee como texto un cuerpo de más de 16 MB pasa a of_download; (4) si compartía un id de petición entre dos objetos, lea la respuesta en el objeto que la envió; (5) un error que ahora aparece en SystemError desde ue_response o ue_failed ya existía: se tragaba.

11.10 speechout: ajustes vivos, una destrucción silenciosa #

La revisión de speechout cumple dos promesas que la documentación hacía y el código no — un ajuste cambiado durante una lectura vale para la frase siguiente, of_speak_from más allá del texto devuelve -5 — y retira un evento levantado en mal momento. No se retira ningún método. Añadidos: of_add_abbreviation, of_clear_abbreviations, el evento ue_mark y dos etiquetas, [mark=nombre] y [rate=150]…[/rate].

Qué3.04.0
of_speak_from (al_index)más allá del texto, la lectura en curso se CORTABA, nada volvía a empezar, y el retorno era 0-5, y la lectura en curso continúa
ii_rate, ii_pitch, ii_volume, is_lang, is_voicecambiados durante una lectura, tomados solo en la lectura SIGUIENTE (la documentación prometía la frase siguiente)propiedades vivas: la frase siguiente las toma
ue_voice_fallbackmudo cuando solo faltaba la REGIÓN (se pedía fr-CA, voz fr-FR)levantado; las etiquetas de idioma se comparan sin mayúsculas, y fr_FR vale fr-FR
destroy (n_pbt_speechout)durante una lectura, levantaba ue_stopped — sobre una ventana ya medio destruidaningún evento; of_close() sigue levantando ue_stopped
of_sentence_count, of_countla cuenta del texto leído la vez ANTERIOR (0 antes de cualquier lectura)la cuenta de is_text tal como está
of_pause, of_resume, of_clear_queuecreaban la voz cuando no existía; una pausa durante la espera de las voces se perdía0 sin crear nada, -4 si la página no respondió; la pausa se mantiene hasta of_resume
ue_sentence (al_index)una abreviatura (Mr., Dr., e.g.), una dirección deletreada o una versión cortaban la frase; un texto sin punto era una sola fraseya no cortan; una frase de más de 250 caracteres se corta: los números de frase pueden cambiar
[pause=ms]ignorada al FINAL del textoun silencio tras la última frase, antes de ue_stopped

La receta: (1) pruebe el -5 de of_speak_from cuando el índice viene de un clic; (2) si su ue_stopped hacía algo al cerrar la ventana, llame usted mismo a of_close() en su close — la destrucción ya no lo levanta; (3) no guarde números de frase de una versión a otra: tómelos de ue_sentence, como la documentación siempre dijo.

11.11 statictext y texto enriquecido: un marcado leído de izquierda a derecha #

La revisión de statictext corrigió sobre todo el texto con etiquetas común (4.7): estas líneas valen para la etiqueta de todo componente — título de pestaña, panel de barra de estado, toast, cuadro de diálogo. No se retira ningún método. Añadido: of_refresh_parent_color(), y las zonas [action], [hyperlink] y los encabezados de [foldarea] de un statictext se alcanzan con el teclado (Tab, luego Intro o Espacio).

Qué3.04.0
of_escape_markup (une donnée collée à une balise)un ] escapado justo después de una etiqueta formaba pareja con el ] de la etiqueta: "[b]" + of_escape_markup("] fin") + "[/b]" mostraba [b]] fin sin negritael dato se muestra tal cual, y el formato a su alrededor se mantiene
[/b], [/i]…una etiqueta de cierre cerraba la ÚLTIMA etiqueta abierta, fuera cual fuera: [b]A[i]B[/b]C dejaba C en negrita; [/br] también cerraba algouna etiqueta de cierre solo cierra la suya (los estilos abiertos dentro continúan); una etiqueta de cierre sin apertura, o la de una etiqueta autocerrada, se ignora
[picture=…]cortada en la primera coma: un data URI (lo que devuelve of_icon()) o un nombre de archivo con coma no se mostrabalas dimensiones se leen al final del valor: ambos se muestran
[picture=\\server\share\x.png]la imagen se leía en el recurso compartido de redrechazada: una imagen del marcado nunca va a buscar un recurso compartido de red. Pase por of_icon(), que la incrusta, o por un picture
[hyperlink=HTTPS://…]un esquema en mayúsculas no se abríaabierto: el esquema se lee sin distinguir mayúsculas; la lista sigue siendo http, https, mailto
ii_padding0 = el margen del tema: una etiqueta nunca podía alinearse con el borde de un campo vecino-1 = el margen del tema (nuevo predeterminado), 0 = ningún margen
ue_clicked, ue_double_clickedlevantados al plegar un [foldarea] (tres eventos para un doble clic), y al soltar el ratón tras una selección de textoya no se levantan: plegar es cosa de lectura
[foldarea:… [action=…]]levantaba ue_action Y plegaba el bloquesolo ue_action, el bloque queda como está
ii_line_spacing, is_marquee_directionun valor fuera de 50-400 se ignoraba y se releía 0; un sentido desconocido ("UP") se desplazaba hacia el inicio pero se releía tal cualllevado al límite más cercano, releído tal como se aplicó; un sentido desconocido vale y se relee MARQUEE_START
of_scroll_to_endno devolvía nadadevuelve 0, o -2 si el componente no está creado

La receta: (1) un ii_padding = 0 escrito para decir «el margen del tema» pasa a -1 — o desaparece; (2) una imagen del marcado alojada en un recurso compartido de red pasa por of_icon(); (3) un ue_clicked que reaccionaba al plegado de una sección ya no se llamará: el plegado no se programa.

11.12 breadcrumb: qué cede cuando la ruta no cabe, y salir del campo #

La segunda revisión de la ruta de navegación (breadcrumb) corrigió el plegado por anchura, el modo OVERFLOW_SHRINK y lo que un segmento se lleva consigo. No se retira ningún método. Una línea vale para todos los menús nativos de la biblioteca: la búsqueda tecleando.

Qué3.04.0
of_edit() sans / without ib_editabledevuelve 0, no se abre nadadevuelve -4
salir del campo de la ruta hacia otro control de la aplicaciónel campo quedaba abierto, el texto a medio escribir, y no se informaba de nadaun texto modificado se valida: ue_path_entered; pasar a otra aplicación sigue conservando lo escrito
OVERFLOW_SHRINKtoda etiqueta limitada a 12 caracteres, incluso con sitio; el lugar actual cortado en seco en el borde de la barrano se corta nada mientras haya sitio; el centro cede primero, hasta una letra y …, el primer segmento y el lugar actual los últimos
OVERFLOW_COLLAPSEla etiqueta del lugar actual podía recortarse antes de que el centro se plegarael centro se pliega primero; el lugar actual solo se recorta como último recurso
of_insert_item(…, ai_index)los handles de los segmentos desplazados designaban otro segmento, sus colores y tooltips se quedaban en la dirección antiguasus handles se liberan, sus colores y tooltips los siguen; un segmento eliminado (of_clear, of_truncate, of_remove_item) se lleva los suyos
of_item("b").il_back_color / of_item("a/b").il_back_colordos valores para el mismo segmentouno solo: la clave única y la dirección designan el mismo segmento
OVERFLOW_SCROLL, rueda del ratónsin efectodesliza la tira
los menús nativos (ramas de la ruta, cinta, barra de menús, barra de herramientas, menú contextual): una letra tecleadano hacía nada, salvo mnemónicoslas letras tecleadas en el mismo segundo saltan a la primera entrada que empieza así («Win»), como en el explorador; un menú de más de 500 entradas solo dibuja lo que se ve

La receta: (1) un of_edit() cuyo 0 comprobaba sin haber puesto ib_editable devuelve ahora -4; (2) un ue_path_entered puede llegar cuando el usuario hace clic en otro sitio de la ventana — es el mismo texto que con Intro; (3) tras un of_insert_item en medio de la ruta, vuelva a pedir los handles de los segmentos que siguen.

11.13 buttonbar y teclado de la ventana: la tecla va al componente del foco #

La segunda revisión de la barra de botones (buttonbar) tocó el teclado de la ventana, que comparten todos los componentes que responden a Intro, Esc, una letra Alt o un atajo registrado (button, buttonbar y los atajos de of_register_shortcut de todos los componentes). No se retira ningún método; se añade uno, of_focus_button.

Qué3.04.0
dos componentes de una misma ventana responden a Intro, Esc o al mismo atajo (dos hojas MDI, dos paneles)la recibía el primero creado, incluso en la otra hojael más cercano al foco (misma hoja, mismo panel); en empate, ninguno: la tecla se queda en la ventana
Intro en un CommandButton PB con el foco, o en una DropDownListBox abierta; Esc en una lista abiertaactivaba el botón predeterminado / cancelar del componentese queda en el control, como en un cuadro de diálogo de Windows
of_register_shortcut(chord, key) en un botón de la barra, luego el botón deshabilitado y rehabilitado, o su letra is_shortcut cambiadael atajo se borrabase conserva: la letra Alt y el atajo de la aplicación ya no se tocan
la letra Alt de un botón frente a un atajo explícito de la misma teclaganaba el primero registradogana el atajo explícito; las letras solo se consultan después
of_clear_shortcuts()borraba también el is_shortcut de un buttonsolo borra los atajos de la aplicación
buttonbar: of_register_shortcut(chord) sin clave, o con una clave que no nombra ningún botóndevolvía 0 y se tragaba la tecla sin activar nadadevuelve -5
buttonbar: quitar el botón de is_default / is_cancel, o vaciar la barrala propiedad conservaba la clave; un botón vuelto a añadir con esa clave volvía a ser el predeterminadovaciada: el rol se va con su botón
buttonbar: otro botón de la barra tiene el focoel acento se quedaba en is_default mientras Intro activaba el botón enfocadoel botón enfocado lleva el aspecto predeterminado; is_default releído no cambia
buttonbar: un ii_padding_x negativovolvía a 12la sangría del tema, como ii_padding_y e ii_gap
buttonbar: la línea separadora entre botonesdibujada en medio del espacio, aunque los botones no se tocaransolo entre botones juntos (ii_gap = 0), y del lado correcto en lectura de derecha a izquierda

La receta: (1) en una barra, dé un atajo a UN botón — of_register_shortcut("Ctrl+S", "save") — la forma sin clave devuelve -5; (2) tras quitar y volver a añadir el botón predeterminado, vuelva a poner is_default; (3) para poner el foco en un botón concreto («No» en lugar de «Sí»), llame a of_focus_button("no").

11.14 button: un botón atenuado suelta la tecla, y Alt+letra responde #

La revisión del botón (button, obsoleto en favor de buttonbar pero todavía entregado y corregido) cambia lo que hace con el teclado y lo que releen sus propiedades. No se retira ni se añade ningún método.

Qué3.04.0
un botón atenuado con ib_default, ib_cancel o is_shortcut (ib_enabled = false)retenía Intro, Esc o su atajo en toda la ventana: la tecla se perdíadevuelve la tecla a la ventana (un CommandButton PB predeterminado, un SingleLineEdit la reciben); reactivado, la recupera
el & de is_text (&Guardar)subrayaba la letra, nada másAlt + la letra activa el botón esté donde esté el foco en la ventana, después de los atajos explícitos, nunca atenuado; una barra de menús PB que usa la misma letra la pierde
Intro o Espacio mantenidos sobre el botón con el focouna ráfaga de ue_clicked; Espacio se disparaba al pulsarun solo ue_clicked; Espacio se dispara al soltar, como en Windows
un is_shortcut que la ventana no sabe activar ("Win+S", "Ctrl+Entrée", "Ctrl+Pause")se releía tal cual; "Win+S" disparaba el botón con una S solarechazado: se relee "". Los nombres de teclas se escriben en inglés (Enter, Esc, Del)
is_shortcut con un tooltipel atajo no aparecía en ninguna parteañadido al tooltip (al título de uno enriquecido): «Guardar (Ctrl+S)»
of_register_shortcut("F5") en el botón, luego ib_default, ib_cancel o is_shortcut cambiadosF5 se borrabaF5 e is_shortcut responden los dos
is_text, is_image, is_style, ii_badge, il_badge_color, ii_badge_size, ii_image_size leídos tras of_reset()el valor anterior, aunque la pantalla estaba restablecidasu valor predeterminado ("", "standard", 0, -1)
un botón atenuado y la tecla Tabrecibía el focose salta
una etiqueta hecha solo de una imagen ([picture=…]), o un & dentro de una etiquetala etiqueta desaparecía, o la etiqueta de marcado se rompíamostrados tal como se escriben

La receta: escriba los nombres de teclas de is_shortcut en inglés ("Ctrl+Enter") y relea la propiedad en caso de duda: "" significa rechazado. Si atenuaba un botón predeterminado para «desactivar Intro», nada que cambiar: es lo que ocurre ahora.

11.15 menubar: una barra de menús que devuelve el foco, y Alt+letra desde cualquier sitio #

La revisión de la barra de menús (menubar) cambia lo que hace con el foco y el teclado, y lo que hacen todos los menús nativos en escritura de derecha a izquierda. Ningún método se retira ni cambia de firma.

Qué3.04.0
un clic en la barra y luego una elección (Edición > Pegar)la barra se quedaba con el foco: GetFocus() en ue_item_selected ya no nombraba el campo, el pegado se perdíael foco vuelve al control anterior antes de que se lance ue_item_selected; igual con Esc y con un clic fuera
Alt+F mantenido, o F10, con el foco en un camponada: solo Alt pulsado y luego F abría FileAlt+F abre File desde cualquier control, F10 hace lo que Alt; un Alt+F registrado por su aplicación conserva la prioridad, y un menú PowerBuilder nativo con la misma letra la pierde
Ctrl++, Ctrl+-, Ctrl+,, Alt+Left, Ctrl+Space, Ctrl+Tab, Ctrl+Backspace (todos los componentes con atajos)mostrados, pero nada se disparaba desde un control PB; el button los rechazaba ("")disparados esté donde esté el foco; estas teclas exigen Ctrl o Alt (solas, siguen siendo navegación)
en RTL, los desplegables de todos los menús nativos (barra de menús, cinta, barra de herramientas, ruta de navegación, menú contextual…)alineados a la izquierda, cascadas a la derecha, chevrón ›, Izquierda cerrabael desplegable cuelga alineado a la derecha bajo su título, una cascada se abre a la izquierda (chevrón ‹): Izquierda abre, Derecha cierra
un clic en el título de un menú ya abiertolo cerraba y luego lo volvía a abrir (un segundo ue_menu_opening)lo cierra, como en Windows
un is_shortcut puesto en una entrada que abre una cascadamostrado, y lanzaba ue_item_selected("file/export"), una dirección que ningún clic produceni mostrado ni disparado: un atajo va en una hoja
una barra cuyos menús están todos ocultos o atenuados, junto a una cintatomaba Alt para nada: los keytips de la cinta ya no salíandevuelve Alt a la cinta mientras ningún título sea alcanzable
dos títulos con la misma letra (&Archivo, &Favoritos con la misma letra)Alt+F abría siempre el primeroen la barra, la banda pasa de uno a otro, Intro abre
una entrada quitada y vuelta a añadir en la misma dirección (una lista de archivos recientes)recuperaba los colores y la información sobre herramientas de la desaparecidanace sin color (il_back_color se relee -1); igual tras of_remove_menu y of_clear
una letra acentuada o no latina en un desplegable (&Édition)subrayada, pero ninguna tecla la alcanzabase teclea como en el teclado
la tecla Tab en la barrauna parada por títulouna sola parada para toda la barra; las flechas pasan de un título a otro
nuevo—is_image (el icono de una entrada, cambiado en caliente), is_group (entradas de opción), ue_menu_closed(as_key) (un desplegable cerrado sin elección)

La receta: en ue_item_selected, trabaje sobre GetFocus() o sobre el DataWindow en edición como con un menú PowerBuilder; ponga un & en cada título; si su aplicación usaba Alt+letra para otra cosa, regístrelo (of_register_shortcut): conserva la prioridad.

11.16 ribbon: una elección que se mantiene, menús que siguen abiertos, rechazos que se dicen #

La segunda revisión de la cinta (ribbon) corrige lo que veía el usuario — una elección de fuente deshecha, un menú que se cerraba bajo el puntero — y aplica a la cinta la regla de la biblioteca: una adición o una retirada imposible devuelve -5. Ningún método se retira ni cambia de firma.

Qué3.04.0
ribbon: una opción en la lista de un cuadro combinado y luego la salida del campoue_combo_changed dos veces — la opción y luego el texto tecleado antes, que la sobrescribía; is_text releía el texto tecleadoun solo ue_combo_changed, la opción; el campo la muestra enseguida, incluso en un cuadro no editable
ribbon: Intro o Escape en un cuadro combinado, un contador, o sobre un botón de la cinta con el focoiban también al botón predeterminado o de cancelación de la ventanase quedan en la cinta; Escape en un campo devuelve el texto anterior a lo tecleado
ribbon: un menú abierto mientras la aplicación actualiza la cinta (otro control ocultado, una pestaña renombrada, un mosaico añadido)se cerraba, y la elección hecha en él no activaba ningún eventosigue abierto; solo se cierra si su propio control desaparece, se oculta o se atenúa
ribbon: is_app_button reescrito («File» → «Archivo»); is_app_button = ""el menú de aplicación se vaciaba; una cadena vacía mostraba «File»el menú se queda; una cadena vacía retira el botón y su menú
ribbon: of_select_tab de una pestaña desconocida u oculta0-5, nada cambia
ribbon: añadir una entrada de menú, un mosaico, una opción de cuadro combinado, un botón de acceso rápido, una entrada del menú de aplicación o un grupo contextual con una clave ya tomada; una clave con una barra vertical o que empieza por __; un padre desconocido (separador, encabezado, opción, entrada sin botón de aplicación, pestaña bajo un grupo contextual ausente)0: un duplicado, o nada en absoluto (una pestaña contextual sin banda)-5
ribbon: of_remove_tab, of_remove_group, of_remove_item, of_select_gallery_item en una dirección desconocida; of_open en un botón de acceso rápido0, sin efecto-5. of_open("pestaña/grupo") abre el panel de un grupo replegado
ribbon: un handle of_qat_item conservado tras of_remove_item de su botónseguía válido y designaba un botón desaparecidoliberado: IsValid() devuelve false
ribbon: teclas de acceso rápido — dos controles con la misma letra, uno de ellos oculto; un control de un grupo replegadoel oculto robaba la letra y no se ejecutaba nada; la letra de un grupo replegado no hacía nada; una tecla de dos letras no respondía nuncasolo responde un control visible y activo; la letra abre el panel del grupo replegado; "FP" se teclea letra a letra
ribbon: flechas del teclado sobre un botón dividido, un selector de color, un cuadro combinado o una galería atenuadosse detenían en ellos, sin poder hacer nadalos saltan; Abajo sobre un botón desplegable o dividido abre su menú

La receta: (1) ue_selection_changed y ue_minimized se lanzan también cuando su código llama a of_select_tab o asigna ib_minimized, como con un clic: si llamaba usted mismo a su tratamiento justo detrás, quite esa llamada, se ejecutaría dos veces; (2) compruebe el -5 de las adiciones si su construcción puede repetir una clave; (3) un is_app_button = "" que quería decir «File» se escribe ahora is_app_button = "File". Las retiradas bajo un control y el handle de una entrada del menú de aplicación están en la tabla 11.5.

11.17 toolbar: una regla de atajos, un único tooltip, rechazos que se dicen #

La segunda revisión de la barra de herramientas (toolbar) alinea sus atajos con los de la ventana y hace visible lo que se escribía sin efecto. No se retira ningún método ni cambia ninguna firma; aparecen dos códigos de retorno (-5).

Qué3.04.0
una herramienta con is_shortcut = "Delete" (una tecla sola) y un campo en la barraSupr en el campo disparaba la herramienta y no borraba nada; fuera de la barra, nadauna tecla sola nunca es un atajo: hace falta Ctrl o Alt, o de F1 a F24 — la regla de la ventana
una tecla de atajo mantenida (todos los componentes)la acción se repetía: un conmutador parpadeabauna acción por pulsación
of_register_shortcut(acorde, clave) heredado, en una toolbarno disparaba nada, y la tecla se perdíatoma la dirección de la herramienta o de la entrada ("main/save"), -5 si no; la forma de un argumento devuelve -5; of_clear_shortcuts también vacía is_shortcut
el atajo de un campo, de un selector de fecha, de una etiquetase tragaba la tecla sin hacer nadael campo recibe el cursor (Ctrl+F en una búsqueda), el selector abre su calendario; una etiqueta no admite ninguno
el tooltip dado al añadir (of_add_button(…, tooltip))etiquetas mostradas tal cual; dos burbujas a la vez si luego se ponía is_tooltipun único tooltip con tema, texto enriquecido, el atajo al final; is_tooltip lo sustituye y se relee
of_add_bar(MAIN_BAR) tras una primera herramienta en maindevolvía 0 sin hacer nada-5: para colocarla, añada main antes de cualquier herramienta
of_set_layout de un texto que no es JSONdevolvía 0-5
ue_layout_changedausente cuando añadir una barra desplazaba a otra; disparado al mostrar una barra ya visiblese dispara en el primer caso, ya no en el segundo
separadores, un desplegable o cascada cuyas entradas están todas ocultastrazos huérfanos; el desplegable y la cascada seguían activos y mudosningún trazo al principio, al final ni duplicado; se dibujan atenuados
un clic derecho en la barraningún evento, ue_rclicked incluidoue_item_rclicked(dirección) en una herramienta, ue_rclicked fuera de toda herramienta — nunca ambos
los colores de una entrada de menú (of_menu_item(…).il_back_color)escritos y releídos, nunca dibujadosdibujados en el menú
toolbar: ue_rclicked, ue_mouse_enter, ue_mouse_leavedocumentados, pero nunca lanzadoslanzados: un clic derecho en la barra fuera de toda herramienta, la entrada y la salida del ratón

La receta: (1) un atajo de herramienta sobre una tecla sola (salvo F1 a F24) lleva Ctrl o Alt; (2) en una toolbar, of_register_shortcut recibe la dirección de la herramienta o de la entrada; (3) para colocar la barra main, llame a of_add_bar(MAIN_BAR, banda, rango) antes de su primera herramienta.

11.18 statusbar: un asa que redimensiona, un mensaje que no sustituye el texto #

La segunda revisión de la barra de estado (statusbar) da al asa de redimensionamiento su verdadero papel y convierte cada clave vacía o desconocida en un rechazo. Ningún método se retira ni cambia de firma; of_flash_panel gana un código de retorno (-5).

Qué3.04.0
ib_show_resize_grip = true, luego arrastrar el asaun dibujo: nada se muevela ventana se redimensiona desde su esquina (inferior izquierda en RTL); el asa no se dibuja en una ventana maximizada o sin borde redimensionable
of_flash_panel sobre una clave que la barra nunca recibió, o sobre una dirección0, no se muestra nada-5
of_panel(k).is_text releído durante un of_flash_panelel mensajeel texto del panel (el mensaje pasa por encima)
of_panel(""), of_panel("a/b"): escritura y relecturaescribía en los paneles sin clave y en los separadoresno designa nada: no escribe en ninguna parte, se relee vacío
is_state fuera de las constantes STATE_* ("Error", "very bad")releído tal cual, sin color; un valor con un espacio provocaba un error de scriptse ignoran las mayúsculas ("Error" = error); cualquier otro valor equivale a « ningún estado » y se relee vacío
ii_progress = 150 y luego releído150 (dibujado al 100 %)100, lo que se dibuja
un panel desactivado que lleva un estadoconservaba el color del estado: parecía activoatenuado, marca de estado incluida
un panel retirado, vaciado (of_clear, of_clear_menu), desactivado u ocultado mientras su lista está abiertala lista seguía abierta, y una elección lanzaba ue_panel_menu_clickedla lista se cierra, no se lanza nada (lo mismo para una entrada que pasó a atenuada u oculta)
doble clic en un panel con lista desplegableue_panel_double_clicked además de la lista abiertasolo la lista
Flecha arriba / abajo en un panel con lista desplegable que tiene el focopasaba al panel vecinoabre la lista (las flechas Izquierda / Derecha siguen desplazando)
una lista desplegable hecha solo de separadoresflecha y lista vacíasin lista: el panel sigue siendo lo que dice ib_clickable

La receta: (1) establezca ib_show_resize_grip en una barra de estado situada en la parte inferior de una ventana redimensionable; (2) compruebe el retorno de of_flash_panel como el de los demás métodos con clave; (3) dé una clave a cada panel que quiera releer o modificar.

11.19 dockcontainer: un of_select_panel que encuentra el panel, ventanas flotantes que recuerdan #

La segunda revisión del contenedor de paneles (dockcontainer) da a of_select_panel un efecto sobre un panel replegado o flotante, y hace que la disposición recuerde las ventanas flotantes. Ningún método se retira ni cambia de firma.

Qué3.04.0
of_select_panel de un panel replegado, flotante u oculto0, no se ve nadareplegado: su panel deslizante se abre; flotante: su ventana pasa al frente; oculto: -5
of_float_panel del panel principal o de un panel oculto0, no pasa nada-5
of_move_panel que apila el panel PRINCIPAL0, y su vecino desaparece sin pestaña-5, nada se mueve
as_position desconocida (of_add_panel, of_move_panel)0, el panel se acopla abajo-5, el control no se toca
disposición (of_get_layout, ue_layout_changed, of_set_layout) y paneles FLOTANTESolvidados: un panel desacoplado volvía acoplado; mover su ventana no lanzaba nadaconservados con el lugar de su ventana, reabiertos al restaurar (devueltos a una pantalla); mover o redimensionar la ventana lanza ue_layout_changed
of_set_layout de una disposición sin panel principalel panel principal actual se quitase conserva
is_title de un panel añadido sin títulosu clave; un título dado después al panel principal no hacía aparecer su cabecera"" (la pestaña sigue mostrando la clave); la cabecera del principal sigue su título

La receta: (1) ue_panel_selected, ue_panel_floated y ue_panel_pinned se lanzan también tras of_select_panel, of_float_panel e ib_pinned, como con un gesto: si llamaba usted mismo a su tratamiento justo detrás, quite esa llamada, se ejecutaría dos veces; (2) compruebe el -5 de of_move_panel, of_float_panel y of_select_panel; (3) una disposición guardada antes de la 4.0 se restaura tal cual, sus paneles siguen acoplados.

11.20 tab: códigos de retorno honestos, un clic derecho que vuelve a la aplicación #

La segunda revisión de las pestañas (tab) hace que of_add_page y of_select_page digan lo que rechazan, anuncia la disposición cuando su código oculta una pestaña, y devuelve el clic derecho a la aplicación cuando el menú integrado está desactivado. Ningún método se retira ni cambia de firma; se añade un evento.

Qué3.04.0
of_add_page de un control ya alojado (por esta pestaña con otra clave, o por otro componente)0, y una pestaña sin nada detrás-5, no se añade nada
of_select_page de una pestaña rechazada cuando ninguna está activa (todas ocultas)0-5
Ocultar o volver a mostrar una pestaña desde su código (ib_visible)ningún ue_layout_changedue_layout_changed lanzado con la disposición entera, como para of_move_page: es el aviso de que la disposición que hay que guardar ha cambiado
Clic derecho en una pestaña con ib_context_menu = falsenadala pestaña se selecciona y luego se lanza ue_tab_rclicked(as_key) (nuevo): abra ahí su menú
Volver a la pestaña actual mientras ue_selection_changing espera su respuestauna respuesta «sí» activaba igualmente la otra pestañala pregunta se anula: gana el último gesto del usuario
Una pestaña desactivada u oculta mientras ue_tab_closing espera su respuestase cerraba igualmentepermanece abierta
Cerrar con el teclado (Supr) la pestaña que tiene el focoel foco salía de la barra, las flechas ya no respondíanel foco pasa a la pestaña que se ha vuelto activa

La receta: (1) compruebe el -5 de of_add_page (una página se aloja una sola vez) y de of_select_page; (2) si guarda la disposición en ue_layout_changed, nada que hacer — ahora sigue también sus ib_visible; (3) donde ib_context_menu = false dejaba el clic derecho sin respuesta, programe ue_tab_rclicked.

11.21 listbar: una entrada oculta nunca seleccionada, una disposición comprobada #

La segunda revisión de la barra de navegación (listbar) hace que of_select_item rechace una entrada oculta y of_set_layout un texto que no es una disposición, y añade una insignia de contador, las teclas Izquierda / Derecha y el clic derecho en una entrada. Ningún método se retira ni cambia de firma.

Qué3.04.0
of_select_item de una entrada oculta (ib_visible = false)0, una selección invisible-5, la selección no se mueve; ocultar la entrada ya seleccionada la mantiene seleccionada
of_set_layout de un texto que no es un objeto JSON (archivo truncado)0, no se aplica nada-5, no se envía nada
Sección plegada en una disposición restaurada, añadida más tardenace plegadanace desplegada: el plegado solo vale para una sección presente
Sección con título vacíosus entradas pegadas a las de arriba; plegable, sin nada para volver a abrirlaun espacio (una línea fina en el riel) la separa; nunca se pliega
Nuevo: is_badge (entrada), ue_item_rclicked(as_keys), Izquierda / Derecha y salto por letra—una insignia de contador, el clic derecho en una entrada (un solo evento, la entrada no se selecciona), el plegado con el teclado

La receta: (1) ue_selection_changed se lanza también tras un of_select_item de su código (abrir la página de inicio al arrancar, por ejemplo), como con un clic: si abría usted mismo la página justo detrás, déjeselo al evento, si no se abriría dos veces; (2) compruebe el -5 de of_select_item si oculta entradas, y el de of_set_layout si la disposición viene de un archivo; (3) una sección sin título ya no se pliega: dele un título si debe plegarse.

11.22 tilesbox: un título que ya no crea grupos, la reorganización desde el teclado #

La segunda revisión del panel de mosaicos (tilesbox) impide que el título de un grupo cree ese grupo, hace que of_add_live_item rechace un texto vacío, da una sola parada de tabulación por grupo y añade la reorganización desde el teclado. Ningún método se retira ni cambia de firma. il_badge_color sigue ahora la regla de todos los colores (vea la fila picture, button, tilesbox más arriba).

Qué3.04.0
of_group(clave).is_title sobre un grupo nunca añadidocreaba un grupo visible que no se podía ni llenar ni quitar (salvo con of_clear)no escribe nada: solo of_add_group crea un grupo; una clave vacía, o con / o ``, da un handle inerte
of_add_live_item con un texto vacío0, y el texto fijo is_live_text se borraba-5, nada cambia
of_tile(dirección).of_count()0el número de caras puestas por of_add_live_item
Reorganizar (ib_reorderable = true)solo con el ratóntambién desde el teclado: Ctrl+Izquierda/Derecha en el grupo (sentido de lectura), Ctrl+Arriba/Abajo hacia el grupo vecino; mismos ue_tile_moved y ue_layout_changed
Tecla Tabse detenía en cada mosaico; una flecha hacia un borde sin vecino saltaba al mosaico anterior o siguiente del documentouna parada por grupo (el último mosaico con foco), las flechas recorren los mosaicos; en el borde, el foco se queda
Mosaico desactivado u oculto mientras se arrastramovido al soltar, ue_tile_moved disparadoel arrastre se abandona, nada se mueve
ib_collapsed de un grupo asignado por su códigoningún eventoue_group_toggled, como un clic en el encabezado (nada cuando el grupo ya está en ese estado)

La receta: (1) cree un grupo con of_add_group antes de cambiar su título; (2) compruebe el -5 de of_add_live_item si el texto de una cara puede estar vacío; (3) lo que hacía en ue_tile_moved vale ahora también para un movimiento desde el teclado.

11.23 stepbar: «todo terminado» anclado en el último paso, pasos retirados que ya no dejan nada #

La segunda revisión de la barra de pasos (stepbar) hace que «todo terminado» sea coherente con la regla del paso en curso (una identidad, no un rango), hace que un paso retirado se lleve lo que le pertenecía y corrige cuatro defectos de visualización. Ninguna firma cambia.

Qué3.04.0
of_add_step mientras la barra está en «todo terminado»el paso añadido aparecía terminado (marca); ii_current pasaba a n + 2 sin eventoañadido después del último paso de entonces, pasa a ser el paso en curso y se lanza ue_step_changed; insertado antes, nada cambia
of_step(clave).is_state sobre una clave que no nombra ningún pasoguardado y aplicado después al paso añadido con ese nombreignorado; un paso añadido nace con su estado calculado
Colores e información sobre herramientas de un paso retirado (of_remove_step, of_clear_steps)volvían en el siguiente paso añadido con la misma clavese van con el paso
Barra compactada (OVERFLOW_AUTO) cuyo paso en curso está forzado a errorninguna etiqueta; un paso forzado a STATE_CURRENT ganaba la suyala etiqueta se queda en el paso en curso (el rango de ii_current), sea cual sea su estado
OVERFLOW_SHRINKetiquetas en varias líneas, palabras largas cortadas sin «…»una línea por etiqueta, terminada en «…»
POSITION_BOTTOM con una segunda línea (is_description)encima de la etiqueta, pegada a ellabajo la etiqueta, encima del círculo
Pasar el ratón sobre un paso desactivado o fuera de alcance (il_back_color_hover, il_text_color_hover)el color al pasar se encendíanada se enciende: el paso no responderá al clic

La receta: si su código añade un paso tras poner «todo terminado» (ii_current = of_count() + 1) y quiere que la barra siga así, vuelva a poner ii_current = of_count() + 1 después del añadido. Si reconstruye la barra con las mismas claves, vuelva a poner los colores e informaciones sobre herramientas deseados: ya no sobreviven a la retirada.

11.24 progressbar: una barra que cabe en su control, una etiqueta que sigue el idioma #

La segunda revisión de la barra de progreso (progressbar) hace que quepa donde estaba una HProgressBar, solo envía al componente los valores que cambian el dibujo, escribe el porcentaje en el idioma de visualización y añade is_label_format (una etiqueta propia) e is_state (pausa, error). Ninguna firma cambia.

Qué3.04.0
Barra lineal en un control bajo o anchomargen de 12 px, 640 px de ancho como máximo: por debajo de 24 px de alto aparecía una barra de desplazamiento y la barra quedaba cortadamargen de 2 px, todo el ancho; la pista (14 px) y la etiqueta se reducen con la altura
Etiqueta del porcentaje (ib_label)«50%» en todos los idiomasen el idioma de visualización: «50 %» en francés
of_set_property("value", "12,5"), o un texto que no es un númeroenviado tal cual: la orden se perdía sin decir nada; un minimum no válido bloqueaba la escala hasta el siguiente of_reset«12,5» se lee 12.5; un texto que no es un número (ni true/false para un booleano) se ignora
id_value releídoel valor que el componente había recibido; cada asignación era un viaje de ida y vuelta con élel último valor asignado por la aplicación; el componente solo recibe los que cambian el dibujo (una décima de punto porcentual)
of_reset() sobre una barra llenala barra bajaba a cero deslizándosevuelve a cero de golpe

La receta: (1) si calculaba un porcentaje a mano, asigne id_maximum y el valor bruto, en cada fila si lo desea; (2) si una prueba automática leía la etiqueta, espere el formato del idioma de visualización; (3) para mostrar una pausa o un error, prefiera is_state a un color elegido con il_color.

11.25 picture: una asignación relee el fichero, un fallo dice su motivo #

La segunda revisión de la imagen (picture) le hace releer el disco en cada asignación, como el Picture nativo, da a ue_error un segundo argumento que dice por qué falta la imagen, rechaza una dirección http:// en lugar de fallar sin motivo y solo lanza un ue_clicked en un doble clic. ue_error es la única firma que cambia.

Qué3.04.0
picture: doble clic en la imagendos ue_clicked y luego ue_double_clickedun solo ue_clicked y luego ue_double_clicked — como el Picture nativo
picture: ue_errorue_error (string as_message): solo el mensajeue_error (string as_message, string as_reason): as_reason es una de las constantes REASON_* (no encontrado, demasiado grande, http rechazado, formato no mostrado, otro). Su script del evento recibe el argumento por sí solo; una llamada event ue_error(…) escrita en su código pasa ahora dos
picture: is_source = "http://…"intentado en https por el motor; en un servidor sin TLS, un fallo sin motivorechazado de entrada: glifo de error y ue_error con REASON_INSECURE. Descargue antes la imagen (n_pbt_restclient.of_download) y muestre el fichero
picture: la misma ruta asignada de nuevo tras reescribir el fichero; mono: o tint: en is_source; una imagen .avifla imagen anterior; el glifo de error; no encontradael fichero releído, como el Picture nativo; el glifo recoloreado por el tema; mostrada
picture: imagen ampliada más pequeña que su marco (bandas); rueda horizontal, panel táctil; botón derecho mantenidosalía del marco al arrastrarla; un paso de zoom por evento, alejamiento en un desplazamiento horizontal; la imagen se movíase queda donde la colocan is_align e is_valign; zoom proporcional al gesto, nada en un desplazamiento horizontal; solo el botón izquierdo desplaza

La receta: (1) si un script abría una ficha en ue_clicked y otra acción en ue_double_clicked, nada que hacer — el doble clic ya no vuelve a abrir la ficha; (2) sustituya cualquier análisis del texto de as_message por una prueba de as_reason; (3) una imagen de un servidor de intranet en http se descarga primero (n_pbt_restclient.of_download en una carpeta temporal) y luego se muestra por su ruta; (4) si añadía un ?v= a la ruta para forzar la relectura de una imagen reescrita, quítelo: volver a asignar basta.

11.26 video: subtítulos y formatos que se reproducen, un fallo que dice su motivo #

La segunda revisión del reproductor (video) da a ue_failed un segundo argumento que dice por qué una película no se reproduce, rechaza una dirección http://, reproduce .mkv y .mov, carga los subtítulos dados por URL, y pone la película en pausa cuando el componente se oculta. ue_failed es la única firma que cambia.

Qué3.04.0
video: ue_failedue_failed (string as_message)ue_failed (string as_message, string as_reason) — as_reason es una constante REASON_*
video: una fuente http://fallaba como « no se encuentra »rechazada enseguida, REASON_INSECURE; solo https se reproduce
video: un .mkv, un .mov.mkv « no se encuentra », .mov rechazado por su nombreservidos y reproducidos cuando el motor los decodifica; .avi, .wmv, .flv siguen rechazados (REASON_FORMAT)
video: un subtítulo dado por URLnunca se mostraba, sin decir nadadescargado por el componente (el servidor debe permitir CORS); un rechazo lanza ue_subtitles_failed
video: of_add_subtitles dos veces para el mismo idiomareemplazaba la pista en silencio, 0-5 (también para un idioma con / o `); of_remove_subtitles` antes
video: el componente oculto durante la reproducciónla película seguía, con sonidoen pausa, ue_paused, y espera of_play (ib_pause_when_hidden, verdadero por defecto)
video: arrastrar el volumen en la barraun ue_volume_changed por píxeluno solo, al soltar
video: of_capture hacia un .jpgun PNG con un nombre .jpgun JPEG; la sobrecarga of_capture(as_path, al_max_width) reduce la imagen
video: of_get_last_error tras un fallo de of_captureel error anterior de la bibliotecael motivo de ESTE fallo (carpeta ausente, ruta vacía…)
video: Escape en pantalla completa, ib_enabled = falsesin efecto (solo Alt+F4 salía)sale de la pantalla completa

La receta: (1) añada as_reason a su script de ue_failed y compruébelo en lugar del texto del mensaje; (2) una película o un subtítulo de un servidor de intranet en http se descarga primero (n_pbt_restclient.of_download hacia una carpeta temporal), luego se reproduce por su ruta; (3) ue_fullscreen_changed, ue_pip_changed, ue_source_changed y ue_chapter_changed se lanzan también tras sus propias llamadas (of_fullscreen, of_pip, of_next, of_seek…), como con un gesto: si su código llamaba él mismo a su tratamiento justo detrás, quite esa llamada, se ejecutaría dos veces; (4) un muro de pantallas que debe reproducirse oculto pone ib_pause_when_hidden = false; (5) para reemplazar la pista de un idioma, of_remove_subtitles y luego of_add_subtitles.

11.27 pdfviewer: of_refresh dice lo que hace, nada se descarga sin que lo sepa #

La segunda revisión del visor (pdfviewer) da un código de retorno a of_refresh — y, para que el mismo nombre tenga el mismo sentido, también a los de webbrowser y shellexplorer —, informa de todo enlace del documento y rechaza lo que nunca se mostrará en lugar de dejar esperando. Ninguna firma de evento cambia.

Qué3.04.0
pdfviewer · webbrowser · shellexplorer: of_refreshsubroutinelong: 0 una vez solicitado, -4 sin documento o página (pdfviewer, webbrowser), -2 si el componente no está creado
pdfviewer: of_refresh tras un rechazo (http://…)no hacía nada, sin eventoel rechazo se repite: ue_load_failed
pdfviewer: una dirección data: de más de 2 MB de caracteresnunca mostrada, ningún eventoue_load_failed con REASON_TOO_LARGE, de inmediato
pdfviewer: un PDF remoto enviado «como descarga»ue_load_failed, pero el fichero acababa en Descargasue_load_failed con REASON_REFUSED, no se descarga nada
pdfviewer: ue_link_clicked en un enlace mailto:, file: o relativonunca lanzado (solo http y https); un enlace relativo llegaba como dirección internalanzado para todo enlace; as_url es un mailto:… tal cual, o una ruta de disco para un fichero local
pdfviewer: of_print_to_pdfescribía la página alrededor del lector, no el documento-4, no se escribe nada: copie el fichero de is_source
pdfviewer: file://localhost/C:/…, file:////servidor/recurso/…una ruta errónea, no encontradaC:\… y \\servidor\recurso\…
pdfviewer: el foco dado al componente (Tab, of_focus_webview)se quedaba en la página: las teclas no desplazaban el documentopasa al documento: AvPág, flechas, Inicio / Fin lo desplazan

La receta: (1) una llamada uo_pdf.of_refresh() compila tal cual; compruebe su retorno si quiere saber que no había nada que volver a leer; (2) un documento de más de 1,5 MB en memoria se escribe en un fichero temporal y luego se muestra por su ruta; (3) en ue_link_clicked, espere también un mailto: y una ruta de disco, no solo una dirección web; (4) para copiar el documento mostrado, copie el fichero de is_source en lugar de of_print_to_pdf.

11.28 codeeditor: una búsqueda que se ve, un «ir a» que mueve el cursor, reemplazar #

La segunda revisión del editor de código (codeeditor) lleva a la pantalla lo que encuentra la búsqueda, conserva el cursor del usuario durante una búsqueda, renombra ii_doc_line y añade lo que se espera de un editor de scripts: reemplazar, dirigir el cursor, saber si hay que guardar, mostrar un error en el margen. Ninguna firma de evento cambia.

Qué3.04.0
codeeditor: ii_doc_lineun long con el prefijo de integeril_doc_line: renómbrelo; una línea más allá del final ya no marca nada (se relee tal como se escribió)
codeeditor: of_find con ib_search_enabled = false0, sin buscar nada-4
codeeditor: of_find("")relanzaba la búsqueda anteriorvacía el campo y borra los resaltados, sin ue_find_result
codeeditor: of_find, Intro en la barrala coincidencia quedaba a menudo fuera de la vista; el cursor iba a ellala coincidencia se lleva a la pantalla; la búsqueda parte del cursor, que solo se mueve al cerrar la barra (Esc)
codeeditor: of_insert_text con la barra de búsqueda abiertareemplazaba la coincidencia encontrada, fuera de la vista, y vaciaba el historial de Ctrl+Zinserta en el cursor del usuario, llevado a la pantalla; Ctrl+Z lo deshace
codeeditor: un is_text nuevoconservaba el desplazamiento del documento anterior; un texto solo con CR se releía en LFse muestra desde su primera línea y borra los marcadores; solo CR se relee en CR (una mezcla en CRLF)
codeeditor: ib_current_line con ib_wrapninguna bandala banda cubre toda la línea del cursor
codeeditor: novedades—reemplazar (of_replace, of_replace_all, Ctrl+H) y opciones de búsqueda (ib_find_match_case, ib_find_whole_word, ib_find_regex, F3); cursor y selección (il_caret_line, il_caret_column, of_select_range, of_selected_text, of_line_count); ib_modified; marcadores en el margen (of_add_marker, of_remove_marker, of_clear_markers, of_marker_count)

La receta: (1) sustituya ii_doc_line por il_doc_line; (2) compruebe el -4 de of_find si la búsqueda puede estar desactivada; (3) para «ir a la línea» de un error moviendo el cursor, asigne il_caret_line (y of_add_marker para mostrarlo) — il_doc_line solo marca; (4) si seguía ue_caret_changed para saber dónde se insertó un fragmento, lea il_caret_line tras of_insert_text; (5) un botón Guardar puede seguir ib_modified, que vuelve a poner en false tras guardar.

11.29 jsontree y xmltree: el teclado se queda en el árbol, una búsqueda que ya no mueve la selección #

La segunda revisión del árbol JSON (jsontree) trató el motor que comparte con el árbol XML (xmltree): lo que sigue vale para ambos, salvo indicación. Ninguna firma cambia; el árbol JSON gana of_expand_path, of_collapse_path, of_is_expanded, of_copy y el evento ue_node_toggled, lanzado por un gesto del usuario como por of_expand_path y of_collapse_path.

Qué3.04.0
jsontree, xmltree: Intro sobre una hojapasada a la ventana: su botón por defecto se disparabala conserva el árbol, lanza ue_node_clicked como un clic; sin selección, nada
jsontree, xmltree: Esc con el cuadro de búsqueda abiertose disparaba el botón Cancelar de la ventanacierra primero el cuadro; con el cuadro cerrado, Esc vuelve a la ventana
jsontree, xmltree: líneas de cierre (}, ], </x>)alcanzadas por las flechas (ue_selection_changed de un bloque ya anunciado); un clic devolvía la vista a la aperturasaltadas por el teclado; un clic selecciona el bloque sin mover la vista
jsontree, xmltree: flecha derecha sobre una hojabajaba una líneano hace nada, como en un árbol
jsontree, xmltree: una búsqueda durante una selecciónof_search_next o Esc podían plegar la línea elegida y mover la selección sin eventola línea seleccionada sigue visible y seleccionada: of_selected_path no cambia
jsontree: el mensaje de ue_errormitad traducido, mitad inglés («JSON no válido : Unexpected end of JSON (line 1, column 6)»)enteramente en el idioma de visualización, línea y columna incluidas: no compare su texto
jsontree, xmltree: un documento de más de 1.500.000 líneasmostrado, pero su final inalcanzable, sin decir nadarechazado: un mensaje en el árbol y ue_error
jsontree: Ctrl+C en el árbolno copiaba nada, y seguía como atajo de la ventanacopia la selección (como of_copy); sin selección, el atajo sigue siendo de la ventana

La receta: (1) si una ventana contaba con Intro en el árbol para disparar su botón por defecto, añada ese paso en ue_node_clicked; (2) no busque más una clave vacía en ue_selection_changed (una línea de cierre ya no se selecciona); (3) no analice el texto de ue_error: sigue el idioma; (4) para restablecer los pliegues de un usuario, lea of_is_expanded y vuelva a ponerlos con of_expand_path / of_collapse_path.

11.30 xmltree: cada línea tiene su XPath, cualquier XPath selecciona #

La segunda revisión del árbol XML (xmltree) retoma todo lo que la sección anterior dice del motor compartido. Añade lo propio del XML: una ruta que designa SIEMPRE el nodo de la línea, legible tal cual por n_pbt_xml. Ninguna firma cambia; el árbol XML gana of_selected_xml, of_copy, of_expand_path, of_collapse_path, of_is_expanded y el evento ue_node_toggled.

Qué3.04.0
xmltree: ruta de una línea de texto, de comentario o de instrucción de procesamientola de su elemento (mientras of_selected_value daba su propio texto); "" antes de la raízla suya: /r/text()[2], /r/comment()[1], /r/processing-instruction('x')[1], /comment()[1] — n_pbt_xml.of_get_value lee allí el mismo valor
xmltree: elemento cuyo prefijo se redeclara con otro URI, o con un hermano del mismo nombre en otro espacio de nombresuna ruta que no encontraba nada, u OTRO nodo*[local-name()='x' and namespace-uri()='urn:…'], que designa ese nodo exactamente
xmltree : of_select_pathsolo la forma exacta que escribe el árbol, si no -5cualquier XPath (//line[@sku='A'], /r/a[1]…): se selecciona el primer nodo encontrado, of_selected_path da luego la ruta del árbol
xmltree: el mensaje de ue_error« XML no válido : error on line 1 at column 11: … »; el árbol quedaba vacío« XML no válido : línea 1, columna 11 (…) », en el idioma de visualización; el árbol muestra el origen, con la línea errónea marcada
xmltree: <?xml-stylesheet?> sin declaración XMLmostrado dos vecesuna sola línea
n_pbt_xml: un XPath con @xml:langrechazado (prefijo xml desconocido), valor vacíoleído: el prefijo xml está ligado de oficio, como exige la norma
xmltree: Flecha derecha en una etiqueta con atributoslos atributos solo se alcanzaban con el ratónrecorre los atributos uno a uno (Flecha izquierda vuelve), un ue_selection_changed por paso, luego baja
xmltree: Ctrl+C, plegar por rutanada; Ctrl+C iba a la ventana como atajoof_selected_xml, of_copy y Ctrl+C (el XML de la selección), of_expand_path, of_collapse_path, of_is_expanded (cualquier XPath), ue_node_toggled (un gesto, o of_expand_path / of_collapse_path)

La receta: (1) si subía de una línea de texto o de comentario a su elemento con of_selected_path, tome el padre de la ruta (lo que precede a la última /); (2) no analice el texto de ue_error: sigue el idioma; (3) una ruta guardada en 3.0 bajo espacios de nombres mezclados se recupera pasándola a of_select_path, que ahora acepta cualquier XPath, y releyendo después of_selected_path.

11.31 xml: rechazos que se dicen, espacios de nombres que se mantienen #

La segunda revisión de n_pbt_xml no cambia ninguna firma. Hace que of_remove siga los códigos de la biblioteca, rechaza una lectura mientras un documento construido tenga un elemento abierto, y hace que los espacios de nombres se mantengan: lo que un mutador escribe se relee en el espacio correcto, o se rechaza diciéndolo.

Qué3.04.0
xml: of_remove(""), of_remove sin documento cargado, página que no responde0, como «nada quitado»-5; -4; -2 — el recuento (>= 0) solo cuando se intentó quitar
xml: una lectura (of_exists, of_count, of_get_value, of_is_valid…) o un cambio mientras un elemento construido sigue abiertoel documento se cargaba tal cual, y el resto de la construcción empezaba un NUEVO documento: lo anterior se perdía sin errorrechazada: -4, vacío o false, e is_last_error = «the document is still being built : close its elements first»; no se pierde nada (of_xml y of_pretty siguen disponibles)
xml: of_add_xml bajo un elemento con espacio de nombres por defecto, o con el prefijo del destino (<s:Item/> bajo s:Body)el fragmento quedaba fuera del espacio de nombres (xmlns=''), invisible para el XPath que había servido para añadirlo; el prefijo del destino se rechazaba (-4)el fragmento hereda los espacios de nombres vigentes en su destino, como of_add_child
xml: of_set_attr / of_add_child con un nombre con prefijo (xsi:type, p:item)0, un atributo fuera del espacio de nombres que el XPath no encontraba; con un prefijo no declarado, un documento que ya no se recargabaen el espacio de nombres del prefijo (declarado en el nodo, o ligado con of_register_namespace); -4 y «undeclared prefix : xsi» si no está ligado en ninguna parte
xml: of_pretty tras un of_add_child bajo un padre con prefijo (s:Body)<Item> sin prefijo: releído, fuera del espacio de nombres<s:Item>, como en of_xml
xml: of_element_attr dos veces con el mismo nombre; un nombre :x, x: o a:b:cdos atributos (documento mal formado); nombre aceptado (un documento que no se carga)un solo atributo, con el segundo valor; nombre rechazado (is_last_error), el elemento se omite
xml: of_transformaplica una hoja XSLT al documento cargadoretirado: XSLT ya no existe en el motor (Chromium lo retira); transforme en el servidor o en PowerScript

La receta: (1) un of_remove comprobado con = 0 (nada quitado) sigue funcionando; compruebe < 0 (nada pudo intentarse); (2) si leía un documento MIENTRAS lo construía (un of_exists para controlar, un of_count para numerar), cierre primero sus elementos, o lleve la cuenta usted mismo; (3) un fragmento de of_add_xml ya no tiene que redeclarar el espacio de nombres de su destino: el que escribía xmlns='' para salir de él todavía puede; (4) compruebe el retorno de of_set_attr / of_add_child con un nombre con prefijo, y declare el prefijo (o lígelo con of_register_namespace).

11.32 json: un array que se construye rápido, números que conservan sus cifras, un texto vacío que se dice vacío #

La segunda revisión de n_pbt_json no quita ni cambia ninguna firma. Añade las sobrecargas decimal y longlong de of_set_number y of_add_number, y los lectores of_get_decimal y of_get_longlong. Construir un array con of_add_* ya no recorre todo el array en cada añadido: 2.000 filas se construyen en una fracción de segundo en lugar de varios minutos. Dos reglas quedan ahora escritas en la documentación, sin cambiar: una cadena nula se escribe "" (para un null JSON, of_set_raw(path, "null")), y una clave escrita dos veces se lee en su PRIMERA aparición.

Qué3.04.0
json: of_load de un texto hecho de blancos (salto de línea, tabulación)-4, como un texto mal formado-5, como un texto vacío
json: of_load de un texto precedido de un BOM (archivo UTF-8 con BOM)-40, el BOM se ignora
json: of_load de un documento anidado en más de 512 niveles0 — y un texto muy profundo podía detener la aplicación-4, la aplicación sigue viva
json: of_set_number / of_add_number de un decimal (o de un literal como 690.50)convertido a double: unas quince cifras, un céntimo podía perdersesobrecarga decimal: todas las cifras, ceros finales quitados (690.5); un longlong también tiene la suya
json: of_get_number de un exponente con ceros iniciales (1E-0000005)0, o un valor enormeel valor correcto (0.00001)
todos los componentes: \u seguido de cuatro caracteres que no son hexadecimales, en una cadena leídalos cuatro caracteres desaparecíanse conservan tal cual, como un escape desconocido

La receta: (1) si comprobaba of_load(...) = -4 para reconocer un archivo vacío, compruebe < 0; (2) un importe decimal pasado a of_set_number se escribe ahora con todas sus cifras, sin cambiar nada en su código; (3) un identificador de más de 15 cifras se relee con of_get_longlong, un importe con of_get_decimal, ya no con of_get_number.

11.33 crosstab: of_from_datastore, rechazos que se dicen, el valor mostrado al doble clic #

La segunda revisión del crosstab renombra of_set_data a of_from_datastore, el nombre del datagrid y del scheduler, que leen un DataStore del mismo modo (mismos argumentos, mismos códigos). Toda adición, filtro o formato que nombra un campo desconocido devuelve ahora -5 en lugar de 0. La tabla solo dibuja las columnas visibles: un código de cliente o una fecha diaria puestos en Columnas ya no bloquean la pantalla. Novedades: is_thousands, CF_ICONS, las constantes VALUEFILTER_* y DATE_*.

Qué3.04.0
crosstab: alimentar desde un DataStoreof_set_data(ds)of_from_datastore(ds), mismos códigos
crosstab: un campo desconocido (errata) pasado a una adición, un filtro, un formato, un orden, una agrupación de fechas0, no pasa nada-5
crosstab: un tipo de filtro, una agregación, una parte de fecha fuera de la lista; una medida calculada en Filas; of_set_value_filter en una posición sin medida0; la posición se deslizaba a la última medida-5
crosstab: of_set_layout de un texto que no es JSON; of_remove_calc_field / of_remove_calc_measure de un nombre desconocido0-5
crosstab: ad_value de ue_cell_double_clickedel agregado bruto (400 bajo « 80,0 % »), 0 para una celda vacíael valor mostrado (0.8), NULL para una celda vacía; un miembro vacío vale null en las tuplas
crosstab: el mismo campo en Filas (o Columnas, Filtros) Y en Valoresdependía del orden de las llamadas: el valor desaparecía; Quitar en una dimensión quitaba todopermitido en todas partes; añadir o mover una dimensión conserva los valores, Quitar solo quita el chip señalado
crosstab: un miembro vacío (NULL, texto vacío); un texto con tabulación o salto de línea en el DataStore« null » o una fila sin etiqueta; filas fantasma, columnas desplazadasun solo miembro (vacío), al final; el texto se queda en su fila
crosstab: is_label tras un nuevo of_from_datastore; is_label = ""perdido; un chip sin textoconservado; "" restablece el encabezado del DataWindow
crosstab: Ctrl+C en modo demoue_copy lanzado, portapapeles escritorechazado como una exportación, la cuadrícula lo indica
crosstab: of_collapse_all; filtro de miembros de la cuadrícula; of_export_xlsx más allá de 16 384 columnas; exportaciones en VALUES_ROWSsolo filas; aplicado en cada casilla; un archivo ilegible; las medidas una al lado de otrafilas y columnas; aplicado con OK (10 000 miembros listados como máximo); rechazado, ue_xlsx_saved dice por qué; como en pantalla

La receta: (1) sustituya of_set_data por of_from_datastore; (2) si ignoraba el código devuelto por of_add_*_field o por un filtro, compruebe < 0 — una errata por fin se ve; (3) en ue_cell_double_clicked, compruebe IsNull(ad_value) antes de calcular, y lea ad_value como el valor mostrado (una parte, no una suma, en modo « % »).

11.34 Base común: of_count y of_keys_at cuentan en long #

of_count devolvía un integer y of_keys_at tomaba una posición integer — en todos los componentes, en sus handles y en los objetos no visuales que los llevan (commandpalette, messagebox, speechout, toaster). Más allá de 32 767 elementos el recuento se desbordaba: un calendario (scheduler) alimentado por un DataStore de 40 000 filas ya no se contaba, y sus últimas filas no se recorrían. Las cuatro firmas son ahora long: long of_count ( ), long of_count ( string as_keys ), string of_keys_at ( long al_index ), string of_keys_at ( string as_keys, long al_index ).

La receta: una llamada no cambia. Una variable integer que recibe of_count() sigue siendo correcta hasta 32 767: declárela long. Un descendiente que sobrescribía of_count o of_keys_at adopta la nueva firma — el compilador le muestra la línea.

11.35 shellexplorer: un refresco que conserva el estado, cada fila para sí #

La revisión del explorador del shell conserva sus eventos: of_select, of_expand y of_collapse los lanzan como un clic, como en la 3.0. of_refresh e ib_show_files ya no cierran el árbol. Novedades: is_file_filter (los archivos mostrados), ib_show_hidden (los elementos ocultos, por defecto el ajuste del Explorador), ib_enabled y of_refresh(ruta), que relee una sola rama.

Qué3.04.0
shellexplorer: of_refresh(), o ib_show_files cambiadoel árbol se cerraba, la selección desaparecía sin eventolas ramas abiertas y la selección vuelven, encontradas por su ruta; una selección que ya no existe dispara ue_selected("", "")
shellexplorer: of_expand, of_select, of_collapse de una ruta vacía0-5
shellexplorer: of_expand de un archivo o de una carpeta sin hijosnadaue_path_not_found(…, "expand", "not a branch")
shellexplorer: of_keys_at(ruta, i)ruta/hijo, que nada sabía releerla ruta del hijo, completa: se reinyecta en of_has, of_select, of_expand
shellexplorer: una misma carpeta en dos niveles (la Música del Escritorio y la de la carpeta del usuario)un clic, un chevron o un doble clic en una actuaba sobre la otracada fila responde por sí misma
shellexplorer: archivos y carpetas ocultosnunca mostradosmostrados según el ajuste del Explorador del puesto, o ib_show_hidden
shellexplorer: una rama en un recurso que no responde«…» para siempre, aun cerrada y reabiertaue_error «… : timeout» a los 30 segundos; la rama se vuelve a pedir al reabrirse

La receta: (1) ue_selected y ue_expanded se lanzan también tras un of_select o un of_expand de su código, una vez alcanzada la carpeta (una ruta aún por leer llega un poco más tarde): haga su trabajo en el evento, no justo detrás de la llamada, o relea of_selected_key() una vez llegada la selección; (2) en ue_selected, trate as_path = "" (la selección ha desaparecido); (3) compruebe -5 en una ruta vacía; (4) ponga ib_show_hidden = false si sus usuarios nunca deben ver los elementos ocultos, diga lo que diga su Explorador.

11.36 commandpalette: cada objeto solo toca su paleta, un cierre que siempre se anuncia, el idioma de la aplicación #

Solo hay una paleta en pantalla a la vez: cuando un segundo objeto paleta abre la suya, sustituye a la primera. Un objeto ya solo responde de su paleta y de su atajo. ue_opened y ue_closed se siguen disparando en of_open / of_close: dicen el ciclo de vida de la ventana, no un gesto (misma regla que los reproductores de audio y vídeo). Novedades: of_insert_command (un comando en una posición elegida), of_anchor_under (la paleta bajo un control, en píxeles de pantalla), y en el handle is_group, is_hint, is_keywords, is_icon.

Qué3.04.0
commandpalette: ue_closedsin argumento; nada en absoluto cuando la paleta moría antes de aparecer (cerrada o sustituida enseguida, ventana rechazada)ue_closed(string as_reason) sigue a cada of_open que devolvió 0: "", cancelled, failed o blocked
commandpalette: of_is_open, of_close, of_reset, destruir un objeto cuya paleta fue sustituida por la de otrorespondían VERDADERO por la paleta del otro, y la cerrabansolo responden de su paleta: FALSO, y no se cierra nada
commandpalette: destruir (o restablecer) un objeto cuyo atajo ha retomado otro objeto paleta de la misma ventanaquitaba el atajo del otro: la tecla ya no respondía en ningún sitioel atajo del otro se queda
commandpalette: of_register_shortcut de una tecla que el gancho no nombra (ctrl+ù, win+k, space sin modificador)0 («puesto»), y la tecla nunca hacía nada-5; se conserva el atajo anterior
commandpalette: of_register_shortcut con is_shortcut vacío y ningún atajo puesto02
commandpalette: of_add_command de una clave que contiene una coma0 — y is_recent la releía como dos comandos-5
commandpalette: un grupo declarado en varias veces (File, Edit, luego File)dos encabezados «File»uno solo, en el lugar de su primera aparición; se conserva el orden de los comandos en el grupo
commandpalette: la búsqueda y los acentospreferences no encontraba «Préférences»los acentos no cuentan
commandpalette: el idiomala paleta hablaba inglés dijera lo que dijera PBT_SetLanguageel idioma de la aplicación; un is_placeholder puesto por usted no se traduce
commandpalette: el atajo mostrado en una fila, teclado AZERTY; AltGr en la búsquedaCtrl+A se leía Ctrl+Q; escribir € (AltGr+E) lanzaba el comando mostrado como Ctrl+Alt+Ela tecla se lee como la nombra la DLL; un carácter escrito nunca es un atajo
commandpalette: un atajo puesto sin ipo_owner (toda la aplicación) antes del atajo de una ventana, en la misma teclaganaba también en esa ventanael atajo de la ventana va primero
commandpalette: POSITION_ABSOLUTEun comando de clave x o y llevaba la paleta al borde de la pantalla; con dos pantallas iba a la de la ventanail_x / il_y se respetan, en la pantalla del punto pedido
commandpalette: inv_pumpvariable interna que quedó públicaprotegida: no forma parte de la API, nada que leer ni escribir
commandpalette: un comando cuyo texto cita __licensela paleta no se abría (-5)se abre: solo una palabra reservada escrita como clave sigue rechazada

La receta: (1) si su código dispara él mismo ue_closed(), pásele un motivo (""); un script que solo lo recibe compila tal cual; (2) si esperaba ue_opened tras of_open, trate también ue_closed("cancelled"), "failed", "blocked"; (3) compruebe 2 y -5 en el retorno de of_register_shortcut; (4) renombre una clave de comando que contenga una coma.

11.37 radialmenu: una clave sola que apunta bien, una rueda abierta que sigue a la aplicación, una etiqueta que se lee #

La rueda se dibuja una vez, y la aplicación sigue funcionando mientras está en pantalla: lo que cambie entretanto ahora cuenta. El cubo ya no deletrea nada (no lo hacía desde la 3.0, dijera lo que dijera la documentación): es la rama señalada la que muestra su etiqueta entera.

Qué3.04.0
radialmenu: of_item con una clave sola (of_item("csv"))cambiaba la etiqueta y el estado de la única rama que la llevaba, pero sus colores no se dibujaban, y el manejador sobrevivía a la eliminación del padrese resuelve en la dirección completa (import/csv): mismo manejador, colores incluidos, liberado con el padre. Ambigua o desconocida: el manejador no cambia nada
radialmenu: un manejador sobre una dirección aún no añadidaun color puesto a través de él coloreaba la rama añadida después en esa dirección, incluso tras of_clearno escribe nada; of_clear olvida todos los colores
radialmenu: of_showno devolvía nadadevuelve un long: 0, o -2 si el componente no está creado
radialmenu: of_show(-1, -1)abría la rueda en el cursorla abre en el punto (-1, -1), como cualquier coordenada negativa; en el cursor es of_show()
radialmenu: una rama retirada, vaciada, atenuada u oculta mientras la rueda está abiertaaún se elegía: ue_item_selected para una rama desaparecidaya no se elige: ue_dismissed; of_clear, of_remove_item y of_reset cierran la rueda abierta
radialmenu: clic derecho en otro sitio mientras la rueda está abiertala nueva rueda sustituía a la anterior sin ue_dismissedue_dismissed para la anterior, y luego la nueva rueda
radialmenu: etiqueta larga o vacíacortada a dos líneas y legible en ninguna parte; vacía, una porción sin nadala rama señalada la muestra entera; vacía, se muestra la clave
radialmenu: lectura de derecha a izquierdala corona giraba en el sentido de las agujas del reloj, ← subíala corona gira en el otro sentido, ← y → se intercambian

La receta: (1) of_show devuelve un long: una llamada suelta compila tal cual; (2) sustituya of_show(-1, -1) por of_show(); (3) si deshacía en ue_dismissed lo que ponía al abrir, nada que hacer: ahora llega también cuando una rueda sustituye a otra; (4) un manejador obtenido con una clave que llevan dos ramas ya no cambia nada: dé la dirección.

11.38 toaster: eventos que dicen qué toast, rechazos que se dicen, un toast que espera a ser visto #

Los tres eventos del toast cambian de firma, of_add_button devuelve un código, y un toast ya no se pierde cuando la aplicación está minimizada.

Qué3.04.0
toaster: ue_toast_clicked, ue_toast_action, ue_toast_dismissed(string as_key …): as_key llevaba el identificador del toast, como texto(long al_id, string as_key …): al_id es el número devuelto por of_show, as_key el is_key del toast (vacío sin clave)
toaster: of_add_buttondevolvía el número de botones; una clave ya ocupada, una clave vacía y un cuarto botón pasaban sin decir nadadevuelve 0; -5 sin añadir nada para una clave vacía, ya ocupada, que contiene / o una barra vertical, o un cuarto botón. El número se lee con of_count()
toaster: of_show con un ajuste fuera de límitesmostraba de todos modos: un tipo desconocido como información, una esquina desconocida arriba a la izquierdadevuelve -5 y no muestra nada: is_kind, is_position o is_sound fuera de sus constantes, il_max_visible fuera de 0 a 20, il_timeout por debajo de TIMEOUT_AUTO
toaster: la misma is_key mostrada por dos toastersel segundo reemplazaba el toast del primero y le quitaba sus eventos; una actualización conservaba la esquina originalcada toaster tiene el suyo; una actualización toma también la esquina, el anclaje a la pantalla y la ventana de anclaje
toaster: el sonidoun sonido del sistema en cada toast, información y éxito incluidos; ninguno para un toast salido de la cola de esperais_sound: SOUND_AUTO (predeterminado) = solo error y advertencia, SOUND_ALWAYS, SOUND_NEVER; se reproduce cuando se solicita el toast, aunque espere su sitio
toaster: toasts anclados a la pantalla desde dos ventanas, o sin ipo_ownerse colocaban exactamente uno sobre otro; el límite se contaba por ventanauna sola pila por monitor y por esquina, e il_max_visible cuenta por monitor
toaster: un toast anclado a una ventana minimizadase iba a -32 000 px y se apagaba sin haber sido vistoespera: no se muestra y su cuenta atrás no corre hasta que la ventana vuelva
toaster: un toast que llega mientras se pasa el puntero por la piladescontaba su tiempo y podía irse durante la lecturanace en pausa, como los demás
toaster: PBT_SetLanguage, PBT_SetDefaultTheme, PBT_SetDefaultThemeAccent, PBT_SetDefaultFont, PBT_SetFlowDirection mientras se muestra un toastno le llegaban; el tamaño de letra seguía en 11 ptlo siguen enseguida, tamaño de letra incluido
toaster: el texto de un toastno se podía seleccionar; agarrar la barra de desplazamiento de un texto largo podía responder y cerrarse puede seleccionar y copiar (clic derecho, Copiar); la selección y la barra de desplazamiento ya no cierran el toast
toaster: il_button_countvariable públicaprivada: lea el número de botones con of_count()
toaster: un toast cuyo texto cita __licenseno se mostrabase muestra: solo una palabra reservada escrita como clave sigue rechazada
toaster: of_close de un toast en pantallaningún eventoue_toast_dismissed, como su cruz; un toast aún en espera, nunca visto, no lanza nada

La receta: (1) añada long al_id como primer argumento de sus ue_toast_clicked, ue_toast_action y ue_toast_dismissed, y sustituya Long(as_key) por al_id; as_key es ahora la clave del toast; (2) si leía el retorno de of_add_button como un número de botones, lea of_count(); (3) para mantener un sonido en una información o un éxito, establezca is_sound = SOUND_ALWAYS.

11.39 messagebox: un campo obligatorio vacío nunca se valida, opciones con claves únicas #

Cambian cinco comportamientos; ninguna firma.

Qué3.04.0
messagebox: ib_input_required y un botón predeterminado con cuenta atrás (of_add_button_timed)el clic automático validaba el cuadro con el campo vacío (of_show devolvía el botón, of_input_value una cadena vacía)la cuenta atrás se agota sin pulsar; el botón espera a que el campo se rellene
messagebox: Esc o Alt+F4 en un botón a la vez predeterminado y de cancelación, campo obligatorio vacíodevolvía 1, como un clic en ese botóndevuelve 0: cerrado sin elección
messagebox: of_add_choiceaceptaba una clave ya usada, o que contiene / o ``devuelve -5 y no añade nada
messagebox: of_choose sin ninguna opciónmostraba un cuadro con un único botón Cancelarno muestra nada: cadena vacía, y of_get_last_error dice «no choice to show»
messagebox: los botones de los cuadros prediseñados (of_info, of_confirm, of_yes_no, of_prompt…) cuando la aplicación no ha fijado ningún idioma«Ok»«OK», la palabra del catálogo inglés («Cancel», «Yes», «No» para los demás)

La receta: (1) un campo obligatorio se valida ahora a mano — si contaba con el clic automático para avanzar, dé al campo un valor por defecto (is_input_value); (2) dé a cada opción una clave única, sin / ni |, y compruebe -5 si sus claves vienen de datos.

11.40 Base común: el idioma anunciado por defecto, los números decimales de cualquier equipo #

Dos correcciones de la base común, válidas para todos los componentes; ninguna firma cambia.

Qué3.04.0
el idioma que anuncia un componente (<html lang>)el francés, mientras la aplicación no eligiera idiomael inglés, el idioma predeterminado de los componentes; el idioma elegido por la aplicación siempre lo sustituye
un número decimal dado a una propiedad (id_*)solo se convertía la coma decimal: en un equipo cuyo separador decimal es otro carácter, el valor no llegabase convierte el separador decimal del equipo, sea cual sea

La receta: nada que cambiar. Una aplicación que elige su idioma lo sigue viendo aplicado; un lector de pantalla que leía en francés un componente de una aplicación inglesa ahora lo lee en inglés.

11.41 Teclado, foco y espacio: lo que las pruebas de la 4.0 han enderezado #

Comportamientos vistos al usar los componentes en una aplicación real; ninguna firma cambia, se añade un método.

Qué3.04.0
Intro sobre un CommandButton de PowerBuilder que tiene el foconada (la tecla se perdía)el botón se pulsa (clicked), como en un cuadro de diálogo de Windows; el botón predeterminado de una barra no
Un componente desactivado (ib_enabled = false)Tab se detenía en élsale del orden de tabulación; reactivado (o of_reset), recupera su sitio
Un atajo Ctrl sobre un carácter sin tecla propia (AZERTY: - en la tecla 6, + con Mayús)Ctrl+- nunca encontraba su atajotras la tecla, el carácter de la distribución activa: Ctrl+-, Ctrl++, Ctrl+,, Ctrl+. funcionan en cualquier teclado
Teclear en un menú abierto (búsqueda, letras subrayadas)una tecla de la fila superior daba su cifra (AZERTY: - llegaba como 6)el carácter de la distribución; una letra subrayada &1 sigue respondiendo a la tecla 1
El calendario del selector de fecha (toolbar)solo con el ratóntambién con el teclado: flechas (día, semana), Re Pág/Av Pág (mes), Inicio/Fin, Intro elige, Esc cierra
Alt con dos cintas (o barras de menús) en la misma ventana, sin subventana entre ellasla primera creadala más cercana al foco en la pantalla
breadcrumb en una barra muy estrechael primer segmento nunca cedía: el lugar actual se reducía a nada, la ruta se desbordabatras el centro, el lugar actual cede hasta una letra y «…», luego el primer segmento; nada sale de la barra
menubar: una elección hecha con el ratón en el desplegableel foco se quedaba en la barra (Edición > Pegar no pegaba en ningún sitio)el foco vuelve al control que lo tenía
ribbon: escribir en un cuadro combinado y luego elegir en su listados ue_combo_changed: el texto tecleado y luego la elecciónuno solo, la elección
toolbar: is_text = "" asignado en ue_text_changed, el foco en el campoel texto antiguo volvía, con un segundo eventoel campo queda vacío
El foco devuelto a un componente tras una ventana de la biblioteca (paleta de comandos)la página, sin elemento: el cursor del editor de código había desaparecidoel elemento que lo tenía
Una etiqueta con letra subrayada (&File) de derecha a izquierdaletras desordenadas («ileF»)la palabra se lee en orden
n_pbt_utils.of_dir_folders(as_dir, ref as_names[])DirList en un ListBox: 4,5 s para 30 000 carpetas, y la carpeta actual de la aplicación cambiabanuevo: las subcarpetas tal como las muestra el Explorador, ordenadas, en una pasada; -4 ilegible, -5 ruta vacía
breadcrumb: of_add_children(as_keys, as_child_keys[], as_texts[])una rama cada vez (of_add_child): 30 000 subcarpetas abrían el menú en más de 20 snuevo: todo un nivel en una llamada

La receta: nada que cambiar. Una aplicación cuyo CommandButton con el foco debía ignorar Intro lo desactiva (Enabled = false) o le quita el foco; para una carpeta voluminosa, sustituya el bucle de of_add_child por un único of_add_children.

11.42 Datos y teclado: lo que el segundo lote de pruebas de la 4.0 ha enderezado #

Comportamientos vistos al usar los componentes de datos en una aplicación real; ninguna firma cambia.

Qué3.04.0
Intro o Esc pulsadas en un componente que no las tomaperdidas: el CommandButton de PowerBuilder Default o Cancel no se disparabala tecla vuelve a la ventana de PowerBuilder, como promete el capítulo 6.4: Esc pulsa el botón Cancel, Intro el botón Default
PBT_SetLanguage seguido enseguida de una orden al componenteel texto de un evento lanzado por esa orden (ue_error de xmltree) seguía en el idioma anteriorel idioma vale desde la orden siguiente
jsontree, xmltree: el foco dado al componente (of_focus_webview, la tecla Tab)se quedaba en la página: las flechas e Intro no iban a ninguna parteel árbol lo toma; F3 y Mayús+F3 pasan a la coincidencia siguiente o anterior de la búsqueda
xmltree: un error señalado DESPUÉS del último carácter de su líneaninguna columna subrayadael final de la línea está marcado (↵)
codeeditor con ajuste de línea (ib_wrap)la banda il_doc_line podía quedar una fila demasiado arriba, al final de la línea anteriorlas bandas cubren todas las filas de su línea y siguen el redimensionado
codeeditor: « Reemplazar todo » y of_replace_all en un texto largovarios segundos cuando el foco estaba en el editor; más allá, of_replace_all podía devolver 0instantáneo, y se devuelve el número de reemplazos; Ctrl+H con una búsqueda vacía pone el cursor en « Buscar »
crosstab: « Añadir a columnas » (o filas, filtros) desde el menú de un chip, con el tecladoel foco se perdía; solo Intro abría el menú de un chipel foco sigue al chip a su nueva zona; Mayús+F10 y la tecla Menú también abren su menú
json: miles de of_add_* seguidoscasi un segundo para 2 000 filasunas decenas de milisegundos; el documento es el mismo

La receta: nada que cambiar. Una aplicación que trataba ella misma Esc pulsada en un componente (un atajo registrado con of_register_shortcut) lo conserva: un atajo va antes que la ventana.

11.43 Contenido y medios: lo que el tercer lote de pruebas de la 4.0 ha enderezado #

Comportamientos vistos al usar los componentes de contenido y medios en una aplicación real; ninguna firma cambia.

Qué3.04.0
speechout: of_speak y luego of_pause en el mismo scriptue_started y la primera ue_sentence llegaban antes de ue_paused: la voz se anunciaba como iniciadaue_started se lanza cuando la voz empieza de verdad a hablar; una pausa puesta antes la retiene: nada se dice ni se anuncia hasta of_resume
speechout: un idioma sin voz exacta en el equipo (fr-CA donde solo hay fr-FR)ue_started anunciaba el idioma pedido (fr-CA)ue_started anuncia el idioma realmente leído (fr-FR), después de ue_voice_fallback
webbrowser: Tab tras el último control de la barra de direccionesel foco salía del componente hacia la ventana de PowerBuilderel foco entra en el sitio, como en un navegador; Mayús+Tab desde el sitio vuelve a la barra
webbrowser: ib_private = true puesto cuando la navegación ya es privadasin efecto: el sitio volvía a encontrar lo que había guardado en la sesión privadacada vez una sesión privada nueva y vacía
video en pantalla completa: un cuadro modal de la aplicación (un MessageBox en ue_ended)oculto bajo la película, que le volvía a quitar el teclado: la aplicación parecía congeladala película cede: el cuadro pasa delante y recibe el teclado; al cerrarlo, la película recupera la pantalla y Esc sale de ella
tilesbox: una flecha en el borde, junto a un mosaico más pequeñoFlecha arriba en un mosaico grande de la primera fila saltaba de lado, al pequeño vecinosolo cuenta un mosaico completamente más allá del borde: en el borde, el foco se queda donde está
dockcontainer: il_back_color / il_text_color de un panel apiladoperdidos en cuanto su pestaña estaba activa (tomaba el acento del tema)la pestaña activa conserva los colores del panel, como su lengüeta en el riel
progressbar: id_value puesto en cada vuelta de un bucle largounos 2,5 s para 20 000 filasbastante menos de un segundo; la barra sigue avanzando durante el bucle

La receta: nada que cambiar. Una aplicación que contaba con ue_started para saber que of_speak había sido aceptado lee en su lugar su código de retorno (0); la que compara el idioma de ue_started con is_lang conoce ahora el reemplazo también por esa diferencia, además de por ue_voice_fallback.

11.44 Datos: leer una celda, ordenar y buscar con más precisión (json, jsontree, xmltree, crosstab) #

Estas adiciones de la 4.0 no quitan ninguna firma. Dos cambian lo que usted ve sin que haya escrito nada: Ctrl+C del crosstab copia ahora los encabezados, y ue_cell_double_clicked recibe un argumento más.

Qué3.04.0
crosstab: ue_cell_double_clicked( string as_row_tuple_json, string as_col_tuple_json, double ad_value )( string as_row_tuple_json, string as_col_tuple_json, integer ai_measure, double ad_value ): ai_measure es la posición del valor pulsado dos veces en Valores, a partir de 1; con las dos tuplas, es la dirección que of_get_cell_value vuelve a leer
crosstab: Ctrl+C sobre celdassolo las cifraslos encabezados con ellas: los nombres de las columnas en una primera línea, el miembro de cada fila (su ruta, «North / Boston») en una primera columna; ib_copy_headers = false da solo las cifras
crosstab: of_remove_field, of_get_cell_value—nuevos: quitar un campo de todas las zonas sin reconstruir la disposición; leer el valor de una celda por sus tuplas y la posición de su medida
json: of_get_array, of_pretty (long al_indent)—nuevos: todos los elementos de un array en una llamada; una sangría en espacios, o el documento compacto en una línea con 0
jsontree, xmltree: la búsquedasiempre sin distinguir mayúsculas, y dentro de las palabrasib_find_match_case e ib_find_whole_word, como el codeeditor, con los conmutadores Aa y ab del cuadro de búsqueda; por defecto, la búsqueda sigue siendo la de la 3.0

La receta: un script de ue_cell_double_clicked no tiene nada que cambiar, el argumento se añade antes del valor. Una aplicación que pega el resultado de Ctrl+C en un proceso que solo espera cifras pone ib_copy_headers = false.

11.45 Navegación y contenedores: pestañas con el teclado, paneles con un doble clic (tab, dockcontainer, ribbon, stepbar, listbar) #

Estas adiciones de la 4.0 no quitan ninguna firma. Tres gestos cambian lo que ve un usuario sin que usted haya escrito nada: el clic central y Ctrl+Tab en un tab, y el doble clic en un panel de dockcontainer o en la barra de título de su ventana flotante.

Qué3.04.0
tab: clic central en una pestañanadacierra una pestaña que se puede cerrar, por el mismo camino que su cruz: ue_tab_closing si ib_veto_close = true, luego ue_tab_closed; una pestaña que no se puede cerrar, o desactivada, no hace nada
tab: Ctrl+Tab, Ctrl+Mayús+Tab, Ctrl+Av Pág / Re Págnadala pestaña siguiente o anterior que puede activarse, en bucle, esté el teclado en la banda o en una página alojada (un control PowerBuilder, otro componente); es un gesto: ue_selection_changing si ib_veto_selection = true, luego ue_selection_changed. Desde un control fuera del tab, la tecla se queda en la ventana
dockcontainer: doble clic en un encabezado o una pestaña; en la barra de título de una ventana flotantenada; la ventana flotante se maximizabadesacopla el panel en una ventana flotante (ue_panel_floated); en la barra de título de esa ventana, lo vuelve a acoplar en su sitio (ue_panel_docked), como su cruz
dockcontainer: clic derecho en un encabezado o una pestañanadaun menú Desacoplar, Cerrar, Cerrar los demás (los demás paneles que se pueden cerrar del mismo grupo); cada cierre plantea su propia pregunta
dockcontainer: ib_veto_close, ue_panel_closing, of_close_panel, n_pbt_dock_panel.ib_closable—nuevos: la pregunta antes de cerrar un panel (opcional, false por defecto), el cierre desde el código (-4 si lo rechaza, -5 para el panel principal o un panel que no se puede cerrar), y la posibilidad de cerrar cambiada en vivo
ribbon: n_pbt_ribbon_item.is_image, id_min, id_max, id_stepfijados al añadirla imagen de un control y el rango de un contador cambian en vivo y se releen; el valor de un contador se devuelve a su nuevo rango sin lanzar ue_value_changed, como id_value
stepbar: STATE_WARNING, STATE_SKIPPED, NAV_VISITED—nuevos: un paso superado con una advertencia (viñeta ámbar), un paso omitido (anillo discontinuo), y un modo en que todo paso ya alcanzado sigue siendo pulsable, también hacia delante tras un retroceso
listbar: n_pbt_listbar_section.ib_pinned—nuevo: una sección anclada al pie de la barra (Configuración, Ayuda), que sigue visible cuando la barra se desplaza, también en el carril; la disposición guardada conserva el orden de las secciones

La receta: nada que cambiar. En una página de tab, Ctrl+Tab cambia ahora de pestaña incluso cuando el foco está en un control de la página, como en una hoja de propiedades de Windows. Para maximizar una ventana flotante del dockcontainer, su botón Maximizar sigue ahí.

11.46 Menús: el chevron de la barra de menús, una lista desplegable en la barra de herramientas, diez mil comandos (menubar, toolbar, commandpalette) #

Estas adiciones de la 4.0 no quitan ninguna firma. Cambia un comportamiento por defecto: una barra de menús demasiado estrecha ya no salta de línea, pliega sus últimos títulos en un chevron. Y of_open de una paleta de comandos ya no se niega a abrirse sin ipo_owner ni ipo_receiver.

Qué3.04.0
menubar: una barra demasiado estrecha para sus títulossaltaba de línea: su altura seguía las filas, ue_auto_height en cada cambio de anchose queda en una línea: los títulos que no caben, desde el final, pasan al desplegable de un chevron (sus entradas en cascada, Alt + su letra los abre desde el chevron, las flechas se detienen en él como en un título, a la izquierda en RTL); la altura ya no cambia. ib_wrap = true devuelve el comportamiento anterior
menubar: ib_track_hover, ue_item_hover, of_add_header, n_pbt_menubar_menu.is_align—nuevos: la entrada señalada de un desplegable, para el texto de ayuda de una barra de estado (opcional, false por defecto; una dirección vacía al cerrar), encabezados de sección en un desplegable, y un menú al final de la barra (ALIGN_END, Ayuda)
toolbar: of_add_combo, of_add_combo_item, of_remove_combo_item, of_clear_combo, ue_combo_changed, n_pbt_toolbar_item.ib_editable—nuevos: una lista desplegable en la barra, editable o no, que sigue funcionando plegada en el chevron; su evento tiene el nombre y el sentido del de la cinta
commandpalette: dos paletas sobre el mismo ipo_ownercompartían su cola de eventos (una podía recibir el ue_closed de la otra), y la segunda retomaba el atajo de la primeracada una sus eventos y su atajo; el mismo atajo registrado por la segunda pasa a ella (1). of_open y of_register_shortcut ya no devuelven -5 sin ipo_owner ni ipo_receiver: los eventos siempre llegan
commandpalette: miles de comandoscada línea dibujada: la apertura y la escritura se ralentizabansolo se dibujan las líneas visibles: 10.000 comandos se abren y se filtran sin espera
Atajos de toda la biblioteca: AltGr + una tecla que escribe un carácter (el euro de un teclado francés)lanzaba el atajo Ctrl+Alt de esa tecla, también en un campo PowerBuilderse escribe el carácter, no se lanza ningún atajo; AltGr solo ya no da el teclado a una barra de menús o a una cinta

La receta: una barra de menús cuya altura variable era deseada pone ib_wrap = true; una aplicación que recolocaba sus controles en ue_auto_height en cada redimensionamiento ya no tiene nada que hacer después del primero. Un atajo de la aplicación en Ctrl+Alt + una letra que el teclado del usuario escribe con AltGr ya no se lanza mientras escribe: elija otra tecla.

11.47 Contenido y medios: un registro línea a línea, el tamaño real de una imagen, una película que espera (statictext, picture, video) #

Estas adiciones de la 4.0 no quitan ninguna firma ni cambian ningún valor por defecto. Dos comportamientos se precisan: el zoom de una imagen puede pasar su tope para alcanzar el tamaño real, y una película de una URL reproducida sin red lo dice.

Qué3.04.0
statictext: of_append_text, ib_follow_end—nuevos: un registro escrito línea a línea — solo la línea añadida viaja al componente — y, como opción, la vista que se queda abajo mientras el lector no suba
statictext: ib_auto_width, ue_auto_width—nuevos: el userobject toma la anchura de su texto (opcional, false por defecto), como hace ib_auto_height con la altura
picture: id_max_zoom, la tecla 1el zoom se detenía en 8.0 veces el encuadre, pasara lo que pasara: un escaneo grande mostrado pequeño nunca se leía píxel a píxelel tope se ajusta (id_max_zoom, 8.0 por defecto); la tecla 1 muestra el tamaño real, y el tope sube hasta él cuando pide más
video: ue_buffering, of_is_bufferinguna película que esperaba sus datos se quedaba congelada sin decir nadaun anillo con el acento del tema gira sobre la imagen, y ue_buffering(true) y luego ue_buffering(false) enmarcan la espera
video: una película de una URL mientras el puesto no tiene red«este archivo no se encuentra o no se puede reproducir», ue_failed con REASON_UNSUPPORTED«sin conexión de red» sobre la imagen, ue_failed con REASON_NETWORK

La receta: nada que cambiar. Un registro que reescribía is_text en cada línea pasa a of_append_text; un código que comprobaba REASON_UNSUPPORTED para una película de una URL sin red comprueba REASON_NETWORK.

11.48 Revisión del 03/10/2026: una disposición restaurada se avisa, una exportación a una ruta relativa cae en el lugar correcto (toolbar, crosstab) #

Ninguna firma cambia. Dos comportamientos se alinean con la regla de la biblioteca: todo cambio de la disposición se avisa, y una ruta relativa de escritura se resuelve como en las demás exportaciones.

Qué3.04.0
toolbar: of_set_layoutningún eventoemite ue_layout_changed, como el dockcontainer y el datagrid: todo cambio de la disposición se avisa, venga del usuario o de su código
crosstab: of_export_csv, of_export_xlsx a una ruta relativaescrito en la carpeta actual del momento — que un DirList o un cuadro de archivos podían haber movido; ue_csv_saved / ue_xlsx_saved devolvían la ruta tal como se dioescrito en la carpeta donde arrancó la aplicación, como las demás exportaciones nativas; el evento devuelve la ruta completa; una ruta que depende de la carpeta actual de una unidad (\x, C:x) se rechaza

La receta: una aplicación que guarda la disposición en ue_layout_changed vuelve a guardar el mismo valor tras of_set_layout — sin consecuencias. Una exportación que contaba con la carpeta actual del momento indica una ruta completa.


← Migrar de la 2.0 a la 3.0 · Índice · Notas de la versión →