PBToolboxAI v5 ← Site

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 #

Userobjectu_pbt_pdfviewer
Classe de items— (componente sem items)
Serve paraApresentar 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 #

PropriedadeTipoPredefiniçãoFunção
is_sourcestring""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_pageinteger0Pá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_zoominteger0Zoom 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_fitstring""Ajuste: FIT_PAGE, FIT_WIDTH, FIT_HEIGHT, ou "" para nenhum. Anula ii_zoom
ib_viewer_toolbarbooleantrueApresenta 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_panebooleanfalseAbre 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_destinationstring""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_findstring""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_savebooleantrueOferece 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_printbooleantrueOferece 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_searchbooleantrueOferece 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_rotatebooleantrueOferece 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_fullscreenbooleantrueOferece 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_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 ( )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 #

EventoAcionado 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.

ConstanteValorCausa
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çãoComo
PaginaçãoRoda do rato e barra de deslocamento, ou introdução direta do número de página no contador n / total
ZoomBotões + / −, ajuste à página ou à largura
PesquisaO botão de pesquisa da barra de ferramentas, no texto do documento
ImpressãoBotão de impressora da barra de ferramentas (pode ser ocultado com ib_allow_print), ou of_print a partir do seu código
GravaçãoBotão de transferência, para guardar uma cópia do documento (pode ser ocultado com ib_allow_save)
RotaçãoRotação das páginas a partir do menu da barra de ferramentas
TecladoAssim 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_sourceExemploObservaçã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 #

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
is_accessible_name · is_accessible_descriptionO nome e a descrição que um leitor de ecrã diz3.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.


← Referência dos componentes · Índice do guia