PBToolboxAI v4 ← Site

webbrowser — u_pbt_webbrowser #

← Referência dos componentes · Índice do guia

Navegador web integrado na janela: apresentação de uma página, barra de endereço, histórico Anterior / Seguinte, menu de contexto de navegação.

▶ Ver ao vivo — Aplicação de demonstração, mosaico Web browser: a pré-visualização, o código que o produz e esta página, lado a lado.


Em resumo #

Userobjectu_pbt_webbrowser
Classe de items— (componente sem items)
Serve paraApresentar uma página web, um portal interno, documentação em linha ou conteúdo HTML gerado, sem sair da aplicação

Início rápido #

// event open da janela
uo_browser.ib_address_bar = true    // barra de endereco + botoes de navegacao
uo_browser.is_address = "https://pt.wikipedia.org/wiki/PowerBuilder"

Atribuir is_address é o ato de navegação: cada atribuição abre a página pedida. Um endereço sem protocolo ("exemplo.com") recebe automaticamente https://. Um caminho de disco (C:\pasta\pagina.html, \\servidor\partilha\pagina.html) torna-se um endereço file:///. Palavras que não são um endereço ("fatura 2026") vão para o motor de pesquisa de is_search_url; sem motor, são recusadas e ue_error indica-o. Um nome de servidor de uma só palavra seguido de /, ? ou # (office/, intranet/inicio) é um endereço, tal como um endereço IPv6 entre parênteses retos ([::1]/x); a palavra sozinha (intranet) continua a ser texto livre. Um servidor sem HTTPS escreve-se com http:// explícito.


Propriedades #

