6. Funciones transversales #
← Idioma y RTL · Índice · FAQ →
Este capítulo reúne los servicios disponibles sea cual sea el componente: tooltips, alojamiento de controles PowerBuilder, arrastrar y soltar desde el Explorador, foco de teclado, exportación de imagen y los objetos de utilidad no visuales.
6.1 Tooltips simples y enriquecidos #
Tooltip del componente #
uo_button.is_tooltip = "Guardar el expediente (Ctrl+S)"
El texto acepta el texto enriquecido con etiquetas: [b], [br], [color=…], [picture=…]…
Tooltip enriquecido (título + texto + imagen) #
Para una ayuda contextual al estilo de la cinta de opciones de Office:
uo_button.is_super_tooltip_title = "Guardar"
uo_button.is_super_tooltip_text = "Escribe las modificaciones en el servidor." &
+ "[br][br][size-=15]Atajo: Ctrl+S[/size-=15]"
uo_button.is_super_tooltip_image = "img\help_save.png"
Las tres propiedades son independientes: un título solo, o un título más texto sin imagen, son válidos. En cuanto se establece una propiedad is_super_tooltip_*, esta prevalece sobre is_tooltip.
Tooltip de un item #
Toda clase de item (n_pbt_item y sus descendientes) lleva las mismas cuatro propiedades:
uo_toolbar.of_item(/*keys*/ "main/save").is_tooltip = "Guardar"
uo_tab.of_page(/*key*/ "clients").is_super_tooltip_title = "Clientes"
uo_tab.of_page(/*key*/ "clients").is_super_tooltip_text = "128 fichas, última sincronización a las 09:12"
Comportamiento #
- El tooltip es una ventana nativa con tema, idéntica en todos los componentes (no está limitada por las fronteras de la webview).
- No se muestra si su aplicación no tiene el foco: pasar el ratón por encima de una ventana en segundo plano no activa nada.
- Desaparece cuando usted cambia a otra aplicación, y como muy tarde al cabo de 10 segundos.
of_reset()elimina los tooltips establecidos sobre la instancia y sobre sus items.
6.2 Alojar controles reales de PowerBuilder #
Los componentes contenedores no muestran HTML en lugar de sus pantallas: alojan controles reales de PowerBuilder (userobjects, DataWindows, grupos de controles), reasignados como ventanas Win32 hijas. Sus pantallas existentes se reutilizan tal cual.
// Pestanas: cada pagina es un userobject PB
uo_tab.of_add_page(/*key*/ "clients", /*title*/ "Clientes", /*page*/ uo_page_clients)
uo_tab.of_add_page(/*key*/ "invoices", /*title*/ "Facturas", /*page*/ uo_page_invoices, /*closable*/ true)
// Paneles acoplables: lo mismo
uo_dock.is_main = "doc" // zona central
uo_dock.of_add_panel(/*key*/ "doc", /*position*/ uo_dock.POSITION_STACK, /*relative_to*/ "", /*size*/ 0, /*title*/ "Documento", /*content*/ uo_editor)
uo_dock.of_add_panel(/*key*/ "explorer", /*position*/ uo_dock.POSITION_START, /*relative_to*/ "", /*size*/ 240, /*title*/ "Explorador", /*content*/ uo_tree)
uo_dock.of_add_panel(/*key*/ "props", /*position*/ uo_dock.POSITION_END, /*relative_to*/ "", /*size*/ 260, /*title*/ "Propiedades", /*content*/ uo_props)
Lo que se gestiona por usted:
- el posicionamiento y el redimensionamiento del control alojado cuando la pestaña o el panel cambia de tamaño;
- la visualización / ocultación al cambiar de pestaña o de panel activo;
- los paneles flotantes, acoplados u ocultados automáticamente (dockcontainer);
- la destrucción limpia al cerrarse la ventana.
⚠️ Un control alojado es una ventana nativa: se dibuja por encima de la capa web. Es intencionado (su DataWindow se mantiene nítida y rápida), pero significa que ningún efecto web — sombra, transparencia, animación — puede pasar por encima de él.
6.3 Recibir archivos desde el Explorador de Windows #
Un componente puede convertirse en destino de soltado para archivos arrastrados desde el Explorador. La biblioteca instala un destino de soltado nativo: usted recibe las rutas completas, algo que un soltado HTML no permite.
uo_editor.ib_allow_drop = true
// event ue_drop_files de uo_editor: (string as_files[])
// Local variables
long ll_i
// Abrir cada archivo soltado
for ll_i = 1 to UpperBound(as_files)
of_open_file(as_files[ll_i])
next
| Evento | Se activa cuando |
|---|---|
ue_drag_enter ( ) | Un arrastre de archivos entra en el componente |
ue_drag_leave ( ) | Sale de él sin soltar |
ue_drop_files (string as_files[]) | Los archivos se sueltan — rutas completas |
El propio componente proporciona la respuesta visual al pasar el cursor (resaltado de la zona de soltado). Publicado por los componentes en los que soltar tiene sentido: statictext, codeeditor.
6.4 Teclado y foco #
Un componente PBToolboxAI participa en la navegación por teclado de su ventana igual que un control nativo:
- la tecla Tab lo alcanza en el orden de tabulación de la ventana;
- las teclas (flechas, Intro, Esc, entrada de datos) las trata el componente que tiene el foco;
- los atajos de ventana (Intro = botón predeterminado, Esc = cancelar) siguen funcionando incluso cuando el foco está dentro de un componente.
Una tecla que el componente trata él mismo se queda con él: Intro sobre un elemento que dibuja como un botón (un paso, un segmento) lo activa — y no pulsa además el botón predeterminado; Esc que abandona un arrastre o sale de un modo no cierra la ventana. Una pulsación nunca produce dos efectos. Una pulsación AltGr que produce un carácter (el euro de un teclado francés) es escritura, nunca un atajo.
Para dar explícitamente el foco al contenido de un componente (por ejemplo, después de abrir un panel de búsqueda):
uo_editor.of_focus_webview()
6.5 Exportar la representación como imagen #
Recordatorio de la base común: todo componente se exporta tal como se muestra.
uo_tiles.of_save_as_png(/*path*/ "C:\temp\accueil.png")
uo_tiles.of_save_as_jpg(/*path*/ "C:\temp\accueil.jpg")
Útil para adjuntar una pantalla a un correo electrónico, alimentar un informe o documentar una incidencia de usuario.
6.6 Cuadros de diálogo y notificaciones #
Dos servicios sin ningún control que colocar en la ventana:
// Local variables
n_pbt_messagebox lnv_mb
// Cuadro de dialogo modal con tema (retorno sincrono)
lnv_mb = create n_pbt_messagebox
lnv_mb.is_title = "Eliminación"
lnv_mb.is_message = "¿Eliminar definitivamente [b]12 expedientes[/b]?"
lnv_mb.is_icon = lnv_mb.ICON_QUESTION
lnv_mb.of_add_button(/*text*/ "Eliminar", /*default*/ false, /*cancel*/ false)
lnv_mb.of_add_button(/*text*/ "Cancelar", /*default*/ true, /*cancel*/ true)
if lnv_mb.of_show(/*hwnd*/ Handle(this)) = 1 then of_delete()
destroy lnv_mb
// Local variables
n_pbt_toaster lnv_toast
// Notificacion "toast" en una esquina de la pantalla, no bloqueante
lnv_toast = create n_pbt_toaster
lnv_toast.is_title = "Importación finalizada"
lnv_toast.is_text = "1 240 filas integradas."
lnv_toast.is_kind = lnv_toast.KIND_SUCCESS
lnv_toast.of_show()
destroy lnv_toast
Detalles completos: messagebox y toaster.
6.7 Objetos de utilidad no visuales #
Entregados en la misma PBL, sin webview ni representación: son simples envoltorios alrededor de la DLL. Créelos, úselos, destrúyalos.
Base64, hashes, identificadores — n_pbt_crypto #
El base64 (texto o archivo), los hashes SHA y los identificadores únicos viven en el componente crypto: of_base64_encode, of_base64_encode_file, of_sha256, of_hash_file, of_uuid… Una sola página para todo lo que calcula sin mostrar nada.
Expresiones regulares — u_pbt_regex #
Sintaxis ECMAScript, ausente de PowerScript.
Sin una clave que lo cubra, u_pbt_regex funciona en modo demo: el texto analizado tiene como máximo 2048 caracteres; por encima, la llamada falla y of_get_last_error() lo indica. Para que se aplique la clave de su aplicación, asigne ipo_owner al objeto que lo usa (lnv_re.ipo_owner = this), como para crypto.
// Local variables
u_pbt_regex lnv_re
string ls_found[], ls_email, ls_date, ls_input, ls_text, ls_year, ls_clean
long ll_nb
// Un objeto para todas las busquedas : crearlo, usarlo, destruirlo
lnv_re = create u_pbt_regex
if lnv_re.of_is_match(/*pattern*/ "^[\w.]+@[\w.]+\.\w{2,}$", /*input*/ ls_email) then …
ls_year = lnv_re.of_match(/*pattern*/ "(\d{4})-(\d{2})-(\d{2})", /*input*/ ls_date, /*group*/ 1)
ls_clean = lnv_re.of_replace(/*pattern*/ "\s+", /*input*/ ls_input, /*replacement*/ " ")
ll_nb = lnv_re.of_match_all(/*pattern*/ "[A-Z]{2}\d{6}", /*input*/ ls_text, /*matches*/ ls_found)
destroy lnv_re
| Método | Función |
|---|---|
of_is_match (patrón, texto [, ab_ignore_case | al_flags]) | ¿Coincide el texto? |
of_match (patrón, texto, ai_groupe [, al_flags]) | Primera coincidencia (0 = todo, 1.. = grupo de captura) |
of_match_all (patrón, texto [, ai_groupe, al_flags], ref as_res[]) | Todas las coincidencias; devuelve el número |
of_replace (patrón, texto, sustitución) | Sustituye todas las apariciones ($1… permitidos) |
Opciones combinables: FLAG_IGNORE_CASE (1), FLAG_SINGLELINE (2, el . atraviesa los saltos de línea).
Archivos ZIP — u_pbt_zip #
// Local variables
u_pbt_zip lnv_zip
// Comprimir una carpeta y luego extraer el archivo en otro lugar
lnv_zip = create u_pbt_zip
lnv_zip.of_compress(/*zip*/ "C:\temp\livraison.zip", /*src*/ "C:\appli\export") // archivo O carpeta
lnv_zip.of_extract(/*zip*/ "C:\temp\livraison.zip", /*dest*/ "C:\appli\import") // carpeta creada si falta
destroy lnv_zip
Los dos métodos devuelven un boolean.
Sin una clave que lo cubra, u_pbt_zip funciona en modo demo: lo que comprime (un archivo o una carpeta, en total) y el archivo que extrae tienen como máximo 2048 bytes; por encima, el método devuelve false e of_get_last_error() lo indica. Asigne ipo_owner al objeto que lo usa (lnv_zip.ipo_owner = this) para que se aplique la clave de su aplicación.
6.8 Información sobre la biblioteca #
// Local variables
long ll_version
// Version de la DLL: un long, mayor x 10000 + menor x 100 + correccion
ll_version = PBT_GetVersion() // 40000 = 4.00.00
| Función global | Función |
|---|---|
PBT_GetVersion ( ) → long | Versión de la biblioteca: 40000 = 4.00.00 (mayor × 10000 + menor × 100 + corrección) |
PBT_CheckRuntime (ref string, long) | Versión del runtime WebView2 instalado (≤ 0 = ausente) |
PBT_GetLastErrorMessage (ref string, long) | Último mensaje de error del proceso |
PBT_LicenseStatus ( ) | Estado de la licencia — véase Licencia |
6.9 Imprimir #
Todo componente sabe imprimirse, tal como se muestra, sin DataWindow intermedia.
// Silencioso: un PDF en disco, nada que pulsar
uo_grid.of_print_to_pdf(/*path*/ "C:\etats\ventes.pdf")
// Horizontal, para una cuadricula ancha
uo_grid.of_print_to_pdf(/*path*/ "C:\etats\ventes.pdf", /*landscape*/ true)
// Con dialogo: el usuario elige su impresora y ve la vista previa
uo_grid.of_print()
// Directamente el dialogo de impresion del sistema
uo_grid.of_print(/*system_dialog*/ /*dialogue systeme*/ true)
| Método | Función |
|---|---|
of_print_to_pdf (string as_path) · of_print_to_pdf (string, boolean ab_landscape) | Escribe un PDF sin mostrar nada. Solo devuelve el control una vez escrito el archivo (0 = hecho) |
of_print ( ) · of_print (boolean ab_system_dialog) | Abre el diálogo de impresión. Devuelve el control en cuanto el diálogo está abierto: lo que el usuario haga con él es cosa suya |
⚠️ Se imprime lo que está RENDERIZADO. Una cuadrícula virtualizada solo imprime las filas que tiene: para un informe completo, pase antes a una disposición que las muestre todas (paginación), o exporte los datos en lugar del renderizado.
El código de retorno -6 señala un runtime WebView2 demasiado antiguo para imprimir (1.0.1108 para el PDF, 1.0.1587 para el diálogo). Todo lo demás sigue los códigos de retorno comunes.