messagebox — n_pbt_messagebox #
← Referência dos componentes · Índice do guia
Caixa de diálogo modal com tema, de retorno síncrono: o substituto direto do
MessageBox()do PowerBuilder, com texto formatado, botões livres, ícones e caixa de verificação.
▶ Ver ao vivo — Aplicação de demonstração, mosaico Message box: a pré-visualização, o código que o produz e esta página, lado a lado.
Em resumo #
| Objeto | n_pbt_messagebox — não visual: nada a colocar na janela |
| Serve para | Colocar uma questão ou anunciar um resultado, em vez do MessageBox() nativo, rígido e sem tema |
| Retorno | Síncrono: of_show() bloqueia e devolve o índice do botão clicado |
Ao contrário dos componentes visuais, este objeto não se insere numa janela: cria-se, configura-se, apresenta-se, destrói-se.
// Variaveis locais
n_pbt_messagebox lnv_mb
// Criar o objeto de dialogo
lnv_mb = create n_pbt_messagebox
// ... configuracao ...
// Libertar o objeto de dialogo
destroy lnv_mb
Início rápido #
// Variaveis locais
n_pbt_messagebox lnv_mb
// Criar o objeto de dialogo
lnv_mb = create n_pbt_messagebox
// Configurar a caixa
lnv_mb.is_title = "Eliminação"
lnv_mb.is_icon = lnv_mb.ICON_WARNING
lnv_mb.is_message = "Eliminar definitivamente [b]12 processos[/b]?[br][br]Esta ação é irreversível."
// Adicionar os botoes
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 em modal e agir sobre o primeiro botao
if lnv_mb.of_show(/*hwnd*/ Handle(this)) = 1 then
of_delete()
end if
// Libertar o objeto de dialogo
destroy lnv_mb
of_show aguarda a resposta do utilizador: a linha seguinte só é executada após o clique, exatamente como acontece com MessageBox().
Propriedades #
A definir antes de of_show.
| Propriedade | Tipo | Predefinição | Função |
|---|---|---|---|
is_title | string | "" | Título apresentado no cabeçalho da caixa |
is_message | string | "" | Corpo da mensagem. Aceita o texto formatado com etiquetas ([b], [i], [br], [accent], [picture=…]…). O texto da mensagem e da instrução pode ser selecionado e copiado. Um valor que vem dos seus dados passa primeiro por of_escape_markup: caso contrário, um parêntese reto seria lido como uma etiqueta — um [action=x] no nome de um cliente fecharia a caixa |
is_instruction | string | "" | Instrução principal: a pergunta em si, apresentada maior acima da mensagem. Título / instrução / mensagem é a anatomia que torna um diálogo legível de relance — «Eliminar 42 linhas?» e depois «Esta ação é definitiva» — em vez de um bloco uniforme. Aceita a marcação |
is_icon | string | "" | Ícone: uma constante ICON_*, ou a sua própria imagem (caminho de ficheiro, ou recurso de DLL minha.dll:NOME) |
is_checkbox | string | "" | Texto de uma caixa de verificação opcional, do género «não voltar a perguntar» ("" = sem caixa) |
ib_checked | boolean | false | Estado inicial da caixa (o estado final lê-se com of_checked()) |
ib_input | boolean | false | Acrescenta um campo de entrada com o tema aplicado (mudar o nome, motivo, comentário), para que uma aplicação já não precise de uma janela feita à mão que não segue nem o tema nem o sentido de leitura. Relê-se com of_input_value() após of_show. Tudo numa chamada: of_prompt |
is_input_label | string | "" | Etiqueta por cima do campo ("" = nenhuma). Requer ib_input |
is_input_value | string | "" | Conteúdo inicial do campo. Está selecionado na abertura: escrever substitui-o, como em qualquer diálogo de mudança de nome |
is_input_placeholder | string | "" | Indicação apresentada enquanto o campo estiver vazio. Não é um valor: se o utilizador nada escrever, nada é devolvido |
ib_input_password | boolean | false | Oculta os carateres escritos |
ib_input_required | boolean | false | O botão predefinido mantém-se desativado enquanto o campo estiver vazio. Deixar submeter para depois repreender não serve a ninguém; o botão de cancelar continua acessível. Uma contagem decrescente nesse botão (of_add_button_timed) não o clica enquanto o campo estiver vazio: esgota-se e o botão espera por uma mão. Um botão ao mesmo tempo predefinido e de cancelamento também fica fora de alcance: Esc e Alt+F4 fecham então a caixa sem escolha (0) |
ib_buttons_reverse | boolean | false | Ordem dos botões: false = da esquerda para a direita, pela ordem de adição; true = invertida |
ib_movable | boolean | true | A caixa pode ser movida? Não tem barra de título — pinta o seu próprio cartão — por isso o Windows não tem pega sobre ela: damos-lhe uma, o cartão arrasta a janela exceto o que já responde a um clique e o texto da mensagem, que se pode selecionar. Verdadeira por omissão, porque uma modal que tapa exatamente aquilo que é preciso ler para responder é uma armadilha. Coloque-a a falso para uma caixa que deve ficar onde está |
is_position | string | POSITION_OWNER | Centragem: POSITION_OWNER (na janela chamadora) ou POSITION_SCREEN (no ecrã) |
il_min_width | long | 0 | Largura mínima em píxeis (0 = automática, 320); nunca abaixo de 200 |
il_max_width | long | 0 | Largura máxima em píxeis (0 = automática): o texto muda de linha dentro deste limite; nunca abaixo de 200 |
il_max_height | long | 0 | Altura máxima em píxeis (0 = automática): para além disso, o corpo da mensagem desloca-se em vez de aumentar a janela |
il_accent | long | -1 | Cor de destaque desta caixa: o botão predefinido e a caixa de seleção adotam-na, e a cor de texto legível deriva dela. -1 (a predefinição) segue a aplicação. Um erro a vermelho, um sucesso a verde, sem tocar no tema |
Constantes #
| Constante | Valor | Utilização |
|---|---|---|
ICON_INFORMATION | "information" | Informação neutra |
ICON_WARNING | "warning" | Aviso, ação arriscada |
ICON_ERROR | "error" | Falha, erro |
ICON_QUESTION | "question" | Questão fechada |
ICON_SUCCESS | "success" | Confirmação de um êxito |
ICON_NONE | "none" | Nenhum ícone |
POSITION_OWNER | "owner" | Centrada na janela chamadora |
POSITION_SCREEN | "screen" | Centrada no ecrã |
Métodos #
| Método | Função | |
|---|---|---|
of_add_button (string as_text) → long | Adiciona um botão simples. Devolve o respetivo índice a partir de 1 | |
of_add_button (string as_text, boolean ab_default, boolean ab_cancel) → long | O mesmo, marcando o botão predefinido (Enter) e/ou de cancelamento (Esc). Devolve o seu índice, a partir de 1 | |
of_add_button (string as_text, string as_icon, boolean ab_default, boolean ab_cancel) → long | O mesmo, com um ícone no botão. Devolve o seu í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) → long | Botão com contagem decrescente: permanece desativado durante al_enable_secs segundos (contador visível) e depois clica-se sozinho ao fim de al_click_secs segundos (0 = temporizador inativo). Enquanto um botão de cancelamento ainda estiver em contagem decrescente, nem Esc nem Alt+F4 fecham a caixa: a espera serve para obrigar a ler. Devolve o seu índice, a partir de 1 | |
of_count ( ) → long | Devolve o número de botões que a caixa carrega. Designam-se pela sua posição — a que of_add_button devolve e a que of_show devolve — pelo que não têm chave: aqui não há of_keys_at nem of_has | |
of_show (long al_hwnd) → long | Apresenta a caixa modal e devolve o índice do botão clicado (0 = fecho por Esc ou Alt+F4, sem botão de cancelamento). Um valor negativo indica que nenhuma caixa pôde ser apresentada: -4, ou -6 se faltar o runtime WebView2 — of_get_last_error() diz porquê. Se a janela proprietária fechar enquanto a caixa está aberta (um temporizador, um evento), a caixa desaparece com ela e of_show devolve 0 | |
of_get_last_error ( ) → string | Porque é que a última caixa não pôde abrir — cadeia vazia se abriu. Lê-se após um of_show (ou um atalho como of_info) que devolveu um valor negativo, ou após um of_choose ou um of_prompt que devolveu uma cadeia vazia | |
of_checked ( ) → boolean | Estado da caixa de verificação no momento do último of_show | |
of_input_value ( ) → string | Texto escrito no último of_show (vazio se ib_input estava desativado) | |
of_action ( ) → string | Id da zona [action=id] clicada na mensagem, cadeia vazia caso contrário. Uma zona destas é uma escolha oferecida na própria frase: fecha o diálogo e of_show devolve 0. Já uma zona [hyperlink=url] abre no navegador e deixa o diálogo aberto — quem chamou está bloqueado em of_show, pelo que uma ligação não pode ser uma resposta | |
of_info (long al_hwnd, string as_title, string as_message) → long | Diálogo numa linha, tal como MessageBox() o é: ícone de informação e um único botão OK, devolve 1. As etiquetas vêm das traduções da biblioteca (6 idiomas) em vez de serem escritas em cada aplicação — é toda a razão de ser destes atalhos (negativo: nenhuma caixa apresentada, ver of_get_last_error) | |
of_warning (long al_hwnd, string as_title, string as_message) → long | Ícone de aviso, um botão OK. Devolve 1 (negativo: nenhuma caixa apresentada, ver of_get_last_error) | |
of_error (long al_hwnd, string as_title, string as_message) → long | Ícone de erro, um botão OK. Devolve 1 (negativo: nenhuma caixa apresentada, ver of_get_last_error) | |
of_success (long al_hwnd, string as_title, string as_message) → long | Ícone de êxito, um botão OK. Devolve 1 (negativo: nenhuma caixa apresentada, ver of_get_last_error) | |
of_confirm (long al_hwnd, string as_title, string as_message) → long | Pergunta + OK / Cancelar. Devolve 1 = OK, 2 = Cancelar, 0 = fechado (negativo: nenhuma caixa apresentada, ver of_get_last_error) | |
of_yes_no (long al_hwnd, string as_title, string as_message) → long | Pergunta + Sim / Não. Devolve 1 = Sim, 2 = Não, 0 = fechado (negativo: nenhuma caixa apresentada, ver of_get_last_error) | |
of_yes_no_cancel (long al_hwnd, string as_title, string as_message) → long | Pergunta + Sim / Não / Cancelar. Devolve 1, 2, 3, ou 0 se fechado (negativo: nenhuma caixa apresentada, ver of_get_last_error) | |
of_add_choice (string as_key, string as_title, string as_description) → long | Adiciona uma escolha sob a mensagem — um título e uma descrição, como as ligações de comando de uma caixa de tarefas do Windows. O clique fecha a caixa e of_action() dá a sua chave (of_show devolve 0). Devolve a posição da escolha (1 para a primeira), -5 com uma chave vazia, já usada ou que contém / ou ` | ` — nada é então adicionado |
of_choose (long al_hwnd) → string | Mostra as escolhas com um único botão Cancelar (traduzido) e devolve a chave da escolha clicada, ou uma cadeia vazia se o utilizador cancelou. A lista desloca-se quando ultrapassa o ecrã. Cadeia vazia também quando nenhuma caixa pôde ser apresentada: of_get_last_error diz então porquê. Sem nenhuma escolha, nada é apresentado: cadeia vazia, e of_get_last_error diz «no choice to show» | |
of_prompt (long al_hwnd, string as_title, string as_message, string as_default) → string | Pede um valor e devolve o que foi escrito, ou uma cadeia vazia se o utilizador cancelou. Para distinguir uma resposta vazia de um cancelamento, use of_show + of_input_value. Cadeia vazia também quando nenhuma caixa pôde ser apresentada: of_get_last_error diz então porquê | |
of_reset ( ) | Limpa todas as propriedades e os botões adicionados: a mesma instância recomeça do zero |
A etiqueta de um botão aceita o texto formatado com etiquetas e o mnemónico & ("&Guardar" sublinha o G e ativa-o com Alt+G); && apresenta um E comercial literal.
O teclado #
| Tecla | Efeito |
|---|---|
| Enter | Aciona o botão marcado como predefinido |
| Esc | Aciona o botão marcado como cancelamento; sem botão de cancelamento, fecha a caixa e devolve 0. Alt+F4 faz o mesmo. Enquanto o botão de cancelamento ainda estiver em contagem decrescente (of_add_button_timed), nenhum dos dois fecha |
| Alt + letra | Aciona o botão cuja etiqueta contém esse mnemónico |
| Tab | Desloca o foco de um botão para outro |
| Ctrl + C | Copia o diálogo (título, instrução, mensagem, escolhas com a sua descrição, caixa de seleção com o seu estado [x] ou [ ], etiquetas dos botões) para a área de transferência, como qualquer caixa de diálogo do Windows — prático quando um erro tem de ser encaminhado para o suporte. Com texto selecionado na mensagem, copia apenas a seleção |
Na abertura, nenhum botão tem contorno de foco: é intencional e corresponde ao comportamento das caixas de diálogo modernas do Windows. O contorno só aparece após uma primeira pressão em Tab, ou seja, quando o utilizador passa explicitamente para o teclado. Enter e Esc permanecem ativos desde o primeiro segundo, mesmo sem foco visível.
Exemplos #
Questão fechada com botão predefinido #
// Variaveis locais
n_pbt_messagebox lnv_mb
long ll_answer
// Criar o objeto de dialogo
lnv_mb = create n_pbt_messagebox
// Configurar a caixa
lnv_mb.is_title = "Guardar as alterações"
lnv_mb.is_icon = lnv_mb.ICON_QUESTION
lnv_mb.is_message = "O processo foi modificado. Pretende guardar antes de fechar?"
// Adicionar os botoes
lnv_mb.of_add_button(/*text*/ "&Guardar", /*default*/ true, /*cancel*/ false) // 1
lnv_mb.of_add_button(/*text*/ "&Não guardar", /*default*/ false, /*cancel*/ false) // 2
lnv_mb.of_add_button(/*text*/ "Cancelar", /*default*/ false, /*cancel*/ true) // 3
// Mostrar em modal e depois libertar o objeto de dialogo
ll_answer = lnv_mb.of_show(/*hwnd*/ Handle(this))
destroy lnv_mb
// Agir conforme o botao clicado (posicao a partir de 1)
choose case ll_answer
case 1 ; of_save() ; Close(parent)
case 2 ; Close(parent)
case else ; // 3 ou 0: nao se fecha
end choose
Mensagem enriquecida e ícone #
// Configurar a caixa
lnv_mb.is_title = "Importação concluída"
lnv_mb.is_icon = lnv_mb.ICON_SUCCESS
lnv_mb.is_message = "[b]1 240 linhas[/b] integradas.[br][br]" &
+ "[accent]18 duplicados[/accent] foram ignorados."
// Adicionar o botao e depois mostrar a caixa
lnv_mb.of_add_button(/*text*/ "OK", /*default*/ true, /*cancel*/ false)
lnv_mb.of_show(/*hwnd*/ Handle(this))
Um valor dos seus dados na mensagem #
A mensagem é texto formatado: um parêntese reto é uma etiqueta. O nome de um cliente, um texto escrito por um utilizador passam por of_escape_markup (de n_pbt_utils) antes de entrar — caso contrário «Silva [action=x]» fecharia a caixa como uma escolha.
// 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))
Caixa «não voltar a perguntar» #
// Variaveis locais
n_pbt_messagebox lnv_mb
// Criar o objeto de dialogo
lnv_mb = create n_pbt_messagebox
// Configurar a caixa
lnv_mb.is_title = "Eliminação"
lnv_mb.is_icon = lnv_mb.ICON_WARNING
lnv_mb.is_message = "Eliminar as linhas selecionadas? Esta ação é irreversível."
lnv_mb.is_checkbox = "Não voltar a perguntar"
lnv_mb.ib_checked = false
// Adicionar os botoes
lnv_mb.of_add_button(/*text*/ "Eliminar", /*default*/ true, /*cancel*/ false)
lnv_mb.of_add_button(/*text*/ "Cancelar", /*default*/ false, /*cancel*/ true)
// Mostrar em modal e agir sobre o primeiro botao
if lnv_mb.of_show(/*hwnd*/ Handle(this)) = 1 then
of_delete()
// Memorizar a escolha do utilizador
ib_confirm_delete = not lnv_mb.of_checked()
end if
// Libertar o objeto de dialogo
destroy lnv_mb
Botão com contagem decrescente #
// Configurar a caixa
lnv_mb.is_title = "Reinício"
lnv_mb.is_icon = lnv_mb.ICON_INFORMATION
lnv_mb.is_message = "A aplicação vai reiniciar para aplicar a atualização."
// "Continuar" permanece esbatido durante 3 segundos (e apresentado um contador)
lnv_mb.of_add_button_timed(/*text*/ "Continuar", /*default*/ true, /*cancel*/ false, /*enable_secs*/ 3, /*click_secs*/ 0)
// "Mais tarde" clica-se sozinho ao fim de 10 segundos
lnv_mb.of_add_button_timed(/*text*/ "Mais tarde", /*default*/ false, /*cancel*/ true, /*enable_secs*/ 0, /*click_secs*/ 10)
// Mostrar em modal
lnv_mb.of_show(/*hwnd*/ Handle(this))
Mensagem longa: limitar o tamanho #
// Um texto volumoso: a caixa e limitada e o corpo desloca-se
lnv_mb.is_title = "Notas de versão"
lnv_mb.is_message = ls_notes
lnv_mb.il_max_width = 480
lnv_mb.il_max_height = 320
// Adicionar o botao e depois mostrar a caixa
lnv_mb.of_add_button(/*text*/ "Fechar", /*default*/ true, /*cancel*/ true)
lnv_mb.of_show(/*hwnd*/ Handle(this))
Reutilizar uma instância #
// Uma instancia de janela, varios dialogos: of_reset entre cada chamada
inv_mb.of_reset() // limpa as propriedades E os botoes anteriores
// Configurar a nova caixa e depois mostra-la
inv_mb.is_title = "Segundo diálogo"
inv_mb.is_message = "Cada of_reset recomeça a partir de uma caixa vazia."
inv_mb.of_add_button(/*text*/ "OK", /*default*/ true, /*cancel*/ false)
inv_mb.of_show(/*hwnd*/ Handle(this))
Boas práticas #
- Chamar sempre
of_reset()antes de reconfigurar uma instância reutilizada: sem isso, os botões do diálogo anterior somam-se aos novos. - Marque sistematicamente um botão predefinido e um botão de cancelamento: o utilizador que trabalha com o teclado espera Enter e Esc.
- Teste o valor de retorno
0: significa que a caixa foi fechada sem escolha (cruz ou Esc). Trate-o como o cancelamento. - Passe
Handle(this)(ouHandle(parent)) como janela chamadora: a caixa centra-se sobre ela e a modalidade aplica-se à janela correta. - Reserve o vermelho e
ICON_ERRORpara os erros verdadeiros; uma confirmação banal mereceICON_QUESTION. - Para uma informação que não exige qualquer resposta, é preferível uma notificação não bloqueante: ver toaster.