372
Introdução 1 Capítulo 1 Introdução (R)evolução “(R)evolução”. Amigos, esta é a palavra mais falada pelos desenvolvedores Delphi quando fazem o primeiro contato com a versão 7 do produto. Uns dizem evolução, outros revolução. Particularmente acho que o Delphi amadureceu de uma forma extraordinária, e que a equipe de negócios do produto conseguiu quebrar algumas barreiras importantes, como a incorporação de um excelente gerador de relatórios, 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 aplicações 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 aplicações Web. Veja que não quero desprezar a tecnologia existente desde a versão 3 do produto, nem a nova tecnologia WebSnap, introduzida na versão 6. Pelo contrário, ainda apóio fortemente tais tecnologias, mas ganhamos um forte aliado: IntraWeb. Podem ficar tranqüilos, teremos um capítulo inteiro sobre o nosso mais novo companheiro. Aproveitando o embalo das apresentações, no próximo tópico veremos todo o potencial do Delphi 7 em todas as suas distribuições, inclusive da novíssima Studio Architect. Novidades do Delphi 7 Primeiramente, irei apresentar as mudanças na nova versão do Delphi e, em seguida, uma tabela comparativa entre as suas distribuições. Nas mensagens de compilação, poderemos obter novas informações através do site da Borland, com um link direto da mensagem. Maior controle sobre os famosos “warnings” ou “advertências” que são geradas. Uma nova seção System para aplicações CLX, com diversos controles de diretórios e arquivos. Anteriormente tais controles estavam disponíveis somente para aplicações VCL. Novas implementações da Nevrona, com melhorias no pacote Indy Components, trazendo Indy Intercepts e Indy I/O Handlers, facilitando ainda mais o desenvolvimento de aplicações para Internet. O poderosíssimo IntraWeb, com as seções IW Standard, IW Data, IW Client Side e IW Control. Para quem reclamava do QuickReport, não pode mais chorar. O Delphi 7 traz consigo o poderoso Rave Reports, com superioridade absoluta em relação ao QR. A cada nova versão, a equipe de desenvolvimento melhora o Code Insight. Agora o code completion (uns dos fortes atrativos do Code Insight) está bem mais rápido, e com inteligência artificial (este é por minha conta). Sem sombra de dúvidas ficou bem mais esperto e rápido. 1

Delphi 7 Internet e Banco de Dados - Facunte

Embed Size (px)

Citation preview

Page 1: Delphi 7 Internet e Banco de Dados - Facunte

Introdução 1

Capítulo 1

Introdução

(R)evolução “(R)evolução”. Amigos, esta é a palavra mais falada pelos desenvolvedores Delphi quando fazem o primeiro contato com a versão 7 do produto. Uns dizem evolução, outros revolução. Particularmente acho que o Delphi amadureceu de uma forma extraordinária, e que a equipe de negócios do produto conseguiu quebrar algumas barreiras importantes, como a incorporação de um excelente gerador de relatórios, 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 aplicações 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 aplicações Web. Veja que não quero desprezar a tecnologia existente desde a versão 3 do produto, nem a nova tecnologia WebSnap, introduzida na versão 6. Pelo contrário, ainda apóio fortemente tais tecnologias, mas ganhamos um forte aliado: IntraWeb. Podem ficar tranqüilos, teremos um capítulo inteiro sobre o nosso mais novo companheiro. Aproveitando o embalo das apresentações, no próximo tópico veremos todo o potencial do Delphi 7 em todas as suas distribuições, inclusive da novíssima Studio Architect.

Novidades do Delphi 7 Primeiramente, irei apresentar as mudanças na nova versão do Delphi e, em seguida, uma tabela comparativa entre as suas distribuições.

!" Nas mensagens de compilação, poderemos obter novas informações através do site da Borland, com um link direto da mensagem.

!" Maior controle sobre os famosos “warnings” ou “advertências” que são geradas. !" Uma nova seção System para aplicações CLX, com diversos controles de diretórios e arquivos. Anteriormente tais

controles estavam disponíveis somente para aplicações VCL. !" Novas implementações da Nevrona, com melhorias no pacote Indy Components, trazendo Indy Intercepts e Indy I/O

Handlers, facilitando ainda mais o desenvolvimento de aplicações para Internet. !" O poderosíssimo IntraWeb, com as seções IW Standard, IW Data, IW Client Side e IW Control. !" Para quem reclamava do QuickReport, não pode mais chorar. O Delphi 7 traz consigo o poderoso Rave Reports, com

superioridade absoluta em relação ao QR. !" A cada nova versão, a equipe de desenvolvimento melhora o Code Insight. Agora o code completion (uns dos fortes

atrativos do Code Insight) está bem mais rápido, e com inteligência artificial (este é por minha conta). Sem sombra de dúvidas ficou bem mais esperto e rápido.

1

Page 2: Delphi 7 Internet e Banco de Dados - Facunte

2 Delphi 7 – Internet e Banco de Dados

!" Temos também um code completion para código HTML. !" Você também poderá criar seus próprios administradores code completion, através da OpenTools. !" Para quem não dispensa as Watch Lists, irá babar com as melhorias: múltiplas seções para organizar suas watchs

(seus vigilantes, observadores) através de grupos. Controle completo sobre a visão das watchs. !" Possibilidade de compilar projetos por grupo através do Project Manager. !" A seção Message View foi dividida em diversas abas para apresentar diferentes tipos de mensagens (Build, Search, e

outros). !" Agora podemos selecionar múltiplos componentes na opção View/Component List. !" O editor suporta diferentes tipos de linguagem: Pascal, C++, C#, HTML e XML. !" Possibilidade de visualizar graficamente “tabs” e “espaços” no editor de código. !" Melhorias para o desenvolvedor Web, com a inclusão do IntraWeb (perceberam como estou feliz, só falo nele),

suporte ao Apache2 (com todas as suas melhorias e recursos) e exclusão do desenvolvimento de aplicações Win-CGI (16 bits).

!" Um novo browser UDDI para WebServices, e também novas classes e interfaces para o SOAP. TSoapAttachments, a grande novidade, onde podemos enviar através do SOAP, mensagens com anexo, utilizando multipart form. Tipos de definições são registrados automaticamente. Agora temos um evento poderoso: THTTPReqResp, onde podemos monitorar o pacote de mensagens, enquanto as mesmas são transmitidas.

!" Novos drivers para o dbExpress, trazendo Informix SE, Oracle 9i, DB2 7.2, Interbase 6.5, MySQL 3.23.49, MSSQL-2000 (uma das grandes novidades).

!" A Borland desaprova o uso dos SQLLinks, e não disponibiliza mais suporte nas próximas versões do Delphi (após 2002). Ela recomenda a utilização da tecnologia dbExpress, que sinceramente, vem melhorando a cada versão.

!" Suporte a Windows XP Themes nas versões Professional e Enterprise. !" A nova unit DBClientActns, com 3 novas classes: TClientDataSetApply, TClientDataSetUndo,

TClientDataSetRevert. !" E os novos componentes dbExpress: TSimpleDataSet para aplicações simples e de 2-camadas (TSimpleDataSet

substitui TSQLClientDataSet). !" Diversos componentes visuais e de diálogo para CLX. !" Melhorias na unit Math. !" Model-Maker. Para quem nunca ouviu falar em UML, sugiro conhecer esta importante especificação. No Delphi 7, a

partir da versão Studio Enterprise, temos uma excelente ferramenta específica para integração UML-Delphi-UML. !" E muito mais.

Para que você tenha uma idéia de qual versão adquirir, a Borland disponibiliza a sua tabela comparativa. Resolvi adaptá-la, fazendo breves comentários, para que você tenha uma idéia mais clara sobre as diferenças de versões. Nesta tabela são apresentadas somente as novidades do produto. Para maiores informações, sugiro uma visita ao site da Borland Latin América: www.borland.com.br

Tabela de características .NET

Características Studio

Architect Studio

Enterprise Studio

Professional Personal Edition

. NET (Interoperabilidade e suporte a migração)

"

Compilador compatível com .NET, abrangendo “warnings” e “hints” # # # #

Importa qualquer objeto .COM no padrão .NET # # # #

Exporta objetos .COM desenvolvidos em Delphi para aplicações .NET

# # # #

Page 3: Delphi 7 Internet e Banco de Dados - Facunte

Introdução 3

. Delphi™ para Microsoft®

.NET prerelease preview

.NET preview compilador CIL para linguagem Delphi # # # #

Migração para documentação .NET # # # #

Tabela de características Model Maker

Características Studio

Architect Studio

Enterprise Studio

Professional Personal Edition

Tecnologia Model Maker "

Design modelagem dirigida # # Modelagem Visual, baseada em UML # #

Engenharia reversa com visualização instantânea, integrada ao Delphi

# #

Minha opinião

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 saudável para todos nós. Para terem uma idéia do que estou querendo dizer, a Borland sempre suportou em seus

produtos tecnologias de ponta, como Java, Object Pascal, C++ e agora .NET.

Minha opinião

Atualmente estamos vivendo uma fase bem madura de desenvolvimento de

software. Antigamente tínhamos aqueles “fantasmagóricos” fluxogramas,passando pela modelagem de dados, e agora, três vivas: UML (Unified

Modeling Language, ou Linguagem de Modelagem Unificada). Ao

contrário dos outros métodos, a UML é uma linguagem de modelagem muito usual em empresas fabricantes de software. E o mais incrível, foi

estendida para outros tipos de segmentos, como automóveis, 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. Além dos fortes

benefícios, está se tornando uma grande exigência para desenvolvedores,

analistas e coordenadores de projetos, além, é claro, dos gerentes.

Page 4: Delphi 7 Internet e Banco de Dados - Facunte

4 Delphi 7 – Internet e Banco de Dados

Tabela de características Intraweb

Características Studio

Architect Studio

Enterprise Studio

Professional Personal Edition

Tecnologia IntraWeb (AtoZed)

"

Desenvolvimento de aplicações WEB utilizando recursos visuais no estilo drag-and-drop.

# # #

Adicione conteúdo interativo para seus sites, de maneira rápida e visual

# # #

Controle transparente de cookies e sessions # #

Grande variedade de componentes visuais para Web #" #" #

Tabela de características Nevrona Rave Reports

Características Studio

Architect Studio

Enterprise Studio

Professional Personal Edition

Rave Report versão Delphi "

Poderoso gerador de relatórios Rave, com desenho visual de relatórios e código baseado em API

# # #

Gera PDF, HTML, RTF e formato texto

# # #

Suporte nativo para VCL e CLX # # #

Estilo flexível de layout #" #" #

Minha opinião

Quando tive meu primeiro contato com o IntraWeb pensei: essa é a grandesolução para o maior problema: prazo. Amigos, sem sombra de dúvidas, o

IntraWeb otimiza diversas tarefas no desenvolvimento de aplicações Web. Até

mesmo quem não entende nada de HTML, JavaScript, desenvolve poderosasaplicações 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, não requer um grandetreinamento.

Com o capítulo dedicado a esta incrível ferramenta, tenho certeza de quetodos vocês estarão desenvolvendo aplicações para Internet com extrema

facilidade.

Outro ponto bastante importante é que a Borland fechou diversas parceriaspara o seu novo produto, sempre pensando em disponibilizar o que há de

melhor no mercado para nós desenvolvedores.

Page 5: Delphi 7 Internet e Banco de Dados - Facunte

Introdução 5

Tabela de características Bold for Delphi

Características Studio Architect

Studio Enterprise

Studio Professional

Personal Edition

Bold versão Delphi (BoldSoft)

"

Assegura menor código utilizando o padrão MDA (Model Driven Architecture)

#

UML. Suporte total para diagramas de classes, valores identificados, entre outros

#

Integração com Rational Rose® e Model Maker®. #

IDE

A IDE do Delphi 7 (figura 1.1) é muito parecida com a versão anterior. Basicamente mudou o seu visual, muito semelhante ao Windows XP. Vamos dar uma rápida olhadinha.

Minha opinião

Continuando com o nosso amigo UML, o conjunto de ferramentas da BoldSoft

vem para complementar o suporte do Model Maker. Através 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”.

Minha opinião

Amigos, alguém lembra do QuickReport? Eu já esqueci, nem sei do que estamos

falando!

Brincadeiras à parte, finalmente ganhamos um gerador de relatórios bastanteprofissional. A nossa Mãe-Borland conseguiu quebrar algumas barreiras para que

esse sonho fosse realizado, e todos nós ganhamos com isso. O Rave Reports da

inovadora e genial empresa Nevrona (a mesma criadora do Indy Componentes) émuito estável e traz diversos recursos que facilitam a vida do desenvolvedor.

Sugiro que criem coragem de aprender um novo gerador de relatórios. Digo issoporque ao longo de minha carreira presenciei diversas pessoas e equipes que

relutaram em adotar um novo gerador de relatórios, por diversas crenças: “Será quea empresa que produz o software vai manter a compatibilidade? Será que a empresa

não vai quebrar? Acho muito difícil este software!” Entre outras...

Page 6: Delphi 7 Internet e Banco de Dados - Facunte

6 Delphi 7 – Internet e Banco de Dados

Figura 1.1 IDE Delphi 7

Como este livro está voltado para o desenvolvimento de aplicação para Internet, vamos conhecer algumas novidades. A figura 1.2 ilustra a nova seção de objetos Web Documents. Sua principal função é de auxiliar na criação dos principais tipos de documentos Web.

Figura 1.2 Nova seção Web Documents

Outra grande novidade é o nosso amigo Intraweb (figuras 1.3, 1.4, 1.5, 1.6 e 1.7) que ganhou um capítulo inteiro neste livro.

Page 7: Delphi 7 Internet e Banco de Dados - Facunte

Introdução 7

Figura 1.3 Seção Intraweb

Figura 1.4 Paleta IWStandard (IntraWeb)

Figura 1.5 Paleta IWData (IntraWeb)

Figura 1.6 Paleta IW Client Side (IntraWeb)

Page 8: Delphi 7 Internet e Banco de Dados - Facunte

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 padrão CLX, só para o desenvolvimento de aplicações Web? Vocês 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 questão. Por isso um livro especializado em Internet, focado no desenvolvimento de aplicações e-Business. E o já consagrado WebSnap? Uma das estrelas da versão 6, ganhou algumas melhorias e as devidas correções 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 vêm surgindo no mercado. A figura 1.9 ilustra a seção

de WebServices do Delphi 7, e a figura 1.10, a paleta de componentes.

Figura 1.9 Seção WebServices

Figura 1.10 Paleta WebServices

Page 9: Delphi 7 Internet e Banco de Dados - Facunte

Introdução 9

Amigos, tivemos uma breve apresentação dos novos recursos do Delphi 7 na área de desenvolvimento para Web. A seguir teremos uma introdução bastante importante sobre o desenvolvimento de aplicações e-Business, bem como sobre o Método Facunte.

Visão geral do e-Business No cenário 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 evolução do mercado de desenvolvimento:

MEADOS PLATAFORMA (*) LINGUAGENS/FERRAMENTAS 80 a 90

Unix, IBM, DOS

Cobol, Dataflex, C, C++, Clipper

91 a 94

DOS, Windows

DataFlex, Clipper, Fox, Visual Basic

94 a 97

DOS, Windows

Clipper, Visual Basic, Delphi

98 e 99

Windows, Internet

Visual Basic, Delphi, ASP, PHP

00 a 01

Windows, Linux, Internet, Intranet, Extranet

Visual Basic, Delphi, Kylix, ASP, PHP, ColdFusion, Java

02 tendências

Cross-plataform, objetos distribuídos

. NET, Delphi, Kylix, Corba (ORB), Java, SOAP, SNAP (Web Services)

TABELA 1 EVOLUÇÃO DO MERCADO DE DESENVOLVIMENTO (*) Principais tecnologias

Como observamos na Tabela 1, o mercado evoluiu muito após a década de 90, tornando confusa a decisão do desenvolvedor na escolha da melhor tecnologia. Para ajudar os desenvolvedores da “velha-guarda”, bem como os da “nova-geração”, foi criado o MÉTODO FACUNTE (falaremos do método em seguida). Bem, Método à parte, falaremos da forte tendência para esta década que, conforme a Tabela 1, é o desenvolvimento Cross-Plataform e Objetos Distribuídos. Mas o que são estas novas tecnologias? Será que são novas mesmo? Vamos iniciar pela tendência Cross-Plataform. Cross-Plataform quer dizer que a aplicação “roda” em duas ou mais plataformas. Isso é excelente, já que estamos num mercado bastante disputado; Windows melhorando, Linux cativando grandes legiões de “adeptos”, e quem sabe o Lindows1 avança no mercado. Agora vamos imaginar nossa aplicação sendo executada em qualquer ambiente operacional. Não é ótimo? Já pensou em oferecer ao seu cliente um produto Cross-Plataform? Tenho certeza de que aumentarão muito as chances de vender o produto. OK, e os Objetos-Distribuídos? Bem, esse é o ponto. Vamos imaginar o seguinte cenário:

!" Aplicação de Controle de Estoque sendo acessada pela LOJA. !" Faturamento acessando informações de Vendas.

1 Lindows – Sistema operacional baseado no LINUX, que traz consigo a tecnologia WINE (kernel para execução de aplicações baseadas em Win32).

Page 10: Delphi 7 Internet e Banco de Dados - Facunte

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 através da Internet. !" Setor de compras fechando pedidos com Fornecedores. !" Compensação automática de crédito/débito da Rede Bancária. !" Vendedores externos fechando negócios com PALM TOPS.

Sem dúvida é um sistema dos sonhos de qualquer empresário e desenvolvedor. Agora imagine efetuar uma manutenção no sistema sem interromper as atividades normais (não vá pensar em atualizar o sistema as 02:00 da manhã, hein?! Isso não é tudo). Vamos melhorar o nosso “lado”? Com a tecnologia de Objetos-Distribuídos podemos criar diversas camadas:

!" Camada de Negócios !" Camada da Aplicação Cliente !" Camada da Aplicação Servidor !" Camada Aplicação Servidor-WEB !" Camada Banco de Dados !" entre outras

Para realizar as tarefas de manutenção no sistema, o desenvolvedor poderá alterar apenas a camada que satisfaz a ocasião. Outro fator bastante interessante é que as camadas podem e devem ficar em servidores diferentes, específicos 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 aplicação em diversas plataformas, certo? Então temos aqui um caso típico de Cross-Plataform – tudo bem, no nível de Client e não Server – eu explico: Desenvolver uma aplicação 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 aplicação, mesmo que o sistema operacional não fosse Win X. Exemplo: Linux, Mac OS, Solaris, celulares com browser baseado em JAVA (esqueça WAP por enquanto), PALM com acesso à Internet, entre outros. Viram que magnífico? Em resumo, o objetivo deste livro é o desenvolvimento de uma Camada Web, uma das grandes tendências desta década.

Método FACUNTE O Método Facunte foi criado em 2001 inspirado nas necessidades de desenvolvedores iniciantes e dos amigos da “velha-guarda” que não tinham base formada sobre qual tecnologia adotar. O método consiste num treinamento completo para o desenvolvedor, abrangendo desde as tendências do mercado, passando por orientações financeiras de projeto, até o desenvolvimento prático de uma aplicação, utilizando ferramentas de alta tecnologia e comumente aceitas como padrão de mercado. No diagrama a seguir temos a representação gráfica do método.

Page 11: Delphi 7 Internet e Banco de Dados - Facunte

Introdução 11

Aspectos Gerais para o Desenvolvimento de Aplicações Web O desenvolvimento de aplicações para web difere do método tradicional em alguns pontos:

!" Aplicações são executadas no browser (Internet Explorer, Netscape, etc.); !" Para construir formulários utilizamos HTML; !" Integração com diversas tecnologias: Flash, JavaScript, Java.

Devemos esquecer alguns costumes do método tradicional, como por exemplo:

!" Grids; !" Barras de navegação entre registros; !" Botões de funções para todos os lados; !" Sobreposição excessiva de janelas.

Os referidos costumes degradam muito a performance do servidor de aplicações e de banco de dados, além de confundir o usuário 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 esforço 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 opinião deve ser seguido, mas novos conceitos deverão ser criados, e até mesmo outros tipos de interfaces existentes no mercado devem ser analisadas. Procure sempre o melhor para o usuário.

SucessoMétodoFacunte

Desenvol-vimento

Como e Quanto Cobrar do Cliente

Definição do Projeto

Quais tecnologias devemos adotar / Aprendizado

Tendências do Mercado

Page 12: Delphi 7 Internet e Banco de Dados - Facunte

12 Delphi 7 – Internet e Banco de Dados

Como está o mercado de trabalho Desenvolvedores de aplicações para web, ou melhor, e-business developers, estão muito bem cotados no mercado atual. Basta olhar para empresas como Oracle, Siebel, Jd Edwards, SAP, People Software, que estão criando ou migrando seus produtos para a tecnologia WEB. Veja a média de salários para desenvolvedores WEB.

cargo desenvolvedor tradicional

desenvolvedor web

desenvolvedor jr R$ 800 a R$ 1200 R$ 1200 a R$ 1800 desenvolvedor pleno R$ 1000 a R$ 2000 R$ 1800 a R$ 3500 desenvolvedor sênior R$ 2000 a R$ 4000 R$ 3000 a R$ 8000 Gerente de projetos R$ 2000 a R$ 6000 R$ 4000 a R$ 12000 arquiteto web - R$ 6000 a R$ 10000 consultor R$ 20 a R$ 50/hora 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 cenário. Claro que aqueles que entrarem antes no mercado serão altamente beneficiados. Não se assustem com as quebradeiras das empresas pontocom, pois este tipo de trabalho não se restringe a este seguimento. O que estamos mostrando aqui é que qualquer empresa pode contratar os serviços de um desenvolvedor web, desde a lojinha de autopeças da esquina, até as grandes corporações.

Como definir os custos de um projeto Quantas e quantas vezes nós desenvolvedores falamos a seguinte frase: “Puxa, deveria ter cobrado mais, este projeto está me causando fortes dores de cabeça”. Acredito que inúmeras vezes, não é? Sem sombra de dúvidas temos o vilão da estória: péssimo planejamento. Então como devemos planejar e definir os custos de um projeto? Bem, ainda não inventaram fórmulas mágicas, mas estão chegando perto disso. Mas enquanto não descobrem, vamos checar algumas sugestões:

!" Reflita sobre a sua experiência – por exemplo: um cliente solicita um orçamento para o desenvolvimento de uma aplicação de controle de estoque. Você já desenvolveu alguma aplicação deste tipo?

NÃO – então aumente relevantemente o tempo de desenvolvimento. SIM – bem, com isso você sairá na frente, reduzindo assim o tempo de desenvolvimento do projeto.

!" Pesquisar o máximo junto ao cliente – antes de emitir a proposta, pesquise o máximo de informações junto ao cliente, para saber até onde ele imagina que a aplicação vai chegar. Não são raros os casos de clientes que pedem uma simples aplicação de controle de estoque e depois questionam: “onde está o meu contas a pagar?” E o desenvolvedor retruca: “você não pediu isso!” Não é mesmo, amigos? Isso faz com que o desenvolvedor tome uma das seguintes atitudes:

!" desenvolve o módulo e não cobra nem um centavo a mais

!" tenta convencer o cliente de pagar uma quantia extra pelo desenvolvimento (isso causa fortes dores de cabeça)

!" “chuta o balde” e deixa o cliente “na mão” (nunca façam isso, amigos.)

!" 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.

Page 13: Delphi 7 Internet e Banco de Dados - Facunte

Introdução 13

!" Nunca faça leilão – é comum o seu cliente querer reduzir o valor de sua proposta, apresentando outras de seus concorrentes. Casos absurdos de redução de 50, 60 e até 70% são comuns. Acredito num valor de redução máximo de 20% e o ideal em 10%.

Tudo bem, Facunte, mas como definir os custos de um projeto? Minha sugestão é a seguinte:

!" Defina seu valor hora, entre R$ 40 e R$ 60 (sessenta reais). !" Baseado em sua experiência, calcule o tempo necessário para desenvolver a aplicação, em número de horas e

multiplique por 2,5. !" Caso haja a necessidade de outros membros no desenvolvimento do projeto, faça a adequação em número de horas e

acrescente 20% por membro. !" Acrescente os impostos. !" E “finito”, encaminhe a proposta ao cliente.

Veja um exemplo prático:

Minha estimativa em horas do projeto : 500 horas Tempo necessário : 500 horas x 2,5 = 1.250 h Prazo estimado pelo cliente : 2 meses O prazo fornecido pelo cliente forçou-me a Introduzir mais 3 membros na equipe : 1.250h + 60% = 2.000 h

(60% = 20% por membro) Valor hora : R$ 40,00 Valor total do projeto : 2.000 x R$ 40,00 = R$ 80.000,00

Repare, o que “pesou” no valor final do projeto foi o prazo estipulado pelo cliente, senão teríamos um valor bem mais atraente, em torno de R$ 45.000,00. Lembre-se de estimar as horas baseadas em sua experiência, e não façam leilões com o seu valor hora. Obviamente numa “fábrica de software” – virou moda este nome – são utilizados recursos mais avançados para avaliação 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 idéia mais abrangente seria necessário 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 é necessário liderança, e quem não nasce com o espírito de líder deverá conquistá-lo. O gerente deverá definir os responsáveis por cada tarefa, além de regras básicas para que o projeto possa fluir tranqüilamente:

!" responsável geral (gerente) !" responsável pelas regras de negócio !" coordenador do projeto !" responsável pela modelagem de dados !" responsável pelo desenvolvimento de classes básicas !" responsável pelo design do projeto !" responsável pelo núcleo do projeto !" responsável pelos testes

Costumo dizer que, após a modelagem de dados, desenvolver fica fácil. Digo isso porque o coração da aplicação é a modelagem. Uma boa modelagem é igual a uma boa aplicação, já uma razoável modelagem é igual a uma semente frutífera de

Page 14: Delphi 7 Internet e Banco de Dados - Facunte

14 Delphi 7 – Internet e Banco de Dados

problemas. Com a modelagem em mãos, o gerente poderá iniciar os trabalhos com cadastros básicos e design, lembrando que a modelagem de dados deve ser baseada na análise de negócios. Os testes deverão ser iniciados paralelamente ao desenvolvimento dos cadastros básicos, assim como o núcleo do projeto (caso haja um responsável por esta área, senão, somente após a conclusão dos cadastros básicos). O próximo tópico complementa as dicas sobre gerenciamento de equipes.

Quais as ferramentas adequadas para a equipe Gerenciar uma equipe não é uma tarefa fácil, mas existem no mercado ferramentas especialmente desenvolvidas para este fim.

MS Project

O Microsoft Project® é o melhor gerenciador de projetos que conheço. Com ele podemos gerenciar diversas equipes ao mesmo tempo, conseqüentemente diversos projetos (mesmo que por equipe), definir metas e analisar gráficos de desempenho por fases, projetos e equipes. O projeto é compartilhado entre os membros da equipe, facilitando assim o andamento do mesmo, mostrando as deficiências e também toda a eficiência da equipe. Recomendo para todos os tamanhos de projeto, e acredito ser indispensável para grandes projetos.

ERWin

Quem nunca ouviu falar da fantástica 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 não recomendo, devido ao seu alto custo (CA, não fique brava comigo, mas é a dura realidade), mas para médios e grandes é indispensável. A Squadra, empresa 100% nacional, é fabricante de uma ótima ferramenta de modelagem de dados: Dr Case. Além do preço 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 específicos para Interbase, como o fantástico IB Admin, da SQLLY (www.sqlly.com) com um custo bastante atraente, e com diversos recursos de gerenciamento do Interbase (altamente recomendável 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 idéia, além das grandes empresas de software, estão adotando UML indústrias automobilísticas (GM, Ford), fabricantes de hardware (Intel, EPSON, HP, Compaq), entre outras. Mas o que é UML? E quais as suas vantagens? Em resumo, UML é a unificação dos métodos Booch, OMT e OOSE, padronizando a modelagem de sistemas de software orientados a objetos, entre outras aplicações. Hoje em dia, a recomendação básica para desenvolvimento de sistemas é a utilização de todo o poder da orientação a objetos. A UML colabora muito para a organização e documentação de projetos orientados a objeto. Para entender melhor o UML, recomendo a leitura do livro Desenvolvendo Aplicações com UML da Brasport. Mas falar de UML sem falar de sua principal ferramenta, é realmente um deslize. Ao meu ver, não existe ferramenta melhor que o Rational Rose da empresa Rational (www.rational.com.br). Todas as especificações da UML são encontradas na ferramenta, além da integração com as principais linguagens de desenvolvimento do mercado. E como agora ganhamos o Model Maker, let´s go, friends!!!

TeamSource

A Borland disponibiliza uma excelente ferramenta de controle de versões e de trabalho em equipe: a TeamSource. Com esta ferramenta é possível gerenciar inúmeras versões do projeto, além de organizar o desenvolvimento em grupo, permitindo que inúmeros desenvolvedores participem do mesmo projeto. Maiores informações www.borland.com.br

Page 15: Delphi 7 Internet e Banco de Dados - Facunte

Introdução 15

Anotações de Dúvidas

Preciso Revisar

Anotações Gerais

?

#

Page 16: Delphi 7 Internet e Banco de Dados - Facunte

16 Delphi 7 – Internet e Banco de Dados

Capítulo 2

Aplicações Servidoras

O que são As aplicações servidoras são responsáveis pelo processamento das informações no servidor WEB, e a geração das informações em formato HTML, ou outro designado pelo desenvolvedor. As Aplicações Servidoras são responsáveis pela comunicação entre um Servidor HTTP e o cliente. No capítulo de servidores WEB, encontramos uma representação gráfica das aplicações servidoras.

Principais exemplos Grandes instituições financeiras utilizam aplicações servidoras para disponibilizar tecnologia Internet Banking aos seus clientes. Bradesco e Itaú são bons exemplos. Atualmente empresas de médio e grande porte utilizam aplicações servidoras em seus sistemas ERP e CRM. O Delphi fornece diversas formas de desenvolver tais aplicações. São elas: CGI, WINCGI,

ISAPI/NSAPI, Apache Modules.

CGI CGI (Common Gateway Interface) é um padrão muito utilizado pela maioria dos servidores WEB. As aplicações CGI são criadas com a extensão EXE, solicitando ao sistema operacional a criação de um novo processo a cada execução, ou seja, para cada execução o sistema operacional aloca memória no servidor, tornando-o bastante carregado. Facunte, então por que o CGI é bastante utilizado, já que o mesmo escraviza o servidor? A resposta é muito simples. Em servidores UNIX as aplicações CGI são bem rápidas e leves, pois os processos no UNIX não 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 extensão do padrão CGI. Foi criado para aproveitar algumas características dos sistemas operacionais baseados no Padrão WIN 3x. 16 bits. Este padrão não é muito utilizado, devido ao baixo número de Servidores Web que o interpretam (não confunda sistema operacional com servidor web). No Delphi 7 este padrão foi descontinuado,

apenas oferecendo suporte na compilação.

16

Page 17: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações Servidoras 17

ISAPI O ISAPI (Internet Server Application Programming Interface) foi criado pela Microsoft para o desenvolvimento de conteúdo dinâmico em servidores Web. A principal diferença entre ISAPI e CGI é justamente a forma de implementação, onde o CGI é gerado no padrão EXE, e o ISAPI é gerado no padrão DLL. Portanto, os processos gerados pelo ISAPI são bem mais leves pelo fato de serem DLLs. Como visto anteriormente, o Apache disponibiliza módulos que tratam o CGI de maneira semelhante ao ISAPI. Toda vez que uma aplicação ISAPI é solicitada ao servidor Web, o mesmo cria um novo thread (um padrão de processamento muito utilizado nos sistemas operacionais Win32).

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

Apache Shared Modules Apache Shared Modules é uma grande novidade incorporada desde a versão 6 do Delphi. A ONG Apache, considerada a melhor do mundo na área de pesquisas e ferramentas Web, desenvolveu um novo padrão para o seu poderoso e popular Servidor Internet, os chamados Apache Shared Modules. É uma espécie de DLL, só que melhor gerenciada pelo Apache. Só para ter uma idéia do seu poder, o próprio Servidor Apache se encarrega de fazer a escalabilidade dos Apaches Shared

Modules, facilitando assim a vida do administrador de servidores web.

Padrões de Mercado Sem sombra de dúvidas o CGI se tornou padrão de mercado pela sua enorme flexibilidade tanto em desenvolvimento como em gerenciamento. Além do padrão EXE gerado pelo Delphi (que já traz consigo todo o núcleo, desde o projeto até as bibliotecas necessárias para a sua execução), existem outros padrões gerados através 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 não têm? A resposta é simples: alta tecnologia à disposição do desenvolvedor. Com uma enorme biblioteca de componentes nativos, além dos milhares de componentes de terceiros, uma excelente gama de funções de manipulação de banco de dados, funções matemáticas, dentre outras.

Page 18: Delphi 7 Internet e Banco de Dados - Facunte

18 Delphi 7 – Internet e Banco de Dados

Anotações de Dúvidas

Preciso Revisar Anotações Gerais

?

!

Page 19: Delphi 7 Internet e Banco de Dados - Facunte

Servidores Web 19

Capítulo 3

Servidores Web

Visão 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 eletrônico) !" FTP (gerenciamento de arquivos) !" entre outros

Aqui falaremos apenas no serviço HTTP. A ilustração a seguir demonstra o trabalho de um servidor HTTP.

Servidor HTTP

Figura 3.1 Servidor HTTP

CGI Aplicações Servidoras

HTML

Internet/ TCP-IP/ HTTP

cliente HTTP

IExplorer

19

Page 20: Delphi 7 Internet e Banco de Dados - Facunte

20 Delphi 7 – Internet e Banco de Dados

Como vimos na Figura 3.1, o servidor HTTP é responsável pelo processo de recebimento e envio de informações. Na realidade ele recebe a requisição do cliente (browser), passa a informação à aplicação servidora (CGI), e transmite ao cliente a resposta gerada pelo CGI. O mais interessante de tudo isso é que o servidor HTTP pode responder às solicitações de uma rede local, não 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 aplicações CGI na Internet para um número ilimitado de usuários, 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 código fonte disponível. Vamos conhecer um pouco das características 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, além das inúmeras vulnerabilidades descobertas a todo o momento. Claro que a Microsoft® trabalha rápido para “fechar as portas” do IIS, mas devido a outras “brechas” no Windows NT, fica difícil tornar o IIS seguro.

Apache Amigos, este é o “queridinho” dos administradores de rede. Atualmente está no topo em número 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 código fonte aberto, e a cada semestre surpreende os administradores de rede, com versões magníficas. Claro que nem tudo são flores, e o Apache também tem suas vulnerabilidades; logicamente no Windows é mais vulnerável e em outras plataformas muito menos. Não possui interface de configuração – apenas de terceiros – mas sua configuração é bastante simples. A dificuldade cresce conforme a necessidade do servidor; por exemplo: um servidor que mantém diversos sites hospedados necessita de uma configuração mais complexa. Altamente recomendável, pode ser executado até mesmo para testar nossas aplicações, o que faremos com enorme satisfação neste livro. O Apache é um dos produtos da Apache Org e poderá ser encontrado no endereço 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 não chegou num nível 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 fácil configuração e traz consigo alguns recursos interessantes, como o personal proxy. Para maiores informações, visite o site do fabricante: www.xitami.com