PropriedadeTipoPredefiniçãoFunção
is_addressstring""Endereço apresentado. Atribuir esta propriedade inicia a navegação. Relê-la devolve a página realmente apresentada: se o utilizador seguir uma ligação ou recuar, ela acompanha (ue_load_completed avisa-o). Esquemas aceites: http(s):, file: (também um caminho de disco), about:, data:, mailto:, tel:; javascript: é recusado
ib_address_barbooleanfalseApresenta a barra de endereço integrada: campo URL, botões Anterior / Seguinte / Recarregar
ib_context_menubooleanfalseAtiva o menu de contexto no clique direito: Anterior, Seguinte, Recarregar, mais Copiar sobre uma seleção, Abrir link e Copiar endereço do link sobre um link, Copiar imagem sobre uma imagem. Aberto pelo teclado (Shift+F10), aparece sobre o elemento. Num campo de entrada mantém-se o menu Cortar / Copiar / Colar
is_search_urlstring""Motor de pesquisa para palavras que não são um endereço, %s = o texto codificado (ex. https://www.bing.com/search?q=%s). Vazio por omissão: esse texto é recusado e ue_error é acionado — uma aplicação de gestão não envia o que os utilizadores escrevem a um motor que não escolheu. Só é aceite um endereço http(s) que contenha %s: qualquer outro lança ue_error e o motor em vigor mantém-se
ib_veto_new_windowbooleanfalsePergunta a ue_new_window antes de abrir uma nova janela na vista; devolver false mantém a página atual
ib_veto_downloadsbooleanfalsePergunta a ue_download_starting antes de cada transferência; devolver false cancela-a
ib_veto_navigationbooleanfalsePergunta a ue_navigating antes de o site passar para outra página (link, formulário, script); devolver false mantém a página atual. Uma página autorizada é reaberta no endereço pedido: um formulário enviado por POST perde os seus dados
ib_privatebooleanfalseNavegação privada: cookies, armazenamento e cache dos sites nunca são escritos no disco e desaparecem com a vista. Deve ser definida antes de is_address: alterá-la reabre a vista vazia (sem página nem histórico); voltar a pô-la a true abre uma sessão privada nova
is_titlestring""Título da página apresentada, lido em direto (ue_title_changed avisa quando muda). Só de leitura: escrevê-lo não altera nada
is_theme_stylestring""Estilo visual do componente (constantes THEME_STYLE_*); vazio = o da aplicação, seguido a cada mudança
is_theme_modestring""Variante clara ou escura (constantes THEME_MODE_*); vazio = a da aplicação, seguida a cada mudança
il_theme_accentlong-1Cor de destaque deste componente (-1 = destaque da aplicação, ou o do tema)

Métodos #

MétodoFunção
of_refresh ( )Recarrega a página atual. Devolve 0 uma vez pedido, -4 se nenhuma página estiver apresentada (is_address vazio), -2 se o componente não estiver criado
of_go_back ( )Volta à página anterior. Segue a ordem do seu código: is_address e depois of_go_back() são executados por essa ordem
of_go_forward ( )Avança para a página seguinte
of_can_go_back ( ) → booleantrue se existir uma página anterior — para ativar ou inativar o botão Anterior. Lido em direto na página; leia-o após um carregamento (ue_load_completed)
of_can_go_forward ( ) → booleantrue se existir uma página seguinte
of_stop ( )Interrompe o carregamento em curso e abandona as páginas ainda em espera; o carregamento interrompido aciona ue_load_failed
of_execute_javascript (string as_script)Executa um script na página apresentada e devolve o seu valor em JSON: um texto volta entre aspas, um número não (42), um script que lança um erro ou não devolve nada dá null. Uma resposta longa volta inteira. Uma só condição, e é estrutural: a página tem de estar carregada, portanto chame-a a partir de ue_load_completed, nunca logo após definir is_address. Devolve uma cadeia vazia se ainda não houver página ou sem resposta em 5 segundos: of_get_last_error() diz porquê
of_show_html (string as_html) → longApresenta uma página construída pela aplicação (uma fatura, uma carta). A página é codificada: uma cor #c00, uma âncora, um % ou um acento aparecem tal como escritos. No máximo 2 MB depois de codificada: acima disso, ue_error e nada muda. Devolve 0 uma vez enviado, -2 se o componente não estiver criado
of_clear_browsing_data ( ) → longApaga o que os sites guardaram: cookies (uma sessão iniciada), armazenamento local, cache, permissões concedidas. A limpeza ocupa o seu lugar depois dos endereços já definidos: a página seguinte abre-se limpa. Todos os webbrowser da aplicação partilham estes dados. Devolve 0 uma vez enviado, -2 se o componente não estiver criado
of_reset ( )Repõe o componente: página esvaziada, histórico de navegação apagado, barra de endereço oculta, menu de contexto desativado, motor de pesquisa esvaziado, perguntas (ib_veto_*) desativadas, navegação privada desligada. Os cookies e sessões dos sites mantêm-se: para isso existe of_clear_browsing_data. Devolve 0 uma vez aplicado, -2 se o componente não estiver criado
of_save_as_png (string) · of_save_as_jpg (string)Exporta o site apresentado como imagem. Devolve 0 depois de a imagem ser escrita, -4 se a escrita falhar, -2 se o componente não estiver criado

Eventos #

EventoAcionado quando
ue_load_completed (string as_url)Uma página terminou de carregar (a sua, uma ligação, Anterior, of_refresh); as_url é o endereço efetivamente atingido, redirecionamentos incluídos. Não acionado para um endereço vazio (about:blank) nem para um carregamento falhado
ue_load_failed (string as_url, long al_status)Uma página não pôde ser carregada: anfitrião desconhecido, sem rede, certificado, ou carregamento cancelado por of_stop ou por um endereço mais recente. al_status indica o motivo: ver Porque é que uma página não carregou
ue_error (string as_message)Um texto definido em is_address (ou escrito na barra) não é um endereço e não há is_search_url, um endereço não pôde de todo ser aberto, ou o processo da página parou. Nada mais fica retido: o endereço seguinte carrega normalmente
ue_new_window (string as_url) → booleanA página pede uma nova janela após um clique (ligação target=_blank, window.open): abre-se nesta vista. Cancelável se ib_veto_new_window = true: devolver false mantém a página atual. Uma janela aberta só por um script, sem clique, é ignorada. Só se abrem endereços http e https: um site que peça um ficheiro, uma página data: ou um link de correio recebe ue_error. Uma ligação file: numa página web (http, https, data:) é recusada pelo próprio motor, antes do componente: nada se abre e nenhum evento é lançado
ue_download_starting (string as_url, string as_path) → booleanUma transferência está a começar: as_url é o que é transferido, as_path o ficheiro que será escrito. Cancelável se ib_veto_downloads = true: devolver false cancela-a; caso contrário continua como no Edge
ue_navigating (string as_url) → booleanO site passa para outra página: um link, um formulário, um script — nunca um endereço definido pela aplicação. Cancelável se ib_veto_navigation = true: devolver false mantém a página atual
ue_title_changed (string as_title)O título da página apresentada mudou (is_title volta a lê-lo a qualquer momento)
ue_permission_requested (string as_url, string as_kind) → booleanO site pede a câmara, o microfone, a localização… (as_kind = uma constante PERMISSION_*). Recusado a menos que o event devolva true: a única pergunta da biblioteca em que o silêncio vale NÃO
ue_ready ( )O componente terminou o carregamento; tudo o que foi enviado antes foi reproduzido
ue_runtime_missing ( )O runtime WebView2 está ausente: o componente permanece vazio
ue_bg_color (long al_color)O componente calculou a cor de fundo do respetivo tema; o userobject já a adotou (backcolor)
ue_script_error (string as_message, string as_stack)Ocorreu um erro de JavaScript na barra de endereço do componente (nunca no site apresentado)

A barra de endereço integrada #

É a solução mais rápida: uma propriedade e o utilizador dispõe de um campo URL e dos botões Anterior / Seguinte / Recarregar, com o tema do resto da aplicação.

// A barra de enderecos, depois a pagina a abrir
uo_browser.ib_address_bar = true
uo_browser.is_address = "https://pt.wikipedia.org/wiki/PowerBuilder"

Os botões ficam inativos automaticamente quando não há para onde ir. No campo de endereço, F5 (ou Ctrl+R) recarrega, Alt+← / Alt+→ recuam e avançam (invertidos na escrita da direita para a esquerda), Esc repõe o endereço atual depois de uma escrita abandonada, e o primeiro clique seleciona todo o endereço.

Botões próprios #

Se preferir comandar a navegação a partir de uma barra de ferramentas própria, deve ocultar-se a barra integrada e utilizar os métodos:

// Botoes Anterior / Seguinte da sua janela
uo_browser.of_go_back()
uo_browser.of_go_forward()
// event ue_load_completed de uo_browser : (string as_url)
// Atualizar o estado dos seus botoes apos cada pagina
uo_toolbar.of_item(/*keys*/ "main/back").ib_enabled = uo_browser.of_can_go_back()
uo_toolbar.of_item(/*keys*/ "main/forward").ib_enabled   = uo_browser.of_can_go_forward()

// E refletir o endereco real (incluindo redirecionamentos)
sle_url.text = as_url

O menu de contexto de navegação #

ib_context_menu acrescenta ao clique direito um pequeno menu Anterior / Seguinte / Recarregar, com tema e desenhado pela aplicação. Segue o que está sob o rato: Copiar sobre um texto selecionado, Abrir link e Copiar endereço do link sobre um link, Copiar imagem sobre uma imagem. Aberto pelo teclado (Shift+F10, tecla Menu), aparece sobre o elemento. Partilha exatamente o mesmo histórico que a barra de endereço: ambos permanecem, por isso, sempre coerentes.

// A small menu on a right click : back, forward, refresh
uo_browser.ib_context_menu = true

Parar um carregamento #

// Botao Parar : interrompe uma pagina que demora
uo_browser.of_stop()

Palavras em vez de um endereço #

Por omissão, um texto que não é um endereço é recusado (ue_error), sem reter nada: o endereço seguinte carrega normalmente. Para o transformar numa pesquisa, escolha o motor:

// Words typed in the address bar go to this engine (%s = the text)
uo_browser.is_search_url = "https://www.bing.com/search?q=%s"
uo_browser.is_address = "PowerBuilder WebView2"

Novas janelas e transferências #

Uma ligação «abrir num novo separador» ou uma janela de início de sessão aberta após um clique aparece na vista, e ue_new_window indica-o. Uma transferência continua como no Edge, e ue_download_starting dá-lhe o endereço e o ficheiro. Ambos se tornam uma pergunta quando o pede:

// Ask before each download
uo_browser.ib_veto_downloads = true
// ue_download_starting event of uo_browser : (string as_url, string as_path)
// Only PDF files may be downloaded
return Lower(Right(as_path, 4)) = ".pdf"

Ficar nos seus próprios servidores #

ue_navigating é lançado sempre que o site passa para outra página — um link, um formulário, um script —, nunca para um endereço definido pelo seu código. Com ib_veto_navigation é uma pergunta: devolver false mantém a página atual. Uma página autorizada é reaberta no endereço pedido pelo site; um formulário enviado por POST perde os seus dados.

// Ask before the site leaves for another page
uo_browser.ib_veto_navigation = true
// ue_navigating event of uo_browser : (string as_url)
// Only the company servers may be opened
return Pos(Lower(as_url), "://intranet.example.com/") > 0

Câmara, microfone, localização #

Quando um site pede a câmara, o microfone, a localização, as notificações ou a leitura da área de transferência, é ue_permission_requested que decide, e a resposta por omissão é não: um site não liga uma câmara através de um aviso que o utilizador não compreende. É a única pergunta da biblioteca em que o silêncio vale recusa. Nada é memorizado: a pergunta volta a cada pedido.

// ue_permission_requested event of uo_browser : (string as_url, string as_kind)
// The video-call page of the company may use the camera and the microphone
if Pos(Lower(as_url), "://visio.example.com/") = 0 then return false
return as_kind = uo_browser.PERMISSION_CAMERA or as_kind = uo_browser.PERMISSION_MICROPHONE

Valores de as_kind: PERMISSION_CAMERA, PERMISSION_MICROPHONE, PERMISSION_GEOLOCATION, PERMISSION_NOTIFICATIONS, PERMISSION_CLIPBOARD, PERMISSION_SENSORS, PERMISSION_DOWNLOADS (várias transferências seguidas), PERMISSION_FILES, PERMISSION_AUTOPLAY, PERMISSION_FONTS, PERMISSION_MIDI, PERMISSION_WINDOWS, PERMISSION_UNKNOWN.

Porque é que uma página não carregou #

al_status de ue_load_failed compara-se com as constantes LOADSTATUS_* do componente:

ConstanteSignifica
LOADSTATUS_HOST_NOT_RESOLVEDAnfitrião desconhecido (nome mal escrito, DNS)
LOADSTATUS_DISCONNECTED · LOADSTATUS_CANNOT_CONNECT · LOADSTATUS_SERVER_UNREACHABLESem rede, servidor inacessível
LOADSTATUS_TIMEOUTO servidor não respondeu a tempo
LOADSTATUS_CERT_INVALID · LOADSTATUS_CERT_EXPIRED · LOADSTATUS_CERT_NAME_INCORRECT · LOADSTATUS_CERT_REVOKED · LOADSTATUS_CLIENT_CERT_ERRORCertificado recusado
LOADSTATUS_CANCELEDCarregamento cancelado por of_stop ou por um endereço mais recente
LOADSTATUS_AUTH_REQUIRED · LOADSTATUS_PROXY_AUTH_REQUIREDCredenciais pedidas (servidor, proxy)
LOADSTATUS_CONNECTION_ABORTED · LOADSTATUS_CONNECTION_RESET · LOADSTATUS_INVALID_RESPONSE · LOADSTATUS_REDIRECT_FAILED · LOADSTATUS_UNEXPECTED_ERROR · LOADSTATUS_UNKNOWNOutras falhas de ligação ou de resposta
// ue_load_failed event of uo_browser : (string as_url, long al_status)
if al_status = uo_browser.LOADSTATUS_HOST_NOT_RESOLVED then
	st_message.text = "Unknown address : " + as_url
end if

Executar um script na página #

of_execute_javascript lê ou altera a página apresentada (o título, um campo, um contador). Não é limitado pela licença, mesmo numa página about:blank ou data:: executar um script na página é o trabalho de um navegador, e o componente é gratuito.

// ue_load_completed event of uo_browser : (string as_url)
// The page title, as JSON : "PowerBuilder - Wikipedia" (quotes included)
sle_title.text = uo_browser.of_execute_javascript(/*script*/ "document.title")

Sites que recusam a apresentação integrada #

Alguns sites — Google, a maioria dos bancos, muitas aplicações SaaS — enviam cabeçalhos de segurança que proíbem a sua apresentação dentro de outra página. O componente não é afetado: nunca apresenta um site numa moldura. A página é aberta como documento principal, exatamente como faz o seu próprio navegador, e esses cabeçalhos deixam de se aplicar.

Não há, portanto, nada a definir nem qualquer caso particular a tratar no seu código.

// Um site que recusa ser integrado numa pagina : nada de especial a fazer
uo_browser.ib_address_bar = true
uo_browser.is_address = "https://www.google.com"

Em contrapartida, a página ocupa toda a superfície do componente sob a barra de endereço: aquilo que desenhasse por cima (faixas, sobreposições com tema) não é visível durante a navegação.


Conteúdo HTML sem rede #

of_show_html apresenta uma página HTML construída pela aplicação: a pré-visualização de uma carta, de um ticket, de uma fatura ou de um relatório, sem qualquer chamada de rede nem ficheiro temporário. A página é codificada por si: uma cor #c00, uma âncora, um % ou um acento aparecem tal como escritos (no máximo 2 MB).

// Local variables
string ls_html

// An order summary built by the application : the colour and the "%" come out as written
ls_html = "<html><body>" &
        + "<h1 style='color:#1f6feb'>Order #4152</h1>" &
        + "<p>Discount : 10%</p>" &
        + "</body></html>"
uo_browser.of_show_html(/*html*/ ls_html)

Definido diretamente em is_address, um endereço data:text/html, não é codificado: um # corta ali a página (tudo o que se segue passa por uma âncora) e um % baralha-a. Prefira of_show_html, ou codifique por si (# → %23, % → %25).

Um ficheiro local abre-se da mesma forma com file:///C:/temp/relatorio.html, ou simplesmente com o seu caminho C:\temp\relatorio.html.


Recomeçar do zero #

of_reset() não se limita a esvaziar a página: apaga também o histórico de navegação. Assim, um utilizador não pode regressar, através do botão Anterior, a uma página consultada pelo utilizador anterior ou noutro dossiê. Não toca no que os sites guardaram: cookies, sessões iniciadas, armazenamento local, permissões. Num posto partilhado, o utilizador seguinte chegaria com a sessão do anterior — é of_clear_browsing_data() que a apaga. Os sites vivem num perfil de navegação próprio, separado dos componentes da aplicação.

// Mudanca de dossie : recomeca-se com um navegador virgem, sem historico
uo_browser.of_reset()

// Depois o dossie, com a sua barra de enderecos
uo_browser.ib_address_bar = true
uo_browser.is_address = ls_folder_url
// The user of the workstation changes : no page, no history, no signed-in session left
uo_browser.of_reset()
uo_browser.of_clear_browsing_data()

Para que nada seja alguma vez escrito no disco, defina ib_private = true antes do primeiro endereço: cookies e armazenamento desaparecem com a vista.

É o reflexo a ter sempre que um mesmo componente serve para apresentar conteúdos de contextos diferentes.


Exemplo completo #

// event open da janela : pagina inicial do portal interno
uo_browser.of_reset()                  // recomecar limpo (incluindo o historico)

// As ferramentas de navegacao, depois a pagina inicial
uo_browser.ib_address_bar  = true      // campo URL + Anterior / Seguinte / Recarregar
uo_browser.ib_context_menu = true      // mesma navegacao com o clique direito
uo_browser.is_address = "https://intranet.empresa.pt/inicio"
// event ue_load_completed de uo_browser : (string as_url)
uo_status.of_panel(/*key*/ "main").is_text = "Página carregada: " + as_url

Boas práticas #

Herdado da base comum #

Estes membros existem em todos os componentes visuais — não são próprios deste. São detalhados uma só vez, nos capítulos transversais; esta tabela apenas diz onde os ler.

MembrosFunçãoDetalhado em
of_resetRepor o componente a zero3.6 Repor um componente a zero: of_reset()
of_register_shortcut · of_clear_shortcutsAtalhos de teclado do componente3.5 Os atalhos de teclado
of_is_created · of_is_ready · of_get_last_errorSe nasceu, se está pronto, o que falhou3.7 Diagnóstico
of_save_as_png · of_save_as_jpgExportar a renderização como imagem3.8 Exportar a representação como imagem
of_set_redrawAgrupar as alterações num único repinte3.10 Boas práticas
of_preload_iconsÍcones mostrados sem atrasoApresentação instantânea: of_icon
of_set_translationTraduzir uma legenda do componente5.2 Adaptar uma etiqueta: of_set_translation
of_focus_webviewDar o foco ao componente6.4 Teclado e focus
of_print · of_print_to_pdfImprimir, ou escrever um PDF6.9 Imprimir
of_set_property · of_get_property · of_component_nameControlar uma propriedade pelo nome3.1 O motor de propriedades

Duas ajudas não são herdadas: of_icon e of_escape_markup vivem em n_pbt_utils. Declare um — n_pbt_utils lnv_utils, nada a criar — e chame-as nele.


← Referência dos componentes · Índice do guia