PBToolboxAI v4 ← Site

11. Migrar da 3.0 para a 4.0 #

← Migrar da 2.0 para a 3.0 · Índice · Notas de versão →


A 4.0 retira dois métodos dos trinta e dois componentes da 3.0 — of_set_data da tabela cruzada, renomeado of_from_datastore (11.33), e of_transform de n_pbt_xml, que sai com o XSLT (11.31) — e muda assinaturas que o compilador lhe mostra linha a linha: três propriedades renomeadas (id_minimum e id_maximum da barra de progresso, 11.6; il_doc_line do editor de código, 11.28), argumentos de evento acrescentados ou renomeados (ue_tile_moved, 11.6; ue_failed do cliente REST, 11.6, e do vídeo, 11.26; ue_error da imagem, 11.25; ue_cell_double_clicked, 11.33; ue_closed da paleta de comandos, 11.36; ue_toast_clicked, ue_toast_action e ue_toast_dismissed do toaster, 11.38), of_count e of_keys_at em long (11.34) e métodos que passam a devolver um código (of_refresh, of_select, of_show, of_scroll_to_end, of_set_header…). A 11.6 alinha ainda duas contagens, um evento e o caminho da árvore JSON com o resto da biblioteca: é aí, com as secções citadas, que há código que compilava a retocar. O que muda concentra-se no friso (ribbon), que foi revisto por completo. Duas mudanças pedem para reler o código: a pergunta colocada antes de um mosaico de galeria (11.1) e os handles libertados por uma remoção (11.2). As outras corrigem comportamentos que pode ter contornado (11.3) — entre eles o clique direito num item, que passa a produzir um só evento em todos os componentes, e o trilho de navegação (breadcrumb), cujos endereços e recusas foram revistos. Seguem-se o gerador n_pbt_menu2ribbon (11.4) e o que foi acrescentado (11.5). A barra lateral (listbar) segue também a regra do 11.1: a sua pergunta antes de uma seleção passa a ser opcional. Os separadores (tab) seguem a mesma regra: as suas duas perguntas, antes de uma mudança de separador e antes de um fecho, passam a ser opcionais (11.1). Por fim, os temas seguem a aplicação (11.7): o destaque da aplicação sobrevive a uma mudança de tema, e um eixo de tema deixado vazio segue o da aplicação. A revisão de segurança de crypto (11.8) fecha uma confusão de algoritmo dos tokens JWT, substitui vários silêncios por uma recusa que diz a sua razão e fixa a regra dos caminhos relativos dos ficheiros.

A revisão completa de 28/09/2026 releu cada componente entregue; o que muda tem uma secção por componente: restclient (11.9), speechout (11.10), statictext e o texto rico (11.11), breadcrumb (11.12), buttonbar e o teclado de janela (11.13), button (11.14), menubar (11.15), ribbon (11.16), toolbar (11.17), statusbar (11.18), dockcontainer (11.19), tab (11.20), listbar (11.21), tilesbox (11.22), stepbar (11.23), progressbar (11.24), picture (11.25), video (11.26), pdfviewer (11.27), codeeditor (11.28), jsontree e xmltree (11.29, 11.30), xml (11.31), json (11.32), crosstab (11.33), shellexplorer (11.35), commandpalette (11.36), radialmenu (11.37), toaster (11.38) e messagebox (11.39); a base comum tem duas secções, 11.34 e 11.40. Uma regra atravessa-as, a do PowerBuilder (SelectTab lança SelectionChanged): uma mudança pedida pelo seu código lança o mesmo evento que um gesto do utilizador, e faz a pergunta do veto se a ativou; o método devolve -4 se recusar. Vale para uma seleção (of_select_*), uma abertura ou um recolhimento (of_expand, of_collapse, of_open), um zoom, um ecrã inteiro, um capítulo; nada é lançado quando nada muda, e of_reset continua em silêncio. Definir um VALOR (uma marca, um texto, um volume, um filtro) continua em silêncio, como SetItem. ue_layout_changed é lançado nos dois casos: diz que uma disposição a guardar mudou.

11.1 As perguntas antes de uma mudança passam a ser opcionais #

Na 3.0 o friso colocava por omissão a pergunta ue_gallery_selection_changing antes de reter um mosaico: ib_veto_gallery valia true. Na 4.0 vale false, como todo o evento cancelável da biblioteca: cada pergunta custa uma ida e volta ao PowerBuilder, e só uma aplicação que responde deve pagá-la. Uma aplicação que não programava o evento não vê nenhuma diferença. Novo: of_select_gallery_item lança ue_gallery_selection_changed como um clique e, com a pergunta ativada, também a faz; uma recusa fá-lo devolver -4, o mosaico não muda.

// 4.0 : the question is only asked on request. If your ue_gallery_selection_changing
// returns false for some tiles, switch it on where the ribbon is built.
uo_ribbon.ib_veto_gallery = true

A receita: procure ue_gallery_selection_changing nos descendentes do friso; onde estiver programado, acrescente ib_veto_gallery = true à construção. Onde escrevia ib_veto_gallery = false para desligar a pergunta, a linha deixa de servir e pode sair.

A barra lateral (listbar): ib_veto_selection #

Mesma regra: na 3.0 a listbar colocava por omissão ue_selection_changing antes de cada mudança de seleção (ib_veto_selection valia true). Na 4.0 vale false. Se programava ue_selection_changing para recusar uma mudança, defina ib_veto_selection = true: sem isso, o evento deixa de ser disparado e a seleção muda sem lhe perguntar. Ativada, a pergunta é feita também para uma seleção pedida pelo seu código (of_select_item, of_clear_selection), como na 3.0; uma recusa faz-lhes agora devolver -4, e a seleção não se move. ue_selection_changed dispara como antes.

// 4.0 : the listbar only asks on request. If your ue_selection_changing
// returns false (unsaved changes), switch the question on where the bar is built.
uo_nav.ib_veto_selection = true

A receita: procure ue_selection_changing nos descendentes de u_pbt_listbar; onde devolver false, acrescente ib_veto_selection = true à construção. Onde escrevia ib_veto_selection = false para desligar a pergunta, a linha deixa de servir e pode sair.

Os separadores (tab): ib_veto_selection e ib_veto_close #

Mesma regra, duas perguntas: na 3.0 o componente tab colocava por omissão ue_selection_changing antes de cada mudança de separador e ue_tab_closing antes de cada fecho (ib_veto_selection e ib_veto_close valiam true). Na 4.0 ambos valem false. Se programava ue_selection_changing ou ue_tab_closing para recusar, defina ib_veto_selection = true ou ib_veto_close = true: sem isso, o evento deixa de ser disparado e o separador muda ou fecha sem lhe perguntar. Ativada, a pergunta é feita também para of_select_page, como na 3.0, mas antes de o separador mudar: uma recusa fá-lo devolver -4 e nada se move; um acordo muda o separador de imediato, ue_selection_changed dispara como antes, e of_selected_key() relido logo a seguir já devolve a nova chave.

// 4.0 : the tab only asks on request. If your ue_selection_changing or
// ue_tab_closing returns false (unsaved changes), switch the questions on.
uo_tabs.ib_veto_selection = true
uo_tabs.ib_veto_close     = true

A receita: procure ue_selection_changing e ue_tab_closing nos descendentes de u_pbt_tab; onde um devolver false, acrescente a linha correspondente à construção. Onde escrevia = false para desligar uma pergunta, a linha deixa de servir e pode sair.

11.2 As adições dizem o que recusam, as remoções libertam os seus handles #

Na 3.0, uma adição que o friso ignorava — uma chave já ocupada, uma entrada de menu sob um simples botão — devolvia na mesma 0, e nada aparecia. Na 4.0 devolve -5, e o código do envio (-2 se o componente não estiver criado) em vez de um 0 fixo. E uma remoção liberta os handles do que sai: uma variável que guardava o handle de um controlo removido deixa de ser válida.

O quê3.04.0
Acrescentar uma chave já ocupada (separador, grupo, controlo)0, ignorada-5
Entrada de menu, escolha de combo ou mosaico sob um controlo de outra natureza0, ignorada-5
of_add_tab, of_insert_tab, of_add_group, of_add_contextual_*, of_add_qat num componente não criado0-2
Um handle guardado após of_remove_tab, of_remove_group, of_remove_item ou of_clearficava em memória até à destruição do frisolibertado: IsValid() devolve false
// 4.0 : after a removal or of_clear, ask the component for the handle again
uo_ribbon.of_clear()
uo_ribbon.of_add_tab(/*key*/ "home", /*title*/ "Home")
uo_ribbon.of_add_group(/*keys*/ "home/clip", /*title*/ "Clipboard")
uo_ribbon.of_add_button(/*keys*/ "home/clip/paste", /*label*/ "Paste", /*image*/ "")
uo_ribbon.of_item(/*keys*/ "home/clip/paste").ib_enabled = false

A receita: não guarde um handle para lá de uma remoção ou de um of_clear — volte a pedi-lo com of_tab, of_group, of_item ou of_menu_item, o que não custa nada. Onde um erro de construção lhe importe, verifique o código devolvido pela adição.

11.3 Outros comportamentos que pode notar #

Quando a janela é estreita, o friso recolhe os grupos num botão que abre um painel. É desse painel que vêm as diferenças mais visíveis:

O quê3.04.0
Botão, ou parte principal de um split, clicado no painel de um grupo recolhidoue_menu_selected("", false)ue_clicked(endereço)
Entrada de menu escolhida nesse painelendereço incompletoendereço completo, cascata incluída
Controlo desativado, ou entrada oculta, nesse painelrespondia / era mostradanão responde / não é mostrada
Split grande reduzido por falta de espaçoum clique só abria o menuduas partes: o comando e a seta do menu
Entrada de menu com a chave do seu controlo (home/clip/paste/paste)ue_clicked("home/clip/paste")ue_menu_selected("home/clip/paste/paste", …)
of_menu_item("…/exp/pdf") quando uma cascata também contém pdfpodia visar …/exp/more/pdfvisa a entrada que o endereço nomeia
as_from_keys de ue_gallery_selection_changed sem mosaico anterioro endereço da galeria""
Reler um handle da barra de acesso rápido, il_color de um seletor de cor, ii_visible_items, is_keytip de um separador, il_color de um grupo contextual, of_count() de uma galeriavazio, -1 ou 0o valor no ecrã
of_keys_at de uma combo"home/font/cb/cb:Arial""home/font/cb/Arial": a chave de uma escolha é a sua etiqueta
of_ctx_group(k).il_color quando um separador também tem a chave kcoloria o separadorcolore apenas o banner
Cores de item (il_back_color…) e is_tooltip de um separador ou de um gruposem efeitoaplicadas; a dica de um grupo aparece no seu título
of_remove_item("save") num botão da barra de acesso rápido-5o botão é removido
of_add_app_menu_separator("saveas/s1")uma linha na raiz do menua linha no submenu de saveas; uma chave sem / não muda
of_clear() enquanto um separador estava ativonenhum eventoue_selection_changed("")
Spinner com passo decimal (0.1)0.300000000000000040.3
Atalho Alt (keytip) num controlo desativado, friso minimizadoo friso ficava abertofecha-se, nada é executado
toolbar: combo, spinner ou galeria desativados no painel do chevronrespondiamnão respondem
Todos: clique direito num item (ue_item_rclicked, ue_panel_rclicked, ue_row_rclicked…)a página enviava também o evento do componente, que nenhum componente com itens transmitia ao PowerBuilderum só evento, o do item; um ue_rclicked de componente, onde existe, só é levantado fora dos itens
Todos: largar ficheiros (ib_allow_drop)ue_drag_leave e depois ue_drop_files; caminhos cortados a 260 caracteressó ue_drop_files, caminhos completos; of_reset retira o destino de largar
breadcrumb: of_path() com um segmento escondido, ou na versão de demonstraçãoas chaves mostradas: o escondido saltado, os primeiros segmentos cortadoso endereço completo do local actual: of_truncate(of_path()) acerta; o campo de escrita parte do mesmo
breadcrumb: of_keys_at(n); of_has("computer/C:")a chave simples; procurava entre os ramos do menuo endereço do segmento; procura entre os segmentos
breadcrumb: ler um handle de endereço profundo, of_item("a/b/c").is_textlia só o último nível: vazio numa chave repetidao segmento desse endereço
breadcrumb: of_truncate, of_remove_item, of_clear_children, of_remove_child num endereço desconhecido ou numa chave simples repetida; of_add_child sob um segmento ausente ou num ramo já ocupado; of_add_item de um endereço que iria parar a outro sítio0, ignorado (ou só a última chave retida)-5
breadcrumb: um handle guardado após of_clear, of_remove_item, of_truncate, of_clear_children ou of_remove_childficava em memórialibertado: IsValid() devolve false
breadcrumb: campo de escrita deixado sem alterações, ou janela mudada (Alt+Tab) durante a escritaue_path_entered levantadonada; o que foi escrito mantém-se ao mudar de janela
breadcrumb: segmento desactivado; Enter num segmentoo seu chevron abria-se e recebia um largar; Enter premia também o botão predefinido da janelatotalmente inerte; Enter só clica no segmento
buttonbar: Enter enquanto outro botão da barra tem o foco do tecladoacionava o botão predefinido (is_default)aciona o botão com o foco, como o Windows; o predefinido é acionado quando nenhum botão da barra tem o foco
buttonbar: botão predefinido ou cancelar desativado ou oculto; is_shortcut de um botão desativado ou ocultoEnter, Esc ou Alt+letra engolidos sem efeito, mesmo num controlo PowerBuilder da janelaa tecla fica com a janela
buttonbar: is_shortcut de várias letras ("Save")Alt+S só funcionava se a barra tivesse o focoAlt+S funciona de qualquer ponto da janela (a primeira letra, como documentado)
buttonbar: of_add_button / of_insert_button numa chave já usada ou que contém / ou uma barra vertical; of_remove_button / of_move_button numa chave desconhecida0, ignorado-5
buttonbar: of_remove_button, of_clear_buttonso atalho Alt+letra, as cores e a tooltip do botão ficavam (um botão recriado com a mesma chave recuperava-os); o handle ficava em memóriasaem com o botão; o handle é libertado: IsValid() devolve false
codeeditor: reler is_text de um texto em CRLFem LF (em CRLF só se o editor estava dobrado): is_text = ls_original era falsocom os finais de linha recebidos, dobrado ou não
codeeditor: reler is_syntax após SYNTAX_CSHARP, SYNTAX_CPP, SYNTAX_JAVA, SYNTAX_XMLa gramática usada ("c", "html")o valor escrito
codeeditor: of_insert_text só de leitura ou dobradoinserido só de leitura; recusado dobrado, mas 0-4, nada é inserido
codeeditor: ii_doc_linesó uma faixa, muitas vezes fora da vista, ausente na mudança de linha; um integera linha vem para o meio da vista (uma região dobrada que a esconde abre-se), faixa também na mudança de linha; cursor e seleção intactos; um long — renomeado il_doc_line na 4.0 (secção 11.28)
codeeditor: #regionopen com ib_foldingreescrito #region no texto (is_text, e depois da dobragem)nunca é tocado; só a vista dobrada mostra #region
codeeditor: ue_find_resultduas vezes por of_find, a cada tecla e (0, 0) ao fechar a barra; lançado mesmo com ib_search_enabled = falseuma vez por pesquisa ou passo; ao escrever se a contagem mudar; nunca ao fechar; of_find sem efeito com a pesquisa desativada
codeeditor: ue_caret_changedmudo durante a escrita; dobrado, a linha APRESENTADAlançado também durante a escrita; dobrado, a linha da calha
codeeditor: Ctrl+Z depois de Enter ou Tab; Enter / Tab dobradoo histórico de anulação era apagado; dobrado, a tecla alterava a vista e perdia-se depoiscada tecla anula-se; dobrado, a tecla não tem efeito
codeeditor: ib_folding = true com ib_line_numbers = falseas regiões ficavam fechadas, sem marcador para as abriruma calha estreita mantém os marcadores
commandpalette: of_add_command numa chave já usada ou que contém / ou uma barra vertical; of_remove_command numa chave desconhecida0 (uma chave usada dava dois comandos gémeos)-5
commandpalette: of_open / of_register_shortcut sem ipo_owner nem ipo_receiver0, e nenhum evento chegava nunca-5
commandpalette: o atalho premido enquanto a paleta está abertasem efeitofecha a paleta
commandpalette: um objeto paleta destruído (página ou janela fechada)o seu atalho ficava registado e engolia a tecla na janela, sem qualquer eventoo atalho sai com o objeto, e uma paleta que tinha aberto fecha-se
commandpalette: atalho mostrado numa linha, num teclado não latino, com um algarismo e Shift, Ctrl+Space, Ctrl+Up, Ctrl+Del, ou uma tecla F sozinhanão respondia; Win + a letra lançava o comando cujo atalho era essa única letraresponde: a tecla física, lida como a DLL a lê; Win nunca é um modificador
commandpalette: um comando cujo atalho é Ctrl+C, Ctrl+V, Ctrl+Z ou Ctrl+A, durante a escritao comando partia em vez da cópia, da colagem…a caixa de pesquisa mantém estas quatro teclas
commandpalette: of_resetmantinha is_recent, uma paleta aberta e o atalho já registadoesvazia-os, fecha-a e repõe o atalho registado em SHORTCUT_DEFAULT
commandpalette: pbm_custom02 da janela ipo_ownerdisparado a cada evento da paletanunca: só um ipo_receiver definido o continua a receber
Todos: reler um valor de texto longo (is_text de um script grande)cada vez mais lento com o tamanho (vários segundos); cortado sem aviso para lá de um milhão de caracteresproporcional ao tamanho; inteiro
n_pbt_utils.of_dir_has_subfolderscontava as pastas escondidas, de sistema e as junções; ilegível para lá de 260 caracteresignora-as, como o Explorador (a sobrecarga ab_include_hidden conta-as); lê caminhos longos
crosstab: separador de milhares de of_set_value_formatvalia para TODAS as medidas; "," não reconhecido ($1 234 em francês)definição DESTA medida; ",", ".", " " reconhecidos; "" = predefinição do menu Opções
crosstab: of_set_member_filter(campo, "")nenhum membro mantido: tabela vaziaremove o filtro, como of_set_member_order("")
crosstab: is_show, is_conditional_formatting, of_set_value_format antes de of_add_value_fieldperdidos sem avisoguardados, relidos tal como definidos, aplicados quando o campo entra em Valores
crosstab: ordenar uma coluna ou recolher um grupo com o ratonenhum eventoue_layout_changed, como tudo o que of_get_layout guarda
crosstab: datas de um DataStore num posto não francês (3/15/2025, 15.03.2025)agrupadas num mês errado ou vazio; datas ordenadas só pelo anoo mês certo; a coluna relida como aaaa-mm-dd, ordenada no tempo
crosstab: números mostrados em alemão, italiano, espanhol, portuguêsà americana (1,234.5)na língua de apresentação (1.234,5 em alemão)
crosstab: of_export_csvnúmeros com ponto (1436.5), lidos como texto por um Excel francês; um rótulo =… executava-se na aberturaseparador decimal da língua de apresentação; um apóstrofo antes de = + - @
crosstab: of_export_xlsxtotais e subtotais ocultos exportados na mesma; total no topo ignorado; símbolo « antes » passado para depoisa tabela tal como no ecrã
crosstab: « Adicionar aos valores » do menu de um campo já em Valoressubstituía os seus valoresacrescenta um valor, como o arrastar
crosstab: « Remover » do menu de um campo filtradoo filtro ficava ativo, invisívelo filtro sai com o campo
crosstab: AGG_DISTINCT_COUNT numa coluna com células vaziaso vazio contava como um valorignorado, como no Excel
crosstab: fórmula que cita uma medida calculadaaceite, valia 0recusada através de ue_calc_field_error; as suas mensagens estão em inglês
crosstab: ue_layout_changed com uma chaveta num membro; ad_value de ue_cell_double_clickeddisposição truncada; valor 0 se um campo em linhas se chama value, expoente perdidolidas inteiras
crosstab: ib_enabled = false, pelo tecladoEnter abria o menu de um chip, Ctrl+C copiavamudo
crosstab: tecladoo foco voltava ao topo da página após cada ação; nenhuma forma de mover um campoo foco fica no elemento acionado; o menu de um chip desloca-o (outra zona, esquerda, direita)
crosstab: tema escuronegativos e setas de ícones pouco legíveis; célula da escala de cores selecionada ilegíveluma paleta própria no modo escuro
crypto: of_jwt_sign com JWT_EDDSAo cabeçalho dizia "alg":"EDDSA", que as outras bibliotecas (jose, PyJWT, jjwt) recusam"alg":"EdDSA", o nome registado; um token 3.0 continua a verificar-se
crypto: of_generate_keypair de um tipo ou tamanho desconhecido ("ec_p256", 1024)0 e um par RSA 2048, sem uma palavra-5, ambos os PEM vazios, is_last_error nomeia as KEY_* admitidas
crypto: of_hash_file("SHA-256", …); algoritmo desconhecidovazio, e is_last_error dizia « ficheiro ilegível » de um ficheiro perfeitoo nome lê-se como of_hash o lê (SHA-256 = HASH_SHA256); um algoritmo desconhecido é dito como tal, à parte de um ficheiro ilegível
crypto: of_base64_encode_file de um ficheiro grande demais (mais de 64 MB em 32 bits, 512 MB em 64 bits); de um ficheiro ausente em demo« ficheiro ilegível »; « limite da demo »« grande demais para este processo »; « ficheiro ilegível » — is_last_error dá a verdadeira razão
crypto: is_last_error após uma chamada nativa bem-sucedida (of_crc32, of_hash em MD5, of_hash_file…)guardava o erro da chamada anteriorvazio
crypto: chave HMAC vazia; exp/nbf não numérico de um JWT; of_password_verify de um valor com mais de 10 000 000 rondas; of_random_password de um conjunto desconhecidoerro obscuro do motor; token válido para sempre; minutos de cálculo; CHARSET_ALL tomado sem uma palavrarecusados de imediato, is_last_error diz porquê
crypto: of_base64_decode_to_file("", caminho)-50, um ficheiro vazio
dockcontainer: of_add_panel com um as_relative_to desconhecido, um controlo já alojado, uma chave com / ou uma barra vertical, ou POSITION_STACK sobre o painel principal0: o painel acoplava-se à raiz, o controlo era alojado duas vezes, ou o painel empilhado sobre o principal ficava invisível-5, e o controlo não é tocado
dockcontainer: of_move_panel para um destino desconhecido, ou POSITION_STACK sobre o painel principal0: o painel ia para a raiz, ou nada se mexia-5
dockcontainer: of_remove_panel, of_reseto controlo voltava à sua window oculto, na posição e com o tamanho do dockvolta ao seu lugar, com o seu tamanho e com a visibilidade que tinha antes de of_add_panel
dockcontainer: is_main definido antes de of_add_panel; is_main = ""; is_main de um painel empilhadoignorado em silêncio; nada era transmitido; os vizinhos de pilha ficavam invisíveisguardado e aplicado ao adicionar o painel; o painel principal é retirado; sai da sua pilha, os outros continuam visíveis
dockcontainer: of_set_layout de uma disposição que não conhece nenhum dos painéis, ou de um texto que não é uma disposiçãoo dock esvaziava-se, ou a mensagem inteira era rejeitada; 0os painéis ficam, arrumados ao lado dos outros (nunca sobre o principal); -5 para um texto que não é uma disposição
dockcontainer: ue_layout_changeddisparado só ao arrastar, redimensionar e acoplar: uma disposição gravada neste evento esquecia um painel fechado ou o separador ativotambém disparado quando um painel é fechado, ocultado, selecionado ou renomeado, e quando o painel principal muda
dockcontainer: clique no separador (ou cabeçalho) do painel já ativoue_panel_selected a cada cliquenada: o evento indica uma MUDANÇA de painel ativo
dockcontainer: painel desafixado (ib_pinned = false)a sua patilha só abria com um clique (a doc dizia « ao passar o ponteiro »)abre ao passar o ponteiro (400 ms) ou com um clique; aberta ao passar o ponteiro, recolhe-se quando o rato a deixa
dockcontainer: controlo PB padrão (MultiLineEdit, botão…) num painel flutuanteas suas notificações (modified, clicked, cores) deixavam de chegarchegam como quando está acoplado
dockcontainer: ocultar um painel flutuante (ib_visible = false)a sua janela ficava abertafecha-se; ao voltar a ser mostrado, o painel regressa acoplado ao seu lugar
dockcontainer: janela flutuantea sua área útil era mais pequena do que o painel (barra de título descontada), podia sair do ecrã, e um título com etiquetas mostrava-asa área útil tem o tamanho do painel, a janela fica no ecrã, o título é texto simples
dockcontainer: divisor pelo tecladoa primeira seta fazia-o saltar para 50 %parte da sua posição apresentada
json: valor nulo dado a of_set_number, of_add_number, of_set_boolean, of_add_boolean, ou valor nulo ou vazio dado a of_set_raw / of_add_rawtodo o documento ficava nulo (of_text devolvia null) ou deixava de ser JSON; um booleano nulo escrevia-se falseescreve-se null, o resto do documento fica intacto
json: escrever num documento CARREGADO cuja chave se escreve "k" : v ou com um carácter escapado, seguido de uma quebra de linha, ou cuja raiz é um array; of_set_members nesse documentoa chave era acrescentada em duplicado (a releitura devolvia o valor antigo), a escrita devolvia -4 sem razão, ou o documento era substituído pelo fragmentoo valor é substituído ou acrescentado como num documento construído; of_set_members devolve -4 se a raiz não for um objeto
json: of_set_*("items/1/qty", …) — uma chave NOVA num objeto situado num array-40: a chave é acrescentada ao primeiro elemento; um array atravessa-se por um índice existente, só se cria uma chave de objeto
json: caminho com um segmento vazio (/name, a//b, a/)eram criadas chaves chamadas ""; of_remove podia retirar outro valor-5, nada é escrito; um leitor responde "ausente"
json: of_load de um número mal escrito (-, 01, +1, .5, 1., 1e)0, e of_is_valid verdadeiro-4, como qualquer JSON inválido
json: of_get_number de um número com expoente (1e-7, 2.5E+3) ou com mais de 9 casas decimaisexpoente ignorado (2.5E+3 lido 2,5), casas decimais cortadas a 9expoente resolvido, 17 algarismos significativos mantidos
json: ler ou modificar um documento grande (uma resposta de API de 80 KB, 2000 linhas)segundos por chamada (20 s para of_count), a aplicação parecia bloqueadaum tempo proporcional ao tamanho; ler as linhas uma a uma (rows/1, rows/2…) ou percorrer as chaves com of_name já não recomeça do início
listbar: of_add_section / of_insert_section com uma chave ocupada ou que contém / ou uma barra vertical; of_add_item / of_insert_item com um endereço ocupado ou sob uma secção que a barra não adicionou; of_remove_item, of_move_item, of_select_item, of_remove_section, of_move_section com um endereço desconhecido0, ignorado; uma entrada sob uma secção desconhecida aparecia sob a última secção-5; of_add_section devolve também -2 quando o componente não está criado
listbar: um handle mantido após of_remove_item, of_remove_section ou of_clearficava em memórialibertado: IsValid() devolve false
listbar: retirar ou esvaziar o que tem a seleção (of_remove_item, of_remove_section, of_clear)a seleção desaparecia sem evento; após of_clear, of_selected_key ainda devolvia a antigaue_selection_changed(antiga, "")
listbar: ue_layout_changedmudo ao recolher uma secção e ao retirar uma entrada; disparado ao entrar na calhadisparado ao recolher (clique ou ib_collapsed de uma secção) e ao retirar; já não para a calha, que não faz parte da disposição
listbar: calha (ib_collapsed = true)as entradas de uma secção recolhida desapareciam; uma entrada sem ícone mostrava um quadrado vazio; of_reset deixava a barra estreitatodas as entradas, um filete entre secções, a inicial de uma entrada sem ícone, a etiqueta ao passar o rato; of_reset devolve à barra a sua largura
listbar: is_image de uma secção; uma cor definida na secção k quando uma entrada também tem a chave ksem efeito; a entrada também ficava com a coro ícone é desenhado antes do título; só a secção fica com a cor
listbar: tecladoapós uma mudança de etiqueta ou uma seleção, as setas deixavam de responder; sem seleção a barra ficava fora da tabulação; os títulos de secção só se recolhiam com o ratoo foco fica na entrada; uma paragem de tabulação; os títulos alcançam-se com as setas e recolhem-se com Enter ou Espaço
listbar: entrada desativada (ib_enabled = false); ib_auto_width numa barra expandidaetiqueta esbatida, pouco legível em temas claros; comunicava a largura já dadaa cor « desativado » do tema; a largura que a linha mais longa pede
listbar: arrastar uma entrada (ib_reorderable)botão largado fora da janela: a entrada continuava a seguir o rato; o clique final podia selecionar a entrada largadao gesto termina quando o rato volta; o fim de um arrasto não seleciona nada
menubar: ue_menu_openinglevantado ao lado do menu pendente: o que mudava (esbater Colar…) só se via na abertura seguinteo menu pendente espera que o evento regresse: a mudança vê-se nesta abertura
menubar: of_item, of_remove_item numa entrada cuja chave também existe noutra cascata (file/export/pdf, file/print/pdf)podiam atingir a outra entrada (a primeira encontrada); o atalho mostrado numa disparava a outraatingem a entrada que o endereço nomeia; uma chave sozinha já não procura nas cascatas
menubar: of_add_menu, of_add_item, of_add_separator numa chave já ocupada, com / ou uma barra vertical, ou sob um menu ou um pai desconhecidos; of_remove_item / of_remove_menu de um endereço desconhecido0; uma entrada com o pai mal escrito ia para a raiz do menu, uma chave ocupada dava entradas gémeas-5
menubar: um handle ou um atalho após of_remove_item, of_remove_menu ou of_clearo handle ficava em memória; o atalho continuava armado e engolia a tecla, que já não chegava à aplicaçãohandle libertado: IsValid() devolve false; atalho desarmado
menubar: entrada esbatida, oculta ou retirada enquanto o seu menu pendente está aberto; atalho de uma entrada sob uma cascata esbatidao clique ou a tecla ainda levantavam ue_item_selectednada
menubar: cores de item (il_back_color…) de um menu ou de uma entrada; is_tooltip de um menusem efeito; uma cor relia-se -1aplicadas: no título do menu, na entrada do menu pendente; a dica de um menu aparece no seu título, uma entrada do menu pendente não mostra nenhuma
menubar: tecladoas setas ficavam bloqueadas num menu esbatido; em RTL, esquerda e direita trocadas; Alt+letra de um menu oculto escondia a mesma letra de outro menu; após Alt+letra e uma escolha, o Alt seguinte desligavaos menus esbatidos são saltados; as setas seguem o sentido da escrita; só um menu visível responde à sua letra; o Alt seguinte volta a acender a barra
menubar: uma cascata cujas entradas estão todas ocultas; of_count("file"), of_keys_atescolhia-se como um comando (file/export); os separadores eram contados (__sep0)esbatida; só as entradas são contadas
menubar: of_item("file") — um endereço de um nívelrelia o menu, e escrevia numa entrada «file» que não existenão designa nada: use of_menu("file")
Todo o texto lido de um componente ou de um JSON: escapes \b e \fficavam escritos tal como estavamdescodificados (retrocesso, avanço de página)
messagebox: uma caixa que não pôde abrir (runtime WebView2 ausente, motor não pronto)of_show e os atalhos (of_info…) devolviam 0, como um fecho: of_info fazia crer que uma caixa tinha aparecido-4 (-6 se faltar o runtime), o motivo por of_get_last_error(); of_choose e of_prompt devolvem "" e of_get_last_error di-lo. Um teste = 1 para «confirmado» continua certo
messagebox: Esc ou Alt+F4 enquanto um botão de cancelamento ainda está em contagem decrescente (of_add_button_timed)fechavam a caixa (0)não fazem nada até ao fim da espera: serve para obrigar a ler
messagebox: o texto da mensagem e da instruçãonão se selecionava; premir sobre ele movia a caixaseleciona-se e copia-se (Ctrl+C copia a seleção, ou a caixa inteira sem seleção); a caixa move-se pelo título, pelo ícone, pelas margens
messagebox: uma entrada com mais de cerca de 900 caracteres (of_prompt, ib_input)voltava vazia, como um cancelamentovolta inteira
messagebox: al_hwnd = 0, uma caixa aberta a partir de outra, uma caixa movida e depois aumentadatodo o ambiente de trabalho era desativado; a janela voltava a ficar ativa enquanto a primeira caixa ainda esperava; a caixa voltava ao centrosem proprietário nada é desativado; a janela continua desativada enquanto uma caixa espera por ela; a caixa mantém o seu lugar
progressbar: intervalo vazio ou invertido (id_maximum = 0 e depois id_value = 0)0 % qualquer que seja o valor100 % assim que o valor atinge o máximo (um lote vazio está terminado), 0 % antes
progressbar: a percentagem apresentada, o anelarredondada ao mais próximo (99,5 % mostrava «100%»); anel fixo em 128 px; em espera, o anel girava com o arco do valor (vazio a 0: nada se mexia)arredondada para baixo: 100 % significa terminado; o anel acompanha o tamanho do controlo; em espera gira um arco fixo; se o Windows pedir menos animações, a espera pulsa
Qualquer propriedade double relida (id_value…) num computador com vírgula decimala parte decimal era mal lida (0,5 não se relia como 0,5)relida exatamente, qualquer que seja o separador do computador
speechout: um novo of_speak (ou of_close) durante uma leituraa leitura cortada não levantava nenhum ue_stoppedtoda a leitura começada termina com um ue_stopped
speechout: il_timeout_ms = 0cortava a leitura síncrona ao fim de 5 ssem limite (24 horas no máximo)
speechout: uma voz que não pôde ser criada (runtime WebView2 ausente, página recusada)of_speak, of_speak_from, of_pause, of_resume, of_enqueue, of_clear_queue devolviam -1, of_open o código bruto da DLL-2 (componente não criado, como em todo o lado), is_last_error diz porquê; -4 se a página não respondeu
speechout: of_speak_sync chamado a partir de um evento levantado durante outro of_speak_synccortava a leitura da chamada exterior, que devolvia 0 mesmo assimrecusado: -4, is_last_error = "already speaking synchronously"
speechout: of_speak_from para além da última frase0, nada era lido-5
speechout: of_is_speaking() logo após of_speakfalse enquanto a lista de vozes não tinha chegadotrue desde of_speak
speechout: of_pick_voice("", género), ou lista de vozes ilegívelescolhia na língua da página; uma falha esvaziava is_voice"" = is_lang; uma falha mantém is_voice e preenche is_last_error
speechout: of_voice_used, of_duration, of_spoken_text logo após mudar is_lang ou o dicionáriopodiam responder com as definições anterioresrespondem com as definições acabadas de pôr
speechout: erro de script na página da vozsilenciosoue_error("script error: …")
statictext: il_back_color com ii_corner_radiuso fundo preenchia todo o retângulo, só o traço do contorno era arredondadoo fundo acompanha o arredondamento; fora dos cantos, a cor do objeto sobre o qual o bloco está, que o userobject também assume
statictext: is_marquee_direction com leitura da direita para a esquerdainvertido: MARQUEE_START deslizava para o fim, "left" para a direitaMARQUEE_START desliza para o início da leitura; "left" / "right" continuam físicos
statictext: reler il_back_color, ii_marquee_speed, is_marquee_direction, ib_marquee_overflow_only, ib_marquee_pause_on_hover, is_font_family-1, 0, "", false fosse qual fosse o valor; uma família com espaço entre aspaso valor atribuído
statictext: ii_marquee_speed = 0mantinha a velocidade anteriorvelocidade predefinida (60)
statictext: of_reset depois de um contornocor e espessura mantidas: o contorno seguinte herdava-asapagadas
statictext: ib_track_mouse, componente desativado durante a passagem do ratoue_mouse_leave nunca levantadoue_mouse_leave levantado à saída
statictext: deslizamento (ib_marquee)um [foldarea] deixava de recolher depois; com ib_marquee_overflow_only, uma mudança de ALTURA recomeçava do início; com ib_wrap = false, um ue_text_overflow(true) erradocorrigido: o texto já não é copiado, só uma LARGURA realmente nova é medida de novo, e o deslizamento mostra todo o texto
statictext: ib_hover_effect e ligações sob o rato num tema escuroescurecidos (contraste reduzido)clareados
Texto rico: [symbol=clock]mostrado tal como estáum glifo monocromático; um nome desconhecido continua a ser texto
statusbar: of_add_panel / of_insert_panel com uma chave ocupada ou que contém / ou uma barra vertical; of_move_panel, of_remove_panel, of_clear_menu, of_add_menu_separator com um painel desconhecido; of_add_menu_item / of_insert_menu_item sob um painel desconhecido ou com uma entrada ocupada; of_remove_menu_item, of_move_menu_item com um endereço desconhecido0, ignorado-5
statusbar: of_insert_panel(…, 0)acrescentado no fim da barraem primeiro, como qualquer posição (0 ou menos = em primeiro)
statusbar: um separador (of_add_sep) em of_count, of_keys_at e nas posições de of_insert_panel / of_move_panelcontado como um painel de chave vaziaignorado: uma posição conta painéis
statusbar: um separador entre dois painéis ALIGN_ENDdesenhado no fim do grupo de inícioentre os dois: abre o grupo do painel que o segue
statusbar: clique direito num painel não clicávelnenhum eventoue_panel_rclicked (um painel desativado permanece mudo)
statusbar: of_panel(k).ii_progress lido num painel sem barra0, como uma barra a 0 %-1
statusbar: of_menu_item("k"), um endereço de um só nívelescrevia no painel k (ib_enabled acinzentava-o)não designa nada: não escreve em lado nenhum, relê-se vazio
statusbar: cores e dica de um painel após of_clear, e depois um painel acrescentado com a mesma chaveretomados pelo novo painelesquecidos: o painel começa limpo
statusbar: is_state num tema escuro; painel desativadocores do tema claro, pouco legíveis; acinzentado por transparência, fundo perdido ao passar o ratouma paleta escura legível; acinzentado pela cor do tema, fundo mantido
statusbar: um painel cujas entradas de lista estão todas ocultasmão e seta, clique sem efeitoum painel normal, clicável ou não conforme ib_clickable
statusbar, toolbar: setas Esquerda / Direita em leitura da direita para a esquerda (RTL)ao contrário: Direita ia para a esquerda do ecrãno sentido do ecrã, como o separador e o friso
stepbar: definir ii_currentnada era lançadoue_step_changed quando a barra se move, como a documentação prometia
stepbar: retirar, inserir ou deslocar uma etapa antes da etapa atuala etapa atual mudava sem aviso (era uma posição)a mesma etapa continua atual; se for ela a retirada, a barra passa à seguinte alcançável e lança ue_step_changed
stepbar: ii_current definido antes das etapas; of_clear_stepsreposto na primeira etapa; a etapa atual sobrevivia ao esvaziamentoguardado e aplicado assim que a etapa existe; o esvaziamento recomeça na primeira etapa
stepbar: of_add_step / of_insert_step com uma chave ocupada ou que contém / ou uma barra vertical; of_move_step, of_remove_step com uma chave desconhecida0, ignorado-5
stepbar: of_insert_step(…, 0)acrescentado no fim da barrainserido no início, como toda posição da biblioteca (of_add_step acrescenta no fim)
stepbar: setas esquerda / direita numa língua da direita para a esquerdaa seta direita ia para a etapa seguinte, desenhada à esquerdainvertidas: a seta esquerda vai para a etapa seguinte
tab: of_add_page / of_insert_page com uma chave que contém / ou uma barra vertical; um envio falhado0; a página ficava alojada e a sua chave ocupada-5; um envio falhado devolve o seu código, a página volta à sua janela e a chave fica livre
tab: of_select_page de uma página oculta, desativada ou além do limite da demonstração0, e a página aparecia sob uma barra sem separador ativo-5, nada se move
tab: cruz, atalho (is_shortcut), «Fechar todos / os outros / à direita» num separador desativado ou ocultoo separador ativava-se ou fechava, e o PB libertava a sua páginasem efeito: um separador que não se pode ver nem alcançar não se ativa nem fecha
tab: o separador ativo é fechado, retirado ou ocultadoo seguinte ou o primeiro assumia, mesmo oculto ou desativado; o as_from_key de ue_selection_changed vinha vazioassume o vizinho selecionável (direita, senão esquerda); as_from_key nomeia o separador realmente abandonado, mesmo desaparecido
tab: nenhum separador visível (todos ocultos, ou uma disposição que os oculta)a página do antigo separador ficava visível, sem eventoa página é ocultada e é lançado ue_selection_changed(antigo, ""); mostrar de novo um separador seleciona-o
tab: um handle mantido após of_remove_page ou um fecho; o seu atalhoficavam; uma página reaberta com a mesma chave recuperava cor, tooltip e o antigo atalholibertados: IsValid() devolve false, a página volta nova
tab: of_set_layout com um texto que não é JSON0, e a mensagem saía partida-5, nada é enviado
tab: teclado na barra de separadoresEnter perdia o foco; as setas paravam nos separadores desativados ou em excesso; nem Cima/Baixo em barra vertical nem inversão na escrita da direita para a esquerdao foco fica no separador; as setas seguem o eixo da barra e saltam o que não responde; Delete fecha um separador que se pode fechar
tab: texto de um separador desativado; tooltip de um separador com título truncadoesbatido em bloco (ilegível ao passar o rato em office2007 escuro); o nome completo nativo ocultava o seu tooltiptexto na cor desativada do tema, legível; o seu tooltip tem prioridade
tilesbox: of_get_layoutdevolvia sempre "": uma disposição guardada nunca era restauradaa disposição inteira, o mesmo texto que ue_layout_changed; guarda também o tamanho e a visibilidade de cada mosaico e a visibilidade de cada grupo
tilesbox: of_set_layout que nomeia um mosaico sob outro grupo que não o seu; um texto que não seja JSONo primeiro mosaico com essa chave, em qualquer grupo, era deslocado para lá; 0um mosaico reencontra-se pelo seu grupo e pela sua chave: a entrada é ignorada; -5 perante um texto que não seja JSON
tilesbox: of_add_group com uma chave já tomada; of_add_tile / of_insert_tile com uma chave tomada ou sob um grupo nunca adicionado; uma chave vazia, ou com / ou ``0; um grupo adicionado de novo era renomeado, um mosaico sob um grupo desconhecido criava-o com a sua chave-5, nada é adicionado: adicione primeiro o grupo com of_add_group
tilesbox: of_move_tile, of_remove_tile, of_add_live_item, of_clear_live_items num mosaico inexistente; of_remove_group num grupo inexistente0-5
tilesbox: um handle guardado após of_remove_tile, of_remove_group, of_clear, ou um mosaico arrastado para outro grupoficava em memória; um mosaico recriado no mesmo endereço retomava as cores e a dica do antigo, um mosaico arrastado perdia-aso handle é libertado (volte a pedi-lo com of_tile / of_group); cores e dica acompanham o mosaico arrastado e partem com o que é removido
statusbar, stepbar, crosstab: um handle guardado após of_remove_panel, of_remove_menu_item, of_clear_menu, of_clear (statusbar), of_remove_step, of_clear_steps (stepbar), of_remove_calc_field ou of_remove_calc_measure (crosstab)ficava em memória até à destruição do componentelibertado: IsValid() devolve false; volte a pedi-lo com of_panel, of_menu_item, of_step ou of_field
Todos os componentes com itens: reler il_back_color_hover / il_text_color_hover de um item nunca colorido0, o preto-1, «a cor do tema», como as outras três cores do item
tilesbox: reler ib_enabled / ib_visible de um grupo, ou ii_badge_sizefalse, false, 0 fosse o que fosse definidoo valor em vigor
tilesbox: grupo desativado (ib_enabled = false)o seu cabeçalho ainda o recolhia (clique, Enter) e lançava ue_group_toggled; um mosaico arrastado podia cair neleinerte: nem recolher, nem evento, nem largar
tilesbox: cores de item (il_back_color, il_text_color, il_accent…) definidas num gruposem efeito; a cor de um grupo a podia pintar um mosaico a de outro grupopintam o cabeçalho do grupo (fundo, título, passagem do rato, filete de destaque), nunca os seus mosaicos
tilesbox: of_tile(""), ou um endereço com um ou três níveisdefinir uma propriedade parava a aplicação («Array boundary exceeded») ou escrevia no grupoum handle inerte: não escreve nada e lê-se vazio
tilesbox: teclado e leitor de ecrão foco perdia-se a cada atualização vinda do PB (um emblema) e o menu de tamanho fechava-se; menu de tamanho só com o rato; em RTL, setas ao contrário; rótulos lidos com as suas etiquetasfoco e menu mantidos; menu de tamanho pelo teclado (setas, Enter, Esc); setas no sentido de leitura; texto simples
toaster: il_max_visiblepredefinição 5, enviada por CADA toaster: um toaster que tinha definido 10 voltava a 5 assim que outro mostrava um toastpredefinição 0 = nada é enviado; o limite é COMUM à aplicação e prevalece o último valor definido (5 enquanto ninguém o definir)
toaster: of_show de um toast que espera lugardevolvia 0: o toast não podia ser fechado por of_close, e os seus eventos traziam um id nunca recebido; fila cheia (200): 0 também, toast perdido sem avisoum identificador verdadeiro, de imediato; of_close retira-o da fila; fila cheia: -4
toaster: dois toasts sem is_key com um botão da mesma chaveo segundo SUBSTITUÍA o primeiro (a chave do botão era tomada pela do toast) e of_show devolvia o id do primeirodois toasts, dois identificadores; só is_key atualiza no lugar
toaster: eventos de vários toastersarquivados por WINDOW: dois toasters ancorados à mesma window roubavam os eventos um ao outro, e os de um toaster destruído iam para o seguintecada toaster recebe os dos SEUS toasts; um toaster destruído já não recebe nada, os seus toasts ficam no ecrã, mudos
toaster: pbm_custom02 da window ipo_ownera window de ancoragem recebia um pbm_custom02 em cada evento de toast, mesmo sem ipo_receiversó uma window definida em ipo_receiver o recebe; se tinha mapeado pbm_custom02 da sua window para os toasts, defina ipo_receiver, ou melhor, retire esse código: os eventos chegam sozinhos
toaster: apresentaçãoum toast ficava parado quando a sua window se movia; um toast com mais de 800 px (um longo rasto de erro) NUNCA aparecia; largura não escalada (180 px a 200 %); atualizar um toast sobrevoado reiniciava toda a pilhasegue a sua window; o texto desloca-se dentro do toast limitado; largura à escala do ecrã; a pilha mantém-se em pausa sob o ponteiro
toolbar: adições, of_add_separator, of_move_item, of_remove_* com uma chave ocupada, com / ou ``, uma barra desconhecida ou um endereço desconhecido0, ignorado — um erro de escrita no nome de uma barra criava uma barra fantasma-5; só main não precisa de of_add_bar
toolbar: of_clear, of_remove_bar, of_remove_itemos handles ficavam, os atalhos continuavam ativos, e uma ferramenta recriada com a mesma chave recuperava as cores da anteriorhandles libertados, atalhos desativados, cores e tooltips esquecidos; volte a pedir um handle depois de uma remoção
toolbar: of_item num endereço de três níveis (uma entrada de menu)agia sobre a FERRAMENTA da barra que tinha o nome da entradanão designa nada; uma entrada controla-se com of_menu_item(endereço)
toolbar: entrada escolhida num pendente recolhido na setaue_menu_selected sem o pai da cascata, sob outro pendente, ou vazioo endereço completo, como na barra
toolbar: ii_index de uma barranunca deslocava uma barra para a direitaa barra toma a posição pedida
toolbar: of_add_bar(chave, banda, posição) numa posição já ocupada, ou uma banda para lá das outrasordem indefinida; a banda relia-se tal como dada (5 para a segunda fila)insere-se antes da barra que ocupava a posição; as bandas cerram fileiras
toolbar: of_count, of_keys_at de uma barra, posição de of_move_itemcontavam os separadores, com uma chave vaziasó as ferramentas: um separador não tem chave nem posição
toolbar: Enter numa caixa de textovalidava o campo E premia o botão predefinido da janelavalida só o campo; Escape repõe o texto validado
toolbar: is_shortcut relido; ii_band / ii_index de uma barra desconhecidactrl+s (normalizado); 1Ctrl+S, tal como escrito; 0
toolbar: cor ou tooltip definido numa BARRA (of_bar)sem efeito, ou pintava a ferramenta com o mesmo nomeaplicado à barra, e só a ela
toolbar: atalho de uma ferramenta oculta ou para lá do limite da demonstraçãoengolia a teclaa tecla vai para a ferramenta seguinte com o mesmo atalho
webbrowser: uma página que não carrega (anfitrião desconhecido, rede, certificado, of_stop)acionava ue_load_completed, como um sucessoaciona ue_load_failed(as_url, al_status) em vez disso
webbrowser: palavras em is_address («fatura 2026»)saíam como https://fatura 2026 e depois nenhuma navegação aconteciarecusadas com ue_error, o seguinte carrega; uma pesquisa se is_search_url estiver definido
webbrowser: um caminho de disco (C:\temp\x.html) ou //anfitrião/x em is_addressprecedido de https://, portanto não encontradofile:///C:/temp/x.html; https://anfitrião/x; javascript: recusado
webbrowser: is_address relido após seguir uma ligação ou Anterioro último endereço definidoa página apresentada
webbrowser: of_go_back, of_go_forward, of_stop logo após is_addresspodiam passar ANTES do endereço; of_stop deixava recomeçar as páginas em esperasão executados pela ordem escrita; of_stop também abandona as páginas em espera
webbrowser: of_save_as_png, of_save_as_jpg, of_print_to_pdf, of_printcapturavam ou imprimiam a barra de endereçoo site apresentado
webbrowser: ligação target=_blank, window.open após um cliquenada aconteciaa página abre-se na vista, ue_new_window indica-o
webbrowser: resposta de of_execute_javascript com mais de 4.095 caracterescortada sem avisointeira
webbrowser: F5, Ctrl+R, Ctrl+roda na barra de endereçorecarregavam ou ampliavam a própria barrasem efeito na barra; ativos no site
webbrowser: clique direito num campo de texto com ib_context_menuAnterior / Seguinte / RecarregarCortar / Copiar / Colar
webbrowser: Tab ou of_focus_webview sem barra de endereço; ficheiro largado no site com ib_allow_dropfoco perdido numa barra de 0 px; ficheiro aberto pelo navegadoro foco vai para o site, Tab sai dele para a sua janela; ue_drop_files
pdfviewer: is_source relido, e as_source de ue_load_completedo endereço interno /_file/?p=…o que escreveu (doc\notice.pdf)
pdfviewer: ficheiro ausente, não é um PDF, site inacessível ou que recusa a molduraue_load_completed numa página de erro, ou nenhum eventoue_load_failed(as_source, as_reason) (constantes REASON_*), o visualizador permanece vazio
pdfviewer: http://, data: de um tipo diferente de PDF, página web em https://apresentados (ou moldura vazia para http://)recusados: ue_load_failed com REASON_INSECURE ou REASON_NOT_PDF
pdfviewer: um # em is_sourcecortava o caminho (Orçamento #12.pdf não encontrado); o fragmento de um URL misturava-se com ii_page / ii_zoomum # faz parte do nome do ficheiro; o fragmento de um URL é ignorado, página e zoom passam pelas propriedades
pdfviewer: ii_page definido antes de is_sourceperdido: o documento abria na página 1conservado para esse documento; sem página definida desde o último is_source, um novo documento abre na página 1
pdfviewer: PDF regenerado no mesmo caminho e depois of_refresh; PDF de 32 MB ou mais; caminho com mais de 260 caracteresa versão antiga durante 5 minutos; nada; não encontradoo ficheiro tal como está no disco; apresentado (servido por partes); apresentado
pdfviewer: ligação seguida no documento; of_printo site substituía o documento, sem retorno; imprimia a página que enquadra o documentoo documento permanece, ue_link_clicked(as_url) dá-lhe o endereço; of_print imprime o documento (-4 sem documento)
picture, button, tilesbox: il_badge_color0 = a cor do tema; o preto era inatingível; não definido, relia-se 0-1 = não definido (a cor do tema), como qualquer outra cor; 0 é o preto. Substitua il_badge_color = 0 por -1
picture: id_zoom definido antes de ib_zoomablerelia-se como definido, enquanto a imagem ficava enquadradaignorado: id_zoom fica em 1.0 enquanto ib_zoomable for falso; defina primeiro ib_zoomable
picture: ib_mirror numa imagem rodada um quarto de volta; is_align / is_valign com uma rotaçãoinversão vertical no ecrã; o posicionamento rodava com a imagemespelho e posicionamento leem-se no ecrã, seja qual for a rotação
picture: arrastar a imagem ampliada; roda; imagem desativada (statictext desativado também)ue_clicked a cada deslocação; zoom para o centro, a imagem podia sair da moldura; os ficheiros largados continuavam aceitesnenhum clique após uma deslocação; zoom para o ponteiro, a imagem cobre sempre a moldura; desativada, recusa qualquer largada; ue_error indica a origem
xml: uma leitura (of_get_value, of_count, of_is_valid…) ou uma alteração depois de uma construçãoagia sobre o último documento CARREGADO, ou sobre nadao documento construído é carregado e torna-se O documento; o of_start_element seguinte começa um novo
xml: of_load falhado (vazio, malformado), of_start_element depois de um carregamentoo documento anterior continuava legível e alterável (of_is_valid verdadeiro); um documento construído a meio ficava em of_xmlnada fica
xml: of_xml, of_pretty, of_get_values de um documento grandecortado sem aviso para lá de alguns MBinteiro
xml: of_get_value de um XPath de valor (count(//line), sum(//@qty))vazioo valor como texto (3, true)
xml: um XPath cujo prefixo é declarado abaixo da raiz (resposta SOAP)vazio sem of_register_namespaceresolvido
xml: is_last_error depois de um XPath inválido, de uma página que não responde, de uma recusa; códigos de of_register_namespace / of_clear_namespacesvazio, ou «no node matched» fosse qual fosse a causa; as alterações devolviam -4 quando faltava a página; sempre 0; uma página sem resposta devolvia o texto nulla verdadeira razão; -2 quando a página não responde; um URI vazio é recusado (-5); vazio em vez de null
xml: of_prettyperdia CDATA, comentários, instruções de processamento e a declaração XML, e alterava o texto mistotudo é mantido; um elemento que contém texto fica numa linha
xml: construção — quebra de linha ou tabulação num atributo, CR num texto, carácter de controlo, nome inválidorelidos alterados; documento malformado; nome escrito tal como estárelidos idênticos; carácter de controlo retirado; nome recusado (is_last_error), o elemento fica de fora
xml: um documento que contém um elemento <parsererror>; mensagem de um XML malformadorecusado como malformado; mensagem enquadrada por «This page contains the following errors»carregado; só a linha de erro
xml: of_remove de nós aninhados, da raiz, de um atributo; of_set_value("/"); of_add_child sob um atributocontava duas vezes; esvaziava o documento; o atributo ficava; 0 sem efeito; «parent not found»a contagem real; a raiz fica (0 e is_last_error); o atributo é retirado; -4; «the node cannot have children»
xml: of_close e depois uma leitura; ipo_owner definido depois da primeira leiturao documento carregado perdia-se; ignorado até of_closeo documento é mantido e recarregado; transmitido na leitura seguinte
temas metro-light e metro-dark: texto sobre a cor de destaquebranco sobre o azul #25a0da nos dois temas (cabeçalhos de painel, separador ativo, botão da aplicação do friso, mosaicos): pouco legívelmetro-light: a cor de destaque passa ao azul mais profundo #1b76a1, texto sempre branco; metro-dark: a cor de destaque mantém-se #25a0da, o texto por cima passa a quase preto (#1b1b1b)
temas office-dark, office2003-dark, office2003-light, office2007-light: cores de destaque e de cabeçalhono modo escuro, a cor de destaque lia-se mal na página (marcador de passo, emblema), tal como o texto branco sobre o destaque sob o rato e sobre os cabeçalhos de coluna do crosstab; no modo claro, o topo dos degradês do botão da aplicação e dos cabeçalhos de painel era demasiado pálido para texto brancooffice-dark: destaque #1178d1, sob o rato #0f6cbd; office2003-dark: destaque #4574cb, sob o rato #2f5aa8; cabeçalhos do crosstab mais escuros sob o rato e nos totais; office2003-light e office2007-light: início do degradê mais profundo (#3e73cf, #4275c5), cabeçalhos de painel de office2007-light mais opacos. Texto sempre branco, pelo menos 4,5:1
texto sobre uma cor escolhida pela aplicação (il_accent, cor de um item, cabeçalho de painel, emblema)branco até uma cor bastante clara: um azul médio como #25a0da recebia texto branco a 2,95:1branco ou quase preto (#1b1b1b), o que se ler melhor (relação de contraste WCAG): #25a0da recebe agora texto escuro
jsontree: of_clearesvaziava a árvore E repunha ib_wrap e ib_search_enabled nos seus valores por omissãoesvazia só a árvore; as definições ficam (é of_reset que repõe tudo)
jsontree: is_json = ""levantava ue_error «Invalid JSON»esvazia a árvore sem erro, como a documentação prometia
jsontree: números e chaves mostrados, is_json relidoreescritos pelo motor: 12345678901234567890 mostrado 12345678901234567000, 1.10 → 1.1, a primeira de duas chaves idênticas perdida; is_json relia-se compactado, e vazio depois de um JSON inválidotal como recebidos, as duas chaves incluídas; is_json relê-se exatamente como foi definido
jsontree: of_match_count, al_count de ue_search_resultcontavam LINHAS; duas ocorrências numa linha eram ambas «atuais»contam OCORRÊNCIAS, só uma é atual e of_search_next passa de uma à outra
jsontree: blocos abertos por uma pesquisaTODOS os que continham uma correspondência, de vez: pesquisar «e» abria o documento inteirosó os que escondem a ocorrência ATUAL; of_clear_search devolve as dobras de antes da pesquisa
jsontree: of_select_pathuma linha escondida num bloco dobrado ficava invisível; um caminho desconhecido devolvia 0os blocos que a escondem abrem-se; um caminho desconhecido devolve -5 e a seleção não se move
jsontree: dobrar o bloco que contém a seleçãoa seleção ficava invisível, e a seta seguinte recomeçava do topoa seleção passa para o bloco dobrado; num gesto do utilizador, ue_selection_changed di-lo
xmltree: of_clearesvaziava a árvore E repunha ib_wrap e ib_search_enabled nos valores predefinidossó esvazia a árvore; as definições ficam (é of_reset que repõe tudo)
xmltree: is_xml = ""levantava ue_error «Invalid XML» e mostrava um erro vermelhoesvazia a árvore sem erro, como a documentação prometia
xmltree: is_xml relureserializado pelo motor: aspas alteradas, quebras de linha perdidas, vazio depois de um XML inválidorelê-se tal como foi definido, mesmo um texto inválido
xmltree: ce qui s'afficheum CDATA era invisível (o elemento aparecia vazio), faltavam comentários, instruções de processamento e declaração, o texto de um conteúdo misto era colado antes dos filhos, um texto perdia os seus espaços, um valor de atributo com aspas era mostrado tal qualcada nó no seu lugar, pela ordem do documento; a linha continua a ser XML (aspa escolhida ou &quot;, &#10;, &amp;, &lt;); os espaços significativos ficam
xmltree: of_match_count, al_count de ue_search_resultcontavam LINHAS; uma correspondência entre dois pedaços (id="4152") era contada sem ser realçadacontam OCORRÊNCIAS, cada uma realçada, só uma é a atual
xmltree: éléments ouverts par une rechercheTODOS os que continham uma correspondência, de vezsó os que escondem a ocorrência ATUAL; of_clear_search devolve as dobras de antes da pesquisa
xmltree: of_select_pathuma linha escondida num elemento dobrado ficava invisível; um caminho desconhecido devolvia 0os elementos que a escondem abrem-se; um caminho desconhecido devolve -5 e a seleção não se move
xmltree: ue_selection_changedlevantado também sem alteração (Fim na última linha); dobrar o elemento que continha a seleção tornava-a invisível, em silênciolevantado só quando a seleção muda; ao dobrar, a seleção passa para o elemento dobrado e o evento di-lo
xmltree: ue_erroro texto bruto da página de erro do motor; um elemento <parsererror> do documento passava por um errosó a linha do erro («error on line N at column M: …»); um <parsererror> do documento é um elemento como outro qualquer
restclient: cookies de um pedido síncrononenhum guardado: cada of_get / of_post abria a sua própria sessão; ib_keep_cookies só valia para o assíncronouma sessão por objeto, comum ao síncrono e ao assíncrono: um início de sessão síncrono mantém-no ligado para as chamadas seguintes
restclient: ib_keep_cookies alterado após o primeiro pedidosem efeito até of_closeaplicado de imediato; a false, os cookies já guardados são esquecidos
restclient: redirecionamento para outro anfitrião ou portasó caíam Authorization, Cookie e a autenticação Basic: uma chave de API (X-Api-Key…) ia para o terceironenhum cabeçalho definido com of_set_header segue, só fica Content-Type
restclient: of_set_bearer("") após of_set_basic; of_set_basic e depois of_set_bearer; of_set_basic("", "")a palavra-passe Basic continuava a partir; dois Authorization ao mesmo tempo; Basic Og== enviadouma só autenticação de cada vez: cada uma substitui a outra, um token ou utilizador vazio retira-a
restclient: HEAD, ou resposta 204 / 304 que anuncia um tamanho-4 «connection lost», e repetida em assíncronoo estado (200, 304…)
restclient: corpo com um byte inválido; charset=iso-8859-1 ou utf-16todo o corpo relido em Windows-1252; charset ignoradosó o byte inválido se torna um carácter de substituição; o charset anunciado é lido
restclient: corpo de texto de várias centenas de MBguardado três vezes em memória: um processo de 32 bits podia morrer-4 «body too large : use of_download» acima de 64 MB
restclient: cem pedidos assíncronos lançados de uma vezcem fios em paraleloseis no máximo ao mesmo tempo, os seguintes esperam a sua vez
restclient: um pedido assíncrono enviado mais vezes do que a cada 50 ms (um temporizador de telemetria)nenhuma resposta entregue enquanto o fluxo duravaas respostas chegam à medida que vêm
restclient: of_cancel de um id desconhecido; de um pedido cuja resposta chegou-1; 0 (mas era ue_response que chegava)-5; -4, tarde demais
restclient: of_response_text() após of_download; após um of_download(url, "")o número de bytes escritos; a resposta anteriorvazio: esse corpo está no ficheiro; vazio
restclient: ler uma resposta assíncrona durante ue_progressuma memória em escrita: falha possívelvazio, of_status(id) = 0 enquanto o pedido decorre
video: mudar de filme (is_source, of_play(source))o segmento, as legendas, marcadores e capítulos do filme anterior ficavampartem com ele (definidos antes de qualquer filme, esperam pelo primeiro); um filme da lista guarda as suas legendas. Defina-os depois de is_source
video: of_go_chapter, of_next_chapter, of_previous_chapterlevantavam ue_seeked; of_go_chapter além do número de capítulos devolvia 0 sem fazer nadaue_seeked e ue_chapter_changed, como um clique na barra; -5
video: of_add_source com um is_source definidoa lista nunca arrancava, of_next ia para o primeiro filmea primeira entrada carrega logo (exceto se o filme definido estiver A TOCAR: a lista segue-o no fim)
video: ue_started após of_stop ou o fim do filme, depois of_playnunca: uma vez por fontea cada nova reprodução (não ao retomar uma pausa)
video: of_play num filme em erro; of_reset; ii_rate no filme seguinte«a tocar» para sempre, sem evento; o filme anterior ficava carregado (of_duration, of_capture); regresso à velocidade normalue_failed de novo; o filme é descarregado; a velocidade mantém-se
video: of_capture para um ficheiro que não se pode escrever; para «\x» ou «C:x»-4 (a doc dizia -5); escritos conforme a pasta atual-4, e não fica nenhum ficheiro truncado; -5: dê um caminho completo
video: ecrã inteiro e depois Alt+Tab para outra aplicaçãoo filme ficava acima de tudoa outra aplicação passa à frente; voltar à sua põe de novo o filme acima de tudo
pdfviewer: um clique simples numa ligação do PDFnada: só Ctrl+clique levantava ue_link_clickedue_link_clicked(url), o documento continua visível
webbrowser: uma página data: (is_address = "data:text/html,…")mostrada, mas nenhum ue_load_completedue_load_completed com o endereço pedido
webbrowser: uma nova janela pedida pelo site para file:, data: ou mailto:aberta na vista, ue_new_window lançadorecusada: ue_error, sem ue_new_window; só se abrem http e https
webbrowser: um site que pede a câmara, o microfone, a localização, as notificaçõesaviso do navegador ao utilizador, resposta memorizadarecusado a menos que ue_permission_requested devolva true; nada é memorizado
webbrowser: cookies, sessões e armazenamento dos sitesno perfil partilhado com os componentesnum perfil de navegação próprio: uma sessão iniciada na 3.0 não é retomada (voltar a entrar uma vez); of_clear_browsing_data apaga-a
webbrowser: is_search_url sem %s, sem http(s):// ou em javascript:aceite: cada pesquisa falhava ou perdia o texto escritorecusado: ue_error, o motor em vigor mantém-se
webbrowser: gestion/ ou [::1]/x em is_address«não é um endereço» (ou uma pesquisa)https://gestion/, https://[::1]/x; a palavra sozinha continua a ser texto
webbrowser: clique direito sobre uma seleção, um link, uma imagem com ib_context_menusó Anterior / Seguinte / Recarregaralém disso: Copiar, Abrir link, Copiar endereço do link, Copiar imagem
tab: separador fechável desativado (ib_enabled = false)a cruz desaparecia mas o seu espaço ficava vazionem cruz nem espaço vazio: o separador tem a largura de um não fechável
video: of_chapters num título que contém `` ou uma tabulaçãopartido em dois capítuloslido tal como é
video: um .srt em Windows-1252 ou UTF-16acentos ilegíveis; nenhuma legendalido corretamente
commandpalette: of_open sem runtime WebView2; toaster: of_show sem runtime-1-6, como a caixa de mensagem
crypto, xml, restclient: of_open quando a página ou o cliente não pode ser criadoo código bruto da DLL (-1, -3…)-2, e is_last_error diz porquê

Se tinha contornado algum destes defeitos — por exemplo tratando ue_menu_selected com um endereço vazio para apanhar os cliques de um grupo recolhido —, retire o contorno: o evento documentado passa a chegar.

11.4 O gerador n_pbt_menu2ribbon #

Na 3.0, o código escrito por n_pbt_menu2ribbon usava métodos de handle que já não existiam: não compilava sem retoques. Na 4.0 escreve a API atual — cada adição pelo seu endereço, a partir do componente —, retoma os submenus a qualquer profundidade, mantém os itens desativados e marcados, e o seu encaminhador cobre ue_clicked, ue_toggled e ue_menu_selected. As chaves mudam: cada uma passa a ser o ClassName do item de menu (m_fichier/g1/m_ouvrir) em vez do caminho com pontos (m_principal.m_fichier.m_ouvrir).

A receita: um friso já construído à mão, ou a partir de código gerado e depois corrigido, não tem nada a mudar. Para recomeçar a partir do gerador, volte a executá-lo e cole também o novo encaminhador: o antigo lia chaves com pontos.

11.5 O que foi acrescentado #

Nada do que se segue pede para alterar o seu código. Os novos componentes da 4.0 são apresentados nas notas de versão.

ObjetoAcrescentado
ribbonof_add_menu_separator aceita o endereço de uma entrada: a linha vai para a cascata por baixo dela
ribbonof_add_menu_item e of_add_menu_check aceitam uma cascata de qualquer profundidade, e cada nível é comandado por of_menu_item(endereço)
menubarof_add_separator aceita o endereço de uma entrada (file/export): a linha vai para a sua cascata; of_menu(...) leva as cores (il_accent, il_back_color…) e a dica do título
crosstabof_set_label_filter(as_field, as_type, as_a, as_b) sobre texto (LABEL_CONTAINS, LABEL_BEGINS, LABEL_ENDS) e as constantes LABEL_GT, LABEL_LT, LABEL_BETWEEN: a forma com dois double só podia passar um número
cryptoKEYFORMAT_TEXT, KEYFORMAT_HEX, KEYFORMAT_BASE64 e uma sobrecarga de of_hmac, of_jwt_sign e of_jwt_verify que os aceita (uma chave em BYTES: segredo fornecido codificado, AWS SigV4); uma entropia opcional para of_protect e of_unprotect
cryptoof_hmac_verify (um HMAC recebido — webhook — comparado em tempo constante); of_jwt_header e uma sobrecarga de of_jwt_sign que acrescenta membros ao cabeçalho (kid); of_totp_verify(…, ref al_step), o passo aceite, para recusar um código já usado; il_password_hash_rounds
messageboxof_get_last_error(): porque é que a última caixa não pôde abrir (cadeia vazia se abriu)
n_pbt_utilsof_dir_has_subfolders(as_dir, ab_include_hidden): a mesma pergunta, contando também as pastas escondidas, de sistema e as junções
n_pbt_utilsof_dw_date_order(): a ordem pela qual um DataWindow escreve uma data neste posto (dmy, mdy, ymd)
speechoutof_is_paused(): verdadeiro enquanto a leitura está em pausa
Texto ricoa etiqueta [symbol=nome]: dezoito glifos monocromáticos que seguem a cor do texto (capítulo 4)
toolbarof_menu_item(endereço) → n_pbt_toolbar_menu_item: cada entrada de menu pendente tem o seu estado (ib_enabled, ib_visible, ib_checked, is_text, is_shortcut), designada pelo seu endereço completo
toolbaris_date num seletor de data; of_clear_menu; of_remove_item de uma entrada de menu; of_add_menu_separator numa entrada (cascata); cascatas de qualquer profundidade
pdfviewerue_load_failed(as_source, as_reason) e as constantes REASON_*; ue_link_clicked(as_url); os endereços file:///; ib_allow_save e ib_allow_print: os comandos Guardar e Imprimir da barra do leitor
pictureis_alt_text (texto alternativo lido por um leitor de ecrã); um teclado para o zoom: +, -, 0 e as setas para se deslocar; n_pbt_utils.of_json_get_str_array
webbrowseris_search_url (motor de pesquisa para palavras que não são um endereço); ib_veto_new_window e ue_new_window; ib_veto_downloads e ue_download_starting; ue_load_failed; ue_error; of_show_html; of_clear_browsing_data e ib_private; ib_veto_navigation e ue_navigating; is_title e ue_title_changed; ue_permission_requested e as constantes PERMISSION_*; as constantes LOADSTATUS_* de ue_load_failed; F5, Ctrl+R, Alt+setas e Esc na barra de endereço
jsontreeof_selected_text devolve o valor DESCODIFICADO da folha selecionada (uma cadeia sem aspas nem escapes); of_has_selection distingue a raiz, cujo caminho é "", de «nada selecionado»; o teclado salta as chavetas de fecho (já não são selecionadas)
xmltreecada atributo é um alvo: um clique dá o seu caminho (/order/@id), of_select_path seleciona-o, of_selected_value devolve o seu valor; um documento grande só desenha as linhas no ecrã (8 000 elementos irmãos: 12 s → 0,15 s, uma seta em poucos ms)
videoue_muted_changed(ab_on): o utilizador cortou ou repôs o som (o altifalante da barra, a tecla M), como o volume e a velocidade já tinham o seu evento
ribbonof_remove_menu_item, of_clear_menu, of_remove_combo_item, of_clear_combo, of_remove_gallery_item, of_remove_app_menu_item, of_remove_contextual_group: as remoções sob um controlo — uma lista «Ficheiros recentes» atualiza-se sem recriar o controlo
ribbonof_app_menu_item(endereço): o handle de uma entrada do menu da aplicação (is_label, is_image, ib_enabled, ib_checked, ib_visible); of_app_menu_item("") percorre o menu
ribbonteclas de acesso rápido de várias letras (is_keytip = "FP"), escritas uma após a outra; nomes acessíveis (barra de acesso rápido, mosaicos) para leitores de ecrã
toolbarof_add_split_button: um botão dividido (ação + menu); is_group: alternadores exclusivos (alinhamento); is_image numa ferramenta e numa entrada de menu; ue_item_rclicked(endereço): o clique direito numa ferramenta

11.6 Nomes e contagens alinhados com o resto da biblioteca #

Sete sítios falavam de maneira diferente do resto da biblioteca. A 4.0 alinha-os em vez de manter a diferença: dois nomes mudam — o compilador mostra-lhe cada linha a retocar —, o caminho devolvido pela árvore JSON passa a ser o de n_pbt_json, o da árvore XML sob um espaço de nomes predefinido um XPath que funciona, duas contagens passam a começar em 1, como toda a posição do produto, e um evento ambiente passa a ser opcional. São as únicas alterações da 4.0 que pedem para retocar código que compilava.

O quê3.04.0
progressbar: limites da escalail_minimum, il_maximum, longid_minimum, id_maximum, double: uma escala 0..1 ou um número de bytes acima de 2 GB é válido; o prefixo diz o tipo
json: índice de array num caminhoa partir de 0: lines/0 é a primeira linhaa partir de 1: lines/1 é a primeira linha; lines/0 não designa nada — uma leitura dá-o como ausente, uma escrita devolve -5
jsontree: caminho de um nó (ue_node_clicked, ue_selection_changed, of_selected_path, of_select_path)níveis unidos por um ponto, índice de array a partir de 0: lines.0.sku — um dialeto que n_pbt_json não liao caminho de n_pbt_json: níveis unidos por /, índice a partir de 1 (lines/1/sku), "" para a raiz — para passar tal como está a of_get_string sobre o mesmo texto
xmltree: caminho de um elemento sob um espaço de nomes PREDEFINIDO (xmlns="urn:…")/Envelope/Body — um XPath que não encontra nada/*[local-name()='Envelope']/*[local-name()='Body'] — para passar tal como está a n_pbt_xml.of_get_value; um elemento sem espaço de nomes ou com prefixo mantém o seu caminho
toolbar: band e index da disposição (of_get_layout, of_set_layout, ue_layout_changed)a partir de 0, uma cadeia dita «opaca» enquanto ii_band, ii_index e ue_bar_reordered contavam a partir de 1a partir de 1, como ii_band, ii_index e ue_bar_reordered; uma ida e volta leitura → restauro devolve a mesma cadeia
statictext: ue_cyclelevantado em cada ciclo do deslizamento, sem subscrição — e também por uma animação dentro do textoum evento ambiente, logo opcional: levantado só quando ib_track_cycle = true, como ue_mouse_enter com ib_track_mouse; só a cada passagem completa do texto
tilesbox: 2.º argumento de ue_tile_movedas_to_keys, embora transporte UMA chave: o grupo de destinoas_to_key: o nome diz o que transporta, como em todo o lado (as_key = um nível, as_keys = um endereço)
restclient: ue_failedue_failed (long al_id, string as_error)ue_failed (long al_id, long al_code, string as_error): -4 falha, -5 URL ou ficheiro — já não é preciso analisar o texto
restclient: of_json_valueuma chave, primeira ocorrência a qualquer profundidade; só um valor de texto — um número devolvia o nome da chave seguinteum caminho n_pbt_json ("json/customer", "items/1/qty"), qualquer valor: "4152", "true". Uma chave aninhada nomeia-se com os seus pais

A receita: (1) recompile — o compilador assinala il_minimum, il_maximum e as_to_keys: renomeie-os id_minimum, id_maximum e as_to_key; (2) procure os caminhos json que apontam para um array e some 1 a cada índice — um ciclo for i = 0 to n - 1 sobre "lines/" + String(i) passa a for i = 1 to n; (3) uma disposição de toolbar guardada pela 3.0 conta a partir de 0: some 1 a band e a index de cada barra antes de a passar a of_set_layout, ou deixe o utilizador reorganizar uma vez — relida tal como está, juntaria as suas duas primeiras bandas; (4) onde ue_cycle estiver programado, defina ib_track_cycle = true na construção; (5) onde lia um caminho da árvore JSON (ue_node_clicked, of_selected_path) ou dava um (of_select_path), substitua os pontos por / e some 1 a cada índice de array — lines.0.sku passa a lines/1/sku, que vai tal como está para n_pbt_json.of_get_string.


11.7 Os temas seguem a aplicação #

A revisão dos temas fez cada componente cumprir a regra que o capítulo 4 já anunciava: a aplicação decide o tema e o destaque, um componente só se afasta deles naquilo que lhe é pedido. Nenhum método é renomeado; o que muda vê-se no ecrã, ao reler as propriedades e em dois códigos de retorno.

O quê3.04.0
PBT_SetDefaultThememudar de tema apagava o destaque definido por PBT_SetDefaultThemeAccent — mesmo ao voltar a definir o mesmo tema — e achatava o fundo em gradiente de office2007 e office2003o destaque da aplicação mantém-se de um tema para o outro; cada tema mantém o seu fundo
PBT_GetDefaultThemeAccento destaque do tema quando a aplicação não tinha definido nenhum-1 enquanto a aplicação não tiver definido um destaque
códigos de retorno nativosPBT_SetDefaultTheme com um nome desconhecido devolvia 0 e deixava sem tema os componentes seguintes; PBT_SetDefaultThemeAccent com uma cor de sistema do PowerBuilder pintava-a de preto-5 nos dois casos; o tema ou o destaque anterior mantém-se
um eixo de tema definido sozinhocongelava o outro eixo no tema da aplicação do momentoo eixo vazio segue o tema da aplicação a cada mudança dele; os dois eixos vazios = o tema da aplicação, por inteiro
is_theme_style · is_theme_mode · il_theme_accentreliam-se "", "" e -1, fosse o que fosse definidoo estilo e o modo mostrados, e o destaque próprio do componente (-1 se não tiver)
um valor de eixo desconhecido ("office2010") ou mal escrito (" Metro ")o componente perdia o seu tema e deixava de ouvir o da aplicação até ao of_reset()espaços e maiúsculas ignorados; um valor desconhecido é ignorado e o eixo mantém o seu valor
destaque de um componente com tema localmantinha o destaque do seu tema, mesmo quando a aplicação definia umsegue o destaque da aplicação enquanto não tiver o seu
um destaque personalizadosó o destaque mudava: passagem e clique dos botões de destaque, seleções tingidas, botões marcados do friso mantinham o destaque do tematudo o que deriva do destaque o segue
tilesbox : il_badge_color0 e -1 = a cor do tema; relido 0 sem cor definida; o preto era inatingível-1 = a cor do tema (relido -1); 0 é o preto, como em todas as cores
uma cor de sistema do PowerBuilder (ButtonFace…) em il_theme_accentpintada de pretocontada como -1: o destaque da aplicação
webbrowser · pdfviewero conteúdo de terceiros seguia o modo claro/escuro do Windows, e um retângulo branco precedia a sua primeira apresentaçãosegue o tema predefinido da aplicação, sobre o fundo do tema (4.11)
acento de office-dark e office2003-darkum azul escuro, legível a 3:1 quando coloria um texto (ligações, [accent])um azul mais claro (#479ef5, #7ea1e8), com um texto escuro por cima
datagrid: linhas entre as linhasausentes em oito temas de dezpresentes nos dez temas, na cor da grelha do tema
alto contraste do Windowsos ícones monocromáticos e os anéis desenhados como sombra desapareciamsuportado (4.10)

A receita: (1) se voltava a definir o destaque depois de cada PBT_SetDefaultTheme, já não é necessário — e se contava com uma mudança de tema para apagar o destaque, chame PBT_SetDefaultThemeAccent(-1); (2) teste o código de retorno de PBT_SetDefaultTheme quando o nome vem de uma entrada ou de um ficheiro; (3) onde definia os dois eixos em cada componente para seguir a aplicação, deixe-os vazios; (4) um mosaico cujo emblema voltava «ao tema» com il_badge_color = 0 escreve-se agora -1.


11.8 crypto: o que a segurança agora recusa, e para onde vão os caminhos relativos #

A revisão de segurança de crypto fecha uma porta real — um JWT forjado com a chave PÚBLICA passava quando faltava o algoritmo — e substitui vários silêncios por uma recusa que diz a sua razão. Nenhum método é retirado; uma assinatura ECDSA muda de forma, e os caminhos relativos dos ficheiros seguem uma só regra.

O quê3.04.0
of_jwt_verify, of_jwt_signum algoritmo VAZIO valia JWT_HS256, e uma chave PEM era aceite como segredo HS256: verificado com a chave PÚBLICA como segredo, um token forjado passava; o algoritmo do cabeçalho comparava-se sem maiúsculas, um cabeçalho crit era ignoradoo algoritmo é OBRIGATÓRIO e comparado EXATAMENTE; uma chave PEM nunca é um segredo HMAC (of_hmac também); crit é recusado — cadeia vazia e is_last_error
of_jwt_signum exp dado nos claims era substituído em silêncio pela duração al_expires_secondsambos ao mesmo tempo são recusados: fique com um ou outro
of_encrypt, of_decryptuma palavra-passe VAZIA cifrava — qualquer um relia o valorrecusada, como of_encrypt_file já fazia; of_password_hash("") continua permitido
il_pbkdf2_roundsum valor fora de 1.000 a 10.000.000 voltava em silêncio a 100.000a chamada é RECUSADA: cadeia vazia para um texto, -5 para um ficheiro, e is_last_error diz os limites
of_password_hashil_pbkdf2_rounds (100.000 rondas)il_password_hash_rounds, 600.000 por omissão (o número da OWASP); os valores já guardados levam as suas rondas e continuam a verificar-se
of_base64_decode, of_base64url_decode, of_hex_decode, of_decrypt…bytes que não são um texto (um PDF, uma imagem) voltavam como caracteres de substituição, sem errocadeia vazia e is_last_error, que remete para of_base64_decode_to_file ou of_decrypt_file
of_sign (chave EC)uma assinatura IEEE-P1363 (64 bytes), que o openssl dgst e o Java recusamuma assinatura DER; of_verify lê as duas formas, uma assinatura já guardada continua a verificar-se; o JWT ES256 continua em P1363
of_totp_code, of_totp_verifyum carácter não base32 no segredo (um 0 digitado por um O) era retirado em silêncio: OUTRO segredo, códigos que nunca coincidiamrecusado (espaços e = tolerados)
of_encrypt_file«qualquer que seja o tamanho»até 64 GB, o limite de um contentor AES-GCM: além disso, -7
caminhos relativos: n_pbt_crypto, u_pbt_zip, of_capture do leitor de vídeolidos na pasta ATUAL (que muda após um DirList ou uma caixa de ficheiros), escritos ao lado do EXE (no IDE: a pasta do PowerBuilder)LIDOS na pasta atual, depois na pasta em que a aplicação arrancou, depois ao lado do EXE; ESCRITOS na pasta em que a aplicação arrancou — a mesma no IDE e compilada

A receita: (1) passe SEMPRE o algoritmo de um JWT como constante (n_pbt_crypto.JWT_RS256), nunca lido do token nem de um INI a que possa faltar; (2) se um servidor verificava as suas assinaturas EC em P1363 (.NET VerifyData por omissão), converta-as ou verifique-as em DER (DSASignatureFormat.Rfc3279DerSequence); (3) um il_pbkdf2_rounds definido fora dos limites tem de voltar para entre 1.000 e 10.000.000; (4) um ficheiro que um caminho relativo escrevia ao lado do EXE está agora na pasta de arranque da aplicação — dê um caminho completo se quiser outro.


11.9 restclient: cabeçalhos que dizem a sua recusa, redirecionamentos que mantêm o pedido #

A revisão de restclient substitui duas perdas silenciosas — uma alteração nunca feita atrás de um redirecionamento, uma autenticação nunca enviada atrás de um cabeçalho mal formado — pelo comportamento certo ou por uma recusa que diz a sua razão. Nenhum método é retirado; três passam a funções, chegam duas propriedades, e a autenticação Windows só parte se a pedir. Um ponto vale para os cinco componentes não visuais que lançam eventos: um erro no seu código de evento passa a ver-se.

O quê3.04.0
of_set_header, of_set_bearer, of_set_basicsub-rotinas: nada era devolvido, um valor mal formado era guardado tal como estavafunções long: 0, ou -5 e nada muda — nome vazio, nome com um espaço, dois pontos ou um carácter de controlo, valor com uma quebra de linha; um valor vazio retira o cabeçalho
um pedido com um cabeçalho mal formadopartia SEM NENHUM cabeçalho — Authorization incluído —, sem erro-5, e is_last_error = «invalid header: <nome>»; nada parte
redirecionamento 301 / 302 de um PUT, PATCH ou DELETEseguia em GET sem corpo: a alteração nunca era feita, e a chamada devolvia 200método e corpo mantidos; só um POST passa a GET; um 303 segue em GET sem corpo (exceto HEAD)
uma ligação reutilizada (a de um redirecionamento) que o servidor fecha no mesmo instante-4 e «request failed: 12152», de vez em quandoo pedido é reenviado UMA vez, corpo incluído, numa ligação nova: o servidor não tinha respondido nada
of_response_text ( ), of_response_headers ( ), of_response_header, of_json_valuea última resposta síncrona do PROCESSO: um segundo n_pbt_restclient substituía-aa do OBJETO; of_close esquece-a
corpo lido como texto, aplicação de 32 bitslimitado a 64 MBlimitado a 16 MB (64 MB em 64 bits): além disso, -4 «body too large» — leia-o com of_download
of_get_async, of_request_async… com um URL ou um cabeçalho inválidoum id de pedido, depois um ue_failed-5 de imediato, nenhum evento se segue; is_last_error diz porquê («invalid URL: …»)
autenticação Windows (Negotiate / NTLM)o sistema respondia sozinho ao desafio de um servidor da intranet com as credenciais da sessãodesativada por predefinição: as credenciais não vão para nenhum servidor sem ib_windows_auth = true (propriedade nova); is_client_certificate (nova) define um certificado de cliente
of_cancel (long al_id), of_status (long al_id), of_response_text (long al_id)…o id de um pedido de OUTRO objeto atingia esse pedidosó os pedidos do objeto: of_cancel devolve -5 e não cancela nada, os leitores devolvem 0 / ""
of_status (long al_id) em ue_failedpodia devolver 200: o estado de uma resposta recebida e depois perdida0 para qualquer pedido falhado
ue_failed-4 falha, -5 URL ou ficheiro-4 falha, -5 ficheiro ou certificado de cliente, -6 pedido de intervalo recusado em demo
erro de execução num evento da aplicação — restclient, speechout, soundplayer, toaster, commandpaletteengolido sem uma palavra, e os eventos seguintes deixavam de ser entregueschega ao evento SystemError da aplicação como qualquer erro de script; os eventos seguintes são entregues
il_max_retriesrepetia também uma falha que se repete de forma idêntica (demasiados redirecionamentos, redirecionamento inválido ou HTTPS → HTTP, TLS, ficheiro impossível de escrever)essas falhas já não são repetidas; 429, 503 e uma falha de rede continuam a sê-lo
URL e caminhoso fragmento #… ia para o servidor; uma Location relativa ?page=2 perdia o último segmento; um caminho relativo de of_download seguia a pasta atual do momentoo fragmento já não é enviado; Location resolvida como um navegador o faz (RFC 3986); um caminho relativo é resolvido na chamada, na pasta atual da aplicação no carregamento da biblioteca

A receita: (1) teste o que of_set_header, of_set_bearer e of_set_basic devolvem quando o valor vem de uma introdução, de um INI ou de uma base de dados — uma chamada que ignora o retorno continua a compilar, mas o -5 é agora o único vestígio de um cabeçalho recusado; (2) uma API de intranet com autenticação Windows que respondia 200 responde agora 401: defina ib_windows_auth = true NESSE cliente; (3) uma aplicação de 32 bits que lê como texto um corpo com mais de 16 MB passa a of_download; (4) se partilhava um id de pedido entre dois objetos, leia a resposta no objeto que o enviou; (5) um erro que agora aparece em SystemError a partir de ue_response ou ue_failed já existia: era engolido.

11.10 speechout: definições vivas, uma destruição silenciosa #

A revisão de speechout cumpre duas promessas que a documentação fazia e o código não — uma definição alterada durante uma leitura vale para a frase seguinte, of_speak_from para além do texto devolve -5 — e retira um evento levantado no momento errado. Nenhum método é retirado. Acrescentados: of_add_abbreviation, of_clear_abbreviations, o evento ue_mark e duas etiquetas, [mark=nome] e [rate=150]…[/rate].

O quê3.04.0
of_speak_from (al_index)para além do texto, a leitura em curso era CORTADA, nada recomeçava, e o retorno era 0-5, e a leitura em curso continua
ii_rate, ii_pitch, ii_volume, is_lang, is_voicealterados durante uma leitura, tomados só na leitura SEGUINTE (a documentação prometia a frase seguinte)propriedades vivas: a frase seguinte toma-as
ue_voice_fallbackmudo quando só faltava a REGIÃO (pedia-se fr-CA, voz fr-FR)levantado; as etiquetas de idioma comparam-se sem maiúsculas, e fr_FR vale fr-FR
destroy (n_pbt_speechout)durante uma leitura, levantava ue_stopped — numa janela já meio destruídanenhum evento; of_close() continua a levantar ue_stopped
of_sentence_count, of_counta contagem do texto lido da vez ANTERIOR (0 antes de qualquer leitura)a contagem de is_text tal como está
of_pause, of_resume, of_clear_queuecriavam a voz quando não existia; uma pausa durante a espera das vozes perdia-se0 sem criar nada, -4 se a página não respondeu; a pausa mantém-se até of_resume
ue_sentence (al_index)uma abreviatura (Mr., Dr., e.g.), um endereço soletrado ou uma versão cortavam a frase; um texto sem ponto era uma só frasejá não cortam; uma frase com mais de 250 caracteres é cortada: os números de frase podem mudar
[pause=ms]ignorada no FIM do textoum silêncio após a última frase, antes de ue_stopped

A receita: (1) teste o -5 de of_speak_from quando o índice vem de um clique; (2) se o seu ue_stopped fazia algo ao fechar a janela, chame você mesmo of_close() no seu close — a destruição já não o levanta; (3) não guarde números de frase de uma versão para a outra: tire-os de ue_sentence, como a documentação sempre disse.

11.11 statictext e texto formatado: uma marcação lida da esquerda para a direita #

A revisão de statictext corrigiu sobretudo o texto com etiquetas comum (4.7): estas linhas valem para o rótulo de qualquer componente — título de separador, painel da barra de estado, toast, caixa de diálogo. Nenhum método é retirado. Acrescentado: of_refresh_parent_color(), e as zonas [action], [hyperlink] e os cabeçalhos de [foldarea] de um statictext alcançam-se pelo teclado (Tab, depois Enter ou Espaço).

O quê3.04.0
of_escape_markup (une donnée collée à une balise)um ] escapado logo após uma etiqueta formava par com o ] da etiqueta: "[b]" + of_escape_markup("] fim") + "[/b]" mostrava [b]] fim sem negritoo dado é mostrado tal como está, e a formatação à volta mantém-se
[/b], [/i]…uma etiqueta de fecho fechava a ÚLTIMA etiqueta aberta, fosse qual fosse: [b]A[i]B[/b]C deixava C a negrito; [/br] também fechava algouma etiqueta de fecho só fecha a sua (os estilos abertos dentro continuam); uma etiqueta de fecho sem abertura, ou a de uma etiqueta auto-fechada, é ignorada
[picture=…]cortada na primeira vírgula: um data URI (o que of_icon() devolve) ou um nome de ficheiro com vírgula não apareciaas dimensões leem-se no fim do valor: ambos aparecem
[picture=\\server\share\x.png]a imagem era lida na partilha de rederecusada: uma imagem da marcação nunca vai buscar uma partilha de rede. Deve passar por of_icon(), que a incorpora, ou por um picture
[hyperlink=HTTPS://…]um esquema em maiúsculas não era abertoaberto: o esquema lê-se sem distinguir maiúsculas; a lista continua http, https, mailto
ii_padding0 = a margem do tema: um rótulo nunca podia alinhar-se com o bordo de um campo vizinho-1 = a margem do tema (nova predefinição), 0 = nenhuma margem
ue_clicked, ue_double_clickedlevantados ao dobrar um [foldarea] (três eventos para um duplo clique), e ao soltar o rato depois de uma seleção de textojá não são levantados: dobrar é uma questão de leitura
[foldarea:… [action=…]]levantava ue_action E dobrava o blocosó ue_action, o bloco fica como está
ii_line_spacing, is_marquee_directionum valor fora de 50-400 era ignorado e relido 0; um sentido desconhecido ("UP") deslocava-se para o início mas relia-se tal como estava escritolevado ao limite mais próximo, relido tal como aplicado; um sentido desconhecido vale e relê-se MARQUEE_START
of_scroll_to_endnão devolvia nadadevolve 0, ou -2 se o componente não estiver criado

A receita: (1) um ii_padding = 0 escrito para dizer «a margem do tema» passa a -1 — ou desaparece; (2) uma imagem da marcação guardada numa partilha de rede passa por of_icon(); (3) um ue_clicked que reagia ao dobrar de uma secção deixa de ser chamado: o dobrar não se programa.

11.12 breadcrumb: o que cede quando o caminho não cabe, e sair do campo #

A segunda revisão do trilho de navegação (breadcrumb) corrigiu o dobrar pela largura, o modo OVERFLOW_SHRINK e o que um segmento leva consigo. Nenhum método é retirado. Uma linha vale para todos os menus nativos da biblioteca: a pesquisa por escrita.

O quê3.04.0
of_edit() sans / without ib_editabledevolve 0, nada se abredevolve -4
sair do campo do caminho para outro controlo da aplicaçãoo campo ficava aberto, o texto a meio, e nada era comunicadoum texto alterado é validado: ue_path_entered; passar para outra aplicação continua a manter o que foi escrito
OVERFLOW_SHRINKtodas as etiquetas limitadas a 12 caracteres, mesmo com espaço; o local actual cortado a direito no bordo da barranada é cortado enquanto houver espaço; o meio cede primeiro, até uma letra e …, o primeiro segmento e o local actual por último
OVERFLOW_COLLAPSEa etiqueta do local actual podia ser encurtada antes de o meio se dobraro meio dobra-se primeiro; o local actual só é encurtado em último recurso
of_insert_item(…, ai_index)os handles dos segmentos deslocados designavam outro segmento, as suas cores e tooltips ficavam no endereço antigoos seus handles são libertados, as suas cores e tooltips seguem-nos; um segmento retirado (of_clear, of_truncate, of_remove_item) leva os seus
of_item("b").il_back_color / of_item("a/b").il_back_colordois valores para o mesmo segmentoum só: a chave única e o endereço designam o mesmo segmento
OVERFLOW_SCROLL, roda do ratosem efeitofaz deslizar a faixa
os menus nativos (ramos do trilho, friso, barra de menus, barra de ferramentas, menu de contexto): uma letra escritanão fazia nada, exceto mnemónicasas letras escritas no mesmo segundo saltam para a primeira entrada que começa assim («Win»), como no explorador; um menu com mais de 500 entradas só desenha o que se vê

A receita: (1) um of_edit() cujo 0 testava sem ter definido ib_editable devolve agora -4; (2) um ue_path_entered pode chegar quando o utilizador clica noutro sítio da janela — é o mesmo texto que com Enter; (3) depois de um of_insert_item a meio do trilho, volte a pedir os handles dos segmentos que se seguem.

11.13 buttonbar e teclado da janela: a tecla vai para o componente do foco #

A segunda revisão da barra de botões (buttonbar) tocou no teclado da janela, partilhado por todos os componentes que respondem ao Enter, ao Esc, a uma letra Alt ou a um atalho registado (button, buttonbar e os atalhos de of_register_shortcut de todos os componentes). Nenhum método é retirado; um é acrescentado, of_focus_button.

O quê3.04.0
dois componentes da mesma janela respondem ao Enter, ao Esc ou ao mesmo atalho (duas folhas MDI, dois painéis)recebia-a o primeiro criado, mesmo na outra folhao mais próximo do foco (mesma folha, mesmo painel); em empate, nenhum: a tecla fica com a janela
Enter num CommandButton PB com o foco, ou numa DropDownListBox aberta; Esc numa lista abertaacionava o botão predefinido / cancelar do componentefica com o controlo, como numa caixa de diálogo do Windows
of_register_shortcut(chord, key) num botão da barra, depois o botão desativado e reativado, ou a sua letra is_shortcut alteradao atalho era apagadomantido: a letra Alt e o atalho da aplicação já não se tocam
a letra Alt de um botão perante um atalho explícito da mesma teclaganhava o primeiro registadoganha o atalho explícito; as letras só são consultadas depois
of_clear_shortcuts()apagava também o is_shortcut de um buttonsó apaga os atalhos da aplicação
buttonbar: of_register_shortcut(chord) sem chave, ou com uma chave que não nomeia nenhum botãodevolvia 0 e engolia a tecla sem acionar nadadevolve -5
buttonbar: remover o botão de is_default / is_cancel, ou esvaziar a barraa propriedade mantinha a chave; um botão acrescentado de novo com essa chave voltava a ser o predefinidoesvaziada: o papel sai com o seu botão
buttonbar: outro botão da barra tem o focoo acento ficava em is_default enquanto o Enter acionava o botão com o focoo botão com o foco tem o aspeto predefinido; is_default relido fica inalterado
buttonbar: um ii_padding_x negativovoltava a 12o recuo do tema, como ii_padding_y e ii_gap
buttonbar: a linha separadora entre botõesdesenhada a meio do espaço, mesmo quando os botões não se tocavamsó entre botões juntos (ii_gap = 0), e do lado certo na leitura da direita para a esquerda

A receita: (1) numa barra, dê um atalho a UM botão — of_register_shortcut("Ctrl+S", "save") — a forma sem chave devolve -5; (2) depois de remover e voltar a acrescentar o botão predefinido, volte a definir is_default; (3) para pôr o foco num botão preciso («Não» em vez de «Sim»), chame of_focus_button("no").

11.14 button: um botão esbatido larga a tecla, e Alt+letra responde #

A revisão do botão (button, obsoleto a favor de buttonbar mas ainda entregue e corrigido) muda o que faz no teclado e o que as suas propriedades releem. Nenhum método é retirado nem acrescentado.

O quê3.04.0
um botão esbatido com ib_default, ib_cancel ou is_shortcut (ib_enabled = false)retinha o Enter, o Esc ou o seu atalho em toda a janela: a tecla perdia-sedevolve a tecla à janela (um CommandButton PB predefinido, um SingleLineEdit recebem-na); reativado, retoma-a
o & de is_text (&Guardar)sublinhava a letra, nada maisAlt + a letra aciona o botão onde quer que esteja o foco na janela, depois dos atalhos explícitos, nunca esbatido; uma barra de menus PB que usa a mesma letra perde-a
Enter ou Espaço mantidos no botão com o focouma rajada de ue_clicked; o Espaço disparava ao premirum único ue_clicked; o Espaço dispara ao largar, como no Windows
um is_shortcut que a janela não sabe acionar ("Win+S", "Ctrl+Entrée", "Ctrl+Pause")relia-se tal e qual; "Win+S" disparava o botão com um S simplesrecusado: relê-se "". Os nomes das teclas escrevem-se em inglês (Enter, Esc, Del)
is_shortcut com um tooltipo atalho não aparecia em lado nenhumacrescentado ao tooltip (ao título de um enriquecido): «Guardar (Ctrl+S)»
of_register_shortcut("F5") no botão, depois ib_default, ib_cancel ou is_shortcut alteradoso F5 era apagadoo F5 e o is_shortcut respondem os dois
is_text, is_image, is_style, ii_badge, il_badge_color, ii_badge_size, ii_image_size lidos depois de of_reset()o valor antigo, embora o ecrã estivesse repostoo seu valor predefinido ("", "standard", 0, -1)
um botão esbatido e a tecla Tabrecebia o focoé saltado
uma etiqueta feita só de uma imagem ([picture=…]), ou um & numa etiquetaa etiqueta desaparecia, ou a marca era partidaapresentados como escritos

A receita: escreva os nomes das teclas de is_shortcut em inglês ("Ctrl+Enter") e releia a propriedade em caso de dúvida: "" significa recusado. Se esbatia um botão predefinido para «desativar o Enter», nada a mudar: é o que acontece agora.

11.15 menubar: uma barra de menus que devolve o foco, e Alt+letra de qualquer lado #

A revisão da barra de menus (menubar) muda o que faz com o foco e o teclado, e o que fazem todos os menus nativos em escrita da direita para a esquerda. Nenhum método é retirado nem muda de assinatura.

O quê3.04.0
um clique na barra e depois uma escolha (Editar > Colar)a barra ficava com o foco: GetFocus() em ue_item_selected já não nomeava o campo, a colagem perdia-seo foco volta ao controlo anterior antes de ue_item_selected partir; o mesmo com Esc e com um clique fora
Alt+F mantido, ou F10, com o foco num camponada: só Alt tocado e depois F abria FileAlt+F abre File a partir de qualquer controlo, F10 faz o que Alt faz; um Alt+F registado pela sua aplicação mantém a prioridade, e um menu PowerBuilder nativo na mesma letra perde-a
Ctrl++, Ctrl+-, Ctrl+,, Alt+Left, Ctrl+Space, Ctrl+Tab, Ctrl+Backspace (todos os componentes com atalhos)mostrados, mas nada partia de um controlo PB; o button recusava-os ("")disparados esteja onde estiver o foco; estas teclas exigem Ctrl ou Alt (sozinhas, continuam a ser navegação)
em RTL, os menus pendentes de todos os menus nativos (barra de menus, friso, barra de ferramentas, breadcrumb, menu de contexto…)alinhados à esquerda, cascatas à direita, chevron ›, Esquerda fechavao menu pendente fica alinhado à direita sob o título, uma cascata abre-se à esquerda (chevron ‹): Esquerda abre, Direita fecha
um clique no título de um menu já abertofechava-o e depois reabria-o (um segundo ue_menu_opening)fecha-o, como no Windows
um is_shortcut posto numa entrada que abre uma cascatamostrado, e levantava ue_item_selected("file/export"), um endereço que nenhum clique produznem mostrado nem disparado: um atalho vai numa folha
uma barra cujos menus estão todos ocultos ou esbatidos, ao lado de um frisotomava Alt para nada: as keytips do friso já não apareciamdevolve Alt ao friso enquanto nenhum título for alcançável
dois títulos com a mesma letra (&Ficheiro, &Favoritos)Alt+F abria sempre o primeirona barra, a faixa passa de um para o outro, Enter abre
uma entrada retirada e depois acrescentada no mesmo endereço (uma lista de ficheiros recentes)retomava as cores e a dica da desaparecidanasce sem cor (il_back_color relido -1); o mesmo após of_remove_menu e of_clear
uma letra acentuada ou não latina num menu pendente (&Édition)sublinhada, mas nenhuma tecla a alcançavatecla-se como no teclado
a tecla Tab na barrauma paragem por títulouma só paragem para toda a barra; as setas passam de um título ao outro
novo—is_image (o ícone de uma entrada, mudado a quente), is_group (entradas de opção), ue_menu_closed(as_key) (um menu pendente fechado sem escolha)

A receita: em ue_item_selected, trabalhe sobre GetFocus() ou sobre o DataWindow em edição como com um menu PowerBuilder; ponha um & em cada título; se a sua aplicação usava Alt+letra para outra coisa, registe-o (of_register_shortcut): mantém a prioridade.

11.16 ribbon: uma escolha que se mantém, menus que ficam abertos, recusas que se dizem #

A segunda revisão da faixa (ribbon) corrige o que o utilizador via — uma escolha de tipo de letra desfeita, um menu que se fechava sob o ponteiro — e aplica à faixa a regra da biblioteca: uma adição ou remoção impossível devolve -5. Nenhum método é retirado nem muda de assinatura.

O quê3.04.0
ribbon: uma escolha na lista de uma caixa de combinação e depois a saída do campoue_combo_changed duas vezes — a escolha, depois o texto escrito antes, que a sobrepunha; is_text relia o texto escritoum único ue_combo_changed, a escolha; o campo mostra-a de imediato, mesmo numa caixa não editável
ribbon: Enter ou Escape numa caixa de combinação, num contador, ou num botão da faixa com o focoiam também para o botão predefinido ou de cancelamento da janelaficam na faixa; Escape num campo repõe o texto de antes da escrita
ribbon: um menu aberto enquanto a aplicação atualiza a faixa (outro controlo ocultado, um separador renomeado, um mosaico acrescentado)fechava-se, e a escolha feita nele não acionava nenhum eventofica aberto; só se fecha se o seu próprio controlo desaparecer, for ocultado ou desativado
ribbon: is_app_button reescrito («File» → «Ficheiro»); is_app_button = ""o menu da aplicação era esvaziado; uma cadeia vazia mostrava «File»o menu fica; uma cadeia vazia retira o botão e o seu menu
ribbon: of_select_tab de um separador desconhecido ou oculto0-5, nada muda
ribbon: acrescentar uma entrada de menu, um mosaico, uma escolha de caixa de combinação, um botão de acesso rápido, uma entrada do menu da aplicação ou um grupo contextual com uma chave já usada; uma chave com uma barra vertical ou a começar por __; um pai desconhecido (separador, cabeçalho, escolha, entrada sem botão da aplicação, separador sob um grupo contextual ausente)0: um duplicado, ou nada (um separador contextual sem faixa)-5
ribbon: of_remove_tab, of_remove_group, of_remove_item, of_select_gallery_item num endereço desconhecido; of_open num botão de acesso rápido0, sem efeito-5. of_open("separador/grupo") abre o painel de um grupo recolhido
ribbon: um handle of_qat_item mantido depois de of_remove_item do seu botãocontinuava válido e designava um botão desaparecidolibertado: IsValid() devolve false
ribbon: teclas de acesso rápido — dois controlos com a mesma letra, um deles oculto; um controlo de um grupo recolhidoo oculto roubava a letra e nada era executado; a letra de um grupo recolhido não fazia nada; uma tecla de duas letras nunca respondiasó responde um controlo visível e ativo; a letra abre o painel do grupo recolhido; "FP" escreve-se letra a letra
ribbon: setas do teclado num botão dividido, seletor de cor, caixa de combinação ou galeria desativadosparavam neles, sem nada poder fazersaltam-nos; Baixo num botão pendente ou dividido abre o seu menu

A receita: (1) ue_selection_changed e ue_minimized são lançados também quando o seu código chama of_select_tab ou define ib_minimized, como num clique: se chamava o seu tratamento logo atrás, retire essa chamada, correria duas vezes; (2) teste o -5 das adições se a sua construção puder repetir uma chave; (3) um is_app_button = "" que queria dizer «File» escreve-se agora is_app_button = "File". As remoções sob um controlo e o handle de uma entrada do menu da aplicação estão na tabela 11.5.

11.17 toolbar: uma regra de atalhos, uma só dica, recusas que se dizem #

A segunda revisão da barra de ferramentas (toolbar) alinha os seus atalhos com os da janela e torna visível o que era escrito sem efeito. Nenhum método é retirado nem muda de assinatura; surgem dois códigos de retorno (-5).

O quê3.04.0
uma ferramenta com is_shortcut = "Delete" (uma tecla sozinha) e um campo na barraDelete no campo despoletava a ferramenta e não apagava nada; fora da barra, nadauma tecla sozinha nunca é um atalho: é preciso Ctrl ou Alt, ou de F1 a F24 — a regra da janela
uma tecla de atalho mantida premida (todos os componentes)a ação repetia-se: um alternador piscavauma ação por pressão
of_register_shortcut(acorde, chave) herdado, numa toolbarnão despoletava nada, e a tecla era engolidarecebe o endereço da ferramenta ou da entrada ("main/save"), -5 caso contrário; a forma de um argumento devolve -5; of_clear_shortcuts também esvazia is_shortcut
o atalho de um campo, de um seletor de data, de uma etiquetaengolia a tecla sem fazer nadao campo recebe o cursor (Ctrl+F numa pesquisa), o seletor abre o seu calendário; uma etiqueta não aceita nenhum
a dica dada ao acrescentar (of_add_button(…, tooltip))etiquetas mostradas à letra; duas bolhas ao mesmo tempo se is_tooltip fosse posto depoisuma só dica com tema, texto rico, o atalho no fim; is_tooltip substitui-a e relê-se
of_add_bar(MAIN_BAR) depois de uma primeira ferramenta em maindevolvia 0 sem fazer nada-5: para a posicionar, acrescente main antes de qualquer ferramenta
of_set_layout de um texto que não é JSONdevolvia 0-5
ue_layout_changedausente quando acrescentar uma barra empurrava outra; despoletado ao mostrar uma barra já visíveldespoletado no primeiro caso, já não no segundo
separadores, menu pendente ou cascata cujas entradas estão todas ocultastraços órfãos; o menu pendente e a cascata ficavam ativos e mudosnenhum traço no início, no fim ou duplicado; são desenhados a cinzento
um clique direito na barranenhum evento, ue_rclicked incluídoue_item_rclicked(endereço) numa ferramenta, ue_rclicked fora de qualquer ferramenta — nunca os dois
as cores de uma entrada de menu (of_menu_item(…).il_back_color)escritas e relidas, nunca desenhadasdesenhadas no menu
toolbar: ue_rclicked, ue_mouse_enter, ue_mouse_leavedocumentados, mas nunca lançadoslançados: um clique direito na barra fora de qualquer ferramenta, a entrada e a saída do rato

A receita: (1) um atalho de ferramenta numa tecla sozinha (fora F1 a F24) leva Ctrl ou Alt; (2) numa toolbar, of_register_shortcut recebe o endereço da ferramenta ou da entrada; (3) para posicionar a barra main, chame of_add_bar(MAIN_BAR, banda, posição) antes da sua primeira ferramenta.

11.18 statusbar: uma pega que redimensiona, uma mensagem que não substitui o texto #

A segunda revisão da barra de estado (statusbar) dá à pega de redimensionamento o seu verdadeiro papel e faz de cada chave vazia ou desconhecida uma recusa. Nenhum método é retirado nem muda de assinatura; of_flash_panel ganha um código de retorno (-5).

O quê3.04.0
ib_show_resize_grip = true, depois arrastar a pegaum desenho: nada se mexea janela redimensiona-se pelo canto (inferior esquerdo em RTL); a pega não é desenhada numa janela maximizada ou sem rebordo redimensionável
of_flash_panel numa chave que a barra nunca recebeu, ou num endereço0, nada é mostrado-5
of_panel(k).is_text relido durante um of_flash_panela mensagemo texto do painel (a mensagem passa por cima)
of_panel(""), of_panel("a/b"): escrita e releituraescrevia nos painéis sem chave e nos separadoresnão designa nada: não escreve em lado nenhum, relê-se vazio
is_state fora das constantes STATE_* ("Error", "very bad")relido tal como está, sem cor; um valor com um espaço provocava um erro de scriptas maiúsculas são ignoradas ("Error" = erro); qualquer outro valor equivale a « nenhum estado » e relê-se vazio
ii_progress = 150 e depois relido150 (desenhado a 100 %)100, o que está desenhado
um painel desativado com um estadomantinha a cor do estado: parecia ativoa cinzento, marca de estado incluída
um painel retirado, esvaziado (of_clear, of_clear_menu), desativado ou ocultado enquanto a sua lista está abertaa lista ficava aberta, e uma escolha acionava ue_panel_menu_clickeda lista fecha-se, nada é acionado (o mesmo para uma entrada que ficou a cinzento ou oculta)
duplo clique num painel com lista pendenteue_panel_double_clicked além da lista abertasó a lista
Seta para cima / baixo num painel com lista pendente que tem o focopassava ao painel vizinhoabre a lista (as setas Esquerda / Direita continuam a deslocar)
uma lista pendente feita apenas de separadoresseta e lista vaziasem lista: o painel continua a ser o que ib_clickable diz

A receita: (1) defina ib_show_resize_grip numa barra de estado colocada no fundo de uma janela redimensionável; (2) teste o retorno de of_flash_panel como o dos outros métodos com chave; (3) dê uma chave a cada painel que quiser reler ou modificar.

11.19 dockcontainer: um of_select_panel que encontra o painel, janelas flutuantes que se lembram #

A segunda revisão do contentor de painéis (dockcontainer) dá a of_select_panel um efeito sobre um painel recolhido ou flutuante, e faz a disposição lembrar-se das janelas flutuantes. Nenhum método é retirado nem muda de assinatura.

O quê3.04.0
of_select_panel de um painel recolhido, flutuante ou oculto0, nada se vêrecolhido: o seu painel deslizante abre-se; flutuante: a sua janela passa para a frente; oculto: -5
of_float_panel do painel principal ou de um painel oculto0, nada acontece-5
of_move_panel que empilha o painel PRINCIPAL0, e o seu vizinho desaparece sem separador-5, nada se mexe
as_position desconhecida (of_add_panel, of_move_panel)0, o painel acopla-se em baixo-5, o controlo não é tocado
disposição (of_get_layout, ue_layout_changed, of_set_layout) e painéis FLUTUANTESesquecidos: um painel destacado voltava acoplado; deslocar a sua janela não disparava nadaguardados com o lugar da sua janela, reabertos ao repor (trazidos de volta para um ecrã); deslocar ou redimensionar a janela dispara ue_layout_changed
of_set_layout de uma disposição sem painel principalo painel principal atual é retiradoé mantido
is_title de um painel adicionado sem títuloa sua chave; um título dado depois ao painel principal não fazia aparecer o seu cabeçalho"" (o separador continua a mostrar a chave); o cabeçalho do principal segue o seu título

A receita: (1) ue_panel_selected, ue_panel_floated e ue_panel_pinned são lançados também após of_select_panel, of_float_panel e ib_pinned, como num gesto: se chamava o seu tratamento logo atrás, retire essa chamada, correria duas vezes; (2) teste o -5 de of_move_panel, of_float_panel e of_select_panel; (3) uma disposição gravada antes da 4.0 repõe-se tal como está, os seus painéis continuam acoplados.

11.20 tab: códigos de retorno honestos, um clique direito que volta à aplicação #

A segunda revisão dos separadores (tab) faz of_add_page e of_select_page dizerem o que recusam, anuncia a disposição quando o seu código oculta um separador, e devolve o clique direito à aplicação quando o menu integrado está desligado. Nenhum método é retirado nem muda de assinatura; é acrescentado um evento.

O quê3.04.0
of_add_page de um controlo já alojado (por este separador com outra chave, ou por outro componente)0, e um separador sem nada por trás-5, nada é acrescentado
of_select_page de um separador recusado quando nenhum está ativo (todos ocultos)0-5
Ocultar ou voltar a mostrar um separador pelo seu código (ib_visible)nenhum ue_layout_changedue_layout_changed disparado com a disposição inteira, como para of_move_page: é o aviso de que a disposição a guardar mudou
Clique direito num separador com ib_context_menu = falsenadao separador é selecionado e depois é disparado ue_tab_rclicked(as_key) (novo): abra aí o seu menu
Voltar ao separador atual enquanto ue_selection_changing espera a sua respostauma resposta «sim» ativava mesmo assim o outro separadora pergunta é anulada: vence o último gesto do utilizador
Um separador desativado ou oculto enquanto ue_tab_closing espera a sua respostafechava mesmo assimpermanece aberto
Fechar pelo teclado (Delete) o separador que tem o focoo foco saía da barra, as setas deixavam de respondero foco passa para o separador que ficou ativo

A receita: (1) teste o -5 de of_add_page (uma página só se aloja uma vez) e de of_select_page; (2) se grava a disposição em ue_layout_changed, nada a fazer — passa a seguir também os seus ib_visible; (3) onde ib_context_menu = false deixava o clique direito sem resposta, programe ue_tab_rclicked.

11.21 listbar: uma entrada oculta nunca selecionada, uma disposição verificada #

A segunda revisão da barra de navegação (listbar) faz of_select_item recusar uma entrada oculta e of_set_layout um texto que não é uma disposição, e acrescenta uma pastilha de contador, as teclas Esquerda / Direita e o clique direito numa entrada. Nenhum método é retirado nem muda de assinatura.

O quê3.04.0
of_select_item de uma entrada oculta (ib_visible = false)0, uma seleção invisível-5, a seleção não se move; ocultar a entrada já selecionada mantém-na selecionada
of_set_layout de um texto que não é um objeto JSON (ficheiro truncado)0, nada é aplicado-5, nada é enviado
Secção recolhida numa disposição reposta, acrescentada mais tardenasce recolhidanasce expandida: o recolhimento só vale para uma secção presente
Secção com título vazioas suas entradas coladas às de cima; recolhível, sem nada para a reabrirum espaço (um filete no trilho) separa-a; nunca se recolhe
Novo: is_badge (entrada), ue_item_rclicked(as_keys), Esquerda / Direita e salto por letra—uma pastilha de contador, o clique direito numa entrada (um só evento, a entrada não é selecionada), o recolhimento pelo teclado

A receita: (1) ue_selection_changed é lançado também após um of_select_item do seu código (abrir a página inicial no arranque, por exemplo), como num clique: se abria a página logo atrás, deixe isso ao evento, senão abriria duas vezes; (2) teste o -5 de of_select_item se ocultar entradas, e o de of_set_layout se a disposição vier de um ficheiro; (3) uma secção sem título já não se recolhe: dê-lhe um título se tiver de se recolher.

11.22 tilesbox: um título que já não cria grupos, a reorganização pelo teclado #

A segunda revisão do painel de mosaicos (tilesbox) impede o título de um grupo de criar esse grupo, faz of_add_live_item recusar um texto vazio, dá uma única paragem de tabulação por grupo e acrescenta a reorganização pelo teclado. Nenhum método é retirado nem muda de assinatura. il_badge_color segue agora a regra de todas as cores (veja a linha picture, button, tilesbox mais acima).

O quê3.04.0
of_group(chave).is_title num grupo nunca adicionadocriava um grupo visível que não se podia encher nem retirar (exceto com of_clear)não escreve nada: só of_add_group cria um grupo; uma chave vazia, ou com / ou ``, dá um handle inerte
of_add_live_item com um texto vazio0, e o texto fixo is_live_text era apagado-5, nada muda
of_tile(endereço).of_count()0o número de faces postas por of_add_live_item
Reorganizar (ib_reorderable = true)só com o ratotambém pelo teclado: Ctrl+Esquerda/Direita no grupo (sentido de leitura), Ctrl+Cima/Baixo para o grupo vizinho; os mesmos ue_tile_moved e ue_layout_changed
Tecla Tabparava em cada mosaico; uma seta para um bordo sem vizinho saltava para o mosaico anterior ou seguinte do documentouma paragem por grupo (o último mosaico com foco), as setas percorrem os mosaicos; no bordo, o foco fica
Mosaico desativado ou oculto enquanto é arrastadodeslocado ao largar, ue_tile_moved disparadoo arrasto é abandonado, nada se move
ib_collapsed de um grupo definido pelo seu códigonenhum eventoue_group_toggled, como um clique no cabeçalho (nada quando o grupo já está nesse estado)

A receita: (1) crie um grupo com of_add_group antes de mudar o seu título; (2) teste o -5 de of_add_live_item se o texto de uma face puder estar vazio; (3) o que fazia em ue_tile_moved vale agora também para um deslocamento pelo teclado.

11.23 stepbar: «tudo concluído» ancorado na última etapa, etapas retiradas que já não deixam nada #

A segunda revisão da barra de etapas (stepbar) torna «tudo concluído» coerente com a regra da etapa atual (uma identidade, não uma posição), faz uma etapa retirada levar o que lhe pertencia e corrige quatro defeitos de apresentação. Nenhuma assinatura muda.

O quê3.04.0
of_add_step quando a barra está em «tudo concluído»a etapa adicionada aparecia concluída (visto); ii_current passava a n + 2 sem eventoadicionada depois da última etapa de então, torna-se a etapa atual e ue_step_changed é lançado; inserida antes, nada muda
of_step(chave).is_state numa chave que não designa nenhuma etapaguardado e depois aplicado à etapa adicionada mais tarde com esse nomeignorado; uma etapa adicionada nasce com o seu estado calculado
Cores e dica de uma etapa retirada (of_remove_step, of_clear_steps)voltavam na próxima etapa adicionada com a mesma chavepartem com a etapa
Barra compactada (OVERFLOW_AUTO) cuja etapa atual está forçada em erronenhum rótulo; uma etapa forçada a STATE_CURRENT ganhava o seuo rótulo fica na etapa atual (a posição de ii_current), seja qual for o seu estado
OVERFLOW_SHRINKrótulos em várias linhas, palavras longas cortadas sem «…»uma linha por rótulo, terminada em «…»
POSITION_BOTTOM com uma segunda linha (is_description)acima do rótulo, colada a elesob o rótulo, acima do marcador
Passar o rato sobre uma etapa desativada ou fora de alcance (il_back_color_hover, il_text_color_hover)a cor ao passar acendianada acende: a etapa não responderá ao clique

A receita: se o seu código adiciona uma etapa depois de definir «tudo concluído» (ii_current = of_count() + 1) e quer que a barra continue assim, volte a definir ii_current = of_count() + 1 após a adição. Se reconstrói a barra com as mesmas chaves, volte a definir as cores e dicas desejadas: já não sobrevivem à retirada.

11.24 progressbar: uma barra que cabe no seu controlo, uma etiqueta que segue o idioma #

A segunda revisão da barra de progresso (progressbar) faz com que caiba onde estava uma HProgressBar, só envia ao componente os valores que mudam o desenho, escreve a percentagem no idioma de apresentação e acrescenta is_label_format (uma etiqueta sua) e is_state (pausa, erro). Nenhuma assinatura muda.

O quê3.04.0
Barra linear num controlo baixo ou largomargem de 12 px, 640 px de largura no máximo: abaixo de 24 px de altura aparecia uma barra de deslocamento e a barra ficava cortadamargem de 2 px, toda a largura; a pista (14 px) e a etiqueta encolhem com a altura
Etiqueta da percentagem (ib_label)«50%» em todos os idiomasno idioma de apresentação: «50 %» em francês
of_set_property("value", "12,5"), ou um texto que não é um númeroenviado tal como estava: o comando perdia-se sem dizer nada; um minimum inválido bloqueava a escala até ao próximo of_reset«12,5» é lido 12.5; um texto que não é um número (nem true/false para um booleano) é ignorado
id_value relidoo valor que o componente tinha recebido; cada atribuição era uma ida e volta com eleo último valor atribuído pela aplicação; o componente só recebe os que mudam o desenho (uma décima de ponto percentual)
of_reset() numa barra cheiaa barra descia a zero deslizandovolta a zero de uma vez

A receita: (1) se calculava uma percentagem à mão, defina id_maximum e atribua o valor bruto, em cada linha se quiser; (2) se um teste automático lia a etiqueta, conte com o formato do idioma de apresentação; (3) para mostrar uma pausa ou um erro, prefira is_state a uma cor escolhida com il_color.

11.25 picture: uma atribuição relê o ficheiro, uma falha diz o motivo #

A segunda revisão da imagem (picture) faz com que releia o disco em cada atribuição, como o Picture nativo, dá a ue_error um segundo argumento que diz porque falta a imagem, recusa um endereço http:// em vez de falhar sem motivo e só emite um ue_clicked num duplo clique. ue_error é a única assinatura que muda.

O quê3.04.0
picture: duplo clique na imagemdois ue_clicked e depois ue_double_clickedum só ue_clicked e depois ue_double_clicked — como o Picture nativo
picture: ue_errorue_error (string as_message): só a mensagemue_error (string as_message, string as_reason): as_reason é uma das constantes REASON_* (não encontrado, demasiado grande, http recusado, formato não apresentado, outro). O seu script do evento recebe o argumento por si; uma chamada event ue_error(…) escrita no seu código passa agora dois
picture: is_source = "http://…"tentado em https pelo motor; num servidor sem TLS, uma falha sem motivorecusado logo à partida: glifo de erro e ue_error com REASON_INSECURE. Descarregue primeiro a imagem (n_pbt_restclient.of_download) e apresente o ficheiro
picture: o mesmo caminho atribuído de novo depois de reescrever o ficheiro; mono: ou tint: em is_source; uma imagem .avifa imagem antiga; o glifo de erro; não encontradao ficheiro relido, como o Picture nativo; o glifo recolorido pelo tema; apresentada
picture: imagem ampliada mais pequena do que a moldura (faixas); roda horizontal, painel tátil; botão direito premidosaía da moldura ao arrastar; um passo de zoom por evento, afastamento num deslocamento horizontal; a imagem deslocava-sefica onde is_align e is_valign a colocam; zoom proporcional ao gesto, nada num deslocamento horizontal; só o botão esquerdo desloca

A receita: (1) se um script abria uma ficha em ue_clicked e outra ação em ue_double_clicked, nada a fazer — o duplo clique já não reabre a ficha; (2) substitua qualquer análise do texto de as_message por um teste de as_reason; (3) uma imagem de um servidor de intranet em http descarrega-se primeiro (n_pbt_restclient.of_download para uma pasta temporária) e depois apresenta-se pelo seu caminho; (4) se acrescentava um ?v= ao caminho para forçar a releitura de uma imagem reescrita, retire-o: voltar a atribuir basta.

11.26 video: legendas e formatos que se reproduzem, uma falha que diz o motivo #

A segunda revisão do leitor (video) dá a ue_failed um segundo argumento que diz porquê um filme não toca, recusa um endereço http://, reproduz .mkv e .mov, carrega as legendas dadas por URL, e põe o filme em pausa quando o componente fica oculto. ue_failed é a única assinatura que muda.

O quê3.04.0
video: ue_failedue_failed (string as_message)ue_failed (string as_message, string as_reason) — as_reason é uma constante REASON_*
video: uma fonte http://falhava como « não encontrado »recusada de imediato, REASON_INSECURE; só https se reproduz
video: um .mkv, um .mov.mkv « não encontrado », .mov recusado pelo nomeservidos e reproduzidos quando o motor os descodifica; .avi, .wmv, .flv continuam recusados (REASON_FORMAT)
video: uma legenda dada por URLnunca aparecia, sem dizer nadadescarregada pelo componente (o servidor tem de autorizar CORS); uma recusa lança ue_subtitles_failed
video: of_add_subtitles duas vezes para o mesmo idiomasubstituía a faixa em silêncio, 0-5 (também para um idioma com / ou `); of_remove_subtitles` primeiro
video: o componente oculto durante a reproduçãoo filme continuava, com somem pausa, ue_paused, e espera por of_play (ib_pause_when_hidden, verdadeiro por omissão)
video: arrastar o volume na barraum ue_volume_changed por píxelum só, ao largar
video: of_capture para um .jpgum PNG com um nome .jpgum JPEG; a sobrecarga of_capture(as_path, al_max_width) reduz a imagem
video: of_get_last_error após uma falha de of_captureo erro anterior da bibliotecao motivo DESTA falha (pasta ausente, caminho vazio…)
video: Escape em ecrã inteiro, ib_enabled = falsesem efeito (só Alt+F4 saía)sai do ecrã inteiro

A receita: (1) acrescente as_reason ao seu script de ue_failed e teste-o em vez do texto da mensagem; (2) um filme ou uma legenda de um servidor intranet em http descarrega-se primeiro (n_pbt_restclient.of_download para uma pasta temporária), depois reproduz-se pelo seu caminho; (3) ue_fullscreen_changed, ue_pip_changed, ue_source_changed e ue_chapter_changed são lançados também após as suas próprias chamadas (of_fullscreen, of_pip, of_next, of_seek…), como num gesto: se o seu código chamava o próprio tratamento logo atrás, retire essa chamada, correria duas vezes; (4) uma parede de ecrãs que tem de tocar oculta define ib_pause_when_hidden = false; (5) para substituir a faixa de um idioma, of_remove_subtitles e depois of_add_subtitles.

11.27 pdfviewer: of_refresh diz o que faz, nada é transferido sem o seu conhecimento #

A segunda revisão do visualizador (pdfviewer) dá um código de retorno a of_refresh — e, para que o mesmo nome tenha o mesmo sentido, também aos de webbrowser e shellexplorer —, comunica todas as ligações do documento e recusa o que nunca será apresentado em vez de deixar à espera. Nenhuma assinatura de evento muda.

O quê3.04.0
pdfviewer · webbrowser · shellexplorer: of_refreshsubroutinelong: 0 uma vez pedido, -4 sem documento ou página (pdfviewer, webbrowser), -2 se o componente não estiver criado
pdfviewer: of_refresh após uma recusa (http://…)não fazia nada, sem eventoa recusa é repetida: ue_load_failed
pdfviewer: um endereço data: com mais de 2 MB de caracteresnunca apresentado, nenhum eventoue_load_failed com REASON_TOO_LARGE, de imediato
pdfviewer: um PDF remoto enviado «como transferência»ue_load_failed, mas o ficheiro ia para Transferênciasue_load_failed com REASON_REFUSED, nada é transferido
pdfviewer: ue_link_clicked numa ligação mailto:, file: ou relativanunca acionado (só http e https); uma ligação relativa chegava como endereço internoacionado para qualquer ligação; as_url é um mailto:… tal como está, ou um caminho em disco para um ficheiro local
pdfviewer: of_print_to_pdfescrevia a página à volta do leitor, não o documento-4, nada é escrito: copie o ficheiro de is_source
pdfviewer: file://localhost/C:/…, file:////servidor/partilha/…um caminho errado, não encontradoC:\… e \\servidor\partilha\…
pdfviewer: o foco dado ao componente (Tab, of_focus_webview)ficava na página: as teclas não deslocavam o documentopassa para o documento: PageDown, setas, Home / End deslocam-no

A receita: (1) uma chamada uo_pdf.of_refresh() compila tal como está; teste o retorno se quiser saber que não havia nada a reler; (2) um documento com mais de 1,5 MB mantido em memória escreve-se num ficheiro temporário e depois apresenta-se pelo seu caminho; (3) em ue_link_clicked, espere também um mailto: e um caminho em disco, não só um endereço web; (4) para copiar o documento apresentado, copie o ficheiro de is_source em vez de of_print_to_pdf.

11.28 codeeditor: uma pesquisa que se vê, um «ir para» que desloca o cursor, substituir #

A segunda revisão do editor de código (codeeditor) traz para o ecrã o que a pesquisa encontra, mantém o cursor do utilizador durante uma pesquisa, muda o nome de ii_doc_line e acrescenta o que se espera de um editor de scripts: substituir, controlar o cursor, saber se é preciso guardar, mostrar um erro na calha. Nenhuma assinatura de evento muda.

O quê3.04.0
codeeditor: ii_doc_lineum long com o prefixo de integeril_doc_line: mude-lhe o nome; uma linha para lá do fim já não marca nada (relê-se tal como foi escrita)
codeeditor: of_find com ib_search_enabled = false0, sem pesquisar nada-4
codeeditor: of_find("")relançava a pesquisa anterioresvazia o campo e apaga os realces, sem ue_find_result
codeeditor: of_find, Enter na barraa ocorrência ficava muitas vezes fora da vista; o cursor ia para elaa ocorrência é trazida para o ecrã; a pesquisa parte do cursor, que só se move ao fechar a barra (Esc)
codeeditor: of_insert_text com a barra de pesquisa abertasubstituía a ocorrência encontrada, fora da vista, e esvaziava o histórico de Ctrl+Zinsere no cursor do utilizador, trazido para o ecrã; Ctrl+Z anula-o
codeeditor: um novo is_textmantinha o deslocamento do documento anterior; um texto só com CR relia-se em LFapresenta-se a partir da primeira linha e apaga os marcadores; só CR relê-se em CR (uma mistura em CRLF)
codeeditor: ib_current_line com ib_wrapnenhuma faixaa faixa cobre toda a linha do cursor
codeeditor: novidades—substituir (of_replace, of_replace_all, Ctrl+H) e opções de pesquisa (ib_find_match_case, ib_find_whole_word, ib_find_regex, F3); cursor e seleção (il_caret_line, il_caret_column, of_select_range, of_selected_text, of_line_count); ib_modified; marcadores na calha (of_add_marker, of_remove_marker, of_clear_markers, of_marker_count)

A receita: (1) substitua ii_doc_line por il_doc_line; (2) teste o -4 de of_find se a pesquisa puder estar desativada; (3) para «ir para a linha» de um erro deslocando o cursor, defina il_caret_line (e of_add_marker para o mostrar) — il_doc_line apenas marca; (4) se seguia ue_caret_changed para saber onde um excerto foi inserido, leia il_caret_line depois de of_insert_text; (5) um botão Guardar pode seguir ib_modified, que repõe a false depois de guardar.

11.29 jsontree e xmltree: o teclado fica com a árvore, uma pesquisa que já não move a seleção #

A segunda revisão da árvore JSON (jsontree) incidiu sobre o motor que partilha com a árvore XML (xmltree): o que se segue vale para as duas, salvo indicação. Nenhuma assinatura muda; a árvore JSON ganha of_expand_path, of_collapse_path, of_is_expanded, of_copy e o evento ue_node_toggled, levantado por um gesto do utilizador como por of_expand_path e of_collapse_path.

O quê3.04.0
jsontree, xmltree: Enter numa folhapassada à janela: o seu botão predefinido disparavafica com a árvore, levanta ue_node_clicked como um clique; sem seleção, nada
jsontree, xmltree: Esc com a caixa de pesquisa abertadisparava o botão Cancelar da janelafecha primeiro a caixa; com a caixa fechada, Esc volta à janela
jsontree, xmltree: linhas de fecho (}, ], </x>)alcançadas pelas setas (ue_selection_changed de um bloco já anunciado); um clique levava a vista de volta à aberturasaltadas pelo teclado; um clique seleciona o bloco sem mover a vista
jsontree, xmltree: seta direita numa folhadescia uma linhanão faz nada, como numa árvore
jsontree, xmltree: uma pesquisa durante uma seleçãoof_search_next ou Esc podiam dobrar a linha escolhida e mover a seleção sem eventoa linha selecionada continua visível e selecionada: of_selected_path não muda
jsontree: a mensagem de ue_errormetade traduzido, metade inglês («JSON inválido : Unexpected end of JSON (line 1, column 6)»)inteiramente na língua de apresentação, linha e coluna incluídas: não compare o seu texto
jsontree, xmltree: um documento com mais de 1 500 000 linhasmostrado, mas o seu fim fora de alcance, sem dizer nadarecusado: uma mensagem na árvore e ue_error
jsontree: Ctrl+C na árvorenão copiava nada, e seguia como atalho da janelacopia a seleção (como of_copy); sem seleção, o atalho continua a ser da janela

A receita: (1) se uma janela contava com Enter na árvore para disparar o seu botão predefinido, acrescente esse passo em ue_node_clicked; (2) deixe de procurar uma chave vazia em ue_selection_changed (uma linha de fecho já não é selecionada); (3) não analise o texto de ue_error: segue a língua; (4) para restabelecer as dobras de um utilizador, leia of_is_expanded e reponha-as com of_expand_path / of_collapse_path.

11.30 xmltree: cada linha tem o seu XPath, qualquer XPath seleciona #

A segunda revisão da árvore XML (xmltree) retoma tudo o que a secção anterior diz do motor partilhado. Acrescenta o que é próprio do XML: um caminho que designa SEMPRE o nó da linha, legível tal como está por n_pbt_xml. Nenhuma assinatura muda; a árvore XML ganha of_selected_xml, of_copy, of_expand_path, of_collapse_path, of_is_expanded e o evento ue_node_toggled.

O quê3.04.0
xmltree: caminho de uma linha de texto, de comentário ou de instrução de processamentoo do seu elemento (enquanto of_selected_value dava o seu próprio texto); "" antes da raizo seu: /r/text()[2], /r/comment()[1], /r/processing-instruction('x')[1], /comment()[1] — n_pbt_xml.of_get_value lê aí o mesmo valor
xmltree: elemento cujo prefixo é redeclarado com outro URI, ou com um irmão do mesmo nome noutro espaço de nomesum caminho que não encontrava nada, ou OUTRO nó*[local-name()='x' and namespace-uri()='urn:…'], que designa exatamente esse nó
xmltree : of_select_pathsó a forma exata que a árvore escreve, senão -5qualquer XPath (//line[@sku='A'], /r/a[1]…): é selecionado o primeiro nó encontrado, of_selected_path dá depois o caminho da árvore
xmltree: a mensagem de ue_error« XML inválido : error on line 1 at column 11: … »; a árvore ficava vazia« XML inválido : linha 1, coluna 11 (…) », na língua de apresentação; a árvore mostra a fonte, com a linha errada marcada
xmltree: <?xml-stylesheet?> sem declaração XMLmostrado duas vezesuma só linha
n_pbt_xml: um XPath com @xml:langrecusado (prefixo xml desconhecido), valor vaziolido: o prefixo xml está ligado de raiz, como exige a norma
xmltree: Seta direita numa etiqueta com atributosos atributos só se alcançavam com o ratopercorre os atributos um a um (Seta esquerda volta), um ue_selection_changed por passo, depois desce
xmltree: Ctrl+C, dobrar por caminhonada; Ctrl+C ia para a janela como atalhoof_selected_xml, of_copy e Ctrl+C (o XML da seleção), of_expand_path, of_collapse_path, of_is_expanded (qualquer XPath), ue_node_toggled (um gesto, ou of_expand_path / of_collapse_path)

A receita: (1) se subia de uma linha de texto ou de comentário ao seu elemento por of_selected_path, pegue no pai do caminho (o que precede a última /); (2) não analise o texto de ue_error: segue a língua; (3) um caminho guardado na 3.0 sob espaços de nomes misturados reencontra-se dando-o a of_select_path, que agora aceita qualquer XPath, e relendo depois of_selected_path.

11.31 xml: recusas que se dizem, espaços de nomes que se mantêm #

A segunda revisão de n_pbt_xml não muda nenhuma assinatura. Faz of_remove seguir os códigos da biblioteca, recusa uma leitura enquanto um documento construído tiver um elemento aberto, e faz os espaços de nomes manterem-se: o que um mutador escreve relê-se no espaço certo, ou é recusado dizendo-o.

O quê3.04.0
xml: of_remove(""), of_remove sem documento carregado, página que não responde0, como «nada retirado»-5; -4; -2 — a contagem (>= 0) só quando a remoção foi tentada
xml: uma leitura (of_exists, of_count, of_get_value, of_is_valid…) ou uma alteração enquanto um elemento construído ainda está abertoo documento era carregado tal como estava, e o resto da construção começava um NOVO documento: o que vinha antes perdia-se sem errorecusada: -4, vazio ou false, e is_last_error = «the document is still being built : close its elements first»; nada se perde (of_xml e of_pretty continuam disponíveis)
xml: of_add_xml sob um elemento com espaço de nomes por omissão, ou com o prefixo do alvo (<s:Item/> sob s:Body)o fragmento ficava fora do espaço de nomes (xmlns=''), invisível para o XPath que servira para o acrescentar; o prefixo do alvo era recusado (-4)o fragmento herda os espaços de nomes em vigor no seu alvo, como of_add_child
xml: of_set_attr / of_add_child com um nome com prefixo (xsi:type, p:item)0, um atributo fora do espaço de nomes que o XPath não encontrava; com um prefixo não declarado, um documento que já não se recarregavano espaço de nomes do prefixo (declarado no nó, ou ligado por of_register_namespace); -4 e «undeclared prefix : xsi» se não estiver ligado em lado nenhum
xml: of_pretty depois de um of_add_child sob um pai com prefixo (s:Body)<Item> sem prefixo: relido, fora do espaço de nomes<s:Item>, como em of_xml
xml: of_element_attr duas vezes com o mesmo nome; um nome :x, x: ou a:b:cdois atributos (documento malformado); nome aceite (um documento que não carrega)um só atributo, com o segundo valor; nome recusado (is_last_error), o elemento fica de fora
xml: of_transformaplica uma folha XSLT ao documento carregadoretirado: o XSLT já não existe no motor (o Chromium retira-o); transforme no servidor ou em PowerScript

A receita: (1) um of_remove testado com = 0 (nada retirado) continua a funcionar; teste < 0 (nada pôde ser tentado); (2) se lia um documento DURANTE a construção (um of_exists para controlar, um of_count para numerar), feche primeiro os seus elementos, ou conte você mesmo; (3) um fragmento de of_add_xml já não tem de redeclarar o espaço de nomes do seu alvo: o que escrevia xmlns='' para sair dele ainda pode; (4) teste o retorno de of_set_attr / of_add_child com um nome com prefixo, e declare o prefixo (ou ligue-o por of_register_namespace).

11.32 json: um array que se constrói depressa, números que mantêm os algarismos, um texto vazio que se diz vazio #

A segunda revisão de n_pbt_json não retira nem altera nenhuma assinatura. Acrescenta as sobrecargas decimal e longlong de of_set_number e of_add_number, e os leitores of_get_decimal e of_get_longlong. Construir um array com of_add_* já não percorre o array inteiro a cada acrescento: 2 000 linhas constroem-se numa fração de segundo em vez de vários minutos. Duas regras ficam agora escritas na documentação, sem mudar: uma cadeia nula escreve-se "" (para um null JSON, of_set_raw(path, "null")), e uma chave escrita duas vezes lê-se na sua PRIMEIRA ocorrência.

O quê3.04.0
json: of_load de um texto feito de brancos (quebra de linha, tabulação)-4, como um texto mal formado-5, como um texto vazio
json: of_load de um texto precedido de um BOM (ficheiro UTF-8 com BOM)-40, o BOM é ignorado
json: of_load de um documento aninhado em mais de 512 níveis0 — e um texto muito profundo podia parar a aplicação-4, a aplicação continua viva
json: of_set_number / of_add_number de um decimal (ou de um literal como 690.50)convertido em double: uns quinze algarismos, um cêntimo podia perder-sesobrecarga decimal: todos os algarismos, zeros finais retirados (690.5); um longlong também tem a sua
json: of_get_number de um expoente com zeros iniciais (1E-0000005)0, ou um valor enormeo valor certo (0.00001)
todos os componentes: \u seguido de quatro caracteres que não são hexadecimais, numa cadeia lidaos quatro caracteres desapareciammantidos tal como estão, como um escape desconhecido

A receita: (1) se testava of_load(...) = -4 para reconhecer um ficheiro vazio, teste < 0; (2) um montante decimal passado a of_set_number escreve-se agora com todos os algarismos, sem mudar nada no seu código; (3) um identificador com mais de 15 algarismos relê-se com of_get_longlong, um montante com of_get_decimal, já não com of_get_number.

11.33 crosstab: of_from_datastore, recusas que se dizem, o valor apresentado no duplo clique #

A segunda revisão do crosstab renomeia of_set_data para of_from_datastore, o nome do datagrid e do scheduler, que leem um DataStore da mesma forma (mesmos argumentos, mesmos códigos). Qualquer adição, filtro ou formato que nomeie um campo desconhecido devolve agora -5 em vez de 0. A tabela só desenha as colunas visíveis: um código de cliente ou uma data diária postos em Colunas já não bloqueiam o ecrã. Novidades: is_thousands, CF_ICONS, as constantes VALUEFILTER_* e DATE_*.

O quê3.04.0
crosstab: alimentar a partir de um DataStoreof_set_data(ds)of_from_datastore(ds), mesmos códigos
crosstab: um campo desconhecido (gralha) passado a uma adição, um filtro, um formato, uma ordem, um agrupamento de datas0, nada acontece-5
crosstab: um tipo de filtro, uma agregação, uma parte de data fora da lista; uma medida calculada em Linhas; of_set_value_filter numa posição sem medida0; a posição deslizava para a última medida-5
crosstab: of_set_layout de um texto que não é JSON; of_remove_calc_field / of_remove_calc_measure de um nome desconhecido0-5
crosstab: ad_value de ue_cell_double_clickedo agregado bruto (400 sob « 80,0 % »), 0 para uma célula vaziao valor apresentado (0.8), NULL para uma célula vazia; um membro vazio vale null nos tuplos
crosstab: o mesmo campo em Linhas (ou Colunas, Filtros) E em Valoresdependia da ordem das chamadas: o valor desaparecia; Remover numa dimensão retirava tudopermitido em todo o lado; adicionar ou mover uma dimensão mantém os valores, Remover só retira o chip visado
crosstab: um membro vazio (NULL, texto vazio); um texto com tabulação ou quebra de linha no DataStore« null » ou uma linha sem rótulo; linhas fantasma, colunas desfasadasum único membro (vazio), em último; o texto fica na sua linha
crosstab: is_label após um novo of_from_datastore; is_label = ""perdido; um chip sem textomantido; "" repõe o cabeçalho do DataWindow
crosstab: Ctrl+C no modo de demonstraçãoue_copy levantado, área de transferência escritarecusado como uma exportação, a grelha di-lo
crosstab: of_collapse_all; filtro de membros da grelha; of_export_xlsx acima de 16 384 colunas; exportações em VALUES_ROWSsó as linhas; aplicado a cada caixa; um ficheiro ilegível; as medidas lado a ladolinhas e colunas; aplicado com OK (no máximo 10 000 membros listados); recusado, ue_xlsx_saved diz porquê; como no ecrã

A receita: (1) substitua of_set_data por of_from_datastore; (2) se ignorava o código devolvido por of_add_*_field ou por um filtro, verifique < 0 — uma gralha finalmente vê-se; (3) em ue_cell_double_clicked, teste IsNull(ad_value) antes de calcular, e leia ad_value como o valor apresentado (uma parte, não uma soma, num modo « % »).

11.34 Base comum: of_count e of_keys_at contam em long #

of_count devolvia um integer e of_keys_at recebia uma posição integer — em todos os componentes, nos seus handles e nos objetos não visuais que os têm (commandpalette, messagebox, speechout, toaster). Para lá de 32 767 elementos a contagem transbordava: um calendário (scheduler) alimentado por um DataStore de 40 000 linhas deixava de se contar, e as suas últimas linhas não se percorriam. As quatro assinaturas são agora long: long of_count ( ), long of_count ( string as_keys ), string of_keys_at ( long al_index ), string of_keys_at ( string as_keys, long al_index ).

A receita: uma chamada não muda. Uma variável integer que recebe of_count() continua certa até 32 767: declare-a long. Um descendente que redefinia of_count ou of_keys_at adota a nova assinatura — o compilador mostra-lhe a linha.

11.35 shellexplorer: uma actualização que mantém o estado, cada linha por si #

A revisão do explorador da shell mantém os seus eventos: of_select, of_expand e of_collapse lançam-nos como um clique, como na 3.0. of_refresh e ib_show_files já não fecham a árvore. Novidades: is_file_filter (os ficheiros mostrados), ib_show_hidden (os itens ocultos, por predefinição a definição do Explorador), ib_enabled e of_refresh(caminho), que relê um só ramo.

O quê3.04.0
shellexplorer: of_refresh(), ou ib_show_files alteradoa árvore fechava-se, a selecção desaparecia sem eventoos ramos abertos e a selecção voltam, encontrados pelo seu caminho; uma selecção que já não existe dispara ue_selected("", "")
shellexplorer: of_expand, of_select, of_collapse de um caminho vazio0-5
shellexplorer: of_expand de um ficheiro ou de uma pasta sem filhosnadaue_path_not_found(…, "expand", "not a branch")
shellexplorer: of_keys_at(caminho, i)caminho/filho, que nada sabia relero caminho do filho, inteiro: volta a of_has, of_select, of_expand
shellexplorer: a mesma pasta em dois níveis (a Música do Ambiente de trabalho e a da pasta do utilizador)um clique, um chevron ou um duplo clique numa agia sobre a outracada linha responde por si
shellexplorer: ficheiros e pastas ocultosnunca mostradosmostrados conforme a definição do Explorador do posto, ou ib_show_hidden
shellexplorer: um ramo numa partilha que não responde«…» para sempre, mesmo fechada e reabertaue_error «… : timeout» ao fim de 30 segundos; o ramo volta a ser pedido ao reabrir

A receita: (1) ue_selected e ue_expanded são lançados também após um of_select ou um of_expand do seu código, uma vez alcançada a pasta (um caminho ainda por ler chega um pouco mais tarde): faça o seu trabalho no evento, não logo atrás da chamada, ou releia of_selected_key() quando a selecção tiver chegado; (2) em ue_selected, trate as_path = "" (a selecção desapareceu); (3) teste -5 num caminho vazio; (4) defina ib_show_hidden = false se os seus utilizadores nunca devem ver itens ocultos, diga o que disser o Explorador deles.

11.36 commandpalette: cada objeto só mexe na sua paleta, um fecho que se anuncia sempre, a língua da aplicação #

Só há uma paleta no ecrã de cada vez: quando um segundo objeto paleta abre a sua, substitui a primeira. Um objeto passa a responder só pela sua paleta e pelo seu atalho. ue_opened e ue_closed continuam a ser disparados em of_open / of_close: dizem o ciclo de vida da janela, não um gesto (mesma regra que os leitores de áudio e vídeo). Novidades: of_insert_command (um comando numa posição escolhida), of_anchor_under (a paleta sob um controlo, em píxeis de ecrã), e no handle is_group, is_hint, is_keywords, is_icon.

O quê3.04.0
commandpalette: ue_closedsem argumento; nada de nada quando a paleta morria antes de aparecer (fechada ou substituída logo, janela recusada)ue_closed(string as_reason) segue cada of_open que devolveu 0: "", cancelled, failed ou blocked
commandpalette: of_is_open, of_close, of_reset, destruir um objeto cuja paleta foi substituída pela de outrorespondiam VERDADEIRO pela paleta do outro, e fechavam-nasó respondem pela sua paleta: FALSO, e nada é fechado
commandpalette: destruir (ou repor) um objeto cujo atalho foi retomado por outro objeto paleta da mesma janelaretirava o atalho do outro: a tecla já não respondia em lado nenhumo atalho do outro fica
commandpalette: of_register_shortcut de uma tecla que o gancho não nomeia (ctrl+ù, win+k, space sem modificador)0 («posto»), e a tecla nunca fazia nada-5; o atalho anterior mantém-se
commandpalette: of_register_shortcut com is_shortcut vazio e nenhum atalho posto02
commandpalette: of_add_command de uma chave que contém uma vírgula0 — e is_recent relia-a como dois comandos-5
commandpalette: um grupo declarado em várias vezes (File, Edit, depois File)dois cabeçalhos «File»um só, no lugar da sua primeira aparição; a ordem dos comandos mantém-se no grupo
commandpalette: a pesquisa e os acentospreferences não encontrava «Préférences»os acentos não contam
commandpalette: a línguaa paleta falava inglês fosse qual fosse PBT_SetLanguagea língua da aplicação; um is_placeholder definido por si não é traduzido
commandpalette: o atalho mostrado numa linha, teclado AZERTY; AltGr na pesquisaCtrl+A lia-se Ctrl+Q; escrever € (AltGr+E) lançava o comando mostrado como Ctrl+Alt+Ea tecla é lida como a DLL a nomeia; um carácter escrito nunca é um atalho
commandpalette: um atalho posto sem ipo_owner (toda a aplicação) antes do atalho de uma janela, na mesma teclaganhava também nessa janelao atalho da janela passa primeiro
commandpalette: POSITION_ABSOLUTEum comando de chave x ou y levava a paleta para a borda do ecrã; com dois ecrãs ia para o da janelail_x / il_y mantêm-se, no ecrã do ponto pedido
commandpalette: inv_pumpvariável interna que ficou públicaprotegida: não faz parte da API, nada a ler nem a escrever
commandpalette: um comando cujo texto cita __licensea paleta não abria (-5)abre: só uma palavra reservada escrita como chave continua recusada

A receita: (1) se o seu código dispara ele próprio ue_closed(), passe-lhe um motivo (""); um script que apenas o recebe compila tal como está; (2) se esperava ue_opened após of_open, trate também ue_closed("cancelled"), "failed", "blocked"; (3) teste 2 e -5 no retorno de of_register_shortcut; (4) renomeie uma chave de comando que contenha uma vírgula.

11.37 radialmenu: uma chave simples que acerta, uma roda aberta que segue a aplicação, um rótulo que se lê #

A roda é desenhada uma vez, e a aplicação continua a correr enquanto está no ecrã: o que mudar entretanto passa a contar. O cubo já não escreve nada (não o fazia desde a 3.0, dissesse a documentação o que dissesse): é o ramo apontado que mostra o rótulo inteiro.

O quê3.04.0
radialmenu: of_item com uma chave simples (of_item("csv"))mudava o rótulo e o estado do único ramo que a levava, mas as suas cores não eram desenhadas, e o manípulo sobrevivia à remoção do paié resolvida no endereço completo (import/csv): mesmo manípulo, cores incluídas, libertado com o pai. Ambígua ou desconhecida: o manípulo não muda nada
radialmenu: um manípulo sobre um endereço ainda não adicionadouma cor definida através dele coloria o ramo adicionado depois nesse endereço, mesmo após of_clearnão escreve nada; of_clear esquece todas as cores
radialmenu: of_shownão devolvia nadadevolve um long: 0, ou -2 se o componente não estiver criado
radialmenu: of_show(-1, -1)abria a roda no cursorabre-a no ponto (-1, -1), como qualquer coordenada negativa; no cursor é of_show()
radialmenu: um ramo retirado, esvaziado, desativado ou ocultado enquanto a roda está abertaainda se escolhia: ue_item_selected para um ramo desaparecidojá não se escolhe: ue_dismissed; of_clear, of_remove_item e of_reset fecham a roda aberta
radialmenu: clique direito noutro sítio enquanto a roda está abertaa nova roda substituía a antiga sem ue_dismissedue_dismissed para a antiga, depois a nova roda
radialmenu: rótulo longo ou vaziocortado a duas linhas e legível em lado nenhum; vazio, uma fatia sem nadao ramo apontado mostra-o inteiro; vazio, mostra-se a chave
radialmenu: leitura da direita para a esquerdaa coroa girava no sentido horário, ← subiaa coroa gira no outro sentido, ← e → trocam de papel

A receita: (1) of_show devolve um long: uma chamada simples compila tal como está; (2) substitua of_show(-1, -1) por of_show(); (3) se desfazia em ue_dismissed o que definia ao abrir, nada a fazer: agora chega também quando uma roda substitui outra; (4) um manípulo obtido com uma chave levada por dois ramos já não muda nada: dê o endereço.

11.38 toaster: eventos que dizem que toast, recusas que se dizem, um toast que espera ser visto #

Os três eventos do toast mudam de assinatura, of_add_button devolve um código, e um toast já não se perde quando a aplicação está minimizada.

O quê3.04.0
toaster: ue_toast_clicked, ue_toast_action, ue_toast_dismissed(string as_key …): as_key transportava o identificador do toast, como texto(long al_id, string as_key …): al_id é o número devolvido por of_show, as_key o is_key do toast (vazio sem chave)
toaster: of_add_buttondevolvia o número de botões; uma chave já ocupada, uma chave vazia e um quarto botão passavam sem uma palavradevolve 0; -5 sem acrescentar nada para uma chave vazia, já ocupada, que contém / ou uma barra vertical, ou um quarto botão. O número lê-se com of_count()
toaster: of_show com uma definição fora dos limitesmostrava na mesma: um tipo desconhecido como informação, um canto desconhecido em cima à esquerdadevolve -5 e nada mostra: is_kind, is_position ou is_sound fora das suas constantes, il_max_visible fora de 0 a 20, il_timeout abaixo de TIMEOUT_AUTO
toaster: a mesma is_key mostrada por dois toasterso segundo substituía o toast do primeiro e ficava com os seus eventos; uma atualização mantinha o canto de origemcada toaster tem o seu; uma atualização retoma também o canto, a fixação ao ecrã e a window de fixação
toaster: o somum som de sistema em cada toast, informação e sucesso incluídos; nenhum para um toast saído da fila de esperais_sound: SOUND_AUTO (predefinição) = apenas erro e aviso, SOUND_ALWAYS, SOUND_NEVER; reproduzido quando o toast é pedido, mesmo que espere o seu lugar
toaster: toasts fixados ao ecrã a partir de duas windows, ou sem ipo_ownerficavam exatamente uns sobre os outros; o limite contava-se por windowuma só pilha por monitor e por canto, e il_max_visible conta por monitor
toaster: um toast fixado a uma window minimizadaia para -32 000 px e apagava-se sem ter sido vistoespera: não é apresentado e a contagem decrescente não corre até a window regressar
toaster: um toast que chega enquanto a pilha está sob o ponteirodescontava o seu tempo e podia sair durante a leituranasce em pausa, como os outros
toaster: PBT_SetLanguage, PBT_SetDefaultTheme, PBT_SetDefaultThemeAccent, PBT_SetDefaultFont, PBT_SetFlowDirection enquanto um toast está apresentadonão o alcançavam; o tamanho da letra ficava em 11 ptseguem-no de imediato, tamanho da letra incluído
toaster: o texto de um toastnão se selecionava; agarrar a barra de deslocamento de um texto longo podia responder e fecharseleciona-se e copia-se (clique direito, Copiar); a seleção e a barra de deslocamento já não fecham o toast
toaster: il_button_countvariável públicaprivada: leia o número de botões com of_count()
toaster: um toast cujo texto cita __licensenão era mostradoé mostrado: só uma palavra reservada escrita como chave continua recusada
toaster: of_close de um toast visívelnenhum eventoue_toast_dismissed, como a sua cruz; um toast ainda em espera, nunca visto, não lança nada

A receita: (1) acrescente long al_id como primeiro argumento dos seus ue_toast_clicked, ue_toast_action e ue_toast_dismissed, e substitua Long(as_key) por al_id; as_key é agora a chave do toast; (2) se lia o retorno de of_add_button como um número de botões, leia of_count(); (3) para manter um som numa informação ou num sucesso, defina is_sound = SOUND_ALWAYS.

11.39 messagebox: um campo obrigatório vazio nunca é validado, escolhas com chaves únicas #

Mudam cinco comportamentos; nenhuma assinatura.

O quê3.04.0
messagebox: ib_input_required e um botão predefinido com contagem decrescente (of_add_button_timed)o clique automático validava a caixa com o campo vazio (of_show devolvia o botão, of_input_value uma cadeia vazia)a contagem decrescente esgota-se sem clicar; o botão espera que o campo seja preenchido
messagebox: Esc ou Alt+F4 num botão ao mesmo tempo predefinido e de cancelamento, campo obrigatório vaziodevolvia 1, como um clique nesse botãodevolve 0: fechada sem escolha
messagebox: of_add_choiceaceitava uma chave já usada, ou que contém / ou ``devolve -5 e não adiciona nada
messagebox: of_choose sem nenhuma escolhamostrava uma caixa com um único botão Cancelarnão mostra nada: cadeia vazia, e of_get_last_error diz «no choice to show»
messagebox: os botões das caixas prontas (of_info, of_confirm, of_yes_no, of_prompt…) quando a aplicação não definiu nenhuma língua«Ok»«OK», a palavra do catálogo inglês («Cancel», «Yes», «No» para os outros)

A receita: (1) um campo obrigatório valida-se agora à mão — se contava com o clique automático para avançar, dê ao campo um valor predefinido (is_input_value); (2) dê a cada escolha uma chave única, sem / nem |, e teste -5 se as suas chaves vierem de dados.

11.40 Base comum: a língua anunciada por predefinição, os números decimais de qualquer posto #

Duas correções da base comum, válidas para todos os componentes; nenhuma assinatura muda.

O quê3.04.0
a língua anunciada por um componente (<html lang>)o francês, enquanto a aplicação não escolhesse línguao inglês, a língua predefinida dos componentes; a língua escolhida pela aplicação substitui-a sempre
um número decimal dado a uma propriedade (id_*)só a vírgula decimal era convertida: num posto cujo separador decimal é outro carácter, o valor não chegavao separador decimal do posto, seja ele qual for, é convertido

A receita: nada a mudar. Uma aplicação que escolhe a sua língua continua a vê-la aplicada; um leitor de ecrã que lia em francês um componente de uma aplicação inglesa passa a lê-lo em inglês.

11.41 Teclado, foco e espaço: o que os testes da 4.0 corrigiram #

Comportamentos vistos ao usar os componentes numa aplicação real; nenhuma assinatura muda, acrescenta-se um método.

O quê3.04.0
Enter sobre um CommandButton PowerBuilder com o foconada (a tecla perdia-se)o botão é premido (clicked), como numa caixa de diálogo do Windows; o botão predefinido de uma barra não
Um componente desativado (ib_enabled = false)Tab parava nelesai da ordem de tabulação; reativado (ou of_reset), retoma o seu lugar
Um atalho Ctrl sobre um carácter sem tecla própria (AZERTY: - na tecla 6, + com Shift)Ctrl+- nunca encontrava o seu atalhodepois da tecla, o carácter da disposição ativa: Ctrl+-, Ctrl++, Ctrl+,, Ctrl+. funcionam em qualquer teclado
Escrever num menu aberto (pesquisa, letras sublinhadas)uma tecla da fila de cima dava o seu algarismo (AZERTY: - chegava como 6)o carácter da disposição; uma letra sublinhada &1 continua a responder à tecla 1
O calendário do seletor de data (toolbar)só com o ratotambém com o teclado: setas (dia, semana), Page Up/Down (mês), Home/End, Enter escolhe, Esc fecha
Alt com duas faixas (ou barras de menus) na mesma janela, sem subjanela entre elaso primeiro criadoo mais próximo do foco no ecrã
breadcrumb numa barra muito estreitao primeiro segmento nunca cedia: o local atual reduzia-se a nada, o trilho transbordavadepois do meio, o local atual cede até uma letra e «…», depois o primeiro segmento; nada sai da barra
menubar: uma escolha feita com o rato no menu pendenteo foco ficava na barra (Editar > Colar não colava em lado nenhum)o foco volta ao controlo que o tinha
ribbon: escrever numa caixa de combinação e depois escolher na sua listadois ue_combo_changed: o texto escrito, depois a escolhaum só, a escolha
toolbar: is_text = "" definido em ue_text_changed, o foco no campoo texto antigo voltava, com um segundo eventoo campo fica vazio
O foco devolvido a um componente após uma janela da biblioteca (paleta de comandos)a página, sem elemento: o cursor do editor de código tinha desaparecidoo elemento que o tinha
Um rótulo com letra sublinhada (&File) da direita para a esquerdaletras fora de ordem («ileF»)a palavra lê-se pela ordem
n_pbt_utils.of_dir_folders(as_dir, ref as_names[])DirList numa ListBox: 4,5 s para 30 000 pastas, e a pasta atual da aplicação mudavanovo: as subpastas tal como o Explorador as mostra, ordenadas, numa passagem; -4 ilegível, -5 caminho vazio
breadcrumb: of_add_children(as_keys, as_child_keys[], as_texts[])um ramo de cada vez (of_add_child): 30 000 subpastas abriam o menu em mais de 20 snovo: todo um nível numa chamada

A receita: nada a mudar. Uma aplicação cujo CommandButton com o foco devia ignorar Enter desativa-o (Enabled = false) ou retira-lhe o foco; para uma pasta volumosa, substitua o ciclo de of_add_child por um único of_add_children.

11.42 Dados e teclado: o que o segundo lote de testes da 4.0 corrigiu #

Comportamentos vistos ao usar os componentes de dados numa aplicação real; nenhuma assinatura muda.

O quê3.04.0
Enter ou Esc premidas num componente que não as tomaperdidas: o CommandButton PowerBuilder Default ou Cancel não disparavaa tecla volta à janela PowerBuilder, como promete o capítulo 6.4: Esc prime o botão Cancel, Enter o botão Default
PBT_SetLanguage seguido logo de uma ordem ao componenteo texto de um evento lançado por essa ordem (ue_error de xmltree) ficava na língua anteriora língua vale a partir da ordem seguinte
jsontree, xmltree: o foco dado ao componente (of_focus_webview, a tecla Tab)ficava na página: as setas e Enter não iam a lado nenhuma árvore toma-o; F3 e Shift+F3 passam à ocorrência seguinte ou anterior da pesquisa
xmltree: um erro assinalado DEPOIS do último carácter da sua linhanenhuma coluna sublinhadao fim da linha é marcado (↵)
codeeditor com quebra de linha (ib_wrap)a faixa il_doc_line podia ficar uma fila acima, no fim da linha anterioras faixas cobrem todas as filas da sua linha e seguem o redimensionamento
codeeditor: « Substituir tudo » e of_replace_all num texto longovários segundos quando o foco estava no editor; além disso, of_replace_all podia devolver 0instantâneo, e o número de substituições é devolvido; Ctrl+H com uma pesquisa vazia põe o cursor em « Procurar »
crosstab: « Adicionar às colunas » (ou linhas, filtros) a partir do menu de um chip, pelo tecladoo foco perdia-se; só Enter abria o menu de um chipo foco segue o chip para a sua nova zona; Shift+F10 e a tecla Menu também abrem o seu menu
json: milhares de of_add_* seguidosquase um segundo para 2 000 linhasalgumas dezenas de milissegundos; o documento é o mesmo

A receita: nada a mudar. Uma aplicação que tratava ela própria Esc premida num componente (um atalho registado com of_register_shortcut) mantém-no: um atalho vem antes da janela.

11.43 Conteúdo e média: o que o terceiro lote de testes da 4.0 corrigiu #

Comportamentos vistos ao usar os componentes de conteúdo e média numa aplicação real; nenhuma assinatura muda.

O quê3.04.0
speechout: of_speak e depois of_pause no mesmo scriptue_started e a primeira ue_sentence chegavam antes de ue_paused: a voz era anunciada como iniciadaue_started é lançado quando a voz começa realmente a falar; uma pausa posta antes retém-na: nada é dito nem anunciado até of_resume
speechout: uma língua sem voz exata no computador (fr-CA onde só há fr-FR)ue_started anunciava a língua pedida (fr-CA)ue_started anuncia a língua realmente lida (fr-FR), depois de ue_voice_fallback
webbrowser: Tab depois do último controlo da barra de endereçoso foco saía do componente para a janela PowerBuildero foco entra no site, como num navegador; Shift+Tab a partir do site volta à barra
webbrowser: ib_private = true posto quando a navegação já é privadasem efeito: o site voltava a encontrar o que tinha guardado na sessão privadade cada vez uma sessão privada nova e vazia
video em ecrã inteiro: uma caixa modal da aplicação (um MessageBox em ue_ended)escondida sob o filme, que lhe retirava o teclado: a aplicação parecia bloqueadao filme cede: a caixa passa à frente e recebe o teclado; ao fechá-la, o filme retoma o ecrã e Esc sai dele
tilesbox: uma seta no limite, ao lado de um mosaico mais pequenoSeta para cima num mosaico grande da primeira fila saltava para o lado, para o pequeno vizinhosó conta um mosaico inteiramente para lá do limite: no limite, o foco fica onde está
dockcontainer: il_back_color / il_text_color de um painel empilhadoperdidas assim que o seu separador ficava ativo (tomava o acento do tema)o separador ativo mantém as cores do painel, como a sua lingueta na calha
progressbar: id_value posto em cada volta de um ciclo longocerca de 2,5 s para 20 000 linhasbem menos de um segundo; a barra continua a avançar durante o ciclo

A receita: nada a mudar. Uma aplicação que contava com ue_started para saber que of_speak tinha sido aceite lê antes o seu código de retorno (0); a que compara a língua de ue_started com is_lang fica agora também a saber da substituição por essa diferença, além de ue_voice_fallback.

11.44 Dados: ler uma célula, ordenar e pesquisar com mais precisão (json, jsontree, xmltree, crosstab) #

Estes acréscimos da 4.0 não retiram nenhuma assinatura. Dois mudam o que vê sem que tenha escrito nada: Ctrl+C do crosstab copia agora os cabeçalhos, e ue_cell_double_clicked recebe mais um argumento.

O quê3.04.0
crosstab: ue_cell_double_clicked( string as_row_tuple_json, string as_col_tuple_json, double ad_value )( string as_row_tuple_json, string as_col_tuple_json, integer ai_measure, double ad_value ): ai_measure é a posição do valor clicado duas vezes em Valores, a partir de 1; com os dois tuplos, é o endereço que of_get_cell_value relê
crosstab: Ctrl+C sobre célulassó os númerosos cabeçalhos com elas: os nomes das colunas numa primeira linha, o membro de cada linha (o seu caminho, «North / Boston») numa primeira coluna; ib_copy_headers = false dá só os números
crosstab: of_remove_field, of_get_cell_value—novos: retirar um campo de todas as zonas sem reconstruir a disposição; ler o valor de uma célula pelos seus tuplos e pela posição da sua medida
json: of_get_array, of_pretty (long al_indent)—novos: todos os elementos de um array numa chamada; uma indentação em espaços, ou o documento compacto numa linha com 0
jsontree, xmltree: a pesquisasempre sem distinguir maiúsculas, e dentro das palavrasib_find_match_case e ib_find_whole_word, como o codeeditor, com os botões Aa e ab da caixa de pesquisa; por predefinição, a pesquisa continua a ser a da 3.0

A receita: um script de ue_cell_double_clicked não tem nada a mudar, o argumento acrescenta-se antes do valor. Uma aplicação que cola o resultado de Ctrl+C num processamento que só espera números define ib_copy_headers = false.

11.45 Navegação e contentores: separadores pelo teclado, painéis com um duplo clique (tab, dockcontainer, ribbon, stepbar, listbar) #

Estes acréscimos da 4.0 não retiram nenhuma assinatura. Três gestos mudam o que um utilizador vê sem que tenha escrito nada: o clique do meio e Ctrl+Tab num tab, e o duplo clique num painel de dockcontainer ou na barra de título da sua janela flutuante.

O quê3.04.0
tab: clique do meio num separadornadafecha um separador que se pode fechar, pelo mesmo caminho que a sua cruz: ue_tab_closing se ib_veto_close = true, depois ue_tab_closed; um separador que não se pode fechar, ou desativado, não faz nada
tab: Ctrl+Tab, Ctrl+Shift+Tab, Ctrl+Page Down / Page Upnadao separador seguinte ou anterior que pode ficar ativo, em ciclo, esteja o teclado na banda ou numa página alojada (um controlo PowerBuilder, outro componente); é um gesto: ue_selection_changing se ib_veto_selection = true, depois ue_selection_changed. A partir de um controlo fora do tab, a tecla fica com a janela
dockcontainer: duplo clique num cabeçalho ou num separador; na barra de título de uma janela flutuantenada; a janela flutuante maximizava-sedestaca o painel numa janela flutuante (ue_panel_floated); na barra de título dessa janela, volta a acoplá-lo no seu lugar (ue_panel_docked), como a sua cruz
dockcontainer: clique direito num cabeçalho ou num separadornadaum menu Destacar, Fechar, Fechar os outros (os outros painéis que se podem fechar do mesmo grupo); cada fecho faz a sua própria pergunta
dockcontainer: ib_veto_close, ue_panel_closing, of_close_panel, n_pbt_dock_panel.ib_closable—novos: a pergunta antes do fecho de um painel (opcional, false por predefinição), o fecho pelo código (-4 se o recusar, -5 para o painel principal ou um painel que não se pode fechar), e a possibilidade de fechar mudada em direto
ribbon: n_pbt_ribbon_item.is_image, id_min, id_max, id_stepfixados na adiçãoa imagem de um controlo e o intervalo de um contador mudam em direto e releem-se; o valor de um contador é trazido para o novo intervalo sem lançar ue_value_changed, como id_value
stepbar: STATE_WARNING, STATE_SKIPPED, NAV_VISITED—novos: um passo concluído com um aviso (marca âmbar), um passo ignorado (anel tracejado), e um modo em que qualquer passo já alcançado continua clicável, também para a frente depois de um recuo
listbar: n_pbt_listbar_section.ib_pinned—novo: uma secção fixada no fundo da barra (Definições, Ajuda), que continua visível quando a barra se desloca, também no carril; a disposição gravada mantém a ordem das secções

A receita: nada a mudar. Numa página de tab, Ctrl+Tab muda agora de separador mesmo quando o foco está num controlo da página, como numa folha de propriedades do Windows. Para maximizar uma janela flutuante do dockcontainer, o seu botão Maximizar continua lá.

11.46 Menus: o chevron da barra de menus, uma lista pendente na barra de ferramentas, dez mil comandos (menubar, toolbar, commandpalette) #

Estes acréscimos da 4.0 não retiram nenhuma assinatura. Muda um comportamento por predefinição: uma barra de menus demasiado estreita já não quebra a linha, recolhe os seus últimos títulos num chevron. E of_open de uma paleta de comandos já não recusa abrir sem ipo_owner nem ipo_receiver.

O quê3.04.0
menubar: uma barra demasiado estreita para os seus títulosquebrava a linha: a sua altura acompanhava as filas, ue_auto_height a cada mudança de largurafica numa só linha: os títulos que não cabem, a partir do fim, passam para o menu de um chevron (as suas entradas em cascata, Alt + a sua letra abre-os a partir do chevron, as setas param nele como num título, à esquerda em RTL); a altura deixa de mudar. ib_wrap = true repõe o comportamento anterior
menubar: ib_track_hover, ue_item_hover, of_add_header, n_pbt_menubar_menu.is_align—novos: a entrada apontada de um menu, para o texto de ajuda de uma barra de estado (opcional, false por predefinição; um endereço vazio ao fechar), cabeçalhos de secção num menu, e um menu no fim da barra (ALIGN_END, Ajuda)
toolbar: of_add_combo, of_add_combo_item, of_remove_combo_item, of_clear_combo, ue_combo_changed, n_pbt_toolbar_item.ib_editable—novos: uma lista pendente na barra, editável ou não, que continua funcional recolhida no chevron; o seu evento tem o nome e o sentido do do friso
commandpalette: duas paletas no mesmo ipo_ownerpartilhavam a sua fila de eventos (uma podia receber o ue_closed da outra), e a segunda retomava o atalho da primeiracada uma os seus eventos e o seu atalho; o mesmo atalho registado pela segunda passa para ela (1). of_open e of_register_shortcut já não devolvem -5 sem ipo_owner nem ipo_receiver: os eventos chegam sempre
commandpalette: milhares de comandoscada linha desenhada: a abertura e a escrita ficavam lentassó as linhas visíveis são desenhadas: 10 000 comandos abrem-se e filtram-se sem espera
Atalhos de toda a biblioteca: AltGr + uma tecla que escreve um carácter (o euro de um teclado francês)lançava o atalho Ctrl+Alt dessa tecla, também num campo PowerBuildero carácter é escrito, nenhum atalho é lançado; AltGr sozinho já não dá o teclado a uma barra de menus ou a um friso

A receita: uma barra de menus cuja altura variável era desejada define ib_wrap = true; uma aplicação que reposicionava os seus controlos em ue_auto_height a cada redimensionamento já não tem nada a fazer depois do primeiro. Um atalho da aplicação em Ctrl+Alt + uma letra que o teclado do utilizador escreve com AltGr já não é lançado enquanto escreve: escolha outra tecla.

11.47 Conteúdo e media: um registo linha a linha, o tamanho real de uma imagem, um filme que espera (statictext, picture, video) #

Estes acréscimos da 4.0 não retiram nenhuma assinatura nem mudam nenhum valor por omissão. Dois comportamentos ficam mais precisos: o zoom de uma imagem pode passar o seu limite para atingir o tamanho real, e um filme de um URL reproduzido sem rede di-lo.

O quê3.04.0
statictext: of_append_text, ib_follow_end—novos: um registo escrito linha a linha — só a linha acrescentada segue para o componente — e, como opção, a vista que fica em baixo enquanto o leitor não subir
statictext: ib_auto_width, ue_auto_width—novos: o userobject assume a largura do seu texto (opcional, false por omissão), como ib_auto_height faz para a altura
picture: id_max_zoom, a tecla 1o zoom parava em 8.0 vezes o enquadramento, acontecesse o que acontecesse: uma digitalização grande mostrada pequena nunca se lia píxel a píxelo limite ajusta-se (id_max_zoom, 8.0 por omissão); a tecla 1 mostra o tamanho real, e o limite sobe até ele quando pede mais
video: ue_buffering, of_is_bufferingum filme que esperava pelos seus dados ficava parado sem dizer nadaum anel na cor de destaque do tema roda sobre a imagem, e ue_buffering(true) e depois ue_buffering(false) enquadram a espera
video: um filme de um URL enquanto o posto não tem rede«este ficheiro não foi encontrado ou não pode ser reproduzido», ue_failed com REASON_UNSUPPORTED«sem ligação de rede» sobre a imagem, ue_failed com REASON_NETWORK

A receita: nada a mudar. Um registo que reescrevia is_text a cada linha passa para of_append_text; um código que testava REASON_UNSUPPORTED para um filme de um URL sem rede testa REASON_NETWORK.

11.48 Revisão de 03/10/2026: uma disposição reposta é anunciada, uma exportação para um caminho relativo cai no sítio certo (toolbar, crosstab) #

Nenhuma assinatura muda. Dois comportamentos alinham-se com a regra da biblioteca: qualquer mudança da disposição é anunciada, e um caminho relativo de escrita resolve-se como nas outras exportações.

O quê3.04.0
toolbar: of_set_layoutnenhum eventoemite ue_layout_changed, como o dockcontainer e o datagrid: qualquer mudança da disposição é anunciada, venha do utilizador ou do seu código
crosstab: of_export_csv, of_export_xlsx para um caminho relativoescrito na pasta atual do momento — que um DirList ou uma caixa de ficheiros podiam ter mudado; ue_csv_saved / ue_xlsx_saved devolviam o caminho tal como dadoescrito na pasta onde a aplicação arrancou, como as outras exportações nativas; o evento devolve o caminho completo; um caminho que depende da pasta atual de uma unidade (\x, C:x) é recusado

A receita: uma aplicação que guarda a disposição em ue_layout_changed volta a guardar o mesmo valor depois de of_set_layout — sem consequências. Uma exportação que contava com a pasta atual do momento indica um caminho completo.


← Migrar da 2.0 para a 3.0 · Índice · Notas de versão →