TINY Amigos, este é o menor servidor HTTP que conheço, e o seu nome TINY (minúsculo) faz jus ao seu tamanho. Desenvolvido em Delphi e com código fonte aberto, o TINY é recomendado para desenvolvedores testarem a sua aplicação, ou até mesmo para pequenas redes locais, com no máximo 20 computadores.

Page 21: Delphi 7 Internet e Banco de Dados - Facunte

Servidores Web 21

Instalação e Configuração do Apache Server Existem diversas distribuições do Apache. Neste livro iremos trabalhar com a distribuição MSI (Windows Installer Package) da Microsoft®, versão 1.3.23. Execute o MSI apache_1.3.23-win32-x86-no_src.msi que se encontra no CD de instalação do Apache e siga os passos adiante:

Figura 3.2 Tela Inicial da Instalação do Apache

A figura 3.2 ilustra a tela inicial da instalação do Apache. Para prosseguir, pressione o botão Next. Em seguida, como ilustra a figura 3.3 é necessário aceitar os termos de instalação do Apache, selecionando a primeira opção “I accept ...” e pressionando o botão Next para prosseguir.

Figura 3.3 Termos de Licenciamento

Page 22: Delphi 7 Internet e Banco de Dados - Facunte

22 Delphi 7 – Internet e Banco de Dados

Em seguida, todas as novidades e informações sobre o Apache, são apresentadas. A figura 3.4 ilustra este passo. É interessante acessar as últimas novidades do Apache a cada mês, pois além de uma super-versão 2 estar a caminho (no momento em que escrevia este livro encontrava-se na versão Beta 2.08), outras novidades são implementadas. Pressione Next para prosseguir.

Figura 3.4 Informações sobre o Apache

O próximo passo é bastante importante, pois iremos configurar os dados do nosso servidor. Como ilustra a figura 3.5 devemos preencher as seguintes informações:

Network Domain Informe o domínio da sua rede. Exemplo: facunte.com Server Name Informe o nome do seu servidor. Exemplo: elvis Administrator Email Informe o email do administrador. Exemplo:

[email protected]

Figura 3.5 Configuração do Servidor

Page 23: Delphi 7 Internet e Banco de Dados - Facunte

Servidores Web 23

Em seguida devemos optar entre a instalação completa e a customizada. Em nosso caso recomendo a instalação completa. Já em caso de servidores comerciais, recomendo a instalação customizada, de forma que possamos eliminar alguns arquivos desnecessários, como documentação do Apache. Clique em Next para prosseguir.

Figura 3.6 Tipo de configuração.

Agora basta clicar no botão Install para dar início à instalação conforme nossa configuração. A figura 3.7 ilustra este momento.

Figura 3.7 Início da Instalação

Após finalizada a instalação, reinicie o Windows para que o mesmo reconheça o Apache e estabeleça o serviço 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 endereço URL: http://localhost Deverão aparecer informações sobre o Apache Server como ilustra a figura 3.8.

Page 24: Delphi 7 Internet e Banco de Dados - Facunte

24 Delphi 7 – Internet e Banco de Dados

Figura 3.8 Teste do Apache

Após a instalação do Apache, devemos configurá-lo para servir uma rede local. No grupo de menus do Apache, temos a seção Configure Apache Server, e dentro desta seção temos a opção Edit the Apache httpd. configuration file. Clique nesta opção 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 padrão texto (ASCII) de fácil edição. Localize a seção de configuração 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.

Page 25: Delphi 7 Internet e Banco de Dados - Facunte

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 comentário no Apache. Neste ponto configuramos o IP ou NOME do nosso Servidor. Como o próprio Apache recomenda, utilizamos o IP 127.0.0.1 para testes e desenvolvimento. O próximo passo é configurar o diretório de scripts, onde executaremos nossas aplicações servidoras. Localize a seção 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 diretório de execução de scripts, apontando para C:/cursoweb/cgi-bin. Para finalizar nossa configuração no Apache, devemos criar nosso VirtualHost. Esta seção 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 [email protected] # 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 [email protected] DocumentRoot “c:/cursoweb” ServerName localhost </VirtualHost>

Grave as configurações do Apache e selecione a opção Restart no grupo de opções. No diretório C:/cursoweb deverá conter o arquivo index.htm, que será o principal. Nos tópicos seguintes iremos abordar o uso de protocolos HTTP, TCP-IP, bem como o aprendizado do HTML.

Page 26: Delphi 7 Internet e Banco de Dados - Facunte

26 Delphi 7 – Internet e Banco de Dados

Anotações de Dúvidas

Preciso Revisar Anotações Gerais

?

#

Page 27: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações Servidoras 27

Capítulo 4

Protocolos

Visão Geral Protocolo é a linguagem utilizada para troca de informações 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 junção do protocolo TCP (Transmission Control Protocol) com o protocolo IP (Internet

Protocol). Hoje é o principal protocolo de transmissão entre redes de computadores, seja via Internet, Local, Intranet ou Extranet.

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

FTP O protocolo FTP (File Transfer Protocol) possui funções semelhantes ao Explorer do Windows (alguns irão achar que estou exagerando). Através dele podemos transferir arquivos entre servidores e clientes (download e upload), eliminar arquivos, criar diretórios, enfim, operações básicas comumente encontradas no Explorer do Windows.

SMTP O protocolo SMTP (Simple Mail Transfer Protocol) é utilizado para enviar mensagens de correio eletrônico para servidor SMTP.

POP O protocolo POP (Post Office Protocol), é utilizado para extrair mensagens de servidor POP3. O servidor POP3 tem como principal função armazenar as mensagens distribuídas pelo servidor SMTP.

27

Page 28: Delphi 7 Internet e Banco de Dados - Facunte

28 Delphi 7 – Internet e Banco de Dados

Anotações de Dúvidas

Preciso Revisar Anotações Gerais

?

!

Page 29: Delphi 7 Internet e Banco de Dados - Facunte

HTML 29

Capítulo 5

HTML

A linguagem HTML (HyperText Markup Language) é padrão para publicação de documentos na Internet. Todos os browsers (navegadores como, Netscape, Internet Explorer, Mosaic, NeoPlanet, entre outros) possuem interpretação de comandos HTML. Existem diversas versões para o padrão HTML, neste livro trabalharemos com a versão 4.

Ferramentas para produzir HTML. No mercado existem várias ferramentas para a criação de documentos HTML. As mais utilizadas são: DreamWeaver, FrontPage, PageMill, HotDog e GoLive. Além das ferramentas citadas, podemos produzir um documento HTML através do Notepad, isso mesmo, NOTEPAD do Windows. Acontece que o documento HTML é um arquivo no padrão 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 Básica Um documento HTML possui basicamente dois conjuntos de informações: Conteúdo – Informação a ser visualizada; Tags – Comandos a serem interpretados pelo browser. Exemplo: <HTML>

<HEAD>

<TITLE>Título do Documento</TITLE>

</HEAD>

<BODY>

Corpo do texto

</BODY>

</HTML>

29

Page 30: Delphi 7 Internet e Banco de Dados - Facunte

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 Básicos <HTML> Estrutura HTML

Para definir o início e o fim de um documento HTML, utilizamos esta expressão: <HTML> para definir o início, 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> Cabeçalho do Documento

Para definir o cabeçalho do documento, utilizamos a TAG <HEAD>. <HEAD> para definir o início do cabeçalho, e

</HEAD> para definir o fim do cabeçalho.

<TITLE> Título do Documento

Para definir o título do documento (aparece na barra de título do browser) , utilizamos a TAG <TITLE>. <TITLE> para definir o início do cabeçalho, e

</TITLE> para definir o fim do cabeçalho.

Exemplo: <TITLE>

Facunte On-Line

</TITLE>

Page 31: Delphi 7 Internet e Banco de Dados - Facunte

HTML 31

<BODY> Corpo

A TAG <BODY> define o corpo do documento, ou seja, é a localização do conteúdo do documento. Esta TAG possui alguns atributos, como mostra a Tabela 5.1.

ATRIBUTO

DESCRIÇÃO

BackGround Exibe uma imagem de fundo para a página HTML.

BGColor Define a cor de fundo do documento

Link

Define a cor do Link

Alink Define a cor dos Links ativos

Vlink Define a cor dos Links já visitados

Text

Define a cor do texto

Tabela 5.1 Atributos da TAG <BODY> Exercício 1: Crie um novo arquivo com o nome exercicio1.html e siga o exemplo: <html>

<head>

<title>Método 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 subdiretório IMAGENS. Faça o exercício com outros tipos de imagens, do tipo GIF ou JPEG. A figura 5.2 ilustra o resultado do nosso exercício. <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>

Page 32: Delphi 7 Internet e Banco de Dados - Facunte

32 Delphi 7 – Internet e Banco de Dados

Figura 5.2 Exercício 1

Exercício 2: <HTML>

<HEAD>

<TITLE>Título do Documento</TITLE>

</HEAD>

<BODY>

<H1> Testando HEADER H1 </H1>

<H2> Testando HEADER H2 </H2>

<H3> Testando HEADER H3 </H3>

<H4> Testando HEADER H4 </H4>

<H5> Testando HEADER H5 </H5>

<H6> Testando HEADER H6 </H6>

</BODY>

</HTML>

Faça o exercício anterior, e fique à vontade para alterar a posição, 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 (exercício 2)

Page 33: Delphi 7 Internet e Banco de Dados - Facunte

HTML 33

<P> Parágrafos

As TAGS <P> e </P> servem para iniciar e finalizar um parágrafo. A TAG <P> possui o atributo <ALIGN> para alinhar o texto, conforme a tabela 5.2.

VALOR

DEFINIÇÃO

Left

Alinha o parágrafo á esquerda

Right

Alinha o parágrafo à direita

Center

Alinha o parágrafo no centro

Justify

Justifica o parágrafo (alguns browsers não aceitam este valor)

Tabela 5.2 Vvalores do atributo ALIGN Com base no exemplo que segue, faça o exercício 3 utilizando os recursos até aqui apresentados, criando quatro parágrafos diferentes com textos de livre expressão. Grave o arquivo como exercicio3.html A figura 5.4 ilustra nosso exemplo. Exercício 3: <HTML>

<HEAD>

<TITLE>Título do Documento</TITLE>

</HEAD>

<BODY>

<P>Parágrafo sem a utilização do atributo ALIGN</P>

<P ALIGN=CENTER>Parágrafo com atributo ALIGN=CENTER</P>

<P ALIGN=RIGHT>Parágrafo com atributo ALIGN=RIGHT</P>

<P ALIGN=LEFT>Parágrafo com atributo ALIGN=LEFT</P>

<P ALIGN=JUSTIFY>Parágrafo com atributo ALIGN=JUSTIFY. Para isso estamos utilizando

um parágrafo mais longo para ver o efeito de sua utilização.</P>

</BODY>

</HTML>

<BR> QUEBRA DE LINHA

Para definir uma quebra de linha é necessário a utilização da TAG <BR>. Pois ao contrário do que parece, o browser não trata os espaços em branco criados através 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>.

Page 34: Delphi 7 Internet e Banco de Dados - Facunte

34 Delphi 7 – Internet e Banco de Dados

Figura 5.4 exercício 3 (tag <P>)

Exercício 4: <HTML>

<HEAD>

<TITLE>Título do Documento</TITLE>

</HEAD>

<BODY>

<P>Parágrafo sem a utilização da TAG (BR)

Segunda linha.

Terceira Linha.</P>

<P>Parágrafo com a utilização da TAG (BR) <BR>

Segunda linha.<BR>

Terceira Linha.</P>

</BODY>

</HTML>

Com base no exemplo, faça o exercício 4 criando dois parágrafos diferentes, sendo o primeiro sem a utilização da tag <BR> e o segundo com a tag. Não se esqueçam de utilizar os recursos já apresentados. A figura 5.5 ilustra o nosso exemplo.

Figura 5.5 exercício 4 (tag <BR>)

Page 35: Delphi 7 Internet e Banco de Dados - Facunte

HTML 35

Formatando o Texto Algumas TAGs definem a formatação do texto, como ítálico e negrito. Utilizamos a TAG <I> para definir a formatação do texto em itálico e a TAG <B> para definir a formatação em negrito. Exemplos: <HTML>

<HEAD>

<TITLE>Título do Documento</TITLE>

</HEAD>

<BODY>

<P><I>Texto em Itálico</I></P>

<BR>

<P><B>Texto em negrito</B></P><BR>

<P><I><B>Texto em itálico e negrito</I></B></P><BR>

<P>Podemos utilizar as <I>TAGs</I> de <B>formatacao</B> em qualquer parte do

texto</P>

</BODY>

</HTML>

A figura 5.6 ilustra o nosso exemplo.

Figura 5.6 Exemplo de Formatação

Existem outras TAGs de formatação, como demonstra a tabela 5.3.

TAG

FORMATAÇÃO

<BIG>

Para texto grande

<SMALL>

Para texto pequeno

Page 36: Delphi 7 Internet e Banco de Dados - Facunte

36 Delphi 7 – Internet e Banco de Dados

TAG

FORMATAÇÃO

<U>

Para sublinhar o texto

<STRIKE>

Para riscar o texto

<SUB>

Para texto SUBescrito

<SUPB>

Para texto SOBrescrito

Tabela 5.3 TAGs de formatação Exercício 5: <HTML>

<HEAD>

<TITLE>Título 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 formatação devidamente apresentadas, faça o exercício 5 utilizando-as da melhor maneira possível. 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 Exercício 5 (vários exemplos de formatação)

Page 37: Delphi 7 Internet e Banco de Dados - Facunte

HTML 37

<FONT> Ainda em formatação – definição de fontes

Um recurso bastante utilizado por web-designers é a alteração dos tipos de fontes, conforme a ocasião. Através da tag <FONT> alteramos as características de fontes de um determinado parágrafo ou até mesmo de todo o corpo do documento. Os seguintes atributos complementam a TAG <FONT>.

ATRIBUTO

DESCRIÇÃO

Color

Define a cor da Fonte

Face

Define o tipo da Fonte

Size

Define o tamanho da Fonte (de 1 a 7) O tamanho também poderá ser definido por pixel size.

Tabela 5.4 Atributos da TAG <FONT> Exemplos: <html>

<head>

<title>Método 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 exercício, proponho a criação de um documento HTML com a utilização dos tipos de fontes conhecidas, bem como a formatação de parágrafos com diversos alinhamentos, e por fim variadas formatações de textos.

Page 38: Delphi 7 Internet e Banco de Dados - Facunte

38 Delphi 7 – Internet e Banco de Dados

Figura 5.8 exemplos de fontes

A figura 5.9 ilustra a sugestão do exercício 6.

Figura 5.9 Exercício 6

Veja a seguir o exemplo que utilizei para criar o exercício 6. <html>

<head>

<title>Método Facunte</title>

</head>

<body bgcolor="#FFFFFF">

<p align=CENTER><font face="Verdana" size="3"><B>Exercício 6</B></font></p>

<p align=RIGHT> <font face="Arial"><I>Fonte Arial com formatação

itálica</I></font></p>

<p align=LEFT> <font face="Verdana"><B><I>Fonte VERDANA com negrito e

itálico</I></B></font></p>

Page 39: Delphi 7 Internet e Banco de Dados - Facunte

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, formulários e imagens. Atributos da TAG <HR>

ATRIBUTO

DESCRIÇÃO

Width

Define o tamanho da linha em percentual % ou em pixel.

Size

Define a altura (espessura) da linha

Align

Define o alinhamento da linha (centro, esquerdo ou direito)

Color

Define a cor da linha

Tabela 5.5 Atributos da TAG <HR> No exemplo que segue, utilizamos três exemplos da tag <HR>. Exemplo: <HTML>

<HEAD>

<TITLE>Título 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 compõem a Bandeira Nacional são...

<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 exercício 7 crie um documento HTML com quatro parágrafos (lembrem-se de utilizar todos os recursos apresentados), separados por linhas horizontais de variadas formas.

Page 40: Delphi 7 Internet e Banco de Dados - Facunte

40 Delphi 7 – Internet e Banco de Dados

Figura 5.10 Exemplo de linhas horizontais <HR>

Veja a figura 5.11 e o código que segue como resolução do exercício.

Figura 5.11 Exercício 7

Listagem 5.1 do Exercício 7

<HTML>

<HEAD><TITLE>Exercício 7</TITLE></HEAD>

<BODY>

<FONT Face=Verdana Size=3>

<P ALIGN=CENTER><B>Parágrafo 1</B>

<HR WIDTH=80% SIZE=1 ALIGN=CENTER>

<P><I>Parágrafo 2</I></P>

<HR WIDTH=100% SIZE=30 ALIGN=RIGHT>

<P><U>Parágrafo 3</U></P>

<HR WIDTH=30% SIZE=2 COLOR="BLACK" ALIGN=CENTER>

<P><B>Parágrafo 4</B></P>

<HR WIDTH=150 SIZE=20 COLOR=GRAY ALIGN=LEFT>

</FONT>

</BODY>

</HTML>

Page 41: Delphi 7 Internet e Banco de Dados - Facunte

HTML 41

<OL> Listas Ordenadas

Para criar listas ordenadas, utilizamos a TAG <OL>. O mais importante atributo da TAG <OL> é o Type. Através deste atributo podemos definir o esquema de numeração.

VALOR DO ATRIBUTO TYPE

DESCRIÇÃO

TYPE = ¨A¨

Utiliza letras maiúsculas no esquema de numeração.

TYPE = ¨a¨

Utiliza letras minúsculas no esquema de numeração.

TYPE = ¨I¨

Utiliza algarismos romanos no esquema de numeração.

Tabela 5.6 Valores para o atributo <TYPE> Para cada item da lista é necessária a utilização 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

Page 42: Delphi 7 Internet e Banco de Dados - Facunte

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 exercício 8 crie um documento com 3 (três) listas com diferentes numerações, e em cada lista coloque um conjunto com 5 itens, utilizando os recursos apresentados até aqui. A figura 5.13 ilustra a resolução deste exercício.

Figura 5.13 Exercício 8

Listagem 5.2 do Exercício 8 <HTML>

<HEAD>

<TITLE>Exercício 8</TITLE>

</HEAD>

Page 43: Delphi 7 Internet e Banco de Dados - Facunte

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 Não Ordenadas

As listas não ordenadas são parecidas com as listas ordenadas, com a diferença de não 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 invés de uma numeração. Exemplo: <HTML>

<HEAD><TITLE>Listas não 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.

Page 44: Delphi 7 Internet e Banco de Dados - Facunte

44 Delphi 7 – Internet e Banco de Dados

Figura 5.14 Listas não ordenadas

Como a tag <UL> é bem parecida com a <OL>, não faremos exercício sobre a mesma.

Imagens Para inserir imagens nos documentos HTML, utilizamos a TAG <IMG>. Os padrões de imagens mais utilizados são GIF e JPG, pela qualidade de imagem e tamanho reduzido. Os seguintes atributos complementam a TAG <IMG>.

ATRIBUTO

DESCRIÇÃO

Alt

Exibe um texto enquanto a imagem não é exibida

SRC

Indica o nome do arquivo a ser exibido

ALIGN (Horizontal)-Right/Left

Alinhamento da imagem na página.

ALIGN(Vertical) –

TextTop/Middle/AbsMiddle/BaseLine/Bottom/AbsBottom

Alinhamento Vertical da imagem

Width

Largura da imagem em pixels.

Height

Altura da imagem em pixels

Page 45: Delphi 7 Internet e Banco de Dados - Facunte

HTML 45

ATRIBUTO

DESCRIÇÃO

HSPACE

Define o número de pixels que são deixados entre a imagem e o texto (Horizontal)

VSPACE

Define o número de pixels que são deixados entre a imagem e o texto (Vertical)

BORDER

Define o tamanho

Tabela 5.7 Atributos da TAG <FONT> 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, através da tag <IMG> alteramos suas características, como tamanho, borda e posicionamento vertical. No exercício 9 crie um documento HTML com 3 (três) imagens com variadas características.

Page 46: Delphi 7 Internet e Banco de Dados - Facunte

46 Delphi 7 – Internet e Banco de Dados

A figura 5.16 ilustra a resolução do exercício 9.

Figura 5.16 exercício 9

Listagem 5.3 do Exercício 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 são indispensáveis 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

DESCRIÇÃO

http

Servidor World Wide Web

ftp

Servidor de transferência de arquivos.

mailto

Enviar e-mail

gopher

Servidor Gopher, normalmente um texto ASCII.

Page 47: Delphi 7 Internet e Banco de Dados - Facunte

HTML 47

PROTOCOLO

DESCRIÇÃO

news

Servidor de Notícias NNTP padrão

nntp

Servidor de Notícias NNTP particular

telnet

Conexão 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 são hyperlinks. Mas como isso aconteceu? É simples, a figura e o texto estão dentro das tags de hyperlink <A>; e qualquer objeto, seja ele imagem ou texto, que estiver entre as tags <A>, viram hyperlink. Para o exercício 10, crie um documento HTML com três hyperlinks, apontando para os seguintes endereços: www.facunte.com.br www.brasport.com.br www.borland.com.br

Page 48: Delphi 7 Internet e Banco de Dados - Facunte

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 resolução do exercício.

Figura 5.18 Exercício 10

Listagem 5.4 do Exercício 10 <HTML>

<HEAD>

<TITLE>Exercício 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.

Page 49: Delphi 7 Internet e Banco de Dados - Facunte

HTML 49

ATRIBUTO/SUB TAG

DESCRIÇÃO

<TR>

Define o início e o fim de uma linha na tabela

<TD>

Define o início e o fim de uma célula

<TH>

Define o cabeçalho da tabela

Border

Define a largura da borda

Width

Largura da tabela, em percentual %, ou pixels

Height 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

DESCRIÇÃO

FONT

Permite definir todas as características da fonte dentro de uma célula

BGCOLOR

Define a cor de fundo da célula

BACKGROUND

Imagem de fundo da tabela

Tabela 5.10 Atributos da TAG 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.

Page 50: Delphi 7 Internet e Banco de Dados - Facunte

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>

Page 51: Delphi 7 Internet e Banco de Dados - Facunte

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 exercício 11 faça um documento HTML baseado no modelo que segue.

BANCO DE DADOS 1998 2001

DB2 32,1% 31,5%

Oracle 29,0% 30,9%

SQL Server 16,3% 20,2%

Interbase 1,2% 3,5% A figura 5.22 ilustra a resolução do exercício.

Page 52: Delphi 7 Internet e Banco de Dados - Facunte

52 Delphi 7 – Internet e Banco de Dados

Figura 5.22 Exercício 11

Listagem 5.5 do Exercício 11 <html>

<head>

<title>Exercício 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>

Page 53: Delphi 7 Internet e Banco de Dados - Facunte

HTML 53

Formulários Os formulários são bastante comuns em aplicações web. Na realidade são indispensáveis. Os formulários HTML funcionam como os formulários de programas cliente/servidor, com a finalidade de fazer a interface entre o usuário e o banco de dados. A TAG <FORM> define o início e o fim do formulário. Os dois principais atributos da TAG <FORM> são:

ATRIBUTO

DESCRIÇÃO

ACTION

Define a localização do programa ou email aos quais serão enviados os dados do formulário

METHOD

Define a forma de troca de dados entre o cliente (formulário) e o programa.

Tabela 5.10 Atributo da TAG <FORM> Objetos do Formulário

Para inserir objetos no formulário, utilizamos a TAG <INPUT>.

ATRIBUTO

DESCRIÇÃO

Name

Nome do objeto

Value

Texto do objeto

Size

Tamanho do objeto

MaxLength

Tamanho máximo permitido para entrada de dados

SRC

Endereço da imagem utilizada

TabIndex

Posição do objeto na ordem de tabulação

Checked

Quando o objeto for do tipo CheckBox ou Radio, é utilizada para atribuir os valores Verdadeiro ou Falso.

Tabela 5.11 Atributos da TAG <INPUT> Para definir o tipo do objeto, utilizamos o atributo TYPE.

ATRIBUTO

DESCRIÇÃO

Text

Permite a entrada de dados, como o Edit ou DBEdit

Page 54: Delphi 7 Internet e Banco de Dados - Facunte

54 Delphi 7 – Internet e Banco de Dados

ATRIBUTO

DESCRIÇÃO

Password

Permite a entrada de dados, com caractere *, como PassWordChar do Delphi

CheckBox

Caixa de seleção, como o CheckBox do Delphi

Radio

Como o RadioGroup do Delphi

Option

Lista de Seleção, como o ComboBox do Delphi

Submit

Botão para enviar os dados do formulário

Reset

Botão para limpar os campos do formulário

Button

Define um botão de ação própria do usuário

Hidden

Incorpora um objeto invisível ao formulário

Image

O mesmo que Submit, mas com uma imagem ao invés do botão

Tabela 5.12 Atributos do <TYPE> Exemplo de Formulário: <html>

<head>

<title>Exemplo de Formulário</title>

</head>

<body bgcolor="#FFFFFF">

<form method="post" action="mailto:[email protected]" 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.

Page 55: Delphi 7 Internet e Banco de Dados - Facunte

HTML 55

F Figura 5.23 Exemplo de formulário

Vejamos outro exemplo: <html>

<head>

<title>Exemplo de Formulário</title>

</head>

<body bgcolor="#FFFFFF">

<form method="post" action="mailto:[email protected]" 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.

Page 56: Delphi 7 Internet e Banco de Dados - Facunte

56 Delphi 7 – Internet e Banco de Dados

Figura 5.24 Exemplo de formulário

Vejamos outro exemplo: <html>

<head>

<title>Exemplo de Formulário</title>

</head>

<body bgcolor="#FFFFFF">

<form method="post" action="mailto:[email protected]" 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 Aplicações Cliente/Servidor<br>

<input type="checkbox" name="produto2" value="checkbox">

Delphi 5 - Soluções Empresariais<br>

<input type="checkbox" name="produto3" value="checkbox">

Delphi 5 – Comércio Eletrônico</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.

Page 57: Delphi 7 Internet e Banco de Dados - Facunte

HTML 57

Figura 5.25 Exemplo de formulário

Neste exemplo vamos utilizar a maioria das TAGS que aprendemos neste livro, para tornar o formulário mais simpático. <html>

<head>

<title>Cadastro</title>

</head>

<body bgcolor="#FFFFFF">

<form method="post" action="mailto:[email protected]" name="Formulario">

<table width="80%" border="1" align="center" bgcolor="#3333FF">

<tr>

<td><font face="Arial" size="2" color="#FFFFFF"> <b>Formulário 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">

Page 58: Delphi 7 Internet e Banco de Dados - Facunte

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 Aplicações Cliente/Servidor<br>

<input type="checkbox" name="produto2" value="checkbox">

Delphi 5 - Soluções Empresariais<br>

<input type="checkbox" name="produto3" value="checkbox">

Delphi 5 - Comércio Eletrônico</font></p>

</td>

</tr>

<tr>

<td>&nbsp;</td>

<td>

<p><br>

Qual versão 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.

Page 59: Delphi 7 Internet e Banco de Dados - Facunte

HTML 59

Figura 5.26 Exemplo de Formulário

Amigos, vimos a complexidade em desenvolver um formulário em HTML, mas não se assustem, pois as ferramentas citadas anteriormente (Dreamweaver, GoLive, etc.) tornam esta tarefa bastante agradável. Para facilitar a compreensão e o andamento do curso, faremos o exercício de formulário em conjunto com as aplicações 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 não iremos detalhar o uso do CSS, mas abordaremos alguns itens interessantes, como por exemplo, melhorar o aspecto do formulário. No final deste capítulo 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 vários estilos, como: externo, inline e incorporado. No exemplo que segue, alteramos as cores dos campos de um formulário. A parte em negrito define nosso estilo. <html>

<head>

<title>Exemplo de Formulário</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; }

Page 60: Delphi 7 Internet e Banco de Dados - Facunte

60 Delphi 7 – Internet e Banco de Dados

</STYLE>

</head>

<body bgcolor="#FFFFFF">

<form method="post" action="mailto:[email protected]" 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 Aplicações Cliente/Servidor<br>

<input type="checkbox" name="produto2" value="checkbox">

Delphi 5 - Soluções Empresariais<br>

<input type="checkbox" name="produto3" value="checkbox">

Delphi 5 – Comércio Eletrônico</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

Page 61: Delphi 7 Internet e Banco de Dados - Facunte

HTML 61

Atributos de CSS

Atributo de CSS O que ele formata

Background Cor de fundo, imagem, transparência.

background-attachment Rolagem do fundo / Marca d'água.

background-image Imagem de fundo.

background-color Cor de fundo ou transparência.

background-position Posicionamento da imagem de fundo.

background-repeat Configuração lado-a-lado da imagem de fundo.

Border Largura, estilo e cor das bordas (superior, inferior, direita e esquerda)

border-bottom Largura, estilo e cor da borda inferior.

border-bottom-color Cor da borda inferior.

border-bottom-style Estilo da borda inferior.

border-bottom-width Largura da borda inferior.

border-color Cor das bordas.

border-left Largura, estilo e cor da borda esquerda.

border-left-color Cor da borda esquerda.

border-left-style Estilo da borda esquerda.

border-left-width Largura da borda esquerda.

border-right Largura, estilo e cor da borda direita.

border-right-color Cor da borda direita.

border-right-style Estilo da borda direita.

border-right-width Largura da borda direita.

border-style Estilo de todas as bordas.

border-top Largura, estilo e cor da borda superior.

border-top-color Cor da borda superior.

border-top-style Estilo da borda superior.

border-top-width Largura da borda superior.

border-width Largura de todas as bordas.

clear Elementos flutuantes à esquerda ou à direita de um elemento.

clip Parte visível de um elemento.

Color Cor de primeiro plano.

Cursor Tipo de ponteiro do mouse.

Display Se o elemento é exibido e o espaço é reservado para ele.

Filter Tipo de filtro aplicado ao elemento.

Float Se o elemento flutua.

Font Estilo, variante, peso, tamanho e altura da linha do tipo de fonte.

@font-face Incorporação da fonte ao arquivo HTML.

font-family Tipo de fonte.

font-size Tamanho da fonte.

font-style Fonte itálico.

Font-variant Fonte bold.

font-weight Peso da fonte de claro a negrito.

height Altura exibida ao elemento.

@import Folha de estilo a importar.

Page 62: Delphi 7 Internet e Banco de Dados - Facunte

62 Delphi 7 – Internet e Banco de Dados

Left Posição do elemento em relação à margem esquerda da página.

letter-spacing Distância entre as letras.

line-height Distância entre linhas de base.

list-style Tipo, imagem e posição do estilo da lista.

list-style-image Marcador de item de lista.

list-style-position Posição do marcador de item da lista.

list-style-type Marcador de item de lista alternativo.

margin Tamanho de todas as margens.

margin-left Tamanho da margem esquerda.

margin-right Tamanho da margem direita.

margin-bottom Tamanho da margem inferior.

margin-top Tamanho da margem superior.

overflow Exibição de imagens que são maiores do que suas molduras.

padding Espaço em torno de um elemento em todos os lados.

padding-bottom Espaço a partir da margem inferior de um elemento.

padding-left Espaço à esquerda do elemento.

padding-right Espaço à direita do elemento.

padding-top Espaço a partir da margem superior do elemento.

page-break-after Inserir quebra de página depois de um elemento.

page-break-before Inserir quebra de página antes de um elemento.

position Como o elemento é posicionado na página.

text-align Alinhamento do texto.

text-decoration Sublinhado, sobrelinhado ou riscado.

text-indent Recuo da primeira linha do parágrafo.

text-transform Transformação para todas maiúsculas, minúsculas ou inicial maiúscula.

top Posição do elemento em relação à parte superior da página.

vertical-align Alinhamento vertical do elemento.

visibility Se elemento é visível ou invisível.

width Largura do elemento.

z-index Posição do elemento na pilha.

Page 63: Delphi 7 Internet e Banco de Dados - Facunte

HTML 63

JavaScript

Assim como no tópico de CSS, abordaremos apenas alguns itens sobre JavaScript. Aqui abordaremos somente a validação de formulários utilizando o JavaScript. No exemplo que segue, verificamos se o usuário deixou o campo nome em branco. Em caso afirmativo, é disparado um alerta ao usuário. <html>

<head>

<title>Exemplo de Formulário</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:[email protected]" name="form1">

Digite seu nome

<input type="text" name="NOME" size="50" maxlength="50">

<input type="submit" name="Submit">

</form>

</body>

</html>

Caso o usuário 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 código. <SCRIPT LANGUAGE=JAVASCRIPT TYPE “TEXT/JAVASCRIPT”>

Neste ponto indicamos ao documento HTML o início do script JavaScript. Entre as tags <SCRIPT> e </SCRIPT> temos a liberdade de inserir códigos de linguagens de script, como o JavaScript. Em seguida criamos a função ValidaForm, com o parâmetro (formulario).

