PBToolboxAI v4 ← Site

messagebox — n_pbt_messagebox #

← Referencia de componentes · Índice de la guía

Cuadro de diálogo modal con tema, de resultado síncrono: el sustituto directo del MessageBox() de PowerBuilder, con texto enriquecido, botones libres, iconos y casilla de verificación.

▶ Verlo en vivo — Aplicación de demostración, mosaico Message box: la vista previa, el código que lo genera y esta página, uno al lado del otro.


De un vistazo #

Objeton_pbt_messagebox — no visual: nada que colocar en la ventana
Sirve paraPlantear una pregunta o anunciar un resultado, en lugar del MessageBox() nativo, rígido y sin tema
ResultadoSíncrono: of_show() bloquea y devuelve el índice del botón pulsado

A diferencia de los componentes visuales, este objeto no se inserta en una ventana: se crea, configura, muestra y destruye.

// Variables locales
n_pbt_messagebox lnv_mb

// Crear el objeto de dialogo
lnv_mb = create n_pbt_messagebox

// ... configuracion ...

// Liberar el objeto de dialogo
destroy lnv_mb

Inicio rápido #

// Variables locales
n_pbt_messagebox lnv_mb

// Crear el objeto de dialogo
lnv_mb = create n_pbt_messagebox

// Configurar el cuadro
lnv_mb.is_title   = "Eliminación"
lnv_mb.is_icon    = lnv_mb.ICON_WARNING
lnv_mb.is_message = "¿Eliminar definitivamente [b]12 carpetas[/b]?[br][br]Esta acción es irreversible."

// Agregar los botones
lnv_mb.of_add_button(/*text*/ "Eliminar", /*default*/ true,  /*cancel*/ false)   // -> 1
lnv_mb.of_add_button(/*text*/ "Cancelar",   /*default*/ false, /*cancel*/ true)    // -> 2

// Mostrar en modal y actuar sobre el primer boton
if lnv_mb.of_show(/*hwnd*/ Handle(this)) = 1 then
    of_delete()
end if

// Liberar el objeto de dialogo
destroy lnv_mb

of_show espera la respuesta del usuario: la línea siguiente no se ejecuta hasta después del clic, exactamente igual que con MessageBox().


Propiedades #

Deben establecerse antes de of_show.

