Sei sulla pagina 1di 372

Introduo 1

Captulo 1

Introduo
(R)evoluo
(R)evoluo. Amigos, esta a palavra mais falada pelos desenvolvedores Delphi quando fazem o primeiro contato com a verso 7 do produto. Uns dizem evoluo, outros revoluo. Particularmente acho que o Delphi amadureceu de uma forma extraordinria, e que a equipe de negcios do produto conseguiu quebrar algumas barreiras importantes, como a incorporao de um excelente gerador de relatrios, ou melhor, um poderoso conjunto de componentes conhecido por grande parte dos desenvolvedores Delphi: Rave Report. Como o foco principal deste livro o desenvolvimento de aplicaes e-Business, a maior novidade para os Web-Developers o excelente pacote da empresa Atozed. J ouviram falar em IntraWeb? Agora sim temos uma ferramenta RAD de respeito para o desenvolvimento de aplicaes Web. Veja que no quero desprezar a tecnologia existente desde a verso 3 do produto, nem a nova tecnologia WebSnap, introduzida na verso 6. Pelo contrrio, ainda apio fortemente tais tecnologias, mas ganhamos um forte aliado: IntraWeb. Podem ficar tranqilos, teremos um captulo inteiro sobre o nosso mais novo companheiro. Aproveitando o embalo das apresentaes, no prximo tpico veremos todo o potencial do Delphi 7 em todas as suas distribuies, inclusive da novssima Studio Architect.

Novidades do Delphi 7
Primeiramente, irei apresentar as mudanas na nova verso do Delphi e, em seguida, uma tabela comparativa entre as suas distribuies. Nas mensagens de compilao, poderemos obter novas informaes atravs do site da Borland, com um link direto da mensagem. Maior controle sobre os famosos warnings ou advertncias que so geradas. Uma nova seo System para aplicaes CLX, com diversos controles de diretrios e arquivos. Anteriormente tais controles estavam disponveis somente para aplicaes VCL. Novas implementaes da Nevrona, com melhorias no pacote Indy Components, trazendo Indy Intercepts e Indy I/O Handlers, facilitando ainda mais o desenvolvimento de aplicaes para Internet. O poderosssimo IntraWeb, com as sees IW Standard, IW Data, IW Client Side e IW Control. Para quem reclamava do QuickReport, no pode mais chorar. O Delphi 7 traz consigo o poderoso Rave Reports, com superioridade absoluta em relao ao QR. A cada nova verso, a equipe de desenvolvimento melhora o Code Insight. Agora o code completion (uns dos fortes atrativos do Code Insight) est bem mais rpido, e com inteligncia artificial (este por minha conta). Sem sombra de dvidas ficou bem mais esperto e rpido. 1

2 Delphi 7 Internet e Banco de Dados Temos tambm um code completion para cdigo HTML. Voc tambm poder criar seus prprios administradores code completion, atravs da OpenTools. Para quem no dispensa as Watch Lists, ir babar com as melhorias: mltiplas sees para organizar suas watchs (seus vigilantes, observadores) atravs de grupos. Controle completo sobre a viso das watchs. Possibilidade de compilar projetos por grupo atravs do Project Manager. A seo Message View foi dividida em diversas abas para apresentar diferentes tipos de mensagens (Build, Search, e outros). Agora podemos selecionar mltiplos componentes na opo View/Component List. O editor suporta diferentes tipos de linguagem: Pascal, C++, C#, HTML e XML. Possibilidade de visualizar graficamente tabs e espaos no editor de cdigo. Melhorias para o desenvolvedor Web, com a incluso do IntraWeb (perceberam como estou feliz, s falo nele), suporte ao Apache2 (com todas as suas melhorias e recursos) e excluso do desenvolvimento de aplicaes Win-CGI (16 bits). Um novo browser UDDI para WebServices, e tambm novas classes e interfaces para o SOAP. TSoapAttachments, a grande novidade, onde podemos enviar atravs do SOAP, mensagens com anexo, utilizando multipart form. Tipos de definies so registrados automaticamente. Agora temos um evento poderoso: THTTPReqResp, onde podemos monitorar o pacote de mensagens, enquanto as mesmas so transmitidas. Novos drivers para o dbExpress, trazendo Informix SE, Oracle 9i, DB2 7.2, Interbase 6.5, MySQL 3.23.49, MSSQL2000 (uma das grandes novidades). A Borland desaprova o uso dos SQLLinks, e no disponibiliza mais suporte nas prximas verses do Delphi (aps 2002). Ela recomenda a utilizao da tecnologia dbExpress, que sinceramente, vem melhorando a cada verso. Suporte a Windows XP Themes nas verses Professional e Enterprise. A nova unit DBClientActns, com 3 novas classes: TClientDataSetApply, TClientDataSetUndo, TClientDataSetRevert. E os novos componentes dbExpress: TSimpleDataSet para aplicaes simples e de 2-camadas (TSimpleDataSet substitui TSQLClientDataSet). Diversos componentes visuais e de dilogo para CLX. Melhorias na unit Math. Model-Maker. Para quem nunca ouviu falar em UML, sugiro conhecer esta importante especificao. No Delphi 7, a partir da verso Studio Enterprise, temos uma excelente ferramenta especfica para integrao UML-Delphi-UML. E muito mais.

x x x x x x x x x

Para que voc tenha uma idia de qual verso adquirir, a Borland disponibiliza a sua tabela comparativa. Resolvi adapt-la, fazendo breves comentrios, para que voc tenha uma idia mais clara sobre as diferenas de verses. Nesta tabela so apresentadas somente as novidades do produto. Para maiores informaes, sugiro uma visita ao site da Borland Latin Amrica: www.borland.com.br

Tabela de caractersticas .NET


Caractersticas Studio Architect Studio Enterprise Studio Professional Personal Edition

. NET (Interoperabilidade e suporte a migrao)


Compilador compatvel com .NET, abrangendo warnings e hints Importa qualquer objeto .COM no padro .NET Exporta objetos .COM desenvolvidos em Delphi para aplicaes .NET

Introduo 3

. Delphi para Microsoft .NET prerelease preview


.NET preview compilador CIL para linguagem Delphi Migrao para documentao .NET Minha opinio A plataforma .NET foi bem planejada e possui uma estrutura bem diferente do que estamos acostumados. A velha briga entre desenvolvedores Delphi e Visual Basic deve ser deixada de lado. Acho que todos devem amadurecer e optar pela ferramenta mais adequada aos seus projetos. A Microsoft est pensando desta maneira, o que muito saudvel para todos ns. Para terem uma idia do que estou querendo dizer, a Borland sempre suportou em seus produtos tecnologias de ponta, como Java, Object Pascal, C++ e agora .NET.

Tabela de caractersticas Model Maker


Caractersticas Studio Architect Studio Enterprise Studio Professional Personal Edition

Tecnologia Model Maker


Design modelagem dirigida Modelagem Visual, baseada em UML Engenharia reversa com visualizao instantnea, integrada ao Delphi

Minha opinio Atualmente estamos vivendo uma fase bem madura de desenvolvimento de software. Antigamente tnhamos aqueles fantasmagricos fluxogramas, passando pela modelagem de dados, e agora, trs vivas: UML (Unified Modeling Language, ou Linguagem de Modelagem Unificada). Ao contrrio dos outros mtodos, a UML uma linguagem de modelagem muito usual em empresas fabricantes de software. E o mais incrvel, foi estendida para outros tipos de segmentos, como automveis, hardwares, empresas de energia, enfim, uma grande variedade. O Model Maker facilita muito o trabalho com UML, integrando totalmente as classes e objetos do Delphi em seu editor. Sugiro a todos que se aprofundem no estudo da UML. Alm dos fortes benefcios, est se tornando uma grande exigncia para desenvolvedores, analistas e coordenadores de projetos, alm, claro, dos gerentes.

4 Delphi 7 Internet e Banco de Dados

Tabela de caractersticas Intraweb


Caractersticas Studio Architect Studio Enterprise Studio Professional Personal Edition

Tecnologia IntraWeb (AtoZed)


Desenvolvimento de aplicaes WEB utilizando recursos visuais no estilo drag-and-drop. Adicione contedo interativo para seus sites, de maneira rpida e visual Controle transparente de cookies e sessions Grande variedade de componentes visuais para Web

Minha opinio Quando tive meu primeiro contato com o IntraWeb pensei: essa a grande soluo para o maior problema: prazo. Amigos, sem sombra de dvidas, o IntraWeb otimiza diversas tarefas no desenvolvimento de aplicaes Web. At mesmo quem no entende nada de HTML, JavaScript, desenvolve poderosas aplicaes Web, com uma interface de primeira. Fico feliz em ter o meu sonho realizado, de aumentar em mais de 30% a produtividade de minhas equipes. E o melhor, no requer um grande treinamento. Com o captulo dedicado a esta incrvel ferramenta, tenho certeza de que todos vocs estaro desenvolvendo aplicaes para Internet com extrema facilidade. Outro ponto bastante importante que a Borland fechou diversas parcerias para o seu novo produto, sempre pensando em disponibilizar o que h de melhor no mercado para ns desenvolvedores.

Tabela de caractersticas Nevrona Rave Reports


Caractersticas Studio Architect Studio Enterprise Studio Professional Personal Edition

Rave Report verso Delphi


Poderoso gerador de relatrios Rave, com desenho visual de relatrios e cdigo baseado em API Gera PDF, HTML, RTF e formato texto Suporte nativo para VCL e CLX Estilo flexvel de layout

Introduo 5

Minha opinio Amigos, algum lembra do QuickReport? Eu j esqueci, nem sei do que estamos falando! Brincadeiras parte, finalmente ganhamos um gerador de relatrios bastante profissional. A nossa Me-Borland conseguiu quebrar algumas barreiras para que esse sonho fosse realizado, e todos ns ganhamos com isso. O Rave Reports da inovadora e genial empresa Nevrona (a mesma criadora do Indy Componentes) muito estvel e traz diversos recursos que facilitam a vida do desenvolvedor. Sugiro que criem coragem de aprender um novo gerador de relatrios. Digo isso porque ao longo de minha carreira presenciei diversas pessoas e equipes que relutaram em adotar um novo gerador de relatrios, por diversas crenas: Ser que a empresa que produz o software vai manter a compatibilidade? Ser que a empresa no vai quebrar? Acho muito difcil este software! Entre outras...

Tabela de caractersticas Bold for Delphi


Caractersticas Studio Architect Studio Enterprise Studio Professional Personal Edition

Bold verso Delphi (BoldSoft)


Assegura menor cdigo utilizando o padro MDA (Model Driven Architecture) UML. Suporte total para diagramas de classes, valores identificados, entre outros Integrao com Rational Rose e Model Maker. Minha opinio Continuando com o nosso amigo UML, o conjunto de ferramentas da BoldSoft vem para complementar o suporte do Model Maker. Atravs de componentes, o desenvolvedor poder gerenciar de maneira bastante profissional seus diagramas UML. Como disse anteriormente, UML um tema muito exigido ultimamente, e recomendo um profundo estudo sobre este maravilhoso mundo.

IDE
A IDE do Delphi 7 (figura 1.1) muito parecida com a verso anterior. Basicamente mudou o seu visual, muito semelhante ao Windows XP. Vamos dar uma rpida olhadinha.

6 Delphi 7 Internet e Banco de Dados

Figura 1.1 IDE Delphi 7 Como este livro est voltado para o desenvolvimento de aplicao para Internet, vamos conhecer algumas novidades. A figura 1.2 ilustra a nova seo de objetos Web Documents. Sua principal funo de auxiliar na criao dos principais tipos de documentos Web.

Figura 1.2 Nova seo Web Documents Outra grande novidade o nosso amigo Intraweb (figuras 1.3, 1.4, 1.5, 1.6 e 1.7) que ganhou um captulo inteiro neste livro.

Introduo 7

Figura 1.3 Seo Intraweb

Figura 1.4 Paleta IWStandard (IntraWeb)

Figura 1.5 Paleta IWData (IntraWeb)

Figura 1.6 Paleta IW Client Side (IntraWeb)

8 Delphi 7 Internet e Banco de Dados

Figura 1.7 Paleta IW Control (IntraWeb) Amigos, d pra imaginar o poder do IntraWeb, com mais de 50 componentes nativos, no padro CLX, s para o desenvolvimento de aplicaes Web? Vocs devem estar pensando: nossa, eu nem aprendi tudo o que o Delphi me oferece de recursos e os caras disponibilizam mais poder, mais novidades! Ser que eu vou aprender tudo isso? Eis a questo. Por isso um livro especializado em Internet, focado no desenvolvimento de aplicaes e-Business. E o j consagrado WebSnap? Uma das estrelas da verso 6, ganhou algumas melhorias e as devidas correes dos pequenos bugs. A figura 1.8 ilustra os componentes do WebSnap.

Figura 1.8 Paleta WebSnap E a moda do momento? WebServices na veia. A tecnologia de WebServices j est sendo utilizada, mesmo que timidamente, em diversos setores, e far mais sucesso ainda com as ferramentas que vm surgindo no mercado. A figura 1.9 ilustra a seo de WebServices do Delphi 7, e a figura 1.10, a paleta de componentes.

Figura 1.9 Seo WebServices

Figura 1.10 Paleta WebServices

Introduo 9 Amigos, tivemos uma breve apresentao dos novos recursos do Delphi 7 na rea de desenvolvimento para Web. A seguir teremos uma introduo bastante importante sobre o desenvolvimento de aplicaes e-Business, bem como sobre o Mtodo Facunte.

Viso geral do e-Business


No cenrio atual temos a enorme necessidade de produzir novos produtos baseados na tecnologia e-business. Mas que produtos? ERP CRM B2B B2C entre outros

Vejamos a evoluo do mercado de desenvolvimento:

MEADOS
80 a 90 91 a 94 94 a 97 98 e 99 00 a 01

PLATAFORMA (*)
Unix, IBM, DOS DOS, Windows DOS, Windows Windows, Internet Windows, Linux, Internet, Intranet, Extranet Cross-plataform, objetos distribudos

LINGUAGENS/FERRAMENTAS
Cobol, Dataflex, C, C++, Clipper DataFlex, Clipper, Fox, Visual Basic Clipper, Visual Basic, Delphi Visual Basic, Delphi, ASP, PHP Visual Basic, Delphi, Kylix, ASP, PHP, ColdFusion, Java . NET, Delphi, Kylix, Corba (ORB), Java, SOAP, SNAP (Web Services)

02 tendncias

TABELA 1 EVOLUO DO MERCADO DE DESENVOLVIMENTO (*) Principais tecnologias

Como observamos na Tabela 1, o mercado evoluiu muito aps a dcada de 90, tornando confusa a deciso do desenvolvedor na escolha da melhor tecnologia. Para ajudar os desenvolvedores da velha-guarda, bem como os da nova-gerao, foi criado o MTODO FACUNTE (falaremos do mtodo em seguida). Bem, Mtodo parte, falaremos da forte tendncia para esta dcada que, conforme a Tabela 1, o desenvolvimento Cross-Plataform e Objetos Distribudos. Mas o que so estas novas tecnologias? Ser que so novas mesmo? Vamos iniciar pela tendncia Cross-Plataform. Cross-Plataform quer dizer que a aplicao roda em duas ou mais plataformas. Isso excelente, j que estamos num mercado bastante disputado; Windows melhorando, Linux cativando grandes legies de adeptos, e quem sabe o Lindows1 avana no mercado. Agora vamos imaginar nossa aplicao sendo executada em qualquer ambiente operacional. No timo? J pensou em oferecer ao seu cliente um produto Cross-Plataform? Tenho certeza de que aumentaro muito as chances de vender o produto. OK, e os Objetos-Distribudos? Bem, esse o ponto. Vamos imaginar o seguinte cenrio:
1

Aplicao de Controle de Estoque sendo acessada pela LOJA. Faturamento acessando informaes de Vendas.

Lindows Sistema operacional baseado no LINUX, que traz consigo a tecnologia WINE (kernel para execuo de aplicaes baseadas em Win32).

10 Delphi 7 Internet e Banco de Dados Financeiro gerenciando Faturamento e Contas a Pagar. Diretoria gerenciando todo o sistema. Clientes consultando e fechando pedidos atravs da Internet. Setor de compras fechando pedidos com Fornecedores. Compensao automtica de crdito/dbito da Rede Bancria. Vendedores externos fechando negcios com PALM TOPS.

Sem dvida um sistema dos sonhos de qualquer empresrio e desenvolvedor. Agora imagine efetuar uma manuteno no sistema sem interromper as atividades normais (no v pensar em atualizar o sistema as 02:00 da manh, hein?! Isso no tudo). Vamos melhorar o nosso lado? Com a tecnologia de Objetos-Distribudos podemos criar diversas camadas: Camada de Negcios Camada da Aplicao Cliente Camada da Aplicao Servidor Camada Aplicao Servidor-WEB Camada Banco de Dados entre outras Para realizar as tarefas de manuteno no sistema, o desenvolvedor poder alterar apenas a camada que satisfaz a ocasio. Outro fator bastante interessante que as camadas podem e devem ficar em servidores diferentes, especficos para cada camada. Tudo bem Facunte, mas o que a tecnologia de desenvolvimento WEB tem a ver com tudo isso? Isso mesmo: TUDO! Bem, quando nos referimos a Cross-Plataform imaginamos que os nossos clientes pudessem executar a mesma aplicao em diversas plataformas, certo? Ento temos aqui um caso tpico de Cross-Plataform tudo bem, no nvel de Client e no Server eu explico: Desenvolver uma aplicao com a tecnologia WEB utilizando o Delphi, a mesma poderia ser executada num servidor Windows NT e qualquer equipamento (micro-computador, PALM, Celular, etc. acessaria a aplicao, mesmo que o sistema operacional no fosse Win X. Exemplo: Linux, Mac OS, Solaris, celulares com browser baseado em JAVA (esquea WAP por enquanto), PALM com acesso Internet, entre outros. Viram que magnfico? Em resumo, o objetivo deste livro o desenvolvimento de uma Camada Web, uma das grandes tendncias desta dcada.

Mtodo FACUNTE
O Mtodo Facunte foi criado em 2001 inspirado nas necessidades de desenvolvedores iniciantes e dos amigos da velhaguarda que no tinham base formada sobre qual tecnologia adotar. O mtodo consiste num treinamento completo para o desenvolvedor, abrangendo desde as tendncias do mercado, passando por orientaes financeiras de projeto, at o desenvolvimento prtico de uma aplicao, utilizando ferramentas de alta tecnologia e comumente aceitas como padro de mercado. No diagrama a seguir temos a representao grfica do mtodo.

Introduo 11

Sucesso Mtodo Facunte Desenvolvimento Como e Quanto Cobrar do Cliente Definio do Projeto

Quais tecnologias devemos adotar / Aprendizado Tendncias do Mercado

Aspectos Gerais para o Desenvolvimento de Aplicaes Web


O desenvolvimento de aplicaes para web difere do mtodo tradicional em alguns pontos: Aplicaes so executadas no browser (Internet Explorer, Netscape, etc.); Para construir formulrios utilizamos HTML; Integrao com diversas tecnologias: Flash, JavaScript, Java.

Devemos esquecer alguns costumes do mtodo tradicional, como por exemplo: Grids; Barras de navegao entre registros; Botes de funes para todos os lados; Sobreposio excessiva de janelas.

Os referidos costumes degradam muito a performance do servidor de aplicaes e de banco de dados, alm de confundir o usurio em alguns aspectos. Outra coisa bastante interessante que a maioria dos desenvolvedores quer trazer para a web uma interface parecida com seu sistema tradicional. Isso pode custar caro, pois exige um esforo grande de desenvolvimento. Para tanto, recomendo um novo conceito de interface, que veremos ao longo do livro. Vejam que isso apenas um exemplo, que na minha opinio deve ser seguido, mas novos conceitos devero ser criados, e at mesmo outros tipos de interfaces existentes no mercado devem ser analisadas. Procure sempre o melhor para o usurio.

12 Delphi 7 Internet e Banco de Dados

Como est o mercado de trabalho


Desenvolvedores de aplicaes para web, ou melhor, e-business developers, esto muito bem cotados no mercado atual. Basta olhar para empresas como Oracle, Siebel, Jd Edwards, SAP, People Software, que esto criando ou migrando seus produtos para a tecnologia WEB. Veja a mdia de salrios para desenvolvedores WEB.

cargo desenvolvedor jr desenvolvedor pleno desenvolvedor snior Gerente de projetos arquiteto web consultor

desenvolvedor tradicional R$ 800 a R$ 1200 R$ 1000 a R$ 2000 R$ 2000 a R$ 4000 R$ 2000 a R$ 6000 R$ 20 a R$ 50/hora

desenvolvedor web R$ 1200 a R$ 1800 R$ 1800 a R$ 3500 R$ 3000 a R$ 8000 R$ 4000 a R$ 12000 R$ 6000 a R$ 10000 R$ 40 a R$ 130/hora

TABELA 2 pesquisa salarial realizada nos principais sites de RH (Grupo Catho, AP Info, Canal de Empregos, Manager) A demanda de desenvolvedores web ainda muito pequena, e a oferta de trabalho muito grande, por isso temos esse cenrio. Claro que aqueles que entrarem antes no mercado sero altamente beneficiados. No se assustem com as quebradeiras das empresas pontocom, pois este tipo de trabalho no se restringe a este seguimento. O que estamos mostrando aqui que qualquer empresa pode contratar os servios de um desenvolvedor web, desde a lojinha de autopeas da esquina, at as grandes corporaes.

Como definir os custos de um projeto


Quantas e quantas vezes ns desenvolvedores falamos a seguinte frase: Puxa, deveria ter cobrado mais, este projeto est me causando fortes dores de cabea. Acredito que inmeras vezes, no ? Sem sombra de dvidas temos o vilo da estria: pssimo planejamento. Ento como devemos planejar e definir os custos de um projeto? Bem, ainda no inventaram frmulas mgicas, mas esto chegando perto disso. Mas enquanto no descobrem, vamos checar algumas sugestes: Reflita sobre a sua experincia por exemplo: um cliente solicita um oramento para o desenvolvimento de uma aplicao de controle de estoque. Voc j desenvolveu alguma aplicao deste tipo? NO ento aumente relevantemente o tempo de desenvolvimento. SIM bem, com isso voc sair na frente, reduzindo assim o tempo de desenvolvimento do projeto. Pesquisar o mximo junto ao cliente antes de emitir a proposta, pesquise o mximo de informaes junto ao cliente, para saber at onde ele imagina que a aplicao vai chegar. No so raros os casos de clientes que pedem uma simples aplicao de controle de estoque e depois questionam: onde est o meu contas a pagar? E o desenvolvedor retruca: voc no pediu isso! No mesmo, amigos? Isso faz com que o desenvolvedor tome uma das seguintes atitudes: x desenvolve o mdulo e no cobra nem um centavo a mais x tenta convencer o cliente de pagar uma quantia extra pelo desenvolvimento (isso causa fortes dores de cabea) x chuta o balde e deixa o cliente na mo (nunca faam isso, amigos.) x entre outras coisas Definir o prazo junto ao cliente quanto menor o prazo, maior ser seu custo, pois dever mobilizar uma equipe ou at mesmo atravessar noites em claro.

Introduo 13 Nunca faa leilo comum o seu cliente querer reduzir o valor de sua proposta, apresentando outras de seus concorrentes. Casos absurdos de reduo de 50, 60 e at 70% so comuns. Acredito num valor de reduo mximo de 20% e o ideal em 10%.

Tudo bem, Facunte, mas como definir os custos de um projeto? Minha sugesto a seguinte: Defina seu valor hora, entre R$ 40 e R$ 60 (sessenta reais). Baseado em sua experincia, calcule o tempo necessrio para desenvolver a aplicao, em nmero de horas e multiplique por 2,5. Caso haja a necessidade de outros membros no desenvolvimento do projeto, faa a adequao em nmero de horas e acrescente 20% por membro. Acrescente os impostos. E finito, encaminhe a proposta ao cliente.

Veja um exemplo prtico: Minha estimativa em horas do projeto Tempo necessrio Prazo estimado pelo cliente O prazo fornecido pelo cliente forou-me a Introduzir mais 3 membros na equipe : 500 horas : 500 horas x 2,5 = 1.250 h : 2 meses : 1.250h + 60% = 2.000 h (60% = 20% por membro) : R$ 40,00 : 2.000 x R$ 40,00 = R$ 80.000,00

Valor hora Valor total do projeto

Repare, o que pesou no valor final do projeto foi o prazo estipulado pelo cliente, seno teramos um valor bem mais atraente, em torno de R$ 45.000,00. Lembre-se de estimar as horas baseadas em sua experincia, e no faam leiles com o seu valor hora. Obviamente numa fbrica de software virou moda este nome so utilizados recursos mais avanados para avaliao de valores.

Como gerenciar uma equipe de desenvolvimento


Bem amigos, o que irei explanar aqui apenas uma base de como gerenciar pequenas equipes de desenvolvimento, pois para uma idia mais abrangente seria necessrio escrever um bom livro. Em primeiro lugar deve-se definir o gerente do projeto. Nunca pense que por estar entre amigos o gerente ir deixar de dar as ordens ou os caminhos para o desenvolvimento do projeto. Para gerenciar uma equipe necessrio liderana, e quem no nasce com o esprito de lder dever conquist-lo. O gerente dever definir os responsveis por cada tarefa, alm de regras bsicas para que o projeto possa fluir tranqilamente: responsvel geral (gerente) responsvel pelas regras de negcio coordenador do projeto responsvel pela modelagem de dados responsvel pelo desenvolvimento de classes bsicas responsvel pelo design do projeto responsvel pelo ncleo do projeto responsvel pelos testes

Costumo dizer que, aps a modelagem de dados, desenvolver fica fcil. Digo isso porque o corao da aplicao a modelagem. Uma boa modelagem igual a uma boa aplicao, j uma razovel modelagem igual a uma semente frutfera de

14 Delphi 7 Internet e Banco de Dados problemas. Com a modelagem em mos, o gerente poder iniciar os trabalhos com cadastros bsicos e design, lembrando que a modelagem de dados deve ser baseada na anlise de negcios. Os testes devero ser iniciados paralelamente ao desenvolvimento dos cadastros bsicos, assim como o ncleo do projeto (caso haja um responsvel por esta rea, seno, somente aps a concluso dos cadastros bsicos). O prximo tpico complementa as dicas sobre gerenciamento de equipes.

Quais as ferramentas adequadas para a equipe


Gerenciar uma equipe no uma tarefa fcil, mas existem no mercado ferramentas especialmente desenvolvidas para este fim.

MS Project
O Microsoft Project o melhor gerenciador de projetos que conheo. Com ele podemos gerenciar diversas equipes ao mesmo tempo, conseqentemente diversos projetos (mesmo que por equipe), definir metas e analisar grficos de desempenho por fases, projetos e equipes. O projeto compartilhado entre os membros da equipe, facilitando assim o andamento do mesmo, mostrando as deficincias e tambm toda a eficincia da equipe. Recomendo para todos os tamanhos de projeto, e acredito ser indispensvel para grandes projetos.

ERWin
Quem nunca ouviu falar da fantstica ferramenta de modelagem de dados ERWin? Hoje pertence a CA (Computer Associates) que tem investido muito para melhoria da ferramenta. O ERWin gera scripts SQL para a maioria dos bancos de dados comerciais, como Oracle, SQL Server, Interbase, Sybase, DB2, Progress, Informix, entre outros. Para pequenos desenvolvedores no recomendo, devido ao seu alto custo (CA, no fique brava comigo, mas a dura realidade), mas para mdios e grandes indispensvel. A Squadra, empresa 100% nacional, fabricante de uma tima ferramenta de modelagem de dados: Dr Case. Alm do preo bastante atraente, a ferramenta traz consigo timos recursos para o trabalho com os principais bancos de dados (recomendo para quem utiliza diversos tipos de banco de dados). Existem produtos alternativos especficos para Interbase, como o fantstico IB Admin, da SQLLY (www.sqlly.com) com um custo bastante atraente, e com diversos recursos de gerenciamento do Interbase (altamente recomendvel para quem utiliza Interbase).

UML
Para quem quer qualidade total em seus projetos, recomendo o trabalho baseado em UML (Unified Modeling Language, ou Linguagem de Modelagem Unificada). S para ter uma idia, alm das grandes empresas de software, esto adotando UML indstrias automobilsticas (GM, Ford), fabricantes de hardware (Intel, EPSON, HP, Compaq), entre outras. Mas o que UML? E quais as suas vantagens? Em resumo, UML a unificao dos mtodos Booch, OMT e OOSE, padronizando a modelagem de sistemas de software orientados a objetos, entre outras aplicaes. Hoje em dia, a recomendao bsica para desenvolvimento de sistemas a utilizao de todo o poder da orientao a objetos. A UML colabora muito para a organizao e documentao de projetos orientados a objeto. Para entender melhor o UML, recomendo a leitura do livro Desenvolvendo Aplicaes com UML da Brasport. Mas falar de UML sem falar de sua principal ferramenta, realmente um deslize. Ao meu ver, no existe ferramenta melhor que o Rational Rose da empresa Rational (www.rational.com.br). Todas as especificaes da UML so encontradas na ferramenta, alm da integrao com as principais linguagens de desenvolvimento do mercado. E como agora ganhamos o Model Maker, lets go, friends!!!

TeamSource
A Borland disponibiliza uma excelente ferramenta de controle de verses e de trabalho em equipe: a TeamSource. Com esta ferramenta possvel gerenciar inmeras verses do projeto, alm de organizar o desenvolvimento em grupo, permitindo que inmeros desenvolvedores participem do mesmo projeto. Maiores informaes www.borland.com.br

Introduo 15

Anotaes de Dvidas

?
Preciso Revisar

Anotaes Gerais

16 Delphi 7 Internet e Banco de Dados

Captulo 2
Aplicaes Servidoras
O que so
As aplicaes servidoras so responsveis pelo processamento das informaes no servidor WEB, e a gerao das informaes em formato HTML, ou outro designado pelo desenvolvedor. As Aplicaes Servidoras so responsveis pela comunicao entre um Servidor HTTP e o cliente. No captulo de servidores WEB, encontramos uma representao grfica das aplicaes servidoras.

Principais exemplos
Grandes instituies financeiras utilizam aplicaes servidoras para disponibilizar tecnologia Internet Banking aos seus clientes. Bradesco e Ita so bons exemplos. Atualmente empresas de mdio e grande porte utilizam aplicaes servidoras em seus sistemas ERP e CRM. O Delphi fornece diversas formas de desenvolver tais aplicaes. So elas: CGI, WINCGI, ISAPI/NSAPI, Apache Modules.

CGI
CGI (Common Gateway Interface) um padro muito utilizado pela maioria dos servidores WEB. As aplicaes CGI so criadas com a extenso EXE, solicitando ao sistema operacional a criao de um novo processo a cada execuo, ou seja, para cada execuo o sistema operacional aloca memria no servidor, tornando-o bastante carregado. Facunte, ento por que o CGI bastante utilizado, j que o mesmo escraviza o servidor? A resposta muito simples. Em servidores UNIX as aplicaes CGI so bem rpidas e leves, pois os processos no UNIX no escravizam o servidor como acontece em sistemas operacionais baseados em WIN32. A comunidade Apache.org trabalhou muito neste caso e disponibilizou, no seu servidor web, o Apache Server, um trabalho semelhante para qualquer plataforma, seja ela baseada em UNIX ou Win32.

WINCGI
WinCGI, na realidade, uma extenso do padro CGI. Foi criado para aproveitar algumas caractersticas dos sistemas operacionais baseados no Padro WIN 3x. 16 bits. Este padro no muito utilizado, devido ao baixo nmero de Servidores Web que o interpretam (no confunda sistema operacional com servidor web). No Delphi 7 este padro foi descontinuado, apenas oferecendo suporte na compilao. 16

Aplicaes Servidoras 17

ISAPI
O ISAPI (Internet Server Application Programming Interface) foi criado pela Microsoft para o desenvolvimento de contedo dinmico em servidores Web. A principal diferena entre ISAPI e CGI justamente a forma de implementao, onde o CGI gerado no padro EXE, e o ISAPI gerado no padro DLL. Portanto, os processos gerados pelo ISAPI so bem mais leves pelo fato de serem DLLs. Como visto anteriormente, o Apache disponibiliza mdulos que tratam o CGI de maneira semelhante ao ISAPI. Toda vez que uma aplicao ISAPI solicitada ao servidor Web, o mesmo cria um novo thread (um padro de processamento muito utilizado nos sistemas operacionais Win32).

NSAPI
O NSAPI (Internet Server Application Programming Interface) trabalha de forma bastante parecida com o padro ISAPI. Pelo fato de ter sido desenvolvido pela NETSCAPE (www.netscape.com), este padro pouco reconhecido pelos servidores Web.

Apache Shared Modules


Apache Shared Modules uma grande novidade incorporada desde a verso 6 do Delphi. A ONG Apache, considerada a melhor do mundo na rea de pesquisas e ferramentas Web, desenvolveu um novo padro para o seu poderoso e popular Servidor Internet, os chamados Apache Shared Modules. uma espcie de DLL, s que melhor gerenciada pelo Apache. S para ter uma idia do seu poder, o prprio Servidor Apache se encarrega de fazer a escalabilidade dos Apaches Shared Modules, facilitando assim a vida do administrador de servidores web.

Padres de Mercado
Sem sombra de dvidas o CGI se tornou padro de mercado pela sua enorme flexibilidade tanto em desenvolvimento como em gerenciamento. Alm do padro EXE gerado pelo Delphi (que j traz consigo todo o ncleo, desde o projeto at as bibliotecas necessrias para a sua execuo), existem outros padres gerados atravs de linguagens como o PERL (o preferido no mundo UNIX), C++, entre outras. Tudo bem Facunte, mas o que o Delphi tem que as outras linguagens no tm? A resposta simples: alta tecnologia disposio do desenvolvedor. Com uma enorme biblioteca de componentes nativos, alm dos milhares de componentes de terceiros, uma excelente gama de funes de manipulao de banco de dados, funes matemticas, dentre outras.

18 Delphi 7 Internet e Banco de Dados

Anotaes de Dvidas

?
Preciso Revisar

Anotaes Gerais

Servidores Web 19

Captulo 3
Servidores Web
Viso Geral
Os servidores web foram projetados para atender a diversas necessidades do mundo WEB, dentre as quais podemos destacar: HTTP (o mais comum) Servidor POP3 e SMTP (correio eletrnico) FTP (gerenciamento de arquivos) entre outros

Aqui falaremos apenas no servio HTTP. A ilustrao a seguir demonstra o trabalho de um servidor HTTP.

Internet/ TCP-IP/ HTTP

cliente HTTP IExplorer

Servidor HTTP H T M L CGI


Aplicaes Servidoras

Figura 3.1 Servidor HTTP

19

20 Delphi 7 Internet e Banco de Dados Como vimos na Figura 3.1, o servidor HTTP responsvel pelo processo de recebimento e envio de informaes. Na realidade ele recebe a requisio do cliente (browser), passa a informao aplicao servidora (CGI), e transmite ao cliente a resposta gerada pelo CGI. O mais interessante de tudo isso que o servidor HTTP pode responder s solicitaes de uma rede local, no havendo necessidade da mesma possuir acesso Internet. No mercado existem diversos servidores HTTP para as mais variadas necessidades. Por exemplo: uma empresa que queira disponibilizar aplicaes CGI na Internet para um nmero ilimitado de usurios, necessitar de um excelente servidor, o Apache Server ou at mesmo o IIS da Microsoft. Em caso de disponibilidade apenas para a rede local, existe Xitami, e o OMNIHTTPd. E para desenvolvedores, o mais conhecido o TINY, totalmente desenvolvido em Delphi e com cdigo fonte disponvel. Vamos conhecer um pouco das caractersticas de cada um deles.

IIS
O IIS (Internet Information Server) da Microsoft bastante utilizado em servidores NT. Possui um timo gerenciador, facilitando muito a vida do administrador. Como o seu uso est restrito somente a servidores baseados em Windows NT, perdeu uma enorme fatia no mercado, alm das inmeras vulnerabilidades descobertas a todo o momento. Claro que a Microsoft trabalha rpido para fechar as portas do IIS, mas devido a outras brechas no Windows NT, fica difcil tornar o IIS seguro.

Apache
Amigos, este o queridinho dos administradores de rede. Atualmente est no topo em nmero de servidores, justamente pelo fato de rodar na maioria das plataformas: Windows, Linux, Unix, Solaris, IBM-AIX, HP-UX, entre outras. O Apache um software livre, com cdigo fonte aberto, e a cada semestre surpreende os administradores de
rede, com verses magnficas. Claro que nem tudo so flores, e o Apache tambm tem suas vulnerabilidades; logicamente no Windows mais vulnervel e em outras plataformas muito menos. No possui interface de configurao apenas de terceiros mas sua configurao bastante simples. A dificuldade cresce conforme a necessidade do servidor; por exemplo: um servidor que mantm diversos sites hospedados necessita de uma configurao mais complexa. Altamente recomendvel, pode ser executado at mesmo para testar nossas aplicaes, o que faremos com enorme satisfao neste livro. O Apache um dos produtos da Apache Org e poder ser encontrado no endereo www.apache.org

Xitami
O Xitami um timo servidor HTTP pessoal. Isso mesmo, pessoal. Embora a empresa fabricante do Xitami coloca um time de craques para melhorar o produto, ainda no chegou num nvel comercial pelo menos este meu ponto de vista, ou meu modo de vista como diz uma figurinha global com o apelido de Bam-Bam. Para uma rede local
excelente, pois de fcil configurao e traz consigo alguns recursos interessantes, como o personal proxy. Para maiores informaes, visite o site do fabricante: www.xitami.com

TINY
Amigos, este o menor servidor HTTP que conheo, e o seu nome TINY (minsculo) faz jus ao seu tamanho. Desenvolvido em Delphi e com cdigo fonte aberto, o TINY recomendado para desenvolvedores testarem a sua aplicao, ou at mesmo para pequenas redes locais, com no mximo 20 computadores.

Servidores Web 21

Instalao e Configurao do Apache Server


Existem diversas distribuies do Apache. Neste livro iremos trabalhar com a distribuio MSI (Windows Installer Package) da Microsoft, verso 1.3.23. Execute o MSI apache_1.3.23-win32-x86-no_src.msi que se encontra no CD de instalao do Apache e siga os passos adiante:

Figura 3.2 Tela Inicial da Instalao do Apache A figura 3.2 ilustra a tela inicial da instalao do Apache. Para prosseguir, pressione o boto Next. Em seguida, como ilustra a figura 3.3 necessrio aceitar os termos de instalao do Apache, selecionando a primeira opo I accept ... e pressionando o boto Next para prosseguir.

Figura 3.3 Termos de Licenciamento

22 Delphi 7 Internet e Banco de Dados Em seguida, todas as novidades e informaes sobre o Apache, so apresentadas. A figura 3.4 ilustra este passo. interessante acessar as ltimas novidades do Apache a cada ms, pois alm de uma super-verso 2 estar a caminho (no momento em que escrevia este livro encontrava-se na verso Beta 2.08), outras novidades so implementadas. Pressione Next para prosseguir.

Figura 3.4 Informaes sobre o Apache O prximo passo bastante importante, pois iremos configurar os dados do nosso servidor. Como ilustra a figura 3.5 devemos preencher as seguintes informaes: Network Domain Server Name Administrator Email Informe o domnio da sua rede. Exemplo: facunte.com Informe o nome do seu servidor. Exemplo: elvis Informe o email do administrador. Exemplo: emerson@facunte.com.br

Figura 3.5 Configurao do Servidor

Servidores Web 23 Em seguida devemos optar entre a instalao completa e a customizada. Em nosso caso recomendo a instalao completa. J em caso de servidores comerciais, recomendo a instalao customizada, de forma que possamos eliminar alguns arquivos desnecessrios, como documentao do Apache. Clique em Next para prosseguir.

Figura 3.6 Tipo de configurao. Agora basta clicar no boto Install para dar incio instalao conforme nossa configurao. A figura 3.7 ilustra este momento.

Figura 3.7 Incio da Instalao Aps finalizada a instalao, reinicie o Windows para que o mesmo reconhea o Apache e estabelea o servio de HTTP. Caso voc esteja utilizando Windows 98x (SE, ME), clique em Start no grupo de programas do Apache e o mesmo ser executado em modo console. Para testar o Apache e ver se est tudo ok, entre no seu browser e digite no endereo URL: http://localhost Devero aparecer informaes sobre o Apache Server como ilustra a figura 3.8.

24 Delphi 7 Internet e Banco de Dados

Figura 3.8 Teste do Apache Aps a instalao do Apache, devemos configur-lo para servir uma rede local. No grupo de menus do Apache, temos a seo Configure Apache Server, e dentro desta seo temos a opo Edit the Apache httpd. configuration file. Clique nesta opo e caso o Windows questione sobre qual tipo de programa utilizar para abrir o arquivo, selecione Bloco de Notas, ou NotePad. Ao abrir o arquivo, temos algo parecido com a figura 3.9.

Figura 3.9 httpd.conf Repare que um arquivo no padro texto (ASCII) de fcil edio. Localize a seo de configurao ServerName; veja o quadro a seguir. # # # # # # # # #

ServerName allows you to set a host name which is sent back to clients for your server if it's different than the one the program would get (i.e., use "www" instead of the host's real name). Note: You cannot just invent host names and hope they work. The name you define here must be a valid DNS name for your host. If you don't understand this, ask your network administrator. If your host doesn't have a registered DNS name, enter its IP address here.

Servidores Web 25 # You will have to access it by its address (e.g., http://123.45.67.89/) # anyway, and this will make redirections work in a sensible way. # # 127.0.0.1 is the TCP/IP local loop-back address, often named localhost. Your # machine always knows itself by this address. If you use Apache strictly for # local testing and development, you may use 127.0.0.1 as the server name. # ServerName 127.0.0.1

Em ServerName coloque o IP 127.0.0.1. Repare que o simbolo # utilizado como comentrio no Apache. Neste ponto configuramos o IP ou NOME do nosso Servidor. Como o prprio Apache recomenda, utilizamos o IP 127.0.0.1 para testes e desenvolvimento. O prximo passo configurar o diretrio de scripts, onde executaremos nossas aplicaes servidoras. Localize a seo ScriptAlias como mostra o quadro a seguir. # # ScriptAlias: This controls which directories contain server scripts. # ScriptAliases are essentially the same as Aliases, except that # documents in the realname directory are treated as applications and # run by the server when requested rather than as documents sent to the client. # The same rules about trailing "/" apply to ScriptAlias directives as to # Alias. # ScriptAlias /cgi-bin/ "C:/cursoweb/cgi-bin/" Neste ponto indicamos o diretrio de execuo de scripts, apontando para C:/cursoweb/cgi-bin. Para finalizar nossa configurao no Apache, devemos criar nosso VirtualHost. Esta seo encontra-se no final do arquivo, como segue: # # VirtualHost example: # Almost any Apache directive may go into a VirtualHost container. # The first VirtualHost section is used for requests without a known # server name. # #<VirtualHost *> # ServerAdmin webmaster@dummy-host.example.com # DocumentRoot /www/docs/dummy-host.example.com # ServerName dummy-host.example.com # ErrorLog logs/dummy-host.example.com-error_log # CustomLog logs/dummy-host.example.com-access_log common #</VirtualHost> <VirtualHost localhost> ServerAdmin emerson@facunte.com.br DocumentRoot c:/cursoweb ServerName localhost </VirtualHost> Grave as configuraes do Apache e selecione a opo Restart no grupo de opes. No diretrio C:/cursoweb dever conter o arquivo index.htm, que ser o principal. Nos tpicos seguintes iremos abordar o uso de protocolos HTTP, TCP-IP, bem como o aprendizado do HTML.

26 Delphi 7 Internet e Banco de Dados

Anotaes de Dvidas

?
Preciso Revisar

Anotaes Gerais

Aplicaes Servidoras 27

Captulo 4
Protocolos
Viso Geral
Protocolo a linguagem utilizada para troca de informaes entre computadores. Existem diversos tipos de protocolos, tais como: TCP, IP, TCP/IP, FTP, HTTP, SMTP, etc. Vejamos um breve resumo dos principais protocolos.

TCP/IP
O protocolo TCP/IP na realidade a juno do protocolo TCP (Transmission Control Protocol) com o protocolo IP (Internet Protocol). Hoje o principal protocolo de transmisso entre redes de computadores, seja via Internet, Local, Intranet ou Extranet.

HTTP
O protocolo HTTP (Hyper Text Transfer Protocol) responsvel pela integridade entre o servidor Web (HTTP) e os clientes (browsers).

FTP
O protocolo FTP (File Transfer Protocol) possui funes semelhantes ao Explorer do Windows (alguns iro achar que estou exagerando). Atravs dele podemos transferir arquivos entre servidores e clientes (download e upload), eliminar arquivos, criar diretrios, enfim, operaes bsicas comumente encontradas no Explorer do Windows.

SMTP
O protocolo SMTP (Simple Mail Transfer Protocol) utilizado para enviar mensagens de correio eletrnico para servidor SMTP.

POP
O protocolo POP (Post Office Protocol), utilizado para extrair mensagens de servidor POP3. O servidor POP3 tem como principal funo armazenar as mensagens distribudas pelo servidor SMTP. 27

28 Delphi 7 Internet e Banco de Dados

Anotaes de Dvidas

?
Preciso Revisar

Anotaes Gerais

HTML 29

Captulo 5
HTML

A linguagem HTML (HyperText Markup Language) padro para publicao de documentos na Internet. Todos os browsers (navegadores como, Netscape, Internet Explorer, Mosaic, NeoPlanet, entre outros) possuem interpretao de comandos HTML. Existem diversas verses para o padro HTML, neste livro trabalharemos com a verso 4.

Ferramentas para produzir HTML.


No mercado existem vrias ferramentas para a criao de documentos HTML. As mais utilizadas so: DreamWeaver, FrontPage, PageMill, HotDog e GoLive. Alm das ferramentas citadas, podemos produzir um documento HTML atravs do Notepad, isso mesmo, NOTEPAD do Windows. Acontece que o documento HTML um arquivo no padro texto, portanto podemos produzi-lo em qualquer editor de programas (at mesmo na ferramenta Delphi). Para facilitar o aprendizado da linguagem HTML, vamos criar nossos documentos no NotePad.

Estrutura Bsica
Um documento HTML possui basicamente dois conjuntos de informaes: Contedo Informao a ser visualizada; Tags Comandos a serem interpretados pelo browser. Exemplo: <HTML> <HEAD> <TITLE>Ttulo do Documento</TITLE> </HEAD> <BODY> Corpo do texto </BODY> </HTML>

29

30 Delphi 7 Internet e Banco de Dados A figura 5.1 demonstra o resultado do nosso primeiro exemplo.

Figura 5.1 Primeiro exemplo

TAGS Bsicos
<HTML> Estrutura HTML Para definir o incio e o fim de um documento HTML, utilizamos esta expresso: <HTML> para definir o incio, e </HTML> para definir o fim do documento. Repare na TAG que define o fim do documento </HTML>, ela possui uma barra (/) antes do comando HTML, e isso define o fechamento do documento. <HEAD> Cabealho do Documento Para definir o cabealho do documento, utilizamos a TAG <HEAD>. <HEAD> para definir o incio do cabealho, e </HEAD> para definir o fim do cabealho.

<TITLE> Ttulo do Documento Para definir o ttulo do documento (aparece na barra de ttulo do browser) , utilizamos a TAG <TITLE>. <TITLE> para definir o incio do cabealho, e </TITLE> para definir o fim do cabealho.

Exemplo:
<TITLE> Facunte On-Line </TITLE>

HTML 31 <BODY> Corpo A TAG <BODY> define o corpo do documento, ou seja, a localizao do contedo do documento. Esta TAG possui alguns atributos, como mostra a Tabela 5.1. ATRIBUTO DESCRIO

BackGround
BGColor Link Alink Vlink Text Exerccio 1:

Exibe uma imagem de fundo para a pgina HTML. Define a cor de fundo do documento Define a cor do Link Define a cor dos Links ativos Define a cor dos Links j visitados Define a cor do texto Tabela 5.1 Atributos da TAG <BODY>

Crie um novo arquivo com o nome exercicio1.html e siga o exemplo: <html> <head> <title>Mtodo Facunte</title> </head> <body bgcolor="#FFFFFF" background="imagens/logo.jpeg"> </body> </html> Repare que estamos utilizando uma figura como fundo do nosso documento HTML (logo.gif), localizado no subdiretrio IMAGENS. Faa o exerccio com outros tipos de imagens, do tipo GIF ou JPEG. A figura 5.2 ilustra o resultado do nosso exerccio. <H> ENFATIZANDO TEXTO Para enfatizar um determinado texto, utilizamos a TAG <H>, a qual chamamos de Header. Esta TAG possui seis tipos de Headers numerados de 1 a 6 <H1>, <H2>...<H6>

32 Delphi 7 Internet e Banco de Dados

Figura 5.2 Exerccio 1 Exerccio 2: <HTML> <HEAD> <TITLE>Ttulo </HEAD> <BODY> <H1> Testando <H2> Testando <H3> Testando <H4> Testando <H5> Testando <H6> Testando </BODY> </HTML>

do Documento</TITLE>

HEADER HEADER HEADER HEADER HEADER HEADER

H1 H2 H3 H4 H5 H6

</H1> </H2> </H3> </H4> </H5> </H6>

Faa o exerccio anterior, e fique vontade para alterar a posio, bem como o texto. Grave o arquivo como exercicio2.html. Sugiro que utilizem os recursos at aqui apresentados. A figura 5.3 ilustra nosso exemplo.

Figura 5.3 Header (exerccio 2)

HTML 33 <P> Pargrafos As TAGS <P> e </P> servem para iniciar e finalizar um pargrafo. A TAG <P> possui o atributo <ALIGN> para alinhar o texto, conforme a tabela 5.2.

VALOR

DEFINIO

Left Right Center Justify

Alinha o pargrafo esquerda Alinha o pargrafo direita Alinha o pargrafo no centro Justifica o pargrafo (alguns browsers no aceitam este valor) Tabela 5.2 Vvalores do atributo ALIGN

Com base no exemplo que segue, faa o exerccio 3 utilizando os recursos at aqui apresentados, criando quatro pargrafos diferentes com textos de livre expresso. Grave o arquivo como exercicio3.html A figura 5.4 ilustra nosso exemplo. Exerccio 3: <HTML> <HEAD> <TITLE>Ttulo do Documento</TITLE> </HEAD> <BODY> <P>Pargrafo sem a utilizao do atributo ALIGN</P> <P ALIGN=CENTER>Pargrafo com atributo ALIGN=CENTER</P> <P ALIGN=RIGHT>Pargrafo com atributo ALIGN=RIGHT</P> <P ALIGN=LEFT>Pargrafo com atributo ALIGN=LEFT</P> <P ALIGN=JUSTIFY>Pargrafo com atributo ALIGN=JUSTIFY. Para isso estamos utilizando um pargrafo mais longo para ver o efeito de sua utilizao.</P> </BODY> </HTML> <BR> QUEBRA DE LINHA Para definir uma quebra de linha necessrio a utilizao da TAG <BR>. Pois ao contrrio do que parece, o browser no trata os espaos em branco criados atravs da tecla <ENTER>. Veja o exemplo a seguir onde utilizamos dois blocos, sendo o primeiro sem a TAG de quebra de linha, e o segundo utilizando a TAG <BR>.

34 Delphi 7 Internet e Banco de Dados

Figura 5.4 exerccio 3 (tag <P>) Exerccio 4: <HTML> <HEAD> <TITLE>Ttulo do Documento</TITLE> </HEAD> <BODY> <P>Pargrafo sem a utilizao da TAG (BR) Segunda linha. Terceira Linha.</P> <P>Pargrafo com a utilizao da TAG (BR) Segunda linha.<BR> Terceira Linha.</P> </BODY> </HTML>

<BR>

Com base no exemplo, faa o exerccio 4 criando dois pargrafos diferentes, sendo o primeiro sem a utilizao da tag <BR> e o segundo com a tag. No se esqueam de utilizar os recursos j apresentados. A figura 5.5 ilustra o nosso exemplo.

Figura 5.5 exerccio 4 (tag <BR>)

HTML 35

Formatando o Texto
Algumas TAGs definem a formatao do texto, como tlico e negrito. Utilizamos a TAG <I> para definir a formatao do texto em itlico e a TAG <B> para definir a formatao em negrito. Exemplos: <HTML> <HEAD> <TITLE>Ttulo do Documento</TITLE> </HEAD> <BODY> <P><I>Texto em Itlico</I></P> <BR> <P><B>Texto em negrito</B></P><BR> <P><I><B>Texto em itlico e negrito</I></B></P><BR> <P>Podemos utilizar as <I>TAGs</I> de <B>formatacao</B> texto</P> </BODY> </HTML> A figura 5.6 ilustra o nosso exemplo.

em

qualquer

parte

do

Figura 5.6 Exemplo de Formatao Existem outras TAGs de formatao, como demonstra a tabela 5.3.

TAG

FORMATAO

<BIG> <SMALL>

Para texto grande Para texto pequeno

36 Delphi 7 Internet e Banco de Dados

TAG

FORMATAO

<U> <STRIKE> <SUB> <SUPB>


Exerccio 5:

Para sublinhar o texto Para riscar o texto Para texto SUBescrito Para texto SOBrescrito
Tabela 5.3 TAGs de formatao

<HTML> <HEAD> <TITLE>Ttulo do Documento</TITLE> </HEAD> <BODY> <P><BIG>Texto formatado na TAG ### BIG ### TEXTO GRANDE</BIG></P> <P><SMALL>Texto formatado na TAG ### SMALL ### TEXTO PEQUENO </SMALL></P> <P><U>Texto formatado na TAG ### U ### TEXTO SUBLINHADO</U></P> <P><STRIKE>Texto formatado na TAG ### STRIKE ### TEXTO RISCADO</STRIKE></P> <P>Texto formatado na TAG ### SUB ### Exemplo : H<SUB>2</SUB>O TEXTO SUBESCRITO</P> <P>Texto formatado na TAG ### SUP ### Exemplo : M<SUP>3</SUP> TEXTO SOBRESCRITO</P> </BODY> </HTML> Agora com as tags de formatao devidamente apresentadas, faa o exerccio 5 utilizando-as da melhor maneira possvel. Com um texto de livre pensamento, que poder torn-lo um poeta, quem sabe? A figura 5.7 ilustra o nosso exemplo.

Figura 5.7 Exerccio 5 (vrios exemplos de formatao)

HTML 37 <FONT> Ainda em formatao definio de fontes

Um recurso bastante utilizado por web-designers a alterao dos tipos de fontes, conforme a ocasio. Atravs da tag <FONT> alteramos as caractersticas de fontes de um determinado pargrafo ou at mesmo de todo o corpo do documento. Os seguintes atributos complementam a TAG <FONT>.
ATRIBUTO DESCRIO

Color Face Size

Define a cor da Fonte Define o tipo da Fonte Define o tamanho da Fonte (de 1 a 7) O tamanho tambm poder ser definido por pixel size. Tabela 5.4 Atributos da TAG <FONT>

Exemplos: <html> <head> <title>Mtodo Facunte</title> </head> <body bgcolor="#FFFFFF"> <p>&nbsp;</p> <p><font size="2">Fonte Default</font></p> <p> <font face="Arial">Fonte Arial</font></p> <p><font face="Verdana">Fonte VERDANA</font></p> <p><font face="Trebuchet">Fonte TREBUCHET</font></p> </body> </html> A figura 5.8 ilustra o nosso exemplo. Como exerccio, proponho a criao de um documento HTML com a utilizao dos tipos de fontes conhecidas, bem como a formatao de pargrafos com diversos alinhamentos, e por fim variadas formataes de textos.

38 Delphi 7 Internet e Banco de Dados

Figura 5.8 exemplos de fontes A figura 5.9 ilustra a sugesto do exerccio 6.

Figura 5.9 Exerccio 6 Veja a seguir o exemplo que utilizei para criar o exerccio 6. <html> <head> <title>Mtodo Facunte</title> </head> <body bgcolor="#FFFFFF"> <p align=CENTER><font face="Verdana" size="3"><B>Exerccio 6</B></font></p> <p align=RIGHT> <font face="Arial"><I>Fonte Arial com formatao itlica</I></font></p> <p align=LEFT> <font face="Verdana"><B><I>Fonte VERDANA com negrito e itlico</I></B></font></p>

HTML 39 <p align=CENTER><font face="Trebuchet" size="7">Fonte TREBUCHET com tamanho 7</font></p> </body> </html> <HR> Linhas Horizontais Para criar linhas horizontais utilizamos a TAG <HR>. Normalmente utilizamos esta TAG para separar blocos de texto, formulrios e imagens. Atributos da TAG <HR>

ATRIBUTO

DESCRIO

Width

Define o tamanho da linha em percentual % ou em pixel. Define a altura (espessura) da linha Define o alinhamento da linha (centro, esquerdo ou direito) Define a cor da linha Tabela 5.5 Atributos da TAG <HR>

Size Align

Color

No exemplo que segue, utilizamos trs exemplos da tag <HR>. Exemplo: <HTML> <HEAD> <TITLE>Ttulo do Documento</TITLE> </HEAD> <BODY> <P>Este bloco fala sobre o descobrimento do BRASIL</P><BR> Em 22 de Abril de 1500 o Brasil...<BR> <HR WIDTH=50% SIZE=2 ALIGN=CENTER> <BR> <P>Este bloco fala sobre as cores da Bandeira Nacional</P><BR> As cores que compem a Bandeira Nacional so... <HR WIDTH=310 SIZE=5 ALIGN=LEFT><BR> <P>O que este bloco faz aqui? </P><BR> Deve estar demonstrando alguma coisa <HR WIDTH=70% SIZE=10 COLOR="BLACK" ALIGN=CENTER> </BODY> </HTML> A figura 5.10 ilustra o nosso exemplo. No exerccio 7 crie um documento HTML com quatro pargrafos (lembrem-se de utilizar todos os recursos apresentados), separados por linhas horizontais de variadas formas.

40 Delphi 7 Internet e Banco de Dados

Figura 5.10 Exemplo de linhas horizontais <HR> Veja a figura 5.11 e o cdigo que segue como resoluo do exerccio.

Figura 5.11 Exerccio 7

Listagem 5.1 do Exerccio 7


<HTML> <HEAD><TITLE>Exerccio 7</TITLE></HEAD> <BODY> <FONT Face=Verdana Size=3> <P ALIGN=CENTER><B>Pargrafo 1</B> <HR WIDTH=80% SIZE=1 ALIGN=CENTER> <P><I>Pargrafo 2</I></P> <HR WIDTH=100% SIZE=30 ALIGN=RIGHT> <P><U>Pargrafo 3</U></P> <HR WIDTH=30% SIZE=2 COLOR="BLACK" ALIGN=CENTER> <P><B>Pargrafo 4</B></P> <HR WIDTH=150 SIZE=20 COLOR=GRAY ALIGN=LEFT> </FONT> </BODY> </HTML>

HTML 41 <OL> Listas Ordenadas Para criar listas ordenadas, utilizamos a TAG <OL>. O mais importante atributo da TAG <OL> o Type. Atravs deste atributo podemos definir o esquema de numerao.

VALOR DO ATRIBUTO TYPE

DESCRIO

TYPE = A

Utiliza letras maisculas no esquema de numerao. Utiliza letras minsculas no esquema de numerao. Utiliza algarismos romanos no esquema de numerao. Tabela 5.6 Valores para o atributo <TYPE>

TYPE = a

TYPE = I

Para cada item da lista necessria a utilizao da TAG <LI>. Veja o exemplo que segue. <HTML> <HEAD> <TITLE>Exemplo de Listas Ordenadas</TITLE> </HEAD> <BODY> <P> <OL> <LI>Primeiro Item <LI>Segundo Item <LI>Terceiro Item </OL> </P> <HR Width=50% SIZE=2 ALIGN=CENTER> <P> <OL TYPE="A"> <LI>Primeiro Item <LI>Segundo Item <LI>Terceiro Item </OL> </P> <HR Width=50% SIZE=2 ALIGN=CENTER> <P> <OL TYPE="a"> <LI>Primeiro Item <LI>Segundo Item <LI>Terceiro Item </OL> </P> <HR Width=50% SIZE=2 ALIGN=CENTER> <P> <OL TYPE="I"> <LI>Primeiro Item

42 Delphi 7 Internet e Banco de Dados <LI>Segundo Item <LI>Terceiro Item </OL> </P> </BODY> </HTML> A figura 5.12 ilustra o nosso exemplo:

Figura 5.12 Listas ordernadas No exerccio 8 crie um documento com 3 (trs) listas com diferentes numeraes, e em cada lista coloque um conjunto com 5 itens, utilizando os recursos apresentados at aqui. A figura 5.13 ilustra a resoluo deste exerccio.

Figura 5.13 Exerccio 8

Listagem 5.2 do Exerccio 8


<HTML> <HEAD> <TITLE>Exerccio 8</TITLE> </HEAD>

HTML 43 <BODY><FONT Face=Verdana Size=2> <P> <OL> <LI>Primeiro Item <LI>Segundo Item <LI>Terceiro Item <LI>Quarto Item <LI>Quinto Item </OL> </P> <P> <OL TYPE="A"> <LI>Item 1 <LI>Item 2 <LI>Item 3 <LI>Item 4 <LI>Item 5 </OL> </P> <P> <OL TYPE="a"> <LI>Primeiro Item <LI>Segundo Item <LI>Terceiro Item <LI>Quarto Item <LI>Quinto Item </OL> </P> </FONT> </BODY> </HTML> <UL> Listas No Ordenadas As listas no ordenadas so parecidas com as listas ordenadas, com a diferena de no numerarem os itens. Para criar uma lista ordenada, utilizamos a TAG <UL>. Para indicar os itens da lista utilizamos a TAG <LI> (a mesma utilizada nas listas ordenadas), onde a mesma receber um marcador ao invs de uma numerao. Exemplo: <HTML> <HEAD><TITLE>Listas no ordenadas</TITLE></HEAD> <BODY> <P> <UL> <LI>Primeiro Item <LI>Segundo Item <LI>Terceiro Item </UL> </P> </BODY> </HTML> A figura 5.14 ilustra o nosso exemplo.

44 Delphi 7 Internet e Banco de Dados

Figura 5.14 Listas no ordenadas Como a tag <UL> bem parecida com a <OL>, no faremos exerccio sobre a mesma.

Imagens
Para inserir imagens nos documentos HTML, utilizamos a TAG <IMG>. Os padres de imagens mais utilizados so GIF e JPG, pela qualidade de imagem e tamanho reduzido. Os seguintes atributos complementam a TAG <IMG>. ATRIBUTO DESCRIO

Alt

Exibe um texto enquanto a imagem no exibida Indica o nome do arquivo a ser exibido Alinhamento da imagem na pgina.

SRC ALIGN (Horizontal)-Right/Left

ALIGN(Vertical) Alinhamento Vertical da imagem TextTop/Middle/AbsMiddle/BaseLine/Bo ttom/AbsBottom Width Height Largura da imagem em pixels. Altura da imagem em pixels

HTML 45

ATRIBUTO

DESCRIO

HSPACE

Define o nmero de pixels que so deixados entre a imagem e o texto (Horizontal) Define o nmero de pixels que so deixados entre a imagem e o texto (Vertical) Define o tamanho Tabela 5.7 Atributos da TAG <FONT>

VSPACE

BORDER Exemplo:

<HTML> <HEAD> <TITLE>Trabalhando com Imagens</TITLE> </HEAD> <BODY> <IMG SRC="imagens/logo.jpg" WIDTH=140 HEIGHT=200 BORDER=5> <IMG SRC="imagens/logo.jpg" WIDTH=160 HEIGHT=240 NOBORDER> <IMG SRC="imagens/logo.jpg" NOBORDER> <IMG SRC="imagens/logo.jpg" NOBORDER Align=top> <IMG SRC="imagens/logo.jpg" NOBORDER Align=middle> </BODY> </HTML>

Figura 5.15 Trabalhando com Imagens A figura 5.15 ilustra o nosso exemplo. Repare que embora a figura seja a mesma, atravs da tag <IMG> alteramos suas caractersticas, como tamanho, borda e posicionamento vertical. No exerccio 9 crie um documento HTML com 3 (trs) imagens com variadas caractersticas.

46 Delphi 7 Internet e Banco de Dados A figura 5.16 ilustra a resoluo do exerccio 9.

Figura 5.16 exerccio 9

Listagem 5.3 do Exerccio 9


<HTML> <HEAD> <TITLE>Trabalhando com Imagens</TITLE> </HEAD> <BODY> <IMG SRC="imagens/logo.jpg" NOBORDER> <IMG SRC="imagens/borland.gif" BORDER=5 ALIGN=TOP> <IMG SRC="imagens/interbase.gif" WIDTH=300 HEIGHT=120> </BODY> </HTML> <A> Hyperlinks Os hyperlinks so indispensveis em documentos HTML. Utilizamos os hyperlinks para disponibilizar atalhos para outros documentos HTML, entre outras funcionalidades. Para criar um hyperlink, utilizamos a TAG <A> em conjunto com o seu atributo HREF. Podemos referenciar nossos hyperlinks a diversos protocolos, tais como:

PROTOCOLO

DESCRIO

http ftp mailto gopher

Servidor World Wide Web Servidor de transferncia de arquivos. Enviar e-mail Servidor Gopher, normalmente um texto ASCII.

HTML 47

PROTOCOLO

DESCRIO

news nntp telnet

Servidor de Notcias NNTP padro Servidor de Notcias NNTP particular Conexo de terminal remoto com um servidor TELNET.

Tabela 5.8 Protocolos


Exemplo: <HTML> <HEAD> <TITLE>Exemplo de Links</TITLE> </HEAD> <BODY> <CENTER> <A HREF="http://www.facunte.com.br> Facunte On-Line<BR> <IMG SRC="imagens/logo.jpg"</A> </P> </CENTER> </BODY> </HTML>

Figura 5.17 Exemplo de hyperlink


Repare na figura 5.17 que a imagem e o texto so hyperlinks. Mas como isso aconteceu? simples, a figura e o texto esto dentro das tags de hyperlink <A>; e qualquer objeto, seja ele imagem ou texto, que estiver entre as tags <A>, viram hyperlink. Para o exerccio 10, crie um documento HTML com trs hyperlinks, apontando para os seguintes endereos: www.facunte.com.br www.brasport.com.br www.borland.com.br

48 Delphi 7 Internet e Banco de Dados Voc poder utilizar imagem, texto, ou at os dois em conjunto. A figura 5.18 ilustra a resoluo do exerccio.

Figura 5.18 Exerccio 10

Listagem 5.4 do Exerccio 10


<HTML> <HEAD> <TITLE>Exerccio 10</TITLE> </HEAD> <BODY> <CENTER> <FONT FACE="Verdana" size=3><P> <A HREF="http://www.brasport.br"> <B>Editora Brasport</B></A><HR> <A HREF="http://www.facunte.com.br"> Facunte ON-LINE<BR> <IMG SRC="imagens/logo.jpg"</A><HR> <A HREF="http://www.borland.com.br"> <IMG SRC="imagens/borland.gif"</A> </FONT></P> </CENTER> </BODY> </HTML>

Tabelas
Aprender a trabalhar com tabelas no documento HTML fundamental para o desenvolvimento de excelentes documentos. Para criar uma tabela utilizamos a TAG <TABLE> em conjunto com seus atributos e subtags.

HTML 49

ATRIBUTO/SUB TAG

DESCRIO

<TR> <TD> <TH> Border Width Height

Define o incio e o fim de uma linha na tabela Define o incio e o fim de uma clula Define o cabealho da tabela Define a largura da borda Largura da tabela, em percentual %, ou pixels Largura da tabela em percentual % ou pixels Tabela 5.9 Atributos da TAG <TABLE>

Para incrementar as tabelas, as subtags <TD> e <TR> possuem atributos interessantes, veja a tabela que segue.

ATRIBUTO/SUBTAG

DESCRIO Permite definir todas as caractersticas da fonte dentro de uma clula Define a cor de fundo da clula Imagem de fundo da tabela Tabela 5.10 Atributos da TAG

FONT BGCOLOR BACKGROUND


Exemplo:

<html> <head> <title>Exemplo Tabela</title> </head><TABLE BORDER=2> <TH> Coluna 1</TH><TH> Coluna 2 </TH> <TR><TD> linha1, coluna 1</td><td> linha 1, coluna 2 </TD></TR> <TR><TD> linha 2, coluna 1</TD><TD>linha 2, coluna 2 </TD></TR> </TABLE> </BODY> </HTML> A figura 5.19 ilustra o primeiro exemplo de tabelas.

50 Delphi 7 Internet e Banco de Dados

Figura 5.19 Exemplo de tabela Vejamos um exemplo parecido, mas sem bordas. Para tanto, basta substituir o valor do BORDER para 0.

Figura 5.20 exemplo sem borda Vejamos um exemplo mais completo. <html> <head> <title>Exemplo Tabela</title> </head> <table width="80%" border="1"> <tr> <td bgcolor=gray><B>Veiculo</B></td> <td bgcolor=gray><B>Marca</B></td> </tr> <tr> <td>Palio</td> <td>Fiat</td> </tr> <tr> <td>Gol</td> <td>Volkswagem</td> </tr> <tr> <td>Corsa</td>

HTML 51 <td>GM</td> </tr> <tr> <td>Ka</td> <td>Ford</td> </tr> </table> </body> </html> A figura 5.21 ilustra o nosso exemplo.

Figura 5.21 Exemplo de tabela No exerccio 11 faa um documento HTML baseado no modelo que segue.

BANCO DE DADOS DB2 Oracle SQL Server Interbase


A figura 5.22 ilustra a resoluo do exerccio.

1998 32,1% 29,0% 16,3% 1,2%

2001 31,5% 30,9% 20,2% 3,5%

52 Delphi 7 Internet e Banco de Dados

Figura 5.22 Exerccio 11

Listagem 5.5 do Exerccio 11


<html> <head> <title>Exerccio 11</title> </head> <table width="80%" border="1"> <tr> <td bgcolor=gray align=center><B>BANCO DE DADOS </B></td> <td bgcolor=gray align=center><B>1998</B></td> <td bgcolor=gray align=center><B>2001</B></td> </tr> <tr> <td>DB2</td> <td align=center>32,1%</td> <td align=center>31,5</td> </tr> <tr> <td>Oracle</td> <td align=center>29,0%</td> <td align=center>30,9%</td> </tr> <tr> <td>SQL Server</td> <td align=center>16,3%</td> <td align=center>20,2%</td> </tr> <tr> <td>Interbase</td> <td align=center>1,2%</td> <td align=center>3,5%</td> </tr> </table> </body> </html>

HTML 53

Formulrios
Os formulrios so bastante comuns em aplicaes web. Na realidade so indispensveis. Os formulrios HTML funcionam como os formulrios de programas cliente/servidor, com a finalidade de fazer a interface entre o usurio e o banco de dados. A TAG <FORM> define o incio e o fim do formulrio. Os dois principais atributos da TAG <FORM> so:

ATRIBUTO

DESCRIO

ACTION

Define a localizao do programa ou email aos quais sero enviados os dados do formulrio Define a forma de troca de dados entre o cliente (formulrio) e o programa. Tabela 5.10 Atributo da TAG <FORM>

METHOD

Objetos do Formulrio Para inserir objetos no formulrio, utilizamos a TAG <INPUT>.

ATRIBUTO

DESCRIO

Name Value Size MaxLength

Nome do objeto Texto do objeto Tamanho do objeto Tamanho mximo permitido para entrada de dados Endereo da imagem utilizada Posio do objeto na ordem de tabulao Quando o objeto for do tipo CheckBox ou Radio, utilizada para atribuir os valores Verdadeiro ou Falso.

SRC TabIndex Checked

Tabela 5.11 Atributos da TAG <INPUT>


Para definir o tipo do objeto, utilizamos o atributo TYPE.

ATRIBUTO
Text

DESCRIO
Permite a entrada de dados, como o Edit ou DBEdit

54 Delphi 7 Internet e Banco de Dados

ATRIBUTO
Password

DESCRIO
Permite a entrada de dados, com caractere *, como PassWordChar do Delphi Caixa de seleo, como o CheckBox do Delphi

CheckBox

Radio Option Submit Reset Button Hidden Image

Como o RadioGroup do Delphi Lista de Seleo, como o ComboBox do Delphi Boto para enviar os dados do formulrio Boto para limpar os campos do formulrio Define um boto de ao prpria do usurio Incorpora um objeto invisvel ao formulrio O mesmo que Submit, mas com uma imagem ao invs do boto Tabela 5.12 Atributos do <TYPE>

Exemplo de Formulrio: <html> <head> <title>Exemplo de Formulrio</title> </head> <body bgcolor="#FFFFFF"> <form method="post" action="mailto:emerson@facunte.com.br" name="form1"> Digite seu nome <input type="text" name="NOME" size="50" maxlength="50"> <input type="submit" name="Submit"> </form> A figura 5.23 ilustra o nosso exemplo.

HTML 55

F Figura 5.23 Exemplo de formulrio Vejamos outro exemplo: <html> <head> <title>Exemplo de Formulrio</title> </head> <body bgcolor="#FFFFFF"> <form method="post" action="mailto:emerson@facunte.com.br" name="Form2"> <p>Digite seu nome <input type="text" name="NOME" size="50" maxlength="50"> </p> <p>Sexo <input type="radio" name="masculino" value="radiobutton"> Masculino <input type="radio" name="feminino" value="radiobutton"> Feminino</p> <p> <input type="submit" name="Submit" value="Enviar"> <input type="reset" name="Reset" value="Limpar Campos"> </p> </form> </body> </html> A figura 5.24 ilustra o segundo exemplo.

56 Delphi 7 Internet e Banco de Dados

Figura 5.24 Exemplo de formulrio Vejamos outro exemplo: <html> <head> <title>Exemplo de Formulrio</title> </head> <body bgcolor="#FFFFFF"> <form method="post" action="mailto:emerson@facunte.com.br" name="Formulario1"> <p>Digite seu nome <input type="text" name="NOME" size="50" maxlength="50"> </p> <p>Sexo <input type="radio" name="masculino" value="radiobutton"> Masculino <input type="radio" name="feminino" value="radiobutton"> Feminino</p> <p>Quais produtos deseja conhecer ?</p> <p> <input type="checkbox" name="Produto1" value="checkbox"> Delphi 5 - Desenvolvendo Aplicaes Cliente/Servidor<br> <input type="checkbox" name="produto2" value="checkbox"> Delphi 5 - Solues Empresariais<br> <input type="checkbox" name="produto3" value="checkbox"> Delphi 5 Comrcio Eletrnico</p> <BR> <p> <input type="submit" name="Submit" value="Enviar"> <input type="reset" name="Reset" value="Limpar Campos"> </p> </form> </body> </html> A figura 5.25 ilustra o exemplo.

HTML 57

Figura 5.25 Exemplo de formulrio Neste exemplo vamos utilizar a maioria das TAGS que aprendemos neste livro, para tornar o formulrio mais simptico. <html> <head> <title>Cadastro</title> </head> <body bgcolor="#FFFFFF"> <form method="post" action="mailto:emerson@facunte.com.br" name="Formulario"> <table width="80%" border="1" align="center" bgcolor="#3333FF"> <tr> <td><font face="Arial" size="2" color="#FFFFFF"> <b>Formulrio de Cadastro</b></font></td> </tr> </table> <table width="80%" border="0" cellpadding="0" cellspacing="0" bgcolor="#CCCCCC" align="center"> <tr> <td><font face="Verdana" size="2">Nome </font></td> <td> <font face="Verdana" size="2"><br> <input type="text" name="NOME" size="50" maxlength="50"> <br> </font></td> </tr> <tr> <td> <p><font face="Verdana" size="2">Email</font> <br> </p> </td> <td><font face="Verdana" size="2"> <input type="text" name="email" size="50" maxlength="50"> </font></td> </tr> <tr> <td><font face="Verdana" size="2"> Sexo</font></td> <td> <font face="Verdana" size="2"><br> <input type="radio" name="masculino" value="radiobutton"> Masculino <input type="radio" name="feminino" value="radiobutton">

58 Delphi 7 Internet e Banco de Dados Feminino<br> </font></td> </tr> <tr> <td><font face="Verdana" size="2"></font></td> <td> <p><font face="Verdana" size="2"><br> Quais produtos deseja conhecer ?</font></p> <p> <font face="Verdana size="2"> <input type="checkbox" name="Produto1" value="checkbox"> Delphi 5 - Desenvolvendo Aplicaes Cliente/Servidor<br> <input type="checkbox" name="produto2" value="checkbox"> Delphi 5 - Solues Empresariais<br> <input type="checkbox" name="produto3" value="checkbox"> Delphi 5 - Comrcio Eletrnico</font></p> </td> </tr> <tr> <td>&nbsp;</td> <td> <p><br> Qual verso do Delphi voc utiliza no momento <select name="versaodelphi"> <option>Delphi 1</option> <option>Delphi 2</option> <option>Delphi 3</option> <option>Delphi 4</option> <option>Delphi 5 Standard</option> <option>Delphi 5 Professional</option> <option selected>Delphi 5 Enterprise</option> </select> </p> <p>&nbsp; </p> </td> </tr> <tr> <td>&nbsp;</td> <td> <p><br> <input type="submit" name="Submit" value="Enviar"> <input type="reset" name="Reset" value="Limpar Campos"> </p> </td> </tr> </table> </form> </body> </html> A figura 5.26 ilustra este exemplo.

HTML 59

Figura 5.26 Exemplo de Formulrio Amigos, vimos a complexidade em desenvolver um formulrio em HTML, mas no se assustem, pois as ferramentas citadas anteriormente (Dreamweaver, GoLive, etc.) tornam esta tarefa bastante agradvel. Para facilitar a compreenso e o andamento do curso, faremos o exerccio de formulrio em conjunto com as aplicaes servidoras.

CSS (Cascading Style Sheet)


Para melhorar o visual dos documentos HTML, foi criado o CSS (Cascading Style Sheet ou Folhas de Estilo em Cascata). Neste livro no iremos detalhar o uso do CSS, mas abordaremos alguns itens interessantes, como por exemplo, melhorar o aspecto do formulrio. No final deste captulo disponibilizei uma tabela com todos os atributos do CSS. Isso poder ajudar no aprimoramento do uso de CSS. Bem, aqui iremos trabalhar com estilo incorporado, mas no CSS podemos trabalhar com vrios estilos, como: externo, inline e incorporado. No exemplo que segue, alteramos as cores dos campos de um formulrio. A parte em negrito
define nosso estilo. <html> <head> <title>Exemplo de Formulrio</title> <STYLE TYPE="text/css"> input { font-family: Arial, Helvetica, sans-serif; font-size: 9pt; color:#000066; background:#99CCFF; border-right:2px solid #000066; border-left:2px solid #000066; border-top:2px solid #000066; border-bottom:2px solid #000066; }

60 Delphi 7 Internet e Banco de Dados </STYLE> </head> <body bgcolor="#FFFFFF"> <form method="post" action="mailto:emerson@facunte.com.br" name="Formulario1"> <p>Digite seu nome <input type="text" name="NOME" size="50" maxlength="50"> </p> <p>Sexo <input type="radio" name="masculino" value="radiobutton"> Masculino <input type="radio" name="feminino" value="radiobutton"> Feminino</p> <p>Quais produtos deseja conhecer ?</p> <p> <input type="checkbox" name="Produto1" value="checkbox"> Delphi 5 - Desenvolvendo Aplicaes Cliente/Servidor<br> <input type="checkbox" name="produto2" value="checkbox"> Delphi 5 - Solues Empresariais<br> <input type="checkbox" name="produto3" value="checkbox"> Delphi 5 Comrcio Eletrnico</p> <BR> <p> <input type="submit" name="Submit" value="Enviar"> <input type="reset" name="Reset" value="Limpar Campos"> </p> </form> </body> </html> A figura 5.27 ilustra o nosso exemplo.

Figura 5.27 Exemplo de CSS

HTML 61

Atributos de CSS Atributo de CSS Background background-attachment background-image background-color background-position background-repeat Border border-bottom border-bottom-color border-bottom-style border-bottom-width border-color border-left border-left-color border-left-style border-left-width border-right border-right-color border-right-style border-right-width border-style border-top border-top-color border-top-style border-top-width border-width clear clip Color Cursor Display Filter Float Font @font-face font-family font-size font-style Font-variant font-weight height @import O que ele formata Cor de fundo, imagem, transparncia. Rolagem do fundo / Marca d'gua. Imagem de fundo. Cor de fundo ou transparncia. Posicionamento da imagem de fundo. Configurao lado-a-lado da imagem de fundo. Largura, estilo e cor das bordas (superior, inferior, direita e esquerda) Largura, estilo e cor da borda inferior. Cor da borda inferior. Estilo da borda inferior. Largura da borda inferior. Cor das bordas. Largura, estilo e cor da borda esquerda. Cor da borda esquerda. Estilo da borda esquerda. Largura da borda esquerda. Largura, estilo e cor da borda direita. Cor da borda direita. Estilo da borda direita. Largura da borda direita. Estilo de todas as bordas. Largura, estilo e cor da borda superior. Cor da borda superior. Estilo da borda superior. Largura da borda superior. Largura de todas as bordas. Elementos flutuantes esquerda ou direita de um elemento. Parte visvel de um elemento. Cor de primeiro plano. Tipo de ponteiro do mouse. Se o elemento exibido e o espao reservado para ele. Tipo de filtro aplicado ao elemento. Se o elemento flutua. Estilo, variante, peso, tamanho e altura da linha do tipo de fonte. Incorporao da fonte ao arquivo HTML. Tipo de fonte. Tamanho da fonte. Fonte itlico. Fonte bold. Peso da fonte de claro a negrito. Altura exibida ao elemento. Folha de estilo a importar.

62 Delphi 7 Internet e Banco de Dados

Left letter-spacing line-height list-style list-style-image list-style-position list-style-type margin margin-left margin-right margin-bottom margin-top overflow padding padding-bottom padding-left padding-right padding-top page-break-after page-break-before position text-align text-decoration text-indent text-transform top vertical-align visibility width z-index

Posio do elemento em relao margem esquerda da pgina. Distncia entre as letras. Distncia entre linhas de base. Tipo, imagem e posio do estilo da lista. Marcador de item de lista. Posio do marcador de item da lista. Marcador de item de lista alternativo. Tamanho de todas as margens. Tamanho da margem esquerda. Tamanho da margem direita. Tamanho da margem inferior. Tamanho da margem superior. Exibio de imagens que so maiores do que suas molduras. Espao em torno de um elemento em todos os lados. Espao a partir da margem inferior de um elemento. Espao esquerda do elemento. Espao direita do elemento. Espao a partir da margem superior do elemento. Inserir quebra de pgina depois de um elemento. Inserir quebra de pgina antes de um elemento. Como o elemento posicionado na pgina. Alinhamento do texto. Sublinhado, sobrelinhado ou riscado. Recuo da primeira linha do pargrafo. Transformao para todas maisculas, minsculas ou inicial maiscula. Posio do elemento em relao parte superior da pgina. Alinhamento vertical do elemento. Se elemento visvel ou invisvel. Largura do elemento. Posio do elemento na pilha.

HTML 63

JavaScript
Assim como no tpico de CSS, abordaremos apenas alguns itens sobre JavaScript. Aqui abordaremos somente a validao de formulrios utilizando o JavaScript. No exemplo que segue, verificamos se o usurio deixou o campo nome
em branco. Em caso afirmativo, disparado um alerta ao usurio. <html> <head> <title>Exemplo de Formulrio</title> <SCRIPT LANGUAGE=JAVASCRIPT TYPE TEXT/JAVASCRIPT> function ValidaForm(formulario) { if (formulario.NOME.value==) { alert(Voc precisa informar o NOME) formulario.NOME.focus() return false } return true } </SCRIPT> </head> <body bgcolor="#FFFFFF"> <form method="post" onSubmit=return ValidaForm(this) action="mailto:emerson@facunte.com.br" name="form1"> Digite seu nome <input type="text" name="NOME" size="50" maxlength="50"> <input type="submit" name="Submit"> </form> </body> </html> Caso o usurio deixe em branco o campo nome, o Javascript dispara a mensagem ilustrada na figura 5.28.

Figura 5.28 Mensagem do JavaScript. Vamos analisar o cdigo. <SCRIPT LANGUAGE=JAVASCRIPT TYPE TEXT/JAVASCRIPT> Neste ponto indicamos ao documento HTML o incio do script JavaScript. Entre as tags <SCRIPT> e </SCRIPT> temos a liberdade de inserir cdigos de linguagens de script, como o JavaScript. Em seguida criamos a funo ValidaForm, com o parmetro (formulario). function ValidaForm(formulario) { Na linha seguinte, verificamos se o usurio deixou o campo nome em branco. if (formulario.NOME.value==) { Em caso afirmativo, o JavaScript dispara um alerta ao usurio. alert(Voc precisa informar o NOME)

64 Delphi 7 Internet e Banco de Dados Em seguida focaliza o campo nome e retorna o valor false ao formulrio. formulario.NOME.focus() return false Caso contrrio retorna o valor true, liberando assim o formulrio. return true Para finalizar o script devemos fechar a tag </SCRIPT>. </SCRIPT> Para que o nosso exemplo funcione, colocamos a funo de validao dentro do formulrio, utilizando o evento OnSubmit. <form method="post" onSubmit=return ValidaForm(this) No exerccio 12, crie um documento HTML com dois campos: Nome e Email, e verifique se o usurio deixou em branco um dos campos. Em caso afirmativo dispare a mensagem Favor informar o nome do campo. A seguir, temos a resoluo do exerccio. <html> <head> <title>Exemplo de Formulrio</title> <SCRIPT LANGUAGE=JAVASCRIPT TYPE TEXT/JAVASCRIPT> function ValidaForm(formulario) { if (formulario.NOME.value==) { alert(Voc precisa informar o NOME) formulario.NOME.focus() return false } if (formulario.EMAIL.value==) { alert(Voc precisa informar o EMAIL) formulario.NOME.focus() return false } return true } </SCRIPT> </head> <body bgcolor="#FFFFFF"> <form method="post" onSubmit=return ValidaForm(this) action="mailto:emerson@facunte.com.br" name="form1"> Digite seu nome <input type="text" name="NOME" size="50" maxlength="50"><BR><BR> Digite seu Email <input type="text" name="EMAIL" size="50" maxlength="50"><HR> <input type="submit" name="Submit"> </form> </body> </html> Com isso conclumos nosso objetivo com o JavaScript.

HTML 65

Anotaes de Dvidas

?
Preciso Revisar

Anotaes Gerais

66 Delphi 7 Internet e Banco de Dados

Captulo 6
Delphi x Web x WebBroker
Para entender como funcionam as aplicaes servidoras desenvolvidas em Delphi, nada melhor do que aprender na prtica. A cada exerccio iremos evoluir no aprendizado de aplicaes servidoras web.

Primeiro Exemplo (Hello World)


Peo licena aos saudosistas para utilizar o nosso famoso Hello World como exemplo. A partir do Delphi, selecione as opes File/New/Other... e em seguida a opo Web Server Application, como ilustra a figura 6.1.

Figura 6.1 Opo Web Server Application Na janela seguinte selecione a opo CGI Stand-Alone executable (figura 6.2), e marque a opo Cross Platform, para que nossa aplicao possa ser compilada normalmente no Kylix.

66

Delphi x Web x WebBroker 67

Figura 6.2 Seleo do tipo da aplicao Em seguida teremos um WebModule (figura 6.3):

Figura 6.3 WebModule Mas o que um WebModule ? WebModule um repositrio de objetos, com a funo de armazenar os objetos no visuais da aplicao tais como (TPageProducer, TQueryPageProducer, TQuery, etc.), bem como responder s requisies do servidor HTTP. Bem, para que uma aplicao servidora possa trabalhar, devemos delegar tarefas, atravs de ActionsItems, ou simplesmente Itens de Ao. Para explicar melhor o uso de ActionsItems, imagine uma aplicao para incluso e alterao de clientes. Teremos o seguinte cenrio:

Aplicao (clientes.exe)
::: ActionItem (incluso) ao para incluir cliente ::: ActionItem(alterao)- ao para alterar cliente bastante simples, cada ActionItem tem uma funo especfica dentro da aplicao servidora. Para executar no browser uma determinada ActionItem, basta fazer como no exemplo: http://site/cgi-bin/clientes.exe/inclusao

68 Delphi 7 Internet e Banco de Dados Repare que informamos o nome da aplicao (clientes.exe) e o nome da ActionItem (/incluso). A aplicao servidora no possui limite de ActionItems, portanto podemos criar aplicaes complexas. Bem, seguindo o nosso primeiro projeto, atravs do duplo-clique no WebModule, acesse o editor de ActionItems (figura 6.4).

Figura 6.4 Editor ActionItems Clique no primeiro boto do editor para inserir uma nova Action (figura 6.5).

Figura 6.5 ActionItem Em seguida altere as seguintes propriedades, como ilustra a figura 6.6.

OBJETO TWebActionItem Objeto Acao1 Propriedade Default Name PathInfo Valor True Acao1 /acao1

Delphi x Web x WebBroker 69

Figura 6.6 Propriedades da Action Embora a propriedade PathInfo possua o mesmo valor da propriedade Name, ela que executa a Action, ou seja, no browser o que vale o valor da PathInfo. No evento OnAction coloque o seguinte cdigo: (coloque somente o cdigo em negrito, o restante criado automaticamente pelo Delphi). procedure TWebModule1.WebModule1acao1Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin Response.Content:=Ol Mundo; end; No cdigo anterior, estamos utilizando o mtodo Response da aplicao servidora. Este mtodo responsvel pela resposta do servidor uma requisio. Antes de compilar o projeto, devemos configurar uma opo. Atravs da opo Projects/Option (menu), selecione a seo Directories/Conditionals e configure a opo Output Directory para C:\cursoweb\cgi-bin, como ilustra a figura 6.7.

Tudo pronto. Agora devemos gravar o projeto com o nome de exemplo1.dpr e a unit como un_1.pas. Compile o projeto, e digite a seguinte URL no browser: http://localhost/cgi-bin/exemplo1.exe/acao1

70 Delphi 7 Internet e Banco de Dados

Figura 6.7 Configurao do diretrio


A figura 6.8 ilustra o nosso primeiro exemplo.

Figura 6.8 Exemplo 1 (aplicao servidora)

Listagem 6.1
unit un_1; interface uses SysUtils, Classes, HTTPApp; type TWebModule1 = class(TWebModule) procedure WebModule1acao1Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); private { Private declarations } public { Public declarations } end; var WebModule1: TWebModule1; implementation

Delphi x Web x WebBroker 71 {$R *.DFM} procedure TWebModule1.WebModule1acao1Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin Response.Content:='Ol Mundo'; end; end.

Segundo Exemplo (Hello World com TPageProducer)


Agora vamos conhecer um excelente objeto para dinamizar nossas aplicaes: o TPageProducer. O objeto TpageProducer tem como principal funo reproduzir uma string de comandos HTML. Na realidade podemos inserir comandos HTML com todas as Tags conhecidas, bem como as Tags transparentes que so substitudas por comandos HTML contidos no evento OnHtmlTag. Crie uma nova aplicao no Delphi atravs das opes File/New..., selecione a opo Web Server Application e clique no boto OK para confirmar. Na janela seguinte selecione a opo CGI Stand-Alone executable (figura 6.9).

Figura 6.9 Seleo do tipo da aplicao


No WebModule vamos inserir um objeto do tipo TPageProducer, que se encontra na paleta Internet. Veja como ficou nosso WebModule (figura 6.10).

. Figura 6.10 Webmodule Para prosseguir altere a propriedade HTMLDOC do PageProducer1 inserindo o seguinte cdigo:

72 Delphi 7 Internet e Banco de Dados <P align=center><B>Ol Mundo</B></P> Reparem que informamos cdigo HTML. Seguindo o nosso projeto, atravs do duplo-clique no WebModule, acesse o editor de ActionItems (figura 6.11).

Figura 6.11 Editor ActionItems Clique no primeiro boto do editor para inserir uma nova Action (figura 6.12).

figura 6.12 ActionItem Em seguida altere as seguintes propriedades.

OBJETO TWebActionItem Objeto Acao1 Propriedade Default Name PathInfo Producer Valor True Acao1 /acao1 PageProducer1

A figura 6.13 ilustra a alterao da propriedade Producer.

Delphi x Web x WebBroker 73

Figura 6.13 Propriedade Producer Com isso vinculamos a nossa Action Acao1 com o nosso produtor de pgina PageProducer1. Veremos que no necessrio disparar um cdigo, como no exemplo1. Antes de compilar o projeto, devemos configurar uma opo. Atravs da opo Projects/Option (menu), selecione a seo Directories/Conditionals e configure a opo Output Directory para C:\cursoweb\cgi-bin, como ilustra a figura 6.14.

Figura 6.14 Configurao do diretrio Tudo pronto. Agora devemos gravar o projeto com o nome de exemplo2.dpr e a unit como un_2.pas Compile o projeto, e digite a seguinte URL no browser:

http://localhost/cgi-bin/exemplo2.exe/acao1
A figura 6.15 ilustra o nosso exemplo.

74 Delphi 7 Internet e Banco de Dados

Figura 6.15 Exemplo 2 Perceberam que no colocamos uma linha sequer de cdigo? Vejam a listagem 6.2, todo o cdigo existente foi gerado automaticamente pelo Delphi.

Listagem 6.2
unit un_2; interface uses SysUtils, Classes, HTTPApp, HTTPProd; type TWebModule1 = class(TWebModule) PageProducer1: TPageProducer; private { Private declarations } public { Public declarations } end; var WebModule1: TWebModule1; implementation {$R *.DFM} end.

Terceiro Exemplo (PageProducer HTMLFile)


Em nosso terceiro exemplo utilizaremos a propriedade HTMLFile do objeto TPageProducer. O uso desta propriedade altamente recomendvel, pelo fator de utilizar um arquivo HTML externo e minimizar a manuteno no cdigo da aplicao servidora. Crie uma nova aplicao no Delphi atravs das opes File/New..., selecione a opo Web Server Application e clique no boto OK para confirmar.

Delphi x Web x WebBroker 75 Na janela seguinte selecione a opo CGI Stand-Alone executable (figura 6.16).

Figura 6.16 Seleo do tipo da aplicao No WebModule vamos inserir um objeto do tipo TPageProducer, que se encontra na paleta Internet. Veja como ficou nosso WebModule (figura 6.17).

. Figura 6.17 Webmodule Para prosseguir, altere a propriedade HTMLFILE do PageProducer1 apontando para o arquivo olamundo.html da seguinte forma: ../olamundo.html Voc deve colocar desta forma mesmo, dois pontos seqenciais seguidos da barra, e por fim o nome do arquivo. Devemos fazer isto desta maneira, pelo fato da nossa aplicao rodar num outro nvel de diretrio (CGI-BIN), e o arquivo HTML no primeiro nvel. Crie um arquivo HTML no diretrio C:\cursoweb com o nome olamundo.html e insira o cdigo que seguinte <P align=center><B>Ol Mundo</B></P> <HR> <P align=center><B>utilizando htmlfile</B></P> Seguindo o nosso projeto, atravs do duplo-clique no WebModule, acesse o editor de ActionItems (figura 6.18).

76 Delphi 7 Internet e Banco de Dados

Figura 6.18 Editor ActionItems Clique no primeiro boto do editor para inserir uma nova Action (figura 6.19).

Figura 6.19 ActionItem Em seguida altere as seguintes propriedades.

OBJETO TwebActionItem Objeto Acao1 Propriedade Default Name PathInfo Producer Valor True Acao1 /acao1 PageProducer1

A figura 6.20 ilustra a alterao da propriedade Producer.

Figura 6.20 Propriedade Producer

Delphi x Web x WebBroker 77 Com isso vinculamos a nossa Action Acao1 com o nosso produtor de pgina PageProducer1. Veremos que no necessrio disparar um cdigo, como no exemplo1. Antes de compilar o projeto, devemos configurar uma opo. Atravs da opo Projects/Option (menu), selecione a seo Directories/Conditionals e configure a opo Output Directory para C:\cursoweb\cgi-bin, como ilustra a figura 6.21.

Figura 6.21 Configurao do diretrio Tudo pronto. Agora devemos gravar o projeto com o nome de exemplo3.dpr e a unit como un_3.pas Compile o projeto, e digite a seguinte URL no browser:

http://localhost/cgi-bin/exemplo3.exe/acao1
A figura 6.22 ilustra o nosso exemplo.

Figura 6.22 Exemplo 3

Listagem 6.3
unit un_3; interface uses SysUtils, Classes, HTTPApp, HTTPProd;

78 Delphi 7 Internet e Banco de Dados type TWebModule1 = class(TWebModule) PageProducer1: TPageProducer; private { Private declarations } public { Public declarations } end; var WebModule1: TWebModule1; implementation {$R *.DFM} end.

Quarto Exemplo (PageProducerOnHTMLTag)


Em nosso quarto exemplo utilizaremos o evento OnHtmlTag do objeto TPageProducer. O uso deste evento est relacionado substituio de contedo das Tags Transparentes. Mas o que so Tags Transparentes? O Delphi interpreta como Tag Transparente a seguinte expresso: <#nome_da_tag>. Para definir uma Tag Transparente num documento HTML, basta inseri-la em qualquer ponto do documento, por exemplo: HORA <#hora>

Neste exemplo criamos uma Tag Transparente com o nome hora. O contedo desta Tag poder ser substitudo por nossa aplicao servidora. Faremos o exemplo. Crie uma nova aplicao no Delphi atravs das opes File/New..., selecione a opo Web Server Application e clique no boto OK para confirmar. Na janela seguinte selecione a opo CGI Stand-Alone executable (figura 6.23).

Figura 6.23 Seleo do tipo da aplicao

Delphi x Web x WebBroker 79 No WebModule vamos inserir um objeto do tipo TPageProducer, que se encontra na paleta Internet. Para prosseguir altere a propriedade HTMLDOC (embora eu recomende o uso do HTMLFile, neste caso utilizamos a outra forma para agilizar o curso), colocando o cdigo que segue: <P align=center><B>Teste de Tag Transparente</B></P> <HR> <P align=center><B>Hora Atual: <#hora></B></P> No evento OnHTMLTag do PageProducer1 insira o seguinte cdigo: if TagString=hora then ReplaceText:=timetostr(time); Repare que estamos substituindo o contedo da Tag Transparente hora pela hora atual (funo time). Seguindo o nosso projeto, atravs do duplo-clique no WebModule, acesse o editor de ActionItems (figura 6.24).

Figura 6.24 Editor ActionItems Clique no primeiro boto do editor para inserir uma nova Action (figura 6.25).

Figura 6.25 ActionItem Em seguida altere as seguintes propriedades.

OBJETO TWebActionItem Objeto Acao1 Propriedade Default Name PathInfo Producer Valor True Acao1 /acao1 PageProducer1

80 Delphi 7 Internet e Banco de Dados A figura 6.26 ilustra a alterao da propriedade Producer.

Figura 6.26 Propriedade Producer Com isso vinculamos a nossa Action Acao1 com o nosso produtor de pgina PageProducer1. Veremos que no necessrio disparar um cdigo, como no exemplo1 (isso est se tornando repetitivo, no acham? Mas para o bem de todos). Antes de compilar o projeto, devemos configurar uma opo. Atravs da opo Projects/Option (menu), selecione a seo Directories/Conditionals e configure a opo Output Directory para C:\cursoweb\cgi-bin, como ilustra a figura 6.27.

Figura 6.27 Configurao do diretrio

Tudo pronto. Agora devemos gravar o projeto com o nome de exemplo4.dpr e a unit como un_4.pas. Compile o projeto, e digite a seguinte URL no browser: http://localhost/cgi-bin/exemplo4.exe/acao1
A figura 6.28 ilustra o nosso exemplo.

Delphi x Web x WebBroker 81

Figura 6.28 Exemplo 4

Listagem 6.4
unit un_4; interface uses SysUtils, Classes, HTTPApp, HTTPProd; type TWebModule1 = class(TWebModule) PageProducer1: TPageProducer; procedure PageProducer1HTMLTag(Sender: TObject; Tag: TTag; const TagString: String; TagParams: TStrings; var ReplaceText: String); private { Private declarations } public { Public declarations } end; var WebModule1: TWebModule1; implementation {$R *.DFM} procedure TWebModule1.PageProducer1HTMLTag(Sender: TObject; Tag: TTag; const TagString: String; TagParams: TStrings; var ReplaceText: String); begin if TagString='hora' then ReplaceText:=timetostr(time); end; end.

82 Delphi 7 Internet e Banco de Dados

Quinto Exemplo (Interatividade com Formulrios)


Em nosso quinto exemplo, trabalharemos com formulrios HTML, interagindo o Delphi e o documento HTML. Crie uma nova aplicao no Delphi atravs das opes File/New..., selecione a opo Web Server Application e clique no boto OK para confirmar. Na janela seguinte selecione a opo CGI Stand-Alone executable (figura 6.29).

Figura 6.29 Seleo do tipo da aplicao No WebModule vamos inserir um objeto do tipo TPageProducer, que se encontra na paleta Internet. Para prosseguir altere a propriedade HTMLFILE do PageProducer1 apontando para o arquivo olamundo.html da seguinte forma: ../formulario.html Crie um arquivo HTML no diretrio C:\cursoweb com o nome formulario.html e insira o cdigo que seguinte <html> <head> <title>Exemplo de Formulrio</title> </head> <body bgcolor="#FFFFFF"> <form method="post" action="confirma" name="form1"> Digite seu nome <input type="text" name="NOME" size="50" maxlength="50"> <input type="submit" name="Submit"> </form> </body> </html>

Delphi x Web x WebBroker 83 Seguindo o nosso projeto, atravs do duplo-clique no WebModule, acesse o editor de ActionItems (figura 6.30).

Figura 6.30 Editor ActionItems Clique no primeiro boto do editor para inserir uma nova Action (figura 6.31).

Figura 6.31 ActionItem Em seguida altere as seguintes propriedades.

OBJETO TWebActionItem Objeto Formulrio Propriedade Default Name PathInfo Producer Valor True formulario /formulario PageProducer1

A figura 6.32 ilustra a alterao da propriedade Producer.

84 Delphi 7 Internet e Banco de Dados

Figura 6.32 Propriedade Producer Repare no cdigo HTML do documento, que estamos encaminhando o contedo do formulrio para a Action confirma. Para que o formulrio possa ser processado em nossa aplicao servidora, devemos criar tal item. Crie uma nova Action alterando as propriedades que seguem:

OBJETO TWebActionItem Objeto confirma Propriedade Default Name PathInfo Valor False confirma /confirma

Repare que neste caso no vinculamos o PageProducer, pois daremos uma outra resposta para esta Action. No evento OnAction da Action confirma insira o cdigo que segue: Response.Content:=Seja bem vindo + Request.ContentFields.Values[nome];

Neste caso estamos utilizando o objeto Request, que tem como principal funo extrair informaes do requerente, em nosso caso o formulrio HTML. O mtodo ContenFields extrai informaes enviadas atravs do mtodo POST do formulrio. Em nosso caso, pegamos o contedo do campo nome. Antes de compilar o projeto, devemos configurar uma opo. Atravs da opo Projects/Option (menu), selecione a seo Directories/Conditionals e configure a opo Output Directory para C:\cursoweb\cgi-bin, como ilustra a figura 6.33.

Delphi x Web x WebBroker 85

Figura 6.33 Configurao do diretrio

Tudo pronto. Agora devemos gravar o projeto com o nome de exemplo5.dpr e a unit como un_5.pas. Compile o projeto, e digite a seguinte URL no browser: http://localhost/cgi-bin/exemplo5.exe/formulario. As figuras 6.34 e 6.35
ilustram o nosso exemplo.

Figura 6.34 Inserindo o nome (Action Formulario)

Figura 6.35 Recebendo a resposta da aplicao (Action Confirma)

86 Delphi 7 Internet e Banco de Dados

Listagem 6.5
unit un_5; interface uses SysUtils, Classes, HTTPApp, HTTPProd; type TWebModule1 = class(TWebModule) PageProducer1: TPageProducer; procedure WebModule1confirmaAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); private { Private declarations } public { Public declarations } end; var WebModule1: TWebModule1; implementation {$R *.DFM} procedure TWebModule1.WebModule1confirmaAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin Response.Content:='Seja bem vindo'+ Request.ContentFields.Values['nome']; end; end.

Sexto Exemplo (Formulrios)


Em nosso sexto exemplo, tambm iremos trabalhar com formulrios HTML, interagindo o Delphi e o documento HTML. Crie uma nova aplicao no Delphi atravs das opes File/New..., selecione a opo Web Server Application e clique no boto OK para confirmar. Na janela seguinte selecione a opo CGI Stand-Alone executable (figura 6.36).

Delphi x Web x WebBroker 87

Figura 6.36 Seleo do tipo da aplicao


No WebModule vamos inserir um objeto do tipo TPageProducer, que se encontra na paleta Internet. Para prosseguir, altere a propriedade HTMLFILE do PageProducer1 apontando para o arquivo olamundo.html da seguinte forma: ../formulario2.html Crie um arquivo HTML no diretrio C:\cursoweb com o nome formulario2.html e insira o cdigo que seguinte <html> <head> <title>Exemplo de Formulrio</title> </head> <body bgcolor="#FFFFFF"> <form method="post" action="soma" name="form1"> Digite o primeiro numero <input type="text" name="NUMERO1" size="10" maxlength="10"> <BR> Digite o segundo numero <input type="text" name="NUMERO2" size="10" maxlength="10"> <input type="submit" name="Submit"> </form> </body> </html> Seguindo o nosso projeto, atravs do duplo-clique no WebModule, acesse o editor de ActionItems (figura 6.37).

Figura 6.37 Editor ActionItems

88 Delphi 7 Internet e Banco de Dados Clique no primeiro boto do editor para inserir uma nova Action (figura 6.38).

Figura 6.38 ActionItem Em seguida altere as seguintes propriedades.

OBJETO TWebActionItem Objeto formulario Propriedade Default Name PathInfo Producer Valor True formulario /formulario PageProducer1

Repare no cdigo HTML do documento que estamos encaminhando o contedo do formulrio para a Action soma. Para que o formulrio possa ser processado em nossa aplicao servidora, devemos criar tal item. Crie uma nova Action alterando as propriedades que seguem:

OBJETO TWebActionItem Objeto soma Propriedade Default Name PathInfo Valor False soma /soma

Repare que neste caso no vinculamos o PageProducer, pois daremos uma outra resposta para esta Action. No evento OnAction da Action soma insira o cdigo que segue: (coloque somente o cdigo em negrito, o restante foi criado automaticamente pelo Delphi) procedure TWebModule1.WebModule1somaAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var numero1,numero2:single; begin numero1:=StrtoFloat(Request.ContentFields.Values ['NUMERO1']); numero2:=StrtoFloat(Request.ContentFields.Values ['NUMERO2']);

Delphi x Web x WebBroker 89

Response.Content:='A soma de '+ floattostr(numero1)+' e '+ floattostr(numero2)+' = '+ floattostr(numero1+numero2);

end; Antes de compilar o projeto, devemos configurar uma opo. Atravs da opo Projects/Option (menu), selecione a seo Directories/Conditionals e configure a opo Output Directory para C:\cursoweb\cgi-bin, como ilustra a figura 6.39.

Figura 6.39 Configurao do diretrio

Tudo pronto. Agora devemos gravar o projeto com o nome de exemplo6.dpr e a unit como un_6.pas. Compile o projeto, e digite a seguinte URL no browser: http://localhost/cgi-bin/exemplo6.exe/formulario
As figuras 6.40 e 6.41 ilustram o nosso exemplo.

Figura 6.40 Action formulrio

90 Delphi 7 Internet e Banco de Dados

Figura 6.41 Action SOMA Com isso conclumos este captulo.

Listagem 6.6
unit un_6; interface uses SysUtils, Classes, HTTPApp, HTTPProd; type TWebModule1 = class(TWebModule) PageProducer1: TPageProducer; procedure WebModule1somaAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); private { Private declarations } public { Public declarations } end; var WebModule1: TWebModule1; implementation {$R *.DFM} procedure TWebModule1.WebModule1somaAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var numero1,numero2:single; begin numero1:=StrtoFloat(Request.ContentFields.Values['NUMERO1']); numero2:=StrtoFloat(Request.ContentFields.Values['NUMERO2']); Response.Content:='A soma de '+ floattostr(numero1)+' e '+ floattostr(numero2)+' = '+ floattostr(numero1+numero2); end; end.

Delphi x Web x WebBroker 91

Anotaes de Dvidas

?
Preciso Revisar

Anotaes Gerais

92 Delphi 7 Internet e Banco de Dados

Captulo 7
Projeto Cadastro de Clientes
Neste captulo iremos desenvolver um projeto completo de cadastro de clientes, com as principais funes: incluso, alterao, excluso e consulta de registros. Antes de prosseguir com o Delphi, devemos criar o banco de dados Interbase ou Firebird com todas as suas propriedades.

Criando o Banco de Dados


Entre no IBConsole e caso no tenha registrado o Servidor Local, selecione a opo Server/Register e informe as propriedades conforme a figura 7.1.

Figura 7.1 Registrando Servidor Local Interbase

92

Projeto Cadastro de Clientes 93 No campo UserName digite SYSDBA (com letras maisculas), e no campo PassWord digite masterkey (com letras minsculas). Estas informaes so para o usurio padro. Agora vamos criar o banco de dados Clientes.GDB. Selecione a opo DataBase/Create Database e crie um novo banco de dados como ilustra a figura 7.2.

Figura 7.2 Criao do banco de dados Clientes.GDB Agora iremos criar os objetos do banco de dados Clientes.GDB. Dentro do Interative SQL execute os seguintes comandos: Criao da Tabela TBCLIENTE create table tbcliente ( cod_cliente integer not null, razao_social varchar(50), endereco varchar(50), cidade varchar(50), estado varchar(2), cep varchar(8), email varchar(50), primary key (cod_cliente) ); Execute o comando atravs das teclas CTRL-E. Criao do Generator create generator gen_clientes; Execute o comando atravs das teclas CTRL-E. Criao da Trigger TGClientes set term ||;

94 Delphi 7 Internet e Banco de Dados CREATE TRIGGER TG_CLIENTES FOR TBCLIENTE ACTIVE BEFORE INSERT POSITION 0 AS BEGIN NEW.COD_CLIENTE = GEN_ID(GEN_CLIENTES,1); END || SET TERM; Execute o comando atravs das teclas CTRL-E. Com isso finalizamos a criao dos objetos. Finalize o IBConsole e vamos iniciar nossas atividades no Delphi.

Criando as definies iniciais


Crie uma nova aplicao no Delphi atravs das opes File/New..., selecione a opo Web Server Application e clique no boto OK para confirmar. Na janela seguinte selecione a opo CGI Stand-Alone executable (figura 7.3).

Figura 7.3 Seleo do tipo da aplicao Insira um objeto do tipo TSQLConnection, e crie uma nova conexo clicando no boto + . Altere as seguintes propriedades:

OBJETO TSQLConnection Objeto BancoDados Propriedade DriverName CommitRetaining DataBase SQLDialect LoginPrompt Valor Interbase True localhost:C:/cursoweb /clientes.gdb 3 False

Projeto Cadastro de Clientes 95

Objetos Bsicos
Insira um objeto do tipo TSQLDataSet e altere as propriedades que seguem:

OBJETO TSQLDataSet Objeto tbClientes Propriedade Name SQLConnection CommandText Valor tbClientes BancoDados select * from tbclientes

Insira um objeto do tipo TSQLQuery e altere as propriedades que seguem.

OBJETO TSQLQuery Objeto SQLGeral Propriedade Name SQLConnection SQL Valor SQLGeral BancoDados select * from tbclientes where cod_cliente= :pcodigo

Na propriedade PARAMS do SQLGeral, altere o tipo do parmetro PCODIGO para Integer.

Objeto de Incluso
Insira um objeto do tipo TSQLQuery e altere as propriedades que seguem.

OBJETO TSQLQuery Objeto SQLInclui Propriedade Valor Name SQLInclui SQLConnection BancoDados SQL INSERT INTO TBCLIENTE VALUES(0,:prazao, :pendereco,:pcidade, :pestado,:pcep,:pemail)

Na propriedade PARAMS do SQLInclui altere os tipos dos parmetros para String.

96 Delphi 7 Internet e Banco de Dados

Objeto de Alterao
Insira um objeto do tipo TSQLQuery e altere as propriedades que seguem.

OBJETO TSQLQuery Objeto SQLAltera Propriedade Valor Name SQLAltera SQLConnection BancoDados SQL UPDATE TBCLIENTE SET RAZAO_SOCIAL=:prazao, ENDERECO=:pendereco, CIDADE=:pcidade, ESTADO=:pestado, CEP=:pcep, EMAIL=:pemail WHERE COD_CLIENTE=:pcodigo

Na propriedade PARAMS do SQLAltera altere os tipos dos parmetros para String, com exceo do parmetro PCODIGO, que deve ser Integer.

Objeto de Excluso
Insira um objeto do tipo TSQLQuery e altere as propriedades que seguem:

OBJETO TSQLQuery Objeto SQLExclui Propriedade Valor Name SQLExclui SQLConnection BancoDados SQL
DELETE FROM TBCLIENTE WHERE COD_CLIENTE=:pcodigo

Na propriedade PARAMS do SQLExclui altere o tipo do parmetro para Integer.

Objeto de Pesquisa Principal


Insira um objeto do tipo TDataSetTableProducer e altere as seguintes propriedades.

Projeto Cadastro de Clientes 97

OBJETO TDataSetTableProducer Objeto ppClientes Propriedade Name DataSet Valor PPClientes tbClientes

Em seguida, atravs do duplo clique adicione os campos, CODIGO e RAZAO_SOCIAL, conforme a figura 7.4

Figura 7.4 Tabela de Clientes Para inserir as colunas ALTERA e EXCLUI clique no primeiro boto. No Object Inspector voc poder alterar as propriedades de cada coluna, melhorando o visual da aplicao. No evento OnCellFormat do objeto PPClientes, insira o cdigo que segue. if (CellRow>0) and (CellColumn=2) then CellData:='<a href="altera?codigo='+tbClientes.FieldByName('cod_cliente').AsString+ '"><img src="\imagens\altera.gif" border=0> </a>'; if (CellRow>0) and (CellColumn=3) then CellData:='<a href="exclui?codigo='+tbClientes.FieldByName('cod_cliente').AsString+ '"><img src="\imagens\elimina.gif" border=0></a>'; Neste ponto indicamos duas funes: para alterar e excluir clientes.

Rotinas de manuteno
Agora insira um objeto do tipo TDataSetPageProducer e altere as seguintes propriedades.

98 Delphi 7 Internet e Banco de Dados

OBJETO TDataSetPageProducer Objeto ppInclui Propriedade Name HTMLFILE Valor PPInclui ../inc_clientes.html

Neste ponto devemos criar o arquivo inc_clientes.html Listagem do arquivo inc_clientes.html <html> <head> <title>INCLUSO DE CLIENTES</title> <STYLE TYPE="text/css"> input { font-family: Arial, Helvetica, sans-serif; font-size: 9pt; color:#000066; background:#CCCCCC; border-right:2px solid #000066; border-left:2px solid #000066; border-top:2px solid #000066; border-bottom:2px solid #000066; } </STYLE> </head> <body bgcolor="#FFFFFF" text="#000000"> <table width="100%" border="1" bordercolor="#000066" bgcolor="#000066"> <tr> <td> <div align="center"><font color="#FFFFFF" face="Verdana"><b>INCLUSAO DE CLIENTES</b></font></div> </td> </tr> </table> <table align=center border=1 cellpadding=0 cellspacing=0 width=100% bordercolor="#000066"> <tr> <td bgcolor=white valign=top width="97%"> <p align="center">&nbsp;</p> <form name="form1" method="post" action="confirma_inc_cliente"> <table width="100%" border="0"> <tr> <td width="23%" height="20"> <div align="right"><font Social:</font></div> </td> <td width="77%" height="20"> <p> <font face="Verdana" size="2">

face="Verdana"

size="2">Razo

Projeto Cadastro de Clientes 99 <input type="text" name="razao_social" size="90" maxlength="70"> </font></p> </td> </tr> <tr> <td width="23%"> <div align="right"><font face="Verdana" size="2">Endereo:</font></div> </td> <td width="77%"> <font face="Verdana" size="2"> <input type="text" name="endereco" size="90" maxlength="70"> </font></td> </tr> <tr> <td width="23%"> <div align="right"><font face="Verdana" size="2">Cidade:</font></div> </td> <td width="77%"> <font face="Verdana" size="2"> <input type="text" name="cidade" size="60" maxlength="50"> </font></td> </tr> <tr> <td width="23%"> <div align="right"><font face="Verdana" size="2">Uf:</font></div> </td> <td width="77%"> <input type="text" name="UF" size="4" maxlength="2"> </td> </tr> <tr> <td width="23%"> <div align="right"><font face="Verdana" size="2">CEP:</font></div> </td> <td width="77%"> <font face="Verdana" size="2"> <input type="text" name="cep" size="10" maxlength="8"> </font></td> </tr> <tr> <td width="23%"> <div align="right"><font face="Verdana" size="2">Email Contato:</font></div> </td> <td width="77%"> <font face="Verdana" size="2"> <input type="text" name="email" size="60" maxlength="50"> </font></td> </tr> </table> <p align="center"> <font face="Verdana" size="2"> <input type="submit" name="Submit" value="Confirma Incluso"> <input type="button" name="Submit2" value="Desiste" onClick="javascript:history.go(-1)"> </font></p> </form> </td> </tr> </table> </body> </html>

100 Delphi 7 Internet e Banco de Dados Agora insira um objeto do tipo TDataSetPageProducer e altere as seguintes propriedades.

OBJETO TDataSetPageProducer Objeto ppAltera Propriedade Name HTMLFILE DataSet Valor PPAltera ../alt_clientes.html SQLGeral

Neste ponto devemos criar o arquivo alt_clientes.html <html> <head> <title>ALTERAO DE CLIENTES</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <STYLE TYPE="text/css"> input { font-family: Arial, Helvetica, sans-serif; font-size: 9pt; color:#000066; background:#CCCCCC; border-right:2px solid #000066; border-left:2px solid #000066; border-top:2px solid #000066; border-bottom:2px solid #000066; } </STYLE> </head> <body bgcolor="#FFFFFF" text="#000000"> <table width="100%" border="1" bordercolor="#000066" bgcolor="#000066"> <tr> <td> <div align="center"><font color="#FFFFFF" face="Verdana"><b>ALTERAO DE CLIENTES</b></font></div> </td> </tr> </table> <table align=center border=1 cellpadding=0 cellspacing=0 width=100% bordercolor="#000066"> <tr> <td bgcolor=white valign=top width="97%"> <p align="center">&nbsp;</p> <form name="form1" method="post" action="confirma_alt_cliente?codigo=<#cod_cliente>"> <table width="100%" border="0"> <tr> <td width="23%" height="20"> <div align="right"><font face="Verdana" size="2">Raz&atilde;o Social:</font></div> </td> <td width="77%" height="20">

Projeto Cadastro de Clientes 101 <p> <font face="Verdana" size="2"> <input type="text" name="razao_social" size="90" maxlength="70" value="<#RAZAO_SOCIAL>"> </font></p> </td> </tr> <tr> <td width="23%"> <div align="right"><font face="Verdana" size="2">Endere&ccedil;o:</font></div> </td> <td width="77%"> <font face="Verdana" size="2"> <input type="text" name="endereco" size="90" maxlength="70" value="<#ENDERECO>"> </font></td> </tr> <tr> <td width="23%"> <div align="right"><font face="Verdana" size="2">Cidade:</font></div> </td> <td width="77%"> <font face="Verdana" size="2"> <input type="text" name="cidade" size="60" maxlength="50" value="<#CIDADE>"> </font></td> </tr> <tr> <td width="23%"> <div align="right"><font face="Verdana" size="2">Uf:</font></div> </td> <td width="77%"> <input type="text" name="UF" size="4" maxlength="2" value="<#ESTADO>"> </td> </tr> <tr> <td width="23%"> <div align="right"><font face="Verdana" size="2">CEP:</font></div> </td> <td width="77%"> <font face="Verdana" size="2"> <input type="text" name="cep" size="10" maxlength="8" value="<#CEP>"> </font></td> </tr> <tr> <td width="23%"> <div align="right"><font face="Verdana" size="2">Email Contato:</font></div> </td> <td width="77%"> <font face="Verdana" size="2"> <input type="text" name="email" size="60" maxlength="50" value="<#EMAIL>"> </font></td> </tr> </table> <p align="center"> <font face="Verdana" size="2"> <input type="submit" name="Submit" value="Confirma Alterao"> <input type="button" name="Submit2" value="Desiste" onClick="javascript:history.go(-1)"> </font></p> </form>

102 Delphi 7 Internet e Banco de Dados </td> </tr> </table> </body> </html>

Actions de manuteno
Neste ponto iremos criar as Actions. Crie uma Action alterando as propriedades que seguem.

OBJETO TWebActionItem Objeto principal Propriedade Default Name PathInfo Valor True principal /principal

Insira o cdigo que segue no evento OnAction. tbClientes.Close; tbClientes.CommandText:='SELECT * FROM TBCLIENTE WHERE RAZAO_SOCIAL LIKE '+''''+'%'+ Request.ContentFields.Values['razao']+'%'+''''; tbClientes.Open; Response.Content:='<HR><A HREF="inclusao">Incluso de Clientes</A>'+ '<FORM METHOD=POST ACTION="CONSULTA">'+ 'Consulta <INPUT TYPE=TEXT NAME=RAZAO SIZE=40>'+ '<INPUT TYPE=SUBMIT></FORM><HR>'+ ppClientes.Content; Crie outra Action alterando as propriedades que seguem.

OBJETO TWebActionItem Objeto Inclusao Propriedade Default Name PathInfo PageProducer Valor False inclusao /inclusao ppInclui

Crie outra Action alterando as propriedades que seguem.

Projeto Cadastro de Clientes 103

OBJETO TWebActionItem Objeto Altera Propriedade Default Name PathInfo Valor False Altera /altera

Insira o cdigo que segue no evento OnAction. SQLGeral.ParamByName('pcodigo').value:=StrtoInt(Request.QueryFields.Values['codigo']) ; SQLGeral.Open; Response.Content:=ppAltera.Content; SQLGeral.Close; Crie outra Action alterando as propriedades que seguem.

OBJETO TWebActionItem Objeto Exclui Propriedade Default Name PathInfo Valor False Exclui /exclui

Insira o cdigo que segue no evento OnAction. { Exclui Cliente } SQLExclui.ParamByName('pcodigo').Value:=StrtoInt(Request.QueryFields.Values['codigo'] ); SQLExclui.ExecSQL; Response.Content:='Registro excluido com sucesso'; Crie outra Action alterando as propriedades que seguem.

OBJETO TWebActionItem Objeto confirma_inc_cliente Propriedade Default Name PathInfo Valor False confirma_inc_cliente /confirma_inc_cliente

104 Delphi 7 Internet e Banco de Dados Insira o cdigo que segue no evento OnAction. { Inclui Cliente } SQLInclui.ParamByName('prazao').Value:=Request.ContentFields.Values['razao_social']; SQLInclui.ParamByName('pendereco').Value:=Request.ContentFields.Values['endereco']; SQLInclui.ParamByName('pcidade').Value:=Request.ContentFields.Values['cidade']; SQLInclui.ParamByName('pestado').Value:=Request.ContentFields.Values['uf']; SQLInclui.ParamByName('pcep').Value:=Request.ContentFields.Values['cep']; SQLInclui.ParamByName('pemail').Value:=Request.ContentFields.Values['email']; SQLInclui.ExecSQL; Response.Content:='Registro incluido com sucesso'; Crie outra Action alterando as propriedades que seguem.

OBJETO TWebActionItem Objeto confirma_alt_cliente Propriedade Default Name PathInfo Valor False confirma_alt_cliente /confirma_alt_cliente

Insira o cdigo que segue no evento OnAction. { Altera Cliente } SQLAltera.ParamByName('pcodigo').Value:=Request.QueryFields.Values['codigo']; SQLAltera.ParamByName('prazao').Value:=Request.ContentFields.Values['razao_social']; SQLAltera.ParamByName('pendereco').Value:=Request.ContentFields.Values['endereco']; SQLAltera.ParamByName('pcidade').Value:=Request.ContentFields.Values['cidade']; SQLAltera.ParamByName('pestado').Value:=Request.ContentFields.Values['uf']; SQLAltera.ParamByName('pcep').Value:=Request.ContentFields.Values['cep']; SQLAltera.ParamByName('pemail').Value:=Request.ContentFields.Values['email']; SQLAltera.ExecSQL; Response.Content:='Registro alterado com sucesso';

Figuras da Aplicao
As figuras que seguem ilustram o resultado da nossa aplicao.

Projeto Cadastro de Clientes 105

Figura 7.5 WebModule

Figura 7.6 Actions

Figura 7.7 Tela Principal da Aplicao

106 Delphi 7 Internet e Banco de Dados

Figura 7.8 Incluso de Clientes

Figura 7.9 Alterao de Clientes

Figura 7.10 Consulta

Projeto Cadastro de Clientes 107

Listagem 7.1 Cdigo completo projeto Clientes


unit un_clientes; interface uses SysUtils, Classes, HTTPApp, DBXpress, FMTBcd, DB, SqlExpr, DBWeb, HTTPProd, DSProd; type TWebModule1 = class(TWebModule) BancoDados: TSQLConnection; tbClientes: TSQLDataSet; ppClientes: TDataSetTableProducer; ppInclui: TDataSetPageProducer; SQLGeral: TSQLQuery; ppAltera: TDataSetPageProducer; SQLInclui: TSQLQuery; SQLAltera: TSQLQuery; SQLExclui: TSQLQuery; procedure ppClientesFormatCell(Sender: TObject; CellRow, CellColumn: Integer; var BgColor: THTMLBgColor; var Align: THTMLAlign; var VAlign: THTMLVAlign; var CustomAttrs, CellData: String); procedure WebModule1confirma_inc_clienteAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); procedure WebModule1confirma_alt_clienteAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); procedure WebModule1alteraAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); procedure WebModule1excluiAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); procedure WebModule1consultaAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); private { Private declarations } public { Public declarations } end; var WebModule1: TWebModule1; implementation {$R *.DFM} procedure TWebModule1.ppClientesFormatCell(Sender: TObject; CellRow, CellColumn: Integer; var BgColor: THTMLBgColor; var Align: THTMLAlign; var VAlign: THTMLVAlign; var CustomAttrs, CellData: String); begin if (CellRow>0) and (CellColumn=2) then CellData:='<a href="altera?codigo='+tbClientes.FieldByName('cod_cliente').AsString+ '"><img src="..\..\imagens\altera.gif" border=0></a>';

108 Delphi 7 Internet e Banco de Dados if (CellRow>0) and (CellColumn=3) then CellData:='<a href="exclui?codigo='+tbClientes.FieldByName('cod_cliente').AsString+ '"><img src="..\..\imagens\elimina.gif" border=0></a>'; end; procedure TWebModule1.WebModule1confirma_inc_clienteAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin { Inclui Cliente } SQLInclui.ParamByName('prazao').Value:=Request.ContentFields.Values['razao_social']; SQLInclui.ParamByName('pendereco').Value:=Request.ContentFields.Values['endereco']; SQLInclui.ParamByName('pcidade').Value:=Request.ContentFields.Values['cidade']; SQLInclui.ParamByName('pestado').Value:=Request.ContentFields.Values['uf']; SQLInclui.ParamByName('pcep').Value:=Request.ContentFields.Values['cep']; SQLInclui.ParamByName('pemail').Value:=Request.ContentFields.Values['email']; SQLInclui.ExecSQL; Response.Content:='Registro incluido com sucesso'; end; procedure TWebModule1.WebModule1confirma_alt_clienteAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin { Altera Cliente } SQLAltera.ParamByName('pcodigo').Value:=Request.QueryFields.Values['codigo']; SQLAltera.ParamByName('prazao').Value:=Request.ContentFields.Values['razao_social']; SQLAltera.ParamByName('pendereco').Value:=Request.ContentFields.Values['endereco']; SQLAltera.ParamByName('pcidade').Value:=Request.ContentFields.Values['cidade']; SQLAltera.ParamByName('pestado').Value:=Request.ContentFields.Values['uf']; SQLAltera.ParamByName('pcep').Value:=Request.ContentFields.Values['cep']; SQLAltera.ParamByName('pemail').Value:=Request.ContentFields.Values['email']; SQLAltera.ExecSQL; Response.Content:='Registro alterado com sucesso'; end; procedure TWebModule1.WebModule1alteraAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin SQLGeral.ParamByName('pcodigo').value:=StrtoInt(Request.QueryFields.Values['codigo']) ; SQLGeral.Open; Response.Content:=ppAltera.Content; SQLGeral.Close; end;

Projeto Cadastro de Clientes 109 procedure TWebModule1.WebModule1excluiAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin { Exclui Cliente } SQLExclui.ParamByName('pcodigo').Value:=StrtoInt(Request.QueryFields.Values['codigo'] ); SQLExclui.ExecSQL; Response.Content:='Registro excluido com sucesso'; end; procedure TWebModule1.WebModule1consultaAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin tbClientes.Close; tbClientes.CommandText:='SELECT * FROM TBCLIENTE WHERE RAZAO_SOCIAL LIKE '+''''+'%'+ Request.ContentFields.Values['razao']+'%'+''''; tbClientes.Open; Response.Content:='<HR><A HREF="inclusao">Incluso de Clientes</A>'+ '<FORM METHOD=POST ACTION="CONSULTA">'+ 'Consulta <INPUT TYPE=TEXT NAME=RAZAO SIZE=40>'+ '<INPUT TYPE=SUBMIT></FORM><HR>'+ ppClientes.Content; end; end.

110 Delphi 7 Internet e Banco de Dados

Anotaes de Dvidas

?
Preciso Revisar

Anotaes Gerais

Enviando E-mails 111

Captulo 8
Enviando E-mails

O recurso mais utilizado na Internet sem dvida o e-mail. Neste captulo iremos tratar deste assunto com extrema facilidade. O Delphi 7 traz incorporado em sua biblioteca de componentes o famoso pacote INDY da empresa Nevrona (www.nevrona.com). Na verso 5, o Delphi trazia o pacote da empresa NETMasters que utilizava API do Windows para executar suas funes, e desde a verso 6, foi includo o pacote INDY. O pacote da NetMasters era muito instvel, devido aos inmeros bugs tanto da parte da NETMasters, como tambm do Windows. A Nevrona adaptou seu excelente pacote (INDY) para o Kylix, baseado na tecnologia CLX. Com isso temos um excelente desempenho devido engenharia do pacote. Neste captulo iremos desenvolver um aplicativo para o envio de e-mails, utilizando os novos componentes da Nevrona. Este aplicativo est registrado na SourceForge com o nome de Mailing.NET em http://sourceforge.net/projects/mailingnet. A SourceForge uma entidade responsvel pelo gerenciamento de aplicaes com cdigo-fonte aberto, distribudos sob a licena pblica GNU. Um fator bastante importante deste projeto que o mesmo poder ser compilado em Kylix, pelo fato de ser baseado na tecnologia CLX.

Incio do Desenvolvimento
Vamos iniciar um novo projeto CLX, e no formulrio principal alterar as seguintes propriedades. OBJETO TForm Objeto fmeMail Propriedade BorderWidth Caption Name Valor 5 Mailing.Net fmeMail

Vamos gravar a unit com o nome f_principal.pas e o projeto como MailingNet.DPR. Insira um objeto do tipo TPanel e altere as propriedades que seguem:

111

112 Delphi 7 Internet e Banco de Dados

OBJETO TPanel Objeto PnConfigura Propriedade Align Caption Height Name Valor alTop ((deixe em branco)) 180 PnConfigura

Agora com o foco no formulrio (objeto fmEmail), insira um objeto do tipo TSplitter e altere as seguintes propriedades: OBJETO TSplitter Objeto Splitter1 Propriedade Align MinSize Valor alTop 30

O objeto TSplitter utilizado para dividir sees de um formulrio. Em nosso projeto, ter a funo de separar as reas de configurao e texto. Ainda com o foco no formulrio insira outro objeto do tipo TPanel e altere as propriedades, como a seguir: OBJETO TPanel Objeto PnTexto Propriedade Align Caption Name Valor alClient (((deixe em branco))) PnTexto

Repare que estamos na fase de desenvolvimento da interface do aplicativo. Claro que uma tarefa um pouco cansativa devido ao grande nmero de objetos do formulrio. Mas amigos, acreditem, vale a pena o pequeno esforo. Agora com o foco no objeto PnTexto, insira um objeto do tipo TMemo e altere as propriedades que seguem: OBJETO TMemo Objeto textodoemail Propriedade Align Lines Name Valor alClient (((deixe em branco))) TextodoEmail

Vamos dar uma pausa e observar como est ficando nosso aplicativo. A figura 8.1 ilustra esse grande momento.

Enviando E-mails 113

Figura 8.1 Fase inicial do Mailing.Net Dando continuidade ao nosso projeto, vamos inserir os objetos que seguem dentro do painel PnConfigura. Para facilitar, colocamos em destaque a seo em que se encontra o referido objeto. Exemplo: [Standard]. OBJETO TLabel [Standard] Objeto Propriedade Caption Left Top Valor Texto 17 19

OBJETO TLabel [Standard] Objeto Propriedade Caption Left Top Valor Assunto 17 51

OBJETO TEdit [Standard] Objeto Propriedade Left Name Text Top Width Valor 96 edTexto (((deixe em branco))) 16 320

114 Delphi 7 Internet e Banco de Dados

OBJETO TEdit [Standard] Objeto Propriedade Left Name Text Top Width Valor 96 edAssunto (((deixe em branco))) 46 320

OBJETO TSpeedButton [Additional] Objeto Propriedade Caption Flat Left Name Top Width Valor >> True 420 btArquivo 16 23

OBJETO TButton [Standard] Objeto Propriedade Caption Left Name Top Width Valor Envia 468 btEnvia 85 75

Ainda com o foco no objeto PnConfigura, insira um objeto do tipo TGroupBox e altere as propriedades que seguem: OBJETO TGroupBox [Standard] Objeto Propriedade Caption Height Left Name Top Width Valor Configurao Servidor SMTP 90 16 gbConfigura 80 425

Agora vamos suar a camisa e inserir alguns objetos dentro do container GbConfigura. Vamos ao batalho de objetos do container GbConfigura.

Enviando E-mails 115 OBJETO TLabel [Standard] Objeto Propriedade Caption Left Top Valor Host 16 20

OBJETO TLabel [Standard] Objeto Propriedade Caption Left Top Valor Usurio 16 44

OBJETO TLabel [Standard] Objeto Propriedade Caption Left Top Valor Conta 16 69

OBJETO TLabel [Standard] Objeto Propriedade Caption Left Top Valor Porta 327 20

OBJETO TLabel [Standard] Objeto Propriedade Caption Left Top Valor Senha 176 44

OBJETO TEdit [Standard] Objeto Propriedade Color Left Valor clAqua 63

116 Delphi 7 Internet e Banco de Dados Name Text edHost coloque o endereo do seu servidor SMTP. Exemplo: smtp.provedor.com.br 16 250

Top Width OBJETO

TEdit [Standard] Objeto Propriedade Color Left Name Text Valor clAqua 63 edUsuario coloque o usurio de sua conta SMTP. Exemplo: seunome 40 106

Top Width OBJETO

TMaskEdit [Additional] Objeto Propriedade Color Left PassWordChar Name Text Valor clAqua 216 * edSenha coloque a senha do usurio da conta de SMTP. Exemplo: suasenha 40 97

Top Width OBJETO

TEdit [Standard] Objeto Propriedade Color Left Name Text Valor clAqua 63 edConta coloque o endereo da conta de SMTP. Exemplo: seunome@provedor.com.br 16 250

Top Width

Enviando E-mails 117

OBJETO TMaskEdit [Additional] Objeto Propriedade Color EditMask Left Name Text Top Width Valor clAqua 9999;1; 368 edPorta 25 16 48

Puxa, ainda bem que esta parte acabou. Acredito que todos se cansaram, mas temos um belo formulrio para envio de e-mails. A figura 8.2 ilustra o nosso formulrio neste momento.

Figura 8.2 Fase final do design do formulrio

Detalhes do Projeto
Antes de prosseguirmos com o projeto, vamos conhec-lo melhor. O Mailing.Net utiliza como base o mesmo banco de dados no padro Interbase empregado no captulo 7. Na realidade utilizamos apenas dois campos da tabela de clientes: razao_social e email. O campo razao_social ser utilizado para substituir uma tag em nosso aplicativo e o campo email para compor o destinatrio. O mais interessante neste aplicativo o uso do objeto TDataSetPageProducer, normalmente utilizado no desenvolvimento de aplicaes Web, como vimos nos captulos anteriores. Alm disso, iremos utilizar um arquivo externo no padro HTML para relacionar com o objeto TMemo. Insira um objeto do tipo TSQLConnection, e crie uma nova conexo clicando no boto + . Altere as seguintes propriedades.

118 Delphi 7 Internet e Banco de Dados OBJETO TSQLConnection Objeto BancoDados Propriedade DriverName CommitRetaining DataBase SQLDialect LoginPrompt Name Insira um objeto do tipo TSQLDataSet e altere as propriedades que seguem: OBJETO TSQLDataSet Objeto tbClientes Propriedade Name SQLConnection CommandText Valor tbClientes BancoDados select * from tbclientes Valor Interbase True localhost:C:/cursoweb /clientes.gdb 3 False BancoDados

Codificando o boto btArquivo O objeto btArquivo ser responsvel por carregar um arquivo externo (HTML) no objeto TextodoEmail. Para nos auxiliar nesta tarefa, necessitamos de outro objeto: TOpenDialog. Insira um objeto do tipo TOpenDialog e altere as propriedades que seguem: OBJETO TOpenDialog Objeto AbrirArquivo Propriedade Name Valor AbrirArquivo

Agora vamos inserir o cdigo do boto btArquivo no evento OnClick do mesmo. procedure TfmeMail.btArquivoClick(Sender: TObject); begin if AbrirArquivo.Execute then begin EdTexto:=AbrirArquivo.FileName; // Zera O TextodoEmail TextodoEmail.Clear; // Associa o Arquivo Texto/HTML com o // objeto TextodoEmail TextodoEmail.Lines.LoadFromFile(edTexto.Text); end;

Enviando E-mails 119 end; Vamos estudar o cdigo em detalhe: if AbrirArquivo.Execute then Esta linha verifica se o mtodo Execute do objeto AbrirArquivo foi executado com xito, ou seja, indaga se o usurio selecionou algum arquivo. EdTexto.Text:=AbrirArquivo.FileName; Associa o nome do arquivo selecionado no objeto AbrirArquivo ao objeto EdTexto. TextodoEmail.Clear; O mtodo Clear limpa o contedo do objeto TextodoEmail. TextodoEmail.Lines.LoadFromFile(edTexto.Text); Aqui estamos carregando (LoadFromFile) o arquivo (edTexto.Text) dentro do objeto TextodoEmail. Em resumo, poderemos digitar o texto ou ento carregar um arquivo previamente criado.

Falando mais um pouco dos objetos INDY


Um dos grandes problemas da biblioteca NetMasters (utilizada at a verso 5 do Delphi) era o congelamento (Freeze) da aplicao em diversos momentos: na conexo, desconexo, entre outros, invariavelmente. A biblioteca da Nevrona (INDY) traz um componente que trata especificamente deste problema: IdAntiFreeze. Sua principal funo priorizar as tarefas da aplicao, evitando o efeito Freeze. Na realidade ele cria um processo, otimizando as tarefas relacionadas a objetos INDY. Vamos inserir um objeto do tipo TIdAntiFreeze, localizado na seo Indy Misc. No necessrio alterar as propriedades deste objeto. Agora iremos inserir o objeto considerado corao da nossa aplicao: TIdSMTP, localizado na seo Indy Clients. Insira um objeto do tipo TIdSMTP em nosso projeto. Iremos codificar as propriedades deste objeto em tempo de execuo. O objeto TidSMTP realiza a conexo da nossa aplicao Cliente com o servidor SMTP, responsvel pela entrega dos e-mails. Na realidade, nosso aplicativo apenas envia os e-mails para um servidor SMTP e o mesmo se encarrega de distribu-los. Poderamos criar um servidor SMTP prprio que enviaria diretamente os e-mails, mas devido complexidade do caso, ficaremos com o exemplo mais simples. Vamos continuar com o nosso projeto. Insira um objeto do tipo TIdMessage, localizado na seo Indy Misc, e altere as propriedades que seguem: OBJETO TIdMessage Objeto Mensagem Propriedade ContentType Name Valor text/HTML Mensagem

Repare que a propriedade ContentType refere-se ao tipo MIME da mensagem, ou seja, o tipo de seu contedo. Configuramos para text/HTML para que as mensagens sejam enviadas com o padro HTML ou texto (o padro HTML predomina por conter recursos de formatao). Agora, amigos, iremos trabalhar com o nosso curinga: TDataSetPageProducer. Como visto nos captulos anteriores, o objeto TDataSetPageProducer responsvel pela substituio automtica de Tags transparentes relacionadas aos campos do DataSet vinculado.

120 Delphi 7 Internet e Banco de Dados Insira um componente do tipo TDataSetPageProducer e altere as propriedades que seguem: OBJETO TDataSetPageProducer Objeto ppMensagem Propriedade DataSet Name Valor tbClientes ppMensagem

Vejamos alguns exemplos da funcionalidade do nosso curinga. Prezado(a) <#RAZAO_SOCIAL>, Estamos enviando este boletim para o seu email<BR> <#EMAIL>. .... Em tempo de execuo teremos: Prezado(a) Emerson Facunte, Estamos enviando este boletim para o seu email emerson@facunte.com.br O interessante que podemos inserir quantas Tags forem necessrias, em qualquer posio. Vejamos outro exemplo: Prezado(a) <#RAZAO_SOCIAL>, Como cliente preferencial, voc tem 10% de desconto em qualquer produto de nossa loja. Entretanto, Sr(a) <#RAZAO_SOCIAL>, esta oferta por tempo limitado. Amigos, como observamos nos captulos anteriores, poderemos produzir documentos HTML com ferramentas de terceiros, como DreamWeaver da Macromedia. Com isso teremos um e-mail mais elegante. Bem, finalmente vamos codificar o nosso glorioso boto btEnvia. Insira o cdigo que segue no evento OnClick do objeto btEnvia. procedure TfmeMail.btEnviaClick(Sender: TObject); begin // Configura Cliente idSMTP1.UserId:=edUsuario.Text; idSMTP1.Password:=edSenha.Text; idSMTP1.Host:=edHost.Text; idSMTP1.Port:=StrtoInt(edPorta.Text); // Atribui o Conteudo do objeto TextodoEmail // ao objeto PPMensagem ppMensagem.HTMLDoc:=TextodoEmail.Lines;

Enviando E-mails 121 // Abre a tabela Clientes tbClientes.Open; tbClientes.First; // Conecta ao Servidor SMTP idSMTP1.Connect; try with Mensagem do begin // Atribui o contedo do edAssunto // ao objeto Mensagem.Subject Subject:=edAssunto.Text; // Atribui o contedo do edConta // ao objeto Mensagem.From.Text From.Text:=edConta.Text; // inicia o lao while not(tbClientes.Eof) do begin // Atribui o contedo do campo EMAIL // ao objeto Mensagem.Recipients.EmailAddresses Recipients.EMailAddresses:=tbClientes.FieldByName('EMAIL').Value; ReceiptRecipient.Address:=tbClientes.FieldByName('EMAIL').Value; // Atribui o contedo do objeto ppMensagem // ao objeto Mensagem.Body.Text Body.Text:=ppMensagem.Content; // Envia a mensagem idSMTP1.Send(Mensagem); // Prximo registro tbClientes.Next; end; // lao end; // with Mensagem finally // Disconecta Servidor idSMTP1.Disconnect; end; end; Vamos analisar com cuidado este cdigo. No primeiro bloco, estamos configurando o Cliente SMTP atravs do nosso objeto idSMTP1. // Configura Cliente idSMTP1.UserId:=edUsuario.Text; idSMTP1.Password:=edSenha.Text; idSMTP1.Host:=edHost.Text; idSMTP1.Port:=StrtoInt(edPorta.Text); Repare que estamos configurando o usurio da conta UserId, a senha Password, o HOST e a porta de conexo (Port). O bloco seguinte atribui o contedo do objeto TextodaMensagem ao objeto PPMensagem.

122 Delphi 7 Internet e Banco de Dados // Atribui o Conteudo do objeto TextodoEmail // ao objeto PPMensagem ppMensagem.HTMLDoc:=TextodoEmail.Lines; A propriedade HTMLDoc armazena um documento para ser processado pelo prprio objeto. O bloco que segue abre a tabela de Clientes e posiciona o ponteiro no primeiro registro: // Abre a tabela Clientes tbClientes.Open; tbClientes.First; O bloco a seguir conecta o objeto idSMTP1 ao servidor de SMTP. // Conecta ao Servidor SMTP idSMTP1.Connect; Agora estamos protegendo o cdigo seguinte com o comando Try/Except/Finally. Em seguida estamos atribuindo o assunto da mensagem e o responsvel pelo envio da mesma. with Mensagem do begin // Atribui o conteudo do edAssunto // ao objeto Mensagem.Subject Subject:=edAssunto.Text; // Atribui o conteudo do edConta // ao objeto Mensagem.From.Text From.Text:=edConta.Text; Como as mensagens so enviadas uma a uma, fizemos um lao percorrendo toda a tabela de Clientes. while not(tbClientes.Eof) do Neste ponto estamos configurando o e-mail destino. // Atribui o conteudo do campo EMAIL // ao objeto Mensagem.Recipients.EmailAddresses Recipients.EMailAddresses:=tbClientes.FieldByName('EMAIL').Value; ReceiptRecipient.Address:=tbClientes.FieldByName('EMAIL').Value; Chegamos ao ponto mais interessante do nosso projeto. Neste bloco estamos associando o resultado do ppMensagem ao corpo da mensagem do objeto Mensagem. Quando chamamos o mtodo Content, ativamos o processamento das informaes contidas na propriedade HTMLDOC do objeto. // Atribui o contedo do objeto ppMensagem // ao objeto Mensagem.Body.Text Body.Text:=ppMensagem.Content; E finalmente enviamos a mensagem. // Envia a mensagem idSMTP1.Send(Mensagem); Bem, amigos, acredito que agora basta usar a imaginao para enviar os e-mails de maneira personalizada. Com isso conclumos nosso projeto de envio de e-mails, e de quebra refrescamos nossas idias com um novo tipo de aplicao.

Enviando E-mails 123

Figura 8.3 MailingNet em ao

Listagem 8.1 Cdigo completo do Mailing Net


unit f_principal; interface uses SysUtils, Types, Classes, QGraphics, QControls, QForms, QDialogs, QStdCtrls, QExtCtrls, QButtons, QMask, DBXpress, FMTBcd, DB, SqlExpr, IdBaseComponent, IdAntiFreezeBase, IdAntiFreeze, IdMessage, HTTPApp, HTTPProd, DSProd, IdComponent, IdTCPConnection, IdTCPClient, IdMessageClient, IdSMTP; type TfmeMail = class(TForm) PnConfigura: TPanel; Splitter1: TSplitter; pnTexto: TPanel; TextodoEmail: TMemo; Label1: TLabel; Label2: TLabel; edTexto: TEdit; edAssunto: TEdit; btArquivo: TSpeedButton; btEnvia: TButton; gbConfigura: TGroupBox; Label3: TLabel; Label4: TLabel; Label5: TLabel; Label6: TLabel; edHost: TEdit; edUsuario: TEdit; edConta: TEdit; Label7: TLabel; edSenha: TMaskEdit; edPorta: TMaskEdit; BancoDados: TSQLConnection; tbClientes: TSQLDataSet; AbrirArquivo: TOpenDialog;

124 Delphi 7 Internet e Banco de Dados IdAntiFreeze1: TIdAntiFreeze; Mensagem: TIdMessage; ppMensagem: TDataSetPageProducer; IdSMTP1: TIdSMTP; procedure btArquivoClick(Sender: TObject); procedure btEnviaClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var fmeMail: TfmeMail; implementation {$R *.xfm} procedure TfmeMail.btArquivoClick(Sender: TObject); begin if AbrirArquivo.Execute then begin EdTexto.Text:=AbrirArquivo.FileName; // Zera O TextodoEmail TextodoEmail.Clear; // Associa o Arquivo Texto/HTML com o objeto // TextodoEmail TextodoEmail.Lines.LoadFromFile(edTexto.Text); end; end; procedure TfmeMail.btEnviaClick(Sender: TObject); begin // Configura Cliente idSMTP1.UserId:=edUsuario.Text; idSMTP1.Password:=edSenha.Text; idSMTP1.Host:=edHost.Text; idSMTP1.Port:=StrtoInt(edPorta.Text); // Atribui o Conteudo do objeto TextodoEmail // ao objeto PPMensagem ppMensagem.HTMLDoc:=TextodoEmail.Lines; // Abre a tabela Clientes tbClientes.Open; tbClientes.First; // Conecta ao Servidor SMTP idSMTP1.Connect; try with Mensagem do

Enviando E-mails 125 begin // Atribui o conteudo do edAssunto // ao objeto Mensagem.Subject Subject:=edAssunto.Text; // Atribui o conteudo do edConta // ao objeto Mensagem.From.Text From.Text:=edConta.Text; // inicia o lao while not(tbClientes.Eof) do begin // Atribui o conteudo do campo EMAIL // ao objeto Mensagem.Recipients.EmailAddresses Recipients.EMailAddresses:=tbClientes.FieldByName('EMAIL').Value; ReceiptRecipient.Address:=tbClientes.FieldByName('EMAIL').Value; // Atribui o contedo do objeto ppMensagem // ao objeto Mensagem.Body.Text Body.Text:=ppMensagem.Content; // Envia a mensagem idSMTP1.Send(Mensagem); // Prximo registro tbClientes.Next; end; // lao end; // with Mensagem finally // Disconecta Servidor idSMTP1.Disconnect; end; end; end.

126 Delphi 7 Internet e Banco de Dados

Anotaes de Dvidas

?
Preciso Revisar

Anotaes Gerais

Desenvolvendo utilitrios para Internet 127

Captulo 9
Desenvolvendo utilitrios para Internet

Neste captulo, iremos desenvolver uma srie de utilitrios para Internet.

Portas Abertas: Seja Bem-Vindo


O primeiro utilitrio visa alertar aos amigos leitores sobre um grave problema: Portas Abertas. Quantos de vocs trancam a porta de suas casas ao anoitecer, ou at mesmo luz do dia? Acredito que a maioria. Com o forte avano da Internet em todo o planeta, nos deparamos com o mesmo problema em nossos computadores: Portas Abertas. Neste captulo iremos desenvolver um aplicativo para scannear e apresentar as portas que esto abertas num determinado servidor. Para facilitar a compreenso de todos, estou apresentando um exemplo muito simples, onde o usurio informa o Nome do Servidor (ou endereo IP) e o intervalo de portas a serem scanneadas. Os leitores com conhecimentos mais avanados ou know-how em Threads iro me crucificar por falta das benditas. Acontece que o principal objetivo deste exemplo demonstrar o uso do componente TCPClient, e no do uso de Threads. Isso iria complicar um pouco a compreenso dos nossos amigos leitores. Aos amigos que se encaixam neste perfil, minhas sinceras desculpas. Bem, continuando, agora vem a parte boa: mona-massa. Vamos iniciar um novo projeto no Delphi (grave a unit como un_scan.pas e o projeto como pscan.drp) e inserir os objetos que seguem:

OBJETO pnTopo TPanel Objeto TPanel Propriedade Align Caption Name Valor alTop pnTopo

127

128 Delphi 7 Internet e Banco de Dados Com o foco no objeto pnTopo insira os seguintes objetos:

OBJETO Label1 TLabel Objeto TLabel Propriedade Caption Left Top Valor HOST 16 14

OBJETO Label2 TLabel Objeto TLabel Propriedade Caption Left Top Valor Porta Inicial 16 43

OBJETO Label3 TLabel Objeto TLabel Propriedade Caption Left Top Valor Porta Final 232 43

Agora vamos inserir os objetos de controle e interatividade com o usurio. Mantenha o foco no objeto pnTopo e insira os seguintes objetos:

OBJETO NomeServidor TEdit Objeto TEdit Propriedade Name Left Top Width Valor NomeServidor 104 10 290

OBJETO Inicio TSpinEdit [Samples] Objeto TSpinEdit Propriedade Name Left Top Valor Inicio 104 40

Desenvolvendo utilitrios para Internet 129

OBJETO Fim TSpinEdit [Samples] Objeto TSpinEdit Propriedade Name Left Top Valor Fim 320 40

Neste ponto vamos inserir o boto para iniciar o processo de scanner de portas.

OBJETO btScan TButton Objeto TButton Propriedade Name Caption Left Top Valor btScan Scan 416 8

Com isso conclumos a primeira etapa do projeto. Prosseguindo, vamos criar o mdulo de sada das informaes. Agora com o foco no formulrio e no mais no objeto pnTopo, insira um objeto do tipo Tpanel alterando as seguintes propriedades:

OBJETO pnDados TPanel Objeto TPanel Propriedade Align Name Valor alClient pnDados

Vamos inserir os objetos deste painel, como segue:

OBJETO ListadePortas TMemo Objeto TMemo Propriedade Name Height Left Top Width Valor ListadePortas 180 16 76 500

Dentro deste mesmo painel pnDados, insira outro objeto do tipo TPanel alterando as propriedades que seguem:

130 Delphi 7 Internet e Banco de Dados

OBJETO PnProgresso TPanel Objeto TPanel Propriedade Name Caption Height Left Top Width Valor pnProgresso 65 16 8 500

Amigos, sei que um pouco cansativo, mas estamos quase no final. Com o foco no objeto pnProgresso insira os seguintes objetos:

OBJETO btParar TButton Objeto TButton Propriedade Name Caption Left Top Valor btParar Parar 400 32

OBJETO ProgressBar1 TProgressBar Objeto TProgressBar Propriedade Name Left Top Width Valor ProgressBar1 16 8 470

OBJETO Label4 TLabel Objeto TLabel Propriedade Caption Left Top Valor Scaneando Porta... 16 36

Desenvolvendo utilitrios para Internet 131

OBJETO porta TLabel Objeto TLabel Propriedade Caption Left Top Valor 0 112 36

Ufa!!! E para concluir a enorme lista de objetos, insira um do tipo TTCPClient que se encontra na seo Internet.

OBJETO TCPClient1 TTCPClient [Internet] Objeto TTCPClient Propriedade Name Valor TCPClient1

Finalmente vamos codificar o nosso projeto. Crie uma varivel global pertencente nossa classe Form1., com o nome Parar, do tipo Integer; veja: var Form1: TForm1; parar:integer; implementation A varivel Parar ser utilizada para finalizar o processo de Scanner das Portas. Neste ponto que poderamos criar uma Thread, mas no vamos complicar. S para aliviar um pouco a forte tenso, vamos dar uma olhadinha na interface do nosso projeto (figura 9.1):

// variavel auxiliar

Figura 9.1 Projeto Port Scanner

132 Delphi 7 Internet e Banco de Dados Vamos codificar o boto btScan, responsvel pelo ncleo do nosso projeto. No evento onClick do objeto btScan, insira o cdigo que segue (para facilitar, numerei as linhas de programao, de forma que possamos analisar melhor o cdigo). 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 procedure TForm1.BtScanClick(Sender: TObject); var i:integer; begin try ListadePortas.Clear; // Limpa a Lista de Portas parar:=0; // 0 = continua, 1 = conclui

// Definies da barra de progresso ProgressBar1.Max:=Fim.Value; ProgressBar1.Min:=Inicio.Value; PainelProgresso.Visible:=True; TcpClient1.RemoteHost := NomeServidor.Text; for i := Inicio.Value to Fim.Value do begin if parar=1 then break; // finaliza o lao ProgressBar1.Position:=i; porta.Caption:=inttostr(i); Application.ProcessMessages; TcpClient1.RemotePort := inttostr(i); TcpClient1.Active:=true; if TcpClient1.Connect then ListadePortas.Lines.Add('Porta ['+ inttostr(i) + '] aberta'); TcpClient1.Disconnect; // disconeta porta end; //for loop except on E:Exception do begin ListadePortas.Lines.Add('Erro: ' + E.Message); end; // end on do begin end; //try block ListadePortas.Lines.Add('Scaneamento das portas finalizado !');

040 PainelProgresso.Visible:=False; 041 end; 042 Vamos ao detalhamento do cdigo: A linha 002 declara uma varivel i que ir auxiliar no lao de contagem das portas. var i:integer; Na linha 004 iniciamos uma proteo de erros da aplicao.

Desenvolvendo utilitrios para Internet 133 try A linha 005 limpa o contedo do objeto ListaPortas. ListadePortas.Clear Na linha 007 inicializamos a varivel parar com o valor 0, de forma que o sistema continue scanneando as portas at o limite solicitado pelo usurio, ou atravs do pressionamento da tecla Parar, fazendo com que a varivel receba o valor 1. parar:=0; As linhas 011 e 012 configuram o objeto ProgressBar1 de maneira que o mesmo fique compatvel com as informaes porta inicial e final. Com isso temos um progresso adequado. ProgressBar1.Max:=Fim.Value; ProgressBar1.Min:=Inicio.Value; A linha 014 torna visvel o objeto PainelProgresso. PainelProgresso.Visible:=True; A linha 015 configura o servidor remoto do objeto TcpClient1. TcpClient1.RemoteHost := NomeServidor.Text; A linha 017 inicia um loop baseado nas informaes Porta Inicial e Final. for i := Inicio.Value to Fim.Value do J na linha 019 nossa aplicao verifica se existe a obrigao de paralisar o loop. Esta informao vem do boto btParar. if parar=1 then break; A linha 021 posiciona a barra de progresso em relao ao andamento do loop. ProgressBar1.Position:=i; Na linha 022 apenas mostramos ao usurio atravs do objeto Porta, qual porta est sendo scanneada no momento. porta.Caption:=inttostr(i); A linha 024 solicita ao Windows que processe as informaes da aplicao, de maneira que a mesma no tenha o efeito congelamento. Application.ProcessMessages; A linha 025 configura a porta que deve ser scanneada, a 026 tenta ativar, e a 028 verifica se houve sucesso na ativao, e em caso afirmativo, a linha 029 adiciona no objeto ListadePortas a informao de que a Porta est aberta. TcpClient1.RemotePort := inttostr(i); TcpClient1.Active:=true; if TcpClient1.Connect then ListadePortas.Lines.Add('Porta ['+ inttostr(i) + '] aberta'); A linha 031 desconecta a porta independente do seu estado (aberta ou fechada).

134 Delphi 7 Internet e Banco de Dados TcpClient1.Disconnect; A linha 032 finaliza o loop. As linhas 033, 034 e 035 tratam qualquer exceo ocorrida no bloco protegido (try...except...end). end; //for loop except on E:Exception do begin ListadePortas.Lines.Add('Erro: ' + E.Message); end; // end on do begin end; //try block Concluindo esta rotina, a linha 039 apresenta uma mensagem indicando o fim do scanneamento das portas e a 041 torna o objeto PainelProgresso invisvel. ListadePortas.Lines.Add('Scaneamento das portas finalizado !'); PainelProgresso.Visible:=False; Para concluir o nosso projeto, devemos codificar o boto btParar com o seguinte cdigo (no evento OnClick): Parar:=1; Amigos, agora s executar o aplicativo, informar o nome do servidor (caso seja seu prprio equipamento, digite localhost, no campo Nome do Servidor), e o intervalo de portas a serem scanneadas. A figura 9.2 ilustra nosso utilitrio scanneando um servidor.

Figura 9.2 Scanner em ao

IMPORTANTE Embora seja possvel, no recomendo o uso deste aplicativo para scannear portas de servidores no-autorizados. Normalmente utilizamos este tipo de aplicativo para vigiar nosso quintal e no o do vizinho. Artigo originalmente publicado na Revista The Club, n 94

Desenvolvendo utilitrios para Internet 135

Listagem 9.1
unit un_scan; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, Sockets, ComCtrls, ExtCtrls, Spin; type TForm1 = class(TForm) TcpClient1: TTcpClient; pnTopo: TPanel; BtScan: TButton; NomeServidor: TEdit; Label2: TLabel; Panel2: TPanel; ListadePortas: TMemo; PainelProgresso: TPanel; ProgressBar1: TProgressBar; Label1: TLabel; porta: TLabel; Inicio: TSpinEdit; Label3: TLabel; Label4: TLabel; Fim: TSpinEdit; btParar: TButton; procedure BtScanClick(Sender: TObject); procedure btPararClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; parar:integer; implementation {$R *.dfm} procedure TForm1.BtScanClick(Sender: TObject); var i:integer; begin try ListadePortas.Clear; // Limpa a Lista de Portas parar:=0; // 0 = continua, 1 = conclui

// variavel auxiliar

// Definies da barra de progresso ProgressBar1.Max:=Fim.Value; ProgressBar1.Min:=Inicio.Value;

136 Delphi 7 Internet e Banco de Dados PainelProgresso.Visible:=True; // Visualiza painel progresso TcpClient1.RemoteHost := NomeServidor.Text; // define o HOST for i := Inicio.Value to Fim.Value do begin if parar=1 then break; // finaliza o lao ProgressBar1.Position:=i; porta.Caption:=inttostr(i); // atualiza ProgressBar // atualiza Label Porta

Application.ProcessMessages; // solicita ao Windows prioridade no processamento da aplicao TcpClient1.RemotePort := inttostr(i); // define porta a ser scaneada TcpClient1.Active:=true; // tenta ativar a porta if TcpClient1.Connect then ListadePortas.Lines.Add('Porta ['+ inttostr(i) + '] aberta'); TcpClient1.Disconnect; // disconecta porta end; //for loop except on E:Exception do begin ListadePortas.Lines.Add('Erro: ' + E.Message); end; // end on do begin end; //try block ListadePortas.Lines.Add('Scaneamento das portas finalizado!'); PainelProgresso.Visible:=False; end; procedure TForm1.btPararClick(Sender: TObject); begin Parar:=1; end; end.

Ping
Neste tpico vamos desenvolver uma nova verso para o ping. Mas Facunte, o que ping? O utilitrio ping, encontrado na maioria dos sistemas operacionais, como Windows e Linux, utilizado para ouvir uma resposta de um determinado servidor, e medir o tempo da mesma. Esta resposta pode ser nula, quando no se consegue estabelecer uma comunicao com o servidor, ou terminal remoto. Normalmente os testes de ping so feitos em servidores de Internet, firewall, roteadores e servidores de banco de dados. Vejamos um exemplo deste utilitrio rodando no sistema operacional Windows:

Desenvolvendo utilitrios para Internet 137

Figura 9.3 Ping sendo executado no Windows XP Neste exemplo, executamos o utilitrio ping no sistema operacional Windows XP, solicitando uma resposta do computador Servidor. Repare que o ping dispara um pacote de 32 bytes no endereo IP (200.173.173.142), relacionado ao Servidor, e ouve quatro respostas num tempo menor que 1ms (um milesegundo). Com isso poderemos medir a eficincia no trfego de dados entre cliente/servidor, seja l qual for a sua origem (servidor de banco de dados, aparelho celular, servidor Internet, PDA, entre outros). Veja alguns exemplos ilustrativos do utilitrio Ping (figuras 9.4, 9.5 e 9.6).

Ping Servidor (32 bytes) Estou aqui (1ms 32 bytes)


Figura 9.4 Ping disparado contra o Servidor com resultado satisfatrio

Ping Servidor (32 bytes) Mudo (sem resposta)

Figura 9.5 Ping disparado contra o Servidor sem resposta

Ping Servidor (32 bytes)

Estou aqui (estouro tempo)


Figura 9.6 Ping disparado contra o Servidor com resultado nada agradvel (lento)

138 Delphi 7 Internet e Banco de Dados Como vimos, existem trs possibilidades de resultado: satisfatrio, sem resposta e lento. Com isso podemos fazer testes de performance em diversos tipos de servidores, e descobrir, em alguns casos, onde est o problema de lentido. Bem, amigos, agora vem a parte boa: mo-na-massa. Inicie um projeto do tipo CLX (Delphi 6 ou superior), pois poderemos executar nossa aplicao no Linux, compilando o projeto no Kylix. Grave a unit com o nome un_ping.pas e o projeto como ping.dpr. Insira o seguinte objeto, alterando suas propriedades.

Objeto TPanel [Standard]


Align Name alTop pnEndereco

Com o foco no objeto pnEndereco, insira os objetos que seguem, alterando suas respectivas propriedades:

Objeto TLabel[Standard]
Caption Left Top Endereo 12 20

Objeto TEdit [Standard]


Left Name Top Width 72 edEndereco 16 210

Objeto TBitBtn [additional]


Caption Left Name Top Width Ping 296 btPing 16 75

Agora com o foco no formulrio, insira outro objeto do tipo TPanel e altere as propriedades que seguem:

Objeto TPanel [Standard]


Align Name AlClient PnResultado

Com o foco no objeto pnResultado insira um objeto do tipo TMemo e altere as seguintes propriedades:

Objeto TMemo [standard]


Height Left Name Lines Top Width 160 16 mmResultado (deixe em branco) 16 500

Com isso teremos um formulrio parecido com a figura 9.7.

Desenvolvendo utilitrios para Internet 139

Figura 9.7 Aplicao Ping em tempo de projeto Neste ponto iremos inserir o nosso objeto chave: TidICMPClient. Muita hora nesta calma, ou melhor, muita calma nesta hora, amigos, no mais um imposto do governo, apenas o nosso componente chave. Facunte, que nome complicado de componente! O que quer dizer ICMP? ICMP quer dizer Internet Control Message Protocol, ou Protocolo Internet de Controle de Mensagens. Este protocolo normalmente utilizado pelos utilitrios que iremos desenvolver, e basicamente serve para enviar mensagens a servidores remotos. Ok, ento vamos inserir o nosso objeto TidICMPClient, e alterar as seguintes propriedades:

Objeto TPanel [Standard]


Name ReceiveTimeout NossoICMP 10000

Perceba que alteramos a propriedade ReceiveTimeout. Esta propriedade indica o tempo mximo em milessegundos para uma resposta do servidor, gerando um timeout quando ultrapassado este tempo. Vamos codificar o boto btPing, inserindo o cdigo que segue no evento OnClick: var i: integer; begin btPing.Enabled:=False; try NossoICMP.Host := edEndereco.Text; for i := 1 to 4 do begin NossoICMP.Ping; Application.ProcessMessages; end; finally btPing.Enabled := True; end; end; Vamos analisar o cdigo. Primeiro, estamos declarando uma varivel do tipo integer para nos auxiliar no lao do ping. var i: integer; Em seguida desabilitamos o boto btPing, impedindo o usurio de clicar vrias vezes e causar um efeito redundante. btPing.Enabled:=False;

140 Delphi 7 Internet e Banco de Dados No prximo ponto, protegemos o cdigo com try para que eventuais erros sejam ignorados em nossa aplicao. try Em seguida configuramos a propriedade Host do nosso objeto NossoICMP de acordo com a informao do usurio extrada do objeto edEndereco. NossoICMP.Host := edEndereco.Text; Finalmente iniciamos o lao, executando o comando Ping 4 vezes (padro), e solicitando ao S.O. uma atualizao da aplicao. for i := 1 to 4 do begin NossoICMP.Ping; Application.ProcessMessages; end; E para concluir esta parte do cdigo, finalizamos o bloco protegido, habilitando novamente o boto btPing. finally btPing.Enabled := True; end; Agora, iremos codificar o evento OnReply do objeto NossoICMP. Este evento responsvel pelas informaes de resposta. Coloque o cdigo a seguir no evento OnReply: var sTime:string; begin if (AReplyStatus.MsRoundTripTime = 0) then sTime := '<1' else sTime := '='; mmResultado.Lines.Add(Format('%d bytes de %s: sequencia#=%d tempo-de-vida(ttl)=%d tempo%s%d ms', [AReplyStatus.BytesReceived, AReplyStatus.FromIpAddress, AReplyStatus.SequenceId, AReplyStatus.TimeToLive, sTime, AReplyStatus.MsRoundTripTime])); end; Nossa Facunte, agora complicou! Que cdigo maluco esse? Amigos, primeira vista, realmente meio maluco, mas iremos desvendar rapidamente o mistrio. Primeiro declaramos uma varivel para nos auxiliar na composio da resposta: var sTime:string; Em seguida estamos verificando a propriedade MsRoundTripTime da constante AReplyStatus. Tudo bem, e de onde vem esta constante, e o que quer dizer MsRoundTripTime? Bem, a constante foi declarada no cabealho do evento OnReply, vejam: procedure TForm1.NossoICMPReply(ASender: TComponent; const AReplyStatus: TReplyStatus);

Desenvolvendo utilitrios para Internet 141 Esta uma declarao padro para o evento OnReply do objeto NossoICMP. Com relao propriedade MsRoundTripTime, ela representa o tempo em milessegundos do resultado de retorno do pacote. Caso o resultado seja 0, ento atribumos o valor < 1 nossa varivel sTime, seno, atribumos o valor = . Prosseguindo com a nossa anlise, agora vem o ponto forte da nossa aplicao: a linha de resultado. mmResultado.Lines.Add(Format('%d bytes de %s: sequencia#=%d tempo-de-vida(ttl)=%d tempo%s%d ms', [AReplyStatus.BytesReceived, AReplyStatus.FromIpAddress, AReplyStatus.SequenceId, AReplyStatus.TimeToLive, sTime, AReplyStatus.MsRoundTripTime])); Percebam que estamos adicionando contedo ao nosso objeto mmResultado: mmResultado.Lines.Add Estamos nos aproveitando da funo Format para facilitar a composio da linha de resultado. Para quem no conhece a funo Format, sugiro uma breve visita no Help do Delphi, onde sempre encontramos ricas informaes. Vejamos os significados das propriedades da constante AReplyStatus. BytesReceived FromIpAddress SequenceId TimeToLive = = = = bytes recebidos endereo do Host nmero da sequncia Tempo de vida do pacote

Agora vamos executar o nosso projeto e ver o resultado. A figura 9.8 ilustra o nosso projeto em execuo.

Figura 9.8 Projeto Ping em execuo

142 Delphi 7 Internet e Banco de Dados

Misso Cumprida
Ao final deste tpico, espero ter esclarecido a todos a utilidade do Ping, bem como ter transmitido com clareza as funcionalidades do objeto TidICMPClient.

Artigo originalmente publicado na Revista Clube Delph, n 33

Listagem 9.2 unit un_ping


unit un_ping; interface uses SysUtils, Types, Classes, QGraphics, QControls, QForms, QDialogs, QStdCtrls, QExtCtrls, QButtons, IdBaseComponent, IdComponent, IdRawBase, IdRawClient, IdIcmpClient; type TForm1 = class(TForm) pnEndereco: TPanel; PnResultado: TPanel; edEndereco: TEdit; btPing: TBitBtn; Label1: TLabel; mmResultado: TMemo; NossoICMP: TIdIcmpClient; procedure btPingClick(Sender: TObject); procedure NossoICMPReply(ASender: TComponent; const AReplyStatus: TReplyStatus); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.xfm} procedure TForm1.btPingClick(Sender: TObject); var i: integer; begin btPing.Enabled:=False; try NossoICMP.Host := edEndereco.Text; for i := 1 to 4 do begin NossoICMP.Ping;

Desenvolvendo utilitrios para Internet 143 Application.ProcessMessages; end; finally btPing.Enabled := True; end; end; procedure TForm1.NossoICMPReply(ASender: TComponent; const AReplyStatus: TReplyStatus); var sTime:string; begin if (AReplyStatus.MsRoundTripTime = 0) then sTime := '<1' else sTime := '='; mmResultado.Lines.Add(Format('%d bytes de %s: sequencia#=%d tempo-de-vida(ttl)=%d tempo%s%d ms', [AReplyStatus.BytesReceived, AReplyStatus.FromIpAddress, AReplyStatus.SequenceId, AReplyStatus.TimeToLive, sTime, AReplyStatus.MsRoundTripTime])); end; end.

TraceRoute (Tracert)
Neste tpico vamos desenvolver uma nova verso para o trace route. Muito semelhante ao nosso utilitrio ping, mas com funcionalidades mais completas, apresentando todos os servidores por onde trafegam os pacotes de informaes, entre cliente e servidor final. A figura 9.9 ilustra uma simulao do trace route.

144 Delphi 7 Internet e Banco de Dados

Cliente (Brasil)

tempo de resposta: 2ms

Provedor de Acesso

tempo de resposta: 3ms

BackBone Embratel

tempo de resposta: 1ms

Servidor Final: Japo

Figura 9.9 Simulao do Trace Route Com o trace route poderemos descobrir falhas ou lentido de resposta em todos os servidores envolvidos no processo de envio e recebimento de pacotes. Normalmente falamos que o site X est extremamente lento. Nem sempre o prprio site, pode ser um dos servidores envolvidos (conhecido como hope) no processo. Nosso utilitrio uma adaptao de um programa de demonstrao que vem no pacote da INDY Components. Vamos iniciar o desenvolvimento do nosso utilitrio. Atravs das opes File/New...CLX Application, crie uma nova aplicao. Grave a unit com o nome un_tracert.pas e o projeto como tracert.dpr. Insira os objetos que seguem alterando suas respectivas propriedades.

Objeto TPanel [Standard]


Align Name Height alTop pnTopo 155

Desenvolvendo utilitrios para Internet 145 Com o foco no objeto pnTopo, insira os objetos que seguem, alterando suas respectivas propriedades:

Objeto TPanel [Standard]


Align Name Height alTop pnDados 60

Ainda com o foco no PnTopo, insira um objeto do tipo TMemo, e altere as seguintes propriedades.

Objeto TListBox [Standard]


Align Name alClient lbLog

Agora com o foco no objeto PnDados, insira os objetos que seguem, alterando suas respectivas propriedades:

Objeto TLabel[Standard]
Caption Left Top Host Destino 12 8

Objeto TLabel[Standard]
Caption Left Top Mximo Hopes 12 40

Objeto TEdit [Standard]


Left Name Text Top Width 110 edTarget (deixar em branco) 5 280

Objeto TSpindEdit [Common Controls]


Left Name Top Value Width 110 seMaxHops 32 50 65

Objeto TButton [Standard]


Caption Left Name Top Width Executa 184 btExecuta 32 75

146 Delphi 7 Internet e Banco de Dados

Objeto TButton [Standard]


Caption Left Name Top Width Cancela 270 btCancela 32 75

Agora com o foco no Formulrio, insira outro componente do tipo TPanel alterando as seguintes propriedades.

Objeto TPanel [Standard]


Align Name AlClient PnInfo

Com o foco no objeto pnInfo insira um componente do tipo TListView, alterando as seguintes propriedades.

Objeto TListView [Common Controls]


Align Columns Name ViewStyle alClient insira trs colunas como ilustra a figura 9.10 LvTrace vsReport

Figura 9.10 Columns.items do listview1 Insira os objetos que seguem, alterando as respectivas propriedades.

Objeto idICMPClient [Indy Clients]


Name idICMPClient

Objeto idAntiFreeze [Indy Misc]


Name A figura 9.11 ilustra nosso formulrio. idAntiFreeze

Desenvolvendo utilitrios para Internet 147

Figura 9.11 Formulrio do projeto Tracert Para facilitar a organizao das nossas procedures e aes, vamos utilizar o componente ActionList. Insira um objeto do tipo TActionList e atravs do duplo-clique insira as seguintes aes (figura 9.12).

: Figura 9.12 Aes do projeto Agora vamos codificar nosso projeto. Na seo private insira o cdigo que segue. bResolved: Boolean; ResolvedHost: String; Stopped: Boolean; function PingHost(Host: string; TTL: Integer): boolean; function FindItem(TTL: Integer; Add: boolean): TListItem; Nesta seo, definimos algumas variveis e funes com o objetivo de auxiliar em alguns processos. bResolved: Boolean; ResolvedHost: String; Stopped: Boolean;

148 Delphi 7 Internet e Banco de Dados bResolved ResolvedHost Stopped para atribuir true ou false na operao de ping para atribuir o host (hope) em operao atribui o valor true para informar a paralisao das operaes.

function PingHost(Host: string; TTL: Integer): boolean; function FindItem(TTL: Integer; Add: boolean): TListItem; Na clusula uses insira as seguintes Units. uses idStack, IdException; Agora vamos codificar as aes: No evento OnExecute da Action acGO, insira o cdigo que segue: try Stopped := false; acGo.Enabled := false; acStop.enabled := true; acResolve.execute; if bResolved and not stopped then begin acPing.execute; if not stopped then acTrace.Execute; end; acGo.Enabled := true; acStop.enabled := false; finally { ok } end; { try/finnaly } Nesta rotina estamos atribuindo as definies iniciais do nosso projeto, e executando as rotinas de ping e trace. No evento OnExecute da Action acResolve, insira o cdigo que segue: bResolved := false; lbLog.Items.Append(Format('resolvendo %s', [edTarget.text])); try Application.ProcessMessages; ResolvedHost := gStack.WSGetHostByName(edTarget.text); bResolved := true; lbLog.Items.Append(format('%s resolvido %s',[edTarget.text, ResolvedHost])); except on e: EIdSocketError do lbLog.Items.text := lbLog.Items.text + e.message; end; Neste cdigo estamos resolvendo um host (hope), ou melhor, verificando informaes e possibilidade de contato com o host. Repare que estamos utilizando a funo WSGetHostByName, da unit IdStack, para mapear e resolver o host. ResolvedHost := gStack.WSGetHostByName(edTarget.text); Se a operao for bem sucedida, adicionamos no lbLog o resultado; caso contrrio, a mensagem de erro. Operao bem sucedida lbLog.Items.Append(format('%s resolvido %s',[edTarget.text, ResolvedHost]));

Desenvolvendo utilitrios para Internet 149 Erro. except on e: EIdSocketError do lbLog.Items.text := lbLog.Items.text + e.message; No evento OnExecute da Action acPing, insira o seguinte cdigo. PingHost(ResolvedHost, seMaxHops.value); Application.ProcessMessages; Aqui estamos executando a chamada da funo PingHost (ser criada posteriormente), com o host atual, e o mximo de hopes. No evento OnExecute da Action acTrace, insira o cdigo que segue. var TTL: Integer; Reached: boolean; aItem: TListItem; begin TTL := 0; reached := false; lvTrace.Items.Clear; repeat inc(TTL); IdIcmpClient.Host := ResolvedHost; IdIcmpClient.TTL := TTL; IdIcmpClient.ReceiveTimeout := 5000; IdIcmpClient.Ping; aItem := FindItem(TTL, True); aItem.SubItems.Clear; case IdIcmpClient.ReplyStatus.ReplyStatusType of rsEcho: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append(format('Reached in : %d ms', [IdIcmpClient.ReplyStatus.MsRoundTripTime])); reached := true; end; rsError: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append('Unknown error.'); end; rsTimeOut: begin aItem.SubItems.Append('?.?.?.?'); aItem.SubItems.Append('Timed out.'); end; rsErrorUnreachable: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append(format('Destination network [IdIcmpClient.ReplyStatus.MsRoundTripTime])); break; end; rsErrorTTLExceeded: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress);

unreachable',

150 Delphi 7 Internet e Banco de Dados aItem.SubItems.Append(format('TTL=%d', [IdIcmpClient.ReplyStatus.TimeToLive])); end; end; // case Application.ProcessMessages; until reached or (TTL > seMaxHops.value) or Stopped; Este cdigo um pouco mais complexo, mas vamos analisar passo a passo. Inicialmente, estamos definindo algumas variveis auxiliares. TTL Reached aItem define o hope atual. define se o TTL atual foi resolvido objeto do tipo TListItem para ser adicionado em nosso LvTrace.

var TTL: Integer; Reached: boolean; aItem: TListItem; Em seguida temos a atribuio inicial das variveis. TTL := 0; reached := false; lvTrace.Items.Clear; O bloco que segue inicia um lao, at que uma das trs situaes (resolvido reached = true, TTL > hopes, ou solicitao de cancelamento) seja verdadeira. Incrementamos o TTL, e atribumos ao objeto idICMPClient algumas configuraes, como Host e TTL. Executamos o mtodo ping do idICMPClient, e em seguida preparamos o objeto aItem para receber a informao do resultado da operao. repeat inc(TTL); IdIcmpClient.Host := ResolvedHost; IdIcmpClient.TTL := TTL; IdIcmpClient.ReceiveTimeout := 5000; IdIcmpClient.Ping; aItem := FindItem(TTL, True); aItem.SubItems.Clear; Os prximos blocos tratam os diversos tipos de resultado do mtodo ping. O bloco que segue trata o tipo de resposta (rsEcho) e adiciona um subitem ao objeto aItem. case IdIcmpClient.ReplyStatus.ReplyStatusType of rsEcho: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append(format('Reached in : %d ms', [IdIcmpClient.ReplyStatus.MsRoundTripTime])); reached := true; end; O bloco seguinte recebe um tipo de resposta de erro (rsError) e tambm adiciona um subitem ao objeto aItem. rsError: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append('Unknown error.'); end;

Desenvolvendo utilitrios para Internet 151 O prximo bloco trata o TimeOut excedido (rsTimeOut), definido como 5000 milesegundos. rsTimeOut: begin aItem.SubItems.Append('?.?.?.?'); aItem.SubItems.Append('Timed out.'); end; Em seguida, temos o tratamento de uma operao no resolvida (rsErrorUnreachable). rsErrorUnreachable: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append(format('Destination network unreachable', [IdIcmpClient.ReplyStatus.MsRoundTripTime])); break; end; E por fim, temos o tratamento de erro (rsErrorTTLExceeded), onde excedido o nmero mximo de tentativas. rsErrorTTLExceeded: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append(format('TTL=%d', [IdIcmpClient.ReplyStatus.TimeToLive])); end; end; // case Application.ProcessMessages; until reached or (TTL > seMaxHops.value) or Stopped; um cdigo realmente complexo, mas estudando com calma e ateno, entenderemos cada mtodo implementado. Agora no evento OnExecute da Action acStop, insira o cdigo que segue. Stopped := true; acStop.enabled := false; Com isso estamos solicitando uma parada nas operaes. Agora vamos atribuir as Actions acGO e acStop, ao objeto btExecuta e btCancela, respectivamente. Para tanto, basta selecionar a Action desejada do objeto em questo. Para finalizar nosso projeto, devemos criar as rotinas que seguem. function PingHost(Host: string; TTL: Integer): boolean; function FindItem(TTL: Integer; Add: boolean): TListItem; Primeiro vamos criar a rotina PingHost. Insira o cdigo que segue em nossa unit. function Tform1.PingHost(Host: string; TTL: Integer): Boolean; begin result := false; IdIcmpClient.Host := Host; IdIcmpClient.TTL := TTL; IdIcmpClient.ReceiveTimeout := 5000; IdIcmpClient.Ping; case IdIcmpClient.ReplyStatus.ReplyStatusType of rsEcho: begin

152 Delphi 7 Internet e Banco de Dados lbLog.Items.Append(format('resposta do host %s in %d milesegundos',[ IdIcmpClient.ReplyStatus.FromIpAddress, IdIcmpClient.ReplyStatus.MsRoundTripTime])); result := true; end; rsError: lbLog.Items.Append('Erro desconhecido'); rsTimeOut: lbLog.Items.Append('Timed out.'); rsErrorUnreachable: lbLog.Items.Append(format('Host %s no resolvido', [IdIcmpClient.ReplyStatus.FromIpAddress])); rsErrorTTLExceeded: lbLog.Items.Append(format('Hope %d %s: TTL expirou', [IdIcmpClient.TTL, idIcmpClient.ReplyStatus.FromIpAddress])); end; // case end; Repare que muito parecida com a Action acTrace, s que neste caso, estamos resumindo o resultado das operaes em nosso objeto lbLog. Agora vamos criar a rotina FindItem. Insira o cdigo que segue em nossa unit. function Tform1.FindItem(TTL: Integer; Add: boolean): TListItem; var i: Integer; begin result := nil; // Find the TTL item if lvTrace.Items.Count < TTL Then begin for i := 0 to lvTrace.Items.Count - 1 do begin if StrToIntDef(lvTrace.Items[i].Caption, -1) = TTL then begin result := lvTrace.Items[i]; Break; end; end; end; if not assigned( result ) then begin // Not found, add it result := lvTrace.Items.Add; result.Caption := IntToStr(TTL); end; end; O objetivo desta funo retornar informaes adicionadas no objeto lvTrace, baseada na TTL atual, e utilizada pela Action acTrace. Agora vamos gravar e compilar nossa aplicao. A figura 9.13 ilustra nossa aplicao sendo executada.

Desenvolvendo utilitrios para Internet 153

Figura 9.13 Tracert em ao

Listagem 9.3 un_tracert.pas


unit un_tracert; interface uses SysUtils, Types, Classes, Variants, QTypes, QGraphics, QControls, QForms, QDialogs, QStdCtrls, QExtCtrls, QComCtrls, QActnList, IdComponent, IdRawBase, IdRawClient, IdIcmpClient, IdBaseComponent, IdAntiFreezeBase, IdAntiFreeze; type TForm1 = class(TForm) pnTopo: TPanel; pnInfo: TPanel; pnDados: TPanel; Label1: TLabel; edTarget: TEdit; Label2: TLabel; seMaxHops: TSpinEdit; btExecuta: TButton; btCancela: TButton; lvTrace: TListView; ActionList1: TActionList; acGo: TAction; acResolve: TAction;

154 Delphi 7 Internet e Banco de Dados acPing: TAction; acTrace: TAction; acStop: TAction; IdAntiFreeze1: TIdAntiFreeze; IdIcmpClient: TIdIcmpClient; lbLog: TListBox; procedure acGoExecute(Sender: TObject); procedure acResolveExecute(Sender: TObject); procedure acPingExecute(Sender: TObject); procedure acTraceExecute(Sender: TObject); procedure acStopExecute(Sender: TObject); private { Private declarations } bResolved: Boolean; ResolvedHost: String; Stopped: Boolean; function PingHost(Host: string; TTL: Integer): boolean; function FindItem(TTL: Integer; Add: boolean): TListItem; public { Public declarations } end; var Form1: TForm1; implementation uses idStack, IdException; {$R *.xfm} procedure TForm1.acGoExecute(Sender: TObject); begin try Stopped := false; acGo.Enabled := false; acStop.enabled := true; acResolve.execute; if bResolved and not stopped then begin acPing.execute; if not stopped then acTrace.Execute; end; acGo.Enabled := true; acStop.enabled := false; finally { ok } end; { try/finally } end; procedure TForm1.acResolveExecute(Sender: TObject); begin bResolved := false; lbLog.Items.Append(Format('resolvendo %s',[edTarget.text]));

Desenvolvendo utilitrios para Internet 155 try Application.ProcessMessages; ResolvedHost := gStack.WSGetHostByName(edTarget.text); bResolved := true; lbLog.Items.Append(format('%s resolvido %s',[edTarget.text, ResolvedHost])); except on e: EIdSocketError do lbLog.Items.text := lbLog.Items.text + e.message; end; end; procedure TForm1.acPingExecute(Sender: TObject); begin PingHost(ResolvedHost, seMaxHops.value); Application.ProcessMessages; end; procedure TForm1.acTraceExecute(Sender: TObject); var TTL: Integer; Reached: boolean; aItem: TListItem; begin TTL := 0; reached := false; lvTrace.Items.Clear; repeat inc(TTL); IdIcmpClient.Host := ResolvedHost; IdIcmpClient.TTL := TTL; IdIcmpClient.ReceiveTimeout := 5000; IdIcmpClient.Ping; aItem := FindItem(TTL, True); aItem.SubItems.Clear; case IdIcmpClient.ReplyStatus.ReplyStatusType of rsEcho: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append(format('Reached in : %d ms', [IdIcmpClient.ReplyStatus.MsRoundTripTime])); reached := true; end; rsError: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append('Unknown error.'); end; rsTimeOut: begin aItem.SubItems.Append('?.?.?.?'); aItem.SubItems.Append('Timed out.'); end; rsErrorUnreachable: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append(format('Destination network unreachable',

156 Delphi 7 Internet e Banco de Dados [IdIcmpClient.ReplyStatus.MsRoundTripTime])); break; end; rsErrorTTLExceeded: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append(format('TTL=%d', [IdIcmpClient.ReplyStatus.TimeToLive])); end; end; // case Application.ProcessMessages; until reached or (TTL > seMaxHops.value) or Stopped; end; procedure TForm1.acStopExecute(Sender: TObject); begin Stopped := true; acStop.enabled := false; end; function TForm1.PingHost(Host: string; TTL: Integer): Boolean; begin result := false; IdIcmpClient.Host := Host; IdIcmpClient.TTL := TTL; IdIcmpClient.ReceiveTimeout := 5000; IdIcmpClient.Ping; case IdIcmpClient.ReplyStatus.ReplyStatusType of rsEcho: begin lbLog.Items.Append(format('response from host %s in %d millisec.', [ IdIcmpClient.ReplyStatus.FromIpAddress, IdIcmpClient.ReplyStatus.MsRoundTripTime ])); result := true; end; rsError: lbLog.Items.Append('Unknown error.'); rsTimeOut: lbLog.Items.Append('Timed out.'); rsErrorUnreachable: lbLog.Items.Append(format('Host %s reports destination network unreachable.', [ IdIcmpClient.ReplyStatus.FromIpAddress ])); rsErrorTTLExceeded: lbLog.Items.Append(format('Hope %d %s: TTL expired.', [ IdIcmpClient.TTL, IdIcmpClient.ReplyStatus.FromIpAddress ])); end; // case end;

Desenvolvendo utilitrios para Internet 157 function TForm1.FindItem(TTL: Integer; Add: boolean): TListItem; var i: Integer; begin result := nil; // Find the TTL item if lvTrace.Items.Count < TTL Then begin for i := 0 to lvTrace.Items.Count - 1 do begin if StrToIntDef(lvTrace.Items[i].Caption, -1) = TTL then begin result := lvTrace.Items[i]; Break; end; end; end; if not assigned( result ) then begin // Not found, add it result := lvTrace.Items.Add; result.Caption := IntToStr(TTL); end; end;

end.

158 Delphi 7 Internet e Banco de Dados

Anotaes de Dvidas

?
Preciso Revisar

Anotaes Gerais

Aplicaes para Celulares 159

Captulo 10

Desenvolvendo Aplicaes para Celulares

Viso geral
Amigos, neste captulo iremos aprender a desenvolver aplicaes WAP para celulares. Mas Facunte, o WAP no foi um fracasso no Brasil? Depende muito do ponto de vista de cada empresa, de cada brasileiro. O WAP uma realidade para muitas empresas, que mesmo aps diversas resistncias, adotaram a tecnologia em suas culturas empresariais. Cultura? isso mesmo! Cultura. O grande problema do WAP que ns brasileiros demoramos para nos acostumar com novidades, alm, claro, da barreira de resistncia a tornar um hbito certas coisas. verdade que o WAP no atingiu o que as teles previam, onde todos os seus assinantes utilizariam o WAP para algum tipo de servio. Isso mesmo, servio. A que est o pecado da coisa. Como pagar por uma coisa que nem sabemos utilizar? Faltou incentivo cultural. Mas, hoje em dia, muitas empresas aproveitam da tecnologia para fora de vendas, troca de mensagens em grupo, pesquisa de campo, entre outras aplicaes que veremos ao longo do captulo.

WAP no Brasil
Continuando com a nossa discusso, ser que temos oportunidades de lucro no Brasil? A oportunidade existe, mas poucas empresas esto investindo nesta rea, certamente lucrativa. Ser que sou um romntico sonhador? Sonhando com o lucro em tempos de vacas magras? Amigos, posso afirmar que no, pois em 2000, quando lancei meu livro de WAP (Wap Guia de Tecnologia), o mercado estava muito aquecido, devido s fortes propagandas de empresas de telefonia em torno do WAP, mas na poca, a barreira cultural de nosso pas quase levou o sonho destas empresas por gua abaixo. Sabem o que elas fizeram? Deixaram o WAP de lado e continuaram a investir em aparelhos mveis, mas destacando apenas sua beleza e algumas funcionalidades. Facunte, ento o sonho do lucro ficou ainda mais distante? Amigos, a que entra o consultor, para explicar aos gerentes de tecnologia, CEOs, que a relao custo benefcio com o WAP muito boa, e que o desenvolvimento quase transparente, pois podemos criar aplicaes WAP na maioria das linguagens, como: Delphi, .NET (VB, C#, ASP), PHP, Java (JSP, EJB), entre outras.

159

160 Delphi 7 Internet e Banco de Dados

Modelos de Aparelhos
A disponibilidade de aparelhos no Brasil muito grande, e o preo um forte atrativo, variando entre R$ 199,00 (modelo LG DM 160), at R$ 1.999,00 (Nokia 9210). Imaginem uma equipe de vendas, ou at mesmo uma equipe de pesquisadores, com modelos mais baratos, em torno de R$ 199,00, fechando negcios, elaborando pesquisas, consultando clientes, disponibilidade de estoque, entre outros.

Motorola v.8160

LG DM 160

Startac 7860

Ericsson T60

LG TM 520

LG DM 515

Siemens SX45

Nokia 9210

Tabela 10.1 Celulares com suporte WAP

Cases de Sucesso
Para provar a fora do WAP, vamos conhecer alguns cases de sucesso.

Caixa Econmica Federal


A Caixa Econmica Federal disponibiliza a todos a informao sobre o saldo do FGTS atravs da tecnologia WAP. Para ter uma idia da transparncia neste case, a mesma aplicao disponibiliza informao via telefone (fixo), Internet e celular (WAP). Totalmente desenvolvida em JAVA, a soluo teve seu custo reduzido devido leve infra-estrutura necessria para abrigar toda a aplicao. Embora tenha exemplificado o case da Caixa Econmica Federal, importante ressaltar que a maioria dos bancos nacionais oferecem variados recursos com a tecnologia WAP.

Aplicaes para Celulares 161

InvestShop.COM.BR
A instituio financeira InvestShop desenvolveu em conjunto com a EverSystem (talvez a maior empresa de desenvolvimento deste setor) uma soluo bastante robusta oferecendo ao usurio um controle total de suas aplicaes. S para ter uma idia, a aplicao disponibiliza at grficos de aes em celulares WAP. realmente incrvel.

DETRAN-SP
Um dos pioneiros na tecnologia WAP, o DETRAN de So Paulo disponibiliza informaes de Multas, Pontuaes na Carteira, entre outros. Viram como o poder do WAP grande? Basta uma idia para transform-lo em lucro!

Algumas idias para ganhar dinheiro


Bem, aqui vo algumas sugestes bastante interessantes para ganhar dinheiro com aplicaes WAP. Fora de Vendas Pesquisas de Campo TimeSheet Processos m-Ticket m-Finance m-Commerce Aplicao de auxlio a vendedores externos, com opo de consulta a estoque, faturas de clientes e fechamento de pedidos. Aplicao que auxilia pesquisadores das mais variadas reas: IBOPE, CENSO, Opinio, Produtos, entre outras. Aplicao para TimeSheet de consultores, advogados, tcnicos, entre outros. Gerenciamento de Processos Jurdicos, onde o advogado ou cliente poder consultar informaes sobre os andamentos dos processos. (m=mobile) Vendas de ingressos, passagens areas, cinemas, teatros, etc . Aplicaes para o mercado financeiro. Comrcio em geral atravs de aplicaes WAP.

Entendendo o funcionamento das aplicaes WAP


Para entender um pouco como funciona uma aplicao WAP, precisamos conhecer o funcionamento de uma aplicao servidora. Em nosso caso teremos apenas o mdulo servidor, pois o cliente da nossa aplicao um browser com suporte tecnologia WAP, ou seja, a grande maioria dos celulares comercializados no mercado nacional. Para facilitar a compreenso, a figura 10.1 ilustra bem o nosso caso:

HTTP/WML

WML/HTTP

celular (cliente)

Servidor

GateWay

Figura 10.1 Esquema de funcionamento WAP

162 Delphi 7 Internet e Banco de Dados Na ilustrao, temos um celular, que funciona como o nosso cliente (terminal), onde solicita os servios ao servidor. Os dados (WML) trafegam atravs do protocolo HTTP. Quando os dados chegam no servidor, o mesmo tem que interpretar a requisio, e esse servio feito pelo GateWay. O GateWay tambm tem como funo empacotar o resultado da requisio, para que o servidor retransmita ao celular. Em resumo, necessitamos de duas aplicaes bsicas no servidor: Servidor HTTP (recomendo o Apache Server) Nossa aplicao servidora.

Um detalhe bastante interessante que o Apache Server traz consigo embutido um excelente GateWay WAP. Embora esteja documentado que o Apache apenas suporta aplicaes WAP, ele possui toda a implementao necessria para um perfeito funcionamento. Para que possamos prosseguir no desenvolvimento de nossas aplicaes, precisamos tambm de um simulador WAP. Existem vrios no mercado, mas particularmente prefiro o Deck-it da PyWeb. A figura 10.2 ilustra a interface do Deck-it.

Figura 10.2 Deck-it O Deck-it est disponvel no site da PyWeb (www.pyweb.com) e, assim como o Apache, totalmente freeware.

Mime-Types WAP
Outra coisa importante a saber so os MimeTypes WAP. Mas o que so MimeTypes? Para que os servidores HTTP reconheam um tipo de requisio, ou ento, um mtodo de envio, necessria a definio dos MimeTypes. S para clarear um pouco a informao, uma imagem do tipo JPG definida como image/JPG. Com isso o servidor saber qual o melhor mtodo de transmisso para este tipo de arquivo.

Mime Types do WAP Tipo de Arquivo Cdigo-fonte WML WML compilado Cdigo-fonte WMLScript WMLScript compilado Imagem bitmap Extenso .wml .wmlc .wmls .wmlcs .wbmp MIME Type text/vnd.wap.wml application/vnd.wap.wmlc text/vnd.wap.wmlscript application/vnd.wap.wmlscriptc image/vnd.wap.wbmp

Tabela 10.2 mime types WAP

Aplicaes para Celulares 163 Vamos adicionar os Mime-Types ao Apache, embora a partir da verso 1.3.1 j estejam implementados todos os tipos necessrios. No arquivo httpd.conf adicione as seguintes linhas: AddType AddType AddType AddType text/vnd.wap.wml image/vnd.wap.wbmp text/vnd.wap.wmlscript application/vnd.wap.wmlscriptc .wml .wbmp .wmls .wlsc

Grave o arquivo e reinicie o Apache.

WML
O WML, Wireless Markup Language, a linguagem de programao para o desenvolvimento de documentos WAP. Muito parecida com o HTML e tambm com alguns conceitos do XML. Uma das caractersticas desta linguagem a adoo do case sensitive, ou seja, deck diferente de Deck ou DECK. Fique atento. Normalmente utilizamos letras minsculas para trabalhar com as Tags WML.

Minha opinio
O WML evoluiu muito durante os tempos e o consrcio formado para a criao deste padro continua investindo na tecnologia. Muitas pessoas comentam que o WAP ruim, que isso, que aquilo, mas como disse anteriormente, a oportunidade est a, batendo na sua porta. Voc vai ficar dando ouvidos a quem nunca ao menos tentou fazer a coisa certa?.

TAGS WML
<a> Cria um hiperlink ligando uma URL, ou ID de outra Tag. recomendado o uso desta Tag ao invs da Tag <anchor>. Exemplo

<a href = consulta consulta>


Atributos

Nome id class xml:lang href title

Tipo String String String href String

Obrigatrio No No No Sim No

164 Delphi 7 Internet e Banco de Dados Descritivo dos Atributos

Atributo id class xml:lang href title


<access>

Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Definio da linguagem XML Link de referncia Texto, descrevendo o link

A Tag <access> define o controle de acesso a um deck. Na realidade controla acessos preestabelecidos de acordo com a combinao domain+path, ou seja, voc poder definir se determinado deck poder ser acessado a partir de um determinado domnio ou path (caminho). Exemplo:

<access domain = facunte.com.br path=/VIP>


Baseado neste exemplo, vejamos o que permitido:

permitido
www.facunte.com.br/VIP/x.wml www.facunte.com.br/VIP/index.wml

no permitido
www.facunte.com.br/livros.wml www.facunte.com.br/x.wml

Neste exemplo determinamos que o deck atual s poder ser acessado, a partir de uma requisio da domnio facunte.com.br, e do caminho /VIP, ou seja, somente quem estiver no diretrio /VIP poder acessar as informaes do deck em questo. Atributos

Nome id class domain path


Descritivo dos Atributos

Tipo String String String String

Obrigatrio No No No No

Atributo id class domain path

Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Domnio que poder acessar o elemento Caminho dentro do domain (domnio) que poder acessar o elemento. Se no for especificado, todos os caminhos do domain podero acessar o elemento

<anchor> Assim como a Tag <a>, cria um hiperlink de um texto. Exemplo:

<anchor href== consulta consulta>

Aplicaes para Celulares 165 <b> Tag utilizada para formatar textos em negrito. recomendado o uso da Tag <strong> ao invs de <b>, <i> ou <u>. Exemplo:

<b> Seja bem-vindo </b>


<big> Utilizada para formatar o texto de maneira enfatizada, grande. Exemplo:

<big> Seja bem-vindo </big>


<br> Utilizada para concluir a linha atual e iniciar uma nova linha. Pode ser utilizada dentro de tabelas. Exemplo:

<br> Linha 1 <br> Linha 2 <br> Linha 3


<card> A Tag <card> utilizada para delimitar um conjunto de elementos. A estrutura da linguagem WML pode conter uma coleo de cards, formando um deck. Exemplos:

<card id =menu> ... </card> <card id =opcao1> .. </card> <card id =opcao2> .. </card> <card id =opcao3> .. </card>

Nome id class xml:lang title newcontext ordered

Tipo String String String String Boolean Boolean

Obrigatrio No No No No No No

Padro

No Sim

166 Delphi 7 Internet e Banco de Dados Descritivo dos Atributos

Atributo id class title newcontext ordered


Eventos do elemento Card

Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Indentificao do carto Indica ao browser para trazer o card em questo atualizado Organiza o card

Evento onenterforward onenterbackward ontimer

Descrio Utilizado em conjunto com o elemento GO (veja nas prximas pginas) Utilizado em conjunto com o elemento PREV (veja nas prximas pginas) Utilizado para disparar uma referncia, que pode ser um CARD ou outra URL, quando o tempo determinado expirar

<do> Esta Tag utilizada para acessar informaes acima do card atual. Exemplos:

<do type="accept" label="Segundo"> <do type="accept" label="Primeiro">


Atributos

Nome id class xml:lang type label name optional


Descritivo dos Atributos

Tipo String String String String String String Boolean

Obrigatrio No No No Sim No No No

Atributo id class type label name optional

Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Tipos definidos do elemento (veja tabela a seguir) Texto descritivo do elemento, visvel para o usurio Identifica o nome de ligao Define o elemento como opcional

Aplicaes para Celulares 167 Complementos do atributo Type

tipo accept prev help reset options delete unknown


<em>

Descrio Reconhecimento positivo Navegao de retorno Ajuda Limpar, ou resetar Solicitao para opes ou operaes adicionais Apagar item De uso genrico

Utilizada para formatar o texto de maneira enfatizada, parecida com a Tag <big>. Exemplo:

<em> Seja bem-vindo </em>


<fieldset> O elemento fieldset permite o agrupamento de campos relacionados ao texto. Este agrupamento permite otimizar o layout e navegao. Atributos

Nome id class xml:lang title


Exemplo:

Tipo String String String String

Obrigatrio No No No No

<fieldset title=endereco> Endereco: <input type=text name=fendereco maxlength=50/> <br/> Cidade: <input type=text name=fcidade maxlength=30/> <br/> Estado: <input type=text name=festado maxlength=2/> <br/> Cep: <input type=text name=fcep maxlength=8/> <br/> </fieldset> <fieldset title=telefones> Fone_Residencial: <input type=text name=fresidencial maxlength=20/> <br/> Fone_Comercial: <input type=text name=fcomercial maxlength=20/>

168 Delphi 7 Internet e Banco de Dados

<br/> Fone_Celular: <input type=text name=fcomercial maxlength=20/> <br/> </fieldset>


<go> A tag <go> permite a navegao entre cards ou decks, e utilizado em conjunto com o elemento <do>. Atributos

Nome id class href sendreferer method accept-charset


Descritivo dos Atributos

Tipo String String href Boolean Method String

Obrigatrio No No No No No No

Padro

false get unknown

Atributo id class href sendreferer

method optional
Exemplo:

Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Endereo URL (caminho) Em caso verdadeiro(True), o browser do usurio dever especificar o URL do deck contendo esta tarefa Mtodo de envio de dados (POST ou GET) Define o elemento como opcional

... <card id=inicio title=teste > <do type=accept label=envia> <go href=#recebe> </do> <p>clique em envia para ir ao card recebe</p> </card> <card id=recebe title=teste > <do type=accept label=volta> <go href=#inicio> </do> <p>clique em volta para retornar</p>

Aplicaes para Celulares 169 <head> A tag <head> contm informaes sobre o documento, como os metadatas e as tags de controle de acesso. Atributos

Nome id class
Descritivo dos Atributos

Tipo String String

Obrigatrio No No

Padro

Atributo id class
<i>

Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence

Utilizada para formatar o texto em itlico. Exemplo: <i> Seja bem-vindo </i> <img> A tag <img> utilizada para incluir uma imagem no documento. As imagens devem seguir o padro WBMP. Veremos um tpico abordando este assunto. Atributos

Nome id class xml:lang alt scr localscr vspace hspace align height width
Descritivo dos Atributos

Tipo String String String String URL String Length Length String Length Length

Obrigatrio No No No No Sim No No No No No No

Padro

Small, nonzero Small, nonzero bottom

Atributo id class alt

Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Texto a ser exibido enquanto a imagem carregada, ou numa possvel falha em seu carregamento

170 Delphi 7 Internet e Banco de Dados

Atributo scr localscr vspace hspace align

height width
Exemplos:

Descrio Especifica o caminho da imagem Alternativa imagem Espao em branco vertical Espao em branco horizontal Alinhamento da imagem em relao pgina top topo da pgina middle meio bottom alinhada abaixo da pgina Tamanho vertical da imagem Tamanho horizontal da imagem

<img src=logo.WBMP> <img alt=logo src=logo.WBMP> <img alt=logo src=logo.WBMP width=32 height=32> <img alt=logo src=logo.WBMP width=32 height=32 vspace=2> <img alt=logo src=logo.WBMP width=32 height=32 hspace=2> <img alt=logo src=logo.WBMP align=top>
<input> A tag <input> utilizada para definir a entrada de dados para o usurio. Atributos

Nome id class xml:lang name type value format emptyok size maxlength tabindex title

Tipo String String String String Input_Type String String Boolean Number Number Number String

Obrigatrio No No No Sim No No No No No No No No

Padro

text *M false Infinite

Aplicaes para Celulares 171 Descritivo dos Atributos

Atributo id class name type value format emptyok size maxlength tabindex title
Mscaras (A)

Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Nome do elemento muito importante para tratar o dado Tipo da entrada de dados, que pode ser texto (text), ou senha (pass) Valor padro do campo Mscara do campo (veja a tabela que segue (A)) Permite a escolha de campos opcionais Largura da rea de entrada de dados Tamanho mximo, em caracteres, para a entrada de dados Como no Delphi ordem de entrada Titulo do campo

Mscara A a N X x M m *f nf
Exemplos

Descrio Letras maisculas e caracteres de pontuao Letras minsculas e caracteres de pontuao Somente nmeros Somente letras maisculas Somente letras minsculas Qualquer caractere e assume maisculo (dependendo do browser) Qualquer caractere e assume minsculo (dependendo do browser) Somente caractere numrico Caractere numrico 0 a 9

<input name=nome type=text maxlength=50> <input name=cep type=text maxlength=8 format=NNNNNNNN> <input name=nome type=text maxlength=50> <input name=pais type=text value=Brasil>

<meta> A tag <meta> contm informaes genricas relativas ao deck do WML. Assim, como no padro HTML, utilizada para definir alguns dados do documento.

172 Delphi 7 Internet e Banco de Dados Atributos

Nome Id class http-equiv name forua content scheme Descritivo dos Atributos Atributo id class http-equiv forua

Tipo String String String String Boolean String String

Obrigatrio No No No No No Sim No

Padro

content scheme
<noop>

Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Indica que a propriedade deve ser interpretada como um cabealho http Em caso de false, o intermedirio dever remover o elemento meta antes do mesmo ser enviado ao cliente; seno (true), os dados so enviados ao browser do usurio Contedo do metadata, como por exemplo, um tipo Estrutura que dever ser utilizada para interpretar o metadata

A tag <noop> utilizada para cancelar operaes realizadas no deck. Atributos

Nome id class
<onevent>

Tipo String String

Obrigatrio No No

Padro

A tag <onevent> associa uma tarefa a um determinado elemento. Atributos

Nome id class type


<optgroup>

Tipo String String String

Obrigatrio No No Sim

Padro

A tag <optgroup> utilizada para agrupar elementos criados com a tag <option> , definindo assim uma hierarquia.

Aplicaes para Celulares 173 Atributos

Nome id class xml:lang title


Descritivo dos Atributos

Tipo String String String String

Obrigatrio No No No No

Padro

Atributo id class title


Exemplos:

Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Referncia do grupo

<optgroup title=estado> <option title=So Paulo value=SP> <option title=Rio de Janeiro value=RJ> <option title=Bahia value=BA> .... </optgroup>
<option> A tag <option> cria uma opo de escolha em um elemento selecionado. Atributos

Nome id class xml:lang value title onpick


Descritivo dos Atributos

Tipo String String String String String href

Obrigatrio No No No No No No

Padro

Atributo id class value title onpick

Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Valor atribudo opo Expresso apresentada ao usurio Dispara a chamada de uma URL, quando a opo for selecionada

174 Delphi 7 Internet e Banco de Dados Exemplos:

<optgroup title=sexo> <option title=Masculino value=M> <option title=Feminino value=F> .... </optgroup> <optgroup title=idioma> <option title=Portugus value=P onpick=/port.wml> <option title=Ingls value=I onpick=/ingles.wml> .... </optgroup>
<p> A tag <p> inicia um pargrafo com os atributos especificados. Atributos

Nome id class xml:lang align mode


Descritivo dos Atributos

Tipo String String String TAlign Wrapmode

Obrigatrio No No No No No

Padro

left wrap

Atributo id class align

mode
Exemplos:

Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Alinhamento do pargrafo left = esquerda right = direita center = centralizado Especifica o modo de parada do texto

<p align=left> Estou alinhado a esquerda </p> <p align=right> Estou alinhado a direita </p> <p align=left> Estou alinhado a esquerda </p>

Aplicaes para Celulares 175

<p align=center wrap=nowrap> Este texto dever ser visto sem rolagem e centralizado </p>
<postfield> A tag <postfield> define o nome de um campo e valor para transmisso a um servidor de origem, durante uma requisio de URL. Atributos

Nome id class name value


Descritivo dos Atributos

Tipo String String String String

Obrigatrio No No Sim Sim

Padro

Atributo id class name value


Exemplos:

Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Nome do campo Valor do campo

<postfield name=PAIS value=BRASIL>


<prev> A tag <prev> retorna a navegao para a URL anterior no histrico do browser. Atributos

Nome id class
Sintaxe

Tipo String String

Obrigatrio No No

Padro

<prev>
<refresh> A tag <refresh> atualiza a URL em atividade e o contexto do dispositivo, de acordo com os dados atuais do servidor.

176 Delphi 7 Internet e Banco de Dados Atributos

Nome Id class
Sintaxe

Tipo String String

Obrigatrio No No

Padro

<refresh>
<select> A tag <select> inicia uma lista de seleo. Os itens da lista so criados atravs da tag <option>. Atributos

Nome id class xml:lang title name value iname ivalue multiple tabindex
Descritivo dos Atributos

Tipo String String String String String String String String Boolean Number

Obrigatrio No No No No Sim No No No No No

Padro

Atributo id class title name value iname ivalue


Exemplos:

Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Define o ttulo a ser exibido ao usurio Nome do elemento (campo) Recebe o nome da opo selecionada; o nome definido no atributo iname, e o valor no ivalue Declarao do nome do elemento Valor da opo selecionada na lista de opes

<select name=linguagens iname=L ivalue=1;2;3;4 multiple=true> <option value=A>Delphi</option> <option value=B>Java</option> <option value=A>C++</option> <option value=A>.Net</option> </select>
<setvar>

Aplicaes para Celulares 177 A tag <setvar> utilizada para definir o valor de uma varivel. Atributos

Nome id class name value


Exemplo:

Tipo String String String String

Obrigatrio No No Sim Sim

Padro

<setvar name=SOBRENOME value=FACUNTE>


<small> A tag <small> formata o texto com a fonte pequena. Atributos

Nome id class xml:lang


Exemplo:

Tipo String String String

Obrigatrio No No No

Padro

<small> made in Borland </small>


<strong> A tag <strong> formata o texto com a fonte destacadas, fortes. Normalmente esta tag utilizada no lugar das tags <b> <i> e <u>. Atributos

Nome id class xml:lang


Exemplo:

Tipo String String String

Obrigatrio No No No

Padro

<strong> powered by Facunte </strong>


<table> A tag <table> utilizada em conjuntos com as tags <tr> e <td>, para criar tabelas.

178 Delphi 7 Internet e Banco de Dados Atributos

Nome id class xml:lang title align columns


Descritivo dos Atributos

Tipo String String String String String Number

Obrigatrio No No No No No Sim

Padro

Atributo id class title align columns


Exemplo simples:

Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Define o ttulo da tabela Alinhamento dos elementos da tabela Nmero de colunas

<table align=right columns =2>


<td> A tag <td> utilizada para delimitar uma celula. <tr> A tag <tr> utilizada para iniciar uma linha na tabela. Exemplos de tabelas:

<table align=center columns=3> <tr> <td>marca</td> <td>ano</td> <td>modelo</td> </tr> <tr> <td>fiat</td> <td>2002</td> <td>palio elx</td> </tr> <tr> <td>mercedes</td> <td>2001</td> <td>E500</td> </tr>

Aplicaes para Celulares 179

<tr> <td>honda</td> <td>1999</td> <td>civic</td> </tr> <tr> <td>GM</td> <td>1998</td> <td>blazer</td> </tr> </table>
Resultado do exemplo marca fiat mercedes honda gm <template> A tag <template> define caractersticas comuns a todos os cards do dispositivo, disparando alguns eventos. Atributos ano 2002 2001 1999 1998 modelo palio elx e500 civic blazer

Nome id class onenterforward onenterbackward ontime


Descritivo dos Atributos

Tipo String String href href href

Obrigatrio No No No No No

Padro

Atributo id class onenterforward onenterbackward ontimer


Exemplo:

Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Define a URL a ser disparada, caso o usurio acesse um carto atravs da tag <do> Define a URL a ser disparada, caso o usurio acesse um carto atravs da tag <prev> Define a URL a ser disparada, caso o tempo definido na tag <timer> expire

<template onenterforward=/home.wml onenterbackward=/delphi.wml

180 Delphi 7 Internet e Banco de Dados

ontimer=/login.wml> </template>
<timer> A tag <timer> utilizada para disparar um evento ou chamada a partir de um determinado tempo, especificado na propriedade value (100 = 1 segundo). Atributos

Nome id class value


Exemplo:

Tipo String String Number

Obrigatrio No No Sim

Padro

<card name=card1 ontimer=#card2> <timer value=100/> <p>Esta mensagem ser destruda em 10 segundos</p> </card> <card name=card2> <p>Mensagem Destruda</p> </card>

Acentos em WML
Nome &nbsp; &iexcl; &cent; &pound; &curren; &yen; &brvbar; &sect; &uml; &copy; &not; &reg; &deg; &plusmn; &acute; &frac14; &frac12; &frac34; &iquest; &Agrave; &Aacute; &Acirc; Cdigo &#160; &#161; &#162; &#163; &#164; &#165; &#166; &#167; &#168; &#169; &#172; &#174; &#176; &#177; &#180; &#188; &#189; &#190; &#191; &#192; &#193; &#194; Resultado espao

Aplicaes para Celulares 181

&Atilde; &Auml; &Aring; &AElig; &Ccedil; &Egrave; &Eacute; &Ecirc; &Euml; &Igrave; &Iacute; &Icirc; &Iuml; &Ntilde; &Ograve; &Oacute; &Ocirc; &Otilde; &Ouml; &times; &Oslash; &Ugrave; &Uacute; &Ucirc; &Uuml; &Yacute; &thorn; &szlig; &agrave; &aacute; &acirc; &atilde; &auml; &aring; &aelig; &ccedil; &egrave; &eacute; &ecirc; &euml; &igrave; &iacute; &icirc; &iuml; &ntilde; &ograve;

&#195; &#196; &#197; &#198; &#199; &#200; &#201; &#202; &#203; &#204; &#205; &#206; &#207; &#209; &#210; &#211; &#212; &#213; &#214; &#215; &#216; &#217; &#218; &#219; &#220; &#221; &#222; &#223; &#224; &#225; &#226; &#227; &#228; &#229; &#230; &#231; &#232; &#233; &#234; &#235; &#236; &#237; &#238; &#239; &#241; &#242;

182 Delphi 7 Internet e Banco de Dados

&oacute; &ocirc; &otilde; &ouml; &divide; &oslash; &ugrave; &uacute; &ucirc; &uuml; &yacute; &thorn; &yuml;

&#243; &#244; &#245; &#246; &#247; &#248; &#249; &#250; &#251; &#252; &#253; &#254; &#255;

Desenvolvendo Aplicaes WAP x Delphi


Agora vamos colocar a mo na massa e desenvolver alguns exemplos de aplicaes WAP, com o nosso amigo Delphi.

Primeiro Exemplo (o famoso Hello...)


Sei que isso pode parecer bobagem, mas o nosso companheiro Hello World ajuda muito. No Delphi iremos criar uma aplicao servidora no padro CGI. A partir do Delphi, selecione as opes File/New/Other... e em seguida a opo Web Server Application, como ilustra a figura 10.3.

Figura 10.3 Opo Web Server Application Na janela seguinte selecione a opo CGI Stand-Alone executable (figura 10.4).

Aplicaes para Celulares 183

Figura 10.4 Seleo do tipo da aplicao Em seguida teremos o nosso WebModule (figura 10.5),

Figura 10.5 WebModule Bem, seguindo o nosso primeiro projeto, atravs do duplo-clique no WebModule, acesse o editor de ActionItems (figura 10.6).

Figura 10.6 editor ActionItems Clique no primeiro boto do editor para inserir uma nova Action (figura 10.7).

184 Delphi 7 Internet e Banco de Dados

Figura 10.7 ActionItem Em seguida altere as seguintes propriedades.

OBJETO TWebActionItem Objeto padrao Propriedade Default Name PathInfo Valor True padrao /padrao

Esta ser nossa Action padro, ou seja, caso o usurio no digite nada, alm do nome da nossa aplicao, esta Action ser executada. Embora a propriedade PathInfo possua o mesmo valor da propriedade Name, ela que executa a Action, ou seja, no browser o que vale o valor da PathInfo. No evento OnAction coloque o seguinte cdigo: 001 002 003 004 Response.ContentType:='text/vnd.wap.wml'; Response.Content:='<?xml version="1.0"?>'+ '<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EM" "http://www.wapforum.org/DTD/wml_1.1.xml">'+ '<wml><card id="cartaum"><p>Ola Mundo!</p></card></wml>';

No se assustem com as denominaes do cabealho <DOCTYPE wml...., isso um padro, e o restante iremos conhecendo aos poucos. Vamos analisar o cdigo: Na linha 001, estou dizendo ao servidor, atravs do mtodo Response.ContentType, que o tipo de informao no padro WAP. Response.ContentType:='text/vnd.wap.wml'; Em, seguida, nas linhas 002,003 e 004, estou empacotando a resposta (Response.Content) e enviando ao servidor, que por sua vez, envia ao celular. Response.Content:='<?xml version="1.0"?>'+ '<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EM" "http://www.wapforum.org/DTD/wml_1.1.xml">'+ '<wml><card id="cartaum"><p>Ola Mundo!</p></card></wml>'; Grave a unit do nosso projeto como un_ola.pas e o projeto como ola.dpr. Habitualmente testamos nossas aplicaes servidoras num browser, como o Internet Explorer, mas neste caso iremos test-la no nosso simulador Deck-It. Lembram dele?

Aplicaes para Celulares 185 No Deck-It digite o que segue na barra de endereos: http://localhost/cgi-bin/ola.exe A figura 10.8 ilustra o resultado da nossa aplicao:

Figura 10.8 Resultado da aplicao S para ter uma idia, voc poderia simular em seu prprio celular WAP este exemplo. Mas Facunte, como eu faria isso? Conecte seu computador Internet, anote o nmero do IP fornecido no momento da conexo, exemplo: 200.198.12.1, e digite no seu celular (o modo de entrada para comunicao WAP varia de celular para celular, consulte o manual de instrues), o endereo: http://200.198.12.1/cgi-bin/ola.exe Repare que o nmero, na realidade o seu endereo de IP atual (exemplo). Continuando com a nossa aplicao, vamos criar mais uma Action com as seguintes propriedades:

OBJETO TWebActionItem Objeto Theclub Propriedade Default Name PathInfo Valor False theclub /theclub

No evento OnAction coloque o seguinte cdigo: 001 002 003 004 Response.ContentType:='text/vnd.wap.wml'; Response.Content:='<?xml version="1.0"?>'+ '<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EM" "http://www.wapforum.org/DTD/wml_1.1.xml">'+ '<wml><card id="cartaum"><p>Sejam bem-vindos ao The Club</p></card></wml>';

186 Delphi 7 Internet e Banco de Dados

O cdigo exatamente igual ao anterior, em que apenas substituimos a mensagem. Vamos testar o cdigo? No Deck-It digite o que segue na barra de endereos: http://localhost/ola.exe/theclub Repare que estamos colocando o pathinfo theclub. A figura 10.9 ilustra o resultado da nossa segunda Action.

Figura 10.9 Segunda Action interessante, no acham? E a, amigos, esto preparados para brincar com banco de dados e WAP?

Listagem 10.1
unit un_ola; interface uses SysUtils, Classes, HTTPApp; type TWebModule1 = class(TWebModule) procedure WebModule1padraoAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); procedure WebModule1theclubAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); private { Private declarations } public { Public declarations } end; var WebModule1: TWebModule1; implementation

Aplicaes para Celulares 187 {$R *.DFM} procedure TWebModule1.WebModule1padraoAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin Response.ContentType:='text/vnd.wap.wml'; Response.Content:='<?xml version="1.0"?>'+ '<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EM" "http://www.wapforum.org/DTD/wml_1.1.xml">'+ '<wml><card id="cartaum"><p>Ola Mundo !</p></card></wml>'; end; procedure TWebModule1.WebModule1theclubAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin Response.ContentType:='text/vnd.wap.wml'; Response.Content:='<?xml version="1.0"?>'+ '<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EM" "http://www.wapforum.org/DTD/wml_1.1.xml">'+ '<wml><card id="cartaum"><p>Sejam bem-vindos ao THE CLUB</p></card></wml>'; end; end.

Segundo Exemplo (Banco de Dados)


A aplicao que iremos desenvolver, consiste em apresentar uma lista de e-mails que est armazenada em nosso banco de dados. Atravs das opes File/New..., selecione o item Web Server Application (figura 10.10) e clique em OK.

Figura 10.10 Item Web Server Application

188 Delphi 7 Internet e Banco de Dados Em seguida, selecione o tipo de aplicao CGI, e marque a opo Cross Platform (figura 10.11). Perceba que com isso poderemos executar a mesma aplicao num servidor Linux, sendo que o cdigo dever ser recompilado em Kylix.

Figura 10.11 Escolha do tipo da aplicao servidora Agora, neste ponto, precisamos estabelecer a conexo com o nosso banco de dados. Insira um objeto do tipo TSQLConnection, e atravs do duplo-clique, j na tela de configurao, crie uma nova conexo do tipo Interbase, alterando as propriedades que seguem. A figura 10.12 ilustra o dilogo de propriedades do componente TSQLConnection.

PROPRIEDADE

VALOR

CommitRetain Database Password UserName Name

False localhost:c:\cursoweb\clientes.gdb a famosa masterkey o famoso SYSDBA ConexaoBD

Altere tambm a propriedade LoginPrompt para false. Nunca esquea de fazer esta alterao, pois numa aplicao servidora, no existe a possibilidade do usurio interagir no login do banco de dados.

Aplicaes para Celulares 189

Figura 10.12 Configurao da Conexo Agora vamos inserir o objeto para manipular nossa tabela de clientes. Insira um objeto do tipo TSQLDataSet, e altere as seguintes propriedades:

PROPRIEDADE

VALOR

SQLConnection CommandText Active

ConexaoBD select * from TBCLIENTE True

Oba, j estamos chegando l. Agora vamos inserir um objeto do tipo TdataSetTableProducer. No confundam com TdataSetPageProducer. Altere o nome do componente para producerCliente, e a propriedade DataSet para SQLCliente. Atravs de um duplo-clique teremos a seguinte tela (assistente de configurao figura 10.13).

Figura 10.13 Assistente de Configurao

190 Delphi 7 Internet e Banco de Dados Caso no esteja vendo uma tela parecida (perceba que os dados j esto inseridos no banco e que voc dever inserir seus prprios registros), verifique se est tudo certo com a sua conexo. Deixe somente o campo e-mail, pois iremos listar apenas esta informao em nosso celular. Para realizar a tarefa, selecione os outros campos e aperte a tecla delete. Veja o resultado desta operao, na figura 10.14.

Figura 10.14 Neste ponto, iremos criar nossa Action para apresentar a informao no celular. Crie uma Action com o nome dados, atravs do duplo-clique no WebModule. Veja a figura 10.15.

Figura 10.15 Action dados No evento OnClick da Action dados, insira o cdigo que segue. // Abre o SQLCliente SQLCliente.Open; // Define o tipo do contedo Response.ContentType:='text/vnd.wap.wml'; // Monta a cabealho padro

Aplicaes para Celulares 191

Response.Content:='<?xml version="1.0"?>'+ '<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EM" "http://www.wapforum.org/DTD/wml_1.1.xml">'+ '<wml><card id="cartaum"><p>'; // Insere o conteudo da nossa Tabela producer_Cliente na resposta e finaliza Response.Content:=Response.Content+producerCliente.Content+ '</p></card></wml>'; // Fecha o SQLCliente SQLCLiente.Close;

Com base no exemplo anterior, fica bastante simples entender este cdigo. Primeiro, estamos abrindo o nosso DataSet (SQLCliente). SQLCliente.Open; Em seguida estamos atribuindo resposta, o tipo de empacotamento WML. Response.ContentType:='text/vnd.wap.wml'; Na prxima instruo, estamos fazendo as definies iniciais, como cabealho <?xml...>, card <card>, e incio de um pargrafo <P>. Isso imprescindvel. Response.Content:='<?xml version="1.0"?>'+ '<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EM" "http://www.wapforum.org/DTD/wml_1.1.xml">'+ '<wml><card id="cartaum"><p>'; Agora vem a parte interessante. Estamos adicionando ao pacote de resposta (Response.Content), a informao obtida atravs do componente producer_Cliente, e finalizando o pargrafo<P>, o Card</card> e o documento WML </wml>. Response.Content:=Response.Content+producerCliente.Content+ '</p></card></wml>'; Amigos, agora s compilar e testar no Deck-It. http://localhost/cgi-bin/wap_bd.exe/dados Vejam o resultado (figura 10.16).

192 Delphi 7 Internet e Banco de Dados

Figura 10.16 Resultado da aplicao.

Listagem 10.2
unit un_wap_bd; interface uses SysUtils, Classes, HTTPApp, DBXpress, FMTBcd, DB, SqlExpr, DBWeb; type TWebModule1 = class(TWebModule) ConexaoBD: TSQLConnection; SQLCliente: TSQLDataSet; producer_Cliente: TDataSetTableProducer; procedure WebModule1WebActionItem1Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); private { Private declarations } public { Public declarations } end; var WebModule1: TWebModule1; implementation {$R *.xfm} procedure TWebModule1.WebModule1WebActionItem1Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin // Abre o SQLCliente SQLCliente.Open; // Define o tipo do contedo Response.ContentType:='text/vnd.wap.wml'; // Monta a cabealho padro

Aplicaes para Celulares 193

Response.Content:='<?xml version="1.0"?>'+ '<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EM" "http://www.wapforum.org/DTD/wml_1.1.xml">'+ '<wml><card id="cartaum"><p>'; // Insere o conteudo da nossa Tabela producer_Cliente na resposta e finaliza Response.Content:=Response.Content+producer_Cliente.Content+ '</p></card></wml>'; // Fecha o SQLCliente SQLCLiente.Close; end; end.

Terceiro Exemplo (Incluso)


Agora vamos desenvolver algo mais interativo, onde o usurio do celular poder se cadastrar em nosso banco de dados. Atravs das opes File/New..., selecione o item Web Server Application (figura 10.10) e clique em OK.

Figura 10.17 Item Web Server Application Em seguida, selecione o tipo de aplicao CGI, e marque a opo Cross Platform (figura 10.18).

194 Delphi 7 Internet e Banco de Dados

Figura 10.18 Escolha do tipo da aplicao servidora Agora, neste ponto, precisamos estabelecer a conexo com o nosso banco de dados. Insira um objeto do tipo TSQLConnection, e atravs do duplo-clique, j na tela de configurao, aponte para a nossa conexo Clientes, criada anteriormente. Vamos relembrar os atributos da conexo.

PROPRIEDADE

VALOR

CommitRetain Database Password UserName Name

False localhost:c:\cursoweb\clientes.gdb a famosa masterkey o famoso SYSDBA ConexaoBD

Altere tambm a propriedade LoginPrompt para false. Nunca esquea de fazer esta alterao, pois numa aplicao servidora, no existe a possibilidade do usurio interagir no login do banco de dados.

Aplicaes para Celulares 195

Figura 10.18 Configurao da Conexo Agora vamos inserir o objeto para manipular nossa tabela de clientes. Insira um objeto do tipo TSQLDataSet, e altere as seguintes propriedades:

PROPRIEDADE

VALOR

SQLConnection CommandText

ConexaoBD INSERT INTO TBCLIENTE (COD_CLIENTE, RAZAO_SOCIAL, EMAIL) VALUES (0,:pRAZAO,:pEMAIL)

Repare que estamos colocando dois parmetros, (pRAZAO e pEMAIL), que devero ser configurados atravs da propriedade PARAMS (figura 10.20).

Figura 10.20 Params

196 Delphi 7 Internet e Banco de Dados Atravs do duplo-clique na propriedade Params, acessamos o editor de parmetros (figura 10.21). Configure os dois parmetros para o tipo ftString, atravs da propriedade DataType.

Figura 10.21 Configurao dos Parmetros Ok amigos, agora vamos continuar nossa aplicao inserindo um componente do tipo TPageProducer e alterar as seguintes propriedades:

PROPRIEDADE

VALOR

Name HTMLDoc

ppInclusao (Veja a listagem de cdigo que segue)

Insira este cdigo na propriedade HTMLDoc do objeto ppInclusao. <wml> <card id="inclusao"> <p align="center"> Inclusao Clientes <br/> <br/> </p> <p> Razao Social: <input type="text" name="razao"/> <br/> eMail : <input type="text" name="email"/> <do type="accept" label="CONFIRMA"> <go href="confirma" method="post"> <postfield name="razao" value="$razao"/> <postfield name="email" value="$email"/> </go> </do> </p> </card> </wml> Agora vamos criar uma varivel em nosso WebModule para facilitar nas respostas ao cliente, em nosso caso, o celular. Antes da seo implementation, crie a nossa varivel cabealho, como segue: var WebModule1: TWebModule1; cabecalho:string = '<?xml version="1.0"?>'+ '<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EM"

Aplicaes para Celulares 197 "http://www.wapforum.org/DTD/wml_1.1.xml">'; implementation Neste ponto, iremos criar nossas Actions (figura10.22).

Figura 10.22 Actions Teremos uma Action para apresentar a tela de incluso, e outra para confirmar. Primeiro vamos criar a Action inclusao.(sem acento mesmo). No evento OnAction, insira o cdigo que segue: Response.ContentType:='text/vnd.wap.wml'; Response.Content:=cabecalho+ppInclusao.Content; Neste cdigo, estamos informando o tipo de pacote e utilizando nossa varivel auxiliar cabealho para compor a nossa resposta, alm, claro, do contedo do Producer ppInclusao. Bem simples, no? Em seguida, precisamos criar a nossa Action confirma. No evento OnAction, insira o cdigo que segue: try SQLInsere.ParamByName('pRazao').Value:=Request.ContentFields.Values['razao']; SQLInsere.ParamByName('pemail').Value:=Request.ContentFields.Values['email']; SQLInsere.ExecSQL(); Response.ContentType:='text/vnd.wap.wml'; Response.Content:='<wml><card id="ok"><p>Registro Incluido</p></card></wml>'; except Response.ContentType:='text/vnd.wap.wml'; Response.Content:='<wml><card id="ok"><p>Erro na Incluso</p></card></wml>'; end; Neste cdigo estamos atribuindo aos parmetros de nossa Query SQLInsere, o contedo informado pelo usurio, e transmitido atravs do mtodo POST. O cdigo est protegido atravs dos comandos try/except e, em caso de sucesso, apresentamos ao usurio a mensagem Registro Includo. Caso contrrio, apresentamos a mensagem Erro na Incluso. As figuras 10.23, 10.24, 10.25 e 10.26 ilustram nossa aplicao em ao. Para chamar a aplicao, utilize: http://localhost/cgi-bin/wap_inc.exe/dados

198 Delphi 7 Internet e Banco de Dados

Figura 10.23 Digitando Razo Social

Figura 10.24 Digitando e-mail

Figura 10.25 Confirmando dados

Aplicaes para Celulares 199

Figura 10.26 Registro includo com sucesso Amigos, com um pouquinho de esforo, d para criar uma aplicao bem completa para celulares. Digo esforo pois existem vrios limites nos aparelhos, como tamanho de tela, capacidade de dados, entre outras coisas, que nos fazem voltar ao tempo da magia e dedicao, onde fazamos malabarismos com o Clipper, o C e o Turbo Pascal para oferecer telas agradveis aos nossos usurios. Encerramos por aqui este tpico, e espero que tenham gostado.

Listagem 10.3 WAP_Inclusao


unit un_wap_inclusao; interface uses SysUtils, Classes, HTTPApp, DBXpress, FMTBcd, HTTPProd, DB, SqlExpr; type TWebModule1 = class(TWebModule) ConexaoBD: TSQLConnection; SQLInsere: TSQLDataSet; ppInclusao: TPageProducer; procedure WebModule1inclusaoAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); procedure WebModule1confirmaAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); private { Private declarations } public { Public declarations } end; var WebModule1: TWebModule1; cabecalho:string = '<?xml version="1.0"?>'+ '<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EM" "http://www.wapforum.org/DTD/wml_1.1.xml">';

200 Delphi 7 Internet e Banco de Dados implementation {$R *.xfm} procedure TWebModule1.WebModule1inclusaoAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin Response.ContentType:='text/vnd.wap.wml'; Response.Content:=cabecalho+ppInclusao.Content; end; procedure TWebModule1.WebModule1confirmaAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin try SQLInsere.ParamByName('pRazao').Value:=Request.ContentFields.Values['razao']; SQLInsere.ParamByName('pemail').Value:=Request.ContentFields.Values['email']; SQLInsere.ExecSQL(); Response.ContentType:='text/vnd.wap.wml'; Response.Content:='<wml><card id="ok"><p>Registro Incluido</p></card></wml>'; except Response.ContentType:='text/vnd.wap.wml'; Response.Content:='<wml><card id="ok"><p>Erro na Incluso</p></card></wml>'; end;

end; end.

Aplicaes para Celulares 201

Anotaes de Dvidas

?
Preciso Revisar

Anotaes Gerais

202 Delphi 7 Internet e Banco de Dados

Captulo 11
WebSnap

O WebSnap, presente desde a verso 6 do Delphi, e a verso 2 do Kylix, tem como proposta e objetivo principal o desenvolvimento de aplicaes para Internet com o conceito RAD (Rapid Application Development), ou desenvolvimento rpido de aplicaes. Na realidade no foi incorporada para substituir o WebBroker, e sim complementar e estender suas funcionalidades. Uma das coisas mais interessantes nesta tecnologia a possibilidade de utilizar inmeros formulrios para uma mesma aplicao. Em WebBroker no era possvel, pelo menos no de maneira organizada e documentada. Na tecnologia WebBroker as equipes de desenvolvimento precisavam criar projetos diferentes para produzir de maneira adequada. Com o WebSnap essa barreira foi quebrada, permitindo compartilhar diversas units entre as equipes. A tecnologia WebSnap tambm permitiu o desenvolvimento de outros frameworks bastante produtivos e que esto fazendo o maior sucesso entre os desenvolvedores. Prova disso foi a incorporao de um desses frameworks nesta verso do Delphi: o Intraweb, que veremos no prximo captulo.

Algumas curiosidades
O modelo de desenvolvimento Web no Delphi vem crescendo a cada verso, provando a forte tendncia deste modelo. Grandes empresas esto partindo para este modelo de desenvolvimento, justamente pela portabilidade, economia e praticidade. Sinceramente, sugiro que todos explorem o mximo este modelo de desenvolvimento, pois o mercado est indo para este lado.

Conhecendo os componentes
Embora a melhor maneira de conhecer os componentes do WebSnap seja praticando alguns exemplos, darei um breve descritivo de cada um deles.

202

WebSnap 203 A figura 11.1 ilustra a paleta de componentes do WebSnap.

Figura 11.1 Componentes WebSnap Componente Descrio Fornece uma interface de scripts e execuo de comandos TAdapter Fornece uma camada lgica para diviso de pginas de dados. Tecnologia comumente encontrada em sites de busca. Fornece solues de controles e comandos para DataSets. Adiciona funes semelhantes aos Adapters, relacionando com os DataSets. Utilizado para criar formulrios de Login. TLoginFormAdapter Fornece aos Adapters uma lista de nomes e valores. Exemplo: Nome e Senha, Cdigo e Razo Social, e assim por diante Semelhante ao TStringValuesList, mas vinculado a um DataSet. TDataSetValuesList Principal componente da tecnologia WebSnap. Fornece toda a interface para o desenvolvimento de aplicaes WebSnap. Fornece interface de scripts relacionados informao da aplicao. TApplicationAdapter Controle de informao sobre o usurio, como Nome, ID, sesso. TEndUserAdapter Controle completo sobre a informao de sesso do usurio. Normalmente utilizado com TSessionsService e TendUserAdapter.

TPagedAdapter

TDataSetAdapter

TStringsValuesList

TWebAppComponents

TEndUserSessionAdapter

204 Delphi 7 Internet e Banco de Dados Componente Descrio Responsvel pela interface de request HTTP de aplicaes WebSnap. necessrio apenas um por aplicao. Fornece interface de tratamento de submisses de formulrios HTML e imagens. necessrio para que a aplicao trabalhe com os adapter actions, alm de imagens provenientes de adapter fields. Fornece controle sobre arquivos de template e arquivos script-server-side. Facilita a manipulao destes arquivos.

TPageDispatcher

TAdapterDispatcher

TLocateFileService

TSessionService

Armazena informaes de sesses temporariamente. Possui TimeOut, nmero mximo de sesses, entre outras funcionalidades. Controla uma lista predefinida de usurios, fazendo validao de login e controle de acesso. Faz um parse em documentos XML, baseados no template XSL. Muito utilizado na tecnologia Web, cria um documento HTML com diversas funcionalidades e controles.

TWebUserList

TXSLPageProducer

TAdapterPageProducer

Preparando o ambiente para os exemplos


Neste ponto vamos preparar nosso ambiente para o desenvolvimento das aplicaes baseadas na tecnologia WebSnap. Crie a seguinte estrutura de diretrios (diagrama 11.1)

C:\CursoWeb WebSnap

exercicio1 exercicio2 exerccio3 exerccio4 clientes


Diagrama 11.1

WebSnap 205

Primeiro Exemplo
Neste primeiro exemplo, faremos uma simples demonstrao da tecnologia WebSnap. O mais importante neste tpico compreender toda a estrutura da tecnologia. Todos os passos sero analisados para que voc compreenda de maneira satisfatria cada detalhe. Atravs das opes File/New/Other..., selecione a seo WebSnap e escolha a opes WebSnap Application (figura 11.2).

Figura 11.2 Selecionando o modelo da aplicao Em seguida teremos uma janela assistente (figura 11.3) com diversas opes de configurao da aplicao.

Figura 11.3 Opes da aplicao WebSnap

206 Delphi 7 Internet e Banco de Dados Vamos analisar as opes: Tipo do servidor Primeiro, devemos escolher o tipo do servidor (CGI, ISAPI, Apache ou Web App Debugger). Escolha a opo Web App Debugger e informe o nome da classe (necessrio apenas para esta opo). Para este exemplo vamos nomear como classExemplo1. O Web App Debugger na realidade um servidor HTTP que oferece um timo nvel de depurao para a nossa aplicao. Escolhendo esta opo gerado um modelo de servidor COM, para interagir com o Web App Debugger. Esta opo utilizada nica e exclusivamente para o desenvolvimento e nunca para a distribuio. Componentes da Aplicao Em seguida temos a seo Application Module Components, responsvel pela configurao dos mdulos da aplicao. Clicando no boto Components, voc ter acesso outra caixa de dilogo (figura 11.4) com opes de servio.

Figura 11.4 Opes de servio Nesta caixa de dilogo escolhemos os servios bsicos de nossa aplicao. Na realidade cada servio poder ser adicionado sua aplicao conforme a necessidade. Para este primeiro exemplo, mantenha as opes padro e clique no boto OK. Opes da Aplicao Em seguida temos a seo Application Module Options, responsvel pela configurao das opes da aplicao. Clicando no boto Page Options, voc ter acesso caixa de dilogo (figura 11.5) com opes da aplicao.

WebSnap 207

Figura 11.5 Opes da aplicao Aqui temos um nvel bastante interessante de configurao. Na primeira seo, temos a configurao do nosso Producer, com os seguintes tipos: AdapterPageProducer DataSetPageProducer InetXPageProducer PageProducer XLSPageProducer Selecione a opo PageProducer. Dependendo do tipo selecionado, temos as seguintes opes para o script engine: JScript VBScript Mantenha a seleo em JScript. Em seguida temos a seo HTML. Esta seo permite ao desenvolvedor criar uma pgina automaticamente, seja a partir de um modelo (Standard) ou em branco (Blank). Selecione a opo Standard e deixe marcada a opo New File. E, por fim, temos as informaes da nossa pgina HTML. Name Title Published Login Required Mantenha as opes padro e pressione o boto OK. Retornando caixa de dilogo inicial, pressione OK para concluir o assistente e gerar nossa primeira aplicao. A figura 11.6 ilustra o PageModule criado. Utilizado como referncia para requisies HTTP e lgica da sua aplicao. Ttulo que ser apresentado na janela do browser. habilita o recurso de resposta as requisies HTTP. Verifica se existe a necessidade do usurio fazer Login para entrar nesta pgina.

208 Delphi 7 Internet e Banco de Dados

Figura 11.6 Page Module Agora vamos gravar nosso primeiro projeto no diretrio \WebSnap\Exercicio1, como segue. Unit PageModule Unit Formulrio Projeto un_ex1.PAS un_form.PAS wsnap1.DPR

Aps a gravao do nosso projeto, repare que foi gerado automaticamente um arquivo un_ex1.HTML, com o seguinte contedo. <html> <head> <title> <%= Page.Title %> </title> </head> <body> <h1><%= Application.Title %></h1> <% if (EndUser.Logout != null) { %> <% if (EndUser.DisplayName != '') { %> <h1>Welcome <%=EndUser.DisplayName %></h1> <% } %> <% if (EndUser.Logout.Enabled) { %> <a href="<%=EndUser.Logout.AsHREF%>">Logout</a> <% } %> <% if (EndUser.LoginForm.Enabled) { %> <a href=<%=EndUser.LoginForm.AsHREF%>>Login</a> <% } %> <% } %> <h2><%= Page.Title %></h2> <table cellspacing="0" cellpadding="0"> <td>

WebSnap 209 <% e = new Enumerator(Pages) s = '' c = 0 for (; !e.atEnd(); e.moveNext()) { if (e.item().Published) { if (c>0) s += '&nbsp;|&nbsp;' if (Page.Name != e.item().Name) s += '<a href="' + e.item().HREF + '">' + e.item().Title + '</a>' else s += e.item().Title c++ } } if (c>1) Response.Write(s)

%> </td> </table>

</body> </html> Podemos visualizar o documento atravs das Tabs do nosso editor de cdigo (figura 11.7).

Figura 11.7 Tabs do editor de cdigo Antes de executar nossa primeira aplicao, insira uma frase qualquer no corpo do documento un_ex1.HTML, como segue. Nossa primeira aplicao </body> </html> Grave o documento para que possamos executar a aplicao. Execute normalmente a aplicao atravs da tecla F9, ou da opo Run/Run... do menu. Perceba que o formulrio em branco, apresentado na tela. Atravs das opes Tools/WebAppDebugger vamos executar o nosso servidor e depurador de aplicaes. A figura 11.8 ilustra o WebAppDebugger em execuo. Clique no boto Start para iniciar o servidor e, em seguida, no link Default URL.

210 Delphi 7 Internet e Banco de Dados

Figura 11.8 Web App Debugger Ao clicar no link Default, ser apresentado um documento HTML (figura 11.9) com todos os servios registrados. Selecione o nosso exemplo e clique no boto GO.

Figura 11.9 Servios registrados A figura 11.10 ilustra o resultado da nossa primeira aplicao WebSnap.

Figura 11.10 Primeira aplicao WebSnap Com isso conclumos nossa primeira aplicao.

WebSnap 211

Listagem 11.1 un_ex1.pas


unit un_ex1; interface uses SysUtils, Classes, HTTPApp, WebModu, HTTPProd, ReqMulti, WebDisp, WebAdapt, WebComp; type Tindex = class(TWebAppPageModule) PageProducer: TPageProducer; WebAppComponents: TWebAppComponents; ApplicationAdapter: TApplicationAdapter; PageDispatcher: TPageDispatcher; AdapterDispatcher: TAdapterDispatcher; private { Private declarations } public { Public declarations } end; function index: Tindex; implementation {$R *.dfm} {*.html}

uses WebReq, WebCntxt, WebFact, Variants; function index: Tindex; begin Result := Tindex(WebContext.FindModuleClass(Tindex)); end; initialization if WebRequestHandler <> nil then WebRequestHandler.AddWebModuleFactory(TWebAppPageModuleFactory.Create(Tindex, TWebPageInfo.Create([wpPublished {, wpLoginRequired}], '.html'), caCache) ); end.

Segundo Exemplo
No segundo exemplo vamos conhecer os conceitos de Server Scripts e dos Adapters. Os Server Scripts nos auxiliam em diversas tarefas, seja para acessar valores em objetos criados atravs do Delphi, ou at mesmo rotinas dinmicas geradas no servidor. A grande vantagem de utilizar Server Scripts justamente a facilidade da manuteno do projeto, onde muitas vezes, apenas o arquivo HTML sofre mudanas. Com isso no h necessidade de uma nova compilao.

212 Delphi 7 Internet e Banco de Dados J os Adapters, como voc ir perceber ao longo deste captulo, sero nossos grandes aliados. Na realidade os Adapters fornecem uma interface de scripts para a sua aplicao servidora. Vamos aprender na prtica esses conceitos. Atravs das opes File/New/Other..., selecione a seo WebSnap e escolha a opes WebSnap Application (figura 11.11).

Figura 11.11 Selecionando o modelo da aplicao Em seguida (figura 11.12) selecione a opo Web App Debugger, e informe o nome da classe (necessrio apenas para esta opo). Para este exemplo vamos nomear como classExemplo2.

Figura 11.12 Opes da aplicao WebSnap

WebSnap 213 Em seguida temos a seo Application Module Components, responsvel pela configurao dos mdulos da aplicao. Clicando no boto Components, voc ter acesso outra caixa de dilogo (figura 11.13) com opes de servio.

Figura 11.13 Opes de servio Assim como no primeiro exemplo, mantenha as opes padro e clique no boto OK. Em seguida temos a seo Application Module Options, responsvel pela configurao das opes da aplicao. Clicando no boto Page Options, voc ter acesso caixa de dilogo (figura 11.14) com opes da aplicao.

Figura 11.14 Opes da aplicao Selecione Page Producer para o Producer Type e mantenha a seleo JScript. no Script Engine. Em seguida temos a seo HTML. Selecione a opo Standard e deixe marcada a opo New File. Retornando caixa de dilogo inicial, pressione OK para concluir o assistente e gerar nossa segunda aplicao. A figura 11.15 ilustra o PageModule criado.

214 Delphi 7 Internet e Banco de Dados

Figura 11.15 Page Module Agora vamos gravar nosso segundo projeto no diretrio \WebSnap\Exercicio2, como segue. Unit PageModule Unit Formulrio Projeto un_ex2.PAS un_form.PAS wsnap2.DPR

Agora vamos inserir um objeto do tipo TAdapter e, em seguida, acessar a propriedade Data deste objeto, clicando no boto relacionado (figura 11.16).

Figura 11.16 Propriedade Data Em seguida temos o editor de campos para o objeto Adapter (figura 11.17).

WebSnap 215

Figura 11.17 Editor de campos Clique com o boto direito do mouse sob o editor e selecione a opo New Component ou clique no primeiro boto, como ilustra a figura 11.17. Em seguida teremos uma lista com os possveis componentes do nosso objeto Adapter1.

Figura 11.18 Componentes do Adapter Selecione o componente AdapterField e clique no boto OK. Modifique a propriedade Name do componente criado para MeuFieldAdapter. A figura 11.19 ilustra os eventos do nosso objeto MeuFieldAdapter.

Figura 11.19 Eventos do MeuFieldAdapter

216 Delphi 7 Internet e Banco de Dados Prosseguindo com nosso exemplo, vamos atribuir um valor dinmico ao nosso objeto MeuFieldAdapter. No evento OnGetValue insira o cdigo que segue: procedure Tindex.MeuFieldAdapterGetValue(Sender: TObject; var Value: Variant); begin Value:=TimetoStr(Time); end; Agora vamos acessar o valor do nosso objeto, no arquivo index.HTML criado pelo assistente. Insira o comando que segue, na seo <BODY> do documento. <B><%Response.Write(Adapter1.MeuFieldAdapter.value)%></B> Grave o nosso projeto e execute normalmente a aplicao atravs da tecla F9, ou da opo Run/Run... do menu. Atravs das opes Tools/WebAppDebugger vamos executar o nosso servidor e depurador de aplicaes. Clique no boto Start para iniciar o servidor, e em seguida no link Default URL. Ao clicar no link Default ser apresentado um documento HTML (figura 11.20) com todos os servios registrados. Selecione o nosso exemplo e clique no boto GO.

Figura 11.20 Servios registrados Amigos, obviamente o exemplo bastante simples, mas imaginem que atravs dos objetos Adapters poderemos acessar valores de clculos, resultados de instrues SQL, imagens dinmicas, entre outras funcionalidades.

Listagem 11.2 un_ex2.pas


unit un_ex2; interface uses SysUtils, Classes, HTTPApp, WebModu, HTTPProd, ReqMulti, WebDisp, WebAdapt, WebComp; type Tindex = class(TWebAppPageModule) PageProducer: TPageProducer; WebAppComponents: TWebAppComponents; ApplicationAdapter: TApplicationAdapter; PageDispatcher: TPageDispatcher; AdapterDispatcher: TAdapterDispatcher; Adapter1: TAdapter;

WebSnap 217 MeuFieldAdapter: TAdapterField; procedure MeuFieldAdapterGetValue(Sender: TObject; var Value: Variant); private { Private declarations } public { Public declarations } end; function index: Tindex; implementation {$R *.dfm} {*.html}

uses WebReq, WebCntxt, WebFact, Variants; function index: Tindex; begin Result := Tindex(WebContext.FindModuleClass(Tindex)); end; procedure Tindex.MeuFieldAdapterGetValue(Sender: TObject; var Value: Variant); begin Value:=TimetoStr(Time); end; initialization if WebRequestHandler <> nil then WebRequestHandler.AddWebModuleFactory(TWebAppPageModuleFactory.Create(Tindex, TWebPageInfo.Create([wpPublished {, wpLoginRequired}], '.html'), caCache) ); end.

Listagem 11.3 un_ex2.HTML


<html> <head> <title> <%= Page.Title %> </title> </head> <body> <h1><%= Application.Title %></h1> <% if (EndUser.Logout != null) { %> <% if (EndUser.DisplayName != '') { %> <h1>Welcome <%=EndUser.DisplayName %></h1> <% } %> <% if (EndUser.Logout.Enabled) { %> <a href="<%=EndUser.Logout.AsHREF%>">Logout</a> <% } %> <% if (EndUser.LoginForm.Enabled) { %> <a href=<%=EndUser.LoginForm.AsHREF%>>Login</a> <% } %> <% } %>

218 Delphi 7 Internet e Banco de Dados

<h2><%= Page.Title %></h2> <table cellspacing="0" cellpadding="0"> <td> <% e = new Enumerator(Pages) s = '' c = 0 for (; !e.atEnd(); e.moveNext()) { if (e.item().Published) { if (c>0) s += '&nbsp;|&nbsp;' if (Page.Name != e.item().Name) s += '<a href="' + e.item().HREF + '">' + e.item().Title + '</a>' else s += e.item().Title c++ } } if (c>1) Response.Write(s) %> </td> </table> <B><% Response.Write(Adapter1.MeuFieldAdapter.value) %></B> </body> </html>

Terceiro Exemplo
No terceiro exemplo vamos trabalhar com mltiplos Page Modules, alm de dispensar o assistente para criao automtica de pginas. Atravs das opes File/New/Other..., selecione a seo WebSnap e escolha a opes WebSnap Application (figura 11.21).

Figura 11.21 Selecionando o modelo da aplicao

WebSnap 219 Em seguida, (figura 11.22) selecione a opo Web App Debugger e informe o nome da classe. Para este exemplo vamos nomear como classExemplo3.

Figura 11.22 Opes da aplicao WebSnap Em seguida temos a seo Application Module Components, responsvel pela configurao dos mdulos da aplicao. Clicando no boto Components, voc ter acesso outra caixa de dilogo (figura 11.23) com opes de servio.

Figura 11.23 Opes de servio Assim como nos exemplos anteriores, mantenha as opes padro e clique no boto OK.

220 Delphi 7 Internet e Banco de Dados Em seguida temos a seo Application Module Options, responsvel pela configurao das opes da aplicao. Clicando no boto Page Options, voc ter acesso caixa de dilogo (figura 11.24) com opes da aplicao. Selecione Page Producer para o Producer Type e mantenha a seleo JScript. no Script Engine. Em seguida temos a seo HTML. Desmarque a opo New File e clique no boto OK.

Figura 11.24 Opes da aplicao Agora vamos gravar nosso terceiro projeto no diretrio \WebSnap\Exercicio3, como segue. Unit PageModule Unit Formulrio Projeto un_ex3.PAS un_form.PAS wsnap3.DPR

Como dispensamos a criao automtica do arquivo HTML, vamos utilizar os novos assistentes do Delphi, para cri-lo. Atravs das opes File/New/Other..., acesse a seo Web Documents como ilustra a figura 11.25 e selecione a opo HTML.

Figura 11.25 Novo documento HTML

WebSnap 221 Veja que o seguinte documento foi criado. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <HTML> <HEAD> <TITLE> Untitled1.html </TITLE> </HEAD> <BODY>

</BODY> </HTML> No editor do Delphi, perceba que existe um assistente code completation para HTML (figura 11.26).

Figura 11.26 Code completation HTML Faa as modificaes (em negrito) como segue: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <HTML> <HEAD> <TITLE> Pgina Principal </TITLE> </HEAD> <BODY> <% e = new Enumerator(Pages) s = '' c = 0 for (; !e.atEnd(); e.moveNext()) { if (e.item().Published) { if (c>0) s += '&nbsp;|&nbsp;' if (Page.Name != e.item().Name) s += '<a href="' + e.item().HREF + '">' + e.item().Title + '</a>' else s += e.item().Title c++

222 Delphi 7 Internet e Banco de Dados } } if (c>1) Response.Write(s) %> </BODY> </HTML> Vamos analisar o cdigo script, normalmente utilizado pelo padro Standard do Page Module: No primeiro bloco, estamos criando um objeto do tipo Enumerator e iniciando as variveis s e c. A varivel s ser a nossa string para montagem dos links que sero apresentados e a varivel c uma auxiliar para contagem de nmeros de pginas da aplicao. <% e = new Enumerator(Pages) s = '' c = 0

No bloco seguinte estamos iniciando um lao baseado no objeto e criado anteriormente e movendo uma posio no objeto a cada ciclo. Perceba que o objeto e cria uma matriz de Page Modules da aplicao. for (; !e.atEnd(); e.moveNext()) No bloco que segue, estamos verificando se o item atual (Page Module) do objeto e possui o mtodo de publicao. if (e.item().Published) Em caso afirmativo, acrescenta-se varivel s, espao | espao, onde &nbsp; igual a espao na linguagem HTML. if (c>0) s += '&nbsp;|&nbsp;' Seguindo com o nosso script, este prximo bloco verifica se o item em questo diferente do que solicita o script, ou seja, verifica se diferente dele mesmo. Em caso afirmativo cria o link da pgina baseado no item atual, seno apenas apresenta o ttulo da pgina. if (Page.Name != e.item().Name) s += '<a href="' + e.item().HREF + '">' + e.item().Title + '</a>' else s += e.item().Title Em seguida apenas incrementamos a varivel c. c++ E por fim, escrevemos no HTML todo o contedo da varivel s caso a varivel c seja maior que 1, isto , apenas se nossa aplicao contiver 2 ou mais PageModules. if (c>1) Response.Write(s) %> Agora vamos adicionar Page Modules ao nosso projeto. Atravs das opes File/New..Other..., seo WebSnap, selecione o assistente WebSnap PageModule (figura 11.27).

WebSnap 223

Figura 11.27 Novo PageModule Em seguida, configure as opes como ilustra a figura 11.28.

Figura 11.28 Configurao Page Module Grave a unit como un_ex3_pag2.pas. Insira o cdigo que segue no HTML associado a unit un_ex3_pag2, em nosso caso un_ex3_pag2.HTML. <B> Estamos na Pgina 2 </B>

224 Delphi 7 Internet e Banco de Dados Grave o nosso projeto e execute normalmente a aplicao atravs da tecla F9, ou da opo Run/Run... do menu. Atravs das opes Tools/WebAppDebugger vamos executar o nosso servidor e depurador de aplicaes. Clique no boto Start para iniciar o servidor, e em seguida no link Default URL. Ao clicar no link Default ser apresentado um documento HTML (figura 11.29) com todos os servios registrados. Selecione o nosso exemplo e clique no boto GO.

Figura 11.29 Aplicaes registradas As figuras 11.30 e 11.31 ilustram o resultado de nossa aplicao.

Figura 11.30 Terceiro exemplo pgina principal

Figura 11.31 Terceiro exemplo pgina 2

WebSnap 225

Listagem 11.4 principal.html


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <HTML> <HEAD> <TITLE> Pgina Principal </TITLE> </HEAD> <BODY> <% e = new Enumerator(Pages) s = '' c = 0 for (; !e.atEnd(); e.moveNext()) { if (e.item().Published) { if (c>0) s += '&nbsp;|&nbsp;' if (Page.Name != e.item().Name) s += '<a href="' + e.item().HREF + '">' + e.item().Title + '</a>' else s += e.item().Title c++ } } if (c>1) Response.Write(s) %> </BODY> </HTML>

Quarto Exemplo
No quarto exemplo vamos trabalhar com a interatividade do usurio. Atravs das opes File/New/Other..., selecione a seo WebSnap e escolha a opes WebSnap Application (figura 11.32).

Figura 11.32 Selecionando o modelo da aplicao

226 Delphi 7 Internet e Banco de Dados Em seguida (figura 11.33) selecione a opo Web App Debugger e informe o nome da classe. Para este exemplo vamos nomear como classExemplo4.

Figura 11.33 Opes da aplicao WebSnap Em seguida temos a seo Application Module Components, responsvel pela configurao dos mdulos da aplicao. Clicando no boto Components, voc ter acesso outra caixa de dilogo (figura 11.34) com opes de servio.

Figura 11.34 Opes de servio Assim como nos exemplos anteriores, mantenha as opes padro, e clique no boto OK.

WebSnap 227 Em seguida temos a seo Application Module Options, responsvel pela configurao das opes da aplicao. Clicando no boto Page Options, voc ter acesso caixa de dilogo (figura 11.35) com opes da aplicao. Selecione Page Producer para o Producer Type e mantenha a seleo JScript. no Script Engine. Em seguida temos a seo HTML. Desmarque a opo New File e clique no boto OK.

Figura 11.35 Opes da aplicao Agora vamos gravar nosso quarto projeto no diretrio \WebSnap\Exercicio4, como segue. Unit PageModule Unit Formulrio Projeto un_ex4.PAS un_form.PAS wsnap4.DPR

Agora vamos criar um novo Web Page Module atravs das opes File/New...Other... e na seo WebSnap, selecione WebSnap Page Module. Configure de acordo com a figura 11.36.

Figura 11.36 Novo Web Page Module

228 Delphi 7 Internet e Banco de Dados Pressione OK, e grave a unit como un_formulario.ps. Repare que selecionamos AdapterPageProducer, ao invs do tradicional Page Producer. Vamos criar trs variveis na seo private, com o objetivo de executar um clculo futuro. private v1:single; v2:single; vResultado:single; Agora insira um objeto do tipo TAdapter para que possamos trabalhar com objetos Fields. Inclua um Adapter Field, atravs da propriedade Data do objeto Adapter1, como ilustra a figura 11.37.

Figura 11.37 Adapter Field Altere a propriedade Name para Valor1 e insira o cdigo que segue no evento OnGetValue: procedure Tformulario.Valor1GetValue(Sender: TObject; var Value: Variant); begin Value:=v1; end; Agora vamos criar outro AdapterField com o nome Valor2 e insira o seguinte cdigo no evento OnGetValue: procedure Tformulario.Valor2GetValue(Sender: TObject; var Value: Variant); begin Value:=v2; end; Agora vamos incluir um AdapterField para exibir o resultado da operao, com o nome Resultado. Insira o cdigo que segue no evento OnGetValue: Value:= vResultado; Antes de definir o layout da aplicao vamos definir a ao que ir alimentar nossas variveis. Selecione o objeto Adapter1 e atravs da propriedade Actions (figura 11.38) crie uma nova Action para o nosso objeto. Altere o nome da Action para calcula.

WebSnap 229

Figura 11.38 Actions No evento OnExecute da Action calcula, insira o cdigo a seguir. procedure Tformulario.calculaExecute(Sender: TObject; Params: TStrings); begin v1:= Valor1.ActionValue.Values[0]; v2:= Valor2.ActionValue.Values[0]; vResultado:=v1+v2; end; O cdigo bastante simples, onde estamos atribuindo s variveis v1,v2 e vResultado, os valores resgatados atravs de um formulrio HTML que iremos criar. Na realidade, a varivel vResultado est sendo alimentada com o resultado da operao (v1+v2). Agora vamos criar o formulrio HTML utilizando o nosso AdapterPageProducer. Atravs do duplo-clique AdapterPageProducer1, adicione um novo componente do tipo AdapterForm no objeto

Figura 11.39 Web Component Agora clique no AdapterForm1 e insira um objeto do tipo AdapterFieldGroup. Devemos vincular o AdapterFieldGroup ao objeto Adapter1, atravs da propriedade Adapter. A figura 11.40 ilustra nosso formulrio aps o vnculo.

230 Delphi 7 Internet e Banco de Dados

Figura 11.40 Formulrio criado atravs do Adapter Em nosso caso desejamos configurar manualmente as propriedades de cada campo. Para realizar tal operao, devemos adicionar os Fields, clicando com o boto direito do mouse em AdapterFieldsGroup e selecionar a opo Add All Fields. A figura 11.41 ilustra nossa operao.

Figura 11.41 Fields Altere as propriedades dos objetos criados como segue: Objeto FldValor1 Valor Informe o primeiro valor Objeto FldValor2 Valor Informe o segundo valor

Propriedade Caption

Propriedade Caption

WebSnap 231 Agora vamos inserir o boto com a nossa ao. Selecione o AdapterForm1 e insira um novo componente do tipo AdapterCommandGroup. No objeto criado, faa o vnculo da propriedade DisplayComponent com o objeto AdapterFieldGroup1. Na realidade estamos colocando o nosso boto dentro do AdapterFieldGroup1. A figura 11.42 ilustra nosso formulrio atual.

Figura 11.42 Formulrio Agora vamos inserir o campo Resultado. Selecione o objeto AdapterForm1 e insira um novo componente do tipo AdapterFieldGroup. Ser criado o AdapterFieldGroup2. Faa o vnculo com o objeto Adapter1, atravs da propridade Adapter. Ainda no AdapterFieldGroup2, adicione o field fldResultado atravs da opo Add Field. Altere a propriedade ViewMode do field adicionado para vwDisplay. A figura 11.43 ilustra o resultado da nossa operao.

Figura 11.43 Campo resultado

232 Delphi 7 Internet e Banco de Dados Grave o nosso projeto e execute normalmente a aplicao atravs da tecla F9, ou da opo Run/Run... do menu. Atravs das opes Tools/WebAppDebugger vamos executar o nosso servidor e depurador de aplicaes. Clique no boto Start para iniciar o servidor e, em seguida, no link Default URL. Ao clicar no link Default ser apresentado um documento HTML (figura 11.44) com todos os servios registrados. Selecione o nosso exemplo e clique no boto GO.

Figura 11.44 Servios registrados A figura 11.45 ilustra o resultado de nossa aplicao.

Figura 11.45 Quarto exemplo em execuo

WebSnap 233

Listagem 11.5 un_formulrio.pas


unit un_formulario; interface uses SysUtils, Classes, HTTPApp, WebModu, HTTPProd, CompProd, PagItems, SiteProd, WebComp, WebAdapt, MidItems, WebForm; type Tformulario = class(TWebPageModule) AdapterPageProducer: TAdapterPageProducer; Adapter1: TAdapter; Valor1: TAdapterField; Valor2: TAdapterField; calcula: TAdapterAction; AdapterForm1: TAdapterForm; AdapterFieldGroup1: TAdapterFieldGroup; FldValor1: TAdapterDisplayField; FldValor2: TAdapterDisplayField; AdapterCommandGroup1: TAdapterCommandGroup; Resultado: TAdapterField; AdapterFieldGroup2: TAdapterFieldGroup; FldResultado: TAdapterDisplayField; procedure Valor1GetValue(Sender: TObject; var Value: Variant); procedure Valor2GetValue(Sender: TObject; var Value: Variant); procedure calculaExecute(Sender: TObject; Params: TStrings); procedure ResultadoGetValue(Sender: TObject; var Value: Variant); private v1:single; v2:single; vResultado:single; { Private declarations } public { Public declarations } end; function formulario: Tformulario; implementation {$R *.dfm} {*.html}

uses WebReq, WebCntxt, WebFact, Variants; function formulario: Tformulario; begin Result := Tformulario(WebContext.FindModuleClass(Tformulario)); end; procedure Tformulario.Valor1GetValue(Sender: TObject; var Value: Variant); begin Value:=v1; end;

234 Delphi 7 Internet e Banco de Dados procedure Tformulario.Valor2GetValue(Sender: TObject; var Value: Variant); begin Value:=v2; end; procedure Tformulario.calculaExecute(Sender: TObject; Params: TStrings); begin v1:= Valor1.ActionValue.Values[0]; v2:= Valor2.ActionValue.Values[0]; vResultado:=v1+v2; end; procedure Tformulario.ResultadoGetValue(Sender: TObject; var Value: Variant); begin Value:=vResultado; end; initialization if WebRequestHandler <> nil then WebRequestHandler.AddWebModuleFactory(TWebPageModuleFactory.Create(Tformulario, TWebPageInfo.Create([wpPublished {, wpLoginRequired}], '.html'), crOnDemand, caCache) ); end.

WebSnap 235

Anotaes de Dvidas

?
Preciso Revisar

Anotaes Gerais

236 Delphi 7 Internet e Banco de Dados

Captulo 12
Intraweb

A grande revoluo, e por que no dizer, a agradvel surpresa presente na nova verso do Delphi: Intraweb. Desenvolvido pela empresa Atozed Software, e rapidamente adotado pela Borland numa distribuio especial (existe uma verso mais poderosa), vem ganhando simpatizantes em todo o mundo. Diversas empresas esto desenvolvendo componentes para trabalhar em conjunto com o Intraweb, dando ainda mais poder a esta incrvel tecnologia. Desenvolver aplicaes com o Intraweb bastante agradvel e prtico e certamente vai encorajar excelentes desenvolvedores Delphi, que antes torciam o nariz para a tecnologia WebBroker, devido s dificuldades comuns encontradas no desenvolvimento de aplicaes para Internet, como o aprendizado de HTML, JavaScript, alguma ferramenta aliada, como o DreamWeaver, entre outros. Desenvolvedores Delphi, criem coragem para entrar no mundo Internet com o Intraweb. Digo isso a todos que chegaram nesse captulo, passando pelos anteriores, ou at mesmo a quem abriu o livro aqui, neste tpico.

Algumas curiosidades
A Borland vem trabalhando com extremo profissionalismo, apoiando diversas empresas parceiras em projetos de tecnologia para as suas ferramentas. S para ter uma idia disso tudo, incorporou na verso 7 diversas tecnologias, como o prprio Intraweb, Rave Report (fantstico gerador de relatrios, e forte substituto do QuickReport), RxLib agora vem no CD 2, Indy Components, j visto no captulo 9, entre outras tecnologias. Se a tecnologia boa, pode ter certeza de que ser adotada nas prximas verses, e isso vem crescendo a cada dia. Sorte nossa! Antes de colocar a mo-na-massa, vou apresentar seus principais componentes: Os componentes esto divididos em quatro sees: IWStandard, IWData, IWClientSide e IWControl.

236

Intraweb 237

Componentes IWStandard
COMPONENTE DESCRIO/USO

TIWApplet TIWButton TIWCheckBox TIWComboBox TIWEdit

Para inserir uma Applet Java em sua pgina, oferecendo a configurao dos controles atravs do Object Inspector. Boto de formulrio, com funes adversas, inclusive Submit. Controles de CheckBox para formulrio. ComboBox para seleo, com opes de preenchimento de lista. Campo para edio com diversas propriedades de controle, como tamanho, se requerido, tipo password, entre outras. Linha horizontal. Para exibio de imagens estticas ou dinmicas. Transforma automaticamente a maioria dos formatos para JPEG. Utilizado para exibir imagens estticas, armazenadas num arquivo. Semelhante ao Label do Delphi. Cria um hyperlink, controlado atravs do evento OnClick. Utilizado para apresentar listas de marcao ou numeradas. Lista de opes que podem ser selecionadas. Possui um forte controle de propriedades. rea de edio (assim como o Delphi), com mltiplas linhas. Componente fantstico, que cria um menu a partir de um componente TMainMenu do Delphi. Muito bom mesmo. Agora suas aplicaes Web tero um aspecto mais profissional. Conjunto de opes ao usurio, semelhante ao RadioGroup do Delphi. Amigos, fiquei impressionado com o poder deste componente. Semelhante ao StringGrid, com opo individual de controle de clulas. Muito bom mesmo.

TIIWHRule TIWImage TIWImageFile TIWLabel TIWLink TIWList TIWListBox

TIWMemo TIWMenu

TIWRadioGroup TIWTable

238 Delphi 7 Internet e Banco de Dados

COMPONENTE

DESCRIO/USO

TIWTemplateProcessorHTML TIWText TIWTimer TIWTreeView TIWURL TIWFile

Este componente permite associar um template HTML ao nosso formulrio. Apresenta textos com mltiplas linhas, sem suporte edio. Cria um Timer no lado servidor para disparar eventos. Apresenta um TreeView com diversos controles. Muito bom. Hyperlinks externos. Este componente quebra um galho incrvel. Quem j tentou fazer rotinas de upload com a tecnologia WebBroker sabe do que estou falando. Era muito difcil, mas agora ficou muito fcil com este componente. Grid sem vnculo com banco de dados. Apresenta figuras retangulares, com diversas opes de preenchimento. Amigos, fiquei de boca aberta com os recursos deste componente. Tem a funo de um container, como o Panel do Delphi. Fantstico!

TIWGrid TIWRectangle TIWRegion

Componentes IWData
COMPONENTE DESCRIO/USO

TIWDBCheckbox TIWDBCombobox

TIWDBEdit TIWDBGrid TIWDBImage TIWDBLabel TIWDBListbox

CheckBox Data Ware, com diversas opes de configurao. ComboBox Data Ware, com incrveis propriedades, como tipo do cursor, ordenao, controle de scripts, entre outros. DBEdit Data Ware, com todos os eventos do HTML, alm de propriedades controladas pelo JavaScript. DBGrid muito bacana e funcional, com diversos controles e eventos. DBImage Data Ware. DBLabel Data Ware. DBListBox com diversos controles e propriedades.

Intraweb 239

COMPONENTE

DESCRIO/USO

TIWDBLookupCombobox

TIWDBLookupListbox TIWDBMemo TIWDBNavigator

Fantstico componente semelhante ao DBLookupComboBox do Delphi. Quem j desenvolveu aplicaes padro WebBroker sabe o enorme trabalho que d para fazer um LookupComboBox. Outra maravilha, semelhante ao DBLookupListBox do Delphi. DBMemo com diversos controles e propriedades. Amigos, este componente incrvel, tem todos os controles do DBNavigator do Delphi e possui controle de mensagens de diversos nveis. Voc poder configurar a prpria mensagem de confirmao para excluso. Muito bom. Nota 10. Semelhante ao DBText. Utilizado para associar um campo do tipo stream com a funo de uploads de arquivo.

TIWDBText TIWDBFile

Componentes IWClientSide
COMPONENTE DESCRIO/USO

TIWCSLabel TIWCSNavigator

TIWDynamicChart

TIWDynamicChartLegend TIWDynGrid

Apresentao de campos de uma tabela do lado cliente (veja controles IWControl). Controle de Navegao dos dados de uma tabela do lado Cliente. Imagine voc acessando uma tabela prconfigurada no lado cliente, e navegando vontade. Grfico com diversas opes, baseados em dados do lado cliente embora seja possvel alimentar com os dados do lado Servidor, pois no existe vnculo com DataWare, e sim com um IWClientDataSet (IW Control). Legendas do grfico, para ser utilizado em conjunto com o TIWDynamicChart. Grid ligado ao IWClientDataSet (IW Control).

240 Delphi 7 Internet e Banco de Dados

Componentes IWControl
COMPONENTE DESCRIO/USO

TIWClientSideDataSet TIWClientSideDataSetDBLink

TIWLayoutMgrForm TIWLayoutMgrHTML

TIWModuleController TIWPageProducer

TIWStandAloneServer

Controle DataSet para armazenar informaes e disponibilizar aos controles IWClientSide. Controle DataSet no padro DataWare, onde voc dever ligar diretamente a um DataSource. Isso muito legal, pois o DataSource poder coletar dados de diversas origens. Controle de layout dos objetos de um formulrio. Permite a edio do formulrio no padro HTML. Quer dar o seu toque pessoal? Ento este o componente certo. Habilita o controle do servidor para o padro PageMode do Intraweb. Com este componente voc poder utilizar toda a tecnologia Intraweb com WebSnap, e tambm aproveitar a tecnologia dos Page Producers do WebBroker. Controle da aparncia e outras propriedades da aplicao.

Antes de Comear
Este tpico muito importante, pois precisamos conhecer alguns conceitos do Intraweb. Na verso distribuda com o Delphi 7, o Intraweb coloca automaticamente o nome das units iniciais bem como do projeto. Isso pode dificultar um pouco no comeo, mas em nosso caso iremos criar uma estrutura de diretrios com o intuito de organizar nossos exerccios com o Intraweb, e evitar conflitos. Crie a seguinte estrutura de diretrios (diagrama 12.1)

Intraweb 241

C:\CursoWeb Intraweb

exercicio1 exercicio2 exerccio3 exerccio4 exerccio5 exerccio6 clientes Diagrama 12.1

Primeiro Exemplo (controles Standard)


Vamos desenvolver nossa primeira aplicao, utilizando alguns componentes da seo IWStandard. Vamos escolher o padro Stand Alone para facilitar a compreenso e o desenvolvimento. Atravs das opes File/New/Other..., selecione a seo Intraweb e escolha o modelo Stand Alone Application (figura 12.1).

Figura 12.1 Escolha do tipo da Aplicao Em seguida, selecione o diretrio de nossa primeira aplicao, em nosso caso (c:\cursoweb\intraweb\exercicio1).

242 Delphi 7 Internet e Banco de Dados

Figura 12.2 Seleo do diretrio Perceba que o Intraweb criou um mdulo principal, com alguns controles (figuras 12.3 e 12.4).

Figura 12.3 Mdulo do Projeto

Figura 12.4 Formulrios padro da aplicao Stand Alone O Intraweb cria a seguinte estrutura de arquivos para o tipo de aplicao Stand Alone:

Intraweb 243 x x x IWProject.DPR IWUnit1.PAS ServerController.PAS Projeto Unit principal, contendo o formulrio principal da aplicao Controle principal da aplicao, com sesses de usurio, tipo de acesso, protocolos de segurana (SSL), browsers, entre outros.

Agora com o foco no formulrio (selecione o formulrio da unit IWUnit1), insira um componente do tipo IWLabel e altere sua propriedade caption para Exerccio 1. A figura 12.5 ilustra o formulrio principal com o objeto IWLabel1.

Figura 12.5 Formulrio principal Agora, meus amigos, para quem estava com saudades do famoso F9 para executar e depurar as aplicaes, o Intraweb retorna aos bons tempos e habilita esta opo. Aperte F9 para executar nosso primeiro exerccio. Dever aparecer o servidor de testes do Intraweb, como ilustra a figura 12.6.

Figura 12.6 Servidor de Aplicaes Intraweb Repare que no existe nenhuma sesso ativa (Active Sessions). Para executar nossa aplicao, voc poder teclar novamente F9, ou pressionar o primeiro speed button, ou ento acessar o menu File/Run.. A figura 12.7 ilustra o resultado do nosso primeiro exerccio.

244 Delphi 7 Internet e Banco de Dados

Figura 12.7 Resultado do primeiro exerccio Tente pressionar F9 algumas vezes no Intraweb Server Application, e repare que so criadas novas sesses (figura 12.8).

Figura 12.8 Sesses ativas O mais interessante de tudo isso, que o Intraweb possui um forte controle de sesses. Repare na figura 12.9 que o Intraweb utiliza um nmero extenso, definindo a sesso do usurio. Este controle bastante robusto e facilita muito a vida do desenvolvedor no controle de sesses.

Figura 12.9 Controle de sesses Encerre o servidor de aplicaes, e retorne ao Delphi. Vejamos agora, todo o cdigo criado pelo Intraweb em nossa primeira aplicao.

Listagem 12.1 Unit IWUnit1.


unit IWUnit1; {PUBDIST} interface uses IWAppForm, IWApplication, IWTypes, Classes, Controls, IWControl, IWCompLabel; type

Intraweb 245 TformMain = class(TIWAppForm) IWLabel1: TIWLabel; public end; implementation {$R *.dfm} uses ServerController; end. Basicamente define a classe TformMain com o objeto IWLabel1. Para analisar mais profundamente nosso primeiro exerccio, clique com o boto direito do mouse no formulrio principal e selecione a opo Preview. A figura 12.10 ilustra o Preview do Intraweb.

Figura 12.10 Preview do Intraweb muito interessante essa versatilidade do Intraweb. Agora, selecione a seo Source logo abaixo do Preview e repare o cdigo HTML gerado, inclusive com CSS (figura 12.11).

Figura 12.11 Cdigo HTML Como o cdigo dinmico, o modelo gerado e visto na figura 12.11 apropriado para o modelo de servidor IntraWeb Server Application, no modo Preview. Veja a verso HTML gerada fora do Preview, mas ainda no servidor Intraweb.

246 Delphi 7 Internet e Banco de Dados

Listagem 12.2 HTML


<html><head> <style type="text/css"> .IWLABEL1CSS {position:absolute;left:136;top:112;z-index:100;font: 10pt;} </style> <script language="Javascript1.2"> function FormDefaultSubmit() {return false;} function Validate() {return true;} var GURLBase=""; var GAppID="08A197007D9506F23B52E240"; history.go(1); var IWLABEL1IWCL; function InitIWCLObjects() { IWLABEL1IWCL = new CreateIWCLObject(IWCLForm, "IWLABEL1", "IWLABEL1IWCL"); if (IWLABEL1IWCL.Item != null) { IWLABEL1IWCL.SetAlign(alNone); IWLABEL1IWCL.SetAnchors(new CreateAnchors(true, false, true, false)); } Body_OnResize(); } function Initialize() { InitSubmitter(); StaticInit(); if (document.body.leftMargin < 0 && document.body.topMargin < 0) { document.body.leftMargin = 0; document.body.topMargin = 0; } InitRects(349, 296); InitIWCLObjects(); } </script> <meta name="GENERATOR" content="IW5.0.43 Serial 0"> <script language=Javascript src="/js/IWCommon.js_5.0.43"></script> <script language=Javascript src="/js/IWCL.js_5.0.43"></script> <script language=Javascript src="/js/IWCSData.js_5.0.43"></script> <script language=Javascript src="/js/IWExplorer.js_5.0.43"></script> </head> <body onload="Initialize()" onblur="GSubmitting = false;" onresize="return Body_OnResize();"><form onsubmit="return FormDefaultSubmit();" name="SubmitForm" action="/EXEC/1/08A197007D9506F23B52E240" method="POST"> <input type="HIDDEN" name="IW_Action"> <input type="HIDDEN" name="IW_ActionParam"> </form>

Intraweb 247 <span id="IWLABEL1" class="IWLABEL1CSS">IWLabel1</span> </body> </html> Complicado, no acham? Podem ficar tranqilos, pois dificilmente teremos que dar manuteno no cdigo HTML. A idia justamente essa, utilizar o RAD (Rapid Application Development) do Intraweb para criar e dar manuteno s nossas aplicaes. S para finalizar a parte de cdigos deste tpico, vamos analisar a unit ServerController.

Listagem 12.3 Unit ServerController


unit ServerController; {PUBDIST} interface uses SysUtils, Classes, IWServerControllerBase, // For OnNewSession Event IWApplication, IWAppForm; type TIWServerController = class(TIWServerControllerBase) procedure IWServerControllerBaseNewSession(ASession: TIWApplication; var VMainForm: TIWAppForm); private public end; // This is a class which you can add variables to that are specific to the user. Add variables // to this class instead of creating global variables. This object can references by using: // UserSession // So if a variable named UserName of type string is added, it can be referenced by using: // UserSession.UserName // Such variables are similar to globals in a normal application, however these variables are // specific to each user. // // See the IntraWeb Manual for more details. TUserSession = class public end; // Procs function UserSession: TUserSession; implementation {$R *.dfm} uses IWInit;

248 Delphi 7 Internet e Banco de Dados function UserSession: TUserSession; begin Result := TUserSession(RWebApplication.Data); end; procedure TIWServerController.IWServerControllerBaseNewSession( ASession: TIWApplication; var VMainForm: TIWAppForm); begin ASession.Data := TUserSession.Create; end; end. Amigos, analisando o cdigo da unit ServerController, podemos perceber a flexibilidade no controle de sesses por usurio. possvel criar variveis similares s globais, mas com instncias por sesso, ou seja, cada usurio ter a sua prpria varivel. Eu explico melhor.Vamos imaginar uma varivel que totaliza o valor da compra, ou at mesmo uma matriz, contendo diversas informaes sobre a compra atual, e poder acessar em nvel de usurio, ou melhor, por sesso, cada varivel. Veja o cenrio: Usurio 1 Sesso 08A197007D9506F23B52E240 Valor 300 Usurio 2 Sesso E4949A0062C7BBC23C52E240 Valor 180 Usurio 3 Sesso D0679B0010B757C63C52E240 Valor 180 Repare que cada sesso possui uma identificao diferente. Imagine quando o usurio solicitar a finalizao da compra, onde necessrio apresentar o resumo e o valor total. Com o Intraweb extremamente simples; basta acessar o contedo das variveis definidas no ServerController. Mas como ele faz isso? Uma mistura de cookies com persistncia. Com isso conclumos nosso primeiro exerccio e conhecemos alguns conceitos do Intraweb.

Segundo Exemplo (controles Standard 2. parte)


Vamos aproveitar o embalo do primeiro exemplo e conhecer alguns componentes do IW Standard. Atravs das opes File/New/Other..., selecione a seo Intraweb e escolha o modelo Stand Alone Application (figura 12.12).

Intraweb 249

Figura 12.12 Escolha do tipo da Aplicao Em seguida, selecione o diretrio de nossa segunda aplicao, em nosso caso (c:\cursoweb\intraweb\exercicio2). Grave toda a aplicao, e insira os componentes que seguem:

OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Segundo Exemplo 120 16

OBJETO TIWEdit Objeto edNome Propriedade Name Left MaxLength Top Width Valor edNome 72 30 56 225

250 Delphi 7 Internet e Banco de Dados

OBJETO TIWButton Objeto btConfirma Propriedade Name Caption Left Top Valor btConfirma Confirma 136 104

OBJETO TIWLabel Objeto lbMensagem Propriedade Name Caption Left Top Visible Valor lbMensagem deixe em branco 24 152 False

A figura 12.13 ilustra nosso formulrio.

Figura 12.13 Formulrio segundo exemplo Agora vamos codificar um pouco. Selecione o objeto btConfirma (boto) e insira o cdigo que segue, no evento OnClick. lbMensagem.Caption:='Seja bem vindo(a) '+edNome.Text; lbMensagem.Visible:=True; O mais interessante de tudo isso, que estamos colocando cdigo Object Pascal puro, ou melhor, Delphi Language como chamado agora.

Intraweb 251 Execute a aplicao, e seguindo o mesmo procedimento do primeiro exemplo, no Intraweb Server Application, pressione novamente a tecla F9. A figura 12.14 ilustra o resultado do nosso segundo exemplo.

Figura 12.14 Resultado segundo exemplo. Muito fcil, no ?

Listagem 12.4 Unit IWUnit1 (segundo exemplo)


unit IWUnit1; {PUBDIST} interface uses IWAppForm, IWApplication, IWTypes, IWCompEdit, Classes, Controls, IWControl, IWCompLabel, IWCompButton; type TformMain = class(TIWAppForm) IWLabel1: TIWLabel; edNome: TIWEdit; btConfirma: TIWButton; lbMensagem: TIWLabel; procedure btConfirmaClick(Sender: TObject); public end; implementation {$R *.dfm} uses ServerController; procedure TformMain.btConfirmaClick(Sender: TObject); begin lbMensagem.Caption:='Seja bem vindo(a) '+edNome.Text; lbMensagem.Visible:=true; end; end.

252 Delphi 7 Internet e Banco de Dados

Terceiro Exemplo (controles Standard 3. parte)


Agora que sabemos que o Intraweb trabalha com Delphi Language pura, vamos abusar um pouco da programao. Atravs das opes File/New/Other..., selecione a seo Intraweb e escolha o modelo Stand Alone Application (figura 12.15).

Figura 12.15 Escolha do tipo da Aplicao Em seguida, selecione o diretrio de nossa segunda aplicao, em nosso caso (c:\cursoweb\intraweb\exercicio3). Insira a unit SysUtils, na clusula uses da aplicao, para que possamos fazer algumas operaes. Grave toda a aplicao, e insira os componentes que seguem:

OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Terceiro Exemplo 112 16

OBJETO TIWHRule Objeto IWHRule1 Propriedade Left Top Width Valor 56 40 225

Intraweb 253

OBJETO TIWLabel Objeto IWLabel2 Propriedade Name Caption Left Top OBJETO TIWEdit Objeto edN1 Propriedade Name Left Text Top Valor edN1 56 (deixe em branco) 80 Valor IWLabel2 Insira dois nmeros e selecione a operao 56 56

OBJETO TIWEdit Objeto edN2 Propriedade Name Left Text Top Valor edN2 56 (deixe em branco) 112

OBJETO TIWHRule Objeto IWHRule1 Propriedade Left Top Width Valor 56 144 73

254 Delphi 7 Internet e Banco de Dados

OBJETO TIWEdit Objeto edTotal Propriedade Name Left Text Top Valor edTotal 56 (deixe em branco) 152

OBJETO TIWButton Objeto btAdicao Propriedade Name Caption Left Tag Width Valor btAdicao + 144 1 25

importante >>> OBJETO

TIWButton Objeto btSubtracao Propriedade Name Caption Left Tag Width Valor btSubtracao 176 2 25

importante >>> OBJETO

TIWButton Objeto btMultiplicacao Propriedade Name Caption Left Tag Width Valor btMultiplicacao x 208 3 25

importante >>>

Intraweb 255

OBJETO TIWButton Objeto btDivisao Propriedade Name Caption Left Tag Width Valor btDivisao : 240 4 25

importante >>>
A figura 12.16 ilustra nosso formulrio.

Figura 12.16 Formulrio terceiro exemplo Agora vamos codificar o boto btAdicao. No evento OnClick do boto, insira o cdigo que segue: var n1,n2,total:single; operacao:integer; begin try n1:=StrtoFloat(edN1.Text); n2:=StrtoFloat(edN2.Text); total:=0; operacao:=(Sender as TIWButton).Tag; case operacao of 1:total:=n1+n2; 2:total:=n1-n2; 3:total:=n1*n2; 4:total:=n1/n2; end;

256 Delphi 7 Internet e Banco de Dados edTotal.Text:=FloatToStr(total); except on EZeroDivide do WebApplication.ShowMessage('Diviso por zero !'); on EOverFlow do WebApplication.ShowMessage('Aconteceu OverFlow !'); // end; Antes de analisar o cdigo, selecione os demais botes e associe o cdigo do evento OnClick, como ilustra a figura 12.17.

Figura 12.17 Associao do evento OnClick aos demais botes. Vamos analisar o cdigo. var n1,n2,total:single; operacao:integer; Neste primeiro bloco estamos declarando variveis para execuo da operao matemtica (n1, n2 e total), bem como uma varivel auxiliar (operao) com o intuito de associar o boto que est chamando o evento. Em cada boto, definimos valores diferentes para a propriedade TAG, que ser facilmente assimilada por nossa aplicao. try n1:=StrtoFloat(edN1.Text); n2:=StrtoFloat(edN2.Text); total:=0; operacao:=(Sender as TIWButton).Tag; Em seguida, iniciamos um bloco protegido (try) e convertemos o contedo dos campos de edio edN1 e edN2, para o tipo float. Neste mesmo bloco estamos iniciando a varivel total e atribuindo varivel operacao, o valor contido na propriedade TAG de um objeto do tipo TIWButton, que em nosso caso, so representadas pelos botes btAdicao, btSubtracao, btMultiplicacao e btDivisao. case operacao of 1:total:=n1+n2; 2:total:=n1-n2; 3:total:=n1*n2; 4:total:=n1/n2; end; Neste bloco, fazemos as devidas operaes de acordo com o boto pressionado. edTotal.Text:=FloatToStr(total);

Intraweb 257 Em seguida, atribumos ao objeto edTotal o resultado da operao. except on EZeroDivide do WebApplication.ShowMessage('Diviso por zero !'); on EOverFlow do WebApplication.ShowMessage('Aconteceu OverFlow !'); // end; Por fim, tratamos duas excees: EZeroDivide (diviso por zero), e EOverFlow (Overflow na operao). Repare que em caso de erro, estamos apresentando mensagens ao usurio. muito parecido com o famoso Application.ShowMessage. Neste caso, utilizamos o WebApplication.ShowMessage. As figuras 12.18, 12.19 e 12.20 ilustram nossa aplicao em tempo de execuo.

Figura 12.18 Operao de adio A figura 12.18 ilustra o sucesso da operao de adio. Em seguida temos nossa primeira mensagem de erro. A figura 12.19 ilustra um erro de diviso por zero.

Figura 12.19 Diviso por zero Em seguida temos um erro de OverFlow (figura 12.20).

258 Delphi 7 Internet e Banco de Dados

Figura 12.20 Overflow

Listagem 12.5 Unit IWUnit1.pas (exemplo 3)


unit IWUnit1; {PUBDIST} interface uses IWAppForm, IWApplication, IWTypes, IWHTMLControls, Classes, Controls, IWControl, IWCompLabel, IWCompEdit, IWCompButton, SysUtils; type TformMain = class(TIWAppForm) IWLabel1: TIWLabel; IWHRule1: TIWHRule; edN1: TIWEdit; edN2: TIWEdit; btAdicao: TIWButton; btSubtracao: TIWButton; btMultiplicacao: TIWButton; btDivisao: TIWButton; IWLabel2: TIWLabel; edTotal: TIWEdit; IWHRule2: TIWHRule; procedure btAdicaoClick(Sender: TObject); public end; implementation {$R *.dfm} uses ServerController; procedure TformMain.btAdicaoClick(Sender: TObject); var n1,n2,total:single; operacao:integer;

Intraweb 259

begin try n1:=StrtoFloat(edN1.Text); n2:=StrtoFloat(edN2.Text); total:=0; operacao:=(Sender as TIWButton).Tag; case operacao of 1:total:=n1+n2; 2:total:=n1-n2; 3:total:=n1*n2; 4:total:=n1/n2; end; edTotal.Text:=FloatToStr(total); except on EZeroDivide do WebApplication.ShowMessage('Diviso por zero !'); on EOverFlow do WebApplication.ShowMessage('Aconteceu OverFlow !'); // end; end; end.

Quarto Exemplo (controles Standard 4. parte)


No quarto exemplo, vamos desenvolver uma rotina para uploads de arquivos. Como disse anteriormente, este processo era muito trabalhoso com o Web-Broker e agora ficou muito mais fcil. Com pouqussimas linhas de cdigo, na realidade apenas uma linha faz o servio, mas em nosso caso faremos um tratamento de erro. Vamos desenvolver tal rotina. Atravs das opes File/New/Other..., selecione a seo Intraweb e escolha o modelo Stand Alone Application (figura 12.21).

Figura 12.21 Escolha do tipo da Aplicao Em seguida, selecione o diretrio de nossa segunda aplicao, em nosso caso (c:\cursoweb\intraweb\exercicio4). Grave toda a aplicao, e insira os componentes que seguem:

260 Delphi 7 Internet e Banco de Dados

OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Quarto Exemplo 112 16

OBJETO TIWLabel Objeto IWLabel2 Propriedade Name Caption Left Top OBJETO TIWLabel Objeto lbMensagem Propriedade Name Caption Left Top Font.Color Valor lbMensagem Mensagem 32 168 clRed Valor IWLabel2 Selecione o arquivo para UpLoad 32 48

OBJETO TIWFile1 Objeto IWFile1 Propriedade Name Left Top Width Valor IWFile1 32 72 200

Intraweb 261

OBJETO TIWButton1 Objeto IWButton1 Propriedade Name Caption Left Top Width Valor IWButton1 UpLoad 32 104 75

A figura 12.22 ilustra o nosso formulrio.

Figura 12.22 Formulrio para UpLoad Agora vamos codificar a rotina de UpLoad. No evento OnClick do objeto IWButton1, coloque o cdigo que segue: try IWFile1.SaveToFile(ExtractFilePath(ParamStr(0)) + IWFile1.FileName); lbMensagem.Caption:='O arquivo'+IWFile1.Filename+' foi gravado no diretrio '+#13#10+ ExtractFilePath(ParamStr(0))+' com xito'; lbMensagem.Visible := True; except lbMensagem.Caption:='Houve um problema com a rotina de UPLOAD'; lbMensagem.Visible := True; end; Amigos, a linha em negrito (IWFile1,SaveToFile...), a nica linha necessria para fazer o UpLoad do arquivo. Em nosso caso estamos fazendo uma rotina de tratamento de erros e exibindo a mensagem do resultado da operao. Caso seja bem sucedida, apresenta o nome do arquivo e em qual diretrio foi gravado no servidor. Em caso de erro, apresenta apenas uma mensagem : Houve um problema.... A figura 12.23 ilustra nossa aplicao sendo executada.

262 Delphi 7 Internet e Banco de Dados

Figura 12.23 Arquivo sendo gravado no diretrio da aplicao. muito fcil, no ?

Dica
Voc poder configurar o diretrio que receber os arquivos. Normalmente numa Intranet, existe um servidor de arquivos, onde sua aplicao poder gravar as informaes provenientes da rotina de UpLoad. Veja o exemplo:

IWFile1.SaveToFile(F:\arquivos\+ IWFile1.FileName);

Listagem 12.6 IWUnit1.pas (Quarto Exemplo)


unit IWUnit1; {PUBDIST} interface uses IWAppForm, IWApplication, IWTypes, Classes, Controls, IWControl, IWCompLabel, IWCompEdit, SysUtils, IWCompButton; type TformMain = class(TIWAppForm) IWLabel1: TIWLabel; IWFile1: TIWFile; IWLabel2: TIWLabel; lbMensagem: TIWLabel; IWButton1: TIWButton; procedure IWButton1Click(Sender: TObject); public end; implementation {$R *.dfm}

Intraweb 263 uses ServerController; procedure TformMain.IWButton1Click(Sender: TObject); begin try IWFIle1.SaveToFile(ExtractFilePath(ParamStr(0)) + IWFile1.FileName); lbMensagem.Caption:='O arquivo'+IWFile1.Filename+' foi gravado no diretrio '+#13#10+ ExtractFilePath(ParamStr(0))+' com xito'; lbMensagem.Visible := True; except lbMensagem.Caption:='Houve um problema com a rotina de UPLOAD'; lbMensagem.Visible := True; end; end; end.

Quinto Exemplo (controles Standard 5. parte)


No quinto exemplo, vamos aprender a trabalhar com mltiplos formulrios. O conceito bem parecido com as aplicaes desktop, com criao e destruio de formulrios dinamicamente. Atravs das opes File/New/Other..., selecione a seo Intraweb e escolha o modelo Stand Alone Application (figura 12.24).

Figura 12.24 Escolha do tipo da Aplicao Em seguida, selecione o diretrio de nossa segunda aplicao, em nosso caso (c:\cursoweb\intraweb\exercicio5). Grave toda a aplicao, e insira os componentes que seguem:

OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Quinto Exemplo 112 16

264 Delphi 7 Internet e Banco de Dados

OBJETO TIWButton Objeto IWButton1 Propriedade Name Caption Left Top Width Valor IWButton1 Formulrio 2 120 56 115

OBJETO TIWButton Objeto IWButton2 Propriedade Name Caption Left Top Width Valor IWButton2 Formulrio 3 225 124 115

OBJETO TIWEdit1 Objeto edNome Propriedade Name Left Text Top Width Valor edNome 40 (deixe em branco) 126 175

Agora vamos criar um segundo formulrio. Atravs das opes File/New/Other..., selecione a seo Intraweb e escolha o modelo Application Form (figura 12.25).

Intraweb 265

Figura 12.25 Criando um novo formulrio Altere a propriedade Name do formulrio para Form2. Grave a unit com o nome un_formulrio2. Insira os componentes que seguem no Form2.

OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Formulrio 2 136 36

OBJETO TIWButton Objeto IWButton1 Propriedade Name Caption Left Top Width Valor IWButton1 Fecha 136 96 75

Vamos codificar este formulrio. No evento OnClick do objeto IWButton1, insira o seguinte cdigo Hide; No cdigo que acabamos de inserir, estamos escondendo o formulrio, e retornando origem. Para entender o funcionamento, vamos codificar o nosso formulrio principal.

266 Delphi 7 Internet e Banco de Dados Insira a unit un_formulario2 na clusula uses do formulrio principal. Agora vamos codificar o evento OnClick do objeto IWButton1 do formulrio principal. var Form2:TForm2; begin Form2 := TForm2.Create(WebApplication); Form2.Show; end; Estamos fazendo uma operao bastante simples. Primeiro declaramos uma varivel do tipo TForm2 (classe herdada da TForm2 que est contida na unit un_formulario2). var Form2:TForm2; Em seguida instanciamos o objeto. Form2 := TForm2.Create(WebApplication); E por fim, apresentamos o objeto. Form2.Show; As figuras 12.26 e 12.27 ilustram nossos dois primeiros formulrios.

Figura 12.26 Formulrio principal.

Intraweb 267

Figura 12.27 Formulrio 2 Vamos dar uma olhadinha no resultado desta primeira parte de nossa aplicao. Execute a aplicao e clique no boto que representa a chamada do primeiro formulrio. As figuras 12.28 e 12.29 ilustram o resultado da primeira parte de nossa aplicao.

Figura 12.28 Formulrio principal em ao

Figura 12.29 Formulrio 2 chamado atravs do formulrio principal

268 Delphi 7 Internet e Banco de Dados Agora vamos criar a segunda parte de nossa aplicao, fazendo uma interatividade entre os formulrios. Atravs das opes File/New/Other..., selecione a seo Intraweb e escolha o modelo Application Form (figura 12.30).

Figura 12.30 Criando um novo formulrio Altere a propriedade Name do formulrio para Form3. Grave a unit com o nome un_formulrio3. Insira os componentes que seguem no Form3.

OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Formulrio 3 136 36

OBJETO TIWLabel Objeto lbMensagem Propriedade Name Caption Left Top Valor lbMensagem Mensagem 32 72

Intraweb 269

OBJETO TIWButton Objeto IWButton1 Propriedade Name Caption Left Top Width Valor IWButton1 Fecha 128 120 75

Vamos codificar este formulrio. No evento OnClick do objeto IWButton1, insira o seguinte cdigo Hide; Voltando ao formulrio principal, coloque a unit un_formulario3 na clusula uses. Vamos codificar o boto IWButton2 do formulrio principal. Coloque o cdigo que segue no evento OnClick do boto. var Form3:TForm3; begin Form3 := TForm3.Create(WebApplication); Form3.lbMensagem.Caption:=edNome.Text+', seja bem-vindo(a)'; Form3.Show; end; Assim como na primeira fase da aplicao, declaramos uma varivel do tipo TForm3 (classe herdada da TForm3 que est contida na unit un_formulario3). var Form3:TForm3; Em seguida instanciamos o objeto. Form3 := TForm3.Create(WebApplication); E agora, que temos o controle total do objeto, estamos alterando a propriedade Caption do objeto lbMensagem. Form3.lbMensagem.Caption:=edNome.Text+', seja bem-vindo(a)'; E por fim, apresentamos o objeto. Form3.Show; As figuras 12.31 e 12.32 ilustram o resultado da segunda fase de nossa aplicao.

270 Delphi 7 Internet e Banco de Dados

Figura 12.31 Formulrio principal fazendo a chamada ao formulrio 3

Figura 12.32 Formulrio 3 em ao Este exemplo, embora bastante simples, demonstra a interatividade entre formulrios. Bastante comum em aplicaes Internet, tenho certeza que utilizaro muito este conceito.

Listagem 12.7 IWUnit1.pas (Quinto Exemplo, Form Principal)


unit IWUnit1; {PUBDIST} interface uses IWAppForm, IWApplication, IWTypes, IWCompEdit, IWCompLabel, Classes, Controls, IWControl, IWCompButton; type TformMain = class(TIWAppForm) IWButton1: TIWButton;

Intraweb 271 IWLabel1: TIWLabel; edNome: TIWEdit; IWLabel2: TIWLabel; IWButton2: TIWButton; procedure IWButton1Click(Sender: TObject); procedure IWButton2Click(Sender: TObject); public end; implementation {$R *.dfm} uses ServerController, un_formulario2, un_formulario3; procedure TformMain.IWButton1Click(Sender: TObject); var Form2:TForm2; begin Form2 := TForm2.Create(WebApplication); Form2.Show; end; procedure TformMain.IWButton2Click(Sender: TObject); var Form3:TForm3; begin Form3 := TForm3.Create(WebApplication); Form3.lbMensagem.Caption:=edNome.Text+', seja bem-vindo(a)'; Form3.Show; end; end.

Listagem 12.8 un_formulario2.ps


unit un_formulario2; {PUBDIST} interface uses IWAppForm, IWApplication, IWTypes, IWCompButton, Classes, Controls, IWControl, IWCompLabel; type TForm2 = class(TIWAppForm) IWLabel1: TIWLabel; IWButton1: TIWButton; procedure IWButton1Click(Sender: TObject); public end; implementation {$R *.dfm} uses

272 Delphi 7 Internet e Banco de Dados ServerController; procedure TForm2.IWButton1Click(Sender: TObject); begin Hide; end; end.

Listagem 12.9 un_formulario3.ps


unit un_formulario3; {PUBDIST} interface uses IWAppForm, IWApplication, IWTypes, IWCompButton, Classes, Controls, IWControl, IWCompLabel; type TForm3 = class(TIWAppForm) IWLabel1: TIWLabel; lbMensagem: TIWLabel; IWButton1: TIWButton; procedure IWButton1Click(Sender: TObject); public end; implementation {$R *.dfm} uses ServerController; procedure TForm3.IWButton1Click(Sender: TObject); begin Hide; end; end.

Sexto Exemplo (primeiro com banco de dados)


Amigos, agora chegou a hora boa: trabalhar com banco de dados e Internet. J desenvolvemos nossas aplicaes com banco de dados para Internet com outras tecnologias (Web-Broker e Websnap) e agora teremos o prazer de utilizar o Intraweb. Atravs das opes File/New/Other..., selecione a seo Intraweb e escolha o modelo Stand Alone Application with Data Module (figura 12.33).

Intraweb 273

Figura 12.33 Iniciando a aplicao A nica diferena na opo with Data Module, justamente a criao automtica de um Data Module, bem como suas referncias. Insira um objeto do tipo TSQLConnection, e atravs do duplo-clique, j na tela de configurao, aponte para a nossa conexo Clientes, criada anteriormente. Vamos relembrar os atributos da conexo. PROPRIEDADE VALOR

CommitRetain Database Password UserName Name

False localhost:c:\cursoweb\clientes.gdb a famosa masterkey o famoso SYSDBA ConexaoBD

Altere tambm a propriedade LoginPrompt para false. Nunca esquea de fazer esta alterao, pois numa aplicao servidora, no existe a possibilidade do usurio interagir no login do banco de dados.

274 Delphi 7 Internet e Banco de Dados

Figura 10.34 Configurao da Conexo Agora vamos inserir o objeto para manipular nossa tabela de clientes. Insira um objeto do tipo TSQLDataSet e altere as seguintes propriedades: PROPRIEDADE VALOR

SQLConnection CommandText Active

ConexaoBD select * from TBCLIENTE True

timo, agora vamos para o formulrio principal. Insira a unit DataModuleUnit na clusula uses, e grave a aplicao. Insira os componentes que seguem.

OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Sexto Exemplo 128 208

Intraweb 275

OBJETO TDataSource [DataAccess] Objeto DataSource1 OBJETO TIWDBGrid Objeto IWDBGrid1 Propriedade Name Align DataSource Valor IWDBGRID1 alTop DataSource1 Propriedade Name DataSet Valor DataSource1 DataModule1.SQLDataSet1

A figura 12.35 ilustra nosso formulrio principal.

Figura 12.35 Formulrio principal No colocamos nenhum cdigo nesta aplicao. Assim como em aplicaes desktop, apenas associamos os objetos. Vamos executar a aplicao e ver o resultado (figura 12.36).

276 Delphi 7 Internet e Banco de Dados

Figura 12.36 Sexto exemplo em execuo Demonstrei neste exemplo uma forma simples de disponibilizar informaes de banco de dados na Internet. O grande momento deste exemplo foi justamente a simplicidade e a semelhana com o mtodo tradicional de desenvolvimento. No prximo tpico vamos desenvolver uma aplicao completa, a mesma que desenvolvemos no Captulo 7.

Listagem 12.10 IWUnit1.pas (Form principal)


unit IWUnit1; {PUBDIST} interface uses IWAppForm, IWApplication, IWTypes, Classes, Controls, IWControl, IWGrids, IWDBGrids, DB, IWDBStdCtrls, IWClientSideDatasetBase, IWClientSideDatasetDBLink, IWCompLabel; type TformMain = class(TIWAppForm) IWDBGrid1: TIWDBGrid; DataSource1: TDataSource; IWLabel1: TIWLabel; public end; implementation {$R *.dfm} uses ServerController, DataModuleUnit; end.

Listagem 12.11 unit DataModuleUnit.pas


unit DatamoduleUnit;

Intraweb 277

interface uses {$IFDEF Linux}QForms, {$ELSE}Forms, {$ENDIF} SysUtils, Classes, DBXpress, FMTBcd, DB, SqlExpr; type TDataModule1 = class(TDataModule) SQLConnection1: TSQLConnection; SQLDataSet1: TSQLDataSet; private public end; // Procs function DataModule1: TDataModule1; implementation {$R *.dfm} uses IWInit, ServerController; // Since we are threaded we cannot use global variables to store form / datamodule references // so we store them in WebApplication.Data and we could reference that each time, but by creating // a function like this our other code looks "normal" almost as if its referencing a global. // This function is not necessary but it makes the code in the main form which references this // datamodule a lot neater. // Without this function ever time we would reference this datamodule we would use: // TDataModule1(WebApplication.Data).Datamodule.<method / component> // By creating this procedure it becomes: // TDataModule1.<method / component> // Which is just like normal Delphi code. function DataModule1: TDataModule1; begin Result := TUserSession(RWebApplication.Data).Datamodule1; end; end.

Cadastro de Clientes
Agora iremos desenvolver uma aplicao parecida com a do Captulo 7, onde faremos um cadastro de clientes com as principais operaes. Atravs das opes File/New/Other..., selecione a seo Intraweb e escolha o modelo Stand Alone Application with Data Module (figura 12.37).

278 Delphi 7 Internet e Banco de Dados

Definies iniciais

Figura 12.37 Iniciando a aplicao Selecione o DataModule e insira um objeto do tipo TSQLConnection. Atravs do duplo-clique, j na tela de configurao, aponte para a nossa conexo Clientes, criada anteriormente. Vamos relembrar os atributos da conexo. PROPRIEDADE VALOR

CommitRetain Database Password UserName Name

False localhost:c:\cursoweb\clientes.gdb a famosa masterkey o famoso SYSDBA ConexaoBD

Altere tambm a propriedade LoginPrompt para false. Nunca esquea de fazer esta alterao, pois numa aplicao servidora, no existe a possibilidade do usurio interagir no login do banco de dados.

Intraweb 279

Figura 10.38 Configurao da Conexo Agora vamos inserir o objeto para manipular nossa tabela de clientes. Insira um objeto do tipo TSQLDataSet, e altere as seguintes propriedades: PROPRIEDADE SQLConnection CommandText Active VALOR ConexaoBD select * from TBCLIENTE True

Objeto de Incluso
Insira um objeto do tipo TSQLQuery e altere as propriedades que seguem.

280 Delphi 7 Internet e Banco de Dados

OBJETO TSQLQuery Objeto SQLInclui Propriedade Valor Name SQLInclui SQLConnection ConexaoBD SQL INSERT INTO TBCLIENTE VALUES(0,:prazao, :pendereco,:pcidade, :pestado,:pcep,:pemail)

Na propriedade PARAMS do SQLInclui altere os tipos dos parmetros para String.

Objeto de Alterao
Insira um objeto do tipo TSQLQuery e altere as propriedades que seguem.

OBJETO TSQLQuery Objeto SQLAltera Propriedade Valor Name SQLAltera SQLConnection BancoDados SQL UPDATE TBCLIENTE SET RAZAO_SOCIAL=:prazao, ENDERECO=:pendereco, CIDADE=:pcidade, ESTADO=:pestado, CEP=:pcep, EMAIL=:pemail WHERE COD_CLIENTE=:pcodigo

Na propriedade PARAMS do SQLAltera altere os tipos dos parmetros para String, com exceo do parmetro PCODIGO, que deve ser Integer.

Objeto de Excluso
Insira um objeto do tipo TSQLQuery e altere as propriedades que seguem.

Intraweb 281

OBJETO TSQLQuery Objeto SQLExclui Propriedade Valor Name SQLExclui SQLConnection BancoDados SQL DELETE FROM TBCLIENTE WHERE COD_CLIENTE=:pcodigo

Na propriedade PARAMS do SQLExclui altere o tipo do parmetro para Integer.

Criando o Formulrio Principal


No formulrio principal (FormMain), adicione um componente do tipo TMainMenu (que utilizamos habitualmente), e configure as opes como segue: Arquivo Incluso Clientes Manuteno/Consulta Finaliza A figura 12.39 ilustra o nosso menu principal. Sobre Informaes...

Figura 12.39 Menu Principal Insira um objeto do tipo TIWMenu (seo IW Standard) e altere a propriedade Attached Menu para MainMenu1. Na realidade estamos vinculando nosso objeto MainMenu1 com o IWMenu1 do Intraweb. Configure a propriedade BackGroundColor do objeto FormMain para $00DDFFFF. Amigos, isto apenas uma sugesto de cor. Insira os componentes que seguem no FormMain.

282 Delphi 7 Internet e Banco de Dados

OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Cadastro de Clientes 136 80

OBJETO TIWImage Objeto IWImage1 Propriedade Name Left Picture Top


A figura 12.40 ilustra o nosso formulrio principal.

Valor IWImmage1 168 insira uma figura qualquer, exemplo: logo.jpg 120

Figura 12.40 Formulrio principal Agora iremos codificar duas opes do menu principal: Finaliza e Informaes/Sobre. Selecione a opo Finaliza no objeto MainMenu1 e insira o cdigo que segue no evento OnClick. WebApplication.Terminate('At logo !'); Neste evento estamos finalizando a aplicao e apresentando a mensagem At Logo!, ao usurio. Agora selecione a opo Informaes/.Sobre e insira o cdigo que segue.

Intraweb 283 WebApplication.ShowMessage('Cadastro de Clientes' +#13#10+ 'Verso 1.0',smAlert); Neste evento apresentamos uma janela de dilogo ao usurio, com as informaes da aplicao. Bastante simples, no?

Criando o Formulrio de Incluso


Atravs das opes File/New/Other..., selecione a seo Intraweb e escolha o modelo Application Form (figura 12.41).

Figura 12.41 Criando um novo formulrio Altere a propriedade Name do formulrio para FmInclusao e BackGroundColor para $00DDFFFF. . Grave a unit com o nome un_inclusao. Insira os componentes que seguem no FmInclusao..

OBJETO TIWRectangle Objeto IWRectangle1 Propriedade Name Align Color Font.Color Font.Size Font.Style.fsBold Text Valor IWRectangle1 alTop clNavy clWhite 16 True Cadastro de Clientes (Incluso)

284 Delphi 7 Internet e Banco de Dados

OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Razo Social 24 88

OBJETO TIWLabel Objeto IWLabel2 Propriedade Name Caption Left Top Valor IWLabel2 Endereo 24 120

OBJETO TIWLabel Objeto IWLabel3 Propriedade Name Caption Left Top Valor IWLabel3 Cidade 24 152

OBJETO TIWLabel Objeto IWLabel4 Propriedade Name Caption Left Top Valor IWLabel4 UF 328 152

Intraweb 285

OBJETO TIWLabel Objeto IWLabel5 Propriedade Name Caption Left Top Valor IWLabel5 CEP 448 152

OBJETO TIWLabel Objeto IWLabel6 Propriedade Name Caption Left Top Valor IWLabel6 e-Mail 24 184

OBJETO TIWEdit Objeto edRazao Propriedade Name BgColor Height Left Text Top Width Valor edRazao clYellow 21 128 deixar em branco 88 450

OBJETO TIWEdit Objeto edEndereco Propriedade Name BgColor Height Left Text Top Width Valor edEndereco clYellow 21 128 deixar em branco 120 450

286 Delphi 7 Internet e Banco de Dados

OBJETO TIWEdit Objeto edCidade Propriedade Name BgColor Height Left Text Top Width Valor edCidade clYellow 21 128 deixar em branco 152 185

OBJETO TIWComboBox Objeto edUF Propriedade Name Height Left Items Sorted Top Width OBJETO TIWEdit Objeto edCEP Propriedade Name BgColor Height Left Text Top Width Valor edCEP clYellow 21 488 deixar em branco 152 90 Valor edUF 21 360 Insira a sigla de todos os estados brasileiros True 152 65

Intraweb 287

OBJETO TIWEdit Objeto edEmail Propriedade Name BgColor Height Left Text Top Width Valor edEmail clYellow 21 128 deixar em branco 184 450

OBJETO TIWButton1 Objeto btConfirma Propriedade Name Caption Height Left Top Width Valor btConfirma Confirma 25 128 232 75

OBJETO TIWButton1 Objeto btDesiste Propriedade Name Caption Height Left Top Width Valor btDesiste Desiste 25 216 232 75

Agora vamos codificar o formulrio. Insira a unit DataModuleUnit na clusula uses do formulrio. uses ServerController, DatamoduleUnit; No evento OnClick do objeto btDesiste insira o cdigo que segue: Hide; Para que possamos retornar ao formulrio de origem, utilizamos o mtodo Hide do formulrio. Agora vamos codificar o evento OnClick do objeto btConfirma.

288 Delphi 7 Internet e Banco de Dados try {Inclui Cliente} with DataModule1.SQLInclui do begin ParamByName('prazao').Value:=edRazao.Text; ParamByName('pendereco').Value:=edEndereco.Text; ParamByName('pcidade').Value:=edCidade.Text; ParamByName('pestado').Value:=edUf.Items[edUf.ItemIndex]; ParamByName('pcep').Value:=edCep.Text; ParamByName('pemail').Value:=edEmail.Text; ExecSQL; end; WebApplication.ShowMessage('Cliente incluido com sucesso',smSameWindow); except WebApplication.ShowMessage('Houve smSameWindow); end; Hide; um problema na incluso do cliente',

Vamos analisar o cdigo. Nesta primeira parte, iniciamos um bloco protegido. try Em seguida, estamos atribuindo parmetros ao objeto SQLInclui do DataModule1. {Inclui Cliente} with DataModule1.SQLInclui do begin ParamByName('prazao').Value:=edRazao.Text; ParamByName('pendereco').Value:=edEndereco.Text; ParamByName('pcidade').Value:=edCidade.Text; ParamByName('pestado').Value:=edUf.Items[edUf.ItemIndex]; ParamByName('pcep').Value:=edCep.Text; ParamByName('pemail').Value:=edEmail.Text; E, finalmente, executando a operao e apresentando a mensagem de sucesso na opero. ExecSQL; WebApplication.ShowMessage('Cliente incluido com sucesso',smSameWindow); Em caso de erro, estamos criando o bloco except. except WebApplication.ShowMessage('Houve smSameWindow); end; um problema na incluso do cliente',

E apresentando a mensagem do problema. A figura 12.42 ilustra o nosso formulrio de incluso de clientes.

Intraweb 289

Figura 12.42 Formulrio incluso de clientes

Criando o Formulrio de Alterao


Atravs das opes File/New/Other..., selecione a seo Intraweb e escolha o modelo Application Form (figura 12.43).

Figura 12.43 Criando um novo formulrio Altere a propriedade Name do formulrio para FmAltera e BackGroundColor para $00DDFFFF. Grave a unit com o nome un_alteracao. Insira os componentes que seguem no FmAltera.

290 Delphi 7 Internet e Banco de Dados

OBJETO TIWRectangle Objeto IWRectangle1 Propriedade Name Align Color Font.Color Font.Size Font.Style.fsBold Text Valor IWRectangle1 alTop clNavy clWhite 16 True Cadastro de Clientes (Alterao)

OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Razo Social 24 88

OBJETO TIWLabel Objeto IWLabel2 Propriedade Name Caption Left Top Valor IWLabel2 Endereo 24 120

OBJETO TIWLabel Objeto IWLabel3 Propriedade Name Caption Left Top Valor IWLabel3 Cidade 24 152

Intraweb 291

OBJETO TIWLabel Objeto IWLabel4 Propriedade Name Caption Left Top Valor IWLabel4 UF 328 152

OBJETO TIWLabel Objeto IWLabel5 Propriedade Name Caption Left Top Valor IWLabel5 CEP 448 152

OBJETO TIWLabel Objeto IWLabel6 Propriedade Name Caption Left Top Valor IWLabel6 e-Mail 24 184

OBJETO TIWLabel Objeto IWLabel7 Propriedade Name Caption Left Top Valor IWLabel7 Cdigo Cliente 24 56

OBJETO TIWLabel Objeto lbCodigo Propriedade Name Caption Left Top Valor lbCodigo cdigo 144 56

292 Delphi 7 Internet e Banco de Dados

OBJETO TIWEdit Objeto edRazao Propriedade Name BgColor Height Left Text Top Width Valor edRazao clYellow 21 128 deixar em branco 88 450

OBJETO TIWEdit Objeto edEndereco Propriedade Name BgColor Height Left Text Top Width Valor edEndereco clYellow 21 128 deixar em branco 120 450

OBJETO TIWEdit Objeto edCidade Propriedade Name BgColor Height Left Text Top Width Valor edCidade clYellow 21 128 deixar em branco 152 185

Intraweb 293

OBJETO TIWComboBox Objeto edUF Propriedade Name Height Left Items Sorted Top Width OBJETO TIWEdit Objeto edCEP Propriedade Name BgColor Height Left Text Top Width Valor edCEP clYellow 21 488 deixar em branco 152 90 Valor edUF 21 360 Insira a sigla de todos os estados brasileiros True 152 65

OBJETO TIWEdit Objeto edEmail Propriedade Name BgColor Height Left Text Top Width Valor edEmail clYellow 21 128 deixar em branco 184 450

294 Delphi 7 Internet e Banco de Dados

OBJETO TIWButton1 Objeto btConfirma Propriedade Name Caption Height Left Top Width Valor btConfirma Confirma 25 128 232 75

OBJETO TIWButton1 Objeto btDesiste Propriedade Name Caption Height Left Top Width Valor btDesiste Desiste 25 216 232 75

Agora vamos codificar o formulrio. Insira a unit DataModuleUnit na clusula uses do formulrio. uses ServerController, DatamoduleUnit; No evento OnClick do objeto btDesiste insira o cdigo que segue: Hide; Para que possamos retornar ao formulrio de origem, utilizamos o mtodo Hide do formulrio. Agora vamos codificar o evento OnClick do objeto btConfirma. try {Altera Cliente} with DataModule1.SQLAltera do begin ParamByName('pcodigo').Value:=StrtoInt(lbCodigo.Text); ParamByName('prazao').Value:=edRazao.Text; ParamByName('pendereco').Value:=edEndereco.Text; ParamByName('pcidade').Value:=edCidade.Text; ParamByName('pestado').Value:=edUf.Items[edUf.ItemIndex]; ParamByName('pcep').Value:=edCep.Text; ParamByName('pemail').Value:=edEmail.Text; ExecSQL; end; WebApplication.ShowMessage('Cliente alterado com sucesso',smSameWindow);

Intraweb 295

except WebApplication.ShowMessage('Houve smSameWindow); end; Hide;

um

problema

na

alterao

do

cliente',

Vamos analisar o cdigo. Nesta primeira parte, iniciamos um bloco protegido. try Em seguida, estamos atribuindo parmetros ao objeto SQLAltera do DataModule1. {Inclui Cliente} with DataModule1.SQLAltera do begin ParamByName('pcodigo').Value:=StrtoInt(lbCodigo.Text); ParamByName('prazao').Value:=edRazao.Text; ParamByName('pendereco').Value:=edEndereco.Text; ParamByName('pcidade').Value:=edCidade.Text; ParamByName('pestado').Value:=edUf.Items[edUf.ItemIndex]; ParamByName('pcep').Value:=edCep.Text; ParamByName('pemail').Value:=edEmail.Text; E finalmente executando a operao e apresentando a mensagem de sucesso na opero. ExecSQL; WebApplication.ShowMessage('Cliente incluido com sucesso',smSameWindow); Em caso de erro, estamos criando o bloco except. except WebApplication.ShowMessage('Houve smSameWindow); end; E apresentando a mensagem do problema. Embora o Intraweb fornea objeto com conexo direta a DataSets, estamos utilizando os objetos convencionais, sem nenhum vnculo com DataSet. Quando trabalhamos com Internet, complicado disponibilizar objeto de conexo direta com DataSets, justamente porque no sabemos o que poder ocorrer com a conexo. Sugiro adotar este modelo de desenvolvimento pela segurana. Ento, para que nossos campos sejam preenchidos automaticamente com as informaes do banco de dados, vamos utilizar o TDataSource e TSQLDataSet. um problema na incluso do cliente',

296 Delphi 7 Internet e Banco de Dados

OBJETO TSQLDataSet Objeto SQLDataSet1 Propriedade Name SQLConnection CommandText Valor SQLDataSet1 DataModule1.ConexaoBD select * from TBCLIENTE WHERE COD_CLIENTE=:pCodigo Query

CommandType
Defina o parmetro pCodigo como Integer.

OBJETO TDataSource Objeto DataSource1 Propriedade Name DataSet Valor DataSource SQLDataSet1

Pronto, agora conclumos o nosso formulrio de alterao de clientes. A figura 12.44 ilustra o nosso formulrio.

Figura 12.44 Formulrio alterao de clientes

Criando o Formulrio de Manuteno


Atravs das opes File/New/Other..., selecione a seo Intraweb e escolha o modelo Application Form (figura 12.45).

Intraweb 297

Figura 12.45 Criando um novo formulrio Altere a propriedade Name do formulrio para FmManutencao e BackGroundColor para $00DDFFFF. . Grave a unit com o nome un_manutencao. Insira os componentes que seguem no FmManutencao..

OBJETO TIWRectangle Objeto IWRectangle1 Propriedade Name Align Color Font.Color Font.Size Font.Style.fsBold Text Valor IWRectangle1 alTop clNavy clWhite 16 True Cadastro de Clientes (Manuteno)

OBJETO TIWRegion1 Objeto IWRegion1 Propriedade Name Align Color Height Valor IWRegion1 alTop clWhite 56

Com o foco no objeto IWRegion1, insira os componentes que seguem.

298 Delphi 7 Internet e Banco de Dados

OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Razo Social 16 16

OBJETO TIWEdit Objeto edPesquisa Propriedade Name BgColor Height Left Text Top Width Valor edPesquisa clYellow 21 112 deixar em branco 16 175

OBJETO TIWButton Objeto btPesquisa Propriedade Name Caption Height Left Top Width Valor btPesquisa Confirma 25 296 16 75

OBJETO TIWButton Objeto btVolta Propriedade Name Caption Height Left Top Width Valor btVolta Menu Principal 25 384 16 122

Intraweb 299 Em nosso formulrio iremos utilizar objetos de acesso a dados. Insira um objeto do tipo TDataSource e outro do tipo TSQLQuery (dbExpress), configurando as propriedades que seguem.

OBJETO TSQLQuery Objeto SQLPesquisa Propriedade Name SQLConnection SQL OBJETO TDataSource Objeto DS1 Propriedade Name DataSet Valor DS1 SQLPesquisa Valor SQLPesquisa DataModule1.ConexaoBD select * from TBCLIENTE

Repare que estamos colocando o comando SELECT * na propriedade SQL do objeto SQLPesquisa. Fazemos isso apenas para nos auxiliar na montagem do Grid. Com o foco no formulrio, insira um objeto do tipo TIWDBGrid e altere as propriedades que seguem.

OBJETO TIWDBGrid Objeto IWDbGrid1 Propriedade Name DataSource Rollover RollOverColor Valor IWDbGrid1 DS1 True $00E1FFE1

Atravs do duplo-clique na propriedade Columns, insira os campos conforme a figura 12.46.

Figura 12.46 Campos do grid.

300 Delphi 7 Internet e Banco de Dados

Curiosidade
Repare que estamos repetindo o campo COD_CLIENTE diversas vezes. Fazemos isto para substituir os mtodos de chamada de operaes, devido a um BUG no Intraweb. At a verso 5.51 (que vem junto com o D7), o BUG de vnculo com controles (Control) ainda no estava corrigido. Existe uma maneira de associar um objeto, como por exemplo, um boto, a um evento do Grid. Iramos fazer isso para disparar as rotinas de alterao e excluso, mas infelizmente, devido ao BUG, estamos substituindo por outro mtodo.

Vamos configurar as colunas inseridas.

Coluna [ 0 ] Cod_Cliente Objeto Propriedade IWDbGrid1>Columns[0] DataField LinkField Title.Text Coluna [ 1 ] Razao_Social Objeto Propriedade IWDbGrid1>Columns[1] DataField Title.Text Coluna [ 2 ] EMAIL Objeto IWDbGrid1>Columns[2] Propriedade DataField Title.Text Coluna [ 3 ] Cod_Cliente Objeto Propriedade IWDbGrid1>Columns[3] DataField LinkField Title.Text Coluna [ 4 ] Cod_Cliente Objeto Propriedade IWDbGrid1>Columns[4] DataField LinkField Title.Text

Valor Cod_Cliente Cod_Cliente Cdigo Valor Razao_Social Razo Social Valor email e-Mail Valor Cod_Cliente Cod_Cliente Altera Valor Cod_Cliente Cod_Cliente Exclui

Agora vamos codificar o nosso formulrio. Na clusula uses insira as seguintes units. uses ServerController, DataModuleUnit, un_alteracao;

Intraweb 301 Em seguida devemos criar uma procedure pblica para auxiliar no posicionamento do registro, de maneira que possamos atribuir o contedo do banco de dados, aos campos do formulrio fmAltera. Defina a procedure LOCALIZA, como segue. public procedure Localiza(Cliente: integer); E na seo implementation, insira o cdigo a seguir. procedure Tfmmanutencao.Localiza(Cliente:integer); begin SQLPesquisa.Locate('cod_cliente', Cliente, []); end; Neste cdigo estamos apenas posicionando o ponteiro do registro de acordo com a seleo do usurio. Agora vamos codificar o objeto btPesquisa. Insira o cdigo que segue no evento OnClick. SQLPesquisa.SQL.Clear; SQLPesquisa.SQL.Add('SELECT * FROM '+''''+'%'+edPesquisa.Text+'%'+''''); SQLPesquisa.Open; TBCLIENTE WHERE RAZAO_SOCIAL LIKE

Neste cdigo estamos preparando uma consulta SQL, baseada na informao do usurio, extrada do objeto edPesquisa. As informaes so apresentadas no Grid, devido ao vnculo com o objeto. Coloque o cdigo a seguir, no evento OnClick do objeto btVolta. Hide; Agora vamos codificar a operao de alterao do Grid. Atravs da propriedade Columns do IWDBGrid1, selecione a coluna 3 (Altera) e insira o cdigo que segue no evento OnClick. var fmAltera:TfmAltera; begin fmAltera:=TFmAltera.Create(WebApplication); {Atribui o cdigo a Query} with fmAltera do begin FmAltera.SQLDataSet1.Params[0].Value:=StrtoInt(AValue); fmAltera.SQLDataSet1.Open; edRazao.Text:=SQLDataSet1RAZAO_SOCIAL.AsString; edEndereco.Text:=SQLDataSet1ENDERECO.AsString; edCidade.Text:=SQLDataSet1CIDADE.AsString; edCEP.Text:=SQLDataSet1CEP.AsString; edUF.ItemIndex:=edUF.Items.IndexOf( QLDataSet1ESTADO.AsString); edEmail.Text:=SQLDataSet1EMAIL.AsString; {Atribui os valores} fmAltera.lbCodigo.Caption:=Avalue; fmAltera.Show; end; Vamos analisar o cdigo. No bloco a seguir, estamos definindo um objeto do tipo TfmAltera, para que possamos manipular o objeto. var

302 Delphi 7 Internet e Banco de Dados fmAltera:TfmAltera; No bloco que segue, instanciamos o objeto FmAltera. begin fmAltera:=TFmAltera.Create(WebApplication); Em seguida atribumos o cdigo do cliente, extrado da varivel AValue (constante da procedure), ao objeto SQLDataSet1. with fmAltera do begin FmAltera.SQLDataSet1.Params[0].Value:=StrtoInt(AValue); fmAltera.SQLDataSet1.Open; O bloco a seguir atribui as informaes do SQLDataSet1 aos campos do objeto fmAltera, apresentando o formulrio de alterao de clientes. edRazao.Text:=SQLDataSet1RAZAO_SOCIAL.AsString; edEndereco.Text:=SQLDataSet1ENDERECO.AsString; edCidade.Text:=SQLDataSet1CIDADE.AsString; edCEP.Text:=SQLDataSet1CEP.AsString; edUF.ItemIndex:=edUF.Items.IndexOf( QLDataSet1ESTADO.AsString); edEmail.Text:=SQLDataSet1EMAIL.AsString; {Atribui os valores} fmAltera.lbCodigo.Caption:=Avalue; fmAltera.Show; Agora vamos codificar a operao de excluso do Grid. Atravs da propriedade Columns do IWDBGrid1, selecione a coluna 4 (Exclui) e insira o cdigo que segue no evento OnClick. try with DataModule1.SQLExclui do begin ParamByName('pcodigo').Value:=StrtoInt(AValue); ExecSQL; end; WebApplication.ShowMessage('Cliente Excluido com sucesso',smSameWindow); except WebApplication.ShowMessage('Houve smSameWindow); end; um problema na exclusao do cliente',

Vamos analisar o cdigo. No cdigo que segue estamos criando um bloco protegido; atribuindo um parmetro para o objeto SQLExclui e finalmente apresentando uma mensagem ao usurio, em caso de sucesso da operao. try with DataModule1.SQLExclui do begin ParamByName('pcodigo').Value:=StrtoInt(AValue); ExecSQL; end; WebApplication.ShowMessage('Cliente Excluido com sucesso',smSameWindow); No bloco a seguir estamos tratando a exceo, apresentando para o usurio uma mensagem de alerta.

Intraweb 303 except WebApplication.ShowMessage('Houve smSameWindow); end;

um

problema

na

exclusao

do

cliente',

Grave a unit un_manutencao e selecione o formulrio principal. A figura 12.47 ilustra o nosso formulrio de manuteno.

Figura 12.47 Formulrio de manuteno Vamos codificar o formulrio principal, para concluir a aplicao. Na clusula uses do formulrio principal (formMain), insira as units que seguem. uses ServerController, un_Inclusao, un_manutencao; Agora vamos codificar a opo Incluso de Clientes do Menu Principal. No evento OnClick da opo, insira o cdigo a seguir. var fmInclusao:TFmInclusao; begin fmInclusao:=TFMInclusao.Create(WebApplication); fmInclusao.Show; end; Neste cdigo estamos instanciando o objeto FmInclusao e apresentando ao usurio. E agora, vamos codificar a opo Manuteno/Consulta.Coloque o cdigo que segue no evento OnClick da opo. var fmManutencao:TFmManutencao; begin fmManutencao:=TFMManutencao.Create(WebApplication); fmManutencao.Show; end; Com isso conclumos o nosso projeto de Cadastro de Clientes. As figuras 12.48 a 12.53 ilustram nossa aplicao em tempo de execuo.

304 Delphi 7 Internet e Banco de Dados

Figura 12.48 Menu principal

Figura 12.49 Formulrio de incluso

Figura 12.50 Informaes sobre a aplicao

Intraweb 305

Figura 12.51 Manuteno Repare que na tela de manuteno existe um rollover passeando entre os registros. Para que voc possa fazer qualquer tipo de operao, clique no cdigo do cliente, correspondente operao (altera ou exclui). Voc poder digitar apenas uma parte da razo social do cliente. Por exemplo: digitando Facunte, so apresentados todos os registros que contm a palavra Facunte, independente da posio.

Figura 12.52 Alterao de clientes

Figura 12.53 Finalizando a aplicao

306 Delphi 7 Internet e Banco de Dados

Listagem 12.12 IWUnit1.pas (FormMain)


unit IWUnit1; {PUBDIST} interface uses IWAppForm, IWApplication, IWTypes, Menus, Classes, Controls, IWControl, IWCompMenu, jpeg, IWExtCtrls, IWCompLabel; type TformMain = class(TIWAppForm) MainMenu1: TMainMenu; Arquivo1: TMenuItem; InclusodeClientes1: TMenuItem; Manuteno1: TMenuItem; Finaliza1: TMenuItem; IWMenu1: TIWMenu; Sobre1: TMenuItem; Informaessobreaaplicao1: TMenuItem; IWImage1: TIWImage; IWLabel1: TIWLabel; procedure InclusodeClientes1Click(Sender: TObject); procedure Finaliza1Click(Sender: TObject); procedure Informaessobreaaplicao1Click(Sender: TObject); procedure Manuteno1Click(Sender: TObject); public end; implementation {$R *.dfm} uses ServerController, Un_Inclusao, un_manutencao; procedure TformMain.InclusodeClientes1Click(Sender: TObject); var fmInclusao:TFmInclusao; begin fmInclusao:=TFMInclusao.Create(WebApplication); fmInclusao.Show; end; procedure TformMain.Finaliza1Click(Sender: TObject); begin WebApplication.Terminate('At logo !'); end; procedure TformMain.Informaessobreaaplicao1Click(Sender: TObject); begin WebApplication.ShowMessage('Cadastro de Clientes'+#13#10+'Verso 1.0',smAlert); end; procedure TformMain.Manuteno1Click(Sender: TObject); var fmManutencao:TFmManutencao;

Intraweb 307 begin fmManutencao:=TFMManutencao.Create(WebApplication); fmManutencao.Show; end; end.

Listagem 12.13 un_inclusao.pas (FmInclusao)


unit un_inclusao; {PUBDIST} interface uses IWAppForm, IWApplication, IWTypes, IWCompLabel, Classes, Controls, IWControl, IWCompEdit, IWCompListbox, IWCompButton, IWCompRectangle; type TfmInclusao = class(TIWAppForm) edRazao: TIWEdit; IWLabel2: TIWLabel; edEndereco: TIWEdit; IWLabel3: TIWLabel; edCidade: TIWEdit; IWLabel4: TIWLabel; IWLabel5: TIWLabel; edUF: TIWComboBox; IWLabel6: TIWLabel; edEmail: TIWEdit; btConfirma: TIWButton; btDesiste: TIWButton; IWRectangle1: TIWRectangle; edCep: TIWEdit; IWLabel1: TIWLabel; procedure btDesisteClick(Sender: TObject); procedure btConfirmaClick(Sender: TObject); public end; implementation {$R *.dfm} uses ServerController, DatamoduleUnit; procedure TfmInclusao.btDesisteClick(Sender: TObject); begin Hide; end; procedure TfmInclusao.btConfirmaClick(Sender: TObject); begin try {Inclui Cliente}

308 Delphi 7 Internet e Banco de Dados with DataModule1.SQLInclui do begin ParamByName('prazao').Value:=edRazao.Text; ParamByName('pendereco').Value:=edEndereco.Text; ParamByName('pcidade').Value:=edCidade.Text; ParamByName('pestado').Value:=edUf.Items[edUf.ItemIndex]; ParamByName('pcep').Value:=edCep.Text; ParamByName('pemail').Value:=edEmail.Text; ExecSQL; end; WebApplication.ShowMessage('Cliente incluido com sucesso',smSameWindow); except WebApplication.ShowMessage('Houve um problema na incluso do cliente', smSameWindow); end; Hide; end; end.

Listagem 12.14 un_alteracao (FmAltera)


unit un_alteracao; {PUBDIST} interface uses IWAppForm, IWApplication, IWTypes, IWCompRectangle, IWCompButton, IWCompListbox, IWCompLabel, Classes, Controls, IWControl, IWCompEdit, FMTBcd, DB, SqlExpr, IWDBStdCtrls, DBClient, SimpleDS, SysUtils; type TfmAltera = class(TIWAppForm) IWButton1: TIWButton; IWButton2: TIWButton; IWRectangle1: TIWRectangle; IWLabel7: TIWLabel; lbCodigo: TIWLabel; DataSource1: TDataSource; SQLDataSet1: TSQLDataSet; edRazao: TIWEdit; IWLabel2: TIWLabel; edEndereco: TIWEdit; IWLabel3: TIWLabel; edCidade: TIWEdit; IWLabel4: TIWLabel; IWLabel5: TIWLabel; edUF: TIWComboBox; IWLabel6: TIWLabel; edEmail: TIWEdit; edCep: TIWEdit; IWLabel1: TIWLabel; SQLDataSet1COD_CLIENTE: TIntegerField; SQLDataSet1RAZAO_SOCIAL: TStringField;

Intraweb 309 SQLDataSet1ENDERECO: TStringField; SQLDataSet1CIDADE: TStringField; SQLDataSet1ESTADO: TStringField; SQLDataSet1CEP: TStringField; SQLDataSet1EMAIL: TStringField; procedure IWButton2Click(Sender: TObject); procedure IWButton1Click(Sender: TObject); public end; implementation {$R *.dfm} uses ServerController, DataModuleUnit; procedure TfmAltera.IWButton2Click(Sender: TObject); begin Hide; end; procedure TfmAltera.IWButton1Click(Sender: TObject); begin try {Altera Cliente} with DataModule1.SQLAltera do begin ParamByName('pcodigo').Value:=StrtoInt(lbCodigo.Text); ParamByName('prazao').Value:=edRazao.Text; ParamByName('pendereco').Value:=edEndereco.Text; ParamByName('pcidade').Value:=edCidade.Text; ParamByName('pestado').Value:=edUf.Items[edUf.ItemIndex]; ParamByName('pcep').Value:=edCep.Text; ParamByName('pemail').Value:=edEmail.Text; ExecSQL; end; WebApplication.ShowMessage('Cliente Alterado com sucesso',smSameWindow); except WebApplication.ShowMessage('Houve um problema na alteracao do cliente', smSameWindow); end; Hide; end; end.

Listagem 12.15 un_manutencao (FmManutencao)


unit un_manutencao; {PUBDIST} interface

310 Delphi 7 Internet e Banco de Dados uses IWAppForm, IWApplication, IWTypes, Classes, Controls, IWControl, IWCompRectangle, Forms, IWContainer, IWRegion, FMTBcd, DB, SqlExpr, IWGrids, IWDBGrids, IWCompLabel, IWCompButton, IWCompEdit, SysUtils, IWHTMLControls; type TfmManutencao = class(TIWAppForm) IWRectangle1: TIWRectangle; IWRegion1: TIWRegion; IWDBGrid1: TIWDBGrid; SQLPesquisa: TSQLQuery; Ds1: TDataSource; edPesquisa: TIWEdit; btPesquisa: TIWButton; IWLabel1: TIWLabel; btVolta: TIWButton; procedure btPesquisaClick(Sender: TObject); procedure btVoltaClick(Sender: TObject); procedure IWDBGrid1Columns3Click(ASender: TObject; const AValue: String); procedure IWDBGrid1Columns4Click(ASender: TObject; const AValue: String); public procedure Localiza(Cliente: integer); end; implementation {$R *.dfm} uses ServerController, DataModuleUnit, un_alteracao; procedure Tfmmanutencao.Localiza(Cliente:integer); begin SQLPesquisa.Locate('cod_cliente', Cliente, []); end; procedure TfmManutencao.btPesquisaClick(Sender: TObject); begin SQLPesquisa.SQL.Clear; SQLPesquisa.SQL.Add('SELECT * FROM TBCLIENTE WHERE '+''''+'%'+edPesquisa.Text+'%'+''''); SQLPesquisa.Open; end; procedure TfmManutencao.btVoltaClick(Sender: TObject); begin Hide; end; procedure TfmManutencao.IWDBGrid1Columns3Click(ASender: TObject; const AValue: String); var fmAltera:TfmAltera; begin

RAZAO_SOCIAL

LIKE

Intraweb 311 fmAltera:=TFmAltera.Create(WebApplication); { Atribui o cdigo a Query } with fmAltera do begin fmAltera.SQLDataSet1.Params[0].Value:=StrtoInt(AValue); fmAltera.SQLDataSet1.Open; edRazao.Text:=SQLDataSet1RAZAO_SOCIAL.AsString; edEndereco.Text:=SQLDataSet1ENDERECO.AsString; edCidade.Text:=SQLDataSet1CIDADE.AsString; edCEP.Text:=SQLDataSet1CEP.AsString; edUF.ItemIndex:=edUF.Items.IndexOf(SQLDataSet1ESTADO.AsString); edEmail.Text:=SQLDataSet1EMAIL.AsString; { Atribui os valores } fmAltera.lbCodigo.Caption:=Avalue; fmAltera.Show; end; end; procedure TfmManutencao.IWDBGrid1Columns4Click(ASender: TObject; const AValue: String); begin try with DataModule1.SQLExclui do begin ParamByName('pcodigo').Value:=StrtoInt(AValue); ExecSQL; end; WebApplication.ShowMessage('Cliente Excluido com sucesso',smSameWindow); except WebApplication.ShowMessage('Houve smSameWindow); end; end; end. um problema na exclusao do cliente',

Listagem 12.16 DataModuleUnit.pas


unit DatamoduleUnit; interface uses {$IFDEF Linux}QForms, {$ELSE}Forms, {$ENDIF} SysUtils, Classes, DBXpress, DB, SqlExpr, FMTBcd; type TDataModule1 ConexaoBD: SQLInclui: SQLAltera: SQLExclui: private = class(TDataModule) TSQLConnection; TSQLQuery; TSQLQuery; TSQLQuery;

312 Delphi 7 Internet e Banco de Dados public end; // Procs function DataModule1: TDataModule1; implementation {$R *.dfm} uses IWInit, ServerController; // Since we are threaded we cannot use global variables to store form / datamodule references // so we store them in WebApplication.Data and we could reference that each time, but by creating // a function like this our other code looks "normal" almost as if its referencing a global. // This function is not necessary but it makes the code in the main form which references this // datamodule a lot neater. // Without this function ever time we would reference this datamodule we would use: // TDataModule1(WebApplication.Data).Datamodule.<method / component> // By creating this procedure it becomes: // TDataModule1.<method / component> // Which is just like normal Delphi code. function DataModule1: TDataModule1; begin Result := TUserSession(RWebApplication.Data).Datamodule1; end; end.

Intraweb 313

Anotaes de Dvidas

?
Preciso Revisar

Anotaes Gerais

314 Delphi 7 Internet e Banco de Dados

Captulo 13

WebServices
O que so WebServices
Para explicar de maneira adequada o significado da tecnologia WebServices, interessante fazer uma breve introduo aos problemas atuais no mundo da tecnologia. Com o grande avano de sistemas operacionais, bancos de dados, hardware, software, enfim, todo o tipo de tecnologia que envolve o mundo dos negcios, vem surgindo a necessidade de compartilhamento de informaes entre parceiros comerciais, governo e sociedade e at mesmo entre departamentos de uma empresa. Acontece que interligar diferentes plataformas, bancos de dados, operaes, entre outros conceitos, uma tarefa muito complicada e trabalhosa. Imagine o seguinte cenrio (figura 13.1) :
Consulta CPF (Restrio)

Dbito no Banco Cliente Sua Aplicao

Investimento em seu Banco

Cotao Preos Fornecedores

Aquisio Produtos

Figura 13.1 Cenrio de uma aplicao

314

WebServices 315 A figura 13.1 ilustra uma situao comum nos dias de hoje, onde temos diversas operaes com tecnologias e parceiros diferentes. Sem dvida que a maioria das operaes poder ser desenvolvida com um grande trabalho em equipe, exigindo um bom trabalho de pesquisa junto aos parceiros e inmeras horas de desenvolvimento. justamente neste cenrio que surgiu a tecnologia WebServices, para impulsionar os sistemas legados e facilitar a integrao de parceiros comerciais. Pegando carona na primeira fase do WebServices, foram implementadas e idealizadas novas funes, com o intuito de promover e consolidar operaes semelhantes. A figura 13.2 ilustra este cenrio.

Cotao Aes Empresa A

Cotao Aes Empresa C Sua Aplicao

Cotao Aes Empresa B

Compra Aes Empresa C

Compra Aes Empresa A

Figura 13.2 Cenrio de WebServices semelhantes Analisando a figura 13.2, temos uma aplicao que utiliza WebServices de diferentes fornecedores para fazer cotaes de aes, assim como efetuar a aquisio. Um exemplo bastante utilizado, a cotao do cmbio atual. Veja o cenrio na figura 13.3. Imagine o cenrio ilustrado pela figura 13.3 onde sua aplicao necessita ter 24 horas/dia (lembre-se de que o mundo no pra) a cotao do cmbio de diferentes pases, onde seria uma catstrofe imaginar a quebra dos servidores. O cenrio da figura 13.3, ilustra uma operao de cotao de cmbio, utilizando WebServices semelhantes, onde no pode haver queda de servidores, pois a misso crtica. Bem, do seu lado tudo sem problemas, pois existe uma infra-estrutura ideal para este tipo de operao. Mas no lado do provedor de informaes? Imagine que voc esteja utilizando apenas um WebService e o mesmo quebra a conexo? O que fazer? Com a segunda fase da tecnologia, voc pode mapear ilimitados WebServices semelhantes para fazer o mesmo servio, ou seja, quando cair o primeiro, passa para o segundo; na queda do segundo, para o terceiro e assim por diante, podendo at retornar ao primeiro WebService.

316 Delphi 7 Internet e Banco de Dados

Cotao Cmbio A

Cotao Cmbio B

Sua Aplicao
Cotao Cmbio E Cotao Cmbio C

Cotao Cmbio D

Figura 13.3 Cotao cmbio atual Para concluir o conceito de WebServices, vamos imaginar um cenrio mais simples, onde precisamos integrar informaes de diferentes departamentos e filiais, que foram desenvolvidos em plataformas diferentes. Um bom exemplo para isso so os bancos que esto adquirindo outros bancos em todo o mundo e que utilizam conceitos e plataformas diferentes de trabalho. A figura 13.4 ilustra o Banco Facunte, adquirindo outros dois bancos com diferentes tecnologias.

Banco Facunte Banco X Banco Y

Figura 13.4 Banco com diferentes plataformas

WebServices 317 Tecnologias do nosso cenrio exemplo Banco Facunte X Y S.O. Unix NT Solaris Banco Dados DB2 SQL Server Oracle Terminais Terminais Linux Windows Terminais Linux

Integrar informaes de diferentes plataformas no novidade e, como j foi mencionado, possvel, mas muito trabalhoso. A proposta da tecnologia WebServices, neste cenrio, o de facilitar a troca de informaes, fazendo o Banco Facunte entender e tratar as informaes dos Bancos X e Y, independente do banco de dados, sistema operacional ou outro fator no citado. Com algumas linhas de programao e um bom planejamento, as informaes essenciais sero interligadas facilmente. Meus amigos, isso WebServices! Em resumo, WebServices, um padro no-proprietrio, que possibilita o processamento distribudo em sistemas heterogneos. E acredito que muitos de vocs neste ponto estejam ansiosos para produzir o seu primeiro WebService. Antes, devemos conhecer os padres que fazem parte da tecnologia.

Padronizao
Imagine IBM, Microsoft, Borland, Oracle, Sun e outros gigantes da rea de tecnologia, planejando, desenvolvendo e decidindo juntos uma mesma tecnologia. isso que acontece com o WebServices. E para facilitar ainda mais o seu uso e aplicabilidade, foram adotados padres j consagrados, alm do desenvolvimento de outros padres bastante simples. Vejamos os padres:

XML
XML (Extensive Markup Language) ou Linguagem de Marcao Extensvel, que consiste em uma srie de regras, dividindo o documento em partes lgicas e hierrquicas. Atualmente utilizada para trabalhar em conjunto com diversas tecnologias, seja no padro de gravao de um arquivo, no transporte de informaes, at mesmo em definies de montagem de veculos. Trabalhando em conjunto com o WebServices, fornece estrutura para o documento de regras e servios (WSDL), pacote de dados e ocorrncias. Veja um exemplo de XML de dados: <?xml version=1.0?> <LISTA_CLIENTES> <Cliente> <RazaoSocial>Banco Facunte</RazaoSocial> <Cidade>So Paulo</Cidade> <Estado>SP</Estado> </Cliente> <Cliente> <RazaoSocial>Global Education</RazaoSocial> <Cidade>So Paulo</Cidade> <Estado>SP</Estado> </Cliente> <Cliente> <RazaoSocial>Clube Delphi</RazaoSocial> <Cidade>Rio de Janeiro</Cidade> <Estado>RJ</Estado> </Cliente> </LISTA_CLIENTES>

318 Delphi 7 Internet e Banco de Dados

WSDL
WSDL Web Service Definition Language ou Linguagem de Definies de WebServices. O WSDL um documento criado no padro XML, com o objetivo de fornecer informaes sobre a definio de um WebService. Esta definio consiste em mtodos, parmetros e servios fornecidos pelo WebService. Veremos na prtica um documento WSDL, bem como a sua forma de utilizao.

SOAP
Soap Simple Object Access Protocol ou Protocolo Simples de Acesso a Objetos. Em poucas palavras, o SOAP o protocolo utilizado para troca de informaes atravs de objetos criados em diversas linguagens de programao, como Delphi, Java, C++, C#, VB.NET, entre outras. Trafega atravs da porta 80 de um servidor HTTP, facilitando assim o trabalho com servidores protegidos por Firewall, onde a porta 80, apesar de fortemente monitorada, permite o trfego de informaes.

UDDI
UDDI Universal Definition Discovery Inteface ou Interface para Descoberta de Definies Universais. Para facilitar a compreenso do UDDI, farei uma comparao com os servios de busca na Internet. Quando queremos procurar algum documento, artigo, software, na Internet, normalmente utilizamos servios de busca, como o Google (meu preferido), Yahoo!, Hotbot, Cad?, entre outros. Imagine que para localizar um WebServices bastante semelhante, com alguns parmetros diferenciados. O UDDI na realidade um grande catlogo de WebServices, oferecido por diversas empresas, seja ela envolvida na padronizao, como IBM e Borland, ou at mesmo empresas independentes, como o SALCentral.COM (www.salcentral.com). Com isso poderemos localizar e mapear servios semelhantes, como o exemplo que vimos neste captulo, sobre a cotao de cmbios.

E UDDI

Figura 13.5 Aplicao utilizando o servio UDDI A figura 13.5 ilustra uma aplicao utilizando os servios do UDDI. Neste cenrio foram localizados e mapeados WebServices semelhantes, de maneira que a aplicao tenha objetos redundantes, aumentando a eficcia e a segurana. Isso demonstra a flexibilidade da tecnologia, onde as empresas podero escolher os servios (WebServices) mais adequados sua aplicao.

WebServices 319

Sugestes de desenvolvimento
CPF Restries de Crdito
Empresas que oferecem servios e informaes sobre restries de crdito podero desenvolver WebServices para fornecer tais informaes diretamente nas aplicaes de seus clientes. O mais interessante que a cobrana ser automtica, pois cada cliente ter uma chave criptografada e a empresa poder cobrar por nmero de acessos.

Rastreamento de Cargas
Empresas como FedEx e DHL j fornecem seus prprios WebServices. Correios, empresas de logstica e transporte, podero desenvolver WebServices para rastrear as cargas e encomendas enviadas. Alm disso, podero fornecer informaes de estimativa de chegada dinmica, ou seja, imagine uma carga que teve um acrscimo na previso de chegada, devido a uma greve no porto, ou at mesmo um problema no trajeto; com isso a informao poder ser fornecida dinamicamente ao cliente, onde o mesmo tomar as devidas providncias, como um adiamento de reunio ou de produo.

Identificao de Veculos
Os DETRANs de todo o pas poderiam desenvolver WebServices, com inmeros objetivos. O mais importante seria a identificao prvia do veculo, onde despachantes, compradores e vendedores de veculos, guardas e operadores de trnsito, saberiam imediatamente informaes do veculo em questo. Atravs de Palmtops ou celulares, guardas de trnsito poderiam controlar com mais facilidade as multas em veculos infratores. Fabricantes de veculos poderiam checar com maior facilidade informaes sobre um grupo de chassis, para um possvel recall, preparando uma estratgia junto sua equipe de mecnicos para um melhor atendimento por regio.

Cotao de Aes
As operadoras de aes poderiam desenvolver WebServices, afim de fornecer informaes diretamente nas aplicaes de seus clientes, onde os mesmos poderiam concluir negcios mais facilmente, e armazenando a informao diretamente em seu prprio banco de dados.

Cotao de Moedas
J existem diversos WebServices catalogados oferecendo o servio de cotao de moedas. Os mais avanados oferecem funes para converso, onde a aplicao fornece as moedas e valores e o WebService retorna o resultado. Existem outros que fazem atualizao monetria baseada em mltiplas moedas. Isso muito interessante em pases como o nosso, que j trocou de moeda uma dezena de vezes.

TEF (Transferncia Eletrnica de Fundos)


Este um assunto muito delicado, pois envolve segurana. A tecnologia de WebServices est amadurecendo nesta questo, tanto que o SPB (Sistema de Pagamentos Brasileiro) est utilizando a tecnologia para o transporte de algumas informaes. O pacote trafega numa rede muito segura, e altamente criptografada, evitando aes de hackers mal-intencionados. Mesmo assim uma sugesto muito interessante, que facilita o trmite das informaes entre instituies.

320 Delphi 7 Internet e Banco de Dados

Controle de Estoque
Tenho certeza que ser muito bem utilizado e aplicado este tipo de WebService. Poderemos desenvolver WebServices que sero utilizados por nossos clientes, vendedores e tambm fornecedores. Os clientes utilizaro para fazer cotaes e fechamento de pedidos atravs de suas prprias aplicaes. Os vendedores, tanto externos como internos, utilizaro para consultar o saldo no estoque e efetuar os seus pedidos. J os fornecedores podero enviar oramentos para produtos que esto chegando no nvel de estoque mnimo, assim como os prprios compradores da empresa.

CEPs
Os Correios, uma das empresas mais respeitadas do pas, poderiam desenvolver um WebService, oferecendo as informaes de sua base de dados on-line, diretamente na aplicao do cliente. O objetivo no apenas consultar e corrigir informaes sobre o CEP; pode-se ampliar o servio para o clculo de envio de encomendas, e os prazos estipulados.

RG
Um dos assuntos polmicos em nosso pas. Cada Estado tem sua forma de estabelecer regras para os nmeros de R.G.s. Ser que um dia iremos acordar e cada cidado brasileiro ter sua identificao prpria, sem duplicidades? Isso s ser possvel atravs de uma integrao entre os municpios de todo o pas. Quando isso for possvel, o Governo poder oferecer WebServices com os mais variados objetivos. Um bom exemplo para isso, seria o Censo. Sem dvida nenhuma teramos um Censo com um percentual prximo do mximo e com muita rapidez.

CNAB
Quem a j passou pelo suado processo de montagem de arquivos no padro (eu disse padro?) CNAB? Cada banco tem um formato de arquivo, um nmero diferente de propriedades a serem preenchidas, headers psicodlicos e linhas de registros com informaes absurdas e repetitivas. Criando um WebService, padro (aqui sim, seria um padro), os clientes poderiam transmitir e receber informaes de cobrana com uma facilidade enorme. O mais interessante disso tudo acontece quando o cliente opta por outra instituio para fazer a sua cobrana e no precisa alterar nenhuma linha de programao, apenas algumas propriedades, como por exemplo, o cdigo da instituio financeira.

Servios de UDDI e catlogos alternativos


http://uddi.org
UDDI principal, responsvel pela especificao do UDDI.

http://uddi.ibm.com
UDDI da IBM, com opes de registros de WebServices corporativos e para testes. .

http://uddi.microsoft.com
UDDI da Microsoft, com diversas opes de busca, registro simples de novos WebServices, ferramentas para desenvolvedores, entre outros servios. Excelente.

WebServices 321

http://uddi.sap.com
UDDI da SAP. necessrio entrar na rea UDDI Discovery para registrar, procurar e publicar WebServices.

http://www.webservicelist.com/
Fantstico catlogo de Webservices independente, com diviso por categoria, busca de semelhantes, palavras chaves, entre outros servios.

http://www.xmethods.com
Excelente catlogo de Webservices, com os mais populares, at Webservices comerciais.

Nos servios aqui apresentados, existe uma imensido de WebServices, divididos nas mais variadas categorias. Desde simples consultas a cotao de moedas, at servios na rea de sade. Mais adiante iremos aprender a importar estes servios (WebServices) em nossa aplicao.

Delphi x WebServices
Neste tpico iremos aprender os conceitos de WebServices integrado com o Delphi. O Delphi possui um conjunto de componentes especfico para a tecnologia de WebServices. Na seo WebServices da paleta de componentes, encontramos os seguintes objetos: COMPONENTE (OBJETO) DESCRIO

HTTPRIO

Utiliza para obter uma referncia para uma interface registrada. Gera em memria uma tabela de mtodos, a fim de fornecer a implementao da interface.

HTTPReqResp

Executa mtodos de chamada na interface, de maneira a enviar e receber mensagens no padro SOAP. Normalmente utilizado em conjunto com o HTTPRio, implementando os mtodos Get e Post.

OpToSOAPDOMConvert

Normalmente instanciado em tempo de execuo pelo componente HTTPRio, tem como principal funo fazer um parser nos mtodos de chamada.

Utilizado para conectar a aplicao aos servidores implementados no padro WebService. SOAPConnection

322 Delphi 7 Internet e Banco de Dados

COMPONENTE (OBJETO)

DESCRIO

Responsvel por responder as chamadas no padro SOAP. HTTPSoapDispatcher

WSDLHTMLPublish

Responsvel por publicar um documento WSDL com todo o descritivo do WebService. Utilizado para interpretar uma mensagem padro SOAP, e executar o mtodo correspondente.

HTTPSoapPascalInvoker

WebService Exemplo
Vamos criar nosso primeiro WebService para aprender melhor seu conceito. Atravs das opes File/New..., seo WebServices, selecione a opo SOAP Server Application (figura 13.6).

Figura 13.6 Nova aplicao WebService Em seguida, selecione a opo CGI para o tipo da aplicao servidora SOAP (figura 13.7).

WebServices 323

Figura 13.7 Tipo da aplicao servidora Em seguida, o Delphi pergunta se deseja criar uma Interface SOAP padro (figura 13.8). Em nosso primeiro exemplo, vamos criar tal Interface, a fim de conhecer sua implementao.

figura 13.8 Criao da Interface Em seguida (figura 13.9). devemos informar os dados da nova Interface. Nos campos Service Name e Unit identifier coloque wsexemplo. Com isso estamos criando uma Interface com o nome wsexemplo, e gravando a unit com o mesmo nome. Em Code generation selecione as opes Generate Comments e Generate Sample Methods. Com isso estamos gerando exemplos de mtodos e comentrios.

Figura 13.9 Identificao do servio Clique em OK para finalizar. Vamos gravar nossa aplicao.

324 Delphi 7 Internet e Banco de Dados Unit WebModule Unit Implementao WsExemplo Unit Interface WsExemplo Projeto Vamos analisar o que o nosso amigo Delphi criou. un_ws1.pas wsexemploImpl.pas wsexemploIntf.pas ws1.dpr

Figura 13.10 WebModule1 A figura 13.10 ilustra nosso WebModule com trs componentes no padro WebService (HTTPSoapDispatcher, HTTPSoapPascalInvoker e WSDLHTMLPublish). Vejamos sua implementao. procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin WSDLHTMLPublish1.ServiceInfo(Sender, Request, Response, Handled); end; A nica funo do nosso WebModule1 a criao de um handler para o WebService e publicao do documento WSDL. Na unit wsexemploIntf estamos definindo a Interface de nossa aplicao. {Invokable interface Iwsexemplo } unit wsexemploIntf; interface uses InvokeRegistry, Types, XSBuiltIns; type TEnumTest = (etNone, etAFew, etSome, etAlot); TDoubleArray = array of Double; TMyEmployee = class(TRemotable) private FLastName: AnsiString; FFirstName: AnsiString; FSalary: Double; published property LastName: AnsiString read FLastName write FLastName; property FirstName: AnsiString read FFirstName write FFirstName; property Salary: Double read FSalary write FSalary;

WebServices 325 end; { Invokable interfaces must derive from IInvokable } Iwsexemplo = interface(IInvokable) ['{A391DC0F-CDA7-4929-97B8-DAECA7C2CF18}'] { Methods of Invokable interface must not use the default } { calling convention; stdcall is recommended } function echoEnum(const Value: TEnumTest): TEnumTest; stdcall; function echoDoubleArray(const Value: TDoubleArray): TDoubleArray; stdcall; function echoMyEmployee(const Value: TMyEmployee): TMyEmployee; stdcall; function echoDouble(const Value: Double): Double; stdcall; end; implementation initialization { Invokable interfaces must be registered } InvRegistry.RegisterInterface(TypeInfo(Iwsexemplo)); end. Esta unit na realidade est seguindo as regras da O.O. (Orientao a Objeto), onde definimos uma Interface como base, para que possamos implementar nossas classes. Alm disso estamos registrando a Interface no modelo SOAP. Repare que os mtodos criados so apenas exemplos de implementao, que solicitamos previamente, justamente para estudar e analisar. Na unit wsexemploImpl, temos a implementao da Interface que vimos anteriormente. Veja o cdigo. { Invokable implementation File for Twsexemplo which implements Iwsexemplo } unit wsexemploImpl; interface uses InvokeRegistry, Types, XSBuiltIns, wsexemploIntf; type { Twsexemplo } Twsexemplo = class(TInvokableClass, Iwsexemplo) public function echoEnum(const Value: TEnumTest): TEnumTest; stdcall; function echoDoubleArray(const Value: TDoubleArray): TDoubleArray; stdcall; function echoMyEmployee(const Value: TMyEmployee): TMyEmployee; stdcall; function echoDouble(const Value: Double): Double; stdcall; end; implementation function Twsexemplo.echoEnum(const Value: TEnumTest): TEnumTest; stdcall; begin { TODO : Implement method echoEnum } Result := Value; end; function stdcall; begin Twsexemplo.echoDoubleArray(const Value: TDoubleArray): TDoubleArray;

326 Delphi 7 Internet e Banco de Dados { TODO : Implement method echoDoubleArray } Result := Value; end; function Twsexemplo.echoMyEmployee(const Value: TMyEmployee): TMyEmployee; stdcall; begin { TODO : Implement method echoMyEmployee } Result := TMyEmployee.Create; end; function Twsexemplo.echoDouble(const Value: Double): Double; stdcall; begin { TODO : Implement method echoDouble } Result := Value; end; initialization { Invokable classes must be registered } InvRegistry.RegisterInvokableClass(Twsexemplo); end. Acredito que deu para perceber, que os mtodos apenas retornam os mesmos valores informados. Para compreender melhor, vamos fazer uma pequena alterao no mtodo echoDouble. Substitua a linha de retorno, pelo cdigo que segue em negrito: function Twsexemplo.echoDouble(const Value: Double): Double; stdcall; begin { TODO : Implement method echoDouble } Result := Value * 3; end; Grave a aplicao. Antes de compilar, vamos definir o diretrio para gerao do nosso WebService. Atravs das opes Project/Options.../Directories_Conditionals, configure a opo Output Directory, apontando para o seu diretrio cgi-bin (figura 13.11).

Figura 13.11 Configurao do diretrio Grave novamente a aplicao.

WebServices 327 Agora vamos compilar a aplicao. Vamos executar a aplicao no browser para analisar o seu contedo. Digite: http://localhost/cgi-bin/ws1.exe/. A figura 13.12 ilustra o resultado da primeira fase de nossa aplicao.

Figura 13.12 Aplicao ws1 Repare que temos todos os mtodos listados na Interface Iwsexemplo (echoEnum, echoDoubleArray, echoMyEmployee, echoDouble). O documento gerado est de acordo com o padro estabelecido pelo W3C-UDDI (rgo responsvel pelo padro WebService). Clicando no link WSDL da Interface Iwexemplo ser apresentado o seguinte documento WSDL. <?xml version="1.0" encoding="utf-8" ?> <definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" name="Iwsexemploservice" targetNamespace="http://tempuri.org/" xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:ns1="urn:wsexemploIntf"> - <types> - <xs:schema targetNamespace="urn:wsexemploIntf" xmlns="urn:wsexemploIntf"> - <xs:simpleType name="TEnumTest"> - <xs:restriction base="xs:string"> <xs:enumeration value="etNone" /> <xs:enumeration value="etAFew" /> <xs:enumeration value="etSome" /> <xs:enumeration value="etAlot" /> </xs:restriction> </xs:simpleType> - <xs:complexType name="TDoubleArray"> - <xs:complexContent> - <xs:restriction base="soapenc:Array"> <xs:sequence /> <xs:attribute ref="soapenc:arrayType" n1:arrayType="xs:double[]" xmlns:n1="http://schemas.xmlsoap.org/wsdl/" /> </xs:restriction> </xs:complexContent> </xs:complexType> - <xs:complexType name="TMyEmployee"> - <xs:sequence>

328 Delphi 7 Internet e Banco de Dados <xs:element name="LastName" type="xs:string" /> <xs:element name="FirstName" type="xs:string" /> <xs:element name="Salary" type="xs:double" /> </xs:sequence> </xs:complexType> </xs:schema> </types> - <message name="echoEnum0Request"> <part name="Value" type="ns1:TEnumTest" /> </message> - <message name="echoEnum0Response"> <part name="return" type="ns1:TEnumTest" /> </message> - <message name="echoDoubleArray1Request"> <part name="Value" type="ns1:TDoubleArray" /> </message> - <message name="echoDoubleArray1Response"> <part name="return" type="ns1:TDoubleArray" /> </message> - <message name="echoMyEmployee2Request"> <part name="Value" type="ns1:TMyEmployee" /> </message> - <message name="echoMyEmployee2Response"> <part name="return" type="ns1:TMyEmployee" /> </message> - <message name="echoDouble3Request"> <part name="Value" type="xs:double" /> </message> - <message name="echoDouble3Response"> <part name="return" type="xs:double" /> </message> - <portType name="Iwsexemplo"> - <operation name="echoEnum"> <input message="tns:echoEnum0Request" /> <output message="tns:echoEnum0Response" /> </operation> - <operation name="echoDoubleArray"> <input message="tns:echoDoubleArray1Request" /> <output message="tns:echoDoubleArray1Response" /> </operation> - <operation name="echoMyEmployee"> <input message="tns:echoMyEmployee2Request" /> <output message="tns:echoMyEmployee2Response" /> </operation> - <operation name="echoDouble"> <input message="tns:echoDouble3Request" /> <output message="tns:echoDouble3Response" /> </operation> </portType> - <binding name="Iwsexemplobinding" type="tns:Iwsexemplo"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" /> - <operation name="echoEnum"> <soap:operation soapAction="urn:wsexemploIntf-Iwsexemplo#echoEnum" style="rpc" /> - <input message="tns:echoEnum0Request"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsexemploIntf-Iwsexemplo" /> </input> - <output message="tns:echoEnum0Response">

WebServices 329 <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsexemploIntf-Iwsexemplo" /> </output> </operation> - <operation name="echoDoubleArray"> <soap:operation soapAction="urn:wsexemploIntf-Iwsexemplo#echoDoubleArray" style="rpc" /> - <input message="tns:echoDoubleArray1Request"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsexemploIntf-Iwsexemplo" /> </input> - <output message="tns:echoDoubleArray1Response"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsexemploIntf-Iwsexemplo" /> </output> </operation> - <operation name="echoMyEmployee"> <soap:operation soapAction="urn:wsexemploIntf-Iwsexemplo#echoMyEmployee" style="rpc" /> - <input message="tns:echoMyEmployee2Request"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsexemploIntf-Iwsexemplo" /> </input> - <output message="tns:echoMyEmployee2Response"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsexemploIntf-Iwsexemplo" /> </output> </operation> - <operation name="echoDouble"> <soap:operation soapAction="urn:wsexemploIntf-Iwsexemplo#echoDouble" style="rpc" /> - <input message="tns:echoDouble3Request"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsexemploIntf-Iwsexemplo" /> </input> - <output message="tns:echoDouble3Response"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsexemploIntf-Iwsexemplo" /> </output> </operation> </binding> - <service name="Iwsexemploservice"> - <port name="IwsexemploPort" binding="tns:Iwsexemplobinding"> <soap:address location="http://localhost/delphi/cgi-bin/ws1.exe/soap/Iwsexemplo" /> </port> </service> </definitions> Parece complicado, no ? Vamos analisar algumas partes do documento para compreender melhor seu funcionamento. <types> <xs:schema targetNamespace="urn:wsexemploIntf" xmlns="urn:wsexemploIntf"> <xs:simpleType name="TEnumTest"> <xs:restriction base="xs:string"> <xs:enumeration value="etNone" /> <xs:enumeration value="etAFew" /> <xs:enumeration value="etSome" />

330 Delphi 7 Internet e Banco de Dados <xs:enumeration value="etAlot" /> </xs:restriction> Passando pelo bloco das definies inicias (<?xml version="1.0"...), chegamos no bloco de definies de tipos e mtodos. Neste bloco so definidos todos os mtodos da nossa Interface, com o descritivo completo. Repare que a classe TEnumTest descrita com perfeio. No bloco que segue, so descritos os mtodos Request e Response da Interface em questo. - <message name="echoEnum0Request"> <part name="Value" type="ns1:TEnumTest" /> </message> - <message name="echoEnum0Response"> <part name="return" type="ns1:TEnumTest" /> </message> A seguir, temos o bloco que define o nome da porta (Port) e as operaes Request e Response, descritas no bloco anterior. - <portType name="Iwsexemplo"> - <operation name="echoEnum"> <input message="tns:echoEnum0Request" /> <output message="tns:echoEnum0Response" /> </operation> Em seguida temos o bloco que envelopa e define a camada de transporte dos mtodos. - <binding name="Iwsexemplobinding" type="tns:Iwsexemplo"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" /> - <operation name="echoEnum"> <soap:operation soapAction="urn:wsexemploIntf-Iwsexemplo#echoEnum" style="rpc" /> - <input message="tns:echoEnum0Request"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsexemploIntf-Iwsexemplo" /> </input> - <output message="tns:echoEnum0Response"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsexemploIntf-Iwsexemplo" /> </output> O ltimo bloco finaliza o documento, declarando o nome do servio, bem como o nome da porta e a sua camada de transporte. - <service name="Iwsexemploservice"> - <port name="IwsexemploPort" binding="tns:Iwsexemplobinding"> <soap:address location="http://localhost/delphi/cgi-bin/ws1.exe/soap/Iwsexemplo" /> </port> </service> </definitions> Agora vamos criar uma aplicao cliente para testar nosso primeiro WebService. Atravs das opes File/New Application crie uma nova aplicao, e grave os arquivos como segue: Unit Projeto un_teste_ws1.PAS teste_ws1.DPR

Agora vamos importar a Interface em nossa aplicao. Atravs das opes File/New.../WebServices (figura 13.13), selecione a opo WSDL Importer.

WebServices 331

Figura 13.13 WSDL importer Em seguida, como ilustra a figura 13.14 , digite o endereo que segue. http://localhost/cgi-bin/ws1.exe/wsdl/Iwsexemplo Este endereo faz a chamada ao documento WSDL da Interface Iwsexemplo.

Fgura 13.14 Importao da Interface atravs do WSDL Este procedimento est importando toda a Interface para a nossa aplicao. Com isso teremos acesso aos mtodos definidos. interessante destacar que um WebService poder ter inmeras Interfaces, onde poderemos importar apenas as que condizem com a nossa necessidade. Aperte o boto Next para avanar prxima fase. A figura 13.15 ilustra a Interface gerada pelo assistente.

332 Delphi 7 Internet e Banco de Dados

Fgura 13.15 Interface gerada pelo assistente Para concluir,aperte a tecla Finish. O assistente gerou uma Unit com toda a Interface implementada. Grave a Unit com o nome Iwsexemplo1.pas. O que acabamos de fazer, na realidade, foi a importao de uma Interface para facilitar o uso do WebService. Agora com o foco na unit un_teste_ws1, insira a unit Iwexemplo1.pas gerada pelo assistente. implementation uses Iwsexemplo1; Neste ponto iremos configurar o acesso para este formulrio. Insira um objeto do tipo THTTPRIO e configure as propriedades que seguem, respeitando a seqncia apresentada, caso contrrio, uma exceo ocorrer.

OBJETO THTTPRio Objeto HTTPRio1 Propriedade Name WSDLLocation Valor HR1 http://localhost/cgi-bin/ ws1.exe/wsdl/Iwsexemplo Iwsexemploservice IwsexemploPort

Service Port

Com isto configuramos o objeto de acesso Interface, informando a localizao do documento WSDL (WSDLLocation), o servio (Service), e a porta (Port). Agora insira os objetos que seguem, configurando suas respectivas propriedades.

WebServices 333

OBJETO TEdit Objeto edValor Propriedade Name Left Text Top Width Valor edValor 32 deixe em branco 24 120

OBJETO TButton Objeto Button1 Propriedade Name Caption Left Top Width Valor Button1 Calcula 176 24 125

OBJETO Tlabel Objeto lbResultado Propriedade Name Caption Left Top Valor lbResultado 0 32 64

A figura 13.16 ilustra o formulrio da nossa aplicao.

Figura 13.16 Formulrio da aplicao Agora vamos codificar a aplicao. Insira o cdigo que segue no evento OnClick do objeto Button1. var Iexemplo: Iwsexemplo; begin

334 Delphi 7 Internet e Banco de Dados Iexemplo:= HR1 as Iwsexemplo; lbResultado.Caption:=FloattoStr(Iexemplo.echoDouble( StrtoFloat(edValor.Text))); end; O cdigo bastante simples, onde estamos definindo um objeto do tipo Iwsexemplo. Em seguida estamos instanciando o objeto a partir do nosso HTTPRio (HR1), adotando o modelo Iwsexemplo. E por fim, apresentamos o resultado em nosso objeto lbResultado, atravs da funo IExemplo.echoDouble. O mais importante, at aqui, justamente a compreenso de como conseguimos implementar o WebService em nossa aplicao. Vamos testar nossa aplicao. Compile e execute a aplicao, informando um nmero no campo e pressionando o boto. A figura 13.17 ilustra nossa aplicao em tempo de execuo.

, Figura 13.17 Aplicao em tempo de execuo Perceba que, na primeira vez que pressionamos o boto, existe um delay, que justamente o tempo de conexo com o WebService. Repita a operao e perceba que j no existe mais o delay. Amigos, no prximo tpico iremos desenvolver nosso prprio WebService.

Listagem 13.1 un_teste_ws1.pas (formulrio principal)


unit un_teste_ws1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, InvokeRegistry, Rio, SOAPHTTPClient, StdCtrls; type TForm1 = class(TForm) HR1: THTTPRIO; edValor: TEdit; lbresultado: TLabel; Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1;

WebServices 335

implementation uses Iwsexemplo1; {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var Iexemplo: Iwsexemplo; begin Iexemplo:= HR1 as Iwsexemplo; lbresultado.Caption:=FloattoStr(Iexemplo.echoDouble(StrtoFloat(edValor.Text))); end; end.

Listagem 13.2 Iwsexemplo1.pas (interface importada para a aplicao)


// // // // // // // // ************************************************************************ // The types declared in this file were generated from data read from the WSDL File described below: WSDL : http://localhost/delphi/cgi-bin/ws1.exe/wsdl/Iwsexemplo Encoding : utf-8 Version : 1.0 (29/08/2002 12:08:27 - 1.33.2.5) ************************************************************************ //

unit Iwsexemplo1; interface uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns; type // ************************************************************************ // // The following types, referred to in the WSDL document are not being represented // in this file. They are either aliases[@] of other types represented or were referred // to but never[!] declared in the document. The types from the latter category // typically map to predefined/known XML or Borland types; however, they could also // indicate incorrect WSDL documents that failed to declare or import a schema type. // ************************************************************************ // // !:double - "http://www.w3.org/2001/XMLSchema" // !:string - "http://www.w3.org/2001/XMLSchema" TMyEmployee = class; { "urn:wsexemploIntf" }

{ "urn:wsexemploIntf" } TEnumTest = (etNone, etAFew, etSome, etAlot); TDoubleArray = array of Double; { "urn:wsexemploIntf" }

// ************************************************************************ // // Namespace : urn:wsexemploIntf // ************************************************************************ // TMyEmployee = class(TRemotable)

336 Delphi 7 Internet e Banco de Dados private FLastName: WideString; FFirstName: WideString; FSalary: Double; published property LastName: WideString read FLastName write FLastName; property FirstName: WideString read FFirstName write FFirstName; property Salary: Double read FSalary write FSalary; end; // ************************************************************************ // // Namespace : urn:wsexemploIntf-Iwsexemplo // soapAction: urn:wsexemploIntf-Iwsexemplo#%operationName% // transport : http://schemas.xmlsoap.org/soap/http // style : rpc // binding : Iwsexemplobinding // service : Iwsexemploservice // port : IwsexemploPort // URL : http://localhost/delphi/cgi-bin/ws1.exe/soap/Iwsexemplo // ************************************************************************ // Iwsexemplo = interface(IInvokable) ['{A21A137B-E1B0-488A-810D-790FBDEA675A}'] function echoEnum(const Value: TEnumTest): TEnumTest; stdcall; function echoDoubleArray(const Value: TDoubleArray): TDoubleArray; stdcall; function echoMyEmployee(const Value: TMyEmployee): TMyEmployee; stdcall; function echoDouble(const Value: Double): Double; stdcall; end; function GetIwsexemplo(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): Iwsexemplo; implementation function GetIwsexemplo(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): Iwsexemplo; const defWSDL = 'http://localhost/delphi/cgi-bin/ws1.exe/wsdl/Iwsexemplo'; defURL = 'http://localhost/delphi/cgi-bin/ws1.exe/soap/Iwsexemplo'; defSvc = 'Iwsexemploservice'; defPrt = 'IwsexemploPort'; var RIO: THTTPRIO; begin Result := nil; if (Addr = '') then begin if UseWSDL then Addr := defWSDL else Addr := defURL; end; if HTTPRIO = nil then RIO := THTTPRIO.Create(nil) else RIO := HTTPRIO; try

WebServices 337 Result := (RIO as Iwsexemplo); if UseWSDL then begin RIO.WSDLLocation := Addr; RIO.Service := defSvc; RIO.Port := defPrt; end else RIO.URL := Addr; finally if (Result = nil) and (HTTPRIO = nil) then RIO.Free; end; end; initialization InvRegistry.RegisterInterface(TypeInfo(Iwsexemplo), 'urn:wsexemploIntf-Iwsexemplo', 'utf-8'); InvRegistry.RegisterDefaultSOAPAction(TypeInfo(Iwsexemplo), 'urn:wsexemploIntfIwsexemplo#%operationName%'); RemClassRegistry.RegisterXSInfo(TypeInfo(TEnumTest), 'urn:wsexemploIntf', 'TEnumTest'); RemClassRegistry.RegisterXSInfo(TypeInfo(TDoubleArray), 'urn:wsexemploIntf', 'TDoubleArray'); RemClassRegistry.RegisterXSClass(TMyEmployee, 'urn:wsexemploIntf', 'TMyEmployee'); end.

Segundo WebService
Neste exemplo vamos criar nosso WebService sem utilizar os exemplos de mtodos gerados pelo assistente. Nosso WebService consiste em fazer um simples clculo, apresentando um nmero aproximado de dias j vividos, a partir de uma idade informada. Exemplo: 28 anos = 10.220 dias aproximadamente ( 28 x 365 ), onde 28 = idade informada, 365 = dias do ano. Atravs das opes File/New..., seo WebServices, selecione a opo SOAP Server Application (figura 13.18).

Figura 13.18 Nova aplicao WebService

338 Delphi 7 Internet e Banco de Dados Em seguida, selecione a opo CGI para o tipo da aplicao servidora SOAP (figura 13.19).

Figura 13.19 Tipo da aplicao servidora Em seguida, o Delphi pergunta se deseja criar uma Interface SOAP padro (figura 13.20). Neste caso, seleciona No, pois iremos criar manualmente.

Figura 13.20 Criao da Interface Vamos gravar nossa aplicao. Unit WebModule Projeto un_ws2.PAS ws2.DPR

Agora vamos criar a Interface de nossa aplicao. A partir da verso 7, existe o assistente para a criao da Interface. Na realidade faz a mesma operao que dispensamos no dilogo anterior (figura 13.20). Atravs das opes File/New..WebServices, selecione o assistente SOAP Server Interface (figura 13.21), e em seguida pressione OK.

WebServices 339

Figura 13.21 Criando a Interface do WebService Em seguida (figura 13.22) devemos informar os dados da nova Interface. Nos campos Service Name e Unit identifier coloque wsidade. Com isso estamos criando uma Interface com o nome wsidade, e gravando a unit com o mesmo nome. Em Code generation desmarque as duas opes (Generate Comments e Generate Sample Methods).

Figura 13.22 Dados complementares da Interface O assistente criou duas novas units: wsIdadeIntf.pas e wsIdadeImpl.pas. Vamos gravar nossa aplicao. Unit wsIdadeIntf Unit wsIdadeImpl Vamos analisar as units criadas. wsIdadeIntf.pas unit wsIdadeIntf; interface uses InvokeRegistry, Types, XSBuiltIns; type IwsIdade = interface(IInvokable) wsIdadeIntf.pas wsIdadeImpl.pas

340 Delphi 7 Internet e Banco de Dados ['{A808C7C4-86BC-446C-B329-60F22BD82A87}'] end; implementation initialization InvRegistry.RegisterInterface(TypeInfo(IwsIdade)); end. Esta a unit para definio da Interface do nosso WebService. No bloco que segue, definimos os mtodos. Repare que foi criado um identificador nico (GUID). Poderamos fazer esta Interface sem o uso do assistente, e para a criao do GUID, basta pressionar as teclas CTRL-G no editor. type IwsIdade = interface(IInvokable) ['{A808C7C4-86BC-446C-B329-60F22BD82A87}'] end; A seguir temos o registro da Interface do nosso WebService.. implementation initialization InvRegistry.RegisterInterface(TypeInfo(IwsIdade)); Agora veremos a unit wsIdadeImpl. wsIdadeImpl.pas unit wsIdadeImpl; interface uses InvokeRegistry, Types, XSBuiltIns, wsIdadeIntf; type TwsIdade = class(TInvokableClass, IwsIdade) public end; implementation initialization InvRegistry.RegisterInvokableClass(TwsIdade); end. Esta a unit para implementao dos mtodos definidos na Interface (unit wsIdadeIntf). Repare no bloco a seguir, que esta unit faz uso da anterior. uses InvokeRegistry, Types, XSBuiltIns, wsIdadeIntf; No bloco que segue, os mtodos so definidos como public. type

WebServices 341 TwsIdade = class(TInvokableClass, IwsIdade) public end; Bem, agora vamos definir o mtodo de nosso WebService. Selecione a unit wsIdadeIntf, e insira o mtodo QuantosDias, como segue. IwsIdade = interface(IInvokable) ['{A808C7C4-86BC-446C-B329-60F22BD82A87}'] function QuantosDias(idade: Integer):integer; stdcall; end; Repare que estamos fazendo uma chamada explcita stdcall, padro em WebServices. Grave a unit. Agora, selecione a unit wsIdadeImpl e insira o mtodo QuantosDias, como segue; public function QuantosDias(idade: Integer):integer; stdcall; end; Na seo implementation, digite o cdigo a seguir. function TwsIdade.QuantosDias(idade: integer):integer; begin Result:=idade * 365; end; Est pronto nosso WebService. Agora vamos desenvolver dois clientes com tecnologias diferentes. O primeiro ser no padro desktop, e o outro uma aplicao CGI. Antes de compilar, vamos definir o diretrio para gerao do nosso WebService. Atravs das opes Project/Options.../Directories_Conditionals, configure a opo Output Directory, apontando para o seu diretrio cgi-bin (figura 13.23).

Figura 13.23 Configurao do diretrio Compile a nossa aplicao para que possamos analisar o documento WSDL. No browser digite http://localhost/cgibin/ws2.exe. A figura 13.24 ilustra o assistente WSDL de nossa aplicao.

342 Delphi 7 Internet e Banco de Dados

Figura 13.24 Pgina de informao (assistente WSDL). Repare que o nosso mtodo QuantosDias est publicado. Clique no WSDL do mtodo para visualizar a implementao. O seguinte documento WSDL foi gerado. <?xml version="1.0" encoding="utf-8" ?> <definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" name="IwsIdadeservice" targetNamespace="http://tempuri.org/" xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"> - <message name="QuantosDias0Request"> <part name="idade" type="xs:int" /> </message> - <message name="QuantosDias0Response"> <part name="return" type="xs:int" /> </message> - <portType name="IwsIdade"> - <operation name="QuantosDias"> <input message="tns:QuantosDias0Request" /> <output message="tns:QuantosDias0Response" /> </operation> </portType> - <binding name="IwsIdadebinding" type="tns:IwsIdade"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" /> - <operation name="QuantosDias"> <soap:operation soapAction="urn:wsIdadeIntf-IwsIdade#QuantosDias" style="rpc" /> - <input message="tns:QuantosDias0Request"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsIdadeIntf-IwsIdade" /> </input> - <output message="tns:QuantosDias0Response"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsIdadeIntf-IwsIdade" /> </output> </operation>

WebServices 343 </binding> - <service name="IwsIdadeservice"> - <port name="IwsIdadePort" binding="tns:IwsIdadebinding"> <soap:address location="http://localhost/delphi/cgi-bin/ws2.exe/soap/IwsIdade" /> </port> </service> </definitions> Agora vamos criar a primeira aplicao cliente para o nosso WebService. Atravs das opes File/New Application cria uma nova aplicao e grave os arquivos como segue: Unit Projeto un_teste_ws2.PAS teste_ws2.DPR

Agora vamos importar a Interface em nossa aplicao. Atravs das opes File/New.../WebServices (figura 13.25), selecione a opo WSDL Importer.

Figura 13.25 WSDL importer Em seguida, como ilustra a figura 13.26 , digite o endereo que segue. http://localhost/cgi-bin/ws2.exe/wsdl/IwsIdade Este endereo faz a chamada ao documento WSDL da Interface IwsIdade.

Figura 13.26 Importando a Interface

344 Delphi 7 Internet e Banco de Dados O assistente gerou uma Unit com toda a Interface implementada. Grave a Unit com o nome IwsIdade1.pas. Agora com o foco na unit un_teste_ws2, insira a unit IwsIdade1.pas gerada pelo assistente. implementation uses IwsIdade1;

Neste ponto iremos configurar o acesso para este formulrio. Insira um objeto do tipo THTTPRIO e configure as propriedades que seguem, respeitando a seqncia apresentada, caso contrrio, uma exceo ocorrer.

OBJETO THTTPRio Objeto HTTPRio1 Propriedade Name WSDLLocation Valor HR1 http://localhost/cgi-bin/ ws2.exe/wsdl/IwsIdade IwsIdadeservice IwsIdadePort

Service Port

Com isto configuramos o objeto de acesso Interface, informando a localizao do documento WSDL (WSDLLocation), o servio (Service), e a porta (Port). Agora insira os objetos que seguem, configurando suas respectivas propriedades.

OBJETO TEdit Objeto edValor Propriedade Name Left Text Top Width Valor edIdade 32 deixe em branco 24 120

OBJETO TButton Objeto Button1 Propriedade Name Caption Left Top Width Valor Button1 Calcula 176 24 125

WebServices 345

OBJETO Tlabel Objeto lbResultado Propriedade Name Caption Left Top Valor lbDias Dias 32 64

A figura 13.27 ilustra o formulrio da nossa aplicao.

Figura 13.27 Formulrio da aplicao Agora vamos codificar a aplicao. Insira o cdigo que segue no evento OnClick do objeto Button1. var IIdade: IwsIdade; begin IIdade:=HR1 as IwsIdade; lbDias.Caption:='Voc j viveu aproximadamente '+InttoStr(IIdade.QuantosDias(StrtoInt(edIdade.Text)))+' dias'; end; Muito parecido com o nosso primeiro teste, estamos definindo um objeto do tipo IwsIdade, em seguida estamos instanciando o objeto a partir do nosso HTTPRio (HR1), adotando o modelo IwsIdade. E por fim, apresentamos o resultado em nosso objeto lbDias, atravs da funo IIDade.QuantosDias. Fcil? Acredito que neste ponto j deu para compreender o mtodo de implementao de um WebService. Agora vamos utilizar o mesmo WebService numa aplicao do tipo CGI. A partir do Delphi, selecione as opes File/New/Other... e em seguida a opo Web Server Application, como ilustra a figura 13.28.

Figura 13.28 Opo Web Server Application

346 Delphi 7 Internet e Banco de Dados Na janela seguinte selecione a opo CGI Stand-Alone executable (figura 13.29).

Figura 13.29 Seleo do tipo da aplicao Em seguida teremos o nosso WebModule (figura 13.30).

Figura 13.30 WebModule Neste ponto ao invs de importar o WSDL, vamos apenas adicionar a unit que j importamos em nossa primeira aplicao: IwsIdade; implementation uses IwsIdade1; Neste ponto iremos configurar o acesso para o nosso CGI. Insira um objeto do tipo THTTPRIO e configure as propriedades que seguem, respeitando a seqncia apresentada, caso contrrio, uma exceo ocorrer.

OBJETO THTTPRio Objeto HTTPRio1 Propriedade Name WSDLLocation Valor HR1 http://localhost/cgi-bin/ ws2.exe/wsdl/IwsIdade IwsIdadeservice IwsIdadePort

Service Port

WebServices 347 Agora vamos criar nossa Action. Atravs do duplo-clique no WebModule, acesse o editor de ActionItems (figura 13.31).

Figura 13.31 Editor ActionItems Clique no primeiro boto do editor para inserir uma nova Action (figura 13.32).

Figura 13.32 ActionItem Em seguida altere as seguintes propriedades.

OBJETO TWebActionItem Objeto padrao Propriedade Default Name PathInfo Valor True dias /dias

Esta ser nossa Action padro, ou seja, caso o usurio no digite nada, alm do nome da nossa aplicao, esta Action ser executada. No evento OnAction coloque o seguinte cdigo: var IIdade: IwsIdade; begin IIdade:=HR1 as IwsIdade; Response.Content:='Voc j viveu aproximadamente '+InttoStr(IIdade.QuantosDias(StrtoInt(Request.QueryFields.Values['idade'])))+' dias'; end; Aqui estamos utilizando o mtodo Response.Content para apresentar ao usurio a mensagem criada atravs do parmetro Idade, utilizando o mtodo QuantosDias do nosso WebService.

348 Delphi 7 Internet e Banco de Dados Antes de compilar vamos definir o diretrio para gerao do nosso WebService. Atravs das opes Project/Options.../Directories_Conditionals, configure a opo Output Directory, apontando para o seu diretrio cgi-bin (figura 13.33).

Figura 13.33 Configurao do diretrio Grave os arquivos como segue. Unit Projeto un_cgi_ws2.PAS teste_cgi_ws2.DPR

Agora vamos testar a nossa aplicao. No browser digite o seguinte endereo:

http://localhost/delphi/cgi-bin/teste_cgi_ws2.exe/dias?idade=55
A figura 13.34 ilustra nosso CGI em tempo de execuo.

Figura 13.34 CGI em execuo Para testar o CGI, estamos passando atravs do parmetro Idade (?idade=), a idade desejada para o clculo. Nosso CGI extrai atravs do mtodo Request.QueryFields o valor do parmetro Idade, e faz o clculo utilizando o mtodo QuantosDias do nosso Webservice. Com isso conclumos o nosso projeto.

WebServices 349

Listagem 13.3 un_teste_ws2.pas (teste modelo desktop)


unit un_teste_ws2; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, InvokeRegistry, Rio, SOAPHTTPClient, StdCtrls; type TForm1 = class(TForm) HR1: THTTPRIO; edIdade: TEdit; Button1: TButton; lbDias: TLabel; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation uses IwsIdade1; {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var IIdade: IwsIdade; begin IIdade:=HR1 as IwsIdade; lbDias.Caption:='Voc j viveu aproximadamente '+InttoStr(IIdade.QuantosDias(StrtoInt(edIdade.Text)))+' dias'; end; end.

Listagem 13.14 IwsIdade1 (implementao da Interface Idade)


// // // // // // // // ************************************************************************ // The types declared in this file were generated from data read from the WSDL File described below: WSDL : http://localhost/delphi/cgi-bin/ws2.exe/wsdl/IwsIdade Encoding : utf-8 Version : 1.0 (28/08/2002 19:06:33 - 1.33.2.5) ************************************************************************ //

unit IwsIdade1; interface uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns;

350 Delphi 7 Internet e Banco de Dados type // ************************************************************************ // // The following types, referred to in the WSDL document are not being represented // in this file. They are either aliases[@] of other types represented or were referred // to but never[!] declared in the document. The types from the latter category // typically map to predefined/known XML or Borland types; however, they could also // indicate incorrect WSDL documents that failed to declare or import a schema type. // ************************************************************************ // // !:int - "http://www.w3.org/2001/XMLSchema" // ************************************************************************ // // Namespace : urn:wsIdadeIntf-IwsIdade // soapAction: urn:wsIdadeIntf-IwsIdade#QuantosDias // transport : http://schemas.xmlsoap.org/soap/http // style : rpc // binding : IwsIdadebinding // service : IwsIdadeservice // port : IwsIdadePort // URL : http://localhost/delphi/cgi-bin/ws2.exe/soap/IwsIdade // ************************************************************************ // IwsIdade = interface(IInvokable) ['{28CE8152-2421-53DD-F897-0FAAB7C4FB3B}'] function QuantosDias(const idade: Integer): Integer; stdcall; end; function GetIwsIdade(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): IwsIdade; implementation function GetIwsIdade(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): IwsIdade; const defWSDL = 'http://localhost/delphi/cgi-bin/ws2.exe/wsdl/IwsIdade'; defURL = 'http://localhost/delphi/cgi-bin/ws2.exe/soap/IwsIdade'; defSvc = 'IwsIdadeservice'; defPrt = 'IwsIdadePort'; var RIO: THTTPRIO; begin Result := nil; if (Addr = '') then begin if UseWSDL then Addr := defWSDL else Addr := defURL; end; if HTTPRIO = nil then RIO := THTTPRIO.Create(nil) else RIO := HTTPRIO; try Result := (RIO as IwsIdade);

WebServices 351 if UseWSDL then begin RIO.WSDLLocation := Addr; RIO.Service := defSvc; RIO.Port := defPrt; end else RIO.URL := Addr; finally if (Result = nil) and (HTTPRIO = nil) then RIO.Free; end; end; initialization InvRegistry.RegisterInterface(TypeInfo(IwsIdade), 'urn:wsIdadeIntf-IwsIdade', 'utf8'); InvRegistry.RegisterDefaultSOAPAction(TypeInfo(IwsIdade), 'urn:wsIdadeIntfIwsIdade#QuantosDias'); end.

Listagem 13.15 un_cgi_ws2 (teste modelo CGI)


unit un_cgi_ws2; interface uses SysUtils, Classes, HTTPApp, InvokeRegistry, Rio, SOAPHTTPClient; type TWebModule1 = class(TWebModule) HR1: THTTPRIO; procedure WebModule1diasAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); private { Private declarations } public { Public declarations } end; var WebModule1: TWebModule1; implementation uses IwsIdade1; {$R *.dfm} procedure TWebModule1.WebModule1diasAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var IIdade: IwsIdade; begin IIdade:=HR1 as IwsIdade; Response.Content:='Voc j viveu aproximadamente '+InttoStr(IIdade.QuantosDias(StrtoInt(Request.QueryFields.Values['idade'])))+' dias';

352 Delphi 7 Internet e Banco de Dados end; end.

WebServices com Banco de Dados


Neste exemplo vamos criar nosso WebService que retorna informaes do nosso banco de dados. Nosso WebService consiste em fazer uma pesquisa em nossa tabela de clientes e retornar a Razo Social. Imagine que o cdigo do cliente uma espcie de C.G.C, onde qualquer contribuinte, seja pessoa fsica ou jurdica, teria acesso aos dados da empresa, em sua prpria aplicao. Atravs das opes File/New..., seo WebServices, selecione a opo SOAP Server Application (figura 13.35).

Figura 13.35 Nova aplicao WebService Em seguida selecione a opo CGI para o tipo da aplicao servidora SOAP (figura 13.36).

Figura 13.36 Tipo da aplicao servidora Na janela de dilogo que segue (figura 13.37), no confirme a criao da Interface.

WebServices 353

Figura 13.37 Criao da Interface Vamos gravar nossa aplicao. Unit WebModule Projeto un_ws3.PAS ws3.DPR

Agora vamos inserir um SOAP Data Module em nossa aplicao. Atravs das opes File/New..WebServices, selecione a opo SOAP Server Data Module (figura 13.38), e em seguida pressione OK.

Figura 13.38 Soap Server Data Module Em seguida (figura 13.39) informe o nome do nosso Soap Server Data Module, como ws3dm.

Figura 13.39 Module Name Grave a unit como un_ws3_dm.pas. Insira um objeto do tipo TSQLConnection. Atravs do duplo-clique, j na tela de configurao, aponte para a nossa conexo Clientes, criada anteriormente. Vamos relembrar os atributos da conexo.

354 Delphi 7 Internet e Banco de Dados

PROPRIEDADE

VALOR

CommitRetain Database Password UserName Name Altere tambm a propriedade LoginPrompt para false.

False localhost:c:\cursoweb\clientes.gdb a famosa masterkey o famoso SYSDBA ConexaoBD

Figura 13.40 Configurao da Conexo Agora vamos inserir o objeto para manipular nossa tabela de clientes. Insira um objeto do tipo TSQLDataSet, e altere as seguintes propriedades: PROPRIEDADE VALOR

SQLConnection CommandText Configure o tipo do parmetro pcodigo para Integer.

ConexaoBD select * from TBCLIENTE where COD_CLIENTE=:pcodigo

Agora vamos codificar a Interface do nosso WebService. Na unit un_ws3_dm, insira o cdigo que segue, adequando ao cdigo j existente.

WebServices 355 type Iws3dm = interface(IAppServerSOAP) ['{7D59A6B9-A6C8-4FC4-B105-C92A0CDA478B}'] function MostraRazao(codigo:integer):String; stdcall; end; Tws3dm = class(TSoapDataModule, Iws3dm, IAppServerSOAP, IAppServer) ConexaoBD: TSQLConnection; SQLClientes: TSQLDataSet; private public function MostraRazao(codigo:integer):String; stdcall; end; Repare que criamos o mtodo MostraRazao, que implementaremos agora na seo implementation. Agora, na seo implementation, insira completamente o cdigo a seguir: function Tws3dm.MostraRazao(codigo:integer):String; begin { configura o parmetro } SQLClientes.ParamByName('pcodigo').Value:=codigo; SQLClientes.Open; if not(SQLClientes.Eof) then Result:=SQLClientes.FieldValues['RAZAO_SOCIAL'] else Result:='Cliente inexistente'; SQLClientes.Close; end; Vamos analisar o cdigo. No bloco a seguir, estamos atribuindo o cdigo transmitido atravs do Client em nosso parmetro e abrindo o DataSet. SQLClientes.ParamByName('pcodigo').Value:=codigo; SQLClientes.Open; Em seguida, verificamos a existncia do cliente, e em caso afirmativo retornamos o valor do campo Razao_Social, caso contrrio, retornamos a mensagem Cliente inexistente !. E para finalizar, fechamos o nosso DataSet. if not(SQLClientes.Eof) then Result:=SQLClientes.FieldValues['RAZAO_SOCIAL'] else Result:='Cliente inexistente'; SQLClientes.Close; O nosso WebService est prontinho pra ser utilizado. Agora vamos criar nossas aplicaes Client. Atravs das opes File/New Application crie uma nova aplicao e grave os arquivos como segue: Unit Projeto un_teste_ws3.PAS teste_ws3.DPR

Agora vamos importar a Interface em nossa aplicao. Atravs das opes File/New.../WebServices (figura 13.41), selecione a opo WSDL Importer.

356 Delphi 7 Internet e Banco de Dados

Figura 13.41 WSDL importer Em seguida, como ilustra a figura 13.42 , digite o endereo que segue. http://localhost/cgi-bin/ws3.exe/wsdl/Iws3DM Este endereo faz a chamada ao documento WSDL da Interface Iws3DM.

Figura 13.42 Importando a Interface O assistente gerou uma Unit com toda a Interface implementada. Grave a Unit com o nome Iws3Dm1.pas. Agora com o foco na unit un_teste_ws3, insira a unit Iws3DM1.pas gerada pelo assistente. implementation uses Iws3DM1; Neste ponto iremos configurar o acesso para este formulrio. Insira um objeto do tipo THTTPRIO e configure as propriedades que seguem, respeitando a seqncia apresentada, caso contrrio, uma exceo ocorrer.

WebServices 357

OBJETO THTTPRio Objeto HTTPRio1 Propriedade Name WSDLLocation Valor HR1 http://localhost/cgi-bin/ ws3.exe/wsdl/Iws3dm Iws3dmservice Iws3DmPort

Service Port

Com isto configuramos o objeto de acesso Interface, informando a localizao do documento WSDL (WSDLLocation), o servio (Service), e a porta (Port). Agora insira os objetos que seguem, configurando suas respectivas propriedades.

OBJETO TEdit Objeto edCodigo Propriedade Name Left Text Top Width Valor edCodigo 32 deixe em branco 24 120

OBJETO TButton Objeto Button1 Propriedade Name Caption Left Top Width Valor Button1 Pesquisa 176 24 125

OBJETO Tlabel Objeto lbRazao Propriedade Name Caption Left Top Valor lbRazao Cliente 32 64

358 Delphi 7 Internet e Banco de Dados A figura 13.43 ilustra o formulrio da nossa aplicao.

Figura 13.43 Formulrio aplicao teste3 Agora vamos implementar o cdigo do formulrio. No evento OnClick do boto, insira o cdigo que segue: var IRazao:IWS3DM; begin IRazao:=HR1 as IwS3DM; lbRazao.Caption:=Irazao.MostraRazao( StrtoInt( edCodigo.Text )); end; Estamos fazendo uma operao bastante simples, passando o parmetro cdigo para o nosso WebService e apresentando o resultado no objeto lbRazao. As figuras 13.44 e 13.45 ilustram nossa aplicao em tempo de execuo.

Figura 13.44 Cliente encontrado

Figura 13.45 Cliente inexistente Amigos, isto fantstico, no ? Agora vamos desenvolver uma aplicao no padro CGI para consultar a razo social de um cliente. A partir do Delphi, selecione as opes File/New/Other... e em seguida a opo Web Server Application, como ilustra a figura 13.46.

WebServices 359

Figura 13.46 Opo Web Server Application Na janela seguinte selecione a opo CGI Stand-Alone executable (figura 13.47).

Figura 13.47 Seleo do tipo da aplicao Em seguida teremos o nosso WebModule (figura 13.48).

figura 13.48 WebModule

360 Delphi 7 Internet e Banco de Dados Neste ponto ao invs de importar o WSDL, vamos apenas adicionar a unit que j importamos em nossa primeira aplicao: Iws3DM; implementation uses Iws3DM; Neste ponto iremos configurar o acesso para o nosso CGI. Insira um objeto do tipo THTTPRIO e configure as propriedades que seguem, respeitando a seqncia apresentada, caso contrrio, uma exceo ocorrer.

OBJETO THTTPRio Objeto HTTPRio1 Propriedade Name WSDLLocation Valor HR1 http://localhost/cgi-bin/ ws3.exe/wsdl/Iws3dm Iws3dmservice Iws3DmPort

Service Port

Agora vamos criar nossa Action. Atravs do duplo-clique no WebModule, acesse o editor de ActionItems (figura 13.49).

Figura 13.49 editor ActionItems Clique no primeiro boto do editor para inserir uma nova Action (figura 13.50).

Figura 13.50 ActionItem Em seguida altere as seguintes propriedades.

WebServices 361

OBJETO TWebActionItem Objeto Padrao Propriedade Default Name PathInfo Valor True consulta /consulta

Esta ser nossa Action padro, ou seja, caso o usurio no digite nada, alm do nome da nossa aplicao, esta Action ser executada. No evento OnAction coloque o seguinte cdigo: var IRazao: Iws3DM1; begin IRazao:=HR1 as Iws3DM; Response.Content:='Cliente = '+ IRazao.MostraRazao(StrtoInt(Request.QueryFields. Values['codigo'])); end; Aqui estamos utilizando o mtodo Response.Content para apresentar ao usurio a mensagem criada atravs do parmetro codigo, utilizando o mtodo MostraRazao do nosso WebService. Antes de compilar, vamos definir o diretrio para gerao do nosso WebService. Atravs das opes Project/Options.../Directories_Conditionals, configure a opo Output Directory, apontando para o seu diretrio cgi-bin (figura 13.51).

Figura 13.51 Configurao do diretrio Grave os arquivos como segue. Unit Projeto un_cgi_ws3.PAS teste_cgi_ws3.DPR

362 Delphi 7 Internet e Banco de Dados Agora vamos testar a nossa aplicao. No browser digite o seguinte endereo:

http://localhost/delphi/cgi-bin/teste_cgi_ws3.exe/consulta? codigo=14
A figura 13.52 ilustra nosso CGI em tempo de execuo.

figura 13.52 Resultado da aplicao Agora deu para perceber o poder do WebService, no? No prximo tpico, iremos desenvolver uma aplicao utilizando o protocolo SOAP em conjunto com a tecnologia DataSNAP.

Listagem 13.16 un_teste_ws3.pas


unit un_teste_ws3; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, InvokeRegistry, Rio, SOAPHTTPClient, StdCtrls; type TForm1 = class(TForm) edCodigo: TEdit; lbRazao: TLabel; Button1: TButton; HR1: THTTPRIO; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation uses iws3dm1; {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var IRazao:IWS3DM; begin IRazao:=HR1 as IwS3DM;

WebServices 363 lbRazao.Caption:=Irazao.MostraRazao(StrtoInt(edCodigo.Text)); end; end.

Listagem 13.17 Interface Iws3DM


// // // // // // // // ************************************************************************ // The types declared in this file were generated from data read from the WSDL File described below: WSDL : http://localhost/delphi/cgi-bin/ws3.exe/wsdl/Iws3Dm Encoding : utf-8 Version : 1.0 (01/09/2002 12:34:46 - 1.33.2.5) ************************************************************************ //

unit Iws3Dm1; interface uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns, SOAPMidas; type // ************************************************************************ // // The following types, referred to in the WSDL document are not being represented // in this file. They are either aliases[@] of other types represented or were referred // to but never[!] declared in the document. The types from the latter category // typically map to predefined/known XML or Borland types; however, they could also // indicate incorrect WSDL documents that failed to declare or import a schema type. // ************************************************************************ // // !:string - "http://www.w3.org/2001/XMLSchema" // !:int - "http://www.w3.org/2001/XMLSchema" // ************************************************************************ // // Namespace : urn:un_ws3_dm-Iws3dm // soapAction: urn:un_ws3_dm-Iws3dm#MostraRazao // transport : http://schemas.xmlsoap.org/soap/http // style : rpc // binding : Iws3dmbinding // service : Iws3dmservice // port : Iws3DmPort // URL : http://localhost/delphi/cgi-bin/ws3.exe/soap/Iws3Dm // ************************************************************************ // Iws3dm = interface(IAppServerSOAP) ['{B8148078-61EE-65BD-6196-A55E0A9CA57C}'] function MostraRazao(const codigo: Integer): WideString; stdcall; end;

implementation initialization

364 Delphi 7 Internet e Banco de Dados InvRegistry.RegisterInterface(TypeInfo(Iws3dm), 'urn:un_ws3_dm-Iws3dm', 'utf-8'); InvRegistry.RegisterDefaultSOAPAction(TypeInfo(Iws3dm), 'urn:un_ws3_dmIws3dm#MostraRazao'); end.

Listagem 13.18 un_cgi_ws3


unit un_cgi_ws3; interface uses SysUtils, Classes, HTTPApp, InvokeRegistry, Rio, SOAPHTTPClient; type TWebModule1 = class(TWebModule) HR1: THTTPRIO; procedure WebModule1consultaAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); private { Private declarations } public { Public declarations } end; var WebModule1: TWebModule1; implementation uses Iws3DM1; {$R *.dfm} procedure TWebModule1.WebModule1consultaAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var IRazao: Iws3DM; begin IRazao:=HR1 as Iws3DM; Response.Content:='Cliente ='+IRazao.MostraRazao(StrtoInt(Request.QueryFields.Values['codigo'])); end; end.

SOAP DataSnap XML


Neste exemplo vamos criar um WebService que fornece um modelo de comunicao de dados muito interessante. O protocolo SOAP responsvel pelo transporte das informaes e a tecnologia DataSnap pelo fornecimento e empacotamento dos dados. Teremos ainda, uma aplicao de teste bastante simples. Bem, vamos iniciar o desenvolvimento do nosso WebService. Atravs das opes File/New..., seo WebServices, selecione a opo SOAP Server Application (figura 13.53).

WebServices 365

Figura 13.53 Nova aplicao WebService Em seguida, selecione a opo CGI para o tipo da aplicao servidora SOAP (figura 13.54).

Figura 13.54 Tipo da aplicao servidora Na janela de dilogo que segue (figura 13.55), no confirme a criao da Interface.

Figura 13.55 Criao da Interface Vamos gravar nossa aplicao.

366 Delphi 7 Internet e Banco de Dados Unit WebModule Projeto un_ws4.PAS ws4.DPR

Agora vamos inserir um SOAP Data Module em nossa aplicao. Atravs das opes File/New..WebServices, selecione a opo SOAP Server Data Module (figura 13.56), e em seguida pressione OK.

Figura 13.56 Soap Server Data Module Em seguida (figura 13.57) informe o nome do nosso Soap Server Data Module, como ws4dm.

Figura 13.57 Module Name Grave a unit como un_ws4_dm.pas. Insira um objeto do tipo TSQLConnection. Atravs do duplo-clique, j na tela de configurao, aponte para a nossa conexo Clientes, criada anteriormente. Vamos relembrar os atributos da conexo. PROPRIEDADE VALOR

CommitRetain Database Password UserName Name

False localhost:c:\cursoweb\clientes.gdb a famosa masterkey o famoso SYSDBA ConexaoBD

WebServices 367 Altere tambm a propriedade LoginPrompt para false.

Figura 13.58 Configurao da Conexo Agora vamos inserir o objeto para manipular nossa tabela de clientes. Insira um objeto do tipo TSQLDataSet, e altere as seguintes propriedades: PROPRIEDADE VALOR

SQLConnection CommandText Name Active

ConexaoBD select * from TBCLIENTE SQLClientes True

Insira um objeto do tipo TDataSetProvider para fornecer os dados de nosso DataSet a qualquer cliente conectado em nossa aplicao. PROPRIEDADE VALOR

DataSet Name

SQLClientes DataSetProvider1

Antes de compilar, vamos definir o diretrio para gerao do nosso WebService. Atravs das opes Project/Options.../Directories_Conditionals, configure a opo Output Directory, apontando para o seu diretrio cgi-bin (figura 13.59).

368 Delphi 7 Internet e Banco de Dados

Figura 13.59 Configurao do diretrio Grave e compile a aplicao. Agora vamos construir nossa aplicao Client. Atravs das opes File/New Application crie uma nova aplicao e grave os arquivos como segue: Unit Projeto un_teste_ws4.PAS teste_ws4.DPR

Agora insira um objeto do tipo TSOAPConnection e altere as propriedades que seguem: PROPRIEDADE VALOR

URL Name Connected

http://localhost/cgi-bin/ ws4.exe/soap/Iws4dm SOAPConnection1 True

Perceba que estamos utilizando o mtodo SOAP do nosso WebService. Agora, insira um objeto do tipo TClientDataSet e altere as seguintes propriedades. PROPRIEDADE VALOR

RemoteServer ProviderName Active

SoapConnection1 DataSetProvider1 True

Atravs do duplo-clique no objeto ClientDataSet1, insira os campos, como ilustra a figura 13.60.

WebServices 369

Figura 13.60 Campos do ClientDataSet1 Agora, selecione todos os campos e arraste para o formulrio, dimensionando como sugere a figura 13.61.

Figura 13.61 Formulrio exemplo Com a propriedade Active do ClientDataSet1 configurada como True, execute a aplicao e veja o resultado (figura 13.62).

Figura 13.62 Aplicao em execuo Amigos, com isso conclumos nosso captulo de WebServices.

370 Delphi 7 Internet e Banco de Dados

Listagem 13.19 un_ws4_dm.pas


Unit un_ws4_dm; interface uses SysUtils, Classes, InvokeRegistry, Midas, SOAPMidas, SOAPDm, DBXpress, FMTBcd, DB, SqlExpr, Provider; type Iws4dm = interface(IAppServerSOAP) ['{CA9392ED-702B-4596-A577-E341279D98D4}'] end; Tws4dm = class(TSoapDataModule, Iws4dm, IAppServerSOAP, IAppServer) ConexaoBD: TSQLConnection; SQLClientes: TSQLDataSet; DataSetProvider1: TDataSetProvider; private public end; implementation {$R *.DFM} procedure Tws4dmCreateInstance(out obj: TObject); begin obj := Tws4dm.Create(nil); end; initialization InvRegistry.RegisterInvokableClass(Tws4dm, Tws4dmCreateInstance); InvRegistry.RegisterInterface(TypeInfo(Iws4dm)); end.

Listagem 13.20 un_teste_ws4.pas


unit un_teste_ws4; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, DB, DBClient, SOAPConn, StdCtrls, Mask, DBCtrls, ExtCtrls; type TForm1 = class(TForm) SoapConnection1: TSoapConnection; ClientDataSet1: TClientDataSet; ClientDataSet1COD_CLIENTE: TIntegerField; ClientDataSet1RAZAO_SOCIAL: TStringField; ClientDataSet1ENDERECO: TStringField; ClientDataSet1CIDADE: TStringField; ClientDataSet1ESTADO: TStringField; ClientDataSet1CEP: TStringField;

WebServices 371 ClientDataSet1EMAIL: TStringField; Label1: TLabel; DBEdit1: TDBEdit; DataSource1: TDataSource; Label2: TLabel; DBEdit2: TDBEdit; Label3: TLabel; DBEdit3: TDBEdit; Label4: TLabel; DBEdit4: TDBEdit; Label5: TLabel; DBEdit5: TDBEdit; Label6: TLabel; DBEdit6: TDBEdit; Label7: TLabel; DBEdit7: TDBEdit; DBNavigator1: TDBNavigator; private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} end.

372 Delphi 7 Internet e Banco de Dados

Anotaes de Dvidas

?
Preciso Revisar

Anotaes Gerais

Potrebbero piacerti anche