function ValidaForm(formulario) {

Na linha seguinte, verificamos se o usuário deixou o campo nome em branco.

if (formulario.NOME.value==””) {

Em caso afirmativo, o JavaScript dispara um alerta ao usuário. alert(“Você precisa informar o NOME”)

Page 64: Delphi 7 Internet e Banco de Dados - Facunte

64 Delphi 7 – Internet e Banco de Dados

Em seguida focaliza o campo nome e retorna o valor false ao formulário. formulario.NOME.focus() return false

Caso contrário retorna o valor true, liberando assim o formulário. return true

Para finalizar o script devemos fechar a tag </SCRIPT>. </SCRIPT>

Para que o nosso exemplo funcione, colocamos a função de validação dentro do formulário, utilizando o evento OnSubmit. <form method="post" onSubmit=”return ValidaForm(this)”

No exercício 12, crie um documento HTML com dois campos: Nome e Email, e verifique se o usuário deixou em branco um dos campos. Em caso afirmativo dispare a mensagem “Favor informar o nome do campo”. A seguir, temos a resolução do exercício. <html>

<head>

<title>Exemplo de Formulário</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:[email protected]" 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 concluímos nosso objetivo com o JavaScript.

Page 65: Delphi 7 Internet e Banco de Dados - Facunte

HTML 65

Anotações de Dúvidas

Preciso Revisar Anotações Gerais

?

!

Page 66: Delphi 7 Internet e Banco de Dados - Facunte

66 Delphi 7 – Internet e Banco de Dados

Capítulo 6

Delphi x Web x WebBroker

Para entender como funcionam as aplicações servidoras desenvolvidas em Delphi, nada melhor do que aprender na prática. A cada exercício iremos evoluir no aprendizado de aplicações servidoras web.

Primeiro Exemplo (Hello World) Peço licença aos saudosistas para utilizar o nosso famoso “Hello World” como exemplo. A partir do Delphi, selecione as opções File/New/Other... e em seguida a opção Web Server Application, como ilustra a figura 6.1.

Figura 6.1 Opção Web Server Application

Na janela seguinte selecione a opção CGI Stand-Alone executable (figura 6.2), e marque a opção Cross Platform, para que nossa aplicação possa ser compilada normalmente no Kylix.

66

Page 67: Delphi 7 Internet e Banco de Dados - Facunte

Delphi x Web x WebBroker 67

Figura 6.2 Seleção do tipo da aplicação

Em seguida teremos um WebModule (figura 6.3):

Figura 6.3 WebModule

Mas o que é um WebModule ?

WebModule é um repositório de objetos, com a função de armazenar os objetos não visuais da aplicação tais como (TPageProducer, TQueryPageProducer, TQuery, etc.), bem como responder às requisições do servidor HTTP. Bem, para que uma aplicação servidora possa trabalhar, devemos delegar tarefas, através de ActionsItems, ou simplesmente Itens de Ação.

Para explicar melhor o uso de ActionsItems, imagine uma aplicação para inclusão e alteração de clientes. Teremos o seguinte cenário:

Aplicação (clientes.exe) ::: ActionItem (inclusão) – ação para incluir cliente

::: ActionItem(alteração)- ação para alterar cliente

É bastante simples, cada ActionItem tem uma função específica dentro da aplicação servidora. Para executar no browser uma determinada ActionItem, basta fazer como no exemplo: http://site/cgi-bin/clientes.exe/inclusao

Page 68: Delphi 7 Internet e Banco de Dados - Facunte

68 Delphi 7 – Internet e Banco de Dados

Repare que informamos o nome da aplicação (clientes.exe) e o nome da ActionItem (/inclusão). A aplicação servidora não possui limite de ActionItems, portanto podemos criar aplicações complexas. Bem, seguindo o nosso primeiro projeto, através do duplo-clique no WebModule, acesse o editor de ActionItems (figura 6.4).

Figura 6.4 Editor ActionItems

Clique no primeiro botão 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 Propriedade Valor Acao1 Default True

Name Acao1

PathInfo /acao1

Page 69: Delphi 7 Internet e Banco de Dados - Facunte

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 código: (coloque somente o código 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 código anterior, estamos utilizando o método Response da aplicação servidora. Este método é responsável pela resposta do servidor à uma requisição. Antes de compilar o projeto, devemos configurar uma opção. Através da opção Projects/Option (menu), selecione a seção Directories/Conditionals e configure a opção 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

Page 70: Delphi 7 Internet e Banco de Dados - Facunte

70 Delphi 7 – Internet e Banco de Dados

Figura 6.7 Configuração do diretório

A figura 6.8 ilustra o nosso primeiro exemplo.

Figura 6.8 Exemplo 1 (aplicação 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

Page 71: Delphi 7 Internet e Banco de Dados - Facunte

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 aplicações: o TPageProducer. O objeto TpageProducer tem como principal função reproduzir uma string de comandos HTML. Na realidade podemos inserir comandos HTML com todas as Tags conhecidas, bem como as Tags transparentes que são substituídas por comandos HTML contidos no evento OnHtmlTag. Crie uma nova aplicação no Delphi através das opções File/New..., selecione a opção Web Server Application e clique no botão OK para confirmar. Na janela seguinte selecione a opção CGI Stand-Alone executable (figura 6.9).

Figura 6.9 Seleção do tipo da aplicação

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 código:

Page 72: Delphi 7 Internet e Banco de Dados - Facunte

72 Delphi 7 – Internet e Banco de Dados

<P align=center><B>Olá Mundo</B></P>

Reparem que informamos código HTML. Seguindo o nosso projeto, através do duplo-clique no WebModule, acesse o editor de ActionItems (figura 6.11).

Figura 6.11 Editor ActionItems

Clique no primeiro botão do editor para inserir uma nova Action (figura 6.12).

figura 6.12 ActionItem

Em seguida altere as seguintes propriedades.

OBJETO

TWebActionItem

Objeto Propriedade Valor

Acao1 Default True

Name Acao1

PathInfo /acao1

Producer PageProducer1

A figura 6.13 ilustra a alteração da propriedade Producer.

Page 73: Delphi 7 Internet e Banco de Dados - Facunte

Delphi x Web x WebBroker 73

Figura 6.13 Propriedade Producer

Com isso vinculamos a nossa Action Acao1 com o nosso produtor de página PageProducer1. Veremos que não é necessário disparar um código, como no exemplo1. Antes de compilar o projeto, devemos configurar uma opção. Através da opção Projects/Option (menu), selecione a seção Directories/Conditionals e configure a opção Output Directory para C:\cursoweb\cgi-bin, como ilustra a figura 6.14.

Figura 6.14 Configuração do diretório

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.

Page 74: Delphi 7 Internet e Banco de Dados - Facunte

74 Delphi 7 – Internet e Banco de Dados

Figura 6.15 Exemplo 2

Perceberam que não colocamos uma linha sequer de código? Vejam a listagem 6.2, todo o código 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 recomendável, pelo fator de utilizar um arquivo HTML externo e minimizar a manutenção no código da aplicação servidora. Crie uma nova aplicação no Delphi através das opções File/New..., selecione a opção Web Server Application e clique no botão OK para confirmar.

Page 75: Delphi 7 Internet e Banco de Dados - Facunte

Delphi x Web x WebBroker 75

Na janela seguinte selecione a opção CGI Stand-Alone executable (figura 6.16).

Figura 6.16 Seleção do tipo da aplicação

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 seqüenciais seguidos da barra, e por fim o nome do arquivo. Devemos fazer isto desta maneira, pelo fato da nossa aplicação “rodar” num outro nível de diretório (CGI-BIN), e o arquivo HTML no primeiro nível. Crie um arquivo HTML no diretório C:\cursoweb com o nome olamundo.html e insira o código que seguinte <P align=center><B>Olá Mundo</B></P> <HR> <P align=center><B>utilizando htmlfile</B></P>

Seguindo o nosso projeto, através do duplo-clique no WebModule, acesse o editor de ActionItems (figura 6.18).

Page 76: Delphi 7 Internet e Banco de Dados - Facunte

76 Delphi 7 – Internet e Banco de Dados

Figura 6.18 Editor ActionItems

Clique no primeiro botão do editor para inserir uma nova Action (figura 6.19).

Figura 6.19 ActionItem

Em seguida altere as seguintes propriedades.

OBJETO

TwebActionItem

Objeto Propriedade Valor Acao1 Default True

Name Acao1

PathInfo /acao1

Producer PageProducer1 A figura 6.20 ilustra a alteração da propriedade Producer.

Figura 6.20 Propriedade Producer

Page 77: Delphi 7 Internet e Banco de Dados - Facunte

Delphi x Web x WebBroker 77

Com isso vinculamos a nossa Action Acao1 com o nosso produtor de página PageProducer1. Veremos que não é necessário disparar um código, como no exemplo1. Antes de compilar o projeto, devemos configurar uma opção. Através da opção Projects/Option (menu), selecione a seção Directories/Conditionals e configure a opção Output Directory para C:\cursoweb\cgi-bin, como ilustra a figura 6.21.

Figura 6.21 Configuração do diretório

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;

Page 78: Delphi 7 Internet e Banco de Dados - Facunte

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 à substituição de conteúdo das Tags Transparentes. Mas o que são Tags Transparentes?

O Delphi interpreta como Tag Transparente a seguinte expressão: <#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 conteúdo desta Tag poderá ser substituído por nossa aplicação servidora. Faremos o exemplo. Crie uma nova aplicação no Delphi através das opções File/New..., selecione a opção Web Server Application e clique no botão OK para confirmar. Na janela seguinte selecione a opção CGI Stand-Alone executable (figura 6.23).

Figura 6.23 Seleção do tipo da aplicação

Page 79: Delphi 7 Internet e Banco de Dados - Facunte

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 código 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 código: if TagString=’hora’ then ReplaceText:=timetostr(time);

Repare que estamos substituindo o conteúdo da Tag Transparente hora pela hora atual (função time). Seguindo o nosso projeto, através do duplo-clique no WebModule, acesse o editor de ActionItems (figura 6.24).

Figura 6.24 Editor ActionItems

Clique no primeiro botão do editor para inserir uma nova Action (figura 6.25).

Figura 6.25 ActionItem

Em seguida altere as seguintes propriedades.

OBJETO

TWebActionItem

Objeto Propriedade Valor Acao1 Default True

Name Acao1

PathInfo /acao1

Producer PageProducer1

Page 80: Delphi 7 Internet e Banco de Dados - Facunte

80 Delphi 7 – Internet e Banco de Dados

A figura 6.26 ilustra a alteração da propriedade Producer.

Figura 6.26 Propriedade Producer

Com isso vinculamos a nossa Action Acao1 com o nosso produtor de página PageProducer1. Veremos que não é necessário disparar um código, como no exemplo1 (isso está se tornando repetitivo, não acham? Mas é para o bem de todos). Antes de compilar o projeto, devemos configurar uma opção. Através da opção Projects/Option (menu), selecione a seção Directories/Conditionals e configure a opção Output Directory para C:\cursoweb\cgi-bin, como ilustra a figura 6.27.

Figura 6.27 Configuração do diretório

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.

Page 81: Delphi 7 Internet e Banco de Dados - Facunte

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.

Page 82: Delphi 7 Internet e Banco de Dados - Facunte

82 Delphi 7 – Internet e Banco de Dados

Quinto Exemplo (Interatividade com Formulários) Em nosso quinto exemplo, trabalharemos com formulários HTML, interagindo o Delphi e o documento HTML. Crie uma nova aplicação no Delphi através das opções File/New..., selecione a opção Web Server Application e clique no botão OK para confirmar. Na janela seguinte selecione a opção CGI Stand-Alone executable (figura 6.29).

Figura 6.29 Seleção do tipo da aplicação

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 diretório C:\cursoweb com o nome formulario.html e insira o código que seguinte <html> <head> <title>Exemplo de Formulário</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>

Page 83: Delphi 7 Internet e Banco de Dados - Facunte

Delphi x Web x WebBroker 83

Seguindo o nosso projeto, através do duplo-clique no WebModule, acesse o editor de ActionItems (figura 6.30).

Figura 6.30 Editor ActionItems

Clique no primeiro botão do editor para inserir uma nova Action (figura 6.31).

Figura 6.31 ActionItem

Em seguida altere as seguintes propriedades.

OBJETO

TWebActionItem

Objeto Propriedade Valor Formulário Default True

Name formulario

PathInfo /formulario

Producer PageProducer1 A figura 6.32 ilustra a alteração da propriedade Producer.

Page 84: Delphi 7 Internet e Banco de Dados - Facunte

84 Delphi 7 – Internet e Banco de Dados

Figura 6.32 Propriedade Producer

Repare no código HTML do documento, que estamos encaminhando o conteúdo do formulário para a Action “confirma”. Para que o formulário possa ser processado em nossa aplicação servidora, devemos criar tal item. Crie uma nova Action alterando as propriedades que seguem:

OBJETO

TWebActionItem

Objeto Propriedade Valor confirma Default False

Name confirma

PathInfo /confirma Repare que neste caso não vinculamos o PageProducer, pois daremos uma outra resposta para esta Action. No evento OnAction da Action confirma insira o código que segue: Response.Content:=’Seja bem vindo ´+ Request.ContentFields.Values[‘nome´];

Neste caso estamos utilizando o objeto Request, que tem como principal função extrair informações do requerente, em nosso caso o formulário HTML. O método ContenFields extrai informações enviadas através do método POST do formulário. Em nosso caso, pegamos o conteúdo do campo nome. Antes de compilar o projeto, devemos configurar uma opção. Através da opção Projects/Option (menu), selecione a seção Directories/Conditionals e configure a opção Output Directory para C:\cursoweb\cgi-bin, como ilustra a figura 6.33.

Page 85: Delphi 7 Internet e Banco de Dados - Facunte

Delphi x Web x WebBroker 85

Figura 6.33 Configuração do diretório

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 aplicação (Action Confirma)

Page 86: Delphi 7 Internet e Banco de Dados - Facunte

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 (Formulários) Em nosso sexto exemplo, também iremos trabalhar com formulários HTML, interagindo o Delphi e o documento HTML. Crie uma nova aplicação no Delphi através das opções File/New..., selecione a opção Web Server Application e clique no botão OK para confirmar. Na janela seguinte selecione a opção CGI Stand-Alone executable (figura 6.36).

Page 87: Delphi 7 Internet e Banco de Dados - Facunte

Delphi x Web x WebBroker 87

Figura 6.36 Seleção do tipo da aplicação

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 diretório C:\cursoweb com o nome formulario2.html e insira o código que seguinte <html> <head> <title>Exemplo de Formulário</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, através do duplo-clique no WebModule, acesse o editor de ActionItems (figura 6.37).

Figura 6.37 Editor ActionItems

Page 88: Delphi 7 Internet e Banco de Dados - Facunte

88 Delphi 7 – Internet e Banco de Dados

Clique no primeiro botão do editor para inserir uma nova Action (figura 6.38).

Figura 6.38 ActionItem

Em seguida altere as seguintes propriedades.

OBJETO

TWebActionItem

Objeto Propriedade Valor formulario Default True

Name formulario

PathInfo /formulario

Producer PageProducer1 Repare no código HTML do documento que estamos encaminhando o conteúdo do formulário para a Action “soma”. Para que o formulário possa ser processado em nossa aplicação servidora, devemos criar tal item. Crie uma nova Action alterando as propriedades que seguem:

OBJETO

TWebActionItem

Objeto Propriedade Valor soma Default False

Name soma

PathInfo /soma Repare que neste caso não vinculamos o PageProducer, pois daremos uma outra resposta para esta Action. No evento OnAction da Action soma insira o código que segue: (coloque somente o código 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']);

Page 89: Delphi 7 Internet e Banco de Dados - Facunte

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 opção. Através da opção Projects/Option (menu), selecione a seção Directories/Conditionals e configure a opção Output Directory para C:\cursoweb\cgi-bin, como ilustra a figura 6.39.

Figura 6.39 Configuração do diretório

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 formulário

Page 90: Delphi 7 Internet e Banco de Dados - Facunte

90 Delphi 7 – Internet e Banco de Dados

Figura 6.41 Action SOMA

Com isso concluímos este capítulo. 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.

Page 91: Delphi 7 Internet e Banco de Dados - Facunte

Delphi x Web x WebBroker 91

Anotações de Dúvidas

Preciso Revisar Anotações Gerais

?

!

Page 92: Delphi 7 Internet e Banco de Dados - Facunte

92 Delphi 7 – Internet e Banco de Dados

Capítulo 7

Projeto Cadastro de Clientes

Neste capítulo iremos desenvolver um projeto completo de cadastro de clientes, com as principais funções: inclusão, alteração, exclusão 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 não tenha registrado o Servidor Local, selecione a opção Server/Register e informe as propriedades conforme a figura 7.1.

Figura 7.1 Registrando Servidor Local Interbase

92

Page 93: Delphi 7 Internet e Banco de Dados - Facunte

Projeto Cadastro de Clientes 93

No campo UserName digite SYSDBA (com letras maiúsculas), e no campo PassWord digite masterkey (com letras

minúsculas). Estas informações são para o usuário padrão. Agora vamos criar o banco de dados Clientes.GDB. Selecione a opção DataBase/Create Database e crie um novo banco de dados como ilustra a figura 7.2.

Figura 7.2 Criação 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: Criação 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 através das teclas CTRL-E. Criação do Generator create generator gen_clientes; Execute o comando através das teclas CTRL-E. Criação da Trigger TGClientes

set term ||;

Page 94: Delphi 7 Internet e Banco de Dados - Facunte

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 através das teclas CTRL-E. Com isso finalizamos a criação dos objetos. Finalize o IBConsole e vamos iniciar nossas atividades no Delphi.

Criando as definições iniciais Crie uma nova aplicação no Delphi através das opções File/New..., selecione a opção Web Server Application e clique no botão OK para confirmar. Na janela seguinte selecione a opção CGI Stand-Alone executable (figura 7.3).

Figura 7.3 Seleção do tipo da aplicação

Insira um objeto do tipo TSQLConnection, e crie uma nova conexão clicando no botão + . Altere as seguintes propriedades:

OBJETO

TSQLConnection

Objeto Propriedade Valor BancoDados DriverName Interbase

CommitRetaining True

DataBase localhost:C:/cursoweb/clientes.gdb

SQLDialect 3

LoginPrompt False

Page 95: Delphi 7 Internet e Banco de Dados - Facunte

Projeto Cadastro de Clientes 95

Objetos Básicos Insira um objeto do tipo TSQLDataSet e altere as propriedades que seguem:

OBJETO

TSQLDataSet

Objeto Propriedade Valor tbClientes Name tbClientes

SQLConnection BancoDados

CommandText select * from tbclientes Insira um objeto do tipo TSQLQuery e altere as propriedades que seguem.

OBJETO

TSQLQuery

Objeto Propriedade Valor SQLGeral Name SQLGeral

SQLConnection BancoDados

SQL

select * from tbclientes where cod_cliente= :pcodigo

Na propriedade PARAMS do SQLGeral, altere o tipo do parâmetro PCODIGO para Integer.

Objeto de Inclusão Insira um objeto do tipo TSQLQuery e altere as propriedades que seguem.

OBJETO

TSQLQuery

Objeto Propriedade Valor SQLInclui 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 parâmetros para String.

Page 96: Delphi 7 Internet e Banco de Dados - Facunte

96 Delphi 7 – Internet e Banco de Dados

Objeto de Alteração Insira um objeto do tipo TSQLQuery e altere as propriedades que seguem.

OBJETO

TSQLQuery

Objeto Propriedade Valor SQLAltera 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 parâmetros para String, com exceção do parâmetro PCODIGO, que deve ser Integer.

Objeto de Exclusão Insira um objeto do tipo TSQLQuery e altere as propriedades que seguem:

OBJETO

TSQLQuery

Objeto Propriedade Valor SQLExclui Name SQLExclui

SQLConnection BancoDados

SQL

DELETE FROM TBCLIENTE WHERE COD_CLIENTE=:pcodigo

Na propriedade PARAMS do SQLExclui altere o tipo do parâmetro para Integer.

Objeto de Pesquisa Principal Insira um objeto do tipo TDataSetTableProducer e altere as seguintes propriedades.

Page 97: Delphi 7 Internet e Banco de Dados - Facunte

Projeto Cadastro de Clientes 97

OBJETO

TDataSetTableProducer

Objeto Propriedade Valor ppClientes Name PPClientes

DataSet tbClientes Em seguida, através 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 botão. No Object Inspector você poderá alterar as propriedades de cada coluna, melhorando o visual da aplicação. No evento OnCellFormat do objeto PPClientes, insira o código 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 funções: para alterar e excluir clientes.

Rotinas de manutenção Agora insira um objeto do tipo TDataSetPageProducer e altere as seguintes propriedades.

Page 98: Delphi 7 Internet e Banco de Dados - Facunte

98 Delphi 7 – Internet e Banco de Dados

OBJETO

TDataSetPageProducer

Objeto Propriedade Valor ppInclui Name PPInclui

HTMLFILE ../inc_clientes.html Neste ponto devemos criar o arquivo inc_clientes.html

Listagem do arquivo inc_clientes.html

<html> <head> <title>INCLUSÂO 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 face="Verdana" size="2">Razão Social:</font></div> </td> <td width="77%" height="20"> <p> <font face="Verdana" size="2">

Page 99: Delphi 7 Internet e Banco de Dados - Facunte

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">Endereço:</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 Inclusão"> <input type="button" name="Submit2" value="Desiste" onClick="javascript:history.go(-1)"> </font></p> </form> </td> </tr> </table> </body> </html>

Page 100: Delphi 7 Internet e Banco de Dados - Facunte

100 Delphi 7 – Internet e Banco de Dados

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

OBJETO

TDataSetPageProducer

Objeto Propriedade Valor ppAltera Name PPAltera

HTMLFILE ../alt_clientes.html

DataSet SQLGeral Neste ponto devemos criar o arquivo alt_clientes.html

<html> <head> <title>ALTERAÇÃO 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>ALTERAÇÃO 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">

Page 101: Delphi 7 Internet e Banco de Dados - Facunte

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 Alteração"> <input type="button" name="Submit2" value="Desiste" onClick="javascript:history.go(-1)"> </font></p> </form>

Page 102: Delphi 7 Internet e Banco de Dados - Facunte

102 Delphi 7 – Internet e Banco de Dados

</td> </tr> </table> </body> </html>

Actions de manutenção Neste ponto iremos criar as Actions. Crie uma Action alterando as propriedades que seguem.

OBJETO

TWebActionItem

Objeto Propriedade Valor principal Default True

Name principal

PathInfo /principal Insira o código 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">Inclusão 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 Propriedade Valor Inclusao Default False

Name inclusao

PathInfo /inclusao

PageProducer ppInclui Crie outra Action alterando as propriedades que seguem.

Page 103: Delphi 7 Internet e Banco de Dados - Facunte

Projeto Cadastro de Clientes 103

OBJETO

TWebActionItem

Objeto Propriedade Valor Altera Default False

Name Altera

PathInfo /altera Insira o código 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 Propriedade Valor Exclui Default False

Name Exclui

PathInfo /exclui Insira o código 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 Propriedade Valor confirma_inc_cliente Default False

Name confirma_inc_cliente

PathInfo /confirma_inc_cliente

Page 104: Delphi 7 Internet e Banco de Dados - Facunte

104 Delphi 7 – Internet e Banco de Dados

Insira o código 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 Propriedade Valor confirma_alt_cliente Default False

Name confirma_alt_cliente

PathInfo /confirma_alt_cliente Insira o código 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 Aplicação As figuras que seguem ilustram o resultado da nossa aplicação.

Page 105: Delphi 7 Internet e Banco de Dados - Facunte

Projeto Cadastro de Clientes 105

Figura 7.5 WebModule

Figura 7.6 Actions

Figura 7.7 Tela Principal da Aplicação

Page 106: Delphi 7 Internet e Banco de Dados - Facunte

106 Delphi 7 – Internet e Banco de Dados

Figura 7.8 Inclusão de Clientes

Figura 7.9 Alteração de Clientes

Figura 7.10 Consulta

Page 107: Delphi 7 Internet e Banco de Dados - Facunte

Projeto Cadastro de Clientes 107

Listagem 7.1 Código 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>';

Page 108: Delphi 7 Internet e Banco de Dados - Facunte

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;

Page 109: Delphi 7 Internet e Banco de Dados - Facunte

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">Inclusão 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.

Page 110: Delphi 7 Internet e Banco de Dados - Facunte

110 Delphi 7 – Internet e Banco de Dados

Anotações de Dúvidas

Preciso Revisar Anotações Gerais

?

!

Page 111: Delphi 7 Internet e Banco de Dados - Facunte

Enviando E-mails 111

Capítulo 8

Enviando E-mails

O recurso mais utilizado na Internet é sem dúvida o e-mail. Neste capítulo 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 versão 5, o Delphi trazia o pacote da empresa NETMasters que utilizava API do Windows para executar suas funções, e desde a versão 6, foi incluído o pacote INDY. O pacote da NetMasters era muito instável, devido aos inúmeros bugs tanto da parte da NETMasters, como também 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 capítulo 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 responsável pelo gerenciamento de aplicações com código-fonte aberto, distribuídos sob a licença pública GNU. Um fator bastante importante deste projeto é que o mesmo poderá ser compilado em Kylix, pelo fato de ser baseado na tecnologia CLX.

Início do Desenvolvimento Vamos iniciar um novo projeto CLX, e no formulário principal alterar as seguintes propriedades.

OBJETO

TForm

Objeto Propriedade Valor fmeMail BorderWidth 5

Caption Mailing.Net

Name 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

Page 112: Delphi 7 Internet e Banco de Dados - Facunte

112 Delphi 7 – Internet e Banco de Dados

OBJETO

TPanel

Objeto Propriedade Valor PnConfigura Align alTop

Caption ((deixe em branco))

Height 180

Name PnConfigura

Agora com o foco no formulário (objeto fmEmail), insira um objeto do tipo TSplitter e altere as seguintes propriedades:

OBJETO

TSplitter

Objeto Propriedade Valor Splitter1 Align alTop

MinSize 30

O objeto TSplitter é utilizado para dividir seções de um formulário. Em nosso projeto, terá a função de separar as áreas de configuração e texto. Ainda com o foco no formulário insira outro objeto do tipo TPanel e altere as propriedades, como a seguir:

OBJETO

TPanel

Objeto Propriedade Valor PnTexto Align alClient

Caption (((deixe em branco)))

Name PnTexto

Repare que estamos na fase de desenvolvimento da interface do aplicativo. Claro que é uma tarefa um pouco cansativa devido ao grande número de objetos do formulário. Mas amigos, acreditem, vale a pena o pequeno esforço. Agora com o foco no objeto PnTexto, insira um objeto do tipo TMemo e altere as propriedades que seguem:

OBJETO

TMemo

Objeto Propriedade Valor textodoemail Align alClient

Lines (((deixe em branco)))

Name TextodoEmail

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

Page 113: Delphi 7 Internet e Banco de Dados - Facunte

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 seção em que se encontra o referido objeto. Exemplo: [Standard].

OBJETO

TLabel [Standard]

Objeto Propriedade Valor Caption Texto

Left 17

Top 19

OBJETO

TLabel [Standard]

Objeto Propriedade Valor Caption Assunto

Left 17

Top 51

OBJETO

TEdit [Standard]

Objeto Propriedade Valor Left 96

Name edTexto

Text (((deixe em branco)))

Top 16

Width 320

Page 114: Delphi 7 Internet e Banco de Dados - Facunte

114 Delphi 7 – Internet e Banco de Dados

OBJETO

TEdit [Standard]

Objeto Propriedade Valor Left 96

Name edAssunto

Text (((deixe em branco)))

Top 46

Width 320

OBJETO

TSpeedButton [Additional]

Objeto Propriedade Valor Caption >>

Flat True

Left 420

Name btArquivo

Top 16

Width 23

OBJETO

TButton [Standard]

Objeto Propriedade Valor Caption Envia

Left 468

Name btEnvia

Top 85

Width 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 Valor Caption Configuração Servidor

SMTP

Height 90

Left 16

Name gbConfigura

Top 80

Width 425

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

Page 115: Delphi 7 Internet e Banco de Dados - Facunte

Enviando E-mails 115

OBJETO

TLabel [Standard]

Objeto Propriedade Valor Caption Host

Left 16

Top 20

OBJETO

TLabel [Standard]

Objeto Propriedade Valor Caption Usuário

Left 16

Top 44

OBJETO

TLabel [Standard]

Objeto Propriedade Valor Caption Conta

Left 16

Top 69

OBJETO

TLabel [Standard]

Objeto Propriedade Valor Caption Porta

Left 327

Top 20

OBJETO

TLabel [Standard]

Objeto Propriedade Valor Caption Senha

Left 176

Top 44

OBJETO

TEdit [Standard]

Objeto Propriedade Valor Color clAqua

Left 63

Page 116: Delphi 7 Internet e Banco de Dados - Facunte

116 Delphi 7 – Internet e Banco de Dados

Name edHost

Text coloque o endereço do seu servidor SMTP. Exemplo: smtp.provedor.com.br

Top 16

Width 250

OBJETO

TEdit [Standard]

Objeto Propriedade Valor Color clAqua

Left 63

Name edUsuario

Text coloque o usuário de sua conta SMTP. Exemplo: seunome

Top 40

Width 106

OBJETO

TMaskEdit [Additional]

Objeto Propriedade Valor Color clAqua

Left 216

PassWordChar *

Name edSenha

Text coloque a senha do usuário da conta de SMTP. Exemplo:

suasenha

Top 40

Width 97

OBJETO

TEdit [Standard]

Objeto Propriedade Valor Color clAqua

Left 63

Name edConta

Text coloque o endereço da conta de SMTP. Exemplo: [email protected]

Top 16

Width 250

Page 117: Delphi 7 Internet e Banco de Dados - Facunte

Enviando E-mails 117

OBJETO

TMaskEdit [Additional]

Objeto Propriedade Valor Color clAqua

EditMask 9999;1;

Left 368

Name edPorta

Text 25

Top 16

Width 48

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

Figura 8.2 Fase final do design do formulário

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 padrão Interbase empregado no capítulo 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 destinatário. O mais interessante neste aplicativo é o uso do objeto TDataSetPageProducer, normalmente utilizado no desenvolvimento de aplicações Web, como vimos nos capítulos anteriores. Além disso, iremos utilizar um arquivo externo no padrão HTML para relacionar com o objeto TMemo. Insira um objeto do tipo TSQLConnection, e crie uma nova conexão clicando no botão + . Altere as seguintes propriedades.

Page 118: Delphi 7 Internet e Banco de Dados - Facunte

118 Delphi 7 – Internet e Banco de Dados

OBJETO

TSQLConnection

Objeto Propriedade Valor BancoDados DriverName Interbase

CommitRetaining True

DataBase localhost:C:/cursoweb/clientes.gdb

SQLDialect 3

LoginPrompt False

Name BancoDados

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

OBJETO

TSQLDataSet

Objeto Propriedade Valor tbClientes Name tbClientes

SQLConnection BancoDados

CommandText select * from tbclientes

Codificando o botão btArquivo O objeto btArquivo será responsável 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 Propriedade Valor AbrirArquivo Name AbrirArquivo

Agora vamos inserir o código do botão 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;

Page 119: Delphi 7 Internet e Banco de Dados - Facunte

Enviando E-mails 119

end;

Vamos estudar o código em detalhe: if AbrirArquivo.Execute then

Esta linha verifica se o método Execute do objeto AbrirArquivo foi executado com êxito, ou seja, indaga se o usuário selecionou algum arquivo.

EdTexto.Text:=AbrirArquivo.FileName;

Associa o nome do arquivo selecionado no objeto AbrirArquivo ao objeto EdTexto.

TextodoEmail.Clear;

O método Clear limpa o conteúdo 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 então carregar um arquivo previamente criado.

Falando mais um pouco dos objetos INDY Um dos grandes problemas da biblioteca NetMasters (utilizada até a versão 5 do Delphi) era o congelamento (Freeze) da aplicação em diversos momentos: na conexão, desconexão, entre outros, invariavelmente. A biblioteca da Nevrona (INDY) traz um componente que trata especificamente deste problema: IdAntiFreeze. Sua principal função é priorizar as tarefas da aplicação, 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 seção Indy Misc. Não é necessário alterar as propriedades deste objeto. Agora iremos inserir o objeto considerado coração da nossa aplicação: TIdSMTP, localizado na seção Indy Clients. Insira um objeto do tipo TIdSMTP em nosso projeto. Iremos codificar as propriedades deste objeto em tempo de execução. O objeto TidSMTP realiza a conexão da nossa aplicação Cliente com o servidor SMTP, responsável 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. Poderíamos criar um servidor SMTP próprio 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 seção Indy Misc, e altere as propriedades que seguem:

OBJETO

TIdMessage

Objeto Propriedade Valor Mensagem ContentType text/HTML

Name Mensagem

Repare que a propriedade ContentType refere-se ao tipo MIME da mensagem, ou seja, o tipo de seu conteúdo. Configuramos para text/HTML para que as mensagens sejam enviadas com o padrão HTML ou texto (o padrão HTML predomina por conter recursos de formatação). Agora, amigos, iremos trabalhar com o nosso “curinga”: TDataSetPageProducer. Como visto nos capítulos anteriores, o objeto TDataSetPageProducer é responsável pela substituição automática de Tags transparentes relacionadas aos campos do DataSet vinculado.

Page 120: Delphi 7 Internet e Banco de Dados - Facunte

120 Delphi 7 – Internet e Banco de Dados

Insira um componente do tipo TDataSetPageProducer e altere as propriedades que seguem:

OBJETO

TDataSetPageProducer

Objeto Propriedade Valor ppMensagem DataSet tbClientes

Name 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 execução teremos: Prezado(a) Emerson Facunte, Estamos enviando este boletim para o seu email [email protected]

O interessante é que podemos inserir quantas Tags forem necessárias, em qualquer posição. 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 capítulos 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 botão btEnvia. Insira o código 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;

Page 121: Delphi 7 Internet e Banco de Dados - Facunte

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 conteúdo do edAssunto // ao objeto Mensagem.Subject Subject:=edAssunto.Text; // Atribui o conteúdo do edConta // ao objeto Mensagem.From.Text From.Text:=edConta.Text; // inicia o laço while not(tbClientes.Eof) do begin

// Atribui o conteúdo do campo EMAIL // ao objeto Mensagem.Recipients.EmailAddresses Recipients.EMailAddresses:=tbClientes.FieldByName('EMAIL').Value; ReceiptRecipient.Address:=tbClientes.FieldByName('EMAIL').Value; // Atribui o conteúdo do objeto ppMensagem // ao objeto Mensagem.Body.Text Body.Text:=ppMensagem.Content; // Envia a mensagem idSMTP1.Send(Mensagem); // Próximo registro tbClientes.Next; end; // laço end; // with Mensagem finally

// Disconecta Servidor idSMTP1.Disconnect; end; end;

Vamos analisar com cuidado este código. No primeiro bloco, estamos configurando o Cliente SMTP através 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 usuário da conta UserId, a senha Password, o HOST e a porta de conexão (Port). O bloco seguinte atribui o conteúdo do objeto TextodaMensagem ao objeto PPMensagem.

Page 122: Delphi 7 Internet e Banco de Dados - Facunte

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 próprio 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 código seguinte com o comando Try/Except/Finally. Em seguida estamos atribuindo o assunto da mensagem e o responsável 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 são enviadas uma a uma, fizemos um laço 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 método Content, ativamos o processamento das informações contidas na propriedade HTMLDOC do objeto. // Atribui o conteúdo 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 imaginação para enviar os e-mails de maneira personalizada. Com isso concluímos nosso projeto de envio de e-mails, e de quebra refrescamos nossas idéias com um novo tipo de aplicação.

Page 123: Delphi 7 Internet e Banco de Dados - Facunte

Enviando E-mails 123

Figura 8.3 MailingNet em ação

Listagem 8.1 Código 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;

Page 124: Delphi 7 Internet e Banco de Dados - Facunte

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

Page 125: Delphi 7 Internet e Banco de Dados - Facunte

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 laço 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 conteúdo do objeto ppMensagem // ao objeto Mensagem.Body.Text Body.Text:=ppMensagem.Content; // Envia a mensagem idSMTP1.Send(Mensagem); // Próximo registro tbClientes.Next; end; // laço end; // with Mensagem finally // Disconecta Servidor idSMTP1.Disconnect; end; end; end.

Page 126: Delphi 7 Internet e Banco de Dados - Facunte

126 Delphi 7 – Internet e Banco de Dados

Anotações de Dúvidas

Preciso Revisar

Anotações Gerais

?

!

Page 127: Delphi 7 Internet e Banco de Dados - Facunte

Desenvolvendo utilitários para Internet 127

Capítulo 9

Desenvolvendo utilitários para Internet

Neste capítulo, iremos desenvolver uma série de utilitários para Internet.

Portas Abertas: Seja Bem-Vindo

O primeiro utilitário visa alertar aos amigos leitores sobre um grave problema: Portas Abertas.

Quantos de vocês trancam a porta de suas casas ao anoitecer, ou até mesmo à luz do dia? Acredito que a maioria. Com o forte avanço da Internet em todo o planeta, nos deparamos com o mesmo problema em nossos computadores: Portas Abertas. Neste capítulo iremos desenvolver um aplicativo para scannear e apresentar as portas que estão abertas num determinado servidor. Para facilitar a compreensão de todos, estou apresentando um exemplo muito simples, onde o usuário informa o Nome do

Servidor (ou endereço IP) e o intervalo de portas a serem scanneadas. Os leitores com conhecimentos mais avançados ou know-how em Threads irão me crucificar por falta das benditas. Acontece que o principal objetivo deste exemplo é demonstrar o uso do componente TCPClient, e não do uso de Threads. Isso iria complicar um pouco a compreensão dos nossos amigos leitores. Aos amigos que se encaixam neste perfil, minhas sinceras desculpas. Bem, continuando, agora vem a parte boa: mão-

na-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 Propriedade Valor

TPanel Align alTop

Caption

Name pnTopo

127

Page 128: Delphi 7 Internet e Banco de Dados - Facunte

128 Delphi 7 – Internet e Banco de Dados

Com o foco no objeto pnTopo insira os seguintes objetos:

OBJETO

Label1 – TLabel

Objeto Propriedade Valor

TLabel Caption HOST

Left 16

Top 14

OBJETO

Label2 – TLabel

Objeto Propriedade Valor

TLabel Caption Porta Inicial

Left 16

Top 43

OBJETO

Label3 – TLabel

Objeto Propriedade Valor

TLabel Caption Porta Final

Left 232

Top 43 Agora vamos inserir os objetos de controle e interatividade com o usuário. Mantenha o foco no objeto pnTopo e insira os seguintes objetos:

OBJETO

NomeServidor – TEdit

Objeto Propriedade Valor

TEdit Name NomeServidor

Left 104

Top 10

Width 290

OBJETO

Inicio– TSpinEdit [Samples]

Objeto Propriedade Valor

TSpinEdit Name Inicio

Left 104

Top 40

Page 129: Delphi 7 Internet e Banco de Dados - Facunte

Desenvolvendo utilitários para Internet 129

OBJETO

Fim– TSpinEdit [Samples]

Objeto Propriedade Valor

TSpinEdit Name Fim

Left 320

Top 40 Neste ponto vamos inserir o botão para iniciar o processo de scanner de portas.

OBJETO

btScan– TButton

Objeto Propriedade Valor

TButton Name btScan

Caption Scan

Left 416

Top 8

Com isso concluímos a primeira etapa do projeto.

Prosseguindo, vamos criar o módulo de saída das informações. Agora com o foco no formulário e não mais no objeto pnTopo, insira um objeto do tipo Tpanel alterando as seguintes propriedades:

OBJETO

pnDados– TPanel

Objeto Propriedade Valor

TPanel Align alClient

Name pnDados

Vamos inserir os objetos deste painel, como segue:

OBJETO

ListadePortas– TMemo

Objeto Propriedade Valor

TMemo Name ListadePortas

Height 180

Left 16

Top 76

Width 500

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

Page 130: Delphi 7 Internet e Banco de Dados - Facunte

130 Delphi 7 – Internet e Banco de Dados

OBJETO

PnProgresso– TPanel

Objeto Propriedade Valor

TPanel Name pnProgresso

Caption

Height 65

Left 16

Top 8

Width 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 Propriedade Valor

TButton Name btParar

Caption Parar

Left 400

Top 32

OBJETO

ProgressBar1– TProgressBar

Objeto Propriedade Valor

TProgressBar Name ProgressBar1

Left 16

Top 8

Width 470

OBJETO

Label4 – TLabel

Objeto Propriedade Valor

TLabel Caption Scaneando Porta...

Left 16

Top 36

Page 131: Delphi 7 Internet e Banco de Dados - Facunte

Desenvolvendo utilitários para Internet 131

OBJETO

porta – TLabel

Objeto Propriedade Valor

TLabel Caption 0

Left 112

Top 36

Ufa!!! E para concluir a “enorme” lista de objetos, insira um do tipo TTCPClient que se encontra na seção Internet.

OBJETO

TCPClient1 – TTCPClient [Internet]

Objeto Propriedade Valor

TTCPClient Name TCPClient1

Finalmente vamos codificar o nosso projeto. Crie uma variável global pertencente à nossa classe Form1., com o nome Parar, do tipo Integer; veja: var

Form1: TForm1; parar:integer; // variavel auxiliar

implementation

A variável Parar será utilizada para finalizar o processo de Scanner das Portas. Neste ponto é que poderíamos criar uma Thread, mas não vamos complicar. Só para aliviar um pouco a forte tensão, vamos dar uma olhadinha na interface do nosso projeto (figura 9.1):

Figura 9.1 Projeto Port Scanner

Page 132: Delphi 7 Internet e Banco de Dados - Facunte

132 Delphi 7 – Internet e Banco de Dados

Vamos codificar o botão btScan, responsável pelo núcleo do nosso projeto. No evento onClick do objeto btScan, insira o código que segue (para facilitar, numerei as linhas de programação, de forma que possamos analisar melhor o código).

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

040 041 042

procedure TForm1.BtScanClick(Sender: TObject); var i:integer; begin try

ListadePortas.Clear; // Limpa a Lista de Portas parar:=0; // 0 = continua, 1 = conclui // Definições 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 laço 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 !'); PainelProgresso.Visible:=False; end;

Vamos ao detalhamento do código: A linha 002 declara uma variável “ i “ que irá auxiliar no laço de contagem das portas. var i:integer;

Na linha 004 iniciamos uma proteção de erros da aplicação.

Page 133: Delphi 7 Internet e Banco de Dados - Facunte

Desenvolvendo utilitários para Internet 133

try

A linha 005 limpa o conteúdo do objeto ListaPortas. ListadePortas.Clear

Na linha 007 inicializamos a variável parar com o valor 0, de forma que o sistema continue scanneando as portas até o limite solicitado pelo usuário, ou através do pressionamento da tecla Parar, fazendo com que a variável receba o valor 1. parar:=0;

As linhas 011 e 012 configuram o objeto ProgressBar1 de maneira que o mesmo fique compatível com as informações porta inicial e final. Com isso temos um progresso adequado. ProgressBar1.Max:=Fim.Value; ProgressBar1.Min:=Inicio.Value;

A linha 014 torna visível 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 informações Porta Inicial e Final. for i := Inicio.Value to Fim.Value do

Já na linha 019 nossa aplicação verifica se existe a obrigação de paralisar o loop. Esta informação vem do botão btParar. if parar=1 then break; A linha 021 posiciona a barra de progresso em relação ao andamento do loop. ProgressBar1.Position:=i; Na linha 022 apenas mostramos ao usuário através do objeto Porta, qual porta está sendo scanneada no momento. porta.Caption:=inttostr(i); A linha 024 solicita ao Windows que processe as informações da aplicação, de maneira que a mesma não 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 ativação, e em caso afirmativo, a linha 029 adiciona no objeto ListadePortas a informação 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).

Page 134: Delphi 7 Internet e Banco de Dados - Facunte

134 Delphi 7 – Internet e Banco de Dados

TcpClient1.Disconnect; A linha 032 finaliza o loop. As linhas 033, 034 e 035 tratam qualquer exceção 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 invisível. ListadePortas.Lines.Add('Scaneamento das portas finalizado !'); PainelProgresso.Visible:=False;

Para concluir o nosso projeto, devemos codificar o botão btParar com o seguinte código (no evento OnClick): Parar:=1;

Amigos, agora é só executar o aplicativo, informar o nome do servidor (caso seja seu próprio equipamento, digite localhost, no campo Nome do Servidor), e o intervalo de portas a serem scanneadas. A figura 9.2 ilustra nosso utilitário scanneando um servidor.

Figura 9.2 Scanner em ação

IMPORTANTE

Embora seja possível, não recomendo o uso deste aplicativo para scannear portas de servidores não-autorizados. Normalmente utilizamos este tipo de aplicativo para vigiar nosso “quintal” e não o do vizinho.

Artigo originalmente publicado na Revista The Club, nº 94

Page 135: Delphi 7 Internet e Banco de Dados - Facunte

Desenvolvendo utilitários 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; // variavel auxiliar 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 // Definições da barra de progresso ProgressBar1.Max:=Fim.Value; ProgressBar1.Min:=Inicio.Value;

Page 136: Delphi 7 Internet e Banco de Dados - Facunte

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 laço ProgressBar1.Position:=i; // atualiza ProgressBar porta.Caption:=inttostr(i); // atualiza Label Porta Application.ProcessMessages; // solicita ao Windows prioridade no processamento da aplicação 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 tópico vamos desenvolver uma nova versão para o ping. Mas Facunte, o que é ping? O utilitário 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 não se consegue estabelecer uma comunicação com o servidor, ou terminal remoto. Normalmente os testes de ping são feitos em servidores de Internet, firewall, roteadores e servidores de

banco de dados. Vejamos um exemplo deste utilitário rodando no sistema operacional Windows:

Page 137: Delphi 7 Internet e Banco de Dados - Facunte

Desenvolvendo utilitários para Internet 137

Figura 9.3 – Ping sendo executado no Windows XP

Neste exemplo, executamos o utilitário ping no sistema operacional Windows XP, solicitando uma resposta do computador Servidor. Repare que o ping dispara um pacote de 32 bytes no endereço IP (200.173.173.142), relacionado ao Servidor, e “ouve” quatro respostas num tempo menor que 1ms (um milesegundo). Com isso poderemos medir a eficiência no tráfego 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 utilitário Ping (figuras 9.4, 9.5 e 9.6).

Figura 9.4 – Ping disparado contra o Servidor com resultado satisfatório

Figura 9.5 – Ping disparado contra o Servidor sem resposta

Figura 9.6 – Ping disparado contra o Servidor com resultado nada agradável (lento)

Ping Servidor (32 bytes)

Estou aqui (1ms – 32 bytes)

Ping Servidor (32 bytes)

Mudo (sem resposta)

Ping Servidor (32 bytes)

Estou aqui (estouro tempo)

Page 138: Delphi 7 Internet e Banco de Dados - Facunte

138 Delphi 7 – Internet e Banco de Dados

Como vimos, existem três possibilidades de resultado: satisfatório, 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 lentidão. Bem, amigos, agora vem a parte boa: mão-na-massa. Inicie um projeto do tipo CLX (Delphi 6 ou superior), pois poderemos executar nossa aplicação 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 alTop Name pnEndereco

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

Objeto TLabel[Standard] Caption Endereço Left 12 Top 20

Objeto TEdit [Standard]

Left 72 Name edEndereco Top 16 Width 210

Objeto TBitBtn [additional] Caption Ping Left 296 Name btPing Top 16 Width 75

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

Objeto TPanel [Standard] Align AlClient Name PnResultado

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

Objeto TMemo [standard] Height 160 Left 16 Name mmResultado Lines (deixe em branco) Top 16 Width 500

Com isso teremos um formulário parecido com a figura 9.7.

Page 139: Delphi 7 Internet e Banco de Dados - Facunte

Desenvolvendo utilitários para Internet 139

Figura 9.7 Aplicação 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, não é 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 utilitários que iremos desenvolver, e basicamente serve para enviar mensagens a servidores remotos. Ok, então vamos inserir o nosso objeto TidICMPClient, e alterar as seguintes propriedades:

Objeto TPanel [Standard] Name NossoICMP ReceiveTimeout 10000

Perceba que alteramos a propriedade ReceiveTimeout. Esta propriedade indica o tempo máximo em milessegundos para uma resposta do servidor, gerando um timeout quando ultrapassado este tempo. Vamos codificar o botão btPing, inserindo o código 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 código. Primeiro, estamos declarando uma variável do tipo integer para nos auxiliar no laço do ping. var

i: integer;

Em seguida desabilitamos o botão btPing, impedindo o usuário de clicar várias vezes e causar um efeito redundante. btPing.Enabled:=False;

Page 140: Delphi 7 Internet e Banco de Dados - Facunte

140 Delphi 7 – Internet e Banco de Dados

No próximo ponto, protegemos o código com try para que eventuais erros sejam ignorados em nossa aplicação. try

Em seguida configuramos a propriedade Host do nosso objeto NossoICMP de acordo com a informação do usuário extraída do objeto edEndereco. NossoICMP.Host := edEndereco.Text;

Finalmente iniciamos o laço, executando o comando Ping 4 vezes (padrão), e solicitando ao S.O. uma atualização da aplicação. for i := 1 to 4 do begin NossoICMP.Ping; Application.ProcessMessages; end;

E para concluir esta parte do código, finalizamos o bloco protegido, habilitando novamente o botão btPing. finally btPing.Enabled := True; end;

Agora, iremos codificar o evento OnReply do objeto NossoICMP. Este evento é responsável pelas informações de resposta. Coloque o código 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 código maluco é esse? Amigos, à primeira vista, realmente é meio maluco, mas iremos desvendar rapidamente o mistério. Primeiro declaramos uma variável para nos auxiliar na composição 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 cabeçalho do evento OnReply, vejam: procedure TForm1.NossoICMPReply(ASender: TComponent; const AReplyStatus: TReplyStatus);

Page 141: Delphi 7 Internet e Banco de Dados - Facunte

Desenvolvendo utilitários para Internet 141

Esta é uma declaração padrão para o evento OnReply do objeto NossoICMP. Com relação à propriedade MsRoundTripTime, ela representa o tempo em milessegundos do resultado de retorno do pacote. Caso o resultado seja 0, então atribuímos o valor “ < 1” à nossa variável sTime, senão, atribuímos o valor “ = “. Prosseguindo com a nossa análise, agora vem o ponto forte da nossa aplicação: 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 conteúdo ao nosso objeto mmResultado: mmResultado.Lines.Add

Estamos nos aproveitando da função Format para facilitar a composição da linha de resultado. Para quem não conhece a função Format, sugiro uma breve visita no Help do Delphi, onde sempre encontramos ricas informações. Vejamos os significados das propriedades da constante AReplyStatus. BytesReceived = bytes recebidos FromIpAddress = endereço do Host SequenceId = número da sequência TimeToLive = Tempo de vida do pacote

Agora vamos executar o nosso projeto e ver o resultado. A figura 9.8 ilustra o nosso projeto em execução.

Figura 9.8 Projeto Ping em execução

Page 142: Delphi 7 Internet e Banco de Dados - Facunte

142 Delphi 7 – Internet e Banco de Dados

Missão Cumprida

Ao final deste tópico, 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;

Page 143: Delphi 7 Internet e Banco de Dados - Facunte

Desenvolvendo utilitários 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 tópico vamos desenvolver uma nova versão para o trace route.

Muito semelhante ao nosso utilitário ping, mas com funcionalidades mais completas, apresentando todos os servidores por onde trafegam os pacotes de informações, entre cliente e servidor final. A figura 9.9 ilustra uma simulação do trace route.

Page 144: Delphi 7 Internet e Banco de Dados - Facunte

144 Delphi 7 – Internet e Banco de Dados

Figura 9.9 Simulação do Trace Route

Com o trace route poderemos descobrir falhas ou lentidão 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 próprio site, pode ser um dos servidores envolvidos (conhecido como hope) no processo. Nosso utilitário é uma adaptação de um programa de demonstração que vem no pacote da INDY Components. Vamos iniciar o desenvolvimento do nosso utilitário. Através das opções File/New...CLX Application, crie uma nova aplicação. 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 alTop Name pnTopo Height 155

Cliente (Brasil)

tempo de resposta: 2ms Provedor de Acesso

tempo de resposta: 3ms BackBone Embratel

tempo de resposta: 1ms Servidor Final: Japão

Page 145: Delphi 7 Internet e Banco de Dados - Facunte

Desenvolvendo utilitários para Internet 145

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

Objeto TPanel [Standard] Align alTop Name pnDados Height 60

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

Objeto TListBox [Standard] Align alClient Name lbLog

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

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

Objeto TLabel[Standard]

Caption Máximo Hopes Left 12 Top 40

Objeto TEdit [Standard] Left 110 Name edTarget Text (deixar em branco) Top 5 Width 280

Objeto TSpindEdit [Common Controls] Left 110 Name seMaxHops Top 32 Value 50 Width 65

Objeto TButton [Standard] Caption Executa Left 184 Name btExecuta Top 32 Width 75

Page 146: Delphi 7 Internet e Banco de Dados - Facunte

146 Delphi 7 – Internet e Banco de Dados

Objeto TButton [Standard] Caption Cancela Left 270 Name btCancela Top 32 Width 75

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

Objeto TPanel [Standard] Align AlClient Name PnInfo

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

Objeto TListView [Common Controls] Align alClient Columns insira três colunas como ilustra a figura 9.10 Name LvTrace ViewStyle 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 idAntiFreeze

A figura 9.11 ilustra nosso formulário.

Page 147: Delphi 7 Internet e Banco de Dados - Facunte

Desenvolvendo utilitários para Internet 147

Figura 9.11 Formulário do projeto Tracert

Para facilitar a organização das nossas procedures e ações, vamos utilizar o componente ActionList. Insira um objeto do tipo TActionList e através do duplo-clique insira as seguintes ações (figura 9.12).

: Figura 9.12 Ações do projeto

Agora vamos codificar nosso projeto. Na seção private insira o código que segue. bResolved: Boolean; ResolvedHost: String; Stopped: Boolean; function PingHost(Host: string; TTL: Integer): boolean; function FindItem(TTL: Integer; Add: boolean): TListItem;

Nesta seção, definimos algumas variáveis e funções com o objetivo de auxiliar em alguns processos. bResolved: Boolean; ResolvedHost: String; Stopped: Boolean;

Page 148: Delphi 7 Internet e Banco de Dados - Facunte

148 Delphi 7 – Internet e Banco de Dados

bResolved para atribuir true ou false na operação de ping ResolvedHost para atribuir o host (hope) em operação Stopped atribui o valor true para informar a paralisação das operações. function PingHost(Host: string; TTL: Integer): boolean; function FindItem(TTL: Integer; Add: boolean): TListItem;

Na cláusula uses insira as seguintes Units. uses idStack, IdException;

Agora vamos codificar as ações: No evento OnExecute da Action acGO, insira o código 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 definições iniciais do nosso projeto, e executando as rotinas de ping e trace. No evento OnExecute da Action acResolve, insira o código 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 código estamos resolvendo um host (hope), ou melhor, verificando informações e possibilidade de contato com o host. Repare que estamos utilizando a função WSGetHostByName, da unit IdStack, para mapear e resolver o host. ResolvedHost := gStack.WSGetHostByName(edTarget.text);

Se a operação for bem sucedida, adicionamos no lbLog o resultado; caso contrário, a mensagem de erro. Operação bem sucedida

lbLog.Items.Append(format('%s resolvido %s',[edTarget.text, ResolvedHost]));

Page 149: Delphi 7 Internet e Banco de Dados - Facunte

Desenvolvendo utilitários 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 código. PingHost(ResolvedHost, seMaxHops.value); Application.ProcessMessages;

Aqui estamos executando a chamada da função PingHost (será criada posteriormente), com o host atual, e o máximo de hopes. No evento OnExecute da Action acTrace, insira o código 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 unreachable', [IdIcmpClient.ReplyStatus.MsRoundTripTime])); break; end; rsErrorTTLExceeded: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress);

Page 150: Delphi 7 Internet e Banco de Dados - Facunte

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 código é um pouco mais complexo, mas vamos analisar passo a passo. Inicialmente, estamos definindo algumas variáveis auxiliares. TTL define o hope atual. Reached define se o TTL atual foi resolvido aItem objeto do tipo TListItem para ser adicionado em nosso LvTrace. var TTL: Integer; Reached: boolean; aItem: TListItem;

Em seguida temos a atribuição inicial das variáveis. TTL := 0; reached := false; lvTrace.Items.Clear;

O bloco que segue inicia um laço, até que uma das três situações (resolvido – reached = true, TTL > hopes, ou solicitação de cancelamento) seja verdadeira. Incrementamos o TTL, e atribuímos ao objeto idICMPClient algumas configurações, como Host e TTL. Executamos o método ping do idICMPClient, e em seguida preparamos o objeto aItem para receber a informação do resultado da operação. repeat inc(TTL); IdIcmpClient.Host := ResolvedHost; IdIcmpClient.TTL := TTL; IdIcmpClient.ReceiveTimeout := 5000; IdIcmpClient.Ping; aItem := FindItem(TTL, True); aItem.SubItems.Clear;

Os próximos blocos tratam os diversos tipos de resultado do método 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 também adiciona um subitem ao objeto aItem. rsError: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append('Unknown error.'); end;

Page 151: Delphi 7 Internet e Banco de Dados - Facunte

Desenvolvendo utilitários para Internet 151

O próximo 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 operação não 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 número máximo 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 código realmente complexo, mas estudando com calma e atenção, entenderemos cada método implementado. Agora no evento OnExecute da Action acStop, insira o código que segue. Stopped := true; acStop.enabled := false;

Com isso estamos solicitando uma parada nas operações. Agora vamos atribuir as Actions acGO e acStop, ao objeto btExecuta e btCancela, respectivamente. Para tanto, basta selecionar a Action desejada do objeto em questão. 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 código 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

Page 152: Delphi 7 Internet e Banco de Dados - Facunte

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 não 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 operações em nosso objeto lbLog. Agora vamos criar a rotina FindItem. Insira o código 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 função é retornar informações adicionadas no objeto lvTrace, baseada na TTL atual, e utilizada pela Action acTrace. Agora vamos gravar e compilar nossa aplicação. A figura 9.13 ilustra nossa aplicação sendo executada.

Page 153: Delphi 7 Internet e Banco de Dados - Facunte

Desenvolvendo utilitários para Internet 153

Figura 9.13 Tracert em ação

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;

Page 154: Delphi 7 Internet e Banco de Dados - Facunte

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]));

Page 155: Delphi 7 Internet e Banco de Dados - Facunte

Desenvolvendo utilitários 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',

Page 156: Delphi 7 Internet e Banco de Dados - Facunte

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;

Page 157: Delphi 7 Internet e Banco de Dados - Facunte

Desenvolvendo utilitários 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.

Page 158: Delphi 7 Internet e Banco de Dados - Facunte

158 Delphi 7 – Internet e Banco de Dados

Anotações de Dúvidas

Preciso Revisar Anotações Gerais

?

!

Page 159: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações para Celulares 159

Capítulo 10

Desenvolvendo Aplicações para Celulares

Visão geral Amigos, neste capítulo iremos aprender a desenvolver aplicações WAP para celulares. Mas Facunte, o WAP não 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 após diversas resistências, adotaram a tecnologia em suas culturas empresariais. Cultura? É isso mesmo! Cultura. O grande problema do WAP é que nós brasileiros demoramos para nos acostumar com novidades, além, é claro, da barreira de resistência a tornar um hábito certas coisas. É verdade que o WAP não atingiu o que as “teles” previam, onde todos os seus assinantes utilizariam o WAP para algum tipo de serviço. Isso mesmo, serviço. 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 força de vendas, troca de mensagens em grupo, pesquisa de campo, entre outras aplicações que veremos ao longo do capítulo.

WAP no Brasil

Continuando com a nossa discussão, será que temos oportunidades de lucro no Brasil? A oportunidade existe, mas poucas empresas estão investindo nesta área, certamente lucrativa. Será que sou um romântico sonhador? Sonhando com o lucro em tempos de vacas magras? Amigos, posso afirmar que não, 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 país 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 móveis, mas destacando apenas sua beleza e algumas funcionalidades. Facunte, então o sonho do lucro ficou ainda mais distante? Amigos, aí é que entra o consultor, para explicar aos gerentes de tecnologia, CEOs, que a relação custo benefício com o WAP é muito boa, e que o desenvolvimento é quase transparente, pois podemos criar aplicações WAP na maioria das linguagens, como: Delphi, .NET (VB, C#, ASP), PHP, Java (JSP, EJB), entre outras.

159

Page 160: Delphi 7 Internet e Banco de Dados - Facunte

160 Delphi 7 – Internet e Banco de Dados

Modelos de Aparelhos A disponibilidade de aparelhos no Brasil é muito grande, e o preço é 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 negócios, 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 força do WAP, vamos conhecer alguns cases de sucesso.

Caixa Econômica Federal A Caixa Econômica Federal disponibiliza a todos a informação sobre o saldo do FGTS através da tecnologia WAP. Para ter uma idéia da transparência neste case, a mesma aplicação disponibiliza informação via telefone (fixo), Internet e celular (WAP). Totalmente desenvolvida em JAVA, a solução teve seu custo reduzido devido à leve infra-estrutura necessária para abrigar toda a aplicação. Embora tenha exemplificado o case da Caixa Econômica Federal, é importante ressaltar que a maioria dos bancos nacionais oferecem variados recursos com a tecnologia WAP.

Page 161: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações para Celulares 161

InvestShop.COM.BR A instituição financeira InvestShop desenvolveu em conjunto com a EverSystem (talvez a maior empresa de desenvolvimento deste setor) uma solução bastante robusta oferecendo ao usuário um controle total de suas aplicações. Só para ter uma idéia, a aplicação disponibiliza até gráficos de ações em celulares WAP. É realmente incrível.

DETRAN-SP Um dos pioneiros na tecnologia WAP, o DETRAN de São Paulo disponibiliza informações de Multas, Pontuações na Carteira, entre outros.

Viram como o poder do WAP é grande? Basta uma idéia para transformá-lo em lucro!

Algumas idéias para ganhar dinheiro Bem, aqui vão algumas sugestões bastante interessantes para ganhar dinheiro com aplicações WAP.

Força de Vendas Aplicação de auxílio a vendedores externos, com opção de consulta a estoque, faturas de clientes e fechamento de pedidos.

Pesquisas de Campo Aplicação que auxilia pesquisadores das mais variadas áreas: IBOPE, CENSO, Opinião, Produtos, entre outras.

TimeSheet Aplicação para TimeSheet de consultores, advogados, técnicos, entre outros. Processos Gerenciamento de Processos Jurídicos, onde o advogado ou cliente poderá

consultar informações sobre os andamentos dos processos. m-Ticket (m=mobile) Vendas de ingressos, passagens aéreas, cinemas, teatros, etc . m-Finance Aplicações para o mercado financeiro. m-Commerce Comércio em geral através de aplicações WAP.

Entendendo o funcionamento das aplicações WAP Para entender um pouco como funciona uma aplicação WAP, precisamos conhecer o funcionamento de uma aplicação servidora. Em nosso caso teremos apenas o módulo servidor, pois o cliente da nossa aplicação é um browser com suporte à tecnologia WAP, ou seja, a grande maioria dos celulares comercializados no mercado nacional. Para facilitar a compreensão, a figura 10.1 ilustra bem o nosso caso:

celular (cliente) Servidor GateWay

Figura 10.1 Esquema de funcionamento WAP

HTTP/WML

WML/HTTP

Page 162: Delphi 7 Internet e Banco de Dados - Facunte

162 Delphi 7 – Internet e Banco de Dados

Na ilustração, temos um celular, que funciona como o nosso cliente (terminal), onde solicita os serviços ao servidor. Os dados (WML) trafegam através do protocolo HTTP. Quando os dados chegam no servidor, o mesmo tem que interpretar a requisição, e esse serviço é feito pelo GateWay. O GateWay também tem como função empacotar o resultado da requisição, para que o servidor retransmita ao celular. Em resumo, necessitamos de duas aplicações básicas no servidor:

!" Servidor HTTP (recomendo o Apache Server) !" Nossa aplicação servidora.

Um detalhe bastante interessante é que o Apache Server traz consigo embutido um excelente GateWay WAP. Embora esteja documentado que o Apache apenas suporta aplicações WAP, ele possui toda a implementação necessária para um perfeito funcionamento. Para que possamos prosseguir no desenvolvimento de nossas aplicações, precisamos também de um simulador WAP. Existem vários 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á disponível no site da PyWeb (www.pyweb.com) e, assim como o Apache, é totalmente freeware.

Mime-Types WAP

Outra coisa importante a saber são os MimeTypes WAP. Mas o que são MimeTypes? Para que os servidores HTTP reconheçam um tipo de requisição, ou então, um método de envio, é necessária a definição dos MimeTypes. Só para clarear um pouco a informação, uma imagem do tipo JPG é definida como image/JPG. Com isso o servidor saberá qual o melhor método de transmissão para este tipo de arquivo.

Mime Types do WAP

Tipo de Arquivo Extensão MIME Type

Código-fonte WML .wml text/vnd.wap.wml

WML compilado .wmlc application/vnd.wap.wmlc

Código-fonte WMLScript .wmls text/vnd.wap.wmlscript

WMLScript compilado .wmlcs application/vnd.wap.wmlscriptc

Imagem bitmap .wbmp image/vnd.wap.wbmp Tabela 10.2 – mime types WAP

Page 163: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações para Celulares 163

Vamos adicionar os Mime-Types ao Apache, embora a partir da versão 1.3.1 já estejam implementados todos os tipos necessários. No arquivo httpd.conf adicione as seguintes linhas: AddType text/vnd.wap.wml .wml AddType image/vnd.wap.wbmp .wbmp AddType text/vnd.wap.wmlscript .wmls AddType application/vnd.wap.wmlscriptc .wlsc

Grave o arquivo e reinicie o Apache.

WML O WML, Wireless Markup Language, é a linguagem de programação para o desenvolvimento de documentos WAP. Muito parecida com o HTML e também com alguns conceitos do XML. Uma das características desta linguagem é a adoção do case

sensitive, ou seja, deck é diferente de Deck ou DECK. Fique atento. Normalmente utilizamos letras minúsculas para trabalhar com as Tags WML.

TAGS WML

<a>

Cria um hiperlink ligando uma URL, ou ID de outra Tag. É recomendado o uso desta Tag ao invés da Tag <anchor>.

Exemplo

<a href = “consulta” consulta> Atributos

Nome Tipo Obrigatório

id String Não class String Não xml:lang String Não href href Sim title String Não

Minha opinião

O WML evoluiu muito durante os tempos e o consórcio formado para a criação deste padrão 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?.

Page 164: Delphi 7 Internet e Banco de Dados - Facunte

164 Delphi 7 – Internet e Banco de Dados

Descritivo dos Atributos

Atributo Descrição

id Identificação do elemento (nome único)

class Classe a que o elemento pertence

xml:lang Definição da linguagem XML

href Link de referência

title Texto, descrevendo o link

<access>

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

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

Baseado neste exemplo, vejamos o que é permitido:

permitido não permitido www.facunte.com.br/VIP/x.wml www.facunte.com.br/livros.wml www.facunte.com.br/VIP/index.wml www.facunte.com.br/x.wml

Neste exemplo determinamos que o deck atual só poderá ser acessado, a partir de uma requisição da domínio facunte.com.br, e do caminho /VIP, ou seja, somente quem estiver no diretório /VIP poderá acessar as informações do deck em questão. Atributos

Nome Tipo Obrigatório

id String Não class String Não domain String Não path String Não

Descritivo dos Atributos

Atributo Descrição

id Identificação do elemento (nome único)

class Classe a que o elemento pertence

domain Domínio que poderá acessar o elemento

path Caminho dentro do domain (domínio) que poderá acessar o elemento. Se não for especificado, todos os caminhos do domain poderão acessar o elemento

<anchor>

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

<anchor href== “consulta” consulta>

Page 165: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações para Celulares 165

<b> Tag utilizada para formatar textos em negrito. É recomendado o uso da Tag <strong> ao invés 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 coleção de cards, formando um deck. Exemplos:

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

Nome Tipo Obrigatório Padrão

id String Não class String Não xml:lang String Não title String Não newcontext Boolean Não Não ordered Boolean Não Sim

Page 166: Delphi 7 Internet e Banco de Dados - Facunte

166 Delphi 7 – Internet e Banco de Dados

Descritivo dos Atributos

Atributo Descrição

id Identificação do elemento (nome único)

class Classe a que o elemento pertence

title Indentificação do cartão

newcontext Indica ao browser para trazer o card em questão atualizado

ordered Organiza o card Eventos do elemento Card

Evento Descrição

onenterforward Utilizado em conjunto com o elemento GO (veja nas próximas páginas)

onenterbackward Utilizado em conjunto com o elemento PREV (veja nas próximas páginas)

ontimer Utilizado para disparar uma referência, que pode ser um CARD ou outra URL, quando o tempo determinado expirar

<do> Esta Tag é utilizada para acessar informações acima do card atual. Exemplos:

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

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

Nome Tipo Obrigatório

id String Não class String Não xml:lang String Não type String Sim label String Não name String Não optional Boolean Não

Descritivo dos Atributos

Atributo Descrição

id Identificação do elemento (nome único)

class Classe a que o elemento pertence

type Tipos definidos do elemento (veja tabela a seguir)

label Texto descritivo do elemento, visível para o usuário

name Identifica o nome de ligação

optional Define o elemento como opcional

Page 167: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações para Celulares 167

Complementos do atributo Type

tipo Descrição

accept Reconhecimento positivo

prev Navegação de retorno

help Ajuda

reset Limpar, ou resetar

options Solicitação para opções ou operações adicionais

delete Apagar item

unknown De uso genérico <em> 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 navegação. Atributos

Nome Tipo Obrigatório

id String Não class String Não xml:lang String Não title String Não

Exemplo:

<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”/>

Page 168: Delphi 7 Internet e Banco de Dados - Facunte

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 navegação entre cards ou decks, e é utilizado em conjunto com o elemento <do>. Atributos

Nome Tipo Obrigatório Padrão

id String Não class String Não href href Não sendreferer Boolean Não false method Method Não get accept-charset String Não unknown

Descritivo dos Atributos

Atributo Descrição

id Identificação do elemento (nome único)

class Classe a que o elemento pertence

href Endereço URL (caminho)

sendreferer Em caso verdadeiro(True), o browser do usuário deverá especificar o URL do deck contendo esta tarefa

method Método de envio de dados (POST ou GET)

optional Define o elemento como opcional Exemplo: ... <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>

Page 169: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações para Celulares 169

<head>

A tag <head> contém informações sobre o documento, como os metadatas e as tags de controle de acesso. Atributos

Nome Tipo Obrigatório Padrão

id String Não class String Não

Descritivo dos Atributos

Atributo Descrição

id Identificação do elemento (nome único)

class Classe a que o elemento pertence <i> Utilizada para formatar o texto em itálico. Exemplo:

<i> Seja bem-vindo </i>

<img>

A tag <img> é utilizada para incluir uma imagem no documento. As imagens devem seguir o padrão WBMP. Veremos um tópico abordando este assunto. Atributos

Nome Tipo Obrigatório Padrão

id String Não class String Não xml:lang String Não alt String Não scr URL Sim localscr String Não vspace Length Não Small, non-

zero hspace Length Não Small, non-

zero align String Não bottom height Length Não width Length Não

Descritivo dos Atributos

Atributo Descrição

id Identificação do elemento (nome único)

class Classe a que o elemento pertence

alt Texto a ser exibido enquanto a imagem é carregada, ou numa possível falha em seu carregamento

Page 170: Delphi 7 Internet e Banco de Dados - Facunte

170 Delphi 7 – Internet e Banco de Dados

Atributo Descrição

scr Especifica o caminho da imagem

localscr Alternativa à imagem

vspace Espaço em branco vertical

hspace Espaço em branco horizontal

align Alinhamento da imagem em relação à página top – topo da página middle – meio bottom – alinhada abaixo da página

height Tamanho vertical da imagem

width Tamanho horizontal da imagem Exemplos:

<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 usuário. Atributos

Nome Tipo Obrigatório Padrão

id String Não class String Não xml:lang String Não name String Sim type Input_Type Não text value String Não format String Não *M emptyok Boolean Não false size Number Não maxlength Number Não Infinite tabindex Number Não title String Não

Page 171: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações para Celulares 171

Descritivo dos Atributos

Atributo Descrição

id Identificação do elemento (nome único)

class Classe a que o elemento pertence

name Nome do elemento — muito importante para tratar o dado

type Tipo da entrada de dados, que pode ser texto (text), ou senha (pass)

value Valor padrão do campo

format Máscara do campo (veja a tabela que segue (A))

emptyok Permite a escolha de campos opcionais

size Largura da área de entrada de dados

maxlength Tamanho máximo, em caracteres, para a entrada de dados

tabindex Como no Delphi — ordem de entrada

title Titulo do campo Máscaras (A)

Máscara Descrição

A Letras maiúsculas e caracteres de pontuação a Letras minúsculas e caracteres de pontuação N Somente números X Somente letras maiúsculas x Somente letras minúsculas M Qualquer caractere e assume maiúsculo (dependendo do

browser) m Qualquer caractere e assume minúsculo (dependendo do

browser) *f Somente caractere numérico nf Caractere numérico 0 a 9

Exemplos

<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> contém informações genéricas relativas ao deck do WML. Assim, como no padrão HTML, é utilizada para definir alguns dados do documento.

Page 172: Delphi 7 Internet e Banco de Dados - Facunte

172 Delphi 7 – Internet e Banco de Dados

Atributos

Nome Tipo Obrigatório Padrão

Id String Não class String Não http-equiv String Não name String Não forua Boolean Não content String Sim scheme String Não

Descritivo dos Atributos

Atributo Descrição

id Identificação do elemento (nome único) class Classe a que o elemento pertence http-equiv Indica que a propriedade deve ser interpretada como

um cabeçalho http forua Em caso de false, o intermediário deverá remover o

“elemento meta” antes do mesmo ser enviado ao cliente; senão (true), os dados são enviados ao browser do usuário

content Conteúdo do metadata, como por exemplo, um tipo scheme Estrutura que deverá ser utilizada para interpretar o

metadata

<noop>

A tag <noop> é utilizada para cancelar operações realizadas no deck. Atributos

Nome Tipo Obrigatório Padrão

id String Não class String Não

<onevent>

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

Nome Tipo Obrigatório Padrão

id String Não class String Não type String Sim

<optgroup>

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

Page 173: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações para Celulares 173

Atributos

Nome Tipo Obrigatório Padrão

id String Não class String Não xml:lang String Não title String Não

Descritivo dos Atributos

Atributo Descrição

id Identificação do elemento (nome único)

class Classe a que o elemento pertence

title Referência do grupo Exemplos:

<optgroup title=”estado”> <option title=”São Paulo” value=”SP”> <option title=”Rio de Janeiro” value=”RJ”> <option title=”Bahia” value=”BA”> .... </optgroup>

<option>

A tag <option> cria uma opção de escolha em um elemento selecionado. Atributos

Nome Tipo Obrigatório Padrão

id String Não class String Não xml:lang String Não value String Não title String Não onpick href Não

Descritivo dos Atributos

Atributo Descrição

id Identificação do elemento (nome único)

class Classe a que o elemento pertence

value Valor atribuído à opção

title Expressão apresentada ao usuário

onpick Dispara a chamada de uma URL, quando a opção for selecionada

Page 174: Delphi 7 Internet e Banco de Dados - Facunte

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=”Português” value=”P” onpick=”/port.wml”> <option title=”Inglês” value=”I” onpick=”/ingles.wml”> .... </optgroup>

<p>

A tag <p> inicia um parágrafo com os atributos especificados. Atributos

Nome Tipo Obrigatório Padrão

id String Não class String Não xml:lang String Não align TAlign Não left mode Wrapmode Não wrap

Descritivo dos Atributos

Atributo Descrição

id Identificação do elemento (nome único)

class Classe a que o elemento pertence

align Alinhamento do parágrafo left = esquerda right = direita center = centralizado

mode Especifica o modo de parada do texto Exemplos:

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

Page 175: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações 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 transmissão a um servidor de origem, durante uma requisição de URL. Atributos

Nome Tipo Obrigatório Padrão

id String Não class String Não name String Sim value String Sim

Descritivo dos Atributos

Atributo Descrição

id Identificação do elemento (nome único)

class Classe a que o elemento pertence

name Nome do campo

value Valor do campo Exemplos:

<postfield name=”PAIS” value=”BRASIL”>

<prev>

A tag <prev> retorna a navegação para a URL anterior no histórico do browser. Atributos

Nome Tipo Obrigatório Padrão

id String Não class String Não

Sintaxe

<prev>

<refresh>

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

Page 176: Delphi 7 Internet e Banco de Dados - Facunte

176 Delphi 7 – Internet e Banco de Dados

Atributos

Nome Tipo Obrigatório Padrão

Id String Não class String Não

Sintaxe

<refresh>

<select>

A tag <select> inicia uma lista de seleção. Os itens da lista são criados através da tag <option>. Atributos

Nome Tipo Obrigatório Padrão

id String Não class String Não xml:lang String Não title String Não name String Sim value String Não iname String Não ivalue String Não multiple Boolean Não tabindex Number Não

Descritivo dos Atributos

Atributo Descrição

id Identificação do elemento (nome único)

class Classe a que o elemento pertence

title Define o título a ser exibido ao usuário

name Nome do elemento (campo)

value Recebe o nome da opção selecionada; o nome é definido no atributo iname, e o valor no ivalue

iname Declaração do nome do elemento

ivalue Valor da opção selecionada na lista de opções Exemplos:

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

Page 177: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações para Celulares 177

A tag <setvar> é utilizada para definir o valor de uma variável. Atributos

Nome Tipo Obrigatório Padrão

id String Não class String Não name String Sim value String Sim

Exemplo:

<setvar name=”SOBRENOME” value=”FACUNTE”>

<small>

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

Nome Tipo Obrigatório Padrão

id String Não class String Não xml:lang String Não

Exemplo:

<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 Tipo Obrigatório Padrão

id String Não class String Não xml:lang String Não

Exemplo:

<strong> powered by Facunte </strong>

<table>

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

Page 178: Delphi 7 Internet e Banco de Dados - Facunte

178 Delphi 7 – Internet e Banco de Dados

Atributos

Nome Tipo Obrigatório Padrão

id String Não class String Não xml:lang String Não title String Não align String Não columns Number Sim

Descritivo dos Atributos

Atributo Descrição

id Identificação do elemento (nome único)

class Classe a que o elemento pertence

title Define o título da tabela

align Alinhamento dos elementos da tabela

columns Número de colunas Exemplo simples:

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

Page 179: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações 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 ano modelo fiat 2002 palio elx

mercedes 2001 e500 honda 1999 civic gm 1998 blazer

<template>

A tag <template> define características comuns a todos os cards do dispositivo, disparando alguns eventos. Atributos

Nome Tipo Obrigatório Padrão

id String Não class String Não onenterforward href Não onenterbackward href Não ontime href Não

Descritivo dos Atributos

Atributo Descrição

id Identificação do elemento (nome único)

class Classe a que o elemento pertence

onenterforward Define a URL a ser disparada, caso o usuário acesse um cartão através da tag <do>

onenterbackward Define a URL a ser disparada, caso o usuário acesse um cartão através da tag <prev>

ontimer Define a URL a ser disparada, caso o tempo definido na tag <timer> expire

Exemplo:

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

Page 180: Delphi 7 Internet e Banco de Dados - Facunte

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 Tipo Obrigatório Padrão

id String Não class String Não value Number Sim

Exemplo:

<card name=”card1” ontimer=”#card2”> <timer value=100/> <p>Esta mensagem será destruída em 10 segundos</p> </card> <card name=”card2”> <p>Mensagem Destruída</p> </card>

Acentos em WML

Nome Código Resultado &nbsp; &#160; espaço &iexcl; &#161; ¡ &cent; &#162; ¢

&pound; &#163; £ &curren; &#164; ¤

&yen; &#165; ¥ &brvbar; &#166; ¦ &sect; &#167; § &uml; &#168; ¨ &copy; &#169; © &not; &#172; ¬ &reg; &#174; ® &deg; &#176; °

&plusmn; &#177; ± &acute; &#180; ´ &frac14; &#188; ¼ &frac12; &#189; ½ &frac34; &#190; ¾ &iquest; &#191; ¿ &Agrave; &#192; À &Aacute; &#193; Á &Acirc; &#194; Â

Page 181: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações para Celulares 181

&Atilde; &#195; Ã &Auml; &#196; Ä &Aring; &#197; Å &AElig; &#198; Æ &Ccedil; &#199; Ç &Egrave; &#200; È &Eacute; &#201; Ò &Ecirc; &#202; Ê &Euml; &#203; Ë &Igrave; &#204; Ì &Iacute; &#205; Í &Icirc; &#206; Î &Iuml; &#207; Ï

&Ntilde; &#209; Ñ &Ograve; &#210; Ò &Oacute; &#211; Ó &Ocirc; &#212; Ô &Otilde; &#213; Õ &Ouml; &#214; Ö &times; &#215; ×

&Oslash; &#216; Ø &Ugrave; &#217; Ù &Uacute; &#218; Ú &Ucirc; &#219; Û &Uuml; &#220; Ü

&Yacute; &#221; Ý &thorn; &#222; Þ &szlig; &#223; ß

&agrave; &#224; à &aacute; &#225; á &acirc; &#226; â &atilde; &#227; ã &auml; &#228; ä &aring; &#229; å &aelig; &#230; æ &ccedil; &#231; Õ &egrave; &#232; è &eacute; &#233; é &ecirc; &#234; ê &euml; &#235; ë &igrave; &#236; ì &iacute; &#237; í &icirc; &#238; î &iuml; &#239; ï

&ntilde; &#241; ñ &ograve; &#242; ò

Page 182: Delphi 7 Internet e Banco de Dados - Facunte

182 Delphi 7 – Internet e Banco de Dados

&oacute; &#243; ó &ocirc; &#244; ô &otilde; &#245; õ &ouml; &#246; ö &divide; &#247; ÷ &oslash; &#248; ø &ugrave; &#249; ù &uacute; &#250; ú &ucirc; &#251; û &uuml; &#252; ü

&yacute; &#253; ý &thorn; &#254; þ &yuml; &#255; ÿ

Desenvolvendo Aplicações WAP x Delphi Agora vamos colocar a mão na massa e desenvolver alguns exemplos de aplicações 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 aplicação servidora no padrão CGI. A partir do Delphi, selecione as opções File/New/Other... e em seguida a opção Web Server Application, como ilustra a figura

10.3.

Figura 10.3 Opção Web Server Application

Na janela seguinte selecione a opção CGI Stand-Alone executable (figura 10.4).

Page 183: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações para Celulares 183

Figura 10.4 Seleção do tipo da aplicação

Em seguida teremos o nosso WebModule (figura 10.5),

Figura 10.5 WebModule

Bem, seguindo o nosso primeiro projeto, através do duplo-clique no WebModule, acesse o editor de ActionItems (figura 10.6).

Figura 10.6 editor ActionItems

Clique no primeiro botão do editor para inserir uma nova Action (figura 10.7).

Page 184: Delphi 7 Internet e Banco de Dados - Facunte

184 Delphi 7 – Internet e Banco de Dados

Figura 10.7 ActionItem

Em seguida altere as seguintes propriedades.

OBJETO

TWebActionItem

Objeto Propriedade Valor

padrao Default True Name padrao PathInfo /padrao

Esta será nossa Action padrão, ou seja, caso o usuário não digite nada, além do nome da nossa aplicação, 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 código: 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>';

Não se assustem com as denominações do cabeçalho “<DOCTYPE wml....”, isso é um padrão, e o restante iremos conhecendo aos poucos. Vamos analisar o código: Na linha 001, estou dizendo ao servidor, através do método Response.ContentType, que o tipo de informação é no padrão 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 aplicações servidoras num browser, como o Internet Explorer, mas neste caso iremos testá-la no nosso simulador Deck-It. Lembram dele?

Page 185: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações para Celulares 185

No Deck-It digite o que segue na barra de endereços: http://localhost/cgi-bin/ola.exe A figura 10.8 ilustra o resultado da nossa aplicação:

Figura 10.8 Resultado da aplicação

Só para ter uma idéia, você poderia simular em seu próprio celular WAP este exemplo. Mas Facunte, como eu faria isso? Conecte seu computador à Internet, anote o número do IP fornecido no momento da conexão, exemplo: 200.198.12.1, e digite no seu celular (o modo de entrada para comunicação WAP varia de celular para celular, consulte o manual de instruções), o endereço: http://200.198.12.1/cgi-bin/ola.exe Repare que o número, na realidade é o seu endereço de IP atual (exemplo). Continuando com a nossa aplicação, vamos criar mais uma Action com as seguintes propriedades:

OBJETO

TWebActionItem

Objeto Propriedade Valor

Theclub Default False Name theclub PathInfo /theclub

No evento OnAction coloque o seguinte código: 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>';

Page 186: Delphi 7 Internet e Banco de Dados - Facunte

186 Delphi 7 – Internet e Banco de Dados

O código é exatamente igual ao anterior, em que apenas substituimos a mensagem. Vamos testar o código? No Deck-It digite o que segue na barra de endereços: 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, não acham? E aí, amigos, estão 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

Page 187: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações 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 aplicação que iremos desenvolver, consiste em apresentar uma lista de e-mails que está armazenada em nosso banco de dados. Através das opções File/New..., selecione o item Web Server Application (figura 10.10) e clique em OK.

Figura 10.10 Item Web Server Application

Page 188: Delphi 7 Internet e Banco de Dados - Facunte

188 Delphi 7 – Internet e Banco de Dados

Em seguida, selecione o tipo de aplicação CGI, e marque a opção Cross Platform (figura 10.11). Perceba que com isso poderemos executar a mesma aplicação num servidor Linux, sendo que o código deverá ser recompilado em Kylix.

Figura 10.11 Escolha do tipo da aplicação servidora

Agora, neste ponto, precisamos estabelecer a conexão com o nosso banco de dados. Insira um objeto do tipo TSQLConnection, e através do duplo-clique, já na tela de configuração, crie uma nova conexão do tipo Interbase, alterando as propriedades que seguem. A figura 10.12 ilustra o diálogo de propriedades do componente TSQLConnection.

PROPRIEDADE

VALOR

CommitRetain

False

Database

localhost:c:\cursoweb\clientes.gdb

Password

a famosa masterkey

UserName

o famoso SYSDBA

Name

ConexaoBD

Altere também a propriedade LoginPrompt para false. Nunca esqueça de fazer esta alteração, pois numa aplicação servidora, não existe a possibilidade do usuário interagir no login do banco de dados.

Page 189: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações para Celulares 189

Figura 10.12 Configuração da Conexão

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

ConexaoBD

CommandText

select * from TBCLIENTE

Active

True

Oba, já estamos chegando lá. Agora vamos inserir um objeto do tipo TdataSetTableProducer. Não confundam com

TdataSetPageProducer. Altere o nome do componente para producerCliente, e a propriedade DataSet para SQLCliente.

Através de um duplo-clique teremos a seguinte tela (assistente de configuração – figura 10.13).

Figura 10.13 Assistente de Configuração

Page 190: Delphi 7 Internet e Banco de Dados - Facunte

190 Delphi 7 – Internet e Banco de Dados

Caso não esteja vendo uma tela parecida (perceba que os dados já estão inseridos no banco e que você deverá inserir seus próprios registros), verifique se está tudo certo com a sua conexão. Deixe somente o campo e-mail, pois iremos listar apenas esta informação em nosso celular. Para realizar a tarefa, selecione os outros campos e aperte a tecla delete.

Veja o resultado desta operação, na figura 10.14.

Figura 10.14

Neste ponto, iremos criar nossa Action para apresentar a informação no celular. Crie uma Action com o nome dados, através do duplo-clique no WebModule. Veja a figura 10.15.

Figura 10.15 Action dados

No evento OnClick da Action dados, insira o código que segue. // Abre o SQLCliente SQLCliente.Open; // Define o tipo do conteúdo Response.ContentType:='text/vnd.wap.wml'; // Monta a cabeçalho padrão

Page 191: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações 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 código. 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 próxima instrução, estamos fazendo as definições iniciais, como cabeçalho <?xml...>, card <card>, e início de um parágrafo <P>. Isso é imprescindível. 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 informação obtida através do componente producer_Cliente, e finalizando o parágrafo<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).

Page 192: Delphi 7 Internet e Banco de Dados - Facunte

192 Delphi 7 – Internet e Banco de Dados

Figura 10.16 Resultado da aplicação.

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 conteúdo Response.ContentType:='text/vnd.wap.wml'; // Monta a cabeçalho padrão

Page 193: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações 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 (Inclusão) Agora vamos desenvolver algo mais interativo, onde o usuário do celular poderá se cadastrar em nosso banco de dados. Através das opções 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 aplicação CGI, e marque a opção Cross Platform (figura 10.18).

Page 194: Delphi 7 Internet e Banco de Dados - Facunte

194 Delphi 7 – Internet e Banco de Dados

Figura 10.18 Escolha do tipo da aplicação servidora

Agora, neste ponto, precisamos estabelecer a conexão com o nosso banco de dados. Insira um objeto do tipo TSQLConnection, e através do duplo-clique, já na tela de configuração, aponte para a nossa conexão Clientes, criada anteriormente. Vamos relembrar os atributos da conexão.

PROPRIEDADE

VALOR

CommitRetain

False

Database

localhost:c:\cursoweb\clientes.gdb

Password

a famosa masterkey

UserName

o famoso SYSDBA

Name

ConexaoBD

Altere também a propriedade LoginPrompt para false. Nunca esqueça de fazer esta alteração, pois numa aplicação servidora, não existe a possibilidade do usuário interagir no login do banco de dados.

Page 195: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações para Celulares 195

Figura 10.18 Configuração da Conexão

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

ConexaoBD

CommandText

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

Repare que estamos colocando dois parâmetros, (pRAZAO e pEMAIL), que deverão ser configurados através da propriedade PARAMS (figura 10.20).

Figura 10.20 Params

Page 196: Delphi 7 Internet e Banco de Dados - Facunte

196 Delphi 7 – Internet e Banco de Dados

Através do duplo-clique na propriedade Params, acessamos o editor de parâmetros (figura 10.21). Configure os dois parâmetros para o tipo ftString, através da propriedade DataType.

Figura 10.21 Configuração dos Parâmetros

Ok amigos, agora vamos continuar nossa aplicação inserindo um componente do tipo TPageProducer e alterar as seguintes propriedades:

PROPRIEDADE

VALOR

Name

ppInclusao

HTMLDoc

(Veja a listagem de código que segue)

Insira este código 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 variável em nosso WebModule para facilitar nas respostas ao cliente, em nosso caso, o celular. Antes da seção implementation, crie a nossa variável cabeçalho, como segue: var WebModule1: TWebModule1; cabecalho:string = '<?xml version="1.0"?>'+ '<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EM"

Page 197: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações 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 inclusão, e outra para confirmar. Primeiro vamos criar a Action inclusao.(sem

acento mesmo). No evento OnAction, insira o código que segue: Response.ContentType:='text/vnd.wap.wml'; Response.Content:=cabecalho+ppInclusao.Content;

Neste código, estamos informando o tipo de pacote e utilizando nossa variável auxiliar cabeçalho para compor a nossa resposta, além, é claro, do conteúdo do Producer ppInclusao. Bem simples, não? Em seguida, precisamos criar a nossa Action confirma. No evento OnAction, insira o código 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 Inclusão</p></card></wml>'; end;

Neste código estamos atribuindo aos parâmetros de nossa Query SQLInsere, o conteúdo informado pelo usuário, e transmitido através do método POST. O código está protegido através dos comandos try/except e, em caso de sucesso, apresentamos ao usuário a mensagem “Registro Incluído”. Caso contrário, apresentamos a mensagem “Erro na Inclusão”. As figuras 10.23,

10.24, 10.25 e 10.26 ilustram nossa aplicação em ação. Para chamar a aplicação, utilize: http://localhost/cgi-bin/wap_inc.exe/dados

Page 198: Delphi 7 Internet e Banco de Dados - Facunte

198 Delphi 7 – Internet e Banco de Dados

Figura 10.23 Digitando Razão Social

Figura 10.24 Digitando e-mail

Figura 10.25 Confirmando dados

Page 199: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações para Celulares 199

Figura 10.26 Registro incluído com sucesso

Amigos, com um pouquinho de esforço, dá para criar uma aplicação bem completa para celulares. Digo esforço pois existem vários limites nos aparelhos, como tamanho de tela, capacidade de dados, entre outras coisas, que nos fazem voltar ao tempo da magia e dedicação, onde fazíamos malabarismos com o Clipper, o C e o Turbo Pascal para oferecer telas agradáveis aos nossos usuários. Encerramos por aqui este tópico, 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">';

Page 200: Delphi 7 Internet e Banco de Dados - Facunte

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 Inclusão</p></card></wml>'; end; end; end.

Page 201: Delphi 7 Internet e Banco de Dados - Facunte

Aplicações para Celulares 201

Anotações de Dúvidas

Preciso Revisar Anotações Gerais

?

#

Page 202: Delphi 7 Internet e Banco de Dados - Facunte

202 Delphi 7 – Internet e Banco de Dados

Capítulo 11

WebSnap

O WebSnap, presente desde a versão 6 do Delphi, e a versão 2 do Kylix, tem como proposta e objetivo principal o desenvolvimento de aplicações para Internet com o conceito RAD (Rapid Application Development), ou desenvolvimento rápido de aplicações. Na realidade não foi incorporada para substituir o WebBroker, e sim complementar e estender suas funcionalidades. Uma das coisas mais interessantes nesta tecnologia é a possibilidade de utilizar inúmeros formulários para uma mesma aplicação. Em WebBroker não era possível, pelo menos não 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 também permitiu o desenvolvimento de outros frameworks bastante produtivos e que estão fazendo o maior sucesso entre os desenvolvedores. Prova disso foi a incorporação de um desses frameworks nesta versão do Delphi: o Intraweb, que veremos no próximo capítulo.

Algumas curiosidades

O modelo de desenvolvimento Web no Delphi vem crescendo a cada versão, provando a forte tendência deste modelo. Grandes empresas estão partindo para este modelo de desenvolvimento, justamente pela portabilidade, economia e praticidade. Sinceramente, sugiro que todos explorem o máximo 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

Page 203: Delphi 7 Internet e Banco de Dados - Facunte

WebSnap 203

A figura 11.1 ilustra a paleta de componentes do WebSnap.

Figura 11.1 Componentes WebSnap

Componente Descrição

TAdapter

Fornece uma interface de scripts e execução de comandos

TPagedAdapter

Fornece uma camada lógica para divisão de páginas de dados. Tecnologia comumente encontrada em sites de busca.

TDataSetAdapter

Fornece soluções de controles e comandos para DataSets. Adiciona funções semelhantes aos Adapters, relacionando com os DataSets.

TLoginFormAdapter

Utilizado para criar formulários de Login.

TStringsValuesList

Fornece aos Adapters uma lista de nomes e valores. Exemplo: Nome e Senha, Código e Razão Social, e assim por diante

TDataSetValuesList

Semelhante ao TStringValuesList, mas vinculado a um DataSet.

TWebAppComponents

Principal componente da tecnologia WebSnap. Fornece toda a interface para o desenvolvimento de aplicações WebSnap.

TApplicationAdapter

Fornece interface de scripts relacionados à informação da aplicação.

TEndUserAdapter

Controle de informação sobre o usuário, como Nome, ID, sessão.

TEndUserSessionAdapter

Controle completo sobre a informação de sessão do usuário. Normalmente utilizado com TSessionsService e TendUserAdapter.

Page 204: Delphi 7 Internet e Banco de Dados - Facunte

204 Delphi 7 – Internet e Banco de Dados

Componente Descrição

TPageDispatcher

Responsável pela interface de request HTTP de aplicações WebSnap. É necessário apenas um por aplicação.

TAdapterDispatcher

Fornece interface de tratamento de submissões de formulários HTML e imagens. É necessário para que a aplicação trabalhe com os adapter actions, além de imagens provenientes de adapter fields.

TLocateFileService

Fornece controle sobre arquivos de template e arquivos script-server-side. Facilita a manipulação destes arquivos.

TSessionService

Armazena informações de sessões temporariamente. Possui TimeOut, número máximo de sessões, entre outras funcionalidades.

TWebUserList

Controla uma lista predefinida de usuários, fazendo validação de login e controle de acesso.

TXSLPageProducer

Faz um parse em documentos XML, baseados no template XSL.

TAdapterPageProducer

Muito utilizado na tecnologia Web, cria um documento HTML com diversas funcionalidades e controles.

Preparando o ambiente para os exemplos Neste ponto vamos preparar nosso ambiente para o desenvolvimento das aplicações baseadas na tecnologia WebSnap.

Crie a seguinte estrutura de diretórios (diagrama 11.1)

Diagrama 11.1

C:\CursoWeb

WebSnap

exercicio1

exercicio2

exercício3

exercício4

clientes

Page 205: Delphi 7 Internet e Banco de Dados - Facunte

WebSnap 205

Primeiro Exemplo Neste primeiro exemplo, faremos uma simples demonstração da tecnologia WebSnap. O mais importante neste tópico é compreender toda a estrutura da tecnologia. Todos os passos serão analisados para que você compreenda de maneira satisfatória cada detalhe. Através das opções File/New/Other..., selecione a seção WebSnap e escolha a opções WebSnap Application (figura 11.2).

Figura 11.2 Selecionando o modelo da aplicação

Em seguida teremos uma janela assistente (figura 11.3) com diversas opções de configuração da aplicação.

Figura 11.3 Opções da aplicação WebSnap

Page 206: Delphi 7 Internet e Banco de Dados - Facunte

206 Delphi 7 – Internet e Banco de Dados

Vamos analisar as opções: Tipo do servidor

Primeiro, devemos escolher o tipo do servidor (CGI, ISAPI, Apache ou Web App Debugger). Escolha a opção Web App

Debugger e informe o nome da classe (necessário apenas para esta opção). Para este exemplo vamos nomear como classExemplo1.

O Web App Debugger na realidade é um servidor HTTP que oferece um ótimo nível de depuração para a nossa aplicação. Escolhendo esta opção é gerado um modelo de servidor COM, para interagir com o Web App Debugger. Esta opção é utilizada única e exclusivamente para o desenvolvimento e nunca para a distribuição. Componentes da Aplicação

Em seguida temos a seção Application Module Components, responsável pela configuração dos módulos da aplicação. Clicando no botão Components, você terá acesso à outra caixa de diálogo (figura 11.4) com opções de serviço.

Figura 11.4 Opções de serviço

Nesta caixa de diálogo escolhemos os serviços básicos de nossa aplicação. Na realidade cada serviço poderá ser adicionado à sua aplicação conforme a necessidade. Para este primeiro exemplo, mantenha as opções padrão e clique no botão OK. Opções da Aplicação

Em seguida temos a seção Application Module Options, responsável pela configuração das opções da aplicação. Clicando no botão Page Options, você terá acesso à caixa de diálogo (figura 11.5) com opções da aplicação.

Page 207: Delphi 7 Internet e Banco de Dados - Facunte

WebSnap 207

Figura 11.5 Opções da aplicação

Aqui temos um nível bastante interessante de configuração. Na primeira seção, temos a configuração do nosso Producer, com os seguintes tipos:

AdapterPageProducer DataSetPageProducer InetXPageProducer PageProducer XLSPageProducer

Selecione a opção PageProducer. Dependendo do tipo selecionado, temos as seguintes opções para o script engine:

JScript VBScript

Mantenha a seleção em JScript. Em seguida temos a seção HTML. Esta seção permite ao desenvolvedor criar uma página automaticamente, seja a partir de um modelo (Standard) ou em branco (Blank). Selecione a opção Standard e deixe marcada a opção New File. E, por fim, temos as informações da nossa página HTML.

Name Utilizado como referência para requisições HTTP e lógica da sua aplicação.

Title Título que será apresentado na janela do

browser. Published habilita o recurso de resposta as requisições

HTTP. Login Required Verifica se existe a necessidade do usuário fazer

Login para entrar nesta página.

Mantenha as opções padrão e pressione o botão OK. Retornando à caixa de diálogo inicial, pressione OK para concluir o assistente e gerar nossa primeira aplicação. A figura 11.6

ilustra o PageModule criado.

Page 208: Delphi 7 Internet e Banco de Dados - Facunte

208 Delphi 7 – Internet e Banco de Dados

Figura 11.6 Page Module

Agora vamos gravar nosso primeiro projeto no diretório \WebSnap\Exercicio1, como segue.

Unit PageModule un_ex1.PAS Unit Formulário un_form.PAS Projeto wsnap1.DPR

Após a gravação do nosso projeto, repare que foi gerado automaticamente um arquivo un_ex1.HTML, com o seguinte conteúdo. <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>

Page 209: Delphi 7 Internet e Banco de Dados - Facunte

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 através das Tabs do nosso editor de código (figura 11.7).

Figura 11.7 Tabs do editor de código

Antes de executar nossa primeira aplicação, insira uma frase qualquer no corpo do documento un_ex1.HTML, como segue. Nossa primeira aplicação

</body> </html>

Grave o documento para que possamos executar a aplicação. Execute normalmente a aplicação através da tecla F9, ou da opção Run/Run... do menu. Perceba que o formulário em branco, é apresentado na tela. Através das opções Tools/WebAppDebugger vamos executar o nosso servidor e depurador de aplicações. A figura 11.8 ilustra o WebAppDebugger em execução. Clique no botão Start para iniciar o servidor e, em seguida, no link Default URL.

Page 210: Delphi 7 Internet e Banco de Dados - Facunte

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 serviços registrados. Selecione o nosso exemplo e clique no botão GO.

Figura 11.9 Serviços registrados

A figura 11.10 ilustra o resultado da nossa primeira aplicação WebSnap.

Figura 11.10 Primeira aplicação WebSnap

Com isso concluímos nossa primeira aplicação.

Page 211: Delphi 7 Internet e Banco de Dados - Facunte

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 através do Delphi, ou até mesmo rotinas dinâmicas geradas no servidor. A grande vantagem de utilizar Server Scripts é justamente a facilidade da manutenção do projeto, onde muitas vezes, apenas o arquivo HTML sofre mudanças. Com isso não há necessidade de uma nova compilação.

Page 212: Delphi 7 Internet e Banco de Dados - Facunte

212 Delphi 7 – Internet e Banco de Dados

Já os Adapters, como você irá perceber ao longo deste capítulo, serão nossos grandes aliados. Na realidade os Adapters fornecem uma interface de scripts para a sua aplicação servidora. Vamos aprender na prática esses conceitos. Através das opções File/New/Other..., selecione a seção WebSnap e escolha a opções WebSnap Application (figura 11.11).

Figura 11.11 Selecionando o modelo da aplicação

Em seguida (figura 11.12) selecione a opção Web App Debugger, e informe o nome da classe (necessário apenas para esta opção). Para este exemplo vamos nomear como classExemplo2.

Figura 11.12 Opções da aplicação WebSnap

Page 213: Delphi 7 Internet e Banco de Dados - Facunte

WebSnap 213

Em seguida temos a seção Application Module Components, responsável pela configuração dos módulos da aplicação. Clicando no botão Components, você terá acesso à outra caixa de diálogo (figura 11.13) com opções de serviço.

Figura 11.13 Opções de serviço

Assim como no primeiro exemplo, mantenha as opções padrão e clique no botão OK. Em seguida temos a seção Application

Module Options, responsável pela configuração das opções da aplicação. Clicando no botão Page Options, você terá acesso à caixa de diálogo (figura 11.14) com opções da aplicação.

Figura 11.14 Opções da aplicação

Selecione Page Producer para o Producer Type e mantenha a seleção JScript. no Script Engine. Em seguida temos a seção HTML. Selecione a opção Standard e deixe marcada a opção New File. Retornando à caixa de diálogo inicial, pressione OK para concluir o assistente e gerar nossa segunda aplicação. A figura 11.15 ilustra o PageModule criado.

Page 214: Delphi 7 Internet e Banco de Dados - Facunte

214 Delphi 7 – Internet e Banco de Dados

Figura 11.15 Page Module

Agora vamos gravar nosso segundo projeto no diretório \WebSnap\Exercicio2, como segue.

Unit PageModule un_ex2.PAS Unit Formulário un_form.PAS Projeto wsnap2.DPR

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

Figura 11.16 Propriedade Data

Em seguida temos o editor de campos para o objeto Adapter (figura 11.17).

Page 215: Delphi 7 Internet e Banco de Dados - Facunte

WebSnap 215

Figura 11.17 Editor de campos

Clique com o botão direito do mouse sob o editor e selecione a opção New Component ou clique no primeiro botão, como ilustra a figura 11.17. Em seguida teremos uma lista com os possíveis componentes do nosso objeto Adapter1.

Figura 11.18 Componentes do Adapter

Selecione o componente AdapterField e clique no botão 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

Page 216: Delphi 7 Internet e Banco de Dados - Facunte

216 Delphi 7 – Internet e Banco de Dados

Prosseguindo com nosso exemplo, vamos atribuir um valor dinâmico ao nosso objeto MeuFieldAdapter. No evento OnGetValue insira o código 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 seção <BODY> do documento. <B><%Response.Write(Adapter1.MeuFieldAdapter.value)%></B>

Grave o nosso projeto e execute normalmente a aplicação através da tecla F9, ou da opção Run/Run... do menu. Através das opções Tools/WebAppDebugger vamos executar o nosso servidor e depurador de aplicações. Clique no botão 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 serviços registrados. Selecione o nosso exemplo e clique no botão GO.

Figura 11.20 Serviços registrados

Amigos, obviamente o exemplo é bastante simples, mas imaginem que através dos objetos Adapters poderemos acessar valores de cálculos, resultados de instruções SQL, imagens dinâmicas, 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;

Page 217: Delphi 7 Internet e Banco de Dados - Facunte

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> <% } %> <% } %>