PropiedadTipoPredeterminadoFunción
is_titlestring""Título mostrado en el encabezado del cuadro
is_messagestring""Cuerpo del mensaje. Acepta el texto enriquecido con etiquetas ([b], [i], [br], [accent], [picture=…]…). El texto del mensaje y de la instrucción se puede seleccionar y copiar. Un valor que viene de sus datos pasa antes por of_escape_markup: si no, un corchete se leería como una etiqueta — un [action=x] en el nombre de un cliente cerraría el cuadro
is_instructionstring""Instrucción principal: la pregunta en sí, mostrada más grande encima del mensaje. Título / instrucción / mensaje es la anatomía que hace un diálogo legible de un vistazo — «¿Eliminar 42 filas?» y luego «Esta acción es definitiva» — en lugar de un bloque uniforme. Acepta el marcado
is_iconstring""Icono: una constante ICON_*, o su propia imagen (ruta de archivo, o recurso de DLL mi.dll:NOMBRE)
is_checkboxstring""Texto de una casilla de verificación opcional, del estilo «no volver a preguntar» ("" = sin casilla)
ib_checkedbooleanfalseEstado inicial de la casilla (el estado final se lee con of_checked())
ib_inputbooleanfalseAñade un campo de entrada con el tema aplicado (renombrar, motivo, comentario), de modo que una aplicación ya no necesita una ventana hecha a mano que no sigue ni el tema ni el sentido de lectura. Se relee con of_input_value() tras of_show. Todo en una llamada: of_prompt
is_input_labelstring""Etiqueta encima del campo ("" = ninguna). Necesita ib_input
is_input_valuestring""Contenido inicial del campo. Está seleccionado al abrirse: escribir lo sustituye, como en todo diálogo de renombrado
is_input_placeholderstring""Indicación mostrada mientras el campo está vacío. No es un valor: si el usuario no escribe nada, no se devuelve nada
ib_input_passwordbooleanfalseEnmascara los caracteres escritos
ib_input_requiredbooleanfalseEl botón predeterminado permanece desactivado mientras el campo esté vacío. Dejar enviar para reprender después no sirve a nadie; el botón de cancelar sigue accesible. Una cuenta atrás en ese botón (of_add_button_timed) no lo pulsa mientras el campo esté vacío: se agota y el botón espera una mano. Un botón a la vez predeterminado y de cancelación también queda fuera de alcance: Esc y Alt+F4 cierran entonces el cuadro sin elección (0)
ib_buttons_reversebooleanfalseOrden de los botones: false = de izquierda a derecha en el orden de adición; true = invertido
ib_movablebooleantrue¿Se puede mover el cuadro? No tiene barra de título — pinta su propia tarjeta — así que Windows no tiene agarre sobre él: se lo damos, la tarjeta arrastra la ventana salvo lo que ya responde a un clic y el texto del mensaje, que se puede seleccionar. Verdadera por defecto, porque una modal que tapa justo lo que hay que leer para responder es una trampa. Póngala a falso para un cuadro que debe quedarse donde está
is_positionstringPOSITION_OWNERCentrado: POSITION_OWNER (sobre la ventana llamante) o POSITION_SCREEN (sobre la pantalla)
il_min_widthlong0Anchura mínima en píxeles (0 = automática, 320); nunca menos de 200
il_max_widthlong0Anchura máxima en píxeles (0 = automática): el texto se ajusta dentro de este límite; nunca menos de 200
il_max_heightlong0Altura máxima en píxeles (0 = automática): más allá, el cuerpo del mensaje se desplaza en lugar de agrandar la ventana
il_accentlong-1Color de acento de este cuadro: el botón predeterminado y la casilla lo toman, y el color de texto legible se deriva de él. -1 (el valor por defecto) sigue a la aplicación. Un error en rojo, un éxito en verde, sin tocar el tema

Constantes #

ConstanteValorUso
ICON_INFORMATION"information"Información neutra
ICON_WARNING"warning"Advertencia, acción arriesgada
ICON_ERROR"error"Fallo, error
ICON_QUESTION"question"Pregunta cerrada
ICON_SUCCESS"success"Confirmación de un éxito
ICON_NONE"none"Ningún icono
POSITION_OWNER"owner"Centrado sobre la ventana llamante
POSITION_SCREEN"screen"Centrado sobre la pantalla

Métodos #

