6. Funcionalidades transversais #
← Idioma e RTL · Índice · FAQ →
Este capítulo reúne os serviços disponíveis seja qual for o componente: tooltips, alojamento de controlos PowerBuilder, arrastar e largar a partir do Explorador, focus de teclado, exportação de imagem e os objetos utilitários não visuais.
6.1 Tooltips simples e enriquecidos #
Tooltip do componente #
uo_button.is_tooltip = "Guardar o processo (Ctrl+S)"
O texto aceita a formatação com etiquetas: [b], [br], [color=…], [picture=…]…
Super tooltip (título + texto + imagem) #
Para uma ajuda contextual ao estilo do friso do Office:
uo_button.is_super_tooltip_title = "Guardar"
uo_button.is_super_tooltip_text = "Escreve as alterações no servidor." &
+ "[br][br][size-=15]Atalho: Ctrl+S[/size-=15]"
uo_button.is_super_tooltip_image = "img\help_save.png"
As três propriedades são independentes: um título isolado, ou um título + texto sem imagem, são válidos. Assim que uma propriedade is_super_tooltip_* é definida, prevalece sobre is_tooltip.
Tooltip de um item #
Todas as classes de item (n_pbt_item e os seus descendentes) possuem as mesmas quatro propriedades:
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 sincronização às 09:12"
Comportamento #
- O tooltip é uma janela nativa com tema, idêntica em todos os componentes (não está limitada pelas fronteiras do webview).
- Não é apresentado se a aplicação não tiver o focus: passar o rato sobre uma window em segundo plano não desencadeia nada.
- Desaparece ao mudar para outra aplicação e, o mais tardar, ao fim de 10 segundos.
of_reset()elimina os tooltips definidos na instância e nos seus items.
6.2 Alojar controlos reais do PowerBuilder #
Os componentes contentores não apresentam HTML em vez dos ecrãs da aplicação: acolhem verdadeiros controlos PowerBuilder (userobjects, DataWindows, grupos de controlos), reparentados como janelas Win32 filhas. Os ecrãs existentes são reutilizados tal como estão.
// Separadores: cada pagina e um userobject PB
uo_tab.of_add_page(/*key*/ "clients", /*title*/ "Clientes", /*page*/ uo_page_clients)
uo_tab.of_add_page(/*key*/ "invoices", /*title*/ "Faturas", /*page*/ uo_page_invoices, /*closable*/ true)
// Paineis acoplaveis: idem
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*/ "Propriedades", /*content*/ uo_props)
O que é assegurado pela biblioteca:
- o posicionamento e o redimensionamento do controlo alojado quando o separador ou o painel muda de tamanho;
- a apresentação / ocultação na mudança de separador ou de painel ativo;
- os painéis flutuantes, acoplados ou ocultados automaticamente (dockcontainer);
- a destruição correta ao fechar a window.
⚠️ Um controlo alojado é uma janela nativa: desenha-se por cima da camada web. Isso é intencional (a DataWindow mantém-se nítida e rápida), mas significa que nenhum efeito web — sombra, transparência, animação — pode passar por cima dele.
6.3 Receber ficheiros a partir do Explorador do Windows #
Um componente pode tornar-se alvo de largada para ficheiros arrastados a partir do Explorador. A biblioteca instala um alvo de largada nativo: são recebidos os caminhos completos, o que uma largada HTML não permite.
uo_editor.ib_allow_drop = true
// event ue_drop_files de uo_editor: (string as_files[])
long ll_i
for ll_i = 1 to UpperBound(as_files)
of_open_file(as_files[ll_i])
next
| Evento | Acionado quando |
|---|---|
ue_drag_enter ( ) | Um arrastamento de ficheiros entra no componente |
ue_drag_leave ( ) | Sai sem largar |
ue_drop_files (string as_files[]) | Os ficheiros são largados — caminhos completos |
O próprio componente fornece o retorno visual de passagem (realce da zona de largada). Publicado pelos componentes onde a largada faz sentido: statictext, codeeditor.
6.4 Teclado e focus #
Um componente PBToolboxAI participa na navegação por teclado da window como um controlo nativo:
- a tecla Tab alcança-o na ordem de tabulação da window;
- as teclas (setas, Enter, Escape, introdução) são tratadas pelo componente que tem o focus;
- os atalhos de window (Enter = botão predefinido, Escape = cancelar) continuam a funcionar mesmo quando o focus está num componente.
Para dar explicitamente o focus ao conteúdo de um componente (por exemplo, depois de abrir um painel de pesquisa):
uo_editor.of_focus_webview()
6.5 Exportar a representação como imagem #
Recordatório da base comum: qualquer componente é exportado tal como está apresentado.
uo_tiles.of_save_as_png(/*path*/ "C:\temp\accueil.png")
uo_tiles.of_save_as_jpg(/*path*/ "C:\temp\accueil.jpg")
Útil para anexar um ecrã a uma mensagem de correio eletrónico, alimentar um relatório ou registar um incidente do utilizador.
6.6 Caixas de diálogo e notificações #
Dois serviços sem controlo a colocar na window:
// Caixa de dialogo modal com tema (retorno sincrono)
n_pbt_messagebox lnv_mb
lnv_mb = create n_pbt_messagebox
lnv_mb.is_title = "Eliminação"
lnv_mb.is_message = "Eliminar definitivamente [b]12 processos[/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
// Notificacao "toast" no canto do ecra, nao bloqueante
n_pbt_toaster lnv_toast
lnv_toast = create n_pbt_toaster
lnv_toast.is_title = "Importação concluída"
lnv_toast.is_text = "1 240 linhas integradas."
lnv_toast.is_kind = lnv_toast.KIND_SUCCESS
lnv_toast.of_show()
destroy lnv_toast
Detalhes completos: messagebox e toaster.
6.7 Objetos utilitários não visuais #
Fornecidos na mesma PBL, sem webview nem representação: são simples invólucros em torno da DLL. Devem ser criados, utilizados e destruídos.
Base64, hashes, identificadores — n_pbt_crypto #
O base64 (texto ou ficheiro), os hashes SHA e os identificadores únicos vivem no componente crypto: of_base64_encode, of_base64_encode_file, of_sha256, of_hash_file, of_uuid… Uma só página para tudo o que calcula sem mostrar nada.
Expressões regulares — u_pbt_regex #
Sintaxe ECMAScript, ausente do PowerScript.
Sem uma chave que o cubra, u_pbt_regex funciona em modo demo: o texto analisado tem no máximo 2048 caracteres; acima disso, a chamada falha e is_last_error indica-o. Para que a chave da sua aplicação se aplique, defina ipo_owner no objeto que o utiliza (lnv_re.ipo_owner = this), como para crypto.
u_pbt_regex lnv_re
string ls_found[]
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 | Função |
|---|---|
of_is_match (motivo, texto [, ab_ignore_case | al_flags]) | O texto corresponde? |
of_match (motivo, texto, ai_groupe [, al_flags]) | Primeira correspondência (0 = tudo, 1.. = grupo de captura) |
of_match_all (motivo, texto [, ai_groupe, al_flags], ref as_res[]) | Todas as correspondências; devolve o número |
of_replace (motivo, texto, substituição) | Substitui todas as ocorrências ($1… permitidos) |
Opções combináveis: FLAG_IGNORE_CASE (1), FLAG_SINGLELINE (2, o . atravessa as mudanças de linha).
Arquivos ZIP — u_pbt_zip #
u_pbt_zip lnv_zip
lnv_zip = create u_pbt_zip
lnv_zip.of_compress(/*zip*/ "C:\temp\livraison.zip", /*src*/ "C:\appli\export") // ficheiro OU pasta
lnv_zip.of_extract(/*zip*/ "C:\temp\livraison.zip", /*dest*/ "C:\appli\import") // pasta criada se ausente
destroy lnv_zip
Ambos os métodos devolvem um boolean.
Sem uma chave que o cubra, u_pbt_zip funciona em modo demo: o que comprime (um ficheiro ou uma pasta, no total) e o arquivo que extrai têm no máximo 2048 bytes; acima disso, o método devolve false e is_last_error indica-o. Defina ipo_owner no objeto que o utiliza (lnv_zip.ipo_owner = this) para que a chave da sua aplicação se aplique.
6.8 Informações sobre a biblioteca #
// Versao da DLL: um long, maior x 10000 + menor x 100 + correcao
long ll_version
ll_version = PBT_GetVersion() // 40000 = 4.00.00
| Função global | Função |
|---|---|
PBT_GetVersion ( ) → long | Versão da biblioteca: 40000 = 4.00.00 (maior × 10000 + menor × 100 + correção) |
PBT_CheckRuntime (ref string, long) | Versão do runtime WebView2 instalado (≤ 0 = ausente) |
PBT_GetLastErrorMessage (ref string, long) | Última mensagem de erro do processo |
PBT_LicenseStatus ( ) | Estado da licença — ver Licença |
6.9 Imprimir #
Qualquer componente sabe imprimir-se, tal como é apresentado, sem DataWindow intermédia.
// Silencioso: um PDF em disco, nada para clicar
uo_grid.of_print_to_pdf(/*path*/ "C:\etats\ventes.pdf")
// Horizontal, para uma grelha larga
uo_grid.of_print_to_pdf(/*path*/ "C:\etats\ventes.pdf", /*landscape*/ true)
// Com caixa de dialogo: o utilizador escolhe a impressora e ve a pre-visualizacao
uo_grid.of_print()
// Diretamente a caixa de dialogo de impressao do sistema
uo_grid.of_print(/*system_dialog*/ /*dialogue systeme*/ true)
| Método | Função |
|---|---|
of_print_to_pdf (string as_path) · of_print_to_pdf (string, boolean ab_landscape) | Escreve um PDF sem apresentar nada. Só devolve o controlo depois de o ficheiro estar escrito (0 = feito) |
of_print ( ) · of_print (boolean ab_system_dialog) | Abre a caixa de diálogo de impressão. Devolve o controlo assim que a caixa está aberta: o que o utilizador fizer com ela é consigo |
⚠️ Imprime-se o que está RENDERIZADO. Uma grelha virtualizada só imprime as linhas que detém: para um relatório completo, passe primeiro por uma disposição que as apresente todas (paginação), ou exporte os dados em vez da representação.
O código de retorno -6 indica um runtime WebView2 demasiado antigo para imprimir (1.0.1108 para o PDF, 1.0.1587 para a caixa de diálogo). Todo o resto segue os códigos de retorno comuns.