Page 218: Delphi 7 Internet e Banco de Dados - Facunte

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 múltiplos Page Modules, além de dispensar o assistente para criação automática de páginas. Através das opções File/New/Other..., selecione a seção WebSnap e escolha a opções WebSnap Application (figura 11.21).

Figura 11.21 Selecionando o modelo da aplicação

Page 219: Delphi 7 Internet e Banco de Dados - Facunte

WebSnap 219

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

Figura 11.22 Opções da aplicação WebSnap

Em seguida temos a seção Application Module Components, responsável pela configuração dos módulos da aplicação. Clicando no botão Components, você terá acesso à outra caixa de diálogo (figura 11.23) com opções de serviço.

Figura 11.23 Opções de serviço

Assim como nos exemplos anteriores, mantenha as opções padrão e clique no botão OK.

Page 220: Delphi 7 Internet e Banco de Dados - Facunte

220 Delphi 7 – Internet e Banco de Dados

Em seguida temos a seção Application Module Options, responsável pela configuração das opções da aplicação. Clicando no botão Page Options, você terá acesso à caixa de diálogo (figura 11.24) com opções da aplicação. Selecione Page Producer

para o Producer Type e mantenha a seleção JScript. no Script Engine.

Em seguida temos a seção HTML. Desmarque a opção New File e clique no botão OK.

