pdfviewer — u_pbt_pdfviewer #
← Referência dos componentes · Índice do guia
Visualizador de PDF integrado: apresenta um documento local ou publicado na web, diretamente na janela da aplicação, com paginação, zoom e impressão.
▶ Ver ao vivo — Aplicação de demonstração, mosaico PDF viewer: a pré-visualização, o código que o produz e esta página, lado a lado.
Em resumo #
| Userobject | u_pbt_pdfviewer |
| Classe de items | — (componente sem items) |
| Serve para | Apresentar uma fatura, uma nota de encomenda, um contrato ou um manual sem iniciar qualquer aplicação externa |
| Opções opt-in | — |
O componente substitui o clássico «gravar o PDF num ficheiro temporário e depois chamar ShellExecute»: o documento permanece dentro da aplicação e o utilizador nunca sai do ecrã em curso.
Início rápido #
// event open da janela : apresentar um documento presente no disco
uo_pdf.is_source = "C:\factures\FA-2026-0142.pdf"
// event ue_load_completed de uo_pdf : (string as_source)
uo_status.of_panel(/*key*/ "main").is_text = "Documento apresentado"
É tudo: basta definir is_source para carregar e apresentar o documento.
Propriedades #
| Propriedade | Tipo | Predefinição | Função |
|---|---|---|---|
is_source | string | "" | Documento a apresentar: um caminho de ficheiro (absoluto, relativo à aplicação ou de rede; um # faz parte do nome), um endereço file:///, um endereço web https://… servido como application/pdf, ou um endereço data:application/pdf. Definir o valor inicia o carregamento; definir "" (ou apenas espaços) esvazia o visualizador e mantém as suas definições. Tudo o resto é recusado e assinalado por ue_load_failed — incluindo http:// e um endereço com nome de utilizador e palavra-passe (https://nome:segredo@…). Um PDF guardado num blob apresenta-se com of_load_blob. Relê-se tal como o escreveu |
ii_page | integer | 0 | Página de abertura, contada a partir de 1 (0 = a primeira página do documento). Definida enquanto um documento é apresentado, é a página desse documento: volta a carregar, aberto nela. Definida com o visualizador vazio, vale para o documento seguinte; caso contrário, um novo documento abre na sua primeira página. Para abrir um documento numa página, defina is_source e depois ii_page: um único carregamento. Cada alteração recarrega o documento e volta a acionar ue_load_completed: o leitor só lê a página no carregamento; o mesmo valor definido de novo não faz nada. Só de escrita: relê-la devolve a última página pedida, não a apresentada. O leitor é o do motor web e não comunica nada. |
ii_zoom | integer | 0 | Zoom em percentagem, de 25 a 500 — o intervalo dos botões do leitor (0 = deixado ao visualizador). Um valor fora desse intervalo é trazido para dentro dele e relê-se tal como foi aplicado. Definir um zoom anula is_fit, que o contradiz. Só de escrita, como ii_page: se o utilizador fizer zoom com a barra do leitor, esta propriedade não acompanha. |
is_fit | string | "" | Ajuste: FIT_PAGE, FIT_WIDTH, FIT_HEIGHT, ou "" para nenhum. Anula ii_zoom |
ib_viewer_toolbar | boolean | true | Apresenta a barra do próprio leitor (número de página, zoom, impressão, transferência). Oculte-a quando a sua janela tiver esses comandos |
ib_navigation_pane | boolean | false | Abre o painel lateral do leitor: as miniaturas das páginas e os marcadores do documento. O painel vem com a barra do leitor. Cada alteração recarrega o documento apresentado |
is_destination | string | "" | Abre o documento num destino com nome do PDF — o destino de um marcador, escrito pela ferramenta que produziu o ficheiro. "" para nenhum; um nome que o documento não tem abre-o na primeira página. Mantém-se para os documentos seguintes até o alterar. Cada alteração recarrega o documento apresentado |
is_find | string | "" | Um texto do documento, realçado onde aparece pela primeira vez, com o leitor a deslocar-se até ele: a linha de uma fatura de que a sua aplicação fala. "" para nenhum; um texto que o documento não contém não altera nada. Não é uma pesquisa conduzida por código (nem contagem, nem ocorrência seguinte): o utilizador pesquisa com a barra do leitor. Mantém-se para os documentos seguintes até o alterar. Cada alteração recarrega o documento apresentado |
ib_allow_save | boolean | true | Oferece os comandos Guardar e Guardar como da barra do leitor e do seu menu. A false, o documento é apresentado sem propor guardar uma cópia. Cada visualizador mantém a sua própria definição: a de outra janela não altera nada aqui. Não é uma proteção: o ficheiro continua legível no disco. Cada alteração recarrega o documento apresentado; definido antes de is_source, o documento carrega uma única vez |
ib_allow_print | boolean | true | Oferece o comando Imprimir da barra do leitor e do seu menu. of_print continua a imprimir: é a sua aplicação que decide. Cada visualizador mantém a sua própria definição. Cada alteração recarrega o documento apresentado; definido antes de is_source, o documento carrega uma única vez |
ib_allow_search | boolean | true | Oferece o comando Procurar da barra do leitor. is_find continua a realçar um texto: é a sua aplicação que decide. Cada visualizador mantém a sua própria definição. Cada alteração recarrega o documento no ecrã; definida antes de is_source, o documento carrega uma só vez |
ib_allow_rotate | boolean | true | Oferece o comando Rodar da barra do leitor. Cada visualizador mantém a sua própria definição. Cada alteração recarrega o documento no ecrã; definida antes de is_source, o documento carrega uma só vez |
ib_allow_fullscreen | boolean | true | Oferece o comando Ecrã inteiro da barra do leitor. Cada visualizador mantém a sua própria definição. Cada alteração recarrega o documento no ecrã; definida antes de is_source, o documento carrega uma só vez |
is_theme_style | string | "" | Estilo visual do componente (constantes THEME_STYLE_*); vazio = o da aplicação, seguido a cada mudança |
is_theme_mode | string | "" | Variante clara ou escura (constantes THEME_MODE_*); vazio = a da aplicação, seguida a cada mudança |
il_theme_accent | long | -1 | Cor de destaque deste componente (-1 = destaque da aplicação, ou o do tema) |
Métodos #
| Método | Função |
|---|---|
of_refresh ( ) | Volta a ler o documento atual (do disco ou da rede) sem alterar as definições: o meio de apresentar um ficheiro regenerado no mesmo caminho. A posição de deslocamento não é conservada: o leitor recomeça em ii_page. Após uma falha, volta a tentar o mesmo documento. Um documento recusado é julgado de novo: ue_load_failed é novamente acionado. Devolve 0 uma vez pedido, -4 sem documento (is_source vazio), -2 se o componente não estiver criado |
of_load_blob (blob ablb_pdf) · of_load_blob (blob ablb_pdf, string as_name) | Apresenta um PDF guardado num blob — lido da base de dados (SELECTBLOB) ou recebido de um serviço — sem escrever ficheiro, seja qual for o tamanho: os bytes ficam em memória e só são servidos a este visualizador. O segundo argumento é o nome que is_source e ue_load_completed / ue_load_failed devolvem (document.pdf sem ele). O blob apresentado antes é libertado; este, pelo documento seguinte ou por of_reset. Devolve 0 uma vez pedido (segue-se ue_load_completed), -5 se o blob estiver vazio ou não for um PDF, -4 se for demasiado grande para este processo (64 MB em 32 bits, 512 MB em 64 bits) — of_get_last_error diz porquê —, -2 se o componente não estiver criado |
of_print ( ) · of_print (boolean) | Abre a pré-visualização de impressão do documento — não da página que o enquadra. Devolve 0 depois de pedida a pré-visualização, -4 quando nenhum documento está apresentado, -2 se o componente não estiver criado. O argumento não tem efeito aqui: é sempre a pré-visualização do leitor PDF |
of_print_to_pdf (string) · of_print_to_pdf (string, boolean) | Devolve -4 neste componente, sem escrever nada: a página impressa seria apenas a moldura do leitor, nunca o documento. O documento já é um PDF: copie o ficheiro de is_source |
of_reset ( ) | Esvazia o visualizador e repõe todas as propriedades nos respetivos valores predefinidos. Devolve 0 depois de aplicado, -2 se o componente não estiver criado |
of_set_redraw (boolean) | Agrupa uma sequência de modificações numa única representação. Devolve 0 depois de aplicado, -2 se o componente não estiver criado |
of_save_as_png (string) · of_save_as_jpg (string) | Exporta a representação como imagem. Devolve 0 depois de a imagem ser escrita, -4 se a escrita falhar, -2 se o componente não estiver criado |
Eventos #
| Evento | Acionado quando |
|---|---|
ue_load_completed (string as_source) | O documento está no ecrã; as_source é is_source tal como o escreveu (para um blob, o nome dado a of_load_blob). Também acionado por of_refresh e por cada alteração de página, zoom, ajuste, barra do leitor, painel, destino, texto realçado, ib_allow_save ou ib_allow_print — defina-os antes de is_source para um único carregamento; o mesmo valor definido de novo não o aciona. Nunca acionado numa falha |
ue_load_failed (string as_source, string as_reason) | Não foi possível apresentar o documento; as_reason é uma das constantes REASON_* abaixo. O visualizador permanece vazio |
ue_link_clicked (string as_url) | O utilizador seguiu uma ligação do documento. O visualizador permanece no documento: abra as_url onde pretender (navegador do posto, webbrowser…). as_url é o endereço da ligação tal como está (https://…, mailto:…); uma ligação relativa de um documento local chega como caminho em disco. Uma ligação para um ficheiro local do posto (file:///) num PDF não é seguida: o leitor de PDF do WebView2 bloqueia-a; nenhum ue_link_clicked é acionado |
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) |
Porque é que um documento não é apresentado #
as_reason de ue_load_failed é uma destas constantes de u_pbt_pdfviewer. Um PDF reconhece-se assim: um ficheiro local tem a extensão .pdf e começa pela assinatura %PDF-; um documento remoto é servido com o tipo application/pdf (o único que o motor entrega ao seu leitor); um endereço data: anuncia application/pdf.
| Constante | Valor | Causa |
|---|---|---|
REASON_NOT_FOUND | "notfound" | Ficheiro ausente ou ilegível, endereço que responde 404 |
REASON_NOT_PDF | "notpdf" | Não é um PDF: ficheiro local sem a assinatura %PDF-, resposta remota que não é application/pdf (um servidor de ficheiros que responde application/octet-stream: descarregue primeiro o documento, ver os exemplos), data: ou blob de outro tipo |
REASON_TOO_LARGE | "toolarge" | Ficheiro demasiado grande para este processo (acima de 64 MB em 32 bits, 512 MB em 64 bits), ou um endereço data: com mais de 2 MB de caracteres (cerca de 1,5 MB de PDF) |
REASON_INSECURE | "insecure" | http://: não suportado, sirva o documento em https:// |
REASON_UNSUPPORTED | "unsupported" | Outro tipo de endereço (ftp:, blob:…), ou um endereço com nome de utilizador e palavra-passe (https://nome:segredo@…) |
REASON_NETWORK | "network" | Servidor inacessível, nome desconhecido, ligação cortada |
REASON_CERTIFICATE | "certificate" | Certificado do site inválido, expirado ou revogado |
REASON_AUTH | "auth" | O site ou o proxy pede uma autenticação: descarregue o documento com o restclient (token, credenciais) e depois apresente-o (ver os exemplos) |
REASON_HTTP | "http" | Outro erro do servidor (403, 500…) |
REASON_REFUSED | "refused" | O site recusa ser apresentado numa moldura, ou envia o PDF como transferência — o ficheiro não é transferido por isso |
REASON_FAILED | "failed" | Qualquer outra causa |
O que o utilizador pode fazer, sem uma linha de código #
O visualizador apresenta a sua barra de ferramentas integrada por cima do documento. Não é necessário programar nada: ela é fornecida e localizada pelo sistema.
| Ação | Como |
|---|---|
| Paginação | Roda do rato e barra de deslocamento, ou introdução direta do número de página no contador n / total |
| Zoom | Botões + / −, ajuste à página ou à largura |
| Pesquisa | O botão de pesquisa da barra de ferramentas, no texto do documento |
| Impressão | Botão de impressora da barra de ferramentas (pode ser ocultado com ib_allow_print), ou of_print a partir do seu código |
| Gravação | Botão de transferência, para guardar uma cópia do documento (pode ser ocultado com ib_allow_save) |
| Rotação | Rotação das páginas a partir do menu da barra de ferramentas |
| Teclado | Assim que o componente tem o foco (Tab ou of_focus_webview): PageDown, as setas, Home / End deslocam o documento, sem clique prévio |
Os atalhos do navegador — Ctrl+F, Ctrl+P, Ctrl + roda do rato — estão desativados em todos os componentes, este incluído: use os botões da barra do leitor.
O que o leitor não diz #
O leitor é o integrado no motor web: nada a instalar, impressão, pesquisa, formulários PDF e ecrã inteiro incluídos. Em contrapartida, não comunica nada à sua aplicação: nem a página apresentada, nem o número de páginas, nem o zoom real, nem o texto selecionado, e a pesquisa não se conduz por código (is_find realça um texto na abertura, nada mais). ii_page e ii_zoom dizem onde abrir o documento, não onde o utilizador está. Um PDF protegido por palavra-passe: o leitor pede-a ele próprio ao utilizador, a sua aplicação não a pode fornecer. É uma escolha deliberada; uma apresentação programável exigiria uma biblioteca externa.
Exemplos #
Abrir um documento local #
// Caminho absoluto, ou relativo ao diretorio da aplicacao
uo_pdf.is_source = "doc\conditions-generales.pdf"
Abrir um documento publicado na web #
// Um endereco web carrega-se exatamente como um ficheiro local
uo_pdf.is_source = "https://www.monsite.fr/tarifs/catalogue-2026.pdf"
É evidentemente necessária uma ligação à internet; o carregamento é assíncrono e ue_load_completed assinala o fim.
Apresentar o PDF acabado de produzir por uma DataWindow #
// Local variables
string ls_file
// Um ficheiro por dia, na pasta temporaria
ls_file = "C:\temp\report_" + String(Today(), "yyyymmdd") + ".pdf"
// A DataWindow produz o ficheiro...
dw_report.SaveAs(ls_file, PDF!, false)
// ...e o visualizador apresenta-o imediatamente
uo_pdf.is_source = ls_file
Atualizar após a regeneração do ficheiro #
// O ficheiro foi reescrito no mesmo local : recarregar sem alterar is_source
uo_pdf.of_refresh()
Encadear vários documentos no mesmo visualizador #
// event rowfocuschanged de dw_list : (long currentrow)
// Local variables
string ls_pdf
// O caminho do PDF da linha atual
ls_pdf = dw_list.GetItemString(currentrow, "pdf_path")
// Sem anexo o visualizador esvazia-se (definicoes mantidas) ; caso contrario mostra-o
if ls_pdf = "" then
uo_pdf.is_source = ""
else
uo_pdf.is_source = ls_pdf
end if
Acompanhar o fim do carregamento #
// event ue_load_completed de uo_pdf : (string as_source)
uo_wait.Hide()
// of_print imprime o documento apresentado
uo_print_button.ib_enabled = true
Dizer porque é que o documento não está lá #
// event ue_load_failed de uo_pdf : (string as_source, string as_reason)
uo_wait.Hide()
choose case as_reason
case uo_pdf.REASON_NOT_FOUND
uo_status.of_panel(/*key*/ "main").is_text = "Documento nao encontrado: " + as_source
case uo_pdf.REASON_NOT_PDF
uo_status.of_panel(/*key*/ "main").is_text = "Este ficheiro nao e um PDF"
case else
uo_status.of_panel(/*key*/ "main").is_text = "Documento indisponivel (" + as_reason + ")"
end choose
Abrir noutro lado uma ligação do documento #
// event ue_link_clicked de uo_pdf : (string as_url)
// O visualizador permanece no documento : a ligacao abre no navegador da janela
uo_web.is_address = as_url
Imprimir o documento #
// clicked do botao Imprimir : a pre-visualizacao do leitor PDF, sobre o proprio documento
if uo_pdf.of_print() = -4 then
uo_status.of_panel(/*key*/ "main").is_text = "Nenhum documento para imprimir"
end if
Mostrar sem deixar guardar nem imprimir #
// Um documento confidencial : nem Guardar nem Imprimir na barra do leitor
uo_pdf.ib_allow_save = false
uo_pdf.ib_allow_print = false
uo_pdf.is_source = is_current_document
Defina-os antes de is_source: o documento carrega uma única vez. Cada visualizador mantém a sua própria definição. Não é uma proteção: o ficheiro continua legível no disco, e of_print continua a imprimir.
Pré-visualização num separador, ao lado da introdução de dados #
// event open : o visualizador ocupa uma pagina de separador, a introducao de dados a outra
uo_tab.of_add_page(/*key*/ "entry", /*title*/ "Introducao", /*page*/ uo_page_entry)
uo_tab.of_add_page(/*key*/ "preview", /*title*/ "Previsao", /*page*/ uo_page_preview)
// O visualizador esta colocado em uo_page_preview como qualquer outro controlo
uo_pdf.is_source = is_current_document
O componente aloja-se sem qualquer precaução especial num tab ou num painel dockcontainer.
Verificar o ficheiro antes de o apresentar #
// Local variables
string ls_path
// O ficheiro da fatura apresentada
ls_path = "C:\factures\" + is_number + ".pdf"
// Sem ficheiro, nada a mostrar : esvazia-se o visualizador em vez de deixar o documento anterior
if not FileExists(ls_path) then
uo_pdf.is_source = ""
uo_status.of_panel(/*key*/ "main").is_text = "Fatura nao encontrada"
return
end if
// Caso contrario, a fatura e apresentada
uo_pdf.is_source = ls_path
Apresentar um PDF lido da base de dados (blob) #
// Local variables
blob lblb_pdf
// A fatura guardada na base de dados, lida num blob
SELECTBLOB pdf_file INTO :lblb_pdf FROM invoice WHERE invoice_no = :is_number USING SQLCA;
// Apresentada diretamente a partir da memoria : nenhum ficheiro temporario, seja qual for o tamanho
if SQLCA.SQLCode = 0 then
uo_pdf.of_load_blob(/*pdf*/ lblb_pdf, /*name*/ "invoice-" + is_number + ".pdf")
end if
O nome dado volta em is_source e em ue_load_completed; o blob é libertado pelo documento seguinte ou por of_reset.
Mostrar uma linha precisa do documento #
// O leitor abre na primeira passagem deste texto, realcada
uo_pdf.is_find = "Delivery and assembly"
uo_pdf.is_source = "C:\factures\FA-2026-0142.pdf"
Abrir num capítulo, marcadores visíveis #
// O painel lateral e os seus marcadores, aberto no capitulo "prices" do catalogo
uo_pdf.ib_navigation_pane = true
uo_pdf.is_destination = "prices"
uo_pdf.is_source = "doc\catalogue-2026.pdf"
O nome de um destino é o que a ferramenta que produziu o PDF escreveu: o seu gerador de documentos conhece-o.
Um documento atrás de um token, ou servido como octet-stream #
// Local variables
long ll_status
string ls_file
// O restclient (inv_rest, preparado na abertura da janela) envia o token e descarrega o ficheiro
ls_file = "C:\temp\invoice-4152.pdf"
ll_status = inv_rest.of_download(/*url*/ "/orders/4152/invoice.pdf", /*path*/ ls_file)
// Depois o visualizador apresenta o ficheiro, seja qual for o tipo anunciado pelo servidor
if ll_status = 200 then
uo_pdf.is_source = ls_file
end if
O leitor do motor não sabe enviar um token nem apresentar uma resposta application/octet-stream (REASON_AUTH, REASON_NOT_PDF): o restclient fá-lo por ele.
Formatos e caminhos aceites #
Forma de is_source | Exemplo | Observação |
|---|---|---|
| Caminho absoluto | "C:\docs\contrat.pdf" | O mais fiável |
| Caminho relativo | "doc\notice.pdf" | Relativo ao diretório da aplicação |
| Caminho de rede | "\\serveur\partage\bon.pdf" | O utilizador tem de possuir direitos de leitura |
Nome com # | "C:\devis\Devis #12.pdf" | O # faz parte do nome do ficheiro |
Endereço file: | "file:///C:/docs/contrat.pdf" | Convertido em caminho, como um caminho absoluto; também file://localhost/C:/… e a forma UNC de quatro barras file:////servidor/partilha/… |
| Endereço web | "https://…/catalogue.pdf" | Servido como application/pdf, carregamento assíncrono. Um #page=… escrito no endereço é ignorado: use ii_page. Um endereço com credenciais (https://nome:segredo@…) é recusado (REASON_UNSUPPORTED): passe pelo restclient |
| Documento em memória | "data:application/pdf;base64,…" | Nada é escrito no disco. Acima de 2 MB de caracteres (cerca de 1,5 MB de PDF), ue_load_failed com REASON_TOO_LARGE: para um documento em memória maior, of_load_blob |
Endereço http:// | "http://intranet/bon.pdf" | Não suportado: ue_load_failed com REASON_INSECURE. Sirva o documento em https:// |
| Vazio | "" | Esvazia o visualizador e mantém as suas definições; um valor feito de espaços também |
Apenas o PDF é suportado por este componente: o resto é recusado e assinalado por ue_load_failed (REASON_NOT_PDF). Para uma imagem, deve utilizar-se picture; para uma página HTML, webbrowser.
Boas práticas #
- Vigiar
ue_load_failed: um caminho inválido, um ficheiro que não é um PDF ou um site inacessível é aí assinalado com a sua causa, e o visualizador permanece vazio. - Para esvaziar o visualizador (mudança de linha sem anexo), defina
is_source = "": caso contrário, o documento anterior permanece visível.of_reset()também o esvazia, mas além disso repõe todas as definições no seu valor por omissão — Guardar e Imprimir incluídos. of_refresh()é o meio de apresentar um ficheiro regenerado no mesmo caminho: volta a ler o ficheiro sem alterar as definições. Não conserva a posição de deslocamento — o leitor recomeça emii_page.- Cada alteração de
ii_zoom,is_fit,ib_viewer_toolbar,ib_navigation_pane,is_destination,is_find,ib_allow_saveouib_allow_printrecarrega o documento (o leitor só lê as suas definições no carregamento) e volta a acionarue_load_completed: defina-os antes deis_sourcepara um único carregamento. O mesmo valor definido de novo não recarrega nada.ii_pagedefinido enquanto um documento é apresentado vale para esse documento: para abrir outro numa página, definais_sourcee depoisii_page. - Prever um indicador de espera para os documentos remotos ou volumosos, e ocultá-lo em
ue_load_completede emue_load_failed. - Atribuir ao componente uma superfície confortável (pelo menos metade da janela): a barra de ferramentas integrada e o documento precisam de espaço para permanecerem legíveis.
- Para apresentar uma página web em vez de um PDF, deve utilizar-se webbrowser; para uma imagem, picture.
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.
| Membros | Função | Detalhado em |
|---|---|---|
of_reset | Repor o componente a zero | 3.6 Repor um componente a zero: of_reset() |
of_register_shortcut · of_clear_shortcuts | Atalhos de teclado do componente | 3.5 Os atalhos de teclado |
of_is_created · of_is_ready · of_get_last_error | Se nasceu, se está pronto, o que falhou | 3.7 Diagnóstico |
of_save_as_png · of_save_as_jpg | Exportar a renderização como imagem | 3.8 Exportar a representação como imagem |
of_set_redraw | Agrupar as alterações num único repinte | 3.10 Boas práticas |
of_preload_icons | Ícones mostrados sem atraso | Apresentação instantânea: of_icon |
of_set_translation | Traduzir uma legenda do componente | 5.2 Adaptar uma etiqueta: of_set_translation |
of_focus_webview | Dar o foco ao componente | 6.4 Teclado e focus |
of_print · of_print_to_pdf | Imprimir, ou escrever um PDF | 6.9 Imprimir |
of_set_property · of_get_property · of_component_name | Controlar uma propriedade pelo nome | 3.1 O motor de propriedades |
is_accessible_name · is_accessible_description | O nome e a descrição que um leitor de ecrã diz | 3.4 Propriedades e eventos opcionais |
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.