MétodoFunción
of_add_button (string as_text) → longAñade un botón simple. Devuelve su índice a partir de 1
of_add_button (string as_text, boolean ab_default, boolean ab_cancel) → longLo mismo, marcando el botón como predeterminado (Intro) y/o de cancelación (Esc). Devuelve su índice, a partir de 1
of_add_button (string as_text, string as_icon, boolean ab_default, boolean ab_cancel) → longLo mismo, con un icono en el botón. Devuelve su índice, a partir de 1
of_add_button_timed (string as_text, boolean ab_default, boolean ab_cancel, long al_enable_secs, long al_click_secs) → longBotón con cuenta atrás: permanece desactivado al_enable_secs segundos (con contador visible), y luego se pulsa solo al cabo de al_click_secs segundos (0 = temporizador inactivo). Mientras un botón de cancelación siga en cuenta atrás, ni Esc ni Alt+F4 cierran el cuadro: la espera está para hacer leer. Devuelve su índice, a partir de 1
of_count ( ) → longDevuelve el número de botones que lleva el cuadro. Se designan por su posición — la que devuelve of_add_button y la que devuelve of_show — por lo que no tienen clave: aquí no hay of_keys_at ni of_has
of_show (long al_hwnd) → longMuestra el cuadro modal y devuelve el índice del botón pulsado (0 = cierre con Esc o Alt+F4 sin botón de cancelación). Un valor negativo indica que no se pudo mostrar ningún cuadro: -4, o -6 si falta el runtime de WebView2 — of_get_last_error() dice por qué. Si la ventana propietaria se cierra mientras el cuadro está abierto (un temporizador, un evento), el cuadro se va con ella y of_show devuelve 0
of_get_last_error ( ) → stringPor qué no se pudo abrir el último cuadro — cadena vacía si se abrió. Se lee tras un of_show (o un atajo como of_info) que devolvió un valor negativo, o tras un of_choose o un of_prompt que devolvió una cadena vacía
of_checked ( ) → booleanEstado de la casilla de verificación en el momento del último of_show
of_input_value ( ) → stringTexto escrito en el último of_show (vacío si ib_input estaba desactivado)
of_action ( ) → stringId de la zona [action=id] pulsada en el mensaje, cadena vacía en caso contrario. Tal zona es una elección ofrecida en la propia frase: cierra el diálogo y of_show devuelve 0. Una zona [hyperlink=url], en cambio, se abre en el navegador y deja el diálogo abierto — el llamante está bloqueado en of_show, así que un enlace no puede ser una respuesta
of_info (long al_hwnd, string as_title, string as_message) → longDiálogo de una línea, como lo es MessageBox(): icono de información y un solo botón Aceptar, devuelve 1. Las etiquetas vienen de las traducciones de la biblioteca (6 idiomas) en lugar de escribirse en cada aplicación — esa es toda la razón de ser de estos atajos (negativo: ningún cuadro mostrado, ver of_get_last_error)
of_warning (long al_hwnd, string as_title, string as_message) → longIcono de advertencia, un botón Aceptar. Devuelve 1 (negativo: ningún cuadro mostrado, ver of_get_last_error)
of_error (long al_hwnd, string as_title, string as_message) → longIcono de error, un botón Aceptar. Devuelve 1 (negativo: ningún cuadro mostrado, ver of_get_last_error)
of_success (long al_hwnd, string as_title, string as_message) → longIcono de éxito, un botón Aceptar. Devuelve 1 (negativo: ningún cuadro mostrado, ver of_get_last_error)
of_confirm (long al_hwnd, string as_title, string as_message) → longPregunta + Aceptar / Cancelar. Devuelve 1 = Aceptar, 2 = Cancelar, 0 = cerrado (negativo: ningún cuadro mostrado, ver of_get_last_error)
of_yes_no (long al_hwnd, string as_title, string as_message) → longPregunta + Sí / No. Devuelve 1 = Sí, 2 = No, 0 = cerrado (negativo: ningún cuadro mostrado, ver of_get_last_error)
of_yes_no_cancel (long al_hwnd, string as_title, string as_message) → longPregunta + Sí / No / Cancelar. Devuelve 1, 2, 3, o 0 si se cierra (negativo: ningún cuadro mostrado, ver of_get_last_error)
of_add_choice (string as_key, string as_title, string as_description) → longAñade una opción bajo el mensaje — un título y una descripción, como los vínculos de comando de un cuadro de tareas de Windows. El clic cierra el cuadro y of_action() da su clave (of_show devuelve 0). Devuelve el rango de la opción (1 para la primera), -5 con una clave vacía, ya usada o que contiene / o `` — entonces no se añade nada
of_choose (long al_hwnd) → stringMuestra las opciones con un único botón Cancelar (traducido) y devuelve la clave de la opción pulsada, o una cadena vacía si el usuario canceló. La lista se desplaza cuando desborda la pantalla. Cadena vacía también cuando no se pudo mostrar ningún cuadro: of_get_last_error dice entonces por qué. Sin ninguna opción no se muestra nada: cadena vacía, y of_get_last_error dice «no choice to show»
of_prompt (long al_hwnd, string as_title, string as_message, string as_default) → stringPide un valor y devuelve lo escrito, o una cadena vacía si el usuario canceló. Para distinguir una respuesta vacía de una cancelación, use of_show + of_input_value. Cadena vacía también cuando no se pudo mostrar ningún cuadro: of_get_last_error dice entonces por qué
of_reset ( )Borra todas las propiedades y los botones añadidos: la misma instancia vuelve a empezar de cero