Figura 11.24 Opções da aplicação

Agora vamos gravar nosso terceiro projeto no diretório \WebSnap\Exercicio3, como segue.

Unit PageModule un_ex3.PAS Unit Formulário un_form.PAS Projeto wsnap3.DPR

Como dispensamos a criação automática do arquivo HTML, vamos utilizar os novos assistentes do Delphi, para criá-lo. Através das opções File/New/Other..., acesse a seção Web Documents como ilustra a figura 11.25 e selecione a opção HTML.

Figura 11.25 Novo documento HTML

Page 221: Delphi 7 Internet e Banco de Dados - Facunte

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

Faça as modificações (em negrito) como segue: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <HTML> <HEAD> <TITLE> Página 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++

Page 222: Delphi 7 Internet e Banco de Dados - Facunte

222 Delphi 7 – Internet e Banco de Dados

} } if (c>1) Response.Write(s) %>

</BODY> </HTML>

Vamos analisar o código script, normalmente utilizado pelo padrão Standard do Page Module:

No primeiro bloco, estamos criando um objeto do tipo Enumerator e iniciando as variáveis s e c. A variável s será a nossa string para montagem dos links que serão apresentados e a variável c uma auxiliar para contagem de números de páginas da aplicação. <% e = new Enumerator(Pages) s = '' c = 0

No bloco seguinte estamos iniciando um laço baseado no objeto e criado anteriormente e movendo uma posição no objeto a cada ciclo. Perceba que o objeto e cria uma matriz de Page Modules da aplicação. for (; !e.atEnd(); e.moveNext())

No bloco que segue, estamos verificando se o item atual (Page Module) do objeto e possui o método de publicação. if (e.item().Published)

Em caso afirmativo, acrescenta-se à variável s, “espaço | espaço”, onde &nbsp; é igual a espaço na linguagem HTML. if (c>0) s += '&nbsp;|&nbsp;'

Seguindo com o nosso script, este próximo bloco verifica se o item em questão é diferente do que solicita o script, ou seja, verifica se é diferente dele mesmo. Em caso afirmativo cria o link da página baseado no item atual, senão apenas apresenta o título da página. 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 variável c. c++

E por fim, escrevemos no HTML todo o conteúdo da variável s caso a variável c seja maior que 1, isto é, apenas se nossa aplicação contiver 2 ou mais PageModules. if (c>1) Response.Write(s) %>

Agora vamos adicionar Page Modules ao nosso projeto. Através das opções File/New..Other..., seção WebSnap, selecione o assistente WebSnap PageModule (figura 11.27).

Page 223: Delphi 7 Internet e Banco de Dados - Facunte

WebSnap 223

Figura 11.27 Novo PageModule

Em seguida, configure as opções como ilustra a figura 11.28.

Figura 11.28 Configuração Page Module

Grave a unit como un_ex3_pag2.pas. Insira o código que segue no HTML associado a unit un_ex3_pag2, em nosso caso un_ex3_pag2.HTML. <B> Estamos na Página 2 </B>

Page 224: Delphi 7 Internet e Banco de Dados - Facunte

224 Delphi 7 – Internet e Banco de Dados

Grave o nosso projeto e execute normalmente a aplicação através da tecla F9, ou da opção Run/Run... do menu. Através das opções Tools/WebAppDebugger vamos executar o nosso servidor e depurador de aplicações. Clique no botão 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 serviços registrados. Selecione o nosso exemplo e clique no botão GO.

Figura 11.29 Aplicações registradas

As figuras 11.30 e 11.31 ilustram o resultado de nossa aplicação.

Figura 11.30 Terceiro exemplo página principal

Figura 11.31 Terceiro exemplo página 2

Page 225: Delphi 7 Internet e Banco de Dados - Facunte

WebSnap 225

Listagem 11.4 principal.html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <HTML> <HEAD> <TITLE> Página 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 usuário. Através das opções File/New/Other..., selecione a seção WebSnap e escolha a opções WebSnap Application (figura 11.32).

Figura 11.32 Selecionando o modelo da aplicação

Page 226: Delphi 7 Internet e Banco de Dados - Facunte

226 Delphi 7 – Internet e Banco de Dados

Em seguida (figura 11.33) selecione a opção Web App Debugger e informe o nome da classe. Para este exemplo vamos nomear como classExemplo4.

Figura 11.33 Opções da aplicação WebSnap

Em seguida temos a seção Application Module Components, responsável pela configuração dos módulos da aplicação. Clicando no botão Components, você terá acesso à outra caixa de diálogo (figura 11.34) com opções de serviço.

Figura 11.34 Opções de serviço

Assim como nos exemplos anteriores, mantenha as opções padrão, e clique no botão OK.

Page 227: Delphi 7 Internet e Banco de Dados - Facunte

WebSnap 227

Em seguida temos a seção Application Module Options, responsável pela configuração das opções da aplicação. Clicando no botão Page Options, você terá acesso à caixa de diálogo (figura 11.35) com opções da aplicação. Selecione Page Producer

para o Producer Type e mantenha a seleção JScript. no Script Engine. Em seguida temos a seção HTML. Desmarque a opção New File e clique no botão OK.

Figura 11.35 Opções da aplicação

Agora vamos gravar nosso quarto projeto no diretório \WebSnap\Exercicio4, como segue.

Unit PageModule un_ex4.PAS Unit Formulário un_form.PAS Projeto wsnap4.DPR

Agora vamos criar um novo Web Page Module através das opções File/New...Other... e na seção WebSnap, selecione WebSnap

Page Module. Configure de acordo com a figura 11.36.

Figura 11.36 Novo Web Page Module

Page 228: Delphi 7 Internet e Banco de Dados - Facunte

228 Delphi 7 – Internet e Banco de Dados

Pressione OK, e grave a unit como un_formulario.pás. Repare que selecionamos AdapterPageProducer, ao invés do tradicional Page Producer. Vamos criar três variáveis na seção private, com o objetivo de executar um cálculo 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, através 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 código 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 código 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 operação, com o nome Resultado. Insira o código que segue no evento OnGetValue:

Value:= vResultado;

Antes de definir o layout da aplicação vamos definir a ação que irá alimentar nossas variáveis. Selecione o objeto Adapter1 e através da propriedade Actions (figura 11.38) crie uma nova Action para o nosso objeto. Altere o nome da Action para calcula.

Page 229: Delphi 7 Internet e Banco de Dados - Facunte

WebSnap 229

Figura 11.38 Actions

No evento OnExecute da Action calcula, insira o código 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 código é bastante simples, onde estamos atribuindo às variáveis v1,v2 e vResultado, os valores resgatados através de um formulário HTML que iremos criar. Na realidade, a variável vResultado está sendo “alimentada” com o resultado da operação (v1+v2). Agora vamos criar o formulário HTML utilizando o nosso AdapterPageProducer. Através do duplo-clique no objeto AdapterPageProducer1, adicione um novo componente do tipo AdapterForm

Figura 11.39 Web Component

Agora clique no AdapterForm1 e insira um objeto do tipo AdapterFieldGroup. Devemos vincular o AdapterFieldGroup ao objeto Adapter1, através da propriedade Adapter. A figura 11.40 ilustra nosso formulário após o vínculo.

Page 230: Delphi 7 Internet e Banco de Dados - Facunte

230 Delphi 7 – Internet e Banco de Dados

Figura 11.40 Formulário criado através do Adapter

Em nosso caso desejamos configurar manualmente as propriedades de cada campo. Para realizar tal operação, devemos adicionar os Fields, clicando com o botão direito do mouse em AdapterFieldsGroup e selecionar a opção Add All Fields. A figura 11.41 ilustra nossa operação.

Figura 11.41 Fields

Altere as propriedades dos objetos criados como segue:

Objeto FldValor1 Propriedade Valor Caption Informe o primeiro valor

Objeto FldValor2

Propriedade Valor Caption Informe o segundo valor

Page 231: Delphi 7 Internet e Banco de Dados - Facunte

WebSnap 231

Agora vamos inserir o botão com a nossa ação. Selecione o AdapterForm1 e insira um novo componente do tipo AdapterCommandGroup. No objeto criado, faça o vínculo da propriedade DisplayComponent com o objeto AdapterFieldGroup1. Na realidade estamos colocando o nosso botão dentro do AdapterFieldGroup1. A figura 11.42 ilustra nosso formulário atual.

Figura 11.42 Formulário

Agora vamos inserir o campo Resultado. Selecione o objeto AdapterForm1 e insira um novo componente do tipo AdapterFieldGroup. Será criado o AdapterFieldGroup2. Faça o vínculo com o objeto Adapter1, através da propridade Adapter. Ainda no AdapterFieldGroup2, adicione o field fldResultado através da opção Add Field. Altere a propriedade ViewMode do field adicionado para vwDisplay. A figura 11.43 ilustra o resultado da nossa operação.

Figura 11.43 Campo resultado

Page 232: Delphi 7 Internet e Banco de Dados - Facunte

232 Delphi 7 – Internet e Banco de Dados

Grave o nosso projeto e execute normalmente a aplicação através da tecla F9, ou da opção Run/Run... do menu. Através das opções Tools/WebAppDebugger vamos executar o nosso servidor e depurador de aplicações. Clique no botão 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 serviços registrados. Selecione o nosso exemplo e clique no botão GO.

Figura 11.44 Serviços registrados

A figura 11.45 ilustra o resultado de nossa aplicação.

Figura 11.45 Quarto exemplo em execução

Page 233: Delphi 7 Internet e Banco de Dados - Facunte

WebSnap 233

Listagem 11.5 un_formulário.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;

Page 234: Delphi 7 Internet e Banco de Dados - Facunte

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.

Page 235: Delphi 7 Internet e Banco de Dados - Facunte

WebSnap 235

Anotações de Dúvidas

Preciso Revisar Anotações Gerais

?

!

Page 236: Delphi 7 Internet e Banco de Dados - Facunte

236 Delphi 7 – Internet e Banco de Dados

Capítulo 12

Intraweb

A grande revolução, e por que não dizer, a agradável surpresa presente na nova versão do Delphi: Intraweb. Desenvolvido pela empresa Atozed Software, e rapidamente adotado pela Borland numa distribuição especial (existe uma versão mais poderosa), vem ganhando simpatizantes em todo o mundo. Diversas empresas estão desenvolvendo componentes para trabalhar em conjunto com o Intraweb, dando ainda mais poder a esta incrível tecnologia. Desenvolver aplicações com o Intraweb é bastante agradável e prático e certamente vai encorajar excelentes desenvolvedores Delphi, que antes torciam o nariz para a tecnologia WebBroker, devido às dificuldades comuns encontradas no desenvolvimento de aplicações 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 capítulo, passando pelos anteriores, ou até mesmo a quem abriu o livro aqui, neste tópico.

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 idéia disso tudo, incorporou na versão 7 diversas tecnologias, como o próprio Intraweb, Rave Report (fantástico gerador de relatórios, e forte substituto do QuickReport), RxLib agora vem no CD 2, Indy Components, já visto no capítulo 9, entre outras tecnologias. Se a tecnologia é boa, pode ter certeza de que será adotada nas próximas versões, e isso vem crescendo a cada dia. Sorte nossa!

Antes de colocar a mão-na-massa, vou apresentar seus principais componentes: Os componentes estão divididos em quatro seções: IWStandard, IWData,

IWClientSide e IWControl.

236

Page 237: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 237

Componentes IWStandard

COMPONENTE

DESCRIÇÃO/USO

TIWApplet Para inserir uma Applet Java em sua página, oferecendo a configuração dos controles através do Object Inspector.

TIWButton Botão de formulário, com funções adversas, inclusive Submit.

TIWCheckBox Controles de CheckBox para formulário.

TIWComboBox ComboBox para seleção, com opções de preenchimento de lista.

TIWEdit Campo para edição com diversas propriedades de controle, como tamanho, se é requerido, tipo password, entre outras.

TIIWHRule Linha horizontal.

TIWImage Para exibição de imagens estáticas ou dinâmicas. Transforma automaticamente a maioria dos formatos para JPEG.

TIWImageFile Utilizado para exibir imagens estáticas, armazenadas num arquivo.

TIWLabel Semelhante ao Label do Delphi.

TIWLink Cria um hyperlink, controlado através do evento OnClick.

TIWList Utilizado para apresentar listas de marcação ou numeradas.

TIWListBox Lista de opções que podem ser selecionadas. Possui um forte controle de propriedades.

TIWMemo Área de edição (assim como o Delphi), com múltiplas linhas.

TIWMenu Componente fantástico, que cria um menu a partir de um componente TMainMenu do Delphi. Muito bom mesmo. Agora suas aplicações Web terão um aspecto mais profissional.

TIWRadioGroup Conjunto de opções ao usuário, semelhante ao RadioGroup do Delphi.

TIWTable Amigos, fiquei impressionado com o poder deste componente. Semelhante ao StringGrid, com opção individual de controle de células. Muito bom mesmo.

Page 238: Delphi 7 Internet e Banco de Dados - Facunte

238 Delphi 7 – Internet e Banco de Dados

COMPONENTE

DESCRIÇÃO/USO

TIWTemplateProcessorHTML Este componente permite associar um template HTML ao nosso formulário.

TIWText Apresenta textos com múltiplas linhas, sem suporte à edição.

TIWTimer Cria um Timer no lado servidor para disparar eventos.

TIWTreeView Apresenta um TreeView com diversos controles. Muito bom.

TIWURL Hyperlinks externos.

TIWFile Este componente quebra um galho incrível. Quem já tentou fazer rotinas de upload com a tecnologia WebBroker sabe do que estou falando. Era muito difícil, mas agora ficou muito fácil com este componente.

TIWGrid Grid sem vínculo com banco de dados.

TIWRectangle Apresenta figuras retangulares, com diversas opções de preenchimento.

TIWRegion Amigos, fiquei de boca aberta com os recursos deste componente. Tem a função de um container, como o Panel do Delphi. Fantástico!

Componentes IWData

COMPONENTE

DESCRIÇÃO/USO

TIWDBCheckbox CheckBox Data Ware, com diversas opções de configuração.

TIWDBCombobox ComboBox Data Ware, com incríveis propriedades, como tipo do cursor, ordenação, controle de scripts, entre outros.

TIWDBEdit DBEdit Data Ware, com todos os eventos do HTML, além de propriedades controladas pelo JavaScript.

TIWDBGrid DBGrid muito bacana e funcional, com diversos controles e eventos.

TIWDBImage DBImage Data Ware.

TIWDBLabel DBLabel Data Ware.

TIWDBListbox DBListBox com diversos controles e propriedades.

Page 239: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 239

COMPONENTE

DESCRIÇÃO/USO

TIWDBLookupCombobox Fantástico componente semelhante ao DBLookupComboBox do Delphi. Quem já desenvolveu aplicações padrão WebBroker sabe o enorme trabalho que dá para fazer um LookupComboBox.

TIWDBLookupListbox Outra maravilha, semelhante ao DBLookupListBox do Delphi.

TIWDBMemo DBMemo com diversos controles e propriedades.

TIWDBNavigator Amigos, este componente é incrível, tem todos os controles do DBNavigator do Delphi e possui controle de mensagens de diversos níveis. Você poderá configurar a própria mensagem de confirmação para exclusão. Muito bom. Nota 10.

TIWDBText Semelhante ao DBText.

TIWDBFile Utilizado para associar um campo do tipo stream com a função de uploads de arquivo.

Componentes IWClientSide

COMPONENTE

DESCRIÇÃO/USO

TIWCSLabel Apresentação de campos de uma tabela do lado cliente (veja controles IWControl).

TIWCSNavigator Controle de Navegação dos dados de uma tabela do lado Cliente. Imagine você acessando uma tabela pré-configurada no lado cliente, e navegando à vontade.

TIWDynamicChart

Gráfico com diversas opções, baseados em dados do lado cliente – embora seja possível alimentar com os dados do lado Servidor, pois não existe vínculo com DataWare, e sim com um IWClientDataSet (IW Control).

TIWDynamicChartLegend Legendas do gráfico, para ser utilizado em conjunto com o TIWDynamicChart.

TIWDynGrid Grid ligado ao IWClientDataSet (IW Control).

Page 240: Delphi 7 Internet e Banco de Dados - Facunte

240 Delphi 7 – Internet e Banco de Dados

Componentes IWControl

COMPONENTE

DESCRIÇÃO/USO

TIWClientSideDataSet Controle DataSet para armazenar informações e disponibilizar aos controles IWClientSide.

TIWClientSideDataSetDBLink Controle DataSet no padrão DataWare, onde você deverá ligar diretamente a um DataSource. Isso é muito legal, pois o DataSource poderá coletar dados de diversas origens.

TIWLayoutMgrForm Controle de layout dos objetos de um formulário.

TIWLayoutMgrHTML Permite a edição do formulário no padrão HTML. Quer dar o seu toque pessoal? Então este é o componente certo.

TIWModuleController Habilita o controle do servidor para o padrão PageMode do Intraweb.

TIWPageProducer Com este componente você poderá utilizar toda a tecnologia Intraweb com WebSnap, e também aproveitar a tecnologia dos Page Producers do WebBroker.

TIWStandAloneServer Controle da aparência e outras propriedades da aplicação.

Antes de Começar Este tópico é muito importante, pois precisamos conhecer alguns conceitos do Intraweb. Na versão distribuída com o Delphi 7, o Intraweb coloca automaticamente o nome das units iniciais bem como do projeto. Isso pode dificultar um pouco no começo, mas em nosso caso iremos criar uma estrutura de diretórios com o intuito de organizar nossos exercícios com o Intraweb, e evitar conflitos. Crie a seguinte estrutura de diretórios (diagrama 12.1)

Page 241: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 241

Diagrama 12.1

Primeiro Exemplo (controles Standard) Vamos desenvolver nossa primeira aplicação, utilizando alguns componentes da seção IWStandard. Vamos escolher o padrão Stand Alone para facilitar a compreensão e o desenvolvimento. Através das opções File/New/Other..., selecione a seção Intraweb e escolha o modelo Stand Alone Application (figura 12.1).

Figura 12.1 Escolha do tipo da Aplicação

Em seguida, selecione o diretório de nossa primeira aplicação, em nosso caso (c:\cursoweb\intraweb\exercicio1).

C:\CursoWeb

Intraweb

exercicio1

exercicio2

exercício3

exercício4

exercício5

exercício6

clientes

Page 242: Delphi 7 Internet e Banco de Dados - Facunte

242 Delphi 7 – Internet e Banco de Dados

Figura 12.2 Seleção do diretório

Perceba que o Intraweb criou um módulo principal, com alguns controles (figuras 12.3 e 12.4).

Figura 12.3 Módulo do Projeto

Figura 12.4 Formulários padrão da aplicação Stand Alone

O Intraweb cria a seguinte estrutura de arquivos para o tipo de aplicação Stand Alone:

Page 243: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 243

!" IWProject.DPR Projeto !" IWUnit1.PAS Unit principal, contendo o formulário principal da aplicação !" ServerController.PAS Controle principal da aplicação, com sessões de usuário, tipo de acesso,

protocolos de segurança (SSL), browsers, entre outros. Agora com o foco no formulário (selecione o formulário da unit IWUnit1), insira um componente do tipo IWLabel e altere sua propriedade caption para Exercício 1. A figura 12.5 ilustra o formulário principal com o objeto IWLabel1.

Figura 12.5 Formulário principal

Agora, meus amigos, para quem estava com saudades do famoso F9 para executar e depurar as aplicações, o Intraweb retorna “aos bons tempos” e habilita esta opção. Aperte F9 para executar nosso primeiro exercício. Deverá aparecer o servidor de testes do Intraweb, como ilustra a figura 12.6.

Figura 12.6 Servidor de Aplicações Intraweb

Repare que não existe nenhuma sessão ativa (Active Sessions). Para executar nossa aplicação, você poderá teclar novamente F9, ou pressionar o primeiro speed button, ou então acessar o menu File/Run.. A figura 12.7 ilustra o resultado do nosso primeiro exercício.

Page 244: Delphi 7 Internet e Banco de Dados - Facunte

244 Delphi 7 – Internet e Banco de Dados

Figura 12.7 Resultado do primeiro exercício

Tente pressionar F9 algumas vezes no Intraweb Server Application, e repare que são criadas novas sessões (figura 12.8).

Figura 12.8 Sessões ativas

O mais interessante de tudo isso, é que o Intraweb possui um forte controle de sessões. Repare na figura 12.9 que o Intraweb utiliza um número extenso, definindo a sessão do usuário. Este controle é bastante robusto e facilita muito a “vida” do desenvolvedor no controle de sessões.

Figura 12.9 Controle de sessões

Encerre o servidor de aplicações, e retorne ao Delphi. Vejamos agora, todo o código criado pelo Intraweb em nossa primeira aplicação. Listagem 12.1 Unit IWUnit1.

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

Page 245: Delphi 7 Internet e Banco de Dados - Facunte

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 exercício, clique com o botão direito do mouse no formulário principal e selecione a opção 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 seção Source logo abaixo do Preview e repare o código HTML gerado, inclusive com CSS (figura 12.11).

Figura 12.11 Código HTML

Como o código é dinâmico, o modelo gerado e visto na figura 12.11 é apropriado para o modelo de servidor IntraWeb Server

Application, no modo Preview. Veja a versão HTML gerada fora do Preview, mas ainda no servidor Intraweb.

Page 246: Delphi 7 Internet e Banco de Dados - Facunte

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>

Page 247: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 247

<span id="IWLABEL1" class="IWLABEL1CSS">IWLabel1</span> </body> </html>

Complicado, não acham? Podem ficar tranqüilos, pois dificilmente teremos que dar manutenção no código HTML. A idéia é justamente essa, utilizar o RAD (Rapid Application Development) do Intraweb para criar e dar manutenção às nossas aplicações. Só para finalizar a parte de códigos deste tópico, 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;

Page 248: Delphi 7 Internet e Banco de Dados - Facunte

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 código da unit ServerController, podemos perceber a flexibilidade no controle de sessões por usuário. É possível criar variáveis similares às globais, mas com instâncias por sessão, ou seja, cada usuário terá a sua própria variável. Eu explico melhor.Vamos imaginar uma variável que totaliza o valor da compra, ou até mesmo uma matriz, contendo diversas informações sobre a compra atual, e poder acessar em nível de usuário, ou melhor, por sessão, cada variável. Veja o cenário:

Usuário 1 Sessão 08A197007D9506F23B52E240 Valor 300

Usuário 2 Sessão E4949A0062C7BBC23C52E240 Valor 180

Usuário 3 Sessão D0679B0010B757C63C52E240 Valor 180

Repare que cada sessão possui uma identificação diferente. Imagine quando o usuário solicitar a finalização da compra, onde é necessário apresentar o resumo e o valor total. Com o Intraweb é extremamente simples; basta acessar o conteúdo das variáveis definidas no ServerController. Mas como ele faz isso? Uma mistura de cookies com persistência. Com isso concluímos nosso primeiro exercício 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. Através das opções File/New/Other..., selecione a seção Intraweb e escolha o modelo Stand Alone Application (figura 12.12).

Page 249: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 249

Figura 12.12 Escolha do tipo da Aplicação

Em seguida, selecione o diretório de nossa segunda aplicação, em nosso caso (c:\cursoweb\intraweb\exercicio2). Grave toda a aplicação, e insira os componentes que seguem:

OBJETO

TIWLabel

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

OBJETO

TIWEdit

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

Page 250: Delphi 7 Internet e Banco de Dados - Facunte

250 Delphi 7 – Internet e Banco de Dados

OBJETO

TIWButton

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

OBJETO

TIWLabel

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

A figura 12.13 ilustra nosso formulário.

Figura 12.13 Formulário segundo exemplo

Agora vamos codificar um pouco. Selecione o objeto btConfirma (botão) e insira o código 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 código Object Pascal puro, ou melhor, Delphi Language como é chamado agora.

Page 251: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 251

Execute a aplicação, 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 fácil, não é? 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.

Page 252: Delphi 7 Internet e Banco de Dados - Facunte

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 programação. Através das opções File/New/Other..., selecione a seção Intraweb e escolha o modelo Stand Alone Application (figura 12.15).

Figura 12.15 Escolha do tipo da Aplicação

Em seguida, selecione o diretório de nossa segunda aplicação, em nosso caso (c:\cursoweb\intraweb\exercicio3). Insira a unit SysUtils, na cláusula uses da aplicação, para que possamos fazer algumas operações. Grave toda a aplicação, e insira os componentes que seguem:

OBJETO

TIWLabel

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

OBJETO

TIWHRule

Objeto Propriedade Valor IWHRule1 Left 56 Top 40 Width 225

Page 253: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 253

OBJETO

TIWLabel

Objeto Propriedade Valor IWLabel2 Name IWLabel2 Caption Insira dois números e

selecione a operação Left 56 Top 56

OBJETO

TIWEdit

Objeto Propriedade Valor edN1 Name edN1 Left 56 Text (deixe em branco) Top 80

OBJETO

TIWEdit

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

OBJETO

TIWHRule

Objeto Propriedade Valor IWHRule1 Left 56 Top 144 Width 73

Page 254: Delphi 7 Internet e Banco de Dados - Facunte

254 Delphi 7 – Internet e Banco de Dados

OBJETO

TIWEdit

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

OBJETO

TIWButton

Objeto Propriedade Valor btAdicao Name btAdicao Caption + Left 144 importante >>> Tag 1 Width 25

OBJETO

TIWButton

Objeto Propriedade Valor btSubtracao Name btSubtracao Caption - Left 176 importante >>> Tag 2 Width 25

OBJETO

TIWButton

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

Page 255: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 255

OBJETO

TIWButton

Objeto Propriedade Valor btDivisao Name btDivisao Caption : Left 240 importante >>> Tag 4 Width 25

A figura 12.16 ilustra nosso formulário.

Figura 12.16 Formulário terceiro exemplo

Agora vamos codificar o botão btAdicao. No evento OnClick do botão, insira o código 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;

Page 256: Delphi 7 Internet e Banco de Dados - Facunte

256 Delphi 7 – Internet e Banco de Dados

edTotal.Text:=FloatToStr(total); except on EZeroDivide do WebApplication.ShowMessage('Divisão por zero !'); on EOverFlow do WebApplication.ShowMessage('Aconteceu OverFlow !'); // end; Antes de analisar o código, selecione os demais botões e associe o código do evento OnClick, como ilustra a figura 12.17.

Figura 12.17 Associação do evento OnClick aos demais botões.

Vamos analisar o código. var n1,n2,total:single; operacao:integer;

Neste primeiro bloco estamos declarando variáveis para execução da operação matemática (n1, n2 e total), bem como uma variável auxiliar (operação) com o intuito de associar o botão que está chamando o evento. Em cada botão, definimos valores diferentes para a propriedade TAG, que será facilmente assimilada por nossa aplicação. 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 conteúdo dos campos de edição edN1 e edN2, para o tipo float. Neste mesmo bloco estamos iniciando a variável total e atribuindo à variável operacao, o valor contido na propriedade

TAG de um objeto do tipo TIWButton, que em nosso caso, são representadas pelos botões 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 operações de acordo com o botão pressionado. edTotal.Text:=FloatToStr(total);

Page 257: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 257

Em seguida, atribuímos ao objeto edTotal o resultado da operação. except on EZeroDivide do WebApplication.ShowMessage('Divisão por zero !'); on EOverFlow do WebApplication.ShowMessage('Aconteceu OverFlow !'); // end; Por fim, tratamos duas exceções: EZeroDivide (divisão por zero), e EOverFlow (Overflow na operação). Repare que em caso de erro, estamos apresentando mensagens ao usuário. É muito parecido com o famoso Application.ShowMessage. Neste caso, utilizamos o WebApplication.ShowMessage. As figuras 12.18, 12.19 e 12.20 ilustram nossa aplicação em tempo de execução.

Figura 12.18 Operação de adição

A figura 12.18 ilustra o sucesso da operação de adição. Em seguida temos nossa primeira mensagem de erro. A figura 12.19 ilustra um erro de divisão por zero.

Figura 12.19 Divisão por zero

Em seguida temos um erro de OverFlow (figura 12.20).

Page 258: Delphi 7 Internet e Banco de Dados - Facunte

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;

Page 259: Delphi 7 Internet e Banco de Dados - Facunte

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('Divisão 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 fácil. Com pouquíssimas linhas de código, na realidade apenas uma linha faz o serviço, mas em nosso caso faremos um tratamento de erro. Vamos desenvolver tal rotina. Através das opções File/New/Other..., selecione a seção Intraweb e escolha o modelo Stand Alone Application (figura 12.21).

Figura 12.21 Escolha do tipo da Aplicação

Em seguida, selecione o diretório de nossa segunda aplicação, em nosso caso (c:\cursoweb\intraweb\exercicio4). Grave toda a aplicação, e insira os componentes que seguem:

Page 260: Delphi 7 Internet e Banco de Dados - Facunte

260 Delphi 7 – Internet e Banco de Dados

OBJETO

TIWLabel

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

OBJETO

TIWLabel

Objeto Propriedade Valor IWLabel2 Name IWLabel2 Caption Selecione o arquivo para

UpLoad Left 32 Top 48

OBJETO

TIWLabel

Objeto Propriedade Valor lbMensagem Name lbMensagem Caption Mensagem Left 32 Top 168 Font.Color clRed

OBJETO

TIWFile1

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

Page 261: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 261

OBJETO

TIWButton1

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

A figura 12.22 ilustra o nosso formulário.

Figura 12.22 Formulário para UpLoad

Agora vamos codificar a rotina de UpLoad. No evento OnClick do objeto IWButton1, coloque o código que segue: try IWFile1.SaveToFile(ExtractFilePath(ParamStr(0)) + IWFile1.FileName); lbMensagem.Caption:='O arquivo'+IWFile1.Filename+' foi gravado no diretório '+#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 necessária para fazer o UpLoad do arquivo. Em nosso caso estamos fazendo uma rotina de tratamento de erros e exibindo a mensagem do resultado da operação. Caso seja bem sucedida, apresenta o nome do arquivo e em qual diretório foi gravado no servidor. Em caso de erro, apresenta apenas uma mensagem : “Houve um problema...”. A figura 12.23 ilustra nossa aplicação sendo executada.

Page 262: Delphi 7 Internet e Banco de Dados - Facunte

262 Delphi 7 – Internet e Banco de Dados

Figura 12.23 Arquivo sendo gravado no diretório da aplicação.

É muito fácil, não é?

Dica

Você poderá configurar o diretório que receberá os arquivos. Normalmente numa Intranet, existe um servidor de arquivos, onde sua aplicação poderá gravar as informações 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}

Page 263: Delphi 7 Internet e Banco de Dados - Facunte

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 diretório '+#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 múltiplos formulários. O conceito é bem parecido com as aplicações desktop, com criação e destruição de formulários dinamicamente. Através das opções File/New/Other..., selecione a seção Intraweb e escolha o modelo Stand Alone Application (figura 12.24).

Figura 12.24 Escolha do tipo da Aplicação

Em seguida, selecione o diretório de nossa segunda aplicação, em nosso caso (c:\cursoweb\intraweb\exercicio5). Grave toda a aplicação, e insira os componentes que seguem:

OBJETO

TIWLabel

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

Page 264: Delphi 7 Internet e Banco de Dados - Facunte

264 Delphi 7 – Internet e Banco de Dados

OBJETO

TIWButton

Objeto Propriedade Valor IWButton1 Name IWButton1 Caption Formulário 2 Left 120 Top 56 Width 115

OBJETO

TIWButton

Objeto Propriedade Valor IWButton2 Name IWButton2 Caption Formulário 3 Left 225 Top 124 Width 115

OBJETO

TIWEdit1

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

Agora vamos criar um segundo formulário. Através das opções File/New/Other..., selecione a seção Intraweb e escolha o modelo Application Form (figura 12.25).

Page 265: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 265

Figura 12.25 Criando um novo formulário

Altere a propriedade Name do formulário para Form2. Grave a unit com o nome un_formulário2. Insira os componentes que seguem no Form2.

OBJETO

TIWLabel

Objeto Propriedade Valor IWLabel1 Name IWLabel1 Caption Formulário 2 Left 136 Top 36

OBJETO

TIWButton

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

Vamos codificar este formulário. No evento OnClick do objeto IWButton1, insira o seguinte código Hide;

No código que acabamos de inserir, estamos “escondendo” o formulário, e retornando à origem. Para entender o funcionamento, vamos codificar o nosso formulário principal.

Page 266: Delphi 7 Internet e Banco de Dados - Facunte

266 Delphi 7 – Internet e Banco de Dados

Insira a unit un_formulario2 na cláusula uses do formulário principal. Agora vamos codificar o evento OnClick do objeto IWButton1 do formulário principal. var Form2:TForm2; begin Form2 := TForm2.Create(WebApplication); Form2.Show; end; Estamos fazendo uma operação bastante simples. Primeiro declaramos uma variável 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 formulários.

Figura 12.26 Formulário principal.

Page 267: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 267

Figura 12.27 Formulário 2

Vamos dar uma olhadinha no resultado desta primeira parte de nossa aplicação. Execute a aplicação e clique no botão que representa a chamada do primeiro formulário. As figuras 12.28 e 12.29 ilustram o resultado da primeira parte de nossa aplicação.

Figura 12.28 Formulário principal em ação

Figura 12.29 Formulário 2 chamado através do formulário principal

Page 268: Delphi 7 Internet e Banco de Dados - Facunte

268 Delphi 7 – Internet e Banco de Dados

Agora vamos criar a segunda parte de nossa aplicação, fazendo uma interatividade entre os formulários. Através das opções File/New/Other..., selecione a seção Intraweb e escolha o modelo Application Form (figura 12.30).

Figura 12.30 Criando um novo formulário

Altere a propriedade Name do formulário para Form3. Grave a unit com o nome un_formulário3. Insira os componentes que seguem no Form3.

OBJETO

TIWLabel

Objeto Propriedade Valor IWLabel1 Name IWLabel1 Caption Formulário 3 Left 136 Top 36

OBJETO

TIWLabel

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

Page 269: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 269

OBJETO

TIWButton

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

Vamos codificar este formulário. No evento OnClick do objeto IWButton1, insira o seguinte código Hide;

Voltando ao formulário principal, coloque a unit un_formulario3 na cláusula uses. Vamos codificar o botão IWButton2 do formulário principal. Coloque o código que segue no evento OnClick do botão. 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 aplicação, declaramos uma variável 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 aplicação.

Page 270: Delphi 7 Internet e Banco de Dados - Facunte

270 Delphi 7 – Internet e Banco de Dados

Figura 12.31 Formulário principal fazendo a chamada ao formulário 3

Figura 12.32 Formulário 3 em ação

Este exemplo, embora bastante simples, demonstra a interatividade entre formulários. Bastante comum em aplicações Internet, tenho certeza que utilizarão 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;

Page 271: Delphi 7 Internet e Banco de Dados - Facunte

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.pás

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

Page 272: Delphi 7 Internet e Banco de Dados - Facunte

272 Delphi 7 – Internet e Banco de Dados

ServerController; procedure TForm2.IWButton1Click(Sender: TObject); begin Hide; end; end.

Listagem 12.9 un_formulario3.pás

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 aplicações com banco de dados para Internet com outras tecnologias (Web-Broker e Websnap) e agora teremos o prazer de utilizar o Intraweb. Através das opções File/New/Other..., selecione a seção Intraweb e escolha o modelo Stand Alone Application with Data

Module (figura 12.33).

Page 273: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 273

Figura 12.33 Iniciando a aplicação

A única diferença na opção with Data Module, é justamente a criação automática de um Data Module, bem como suas referências. Insira um objeto do tipo TSQLConnection, e através do duplo-clique, já na tela de configuração, aponte para a nossa conexão Clientes, criada anteriormente. Vamos relembrar os atributos da conexão.

PROPRIEDADE

VALOR

CommitRetain

False

Database

localhost:c:\cursoweb\clientes.gdb

Password

a famosa masterkey

UserName

o famoso SYSDBA

Name

ConexaoBD

Altere também a propriedade LoginPrompt para false. Nunca esqueça de fazer esta alteração, pois numa aplicação servidora, não existe a possibilidade do usuário interagir no login do banco de dados.

Page 274: Delphi 7 Internet e Banco de Dados - Facunte

274 Delphi 7 – Internet e Banco de Dados

Figura 10.34 Configuração da Conexão

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

ConexaoBD

CommandText

select * from TBCLIENTE

Active

True

Ótimo, agora vamos para o formulário principal. Insira a unit DataModuleUnit na cláusula uses, e grave a aplicação. Insira os componentes que seguem.

OBJETO

TIWLabel

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

Page 275: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 275

OBJETO

TDataSource [DataAccess]

Objeto Propriedade Valor DataSource1 Name DataSource1 DataSet DataModule1.SQLDataSet1

OBJETO

TIWDBGrid

Objeto Propriedade Valor IWDBGrid1 Name IWDBGRID1 Align alTop DataSource DataSource1

A figura 12.35 ilustra nosso formulário principal.

Figura 12.35 Formulário principal

Não colocamos nenhum código nesta aplicação. Assim como em aplicações desktop, apenas associamos os objetos. Vamos executar a aplicação e ver o resultado (figura 12.36).

Page 276: Delphi 7 Internet e Banco de Dados - Facunte

276 Delphi 7 – Internet e Banco de Dados

Figura 12.36 Sexto exemplo em execução

Demonstrei neste exemplo uma forma simples de disponibilizar informações de banco de dados na Internet. O grande momento deste exemplo foi justamente a simplicidade e a semelhança com o método tradicional de desenvolvimento. No próximo tópico vamos desenvolver uma aplicação completa, a mesma que desenvolvemos no Capítulo 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;

Page 277: Delphi 7 Internet e Banco de Dados - Facunte

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 aplicação parecida com a do Capítulo 7, onde faremos um cadastro de clientes com as principais operações. Através das opções File/New/Other..., selecione a seção Intraweb e escolha o modelo Stand Alone Application with Data Module (figura 12.37).

Page 278: Delphi 7 Internet e Banco de Dados - Facunte

278 Delphi 7 – Internet e Banco de Dados

Definições iniciais

Figura 12.37 Iniciando a aplicação

Selecione o DataModule e insira um objeto do tipo TSQLConnection. Através do duplo-clique, já na tela de configuração, aponte para a nossa conexão Clientes, criada anteriormente. Vamos relembrar os atributos da conexão.

PROPRIEDADE

VALOR

CommitRetain

False

Database

localhost:c:\cursoweb\clientes.gdb

Password

a famosa masterkey

UserName

o famoso SYSDBA

Name

ConexaoBD

Altere também a propriedade LoginPrompt para false. Nunca esqueça de fazer esta alteração, pois numa aplicação servidora, não existe a possibilidade do usuário interagir no login do banco de dados.

Page 279: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 279

Figura 10.38 Configuração da Conexão

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

ConexaoBD

CommandText

select * from TBCLIENTE

Active

True

Objeto de Inclusão Insira um objeto do tipo TSQLQuery e altere as propriedades que seguem.

Page 280: Delphi 7 Internet e Banco de Dados - Facunte

280 Delphi 7 – Internet e Banco de Dados

OBJETO

TSQLQuery

Objeto Propriedade Valor SQLInclui 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 parâmetros para String.

Objeto de Alteração Insira um objeto do tipo TSQLQuery e altere as propriedades que seguem.

OBJETO

TSQLQuery

Objeto Propriedade Valor SQLAltera 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 parâmetros para String, com exceção do parâmetro PCODIGO, que deve ser Integer.

Objeto de Exclusão Insira um objeto do tipo TSQLQuery e altere as propriedades que seguem.

Page 281: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 281

OBJETO

TSQLQuery

Objeto Propriedade Valor SQLExclui Name SQLExclui SQLConnection BancoDados

SQL DELETE FROM TBCLIENTE WHERE COD_CLIENTE=:pcodigo

Na propriedade PARAMS do SQLExclui altere o tipo do parâmetro para Integer.

Criando o Formulário Principal No formulário principal (FormMain), adicione um componente do tipo TMainMenu (que utilizamos habitualmente), e configure as opções como segue:

Arquivo Sobre Inclusão Clientes Informações... Manutenção/Consulta Finaliza

A figura 12.39 ilustra o nosso menu principal.

Figura 12.39 Menu Principal

Insira um objeto do tipo TIWMenu (seção 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 sugestão de cor. Insira os componentes que seguem no FormMain.

Page 282: Delphi 7 Internet e Banco de Dados - Facunte

282 Delphi 7 – Internet e Banco de Dados

OBJETO

TIWLabel

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

OBJETO

TIWImage

Objeto Propriedade Valor IWImage1 Name IWImmage1 Left 168 Picture insira uma figura qualquer,

exemplo: logo.jpg Top 120

A figura 12.40 ilustra o nosso formulário principal.

Figura 12.40 Formulário principal

Agora iremos codificar duas opções do menu principal: Finaliza e Informações/Sobre.

Selecione a opção Finaliza no objeto MainMenu1 e insira o código que segue no evento OnClick.

WebApplication.Terminate('Até logo !');

Neste evento estamos finalizando a aplicação e apresentando a mensagem “Até Logo!”, ao usuário. Agora selecione a opção Informações/.Sobre e insira o código que segue.

Page 283: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 283

WebApplication.ShowMessage('Cadastro de Clientes' +#13#10+ 'Versão 1.0',smAlert);

Neste evento apresentamos uma janela de diálogo ao usuário, com as informações da aplicação. Bastante simples, não?

Criando o Formulário de Inclusão Através das opções File/New/Other..., selecione a seção Intraweb e escolha o modelo Application Form (figura 12.41).

Figura 12.41 Criando um novo formulário

Altere a propriedade Name do formulário para FmInclusao e BackGroundColor para $00DDFFFF. . Grave a unit com o nome un_inclusao. Insira os componentes que seguem no FmInclusao..

OBJETO

TIWRectangle

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

(Inclusão)

Page 284: Delphi 7 Internet e Banco de Dados - Facunte

284 Delphi 7 – Internet e Banco de Dados

OBJETO

TIWLabel

Objeto Propriedade Valor IWLabel1 Name IWLabel1 Caption Razão Social Left 24 Top 88

OBJETO

TIWLabel

Objeto Propriedade Valor IWLabel2 Name IWLabel2 Caption Endereço Left 24 Top 120

OBJETO

TIWLabel

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

OBJETO

TIWLabel

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

Page 285: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 285

OBJETO

TIWLabel

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

OBJETO

TIWLabel

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

OBJETO

TIWEdit

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

OBJETO

TIWEdit

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

Page 286: Delphi 7 Internet e Banco de Dados - Facunte

286 Delphi 7 – Internet e Banco de Dados

OBJETO

TIWEdit

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

OBJETO

TIWComboBox

Objeto Propriedade Valor edUF Name edUF Height 21 Left 360 Items Insira a sigla de todos os

estados brasileiros Sorted True Top 152 Width 65

OBJETO

TIWEdit

Objeto Propriedade Valor edCEP Name edCEP BgColor clYellow Height 21 Left 488 Text deixar em branco Top 152 Width 90

Page 287: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 287

OBJETO

TIWEdit

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

OBJETO

TIWButton1

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

OBJETO

TIWButton1

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

Agora vamos codificar o formulário. Insira a unit DataModuleUnit na cláusula uses do formulário. uses ServerController, DatamoduleUnit; No evento OnClick do objeto btDesiste insira o código que segue: Hide;

Para que possamos retornar ao formulário de origem, utilizamos o método Hide do formulário. Agora vamos codificar o evento OnClick do objeto btConfirma.

Page 288: Delphi 7 Internet e Banco de Dados - Facunte

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 um problema na inclusão do cliente', smSameWindow); end; Hide;

Vamos analisar o código. Nesta primeira parte, iniciamos um bloco protegido. try Em seguida, estamos atribuindo parâmetros 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 operação e apresentando a mensagem de sucesso na operção. ExecSQL; WebApplication.ShowMessage('Cliente incluido com sucesso',smSameWindow);

Em caso de erro, estamos criando o bloco except.

except WebApplication.ShowMessage('Houve um problema na inclusão do cliente', smSameWindow); end; E apresentando a mensagem do problema. A figura 12.42 ilustra o nosso formulário de inclusão de clientes.

Page 289: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 289

Figura 12.42 Formulário inclusão de clientes

Criando o Formulário de Alteração Através das opções File/New/Other..., selecione a seção Intraweb e escolha o modelo Application Form (figura 12.43).

Figura 12.43 Criando um novo formulário

Altere a propriedade Name do formulário para FmAltera e BackGroundColor para $00DDFFFF. Grave a unit com o nome un_alteracao. Insira os componentes que seguem no FmAltera.

Page 290: Delphi 7 Internet e Banco de Dados - Facunte

290 Delphi 7 – Internet e Banco de Dados

OBJETO

TIWRectangle

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

(Alteração)

OBJETO

TIWLabel

Objeto Propriedade Valor IWLabel1 Name IWLabel1 Caption Razão Social Left 24 Top 88

OBJETO

TIWLabel

Objeto Propriedade Valor IWLabel2 Name IWLabel2 Caption Endereço Left 24 Top 120

OBJETO

TIWLabel

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

Page 291: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 291

OBJETO

TIWLabel

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

OBJETO

TIWLabel

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

OBJETO

TIWLabel

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

OBJETO

TIWLabel

Objeto Propriedade Valor IWLabel7 Name IWLabel7 Caption Código Cliente Left 24 Top 56

OBJETO

TIWLabel

Objeto Propriedade Valor lbCodigo Name lbCodigo Caption código Left 144 Top 56

Page 292: Delphi 7 Internet e Banco de Dados - Facunte

292 Delphi 7 – Internet e Banco de Dados

OBJETO

TIWEdit

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

OBJETO

TIWEdit

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

OBJETO

TIWEdit

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

Page 293: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 293

OBJETO

TIWComboBox

Objeto Propriedade Valor edUF Name edUF Height 21 Left 360 Items Insira a sigla de todos os

estados brasileiros Sorted True Top 152 Width 65

OBJETO

TIWEdit

Objeto Propriedade Valor edCEP Name edCEP BgColor clYellow Height 21 Left 488 Text deixar em branco Top 152 Width 90

OBJETO

TIWEdit

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

Page 294: Delphi 7 Internet e Banco de Dados - Facunte

294 Delphi 7 – Internet e Banco de Dados

OBJETO

TIWButton1

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

OBJETO

TIWButton1

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

Agora vamos codificar o formulário. Insira a unit DataModuleUnit na cláusula uses do formulário. uses ServerController, DatamoduleUnit; No evento OnClick do objeto btDesiste insira o código que segue: Hide;

Para que possamos retornar ao formulário de origem, utilizamos o método Hide do formulário. 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);

Page 295: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 295

except WebApplication.ShowMessage('Houve um problema na alteração do cliente', smSameWindow); end; Hide;

Vamos analisar o código. Nesta primeira parte, iniciamos um bloco protegido. try Em seguida, estamos atribuindo parâmetros 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 operação e apresentando a mensagem de sucesso na operção. ExecSQL; WebApplication.ShowMessage('Cliente incluido com sucesso',smSameWindow);

Em caso de erro, estamos criando o bloco except.

except WebApplication.ShowMessage('Houve um problema na inclusão do cliente', smSameWindow); end;

E apresentando a mensagem do problema. Embora o Intraweb forneça objeto com conexão direta a DataSets, estamos utilizando os objetos convencionais, sem nenhum vínculo com DataSet. Quando trabalhamos com Internet, é complicado disponibilizar objeto de conexão direta com DataSets,

justamente porque não sabemos o que poderá ocorrer com a conexão. Sugiro adotar este modelo de desenvolvimento pela segurança. Então, para que nossos campos sejam preenchidos automaticamente com as informações do banco de dados, vamos utilizar o TDataSource e TSQLDataSet.

Page 296: Delphi 7 Internet e Banco de Dados - Facunte

296 Delphi 7 – Internet e Banco de Dados

OBJETO

TSQLDataSet

Objeto Propriedade Valor SQLDataSet1 Name SQLDataSet1 SQLConnection DataModule1.ConexaoBD

CommandText select * from TBCLIENTE WHERE COD_CLIENTE=:pCodigo

CommandType Query Defina o parâmetro pCodigo como Integer.

OBJETO

TDataSource

Objeto Propriedade Valor DataSource1 Name DataSource DataSet SQLDataSet1

Pronto, agora concluímos o nosso formulário de alteração de clientes. A figura 12.44 ilustra o nosso formulário.

Figura 12.44 Formulário alteração de clientes

Criando o Formulário de Manutenção Através das opções File/New/Other..., selecione a seção Intraweb e escolha o modelo Application Form (figura 12.45).

Page 297: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 297

Figura 12.45 Criando um novo formulário

Altere a propriedade Name do formulário para FmManutencao e BackGroundColor para $00DDFFFF. . Grave a unit com o nome un_manutencao. Insira os componentes que seguem no FmManutencao..

OBJETO

TIWRectangle

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

(Manutenção)

OBJETO

TIWRegion1

Objeto Propriedade Valor IWRegion1 Name IWRegion1 Align alTop Color clWhite Height 56

Com o foco no objeto IWRegion1, insira os componentes que seguem.

Page 298: Delphi 7 Internet e Banco de Dados - Facunte

298 Delphi 7 – Internet e Banco de Dados

OBJETO

TIWLabel

Objeto Propriedade Valor IWLabel1 Name IWLabel1 Caption Razão Social Left 16 Top 16

OBJETO

TIWEdit

Objeto Propriedade Valor edPesquisa Name edPesquisa BgColor clYellow Height 21 Left 112 Text deixar em branco Top 16 Width 175

OBJETO

TIWButton

Objeto Propriedade Valor btPesquisa Name btPesquisa Caption Confirma Height 25 Left 296 Top 16 Width 75

OBJETO

TIWButton

Objeto Propriedade Valor btVolta Name btVolta Caption Menu Principal Height 25 Left 384 Top 16 Width 122

Page 299: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 299

Em nosso formulário 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 Propriedade Valor SQLPesquisa Name SQLPesquisa SQLConnection DataModule1.ConexaoBD

SQL select * from TBCLIENTE

OBJETO

TDataSource

Objeto Propriedade Valor DS1 Name DS1 DataSet SQLPesquisa

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 formulário, insira um objeto do tipo TIWDBGrid e altere as propriedades que seguem.

OBJETO

TIWDBGrid

Objeto Propriedade Valor IWDbGrid1 Name IWDbGrid1 DataSource DS1 Rollover True RollOverColor $00E1FFE1

Através do duplo-clique na propriedade Columns, insira os campos conforme a figura 12.46.

Figura 12.46 Campos do grid.

Page 300: Delphi 7 Internet e Banco de Dados - Facunte

300 Delphi 7 – Internet e Banco de Dados

Curiosidade

Repare que estamos repetindo o campo COD_CLIENTE diversas vezes. Fazemos isto para substituir os métodos de chamada de operações, devido a um BUG no Intraweb. Até a versão 5.51 (que vem junto com o D7), o BUG de vínculo com controles (Control) ainda não estava corrigido. Existe uma maneira de associar um objeto, como por exemplo, um botão, a um evento do Grid. Iríamos fazer isso para disparar as rotinas de alteração e exclusão, mas infelizmente, devido ao BUG, estamos substituindo por outro método.

Vamos configurar as colunas inseridas.

Coluna [ 0 ] Cod_Cliente Objeto Propriedade Valor IWDbGrid1>Columns[0] DataField Cod_Cliente LinkField Cod_Cliente Title.Text Código

Coluna [ 1 ] Razao_Social Objeto Propriedade Valor IWDbGrid1>Columns[1] DataField Razao_Social Title.Text Razão Social

Coluna [ 2 ] EMAIL Objeto Propriedade Valor IWDbGrid1>Columns[2] DataField email Title.Text e-Mail

Coluna [ 3 ] Cod_Cliente Objeto Propriedade Valor IWDbGrid1>Columns[3] DataField Cod_Cliente LinkField Cod_Cliente Title.Text Altera

Coluna [ 4 ] Cod_Cliente Objeto Propriedade Valor IWDbGrid1>Columns[4] DataField Cod_Cliente LinkField Cod_Cliente Title.Text Exclui

Agora vamos codificar o nosso formulário. Na cláusula uses insira as seguintes units. uses ServerController, DataModuleUnit, un_alteracao;

Page 301: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 301

Em seguida devemos criar uma procedure pública para auxiliar no posicionamento do registro, de maneira que possamos atribuir o conteúdo do banco de dados, aos campos do formulário fmAltera. Defina a procedure LOCALIZA, como segue. public procedure Localiza(Cliente: integer);

E na seção implementation, insira o código a seguir. procedure Tfmmanutencao.Localiza(Cliente:integer); begin SQLPesquisa.Locate('cod_cliente', Cliente, []); end; Neste código estamos apenas posicionando o ponteiro do registro de acordo com a seleção do usuário. Agora vamos codificar o objeto btPesquisa. Insira o código que segue no evento OnClick. SQLPesquisa.SQL.Clear; SQLPesquisa.SQL.Add('SELECT * FROM TBCLIENTE WHERE RAZAO_SOCIAL LIKE '+''''+'%'+edPesquisa.Text+'%'+''''); SQLPesquisa.Open;

Neste código estamos preparando uma consulta SQL, baseada na informação do usuário, extraída do objeto edPesquisa. As informações são apresentadas no Grid, devido ao vínculo com o objeto. Coloque o código a seguir, no evento OnClick do objeto btVolta. Hide;

Agora vamos codificar a operação de alteração do Grid. Através da propriedade Columns do IWDBGrid1, selecione a coluna 3 (Altera) e insira o código que segue no evento OnClick. var fmAltera:TfmAltera; begin fmAltera:=TFmAltera.Create(WebApplication); {Atribui o código 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 código. No bloco a seguir, estamos definindo um objeto do tipo TfmAltera, para que possamos manipular o objeto. var

Page 302: Delphi 7 Internet e Banco de Dados - Facunte

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 atribuímos o código do cliente, extraído da variável 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 informações do SQLDataSet1 aos campos do objeto fmAltera, apresentando o formulário de alteração 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 operação de exclusão do Grid. Através da propriedade Columns do IWDBGrid1, selecione a coluna 4 (Exclui) e insira o código 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 um problema na exclusao do cliente', smSameWindow); end; Vamos analisar o código. No código que segue estamos criando um bloco protegido; atribuindo um parâmetro para o objeto SQLExclui e finalmente apresentando uma mensagem ao usuário, em caso de sucesso da operação. 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 exceção, apresentando para o usuário uma mensagem de alerta.

Page 303: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 303

except WebApplication.ShowMessage('Houve um problema na exclusao do cliente', smSameWindow); end; Grave a unit un_manutencao e selecione o formulário principal. A figura 12.47 ilustra o nosso formulário de manutenção.

Figura 12.47 Formulário de manutenção

Vamos codificar o formulário principal, para concluir a aplicação. Na cláusula uses do formulário principal (formMain), insira as units que seguem. uses ServerController, un_Inclusao, un_manutencao; Agora vamos codificar a opção Inclusão de Clientes do Menu Principal. No evento OnClick da opção, insira o código a seguir. var fmInclusao:TFmInclusao; begin fmInclusao:=TFMInclusao.Create(WebApplication); fmInclusao.Show; end; Neste código estamos instanciando o objeto FmInclusao e apresentando ao usuário. E agora, vamos codificar a opção Manutenção/Consulta.Coloque o código que segue no evento OnClick da opção. var fmManutencao:TFmManutencao; begin fmManutencao:=TFMManutencao.Create(WebApplication); fmManutencao.Show; end; Com isso concluímos o nosso projeto de Cadastro de Clientes. As figuras 12.48 a 12.53 ilustram nossa aplicação em tempo de execução.

Page 304: Delphi 7 Internet e Banco de Dados - Facunte

304 Delphi 7 – Internet e Banco de Dados

Figura 12.48 Menu principal

Figura 12.49 Formulário de inclusão

Figura 12.50 Informações sobre a aplicação

Page 305: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 305

Figura 12.51 Manutenção

Repare que na tela de manutenção existe um rollover passeando entre os registros. Para que você possa fazer qualquer tipo de operação, clique no código do cliente, correspondente à operação (altera ou exclui). Você poderá digitar apenas uma parte da razão social do cliente. Por exemplo: digitando Facunte, são apresentados todos os registros que contêm a palavra Facunte, independente da posição.

Figura 12.52 Alteração de clientes

Figura 12.53 Finalizando a aplicação

Page 306: Delphi 7 Internet e Banco de Dados - Facunte

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+'Versão 1.0',smAlert); end; procedure TformMain.Manuteno1Click(Sender: TObject); var fmManutencao:TFmManutencao;

Page 307: Delphi 7 Internet e Banco de Dados - Facunte

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}

Page 308: Delphi 7 Internet e Banco de Dados - Facunte

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 inclusão 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;

Page 309: Delphi 7 Internet e Banco de Dados - Facunte

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

Page 310: Delphi 7 Internet e Banco de Dados - Facunte

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 RAZAO_SOCIAL LIKE '+''''+'%'+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

Page 311: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 311

fmAltera:=TFmAltera.Create(WebApplication); { Atribui o código 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 um problema na exclusao do cliente', smSameWindow); end; end; end.

Listagem 12.16 DataModuleUnit.pas unit DatamoduleUnit; interface uses {$IFDEF Linux}QForms, {$ELSE}Forms, {$ENDIF} SysUtils, Classes, DBXpress, DB, SqlExpr, FMTBcd; type TDataModule1 = class(TDataModule) ConexaoBD: TSQLConnection; SQLInclui: TSQLQuery; SQLAltera: TSQLQuery; SQLExclui: TSQLQuery; private

Page 312: Delphi 7 Internet e Banco de Dados - Facunte

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.

Page 313: Delphi 7 Internet e Banco de Dados - Facunte

Intraweb 313

Anotações de Dúvidas

Preciso Revisar Anotações Gerais

?

!

Page 314: Delphi 7 Internet e Banco de Dados - Facunte

314 Delphi 7 – Internet e Banco de Dados

Capítulo 13

WebServices

O que são WebServices Para explicar de maneira adequada o significado da tecnologia WebServices, é interessante fazer uma breve introdução aos problemas atuais no mundo da tecnologia. Com o grande avanço de sistemas operacionais, bancos de dados, hardware, software, enfim, todo o tipo de tecnologia que envolve o mundo dos negócios, vem surgindo a necessidade de compartilhamento de informações entre parceiros comerciais, governo e sociedade e até mesmo entre departamentos de uma empresa. Acontece que interligar diferentes plataformas, bancos de dados, operações, entre outros conceitos, é uma tarefa muito complicada e trabalhosa. Imagine o seguinte cenário (figura 13.1) :

Figura 13.1 Cenário de uma aplicação

Débito no Banco Cliente

Cotação Preços

Fornece-dores

Aquisição Produtos

Investi-mento em seu Banco

Consulta CPF

(Restrição)

Sua

Aplicação

314

Page 315: Delphi 7 Internet e Banco de Dados - Facunte

WebServices 315

A figura 13.1 ilustra uma situação comum nos dias de hoje, onde temos diversas operações com tecnologias e parceiros diferentes. Sem dúvida que a maioria das operações poderá ser desenvolvida com um grande trabalho em equipe, exigindo um bom trabalho de pesquisa junto aos parceiros e inúmeras horas de desenvolvimento. É justamente neste cenário que surgiu a tecnologia WebServices, para impulsionar os sistemas legados e facilitar a integração de parceiros comerciais. Pegando carona na primeira fase do WebServices, foram implementadas e idealizadas novas funções, com o intuito de promover e consolidar operações semelhantes. A figura 13.2 ilustra este cenário.

Figura 13.2 Cenário de WebServices semelhantes

Analisando a figura 13.2, temos uma aplicação que utiliza WebServices de diferentes fornecedores para fazer cotações de ações, assim como efetuar a aquisição. Um exemplo bastante utilizado, é a cotação do câmbio atual. Veja o cenário na figura

13.3. Imagine o cenário ilustrado pela figura 13.3 onde sua aplicação necessita ter 24 horas/dia (lembre-se de que o mundo não pára) a cotação do câmbio de diferentes países, onde seria uma catástrofe imaginar a quebra dos servidores. O cenário da figura 13.3, ilustra uma operação de cotação de câmbio, utilizando WebServices semelhantes, onde não pode haver queda de servidores, pois a missão é crítica. Bem, do seu lado tudo sem problemas, pois existe uma infra-estrutura ideal para este tipo de operação. Mas no lado do provedor de informações? Imagine que você esteja utilizando apenas um WebService e o mesmo quebra a conexão? O que fazer? Com a segunda fase da tecnologia, você pode mapear ilimitados WebServices semelhantes para fazer o mesmo serviço, 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.

Cotação Ações

Empresa C

Compra Ações

Empresa C

Compra Ações

EmpresaA

Cotação Ações

Empresa B

Cotação Ações

EmpresaA

Sua

Aplicação

Page 316: Delphi 7 Internet e Banco de Dados - Facunte

316 Delphi 7 – Internet e Banco de Dados

Figura 13.3 Cotação câmbio atual

Para concluir o conceito de WebServices, vamos imaginar um cenário mais simples, onde precisamos integrar informações de diferentes departamentos e filiais, que foram desenvolvidos em plataformas diferentes. Um bom exemplo para isso são os bancos que estão 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.

Figura 13.4 Banco com diferentes plataformas

Cotação Câmbio

C

CotaçãoCâmbio

B

Cotação Câmbio

E

CotaçãoCâmbio

D

Cotação Câmbio

A

Sua Aplicação

Banco

X

Banco

Facunte

Banco

Y

Page 317: Delphi 7 Internet e Banco de Dados - Facunte

WebServices 317

Tecnologias do nosso cenário exemplo

Banco S.O. Banco Dados Terminais Facunte

Unix

DB2

Terminais Linux

X

NT

SQL Server

Windows

Y

Solaris

Oracle

Terminais Linux

Integrar informações de diferentes plataformas não é novidade e, como já foi mencionado, é possível, mas muito trabalhoso. A proposta da tecnologia WebServices, neste cenário, é o de facilitar a troca de informações, fazendo o Banco Facunte entender e tratar as informações dos Bancos X e Y, independente do banco de dados, sistema operacional ou outro fator não citado. Com algumas linhas de programação e um bom planejamento, as informações essenciais serão interligadas facilmente. Meus amigos, isso é WebServices! Em resumo, WebServices, é um padrão não-proprietário, que possibilita o processamento distribuído em sistemas heterogêneos. E acredito que muitos de vocês neste ponto estejam ansiosos para produzir o seu primeiro WebService. Antes, devemos conhecer os padrões que fazem parte da tecnologia.

Padronização 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 padrões já consagrados, além do desenvolvimento de outros padrões bastante simples. Vejamos os padrões:

XML XML (Extensive Markup Language) ou Linguagem de Marcação Extensível, que consiste em uma série de regras, dividindo o documento em partes lógicas e hierárquicas. Atualmente é utilizada para trabalhar em conjunto com diversas tecnologias, seja no padrão de gravação de um arquivo, no transporte de informações, até mesmo em definições de montagem de veículos. Trabalhando em conjunto com o WebServices, fornece estrutura para o documento de regras e serviços (WSDL), pacote de dados e ocorrências. Veja um exemplo de XML de dados: <?xml version=”1.0”?> <LISTA_CLIENTES> <Cliente> <RazaoSocial>Banco Facunte</RazaoSocial> <Cidade>São Paulo</Cidade> <Estado>SP</Estado> </Cliente> <Cliente> <RazaoSocial>Global Education</RazaoSocial> <Cidade>São Paulo</Cidade> <Estado>SP</Estado> </Cliente> <Cliente> <RazaoSocial>Clube Delphi</RazaoSocial> <Cidade>Rio de Janeiro</Cidade> <Estado>RJ</Estado> </Cliente> </LISTA_CLIENTES>

Page 318: Delphi 7 Internet e Banco de Dados - Facunte

318 Delphi 7 – Internet e Banco de Dados

WSDL WSDL – Web Service Definition Language ou Linguagem de Definições de WebServices. O WSDL é um documento criado no padrão XML, com o objetivo de fornecer informações sobre a definição de um WebService. Esta definição consiste em métodos, parâmetros e serviços fornecidos pelo WebService. Veremos na prática um documento WSDL, bem como a sua forma de utilização.

SOAP Soap – Simple Object Access Protocol ou Protocolo Simples de Acesso a Objetos. Em poucas palavras, o SOAP é o protocolo utilizado para troca de informações através de objetos criados em diversas linguagens de programação, como Delphi, Java, C++, C#, VB.NET, entre outras. Trafega através 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 tráfego de informações.

UDDI UDDI – Universal Definition Discovery Inteface ou Interface para Descoberta de Definições Universais. Para facilitar a compreensão do UDDI, farei uma comparação com os serviços de busca na Internet. Quando queremos procurar algum documento, artigo, software, na Internet, normalmente utilizamos serviços de busca, como o Google (meu preferido), Yahoo!, Hotbot, Cadê?, entre outros. Imagine que para localizar um WebServices é bastante semelhante, com alguns parâmetros diferenciados. O UDDI na realidade é um grande catálogo de WebServices, oferecido por diversas empresas, seja ela envolvida na padronização, como IBM e Borland, ou até mesmo empresas independentes, como o SALCentral.COM (www.salcentral.com). Com isso poderemos localizar e mapear serviços semelhantes, como o exemplo que vimos neste capítulo, sobre a cotação de câmbios.

Figura 13.5 Aplicação utilizando o serviço UDDI

A figura 13.5 ilustra uma aplicação utilizando os serviços do UDDI. Neste cenário foram localizados e mapeados WebServices semelhantes, de maneira que a aplicação tenha objetos redundantes, aumentando a eficácia e a segurança. Isso demonstra a flexibilidade da tecnologia, onde as empresas poderão escolher os serviços (WebServices) mais adequados à sua aplicação.

E

D C

B

A

UDDI

Page 319: Delphi 7 Internet e Banco de Dados - Facunte

WebServices 319

Sugestões de desenvolvimento

CPF Restrições de Crédito Empresas que oferecem serviços e informações sobre restrições de crédito poderão desenvolver WebServices para fornecer tais informações diretamente nas aplicações de seus clientes. O mais interessante é que a cobrança será automática, pois cada cliente terá uma chave criptografada e a empresa poderá cobrar por número de acessos.

Rastreamento de Cargas Empresas como FedEx e DHL já fornecem seus próprios WebServices. Correios, empresas de logística e transporte, poderão desenvolver WebServices para rastrear as cargas e encomendas enviadas. Além disso, poderão fornecer informações de estimativa de chegada dinâmica, ou seja, imagine uma carga que teve um acréscimo na previsão de chegada, devido a uma greve no porto, ou até mesmo um problema no trajeto; com isso a informação poderá ser fornecida dinamicamente ao cliente, onde o mesmo tomará as devidas providências, como um adiamento de reunião ou de produção.

Identificação de Veículos Os DETRANs de todo o país poderiam desenvolver WebServices, com inúmeros objetivos. O mais importante seria a identificação prévia do veículo, onde despachantes, compradores e vendedores de veículos, guardas e operadores de trânsito, saberiam imediatamente informações do veículo em questão. Através de Palmtops ou celulares, guardas de trânsito poderiam controlar com mais facilidade as multas em veículos infratores. Fabricantes de veículos poderiam checar com maior facilidade informações sobre um grupo de chassis, para um possível recall, preparando uma estratégia junto à sua equipe de mecânicos para um melhor atendimento por região.

Cotação de Ações As operadoras de ações poderiam desenvolver WebServices, afim de fornecer informações diretamente nas aplicações de seus clientes, onde os mesmos poderiam concluir negócios mais facilmente, e armazenando a informação diretamente em seu próprio banco de dados.

Cotação de Moedas Já existem diversos WebServices catalogados oferecendo o serviço de cotação de moedas. Os mais avançados oferecem funções para conversão, onde a aplicação fornece as moedas e valores e o WebService retorna o resultado. Existem outros que fazem atualização monetária baseada em múltiplas moedas. Isso é muito interessante em países como o nosso, que já trocou de moeda uma dezena de vezes.

TEF (Transferência Eletrônica de Fundos) Este é um assunto muito delicado, pois envolve segurança. A tecnologia de WebServices está amadurecendo nesta questão, tanto que o SPB (Sistema de Pagamentos Brasileiro) está utilizando a tecnologia para o transporte de algumas informações. O pacote trafega numa rede muito segura, e altamente criptografada, evitando ações de hackers mal-intencionados. Mesmo assim é uma sugestão muito interessante, que facilita o trâmite das informações entre instituições.

Page 320: Delphi 7 Internet e Banco de Dados - Facunte

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 serão utilizados por nossos clientes, vendedores e também fornecedores. Os clientes utilizarão para fazer cotações e fechamento de pedidos através de suas próprias aplicações. Os vendedores, tanto externos como internos, utilizarão para consultar o saldo no estoque e efetuar os seus pedidos. Já os fornecedores poderão enviar orçamentos para produtos que estão chegando no nível de estoque mínimo, assim como os próprios compradores da empresa.

CEPs Os Correios, uma das empresas mais respeitadas do país, poderiam desenvolver um WebService, oferecendo as informações de sua base de dados on-line, diretamente na aplicação do cliente. O objetivo não é apenas consultar e corrigir informações sobre o CEP; pode-se ampliar o serviço para o cálculo de envio de encomendas, e os prazos estipulados.

RG Um dos assuntos polêmicos em nosso país. Cada Estado tem sua forma de estabelecer regras para os números de R.G.s. Será que um dia iremos acordar e cada cidadão brasileiro terá sua identificação própria, sem duplicidades? Isso só será possível através de uma integração entre os municípios de todo o país. Quando isso for possível, o Governo poderá oferecer WebServices com os mais variados objetivos. Um bom exemplo para isso, seria o Censo. Sem dúvida nenhuma teríamos um Censo com um percentual próximo do máximo e com muita rapidez.

CNAB Quem aí já passou pelo suado processo de montagem de arquivos no “padrão” (eu disse padrão?) CNAB? Cada banco tem um formato de arquivo, um número diferente de propriedades a serem preenchidas, headers psicodélicos e linhas de registros com informações absurdas e repetitivas. Criando um WebService, padrão (aqui sim, seria um padrão), os clientes poderiam transmitir e receber informações de cobrança com uma facilidade enorme. O mais interessante disso tudo acontece quando o cliente opta por outra instituição para fazer a sua cobrança e não precisa alterar nenhuma linha de programação, apenas algumas propriedades, como por exemplo, o código da instituição financeira.

Serviços de UDDI e catálogos alternativos

http://uddi.org

UDDI principal, responsável pela especificação do UDDI.

http://uddi.ibm.com

UDDI da IBM, com opções de registros de WebServices corporativos e para testes.

.

http://uddi.microsoft.com UDDI da Microsoft, com diversas opções de busca, registro simples de novos WebServices, ferramentas para desenvolvedores, entre outros serviços. Excelente.

Page 321: Delphi 7 Internet e Banco de Dados - Facunte

WebServices 321

http://uddi.sap.com UDDI da SAP. É necessário entrar na área UDDI Discovery para registrar, procurar e publicar WebServices.

http://www.webservicelist.com/ Fantástico catálogo de Webservices independente, com divisão por categoria, busca de semelhantes, palavras chaves, entre outros serviços.

http://www.xmethods.com Excelente catálogo de Webservices, com os mais populares, até Webservices comerciais.

Nos serviços aqui apresentados, existe uma imensidão de WebServices, divididos nas mais variadas categorias. Desde simples consultas a cotação de moedas, até serviços na área de saúde. Mais adiante iremos aprender a importar estes serviços (WebServices) em nossa aplicação.

Delphi x WebServices Neste tópico iremos aprender os conceitos de WebServices integrado com o Delphi. O Delphi possui um conjunto de componentes específico para a tecnologia de WebServices. Na seção WebServices da paleta de componentes, encontramos os seguintes objetos:

COMPONENTE (OBJETO)

DESCRIÇÃO

HTTPRIO

Utiliza para obter uma referência para uma interface registrada. Gera em memória uma tabela de métodos, a fim de fornecer a implementação da interface.

HTTPReqResp

Executa métodos de chamada na interface, de maneira a enviar e receber mensagens no padrão SOAP. Normalmente utilizado em conjunto com o HTTPRio, implementando os métodos Get e Post.

OpToSOAPDOMConvert

Normalmente instanciado em tempo de execução pelo componente HTTPRio, tem como principal função fazer um parser nos métodos de chamada.

SOAPConnection

Utilizado para conectar a aplicação aos servidores implementados no padrão WebService.

Page 322: Delphi 7 Internet e Banco de Dados - Facunte

322 Delphi 7 – Internet e Banco de Dados

COMPONENTE (OBJETO)

DESCRIÇÃO

HTTPSoapDispatcher

Responsável por responder as chamadas no padrão SOAP.

WSDLHTMLPublish

Responsável por publicar um documento WSDL com todo o descritivo do WebService.

HTTPSoapPascalInvoker

Utilizado para interpretar uma mensagem padrão SOAP, e executar o método correspondente.

WebService Exemplo Vamos criar nosso primeiro WebService para aprender melhor seu conceito. Através das opções File/New..., seção WebServices, selecione a opção SOAP Server Application (figura 13.6).

Figura 13.6 Nova aplicação WebService

Em seguida, selecione a opção CGI para o tipo da aplicação servidora SOAP (figura 13.7).

Page 323: Delphi 7 Internet e Banco de Dados - Facunte

WebServices 323

Figura 13.7 Tipo da aplicação servidora

Em seguida, o Delphi pergunta se deseja criar uma Interface SOAP padrão (figura 13.8). Em nosso primeiro exemplo, vamos criar tal Interface, a fim de conhecer sua implementação.

figura 13.8 Criação 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 opções Generate Comments e Generate

Sample Methods. Com isso estamos gerando exemplos de métodos e comentários.

Figura 13.9 Identificação do serviço

Clique em OK para finalizar. Vamos gravar nossa aplicação.

Page 324: Delphi 7 Internet e Banco de Dados - Facunte

324 Delphi 7 – Internet e Banco de Dados

Unit WebModule un_ws1.pas Unit Implementação WsExemplo wsexemploImpl.pas Unit Interface WsExemplo wsexemploIntf.pas Projeto ws1.dpr

Vamos analisar o que o nosso amigo Delphi criou.

Figura 13.10 WebModule1

A figura 13.10 ilustra nosso WebModule com três componentes no padrão WebService (HTTPSoapDispatcher,

HTTPSoapPascalInvoker e WSDLHTMLPublish). Vejamos sua implementação. procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin

WSDLHTMLPublish1.ServiceInfo(Sender, Request, Response, Handled); end; A única função do nosso WebModule1 é a criação de um handler para o WebService e publicação do documento WSDL. Na unit wsexemploIntf estamos definindo a Interface de nossa aplicação. {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;

Page 325: Delphi 7 Internet e Banco de Dados - Facunte

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. (Orientação a Objeto), onde definimos uma Interface como base, para que possamos implementar nossas classes. Além disso estamos registrando a Interface no modelo SOAP. Repare que os métodos criados são apenas exemplos de implementação, que solicitamos previamente, justamente para estudar e analisar. Na unit wsexemploImpl, temos a implementação da Interface que vimos anteriormente. Veja o código. { 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 Twsexemplo.echoDoubleArray(const Value: TDoubleArray): TDoubleArray; stdcall; begin

Page 326: Delphi 7 Internet e Banco de Dados - Facunte

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 métodos apenas retornam os mesmos valores informados. Para compreender melhor, vamos fazer uma pequena alteração no método echoDouble. Substitua a linha de retorno, pelo código que segue em negrito: function Twsexemplo.echoDouble(const Value: Double): Double; stdcall; begin { TODO : Implement method echoDouble } Result := Value * 3;

end;

Grave a aplicação. Antes de compilar, vamos definir o diretório para geração do nosso WebService. Através das opções Project/Options.../Directories_Conditionals, configure a opção Output Directory, apontando para o seu diretório cgi-bin (figura 13.11).

Figura 13.11 Configuração do diretório

Grave novamente a aplicação.

Page 327: Delphi 7 Internet e Banco de Dados - Facunte

WebServices 327

Agora vamos compilar a aplicação. Vamos executar a aplicação no browser para analisar o seu conteúdo. Digite: http://localhost/cgi-bin/ws1.exe/. A figura 13.12 ilustra o resultado da primeira fase de nossa aplicação.

Figura 13.12 Aplicação ws1

Repare que temos todos os métodos listados na Interface Iwsexemplo (echoEnum, echoDoubleArray, echoMyEmployee, echoDouble). O documento gerado está de acordo com o padrão estabelecido pelo W3C-UDDI (órgão responsável pelo padrão 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>

Page 328: Delphi 7 Internet e Banco de Dados - Facunte

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">

Page 329: Delphi 7 Internet e Banco de Dados - Facunte

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, não é? 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" />

Page 330: Delphi 7 Internet e Banco de Dados - Facunte

330 Delphi 7 – Internet e Banco de Dados

<xs:enumeration value="etAlot" /> </xs:restriction>

Passando pelo bloco das definições inicias (<?xml version="1.0"...), chegamos no bloco de definições de tipos e métodos. Neste bloco são definidos todos os métodos da nossa Interface, com o descritivo completo. Repare que a classe TEnumTest é descrita com perfeição. No bloco que segue, são descritos os métodos Request e Response da Interface em questão. - <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 operações 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 métodos. - <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 serviço, 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 aplicação cliente para testar nosso primeiro WebService. Através das opções File/New Application crie uma nova aplicação, e grave os arquivos como segue:

Unit un_teste_ws1.PAS Projeto teste_ws1.DPR

Agora vamos importar a Interface em nossa aplicação. Através das opções File/New.../WebServices (figura 13.13), selecione a opção WSDL Importer.

Page 331: Delphi 7 Internet e Banco de Dados - Facunte

WebServices 331

Figura 13.13 WSDL importer

Em seguida, como ilustra a figura 13.14 , digite o endereço que segue. http://localhost/cgi-bin/ws1.exe/wsdl/Iwsexemplo

Este endereço faz a chamada ao documento WSDL da Interface Iwsexemplo.

Fgura 13.14 Importação da Interface através do WSDL

Este procedimento está importando toda a Interface para a nossa aplicação. Com isso teremos acesso aos métodos definidos. É interessante destacar que um WebService poderá ter inúmeras Interfaces, onde poderemos importar apenas as que condizem com a nossa necessidade. Aperte o botão Next para avançar à próxima fase. A figura 13.15 ilustra a Interface gerada pelo assistente.

Page 332: Delphi 7 Internet e Banco de Dados - Facunte

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 importação 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 formulário. Insira um objeto do tipo THTTPRIO e configure as propriedades que seguem, respeitando a seqüência apresentada, caso contrário, uma exceção ocorrerá.

OBJETO

THTTPRio

Objeto Propriedade Valor

HTTPRio1 Name HR1

WSDLLocation

http://localhost/cgi-bin/ ws1.exe/wsdl/Iwsexemplo

Service Iwsexemploservice

Port IwsexemploPort Com isto configuramos o objeto de acesso à Interface, informando a localização do documento WSDL (WSDLLocation), o serviço (Service), e a porta (Port). Agora insira os objetos que seguem, configurando suas respectivas propriedades.

Page 333: Delphi 7 Internet e Banco de Dados - Facunte

WebServices 333

OBJETO

TEdit

Objeto Propriedade Valor

edValor Name edValor

Left 32

Text deixe em branco

Top 24

Width 120

OBJETO

TButton

Objeto Propriedade Valor

Button1 Name Button1

Caption Calcula

Left 176

Top 24

Width 125

OBJETO

Tlabel

Objeto Propriedade Valor

lbResultado Name lbResultado

Caption 0

Left 32

Top 64 A figura 13.16 ilustra o formulário da nossa aplicação.

Figura 13.16 Formulário da aplicação

Agora vamos codificar a aplicação. Insira o código que segue no evento OnClick do objeto Button1. var

Iexemplo: Iwsexemplo; begin

Page 334: Delphi 7 Internet e Banco de Dados - Facunte

334 Delphi 7 – Internet e Banco de Dados

Iexemplo:= HR1 as Iwsexemplo; lbResultado.Caption:=FloattoStr(Iexemplo.echoDouble( StrtoFloat(edValor.Text))); end;

O código é 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, através da função IExemplo.echoDouble. O mais importante, até aqui, é justamente a compreensão de como conseguimos implementar o WebService em nossa aplicação. Vamos testar nossa aplicação. Compile e execute a aplicação, informando um número no campo e pressionando o botão. A figura 13.17 ilustra nossa aplicação em tempo de execução.

, Figura 13.17 Aplicação em tempo de execução

Perceba que, na primeira vez que pressionamos o botão, existe um delay, que é justamente o tempo de conexão com o WebService. Repita a operação e perceba que já não existe mais o delay. Amigos, no próximo tópico iremos desenvolver nosso próprio WebService. Listagem 13.1 un_teste_ws1.pas (formulário 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;

Page 335: Delphi 7 Internet e Banco de Dados - Facunte

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 aplicação) // ************************************************************************ // // 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)

Page 336: Delphi 7 Internet e Banco de Dados - Facunte

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

Page 337: Delphi 7 Internet e Banco de Dados - Facunte

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:wsexemploIntf-Iwsexemplo#%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 métodos gerados pelo assistente. Nosso WebService consiste em fazer um simples cálculo, apresentando um número 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. Através das opções File/New..., seção WebServices, selecione a opção SOAP Server Application (figura 13.18).

Figura 13.18 Nova aplicação WebService

Page 338: Delphi 7 Internet e Banco de Dados - Facunte

338 Delphi 7 – Internet e Banco de Dados

Em seguida, selecione a opção CGI para o tipo da aplicação servidora SOAP (figura 13.19).

Figura 13.19 Tipo da aplicação servidora

Em seguida, o Delphi pergunta se deseja criar uma Interface SOAP padrão (figura 13.20). Neste caso, seleciona No, pois iremos criar “manualmente”.

Figura 13.20 Criação da Interface

Vamos gravar nossa aplicação.

Unit WebModule un_ws2.PAS Projeto ws2.DPR

Agora vamos criar a Interface de nossa aplicação. A partir da versão 7, existe o assistente para a criação da Interface. Na realidade faz a mesma operação que dispensamos no diálogo anterior (figura 13.20). Através das opções File/New..WebServices, selecione o assistente SOAP Server Interface (figura 13.21), e em seguida pressione OK.

Page 339: Delphi 7 Internet e Banco de Dados - Facunte

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 opções (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 aplicação.

Unit wsIdadeIntf wsIdadeIntf.pas Unit wsIdadeImpl wsIdadeImpl.pas

Vamos analisar as units criadas. wsIdadeIntf.pas unit wsIdadeIntf; interface uses InvokeRegistry, Types, XSBuiltIns; type IwsIdade = interface(IInvokable)

Page 340: Delphi 7 Internet e Banco de Dados - Facunte

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 definição da Interface do nosso WebService. No bloco que segue, definimos os métodos. Repare que foi criado um identificador único (GUID). Poderíamos fazer esta Interface sem o uso do assistente, e para a criação 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 implementação dos métodos 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 métodos são definidos como public. type

Page 341: Delphi 7 Internet e Banco de Dados - Facunte

WebServices 341

TwsIdade = class(TInvokableClass, IwsIdade) public end;

Bem, agora vamos definir o método de nosso WebService. Selecione a unit wsIdadeIntf, e insira o método QuantosDias, como segue. IwsIdade = interface(IInvokable) ['{A808C7C4-86BC-446C-B329-60F22BD82A87}'] function QuantosDias(idade: Integer):integer; stdcall;

end;

Repare que estamos fazendo uma chamada explícita stdcall, padrão em WebServices. Grave a unit. Agora, selecione a unit

wsIdadeImpl e insira o método QuantosDias, como segue; public function QuantosDias(idade: Integer):integer; stdcall;

end;

Na seção implementation, digite o código 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 padrão desktop, e o outro uma aplicação CGI. Antes de compilar, vamos definir o diretório para geração do nosso WebService. Através das opções Project/Options.../Directories_Conditionals, configure a opção Output Directory, apontando para o seu diretório cgi-bin (figura 13.23).

Figura 13.23 Configuração do diretório

Compile a nossa aplicação para que possamos analisar o documento WSDL. No browser digite http://localhost/cgi-bin/ws2.exe. A figura 13.24 ilustra o assistente WSDL de nossa aplicação.

Page 342: Delphi 7 Internet e Banco de Dados - Facunte

342 Delphi 7 – Internet e Banco de Dados

Figura 13.24 Página de informação (assistente WSDL).

Repare que o nosso método QuantosDias está publicado. Clique no WSDL do método para visualizar a implementação. 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>

Page 343: Delphi 7 Internet e Banco de Dados - Facunte

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 aplicação cliente para o nosso WebService. Através das opções File/New Application cria uma nova aplicação e grave os arquivos como segue:

Unit un_teste_ws2.PAS Projeto teste_ws2.DPR

Agora vamos importar a Interface em nossa aplicação. Através das opções File/New.../WebServices (figura 13.25), selecione a opção WSDL Importer.

Figura 13.25 WSDL importer

Em seguida, como ilustra a figura 13.26 , digite o endereço que segue. http://localhost/cgi-bin/ws2.exe/wsdl/IwsIdade

Este endereço faz a chamada ao documento WSDL da Interface IwsIdade.

Figura 13.26 Importando a Interface

Page 344: Delphi 7 Internet e Banco de Dados - Facunte

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 formulário. Insira um objeto do tipo THTTPRIO e configure as propriedades que seguem, respeitando a seqüência apresentada, caso contrário, uma exceção ocorrerá.

OBJETO

THTTPRio

Objeto Propriedade Valor

HTTPRio1 Name HR1

WSDLLocation

http://localhost/cgi-bin/ ws2.exe/wsdl/IwsIdade

Service IwsIdadeservice

Port IwsIdadePort Com isto configuramos o objeto de acesso à Interface, informando a localização do documento WSDL (WSDLLocation), o serviço (Service), e a porta (Port). Agora insira os objetos que seguem, configurando suas respectivas propriedades.

OBJETO

TEdit

Objeto Propriedade Valor

edValor Name edIdade

Left 32

Text deixe em branco

Top 24

Width 120

OBJETO

TButton

Objeto Propriedade Valor

Button1 Name Button1

Caption Calcula

Left 176

Top 24

Width 125

Page 345: Delphi 7 Internet e Banco de Dados - Facunte

WebServices 345

OBJETO

Tlabel

Objeto Propriedade Valor

lbResultado Name lbDias

Caption Dias

Left 32

Top 64 A figura 13.27 ilustra o formulário da nossa aplicação.

Figura 13.27 Formulário da aplicação

Agora vamos codificar a aplicação. Insira o código 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, através da função IIDade.QuantosDias. Fácil? Acredito que neste ponto já deu para compreender o método de implementação de um WebService. Agora vamos utilizar o mesmo WebService numa aplicação do tipo CGI. A partir do Delphi, selecione as opções File/New/Other... e em seguida a opção Web Server Application, como ilustra a figura 13.28.

Figura 13.28 Opção Web Server Application

Page 346: Delphi 7 Internet e Banco de Dados - Facunte

346 Delphi 7 – Internet e Banco de Dados

Na janela seguinte selecione a opção CGI Stand-Alone executable (figura 13.29).

Figura 13.29 Seleção do tipo da aplicação

Em seguida teremos o nosso WebModule (figura 13.30).

Figura 13.30 WebModule

Neste ponto ao invés de importar o WSDL, vamos apenas adicionar a unit que já importamos em nossa primeira aplicação: 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 seqüência apresentada, caso contrário, uma exceção ocorrerá.

OBJETO

THTTPRio

Objeto Propriedade Valor

HTTPRio1 Name HR1

WSDLLocation

http://localhost/cgi-bin/ ws2.exe/wsdl/IwsIdade

Service IwsIdadeservice

Port IwsIdadePort

Page 347: Delphi 7 Internet e Banco de Dados - Facunte

WebServices 347

Agora vamos criar nossa Action. Através do duplo-clique no WebModule, acesse o editor de ActionItems (figura 13.31).

Figura 13.31 Editor ActionItems

Clique no primeiro botão do editor para inserir uma nova Action (figura 13.32).

Figura 13.32 ActionItem

Em seguida altere as seguintes propriedades.

OBJETO

TWebActionItem

Objeto Propriedade Valor

padrao Default True

Name dias

PathInfo /dias Esta será nossa Action padrão, ou seja, caso o usuário não digite nada, além do nome da nossa aplicação, esta Action será executada. No evento OnAction coloque o seguinte código: 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 método Response.Content para apresentar ao usuário a mensagem criada através do parâmetro Idade, utilizando o método QuantosDias do nosso WebService.

Page 348: Delphi 7 Internet e Banco de Dados - Facunte

348 Delphi 7 – Internet e Banco de Dados

Antes de compilar vamos definir o diretório para geração do nosso WebService. Através das opções Project/Options.../Directories_Conditionals, configure a opção Output Directory, apontando para o seu diretório cgi-bin (figura 13.33).

Figura 13.33 Configuração do diretório

Grave os arquivos como segue.

Unit un_cgi_ws2.PAS Projeto teste_cgi_ws2.DPR

Agora vamos testar a nossa aplicação. No browser digite o seguinte endereço: http://localhost/delphi/cgi-bin/teste_cgi_ws2.exe/dias?idade=55

A figura 13.34 ilustra nosso CGI em tempo de execução.

Figura 13.34 CGI em execução

Para testar o CGI, estamos passando através do parâmetro Idade (?idade=), a idade desejada para o cálculo. Nosso CGI extrai através do método Request.QueryFields o valor do parâmetro Idade, e faz o cálculo utilizando o método QuantosDias do nosso Webservice. Com isso concluímos o nosso projeto.

Page 349: Delphi 7 Internet e Banco de Dados - Facunte

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 (implementação 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;

Page 350: Delphi 7 Internet e Banco de Dados - Facunte

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);

Page 351: Delphi 7 Internet e Banco de Dados - Facunte

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', 'utf-8'); InvRegistry.RegisterDefaultSOAPAction(TypeInfo(IwsIdade), 'urn:wsIdadeIntf-IwsIdade#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';

Page 352: Delphi 7 Internet e Banco de Dados - Facunte

352 Delphi 7 – Internet e Banco de Dados

end; end.

WebServices com Banco de Dados Neste exemplo vamos criar nosso WebService que retorna informações do nosso banco de dados. Nosso WebService consiste em fazer uma pesquisa em nossa tabela de clientes e retornar a Razão Social. Imagine que o código do cliente é uma espécie de C.G.C, onde qualquer contribuinte, seja pessoa física ou jurídica, teria acesso aos dados da empresa, em sua própria aplicação. Através das opções File/New..., seção WebServices, selecione a opção SOAP Server Application (figura 13.35).

Figura 13.35 Nova aplicação WebService

Em seguida selecione a opção CGI para o tipo da aplicação servidora SOAP (figura 13.36).

Figura 13.36 Tipo da aplicação servidora

Na janela de diálogo que segue (figura 13.37), não confirme a criação da Interface.

Page 353: Delphi 7 Internet e Banco de Dados - Facunte

WebServices 353

Figura 13.37 Criação da Interface

Vamos gravar nossa aplicação.

Unit WebModule un_ws3.PAS Projeto ws3.DPR

Agora vamos inserir um SOAP Data Module em nossa aplicação. Através das opções File/New..WebServices, selecione a opção 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. Através do duplo-clique, já na tela de configuração, aponte para a nossa conexão Clientes, criada anteriormente. Vamos relembrar os atributos da conexão.

Page 354: Delphi 7 Internet e Banco de Dados - Facunte

354 Delphi 7 – Internet e Banco de Dados

PROPRIEDADE

VALOR

CommitRetain

False

Database

localhost:c:\cursoweb\clientes.gdb

Password

a famosa masterkey

UserName

o famoso SYSDBA

Name

ConexaoBD

Altere também a propriedade LoginPrompt para false.

Figura 13.40 Configuração da Conexão

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

ConexaoBD

CommandText

select * from TBCLIENTE where COD_CLIENTE=:pcodigo

Configure o tipo do parâmetro pcodigo para Integer. Agora vamos codificar a Interface do nosso WebService. Na unit un_ws3_dm, insira o código que segue, adequando ao código já existente.

Page 355: Delphi 7 Internet e Banco de Dados - Facunte

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 método MostraRazao, que implementaremos agora na seção implementation. Agora, na seção implementation, insira completamente o código a seguir: function Tws3dm.MostraRazao(codigo:integer):String; begin

{ configura o parâmetro } 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 código. No bloco a seguir, estamos atribuindo o código transmitido através do Client em nosso parâmetro e abrindo o DataSet. SQLClientes.ParamByName('pcodigo').Value:=codigo; SQLClientes.Open;

Em seguida, verificamos a existência do cliente, e em caso afirmativo retornamos o valor do campo Razao_Social, caso contrário, 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 aplicações Client. Através das opções File/New

Application crie uma nova aplicação e grave os arquivos como segue:

Unit un_teste_ws3.PAS Projeto teste_ws3.DPR

Agora vamos importar a Interface em nossa aplicação. Através das opções File/New.../WebServices (figura 13.41), selecione a opção WSDL Importer.

Page 356: Delphi 7 Internet e Banco de Dados - Facunte

356 Delphi 7 – Internet e Banco de Dados

Figura 13.41 WSDL importer

Em seguida, como ilustra a figura 13.42 , digite o endereço que segue. http://localhost/cgi-bin/ws3.exe/wsdl/Iws3DM

Este endereço 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 formulário. Insira um objeto do tipo THTTPRIO e configure as propriedades que seguem, respeitando a seqüência apresentada, caso contrário, uma exceção ocorrerá.

Page 357: Delphi 7 Internet e Banco de Dados - Facunte

WebServices 357

OBJETO

THTTPRio

Objeto Propriedade Valor

HTTPRio1 Name HR1

WSDLLocation

http://localhost/cgi-bin/ ws3.exe/wsdl/Iws3dm

Service Iws3dmservice

Port Iws3DmPort Com isto configuramos o objeto de acesso à Interface, informando a localização do documento WSDL (WSDLLocation), o serviço (Service), e a porta (Port). Agora insira os objetos que seguem, configurando suas respectivas propriedades.

OBJETO

TEdit

Objeto Propriedade Valor

edCodigo Name edCodigo

Left 32

Text deixe em branco

Top 24

Width 120

OBJETO

TButton

Objeto Propriedade Valor

Button1 Name Button1

Caption Pesquisa

Left 176

Top 24

Width 125

OBJETO

Tlabel

Objeto Propriedade Valor

lbRazao Name lbRazao

Caption Cliente

Left 32

Top 64

Page 358: Delphi 7 Internet e Banco de Dados - Facunte

358 Delphi 7 – Internet e Banco de Dados

A figura 13.43 ilustra o formulário da nossa aplicação.

Figura 13.43 Formulário aplicação teste3

Agora vamos implementar o código do formulário. No evento OnClick do botão, insira o código que segue: var

IRazao:IWS3DM; begin

IRazao:=HR1 as IwS3DM; lbRazao.Caption:=Irazao.MostraRazao( StrtoInt( edCodigo.Text )); end;

Estamos fazendo uma operação bastante simples, passando o parâmetro código para o nosso WebService e apresentando o resultado no objeto lbRazao. As figuras 13.44 e 13.45 ilustram nossa aplicação em tempo de execução.

Figura 13.44 Cliente encontrado

Figura 13.45 Cliente inexistente

Amigos, isto é fantástico, não é? Agora vamos desenvolver uma aplicação no padrão CGI para consultar a razão social de um cliente. A partir do Delphi, selecione as opções File/New/Other... e em seguida a opção Web Server Application, como ilustra a figura

13.46.

Page 359: Delphi 7 Internet e Banco de Dados - Facunte

WebServices 359

Figura 13.46 Opção Web Server Application

Na janela seguinte selecione a opção CGI Stand-Alone executable (figura 13.47).

Figura 13.47 Seleção do tipo da aplicação

Em seguida teremos o nosso WebModule (figura 13.48).

figura 13.48 WebModule

Page 360: Delphi 7 Internet e Banco de Dados - Facunte

360 Delphi 7 – Internet e Banco de Dados

Neste ponto ao invés de importar o WSDL, vamos apenas adicionar a unit que já importamos em nossa primeira aplicação: 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 seqüência apresentada, caso contrário, uma exceção ocorrerá.

OBJETO

THTTPRio

Objeto Propriedade Valor

HTTPRio1 Name HR1

WSDLLocation

http://localhost/cgi-bin/ ws3.exe/wsdl/Iws3dm

Service Iws3dmservice

Port Iws3DmPort Agora vamos criar nossa Action. Através do duplo-clique no WebModule, acesse o editor de ActionItems (figura 13.49).

Figura 13.49 editor ActionItems

Clique no primeiro botão do editor para inserir uma nova Action (figura 13.50).

Figura 13.50 ActionItem

Em seguida altere as seguintes propriedades.

Page 361: Delphi 7 Internet e Banco de Dados - Facunte

WebServices 361

OBJETO

TWebActionItem

Objeto Propriedade Valor

Padrao Default True

Name consulta

PathInfo /consulta Esta será nossa Action padrão, ou seja, caso o usuário não digite nada, além do nome da nossa aplicação, esta Action será executada. No evento OnAction coloque o seguinte código: var IRazao: Iws3DM1; begin IRazao:=HR1 as Iws3DM; Response.Content:='Cliente = '+ IRazao.MostraRazao(StrtoInt(Request.QueryFields. Values['codigo'])); end;

Aqui estamos utilizando o método Response.Content para apresentar ao usuário a mensagem criada através do parâmetro codigo, utilizando o método MostraRazao do nosso WebService. Antes de compilar, vamos definir o diretório para geração do nosso WebService. Através das opções Project/Options.../Directories_Conditionals, configure a opção Output Directory, apontando para o seu diretório cgi-bin (figura 13.51).

Figura 13.51 Configuração do diretório

Grave os arquivos como segue.

Unit un_cgi_ws3.PAS Projeto teste_cgi_ws3.DPR

Page 362: Delphi 7 Internet e Banco de Dados - Facunte

362 Delphi 7 – Internet e Banco de Dados

Agora vamos testar a nossa aplicação. No browser digite o seguinte endereço: http://localhost/delphi/cgi-bin/teste_cgi_ws3.exe/consulta? codigo=14

A figura 13.52 ilustra nosso CGI em tempo de execução.

figura 13.52 Resultado da aplicação

Agora deu para perceber o poder do WebService, não? No próximo tópico, iremos desenvolver uma aplicação 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;

Page 363: Delphi 7 Internet e Banco de Dados - Facunte

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

Page 364: Delphi 7 Internet e Banco de Dados - Facunte

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_dm-Iws3dm#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 comunicação de dados muito interessante. O protocolo SOAP responsável pelo transporte das informações e a tecnologia DataSnap pelo fornecimento e empacotamento dos dados. Teremos ainda, uma aplicação de teste bastante simples. Bem, vamos iniciar o desenvolvimento do nosso WebService. Através das opções File/New..., seção WebServices, selecione a opção SOAP Server Application (figura 13.53).

Page 365: Delphi 7 Internet e Banco de Dados - Facunte

WebServices 365

Figura 13.53 Nova aplicação WebService

Em seguida, selecione a opção CGI para o tipo da aplicação servidora SOAP (figura 13.54).

Figura 13.54 Tipo da aplicação servidora

Na janela de diálogo que segue (figura 13.55), não confirme a criação da Interface.

Figura 13.55 Criação da Interface

Vamos gravar nossa aplicação.

Page 366: Delphi 7 Internet e Banco de Dados - Facunte

366 Delphi 7 – Internet e Banco de Dados

Unit WebModule un_ws4.PAS Projeto ws4.DPR

Agora vamos inserir um SOAP Data Module em nossa aplicação. Através das opções File/New..WebServices, selecione a opção 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. Através do duplo-clique, já na tela de configuração, aponte para a nossa conexão Clientes, criada anteriormente. Vamos relembrar os atributos da conexão.

PROPRIEDADE

VALOR

CommitRetain

False

Database

localhost:c:\cursoweb\clientes.gdb

Password

a famosa masterkey

UserName

o famoso SYSDBA

Name

ConexaoBD

Page 367: Delphi 7 Internet e Banco de Dados - Facunte

WebServices 367

Altere também a propriedade LoginPrompt para false.

Figura 13.58 Configuração da Conexão

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

ConexaoBD

CommandText

select * from TBCLIENTE

Name

SQLClientes

Active

True

Insira um objeto do tipo TDataSetProvider para fornecer os dados de nosso DataSet a qualquer cliente conectado em nossa aplicação.

PROPRIEDADE

VALOR

DataSet

SQLClientes

Name

DataSetProvider1

Antes de compilar, vamos definir o diretório para geração do nosso WebService. Através das opções Project/Options.../Directories_Conditionals, configure a opção Output Directory, apontando para o seu diretório cgi-bin (figura 13.59).

Page 368: Delphi 7 Internet e Banco de Dados - Facunte

368 Delphi 7 – Internet e Banco de Dados

Figura 13.59 Configuração do diretório

Grave e compile a aplicação. Agora vamos construir nossa aplicação Client. Através das opções File/New Application crie uma nova aplicação e grave os arquivos como segue:

Unit un_teste_ws4.PAS Projeto teste_ws4.DPR

Agora insira um objeto do tipo TSOAPConnection e altere as propriedades que seguem:

PROPRIEDADE

VALOR

URL

http://localhost/cgi-bin/ ws4.exe/soap/Iws4dm

Name

SOAPConnection1

Connected

True

Perceba que estamos utilizando o método SOAP do nosso WebService. Agora, insira um objeto do tipo TClientDataSet e altere as seguintes propriedades.

PROPRIEDADE

VALOR

RemoteServer

SoapConnection1

ProviderName

DataSetProvider1

Active

True

Através do duplo-clique no objeto ClientDataSet1, insira os campos, como ilustra a figura 13.60.

Page 369: Delphi 7 Internet e Banco de Dados - Facunte

WebServices 369

Figura 13.60 Campos do ClientDataSet1

Agora, selecione todos os campos e arraste para o formulário, dimensionando como sugere a figura 13.61.

Figura 13.61 Formulário exemplo

Com a propriedade Active do ClientDataSet1 configurada como True, execute a aplicação e veja o resultado (figura 13.62).

Figura 13.62 Aplicação em execução

Amigos, com isso concluímos nosso capítulo de WebServices.

Page 370: Delphi 7 Internet e Banco de Dados - Facunte

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;

Page 371: Delphi 7 Internet e Banco de Dados - Facunte

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.

Page 372: Delphi 7 Internet e Banco de Dados - Facunte

372 Delphi 7 – Internet e Banco de Dados

Anotações de Dúvidas

Preciso Revisar Anotações Gerais

?

!