quarta-feira, 19 de dezembro de 2012

DataWindows com Marca d'água


A utilização de imagens como marca d'água de relatórios ou documentos é uma prática normalmente associada à segurança. Sistemas precisam inserir marcas d'águas em páginas impressas, a fim de deixar visível que a impressão foi realizada sobre uma circunstância especial.

Existem textos bastante comuns utilizados como marca d'água, como por exemplo: "Rascunho", "Cancelado", "Sem validade", "Para uso interno", etc.

Mas como utilizar marca d'águas no PowerBuilder? Bem, isto é possível através da inserção de imagens nas datawindows, mas imagine o trabalho que pode dar se a quantidade de dataobjects do seu sistema seja alta.
A fim de evitar que cada datawindow seja alterada, eu criei um código que insere a marca d'água dinamicamente em uma datawindow. Veja mais abaixo.



String  ls_marca_dagua
String ls_datawindow_syntax
Long  ll_pos

// Recupera dinamicamente a sintaxe da datawindow
ls_datawindow_syntax = dw_report.DESCRIBE("Datawindow.syntax")

// Constrói a sintaxe do controle referente a imagem da marca dágua
ls_marca_dagua= 'bitmap(band=foreground filename="Imagens\Marca.gif" x="14" y="28" height="2572" width="2194" border="0"  name=p_1 visible="1" )'

// Recupera a posição do caractere em que será inserido o controle
ll_pos = Pos(ls_datawindow_syntax, "htmltable(")

// Modifica a sintaxe data datawindow, inserindo o controle
ls_datawindow_syntax = MID(ls_datawindow_syntax, 1, ll_pos -1) + ls_marca_dagua + MID(ls_datawindow_syntax, ll_pos , LEN(ls_datawindow_syntax))

// Recria a datawindow com a nova sintaxe
dw_report.CREATE( ls_datawindow_syntax)


Perceba no código acima que eu trabalhei com a imagem no formato GIF. O motivo disto foi para tentar colocar um pouco de "transparência" à minha marca d'água. Eu só precisei utilizar este formato porque desenvolvi o código fonte em PowerBuilder 10. Se você estiver utilizando a versão 11 do PowerBuilder ou uma superior, pode usar dois recursos mais eficientes para a transparência:

  • Ou utilizar uma imagem no formato PNG;
  • Ou definir o atributo transparency para o controle de imagem. Veja como ficaria:


...

// Constrói a sintaxe do controle referente a imagem da marca dágua
ls_marca_dagua= 'bitmap(band=foreground filename="Imagens\Marca.gif" x="14" y="28" height="2572" width="2194" border="0"  name=p_1 visible="1" transparency="50")'

...


A imagem com a marca utilizada por mim foi esta:


Agora, veja um relatório de exemplo com e sem marca d'água.





terça-feira, 4 de dezembro de 2012

Verificação de IPs (ping)

Certas aplicações necessitam utilizar recursos da rede ou se conectar com outros computadores. Infelizmente, em PowerBuilder, as bibliotecas oferecidas para este tipo de conexão são bastante pobres.

Neste post eu apenas dou uma dica para realizar uma simples verificação de IP, ou seja, executar o clássico comando "ping" através do PowerBuilder. Faremos isto através de instruções fornecidas pelo próprio Shell do sistema operacional.

Abaixo eu apresento um exemplo de como isto pode ser implementado.

OleObject lo_Shell
Integer  li_return
String ls_ip

ls_ip = sle_ip.text

lo_Shell = CREATE OleObject
li_return = lo_Shell.ConnectToNewObject( "WScript.Shell" )

IF li_return <> 0 THEN
Messagebox("Falha", "Falha ao tentar instanciar Shell do Sistema Operacional.")
END IF

li_return =  lo_Shell.Run("ping -n 1 -w 300 " + ls_ip, 0, TRUE)

IF li_return <> 0 THEN
Messagebox("Falha", "Host indisponível.")
END IF


sábado, 1 de dezembro de 2012

Validação de campos de e-mail em PowerBuilder

