Página de Degustação Não Perca! Adquira já a sua edição e confira a matéria por completo. Open Tools API Gustavo Chaurais Crie seus próprios plug-ins para o IDE do Delphi Se você já pensou:“o Delphi é tão bom, mas por que o IDE não tem mais essa funcionalidade para facilitar meu trabalho?”, certamente irá se identificar com o que a Open Tools API (OTA) permite fazer. De maneira rápida e fácil, podemos implementar desde simples itens no menu a poderosos assistentes com a função de automatizar a criação de formulários. Só dependemos de nossa criatividade e/ou necessidade para criar excelentes plug-ins e melhorar ainda mais a ferramenta de trabalho. Hoje existem diversos plugins, pagos e gratuitos, disponíveis na internet para download. Por exemplo, podemos citar o GExperts e o CnPack, que oferecem conjuntos de funcionalidades para aumentar ainda mais a produtividade do desenvolvedor. Neste artigo, você aprenderá a criar seus próprios plug-ins e wizards para o IDE do Delphi, usando OTA. Um primeiro exemplo – “Hacking” Antes de começarmos a utilizar a API do OTA, vamos ver como podemos acessar os objetos do IDE através de pacotes. Note que essa é uma maneira totalmente desaconselhada para a construção de plug-ins, pois existem meios que nos garantem uma maior confiabilidade em tal tarefa, principalmente no tocante a compatibilidade entre versões da ferramenta. No Delphi, crie um pacote (File>New>Other>Package), adicione nele uma nova unit (File>New>Unit) e salve os arquivos como “HackingPackage.dpk” e “Hacking.pas”, respectivamente. Substitua o conteúdo de Hacking.pas pelo código da Listagem 1 e lembre-se que a declaração do método Register é case-sensitive. Compile e instale seu pacote. Quando lhe for perguntado sobre a adição de uma referência à VCL, responda OK. Veja que conseguimos acessar facilmente os objetos internos do IDE e alterar algumas propriedades, como o título e a cor do formulário principal. A seção finalization da unit, que só pode ser declarada se existir initialization, servirá para restaurarmos os valores antigos e liberarmos regiões alocadas da memória. Agora, a menos que você queira continuar com o IDE do Delphi na cor vermelha, desinstale o pacote através de Component>Install Packages. Mais uma vez, devemos salientar que essa técnica deve ser usada somente em situações extremas, e foi apresentada aqui apenas para fins didáticos. Como veremos, existem soluções muito mais elegantes para a construção de plug-ins. 6 Listagem 1. Código de Hacking.pas do projeto HackingPackage unit Hacking; interface uses Forms, Graphics; procedure Register; implementation var TituloAntigo: string; CorAntiga: TColor; procedure Register; begin TituloAntigo := Application.Title; // Muda o Caption do próprio Delphi Application.Title := ‘Revista ClubeDelphi’; CorAntiga := Application.MainForm.Color; // Muda a cor do main form do IDE Application.MainForm.Color := clRed; end; initialization finalization Application.Title := TituloAntigo; Application.MainForm.Color := CorAntiga; end. Open Tools API e IOTAWizard A Open Tools API, comumente chamada apenas de OTA, pode ser compreendida como um conjunto de ferramentas para a extensão do IDE. Sua infra-estrutura é baseada em interfaces e pacotes, ou seja, para registrar um plug-in que exerça determinada tarefa, é preciso apenas implementar a interface correspondente e compilar tudo em um pacote. Além disso, os plug-ins construídos poderão rodar tanto no Delphi quanto no C++ Builder, sem grandes problemas. Dica: Para o bom entendimento deste artigo, é ideal que o leitor tenha conhecimento básico sobre o uso de interfaces. Para aprender mais sobre interfaces, consulte a minha coluna no portal ClubeDelphi (www.clubedelphi.net). Página de Degustação Não Perca! Adquira já a sua edição e confira a matéria por completo. Edição 70- ClubeDelphi www.clubedelphi.net API Hooking Michael Benford Parte III – Monitorando cópia, execução e exclusão de arquivos No primeiro artigo desta série (edição 68), fomos apresentados à técnica de API Hooking. Vimos do que se trata, tivemos noções de como ela funciona etc. Na segunda parte (edição 69), aprendemos sobre o conceito de IPC (Inter Process Communication), que nos permite fazer uma DLL conversar com um aplicativo executável. Agora, na terceira e última parte desta série, iremos desenvolver uma aplicação completa usando o que aprendemos, para sabermos bem do que ela é capaz de fazer. Resolvi dar esse desfecho à trilogia porque a maioria dos programadores desconhece a técnica de API Hooking. E, quando ficam sabendo do que se trata, inicialmente não percebem o quanto ela é avançada. Eis o que faremos: um aplicativo que monitore as ações do sistema operacional sobre arquivos, mais especificamente em programas executáveis. O usuário irá criar uma lista de aplicativos protegidos e, com base nela, nosso software irá vigiar o sistema e bloquear alterações no arquivo. e eliminaria as chances de erro por parte do programador. Então, criei um expert para o IDE do Delphi, que gera todo o código da DLL automaticamente, facilitando nossa vida. Usaremos essa ferramenta para o desenvolvimento da aplicação proposta para este artigo. Este plug-in que desenvolvi é distribuído como um software freeware e está disponível para as versões 6, 7 e 2005 do Delphi (com código-fonte, que pode servir de base para quem quiser criar seus próprios plug-ins). Para baixar, acesse os sites www.projetobms.net ou www.otamasters.net, clicando no link Downloads. Em seguida, feche o Delphi, caso ele esteja aberto, execute o arquivo baixado e siga as instruções apresentadas pelo assistente de instalação. Nota: Por ser uma versão beta, algumas funcionalidades apresentadas aqui podem mudar ou desaparecer (pouco provável) na versão final. Uma tarefa cansativa Mãos à obra! O leitor que acompanhou esta série deve ter notado que a codificação das DLL’s usadas no processo de hooking, dependendo de quais API’s serão “hookadas”,pode tornar-se bastante trabalhosa. Para cada API, devemos ter uma variável de função e um callback, que são clones da declaração da API original. Para a função CreateProcess, por exemplo, precisaríamos escrever duas vezes seus 10 parâmetros. Pior, se fosse necessário usar a variável Next dentro do callback, o que é comum em praticamente 100% dos casos, mais uma codificação da API deveria ser escrita. E isso é apenas para a versão Ansi da API. Resta ainda a versão Wide, que acarretaria a digitação de mais três declarações muito parecidas com a primeira (seriam mudados apenas os tipos Ansi para Wide em parâmetros string). No final, isso demandaria a codificação de 60 parâmetros. Implementar tanto código igual em lugares diferentes, além de ser uma tarefa trabalhosa e totalmente manual, é um processo altamente propenso a erros. E se tratando de API Hooking, a omissão de um parâmetro em callbacks e/ou variáveis Next pode levar o sistema operacional à instabilidade, forçando um reboot no PC para que as coisas voltem ao normal (veja Regras de hooking, na edição 68). Vamos começar pela criação da DLL que será utilizada pelo nosso aplicativo. Como dito anteriormente, ele vai monitorar operações sobre programas. Então, devemos saber quais API’s “hookar” em cada situação. Essas situações, com suas respectivas API’s, são: • Cópia: CopyFileA/W, CopyFileExA/W; • Mudança de pasta/unidade e renomeação:MoveFileA/W,MoveFileExA/W; • Exclusão: DeleteFileA/W; • Execução: CreateProcessA/W; • Edição de atributos: SetFileAttributesA/W. Um grande aliado Observando esse problema, percebi que a automatização do processo reduziria o tempo gasto na digitação do código extenso Precisamos, portanto, criar uma DLL que contenha as variáveis Next e os callbacks dessas API’s. Para isso, faremos uso de nosso wizard. Muito bem. Clique no menu File, selecione New e Other. Clique sobre o nó (ou aba, se seu Delphi é anterior ao 2005) API Hooking. Marque então API Hook DLL Wizard e clique em OK. A primeira tela do assistente será mostrada. Como primeiro passo, devemos escolher uma biblioteca de funções de hooking para utilizar. Por padrão, o assistente já vem com duas pré-configuradas. Ambas são as comentadas na primeira parte desta série de artigos, sendo uma delas a nossa já conhecida BmsApiHook, do colega Bruno Martins Stuani. Selecione-a e clique em Avançar. A próxima etapa é selecionar quais API’s queremos “hookar” (Figura 1). Página de Degustação Não Perca! Adquira já a sua edição e confira a matéria por completo. www.clubedelphi.net Edição 70 - ClubeDelphi 15 Cadastros com Firebird Everson Volaco Criando cadastros básicos em Delphi utilizando Stored Procedures dinâmicas Neste artigo veremos como criar Stored Procedures dinâmicas no Firebird 1.5.x para uso, de forma genérica, em telas de cadastro desenvolvidas em Delphi 7 ou 2005/2006. O objetivo principal é demonstrar como reutilizar Stored Procedures do banco de dados em diferentes telas de cadastro de nossa aplicação, como também reutilizar código através do suporte a herança de formulários. Nossa aplicação Delphi conterá um formulário de cadastro genérico que será utilizado como base para a criação de todas as telas de cadastro do sistema, onde utilizaremos em todas elas apenas duas Stored Procedures do banco de dados: uma para inclusão, alteração e exclusão dos dados, e outra para consulta dos dados. Nota: Para o exemplo deste artigo utilizei o Delphi 7 com o driver DBX InterXpress for Firebird (Upscene Productions), que pode ser baixado a partir do site www.upscene.com. O mesmo exemplo podem ser desenvolvido em Delphi 6, 2005 ou 2006. Por padrão, o campo Client Library File vem configurado para a biblioteca do InterBase (gds32.dll). Como estamos utilizando Firebird, altere esse campo apontando o mesmo para a biblioteca fbclient.dll que está disponível dentro do diretório Bin da instalação do Firebird. Ao clicar no botão OK será aberta a janela Database Registration para que possamos registrar nosso banco de dados dentro do IB Expert. Para o campo Server Version selecione o banco e versão que está utilizando, no nosso caso Firebird 1.5. Para o campo Database Alias, digite uma alias para o banco de dados, por exemplo: “Cadastro”. Através do botão Test Connect é possível testar a conexão com o banco de dados recém criado. Pronto, basta clicar no botão Register para registrar o novo banco dentro do IBExpert. Para conectar no banco basta dar um clique duplo em cima do alias Cadastro criado na janela Database Explorer ou ainda a partir da opção Connect to Database disponível no menu de contexto. Criando as Tables, Generators e Triggers Criando o banco de dados Para a criação do banco de dados e de seus objetos utilizei a ferramenta IBExpert Personal Edition que pode ser baixada gratuitamente a partir do site www.ibexpert.com. Para criar o banco de dados que será utilizado em nosso exemplo, abra o IBExpert e selecione a opção Database>Create Database a partir do menu principal da ferramenta. Na janela Create Database preencha as informações necessárias para a criação do banco de dados Firebird (veja a Figura 1). Antes de implementarmos as Stored Procedures com SQL dinâmico, principal assunto deste artigo, devemos criar os outros objetos que farão parte do nosso banco de dados, como por exemplo, as tabelas de cadastros que serão utilizadas por nossa aplicação Delphi para armazenar os dados informados pelo usuário. Após conectar no banco de dados, acesse a opção Tools>SQL Editor disponível no menu principal para acessar o editor de SQL do IBExpert. Será dentro dessa janela que executaremos todas as instruções DDL (Linguagem de Definição de Dados) para criar nossos objetos, inclusive as SP’s. Nota: A ferramenta IBExpert traz consigo opções para facilitar a criação e gerenciamento dos objetos dentro do banco de dados. Para acessar essas opções, basta selecionar o tipo do objeto que deseja trabalhar dentro da janela Database Explorer e selecionar as opções de Create, Alter ou Drop desse tipo de objeto a partir do menu de contexto. Figura 1. Criando o banco de dados Firebird através do IBExpert Personal Edition Começaremos criando as tabelas que farão parte do banco de dados. Nesse exemplo criaremos duas tabelas: “Clientes” e “Fornecedores”. Dentro do SQL Editor entre com as instruções SQL, uma por vez, como mostrado na Listagem 1. Para fazer o auto-incremento do campo-chave de cada uma das tabelas criadas, utilizaremos Generators, Triggers e a função GEN_ID. Como visto em artigos anteriores sobre IB/FB, Generators são Página de Degustação Não Perca! Adquira já a sua edição e confira a matéria por completo. www.clubedelphi.net Edição 70 - ClubeDelphi 19 Delphi + Ajax.NET Rodolfo de Faria Otimizando o tráfego HTTP com chamadas assíncronas e Callbacks em aplicações ASP.NET Conforme já foi dito em outros artigos da ClubeDelphi, para desenvolver para Web é necessário quebrar paradigmas. Um deles é que um Web Form (ASP.NET) é limitado e não possui tantos recursos quanto um formulário tradicional (TForm da VCL). Ajax surge como uma opção para enriquecer as interfaces via Web e melhorar a usabilidade das páginas, deixando-as mais responsivas. O funcionamento do protocolo HTTP é chamado de request/ response, isto é, a cada ação do usuário (clique por ex.), uma requisição é enviada ao servidor e após uma espera, outra página HTML é devolvida ao browser (ou seja, há refresh total da página). Esse ciclo “clique, espera, atualiza página” é demorado, consome banda e é pouco eficiente. E se pudéssemos atualizar apenas as partes da página onde de fato houve modificações? Ajax faz isso e também permite que o usuário continue interagindo com a página enquanto uma requisição paralela está em andamento. Neste artigo veremos como são implementadas requisições síncronas e assíncronas usando a biblioteca Ajax.NET e como as páginas podem ser atualizadas sem efetuar postback (execução do método Submit do formulário da página). Uma roupagem nova para tecnologias já conhecidas O acrônimo Ajax significa Asynchronous Javascript + XML e consiste na combinação do objeto XmlHttpRequest com JavaScript e XML para envio e recebimento de informações sem a necessidade de se efetuar postback. Com ele é possível fazer requisições em background e atualizar a tela de modo transparente para o usuário, assemelhando-se a uma aplicação desktop. O termo Ajax foi cunhado por Jesse James Garrett da empresa Adaptive Path (www.adaptivepath.com), mas o objeto XmlHttp Request já existia no Internet Explorer desde sua versão 5 como um componente ActiveX. Outros browsers já possuem uma implementação nativa desse objeto. com o atributo [AjaxMethodAttribute] e serializa o objeto de retorno usando JSON (JavaScript Object Notation). No cliente, a string JSON é transformada novamente em objeto, a função de callback é chamada e alguma parte da página é atualizada. Isso acontece de maneira transparente para o usuário. Neste artigo,para ver como o Ajax funciona na prática,vamos criar uma aplicação simples com dois controles HtmlTextBox, onde iremos digitar no primeiro controle e uma descrição aparecerá no segundo. Adicionando Ajax.dll ao projeto No Delphi 2005 ou 2006 crie uma nova ASP.NET Web Application e salve-a como “DemoAjax”. No Project Manager dê um clique de direita e escolha Add Reference (Figura 2). No editor, clique em Browse, localize o arquivo Ajax.dll e clique em OK. Adicione Ajax na cláusula uses da unit. Editando o Web.Config No Project Manager dê um duplo clique no arquivo Web.Config e insira o código a seguir dentro da tag system.web: <httpHandlers> <add verb=”POST,GET” path=”ajax/*.ashx” type=”Ajax.PageHandlerFactory, Ajax” /> </httpHandlers> Ajax .NET Ajax.NET é uma biblioteca open source para .NET Framework que visa simplificar a programação com Ajax. Baixe-a no endereço: ajax. schwarz-interactive.de. No site existem duas versões: Ajax.NET e Ajax. NET Professional. Usaremos a primeira versão. Veja na Figura 1 a ilustração de uma solução Ajax. No lado cliente uma função JavaScript cria um objeto XMLHTTP Request e faz uma requisição de dados ao servidor. No lado servidor um HttpHandler recebe a requisição, chama um dos métodos marcados Figura 1. Ilustração de uma solução Ajax baseada na imagem obtida de www.adaptivepath.com Página de Degustação Não Perca! Adquira já a sua edição e confira a matéria por completo. www.clubedelphi.net Edição 70 - ClubeDelphi 25 Debugando com Codesite Bruno Sonnino Conheça uma excelente ferramenta para debugar seu código Você está desenvolvendo um aplicativo e as coisas não estão correndo como deveriam: o programa não faz o que deveria fazer, você tem muita dificuldade para seguir o código usando o debugger integrado do Delphi, pois os métodos se entrelaçam e eventos são ativados durante a execução, ou mesmo o erro está no meio de uma rotina de reescrita da tela (nesse caso, quando o debugger é ativado a tela é coberta e a rotina é chamada novamente), ou mesmo sua aplicação é multithreaded, onde diversas tarefas são executadas simultaneamente (por exemplo aplicações Web ou servidores de aplicação DataSnap). Normalmente, minha primeira opção quando isso acontece é colocar uma chamada para ShowMessage para que a caixa de diálogo mostre o valor da variável. Quando a rotina com erro é chamada diversas vezes, isso é impraticável, pois temos que clicar no botão OK cada vez, além de interromper a execução, escondendo bugs e introduzindo outros. Passo então para a segunda opção: criar um arquivo de log, usando WriteLn. Essa opção é mais interessante, pois não interrompe a aplicação e permite mostrar todas as informações que desejo. Esse enfoque funciona até o momento em que as funções começam a se entrelaçar ou quando tenho que enviar informações mais complexas, como uma imagem. Uma solução para esses problemas pode ser o CodeSite, da Raize Software, já premiado como melhor ferramenta de debugging pela revista Delphi Informant. Dispatcher e a mensagem enviada é mostrada no CodeSite Viewer, como na Figura 1. O Send é um método sobrecarregado e pode receber diversos tipos como parâmetro.Você pode enviar para o log de mensagens dados de diversos tipos: strings, inteiros, imagens, listas e até dados personalizados (como veremos mais adiante). Você pode incluir na mensagem uma string explicativa e também um tipo de mensagem. Conforme o tipo, a mensagem é mostrada com um ícone diferente no log. O código a seguir envia as mensagens disponíveis no CodeSite. Note que não enviamos a mensagem csmClear, que limpa o Viewer. var i: Integer; begin for i := csmFirst to csmLast do if i <> csmClear then Codesite.Send(i,’Mensagem número’, i); A Figura 2 mostra o log de mensagens após a execução do código. Muitas dessas mensagens não serão enviadas dessa maneira. Por exemplo, para enviar um separador ao Viewer, usamos o método AddSeparator ou para limpar as mensagens usamos o método Clear. Usando o CodeSite O método Send, embora seja muito importante, é apenas parte do que o CodeSite pode fazer. Um recurso muito interessante é o tracing Introdução ao CodeSite O CodeSite, que pode ser obtido em www.raize.com, é como um super gerador de arquivos de log, pois permite enviar dados de diversos tipos para o log, inclusive tipos personalizados. O log pode então ser visualizado localmente, no Viewer, gravado num arquivo, para ser visto em outro computador ou mesmo enviado para outra máquina. As mensagens podem ser de diversos tipos, sendo mostradas com ícones diferentes, podendo ser filtradas, para esconder mensagens desnecessárias. Após instalar o CodeSite, basta incluir a unit CodesiteLogging na cláusula uses e usar o método Send, do objeto CodeSite, como: CodeSite.Send(‘Teste de mensagem’); Ao executar o programa, duas coisas acontecem: aparece um novo ícone na barra de tarefas, ao lado do relógio: é o CodeSite 32 Figura 1. CodeSite Viewer Página de Degustação Não Perca! Adquira já a sua edição e confira a matéria por completo. Edição 70 - ClubeDelphi www.clubedelphi.net DataSnap e SOAP Guinther Pauli Aplicações distribuídas usando ClientDataSet, XML e Web Services Quando pensamos na criação de aplicações para Internet, a primeira coisa que vem à mente é o desenvolvimento Web. Usando um browser, podemos acessar nossa aplicação a partir de qualquer local do planeta, consultar informações dinâmicas vindas de um banco de dados, fazer compras on-line, efetuar cadastros e muito mais. Usando tecnologias como ASP.NET Web Forms com o Delphi, podemos criar aplicações Web de forma muito semelhante ao que já estamos acostumados a fazer no Desktop. Os problemas começam a surgir quando tentamos fazer na Web as mesmas coisas que estamos acostumados a fazer com a VCL Win32. Em várias oportunidades aqui na Revista, e também nas palestras que tenho ministrado sobre desenvolvimento Web, a primeira coisa que gosto de deixar claro é: um browser não é um formulário Delphi. Considero os protocolos HTTP e HTML arcaicos para serem usados como base na construção de aplicações; esses protocolos nasceram há anos, quando a Internet se limitava a consulta de informações estáticas, como imagens e textos (do tempo onde as primeiras aplicações dinâmicas sugiram com o CGI - Writeln). De lá pra cá, tudo o que se fez, foi meramente criar tecnologias que facilitam o desenvolvimento sobre eles, mas as limitações continuam a existir. Claro, temos alguns facilitadores, mas nada como o velho e bom TForm. Por exemplo, ao desenvolver para Web, você precisa aprender algumas coisas que até então pareciam esotéricas para quem sempre desenvolveu para Desktop: manter estado, fazer gerenciamento de sessão, processar requisições HTTP, ter uma preocupação triplicada com escalabilidade e por aí vai. Como se já não bastasse, o HTML oferece um conjunto pobre de elementos (tags) para a construção de formulários, se comparamos com a VCL. É muito mais fácil construir uma interface rica de elementos visuais usando VCL. Porém, a necessidade de acessar informações On-Line e centralizar o banco de dados em um local que possa ser acessado pela Internet, não nos deixa outra saída: mais cedo ou mais tarde vamos precisar construir aplicações para Web! O que proponho neste artigo é unificar o melhor dos dois mundos: a facilidade do desenvolvimento Desktop com VCL Win32 com os benefícios que só a Internet oferece. Você aprenderá hoje, neste artigo, a criar aplicações distribuídas para Internet usando VCL (“TFormbased”, ao invés de um browser), DataSnap, SOAP e Web Services. E o melhor de tudo, você verá que graças ao Delphi, esse trabalho se torna muito simples, rápido, prático e RAD. 38 Vantagens ao utilizar DataSnap com SOAP Antes de começar nosso exemplo, na já tradicional metodologia passo a passo, gostaria de justificar o porquê da abordagem que estou propondo e quais as suas vantagens: • Ao usar VCL para desenvolver para Internet, você não precisa aprender outro framework. Podemos continuar usando os mesmos controles que já usamos há anos; • É muito simples migrar uma solução client/server para a abordagem proposta, você vai economizar tempo e código; • Não sofreremos com as limitações impostas pelo HTTP e HTML: esqueça gerenciamento de estado, sessão, processamento de requisições e afins; • Diferente do HTML, que a cada requisição trafega formulários completos (resfresh total da página no postback), mesmo que você tenha solicitado a simples mudança em um controle, em nossa solução tudo o que vai tr afegar por HTTP são os dados dinâmicos, em formato XML; • Aplicações client e usando essa arquitetura são chamadas rich-client, elas contém basicamente código de tratamento de interface. O acesso a dados, regras de negócio, SQL, tudo fica no servidor. Isso garante uma centralização e compartilhamento de acesso. Usando as tecnologias abordadas neste artigo, você poderá ao final: • Acessar seu banco de dados a partir de qualquer lugar da Internet; • Criar aplicações distribuídas para a Internet. Você pode, por exemplo, centralizar o banco de dados e servidor de aplicação na matriz da empresa e distribuir as aplicações clientes para as filiais, que terão acesso a dados em tempo real e que se mantêm sempre atualizados, sem a necessidade de sincronização; • Poderá ter sua aplicação oferecida como um serviço: seus clientes podem pagar um taxa, por exemplo, e acessar a aplicação através da Internet, sem a necessidade de nenhuma configuração local na empresa, tudo fica configurado e armazenado no servidor. Arquitetura da solução Para ter uma visão geral da arquitetura da aplicação que será criada, veja o esquema da Figura 1. Durante todo este tutorial, sempre que tiver uma dúvida de como a solução está sendo implementada e em que camada está sendo empregada determinada tecnologia, consulte essa figura. Ela será nosso “mapa”. Temos três camadas envolvidas na solução: • C amada de Dados: o banco de dados (SGBD), nesse caso usaremos o Firebird 1.5; Página de Degustação Não Perca! Adquira já a sua edição e confira a matéria por completo. Edição 70- ClubeDelphi www.clubedelphi.net