La etiqueta de un botón acepta el texto enriquecido con etiquetas y el mnemotécnico & ("&Guardar" subraya la G y lo activa con Alt+G); && muestra un ampersand literal.


El teclado #

TeclaEfecto
IntroActiva el botón marcado como predeterminado
EscActiva el botón marcado como cancelación; sin botón de cancelación, cierra el cuadro y devuelve 0. Alt+F4 hace lo mismo. Mientras el botón de cancelación siga en cuenta atrás (of_add_button_timed), ninguno de los dos cierra
Alt + letraActiva el botón cuya etiqueta lleva ese mnemotécnico
TabDesplaza el foco de un botón a otro
Ctrl + CCopia el diálogo (título, instrucción, mensaje, opciones con su descripción, casilla con su estado [x] o [ ], etiquetas de los botones) al portapapeles, como todo cuadro de diálogo de Windows — práctico cuando hay que reenviar un error al soporte. Con texto seleccionado en el mensaje, copia solo la selección

Al abrirse, ningún botón tiene contorno de foco: es intencionado, y es el comportamiento de los cuadros de diálogo modernos de Windows. El borde solo aparece tras una primera pulsación de Tab, es decir, cuando el usuario pasa explícitamente al teclado. Intro y Esc permanecen activos desde el primer segundo, incluso sin foco visible.


Ejemplos #

Pregunta cerrada con botón predeterminado #

// Variables locales
n_pbt_messagebox lnv_mb
long ll_answer

// Crear el objeto de dialogo
lnv_mb = create n_pbt_messagebox

// Configurar el cuadro
lnv_mb.is_title   = "Guardar los cambios"
lnv_mb.is_icon    = lnv_mb.ICON_QUESTION
lnv_mb.is_message = "La carpeta se ha modificado. ¿Desea guardar antes de cerrar?"

// Agregar los botones
lnv_mb.of_add_button(/*text*/ "&Guardar",     /*default*/ true,  /*cancel*/ false)  // 1
lnv_mb.of_add_button(/*text*/ "&No guardar", /*default*/ false, /*cancel*/ false) // 2
lnv_mb.of_add_button(/*text*/ "Cancelar",          /*default*/ false, /*cancel*/ true)   // 3

// Mostrar en modal y liberar el objeto de dialogo
ll_answer = lnv_mb.of_show(/*hwnd*/ Handle(this))
destroy lnv_mb

// Actuar segun el boton pulsado (rango desde 1)
choose case ll_answer
    case 1 ; of_save() ; Close(parent)
    case 2 ; Close(parent)
    case else ; // 3 o 0 : no se cierra
end choose

Mensaje enriquecido e icono #

// Configurar el cuadro
lnv_mb.is_title   = "Importación finalizada"
lnv_mb.is_icon    = lnv_mb.ICON_SUCCESS
lnv_mb.is_message = "[b]1 240 líneas[/b] integradas.[br][br]" &
                  + "[accent]18 duplicados[/accent] se han ignorado."

// Agregar su boton y mostrar el cuadro
lnv_mb.of_add_button(/*text*/ "Aceptar", /*default*/ true, /*cancel*/ false)
lnv_mb.of_show(/*hwnd*/ Handle(this))

Un valor de sus datos en el mensaje #

El mensaje es texto enriquecido: un corchete es una etiqueta. El nombre de un cliente, un texto escrito por un usuario pasan por of_escape_markup (de n_pbt_utils) antes de entrar — si no, «García [action=x]» cerraría el cuadro como una opción.

// Local variables
n_pbt_utils lnv_utils

// The name comes from the database : escape it, it is shown as it is
lnv_mb.is_title   = "Delete customer"
lnv_mb.is_message = "Delete the customer [b]" + lnv_utils.of_escape_markup(/*text*/ ls_name) + "[/b] ?"

// Add the buttons, then show the box
lnv_mb.of_add_button(/*text*/ "Delete", /*default*/ false, /*cancel*/ false)
lnv_mb.of_add_button(/*text*/ "Cancel", /*default*/ true, /*cancel*/ true)
lnv_mb.of_show(/*hwnd*/ Handle(this))

Casilla «no volver a preguntar» #

// Variables locales
n_pbt_messagebox lnv_mb

// Crear el objeto de dialogo
lnv_mb = create n_pbt_messagebox

// Configurar el cuadro
lnv_mb.is_title    = "Eliminación"
lnv_mb.is_icon     = lnv_mb.ICON_WARNING
lnv_mb.is_message  = "¿Eliminar las líneas seleccionadas? Esta acción es irreversible."
lnv_mb.is_checkbox = "No volver a preguntar"
lnv_mb.ib_checked  = false

// Agregar los botones
lnv_mb.of_add_button(/*text*/ "Eliminar", /*default*/ true,  /*cancel*/ false)
lnv_mb.of_add_button(/*text*/ "Cancelar",   /*default*/ false, /*cancel*/ true)

// Mostrar en modal y actuar sobre el primer boton
if lnv_mb.of_show(/*hwnd*/ Handle(this)) = 1 then
    of_delete()

    // Memorizar la eleccion del usuario
    ib_confirm_delete = not lnv_mb.of_checked()
end if

// Liberar el objeto de dialogo
destroy lnv_mb

Botón con cuenta atrás #

// Configurar el cuadro
lnv_mb.is_title   = "Reinicio"
lnv_mb.is_icon    = lnv_mb.ICON_INFORMATION
lnv_mb.is_message = "La aplicación se va a reiniciar para aplicar la actualización."

// "Continuar" permanece atenuado 3 segundos (se muestra un contador)
lnv_mb.of_add_button_timed(/*text*/ "Continuar", /*default*/ true, /*cancel*/ false, /*enable_secs*/ 3, /*click_secs*/ 0)

// "Mas tarde" se pulsa solo al cabo de 10 segundos
lnv_mb.of_add_button_timed(/*text*/ "Más tarde", /*default*/ false, /*cancel*/ true, /*enable_secs*/ 0, /*click_secs*/ 10)

// Mostrar en modal
lnv_mb.of_show(/*hwnd*/ Handle(this))

Mensaje largo: limitar el tamaño #

// Un texto voluminoso : el cuadro esta limitado y el cuerpo se desplaza
lnv_mb.is_title      = "Notas de la versión"
lnv_mb.is_message    = ls_notes
lnv_mb.il_max_width  = 480
lnv_mb.il_max_height = 320

// Agregar su boton y mostrar el cuadro
lnv_mb.of_add_button(/*text*/ "Cerrar", /*default*/ true, /*cancel*/ true)
lnv_mb.of_show(/*hwnd*/ Handle(this))

Reutilizar una instancia #

// Una instancia de ventana, varios dialogos : of_reset entre cada llamada
inv_mb.of_reset()      // borra las propiedades Y los botones anteriores

// Configurar el nuevo cuadro y mostrarlo
inv_mb.is_title   = "Segundo diálogo"
inv_mb.is_message = "Cada of_reset vuelve a empezar con un cuadro en blanco."
inv_mb.of_add_button(/*text*/ "Aceptar", /*default*/ true, /*cancel*/ false)
inv_mb.of_show(/*hwnd*/ Handle(this))

Buenas prácticas #


← Referencia de componentes · Índice de la guía