Neste post eu apresento um código bastante útil para quem está trabalhando com campos de e-mail em uma aplicação.

Por questões de segurança e padronização, ao permitir que o usuário de seu sistema insira um e-mail, você deve validá-lo quanto ao seu formato. Abaixo segue um código em PowerBuider, mas que também pode ser adaptado a outras linguagens, cujo resultado é a validação de um-mail.

string  ls_email
boolean lb_email_valido

// Código para setar o e-mail em ls_email
ls_email = of_getEmail()

lb_email_valido = FALSE

IF (NOT ISNULL(ls_email)) AND Trim(ls_email) <> "" THEN
IF match(ls_email,'^[a-zA-Z0-9][a-zA-Z\0-9\-_\.]*[^.]\@[^.][a-zA-Z\0-9\-_\.]+\.[a-zA-Z\0-9\-_\.]*[a-zA-Z\0-9]+$'THEN
lb_email_valido = TRUE
END IF
END IF




segunda-feira, 12 de novembro de 2012

Trabalhando com links

O PowerBuilder disponibiliza diferentes formas para o desenvolvedor trabalhar com links.

A forma mais comum é a através do controle StaticHyperLink. Independente de você estar desenvolvendo uma interface para desktop ou para web, o controle StaticHyperLink trabalhará do mesmo modo.

Para testá-lo, crie uma novo objeto window em um workspace de teste e adicione o controle através do menu Insert > Control > StaticHyperLink (ver imagem 1).

Imagem 1
Após adicionar o controle na sua interface, é hora de configurar as propriedades. Dentre elas, detalhei as mais relevantes:

  • Text: Texto a ser exibido ao usuário para efetuar o clique do link;
  • URL: Endereço propriamente dito a ser acessado através do link. Ex: "http://www.blogger.com";

Obs: Há um bug nos navegadores Mozilla Firefox e Opera em que, ao clicar no link com seu navegador padrão fechado, o programa não acessa o endereço definido. Uma solução para isto é adicionar um espaço em branco antes do endereço no campo URL.

É possível também definir links que redirecionem para os provedores de e-mail. Isto é feito definindo um código mais completo no campo URL, por exemplo: "<a href=”mailto:teste@gmail.com?subject=Feedback” >teste@gmail.com</a>".

Outro modo de trabalhar com links é pelo próprio código fonte. Segue abaixo um exemplo de como isto pode ser feito através da classe INet.

INet iinet_base
GetContextService("Internet", iinet_base)
iinet_base.HyperlinkToURL("http://www.blogger.com")


Por último, mostro como utilizar links através de datawindows. Porém, este modo só é possível quando você está trabalhando com uma aplicação web. Se este é o seu caso, crie uma datawindow e adicione um novo controle do tipo "Text" ou utilize uma "Column" mesmo. Acesse a aba "HTML" em suas propriedades. Lá você irá encontrar os seguintes campos:

  • Link: Endereço propriamente dito a ser acessado através do link. Perceba que é possível utilizar uma fórmula para compôr o link dinamicamente;
  • Link Target: Define como cada link será carregado na janela do navegador quando for clicado. Os valores possíveis são:
    • _blank: Abre uma nova página em uma nova janela do navegador;
    • _self: Carrega a nova página na janela atual;
    • _parent: Carrega a nova página no frame ancestral;
    • _top: Carrega a nova página na janela atual do navegador, cancelando todos os frames.

Os demais campos não são para situações tão básicas, mas você pode sentir necessidade de utilizá-los também.

Bom, espero que tenha dado uma visão geral da utilização de links em PowerBuilder. Existem muitas situações mais avançadas do que as que exemplifiquei aqui. Caso tenha dúvidas para utilizar algum recurso, é só me passar pelos comentários ou através do e-mail.

sexta-feira, 9 de novembro de 2012

PowerBuilder x TFS Source Control

Neste post eu explico como configurar o PowerBuilder para utilizar o Team Foundation Server Source Control como controlador de versão dos objetos.

De antemão, gostaria de listar aqui os benefícios e limitações desta integração. Os principais benefícios são:

  • Performance: Os check-ins, check-outs, atualização de status de objetos e outras operações são mais velozes do que outros sistemas controladores de versão;
  • Associação de check-ins com WorkItens do TFS: Para quem já utiliza o Team Foundation Server como sistema gerenciador de projetos, pode associar o check-in dos objetos à um WorkItem, proporcionando uma completa rastreabilidade do que é produzido. Isto significa que, através do WorkItem, é possível visualizar todos os objetos alterados para o tal;
  • Rastreabilidade a nível de código: O Source Control permite que o usuário abra o código fonte de um objeto registrado e exiba em qual check-in foi inserido ou alterado cada parte do código. Isto significa que o usuário pode, por exemplo, visualizar quem e porque inseriu aquele "IF" que está ocasionando um bug no sistema.
Como nem tudo são flores, o Source Control também possui seus problemas. Porém, o único que considero  relevante citar é a forma como ele define o status de cada objeto. O controle é feito através de um "flag"  atribuído a cada objeto, que define se o objeto no "workspace" do usuário está atualizado conforme última versão ou não. Isto significa que a atualização de status dos objetos não é feita através de um "diff", como em outros sistema controladores de versão, a exemplo do Microsoft Visual Source Safe. O problema disto é que se o usuário não realizar corretamente as operações, terá uma dor de cabeça com os status dos objetos. O Source Control poderá exibir que o objeto está atualizado, porém não estará.

Bem, o primeiro passo para configurar a integração é baixar e instalar o plug-in que permite que o PowerBuilder se integre ao Source Control. Este plug-in é fornecido pela própria Microsoft.
Acesse este link para baixar o plug-in compatível com suas configurações: Team Foundation Server MSSCCI Provider

Se ainda não possui o seu projeto criado no Source Control, crie-o. Para isto, abra o Team Explorer no Visual Studio e clique em adicionar (seu usuário precisará ter autorização para tal).

Após isto, abra o PowerBuilder e, em seguida, o workspace do projeto que deseja "versionar". Clique com o botão direito do mouse no workspace e acesse "Propriedades". Na aba "SourceControl", selecione "Microsoft Team Foundation Server" (ver imagem 1).

Imagem 1
Esta opção será exibida somente se você estiver instalado corretamente o plug-in mencionado anteriormente. Nos campos seguintes defina o usuário e selecione o projeto do TFS. O PowerBuilder disponibiliza algumas opções para tratar a integração:
  • Requires comments on chek-in: Obriga ao desenvolvedor a informar um comentário no momento que efetuar o check-in de um objeto. Sugiro habilitar esta opção;
  • This project requires that I sometimes work offline: Desabilita a conexão automática ao sistema controlador de versão quando você abre o workspace. Sugiro desabilitar esta opção;
  • Delete PowerBuilder-genereated object files: Para realizar algumas operações internas como a comparação de objetos ("Show differences"), o PowerBuilder precisa gerar arquivos fisicamente na pasta onde está localizada a PBL em questão. Marcando esta opção o PowerBuilder irá excluir estes arquivos gerados. Deixe esta opção habilitada;
  • Perform diff on status update: Verifica quais objetos locais estão diferentes do servidor, permitindo que o desenvolvedor identifique que já existe uma versão mais atual. Esta opção não funciona corretamente com o Source Control. Deixe esta opção desabilitada.
  • Suppress prompts to overwrite read-only files: É comum que os sistemas controladores de versão, inclusive o Source Control, gerem os arquivos versionados como "read only" na pasta de trabalho do desenvolvedor, a fim de evitar uma edição desses arquivos sem um prévio check-out. Como PowerBuilder exporta arquivos para esta pasta e encontra o arquivo como "read only",  ele irá solicitar ao usuário se deseja substituir o arquivo ou não. Selecionando esta opção, esse tipo de solicitação ao usuário não será realizado. Deixe esta opção habilitada;
  • Show warning when opening objects not checked out: Oculta mensagens exibidas ao abrir objetos que não estão em check-out. Deixe esta opção habilitada.