the club - megazine · primeiros passos com android editorial halloween ou dia das outubro é o...

32
novembro 2011

Upload: others

Post on 14-Oct-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 2011

Page 2: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 2011

Page 3: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 2011 03

Desafio The Club

- Dicas Delphi

Dicas

- Cruzada

30

Delphi Delphi

DelphiDelphi

Métodos RAVReport - de A a Z - parte 3

Comunicado:

Seguindo nossa tradição, o The Club estará em recesso do dia 19 de dezembro de 2011 a 30 de dezembro de 2011.

índicePrimeiros passos com Android

Editorial

13Outubro é o mês em que celebramos o

Halloween ou dia das bruxas. Para quem trabalha com progra-mação, não é raro se deparar ... 04

Criando uma aplicação Client-server no Delphi - Parte 1 05

Utilizando API do Google Maps em aplicações Delphi 17

28

22

LegendaInicianteIntermediárioAvançado

Autor:Thiago Cavalheiro Montebugnoli

Autor: Eduardo Massud

Autor:Luciano Pimenta

Autor: Leonora Golin

Page 4: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 201104

Bem-vindo

Delphi é marca registrada da Borland International, as demais marcas citadas são registradas

pelos seus respectivos proprietários.

Antonio Spitaleri Neto - Editor [email protected]

A plataforma Android vem, no decorrer do último ano, fir-mando seu lugar entre S.O’s para dispositivos móveis e se tornou um grande concorrente para as plataformas Black-Berry e Windows Phone.

Claro que nós do The Club não podíamos perder o “bonde” dos acontecimentos, e por isso esse mês trazemos um artigo de nosso colaborador Thiago Montebugnoli mostrando como iniciamos na programação para a plataforma Android no artigo “Primeiros passos com Android”.

Aplicações Cliente Servidor são ainda hoje foco de muita curiosi-dade por parte da comunidade Delphi. Por isso trazemos novamente esse assunto para um breve “review”, no artigo de nosso colaborador Luciano Pimenta: “Criando uma aplicação Client-Server no Delphi”.

Nosso consultor Eduardo Massud nos traz em seu artigo: “Utilizando a API do Gogle Maps em Aplicações Delphi”, como podemos integrar a fantástica ferramenta do Google para geração de mapas em nossas aplicações.

Para finalizar, Leonora Golin segue nos mostrando em detalhes os métodos do Rave Reports na terceira parte do artigo “Métodos Rave Report de A a Z”.

Por enquanto é isso. Um grande novembro a todos e até dezembro !

Av. Profº Celso Ferreira da Silva, 190 Jd. Europa - Avaré - SP - CEP 18.707-150

Informações e Suporte: (14) 3732-1529

Internethttp://www.theclub.com.br

Cadastro: [email protected]: [email protected] Informações: [email protected] Cadastro: theclub_cadastro

Skype Suporte: theclub_linha1 theclub_linha2 theclub_linha3

www.twitter.com/theclubbr

Copyright The Club Megazine 2009

Diretor TécnicoMarcos César Silva

Diagramação e ArteVitor M. Rodrigues

RevisãoEliziane Valentim

ColunistasAntonio Spitaleri Neto

Bruno AlcarásEduardo Massud

Leonora GolinLuciano Pimenta

Thiago Cavalheiro Montebugnoli

Impressão e acabamento:GRIL - Gráfica e Editora

Taquarituba-SP - Tel. (14) 3762-1345

ReproduçãoA utilização, reprodução, apropriação, armazenamento em banco de dados, sob qualquer forma ou meio, de textos, fotos e outras criações intelectuais em cada publicação da revista “The Club Megazine” são terminantemente proibidos sem autorização escrita dos titulares dos direitos autorais.

Page 5: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 2011 05

Delphi

Delphi sempre teve a facilidade de criar aplicações rápidas e de forma muito dinâmica. Basta arrastar alguns componentes e temos uma aplicação com um cadastro, seja para arquivos XML como para banco de dados.

Nesse artigo, quero mostrar uma série para criarmos um aplicativo base para que você leitor, possa iniciar ou completar seus projetos com as dicas que serão apresenta-das aqui.

Quero deixar claro que não vou fazer uma aplicação comercial, nem tão pouco sou o dono da verdade, a aplicação mostrada aqui, serve como base para a criação de aplicações client-server com dicas de boas práticas. Você pode mudar os conceitos ou se tiver um projeto parecido verá que conceitos e regras podem ser diferentes, portanto não se apegue há isso.

Criaremos uma aplicação para uma oficina de carros, onde teremos cadastro de clientes, carros, orçamentos, ordem de serviço, peças etc. Nossa aplicação funcionará

Criando uma aplicação client-server no Delphi Parte I

da seguinte maneira: o cliente chega para arrumar o carro, caso ele não seja cadastrado, será feito o cadastro do cliente e carro.

Será criado um orçamento para o serviço. Assim que o cliente confirmar o orçamento, será criada uma ordem de serviço, baseada nesse orçamento. No orçamento, não iremos descrever peças ou serviços. Já na ordem de serviço teremos a especificação dos serviços e peças trocadas.

Teremos ainda relatórios de orçamento, OS e peças etc. Caso você deseje, pode imple-mentar mais funcionalidades como controle de estoque, financeiro entre outros módulos. Como já frisei, o projeto quer dar uma base para criação de aplicações client-server.

Para deixar nosso projeto ainda mais in-teressante, tentaremos criar uma classe para ser a responsável pela execução de inserções, atualizações do cadastro. Um conjunto de métodos e funções que irão nos ajudar no desenvolver do projeto.

Usaremos controles para selecionar os dados do banco e classe para inserir e atualizar dados. Não é mais fácil apenas usar componentes, você pode ser perguntar? Sim, respondo, mas quero deixar uma idéia pra você entender o funcionamento de classes e quem sabe criar seu próprio “framework” para persistência de dados, por exemplo.

Banco de dados

Quando analisamos a criação de um projeto cliente-server o primeiro pensamento recai sobre o banco de dados e várias dúvidas surgem: qual o banco usar? As regras de negócio devem ser colo-cadas no banco? Usar Stored Procedures? banco free ou banco pago?

Bom, quero deixar claro que cada caso é um caso. No nosso projeto usarei o SQL Express (versão gratuita), mas fique a vontade para usar Firebird, MySQL etc. Afinal, o Delphi tem driver para a maioria dos bancos .

Page 6: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 201106

Com a tecnologia dbExpress, podemos co-nectar com SQL Server, Firebird, Oracle e muitos outros sistemas gerenciadores de banco de dados. Caso deseje, você pode usar outra tecnologia de banco de dados, além do banco de dados de sua preferência.

Você pode baixar a versão gratuita do SQL Server no seguinte link: www.microsoft.com/sqlserver/en/us/editions/express.aspx. Indico que baixe a versão que acompanha o SQL Server Management Studio (with Tools), ferramenta de manipulação de objetos do SQL Server.

Veja na Figura 1 a ferramenta.

Note que para conectar ao SQL Express, você deve nomear a instância do mesmo (EXPRESS). Para criar um banco, clique com o botão direito em Databases e escolha New Database. Dê um nome para o banco: “SysCar” e clique em OK. Na Listagem 1, temos o script de criação das tabelas do nosso projeto.

Listagem 1. Script de criação das tabelas

CREATE TABLE CLIENTE( nCdCliente int not null primary key identity, sNmCliente varchar(50) not null, sNrDocumento varchar(11) )

CREATE TABLE VEICULO( nCdVeiculo int not null primary key identity, nCdCliente int not null, sNmModelo varchar(50) not null, nNrAnoModelo int not null, nNrAnoFabricacao int not null, sNrPlaca char(8) not null, sNrChassi varchar(30))

ALTER TABLE VEICULO

Figura 1. Ferramenta para manipular objetos do SQL Server

ADD CONSTRAINT FK_VEICULO_CLIENTE FOREIGN KEY(nCdCliente)REFERENCES CLIENTE (nCdCliente)

CREATE TABLE PECA( nCdPeca int not null primary key identity, sNmPeca varchar(50) not null, nIdTipo int not null, --1: peça 2: serviço nVlPeca numeric(9,2) not null)

CREATE TABLE ORCAMENTO( nCdOrcamento int not null primary key identity, nCdVeiculo int not null, sNmCliente varchar(50) not null, tDtOrcamento datetime not null, sDsProblema varchar(max), sDsParecer varchar(max),

nIdStatus int not null --1: aberto, 2: cancelado, 3: autorizado)

ALTER TABLE ORCAMENTO ADD CONSTRAINT FK_ORCAMENTO_VEICULO FOREIGN KEY(nCdVeiculo)REFERENCES VEICULO (nCdVeiculo)

CREATE TABLE OS( nCdOrdem int not null primary key identity, nCdVeiculo int not null, nCdOrcamento int null, tDtOrdem datetime not null, sDsObservacoes varchar(max) )

ALTER TABLE OS ADD CONSTRAINT FK_OS_VEICULO FOREIGN KEY(nCdVeiculo)REFERENCES VEICULO (nCdVeiculo)

Page 7: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 2011 07

CREATE TABLE OS_DETALHE( nCdOrdem int not null, nCdPeca int not null, nQtPeca numeric(9,2) not null, nVlUnitario numeric(9,2) not null)

ALTER TABLE OS_DETALHE ADD CONSTRAINT FK_OS_PECA FOREIGN KEY(nCdPeca)REFERENCES PECA (nCdPeca)

ALTER TABLE OS_DETALHE ADD CONSTRAINT FK_OS_ORDEM FOREIGN KEY(nCdOrdem)REFERENCES OS (nCdOrdem)

Veja na Figura 2 o relacionamento entre as tabelas do banco.

Note que os relacionamentos são simples, onde temos estruturas para o VEICULO ter um CLIENTE (proprietário). No orçamento temos o VEICULO vinculado. Você deve ter notado algo diferente na tabela ORCAMENTO, onde temos o nome do cliente.

Por que temos isso? Simples, para fins de histórico. Imaginamos que o veículo pode trocar de cliente, mas continuar sendo consertado na oficina. Assim, utilizamos a tabela ORCAMENTO para tê-la como histórico dos serviços realizados no veiculo e saber os clientes que vieram a oficina usar nossos serviços.

Salvando o nome do cliente, temos o histórico dos clientes que possuíam o referido veiculo. Na tabela PECA temos um tipo para indicar se é uma peça ou um serviço. No ORCAMENTO temos o sta-tus que pode ser: aberto, cancelado ou autorizado.

Quando o orçamento estiver como autorizado, ele não aparecerá mais na pesquisa de orçamento e estará disponível para ser aberto pela ordem de serviço. Ou seja, o campo servirá para filtragem de dados nas pesquisas.

Herança visual de formulários

Crie um novo projeto no Delphi. Vamos criar

Figura 2. Diagrama do banco de dados

nosso formulário base da aplicação. Uma das teclas que sempre bati no desenvolvimento, foi na parte de produtividade e não poderia deixar de falar em produtividade, sem falar em herança visual.

Imagine um projeto de médio a grande porte, onde a quantidade de formulários de cadastro, seja em um número grande. Imagine agora, que a maioria desses formulários possua características muitas semelhantes, como os botões de Salvar, Incluir, Excluir, Pesquisar etc.

O trabalho de criar cada um desses formulá-rios, nem gostaria de imaginar ou calcular. Então, o Delphi possui uma vantagem presente desde a versão 1, a herança visual. Precisamos criar um for-

mulário base com características comuns (botões, imagens etc.) de cadastro e criar um formulário descendente.

Nesse formulário criado, vamos adicionar as características do cadastro, como as caixas de textos, validações etc. Precisamos trabalhar o mais genérico possível, para que possamos colocar no formulário base a maior quantidade de código possível.

Assim, no formulário herdado, vamos apenas implementar as características do cadastro (nome dos campos daquele cadastro etc). Vamos a um exemplo, veja na Figura 3 um formulário de cadas-tro para ser base.

Figura 3. Formulário base de cadastro

Page 8: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 201108

Como você pode notar, nosso formulário possui uma aba de cadastro e outro de pesquisa. Por que isso? Quando o usuário entrar na tela, os dados não serão carregados, nosso cadastro será parametrizado para fins de performance.

Assim, o usuário entra na tela, pesquisa o registro que deseja modificar e o tráfego na rede é o menor possível, viabilizando nosso projeto client-server ser o mais correto.

Voltando ao formulário de cadastro base, imagine que teremos um código que deve ser executado em todos os formulários de cadastro, como, por exemplo, o botão Fechar, clicando em um menu/botão ou usando a tecla ESC. Se não usássemos herança, teríamos que implementar a chamada ao método Close do formulário, em todos os controles e no evento correspondente ao ESC.

Isso seria muita duplicação de código e perda de tempo. Com o formulário base, vamos imple-mentar isso no mesmo e quando herdarmos um formulário baseado no base, o código também será herdado, não precisando ser implementado novamente.

Esse é um exemplo simples, mas imagine a seguinte situação: preciso implementar um fun-cionalidade de permissões/restrições do usuário na aplicação. Esse tipo de funcionalidade depende muito do que o cliente precisa, mas de maneira genérica é bem fácil de implementar.

Veja na Listagem 2 os principais métodos do formulário base para que possamos entender o seu funcionamento.

Listagem 2. Métodos do formulário base da aplicação

procedure HabilitarControles(bValor: boolean);var i: integer;begin {: faz um laço em todos os componentes} for i := 0 to ComponentCount -1 do begin if (Components[i] is TCustomEdit) then (Components[i] as TCustomEdit).Enabled := bValor;

if (Components[i] is TBitBtn) then (Components[i] as TBitBtn).Enabled := bValor; end; btnNovo.Enabled := True; edtPesquisa.Enabled := True;end;

function CamposObrigatorios (DataSource: TDataSource): boolean;var i: integer; {: verifica quais os campos que estão em branco no cadastro}begin Result := True; for i := 0 to DataSource.DataSet.FieldCount - 1 do begin if DataSource.DataSet.Fields[i].Required then if (DataSource.DataSet.Fields[i].IsNull) or (DataSource.DataSet.Fields[i].AsString = ‘’) then begin MessageDlg(‘Campo: “ ‘+ DataSource.DataSet.Fields[i].DisplayLabel + ‘”. Preenchimento obrigatório.’, mtWarning,[mbOk], 0); Result := False; DataSource.DataSet.Fields[i].FocusControl; break; end; end;end;

procedure btnSalvarClick(Sender: TObject);begin {: salvo as dados se os campos estiverem preenchidos} if CamposObrigatorios (dsCadastro) and (dsCadastro.State in [dsEdit, dsInsert]) then dsCadastro.DataSet.

Post;end;

procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);begin {: verifica se esta em modo de edição ou inserção} if dsCadastro.State in [dsEdit,dsInsert] then case MessageDlg(‘Deseja salvar as alterações?’, mtConfirmation, [mbYes,mbNo,mbCancel], 0) of mrYes : begin dsCadastro.DataSet.Post; CanClose := True; end; mrNo : begin dsCadastro.DataSet.Cancel; CanClose := True; end; mrCancel : CanClose := False; end;end;

procedure dsCadastroDataChange (Sender: TObject; Field: TField);begin {: verifica o estado do DataSource para mostrar na barra } case dsCadastro.State of dsEdit: StatusBar1.Panels[1].Text := ‘Alterando’; dsInsert: StatusBar1.Panels[1].Text := ‘Inserindo’; dsBrowse: StatusBar1.Panels[1].Text := ‘Navegando’; end; HabilitarControles(not dsCadastro.DataSet.IsEmpty); {: habilita os botões de acordo com o estado do DataSource }

Page 9: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 2011 09

btnSalvar.Enabled := dsCadastro.State in [dsEdit, dsInsert]; btnExcluir.Enabled := dsCadastro.State in [dsEdit];end;

procedure Pesquisar;begin {: pesquisa o registro } dsPesquisa.DataSet.Close; (dsPesquisa.DataSet as TClientDataSet).Params[0].AsString := UpperCase(‘%’ + edtPesquisa.Text + ‘%’); dsPesquisa.DataSet.Open;end;

procedure DBGrid1DblClick(Sender: TObject);begin {: filtra os dados e mostra a aba de dados cadastrais } dsCadastro.DataSet.Close; (dsCadastro.DataSet as TClientDataSet).Params[0].AsInteger := dsPesquisa.DataSet.Fields[0].AsInteger; dsCadastro.DataSet.Open;

if (dsCadastro.DataSet.RecordCount > 0) then PageControl1.ActivePage := tabDados;end;

Primeiro, o método HabilitarControles, percor-re os controles de tela e verifica o tipo do controle. Para os tipos TCustomEdit e TBitBtn, indicamos na propriedade Enabled o valor do parâmetro do mé-todo. Caso tenhamos outros tipos de componentes, basta colocar nesse método.

No final, sempre deixamos habilitado o botão de inserção do registro e a caixa de texto para pesquisa. Já a função CamposObrigatorios percorre os campos do cadastro e verifica quais estão com a propriedade Required esteja como True e estejam sem o preenchimento. Assim, emitimos uma men-sagem para que o campo é obrigatório.

Essa propriedade esta presente no DataSet

(que no nosso caso será um ClientDataSet) vincu-lado ao DataSource do cadastro.

No salvar do cadastro, verificamos a função anterior e se o DataSource esta como edição ou inserção, para assim, chamarmos o Post para salvar o registro atual. Ao fecharmos o formulário, o even-to FormCloseQuery é chamado, assim, podemos verificar se o usuário fez alterações e ainda não salvou as mesmas.

Nas opções apresentadas, podemos salvar, cancelar as alterações ou cancelar o fechamento do formulário. Por fim, no evento DataChange do DataSource verificamos o “estado” do controle e mostramos uma mensagem na barra de status.

O método Pesquisar, repassa pro ClientDataSet o valor digitado na caixa de texto disponibilizada na aba Pesquisar. Vale lembrar que nosso comando SQL estará nos ClientDataSets, portanto temos que ter uma padronização.

Veja que em nenhum momento fizemos indi-cação do componente (ClientDataSet) que terá os dados do cadastro ou de pesquisa. Isso é abstração. Não sabemos quem será o controle indicado, mas temos a propriedade DataSet do DataSource que nos fornecemos as “informações” que queremos. Assim, nosso formulário de cadastro pode ser usa-do em qualquer projeto que queremos.

Por fim, no duplo clique no DBGrid, filtramos os dados do cadastro com o valor escolhido no Grid. Também aqui vale a indicação da padronização que usaremos. Note que indicamos o primeiro “campo” do componente de pesquisa, portanto o primeiro na consulta SQL do componente de pesquisa deve ser o chave da tabela do cadastro.

A seguir, criaremos um cadastro, onde as dúvi-das que tenham ficado até aqui, serão respondidas.

Entendendo as “regras”Para entender o funcionamento do nosso

cadastro. Teremos um DataModule que terá um SQLConnection, responsável pela conexão com o banco de dados, um SQLDataSet, nesse nosso exemplo, responsável por trazer os dados do banco e um DataSetProvider, que será a “ponte” entre o SQLDataSet e o ClientDataSet, que “mostrará” os dados do cadastro.

No próprio componente, indicaremos o SQL para retornar os dados do cadastro, assim como os dados da pesquisa. Precisamos configurar os componentes para que retorne os campos que desejamos (inclusive joins) e as respectivas pro-priedades dos campos (por exemplo, para campos obrigatórios).

Continuo frisando, estamos utilizando essa padronização apenas para fins didáticos. Ela não é a mais pura verdade, você pode tomar por base os conceitos que apresentarei aqui e implementar partes em seu projeto para que atenda as suas necessidades.

Crie um DataModule. No Data Explorer, vamos criar a conexão com o banco de dados. Clique com o botão direito no item MSSQL e escolha Add New Connection. Dê o nome para a conexão de “SysCar”.

Na conexão criada, clique com o botão direito e escolha Modify Connection. Na Figura 4 veja as configurações que devem ser colocadas.

Figura 4. Configurações da conexão com o banco de dados

Page 10: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 201110

Clique no Advanced e configure a propriedade os authentication para true. Essa configuração vale apenas para a autenticação integrada do Windows com o SQL Server. Caso contrário, utilize o User Name e Passaword da Figura 4.

Para testar a conexão, use o Test Connection. Após concluído esse passo, basta arrastar o item do DataExplorer para o DataModule. Será adicionado um SQLConnection com a configuração do banco. Adicione no DataModule um SQLDataSet e confi-gure a propriedade SQLConnection para SysCar.

Adicione um DataSetProvider e configure a propriedade DataSet para o SQLDataSet adiciona-do anteriormente. Altere para True a propriedade Options>poAllowCommandText. Essa propriedade indica que os comandos SQLs estarão na proprie-dade CommandText do ClientDataSet.

Figura 5. DataModule criado na aplicação

Adicione dois ClientDataSets no container, um chamado “cdsCliente” e outro chamado “cdsClien-tePesquisa”. Aponte ambos para o DataSetProvider para prover as consultas e exibição dos dados.

Criando o primeiro cadastro

Caso você esteja confuso, agora criaremos nosso primeiro cadastro, e acredito que será mais fácil entender as regras. Crie um novo formulário, através do menu File>New>Other. Escolha no item Inheritable Items o nome do nosso formulário base (Figura 6).

Veja a figura 6.

Note que foi criado um formulário igual ao de cadastro, mas podemos mudar suas configura-ções. Apenas não podemos retirar componentes. Configure os DataSources para “apontarem” os ClientDataSets do DataModule.

Configure o ClientDataSet do cadastro para re-tornar os dados da tabela CLIENTE filtrando o mes-mo pelo código do cliente, ou seja, parametrizado:

Figura 6. Criando um formulário herdado do formulário base de cadastro

select * from CLIENTE where nCdCliente = :CLIENTE

Para o componente de pesquisa, apenas retorne o código e a descrição do cliente, como no código SQL:

select nCdCliente, sNmCliente from CLIENTE where UPPER(sNmCliente) like :NOME

Veja que temos uma padronização aqui. Retor-namos sempre o código e um campo de descrição, nessa ordem. Além disse, usamos o UPPER para comparar os valores em maiúsculo, para evitar que valores iguais com digitações diferentes, fiquem de fora da pesquisa.

Você deve configurar os parâmetros dos Clien-tDataSets. Adicione os Fields no ClientDataSet e configure o formulário com os campos e também na tela de pesquisa. Nosso cadastro esta pronto, faltando apenas a parte de salvar/excluir dados no banco.

Faça um teste, adicione valores pelo banco e faça a pesquisa de clientes pela aba Pesquisar. Escolha um registro e dê um duplo clique para que o registro seja aberto na aba Dados Cadastrais

(Figura 7).

Veja a figura 7.

Veja que em alguns cliques, arrastar e soltar, temos um cadastro funcional. Se analisarmos bem o projeto e implementarmos corretamente as ne-cessidades, temos um projeto cliente-server bem projetado e com muita qualidade.

Biblioteca de função

Implementar métodos e funções corretas, faz parte da premissa de todo bom programador. Mas e aqueles códigos que são repetitivos e são usados em vários locais da nossa aplicação, como evitar duplicação de código e retrabalho?

Simples, usando uma Lib (biblioteca). Vamos colocar no nosso projeto um arquivo (unit), com métodos e funções comuns a serem usadas em nosso projeto, assim economizamos código e centralizamos os métodos e funções em apenas um local.

Observação: Alguns códigos mostra-dos a seguir foram coletados da internet e sofreram alguma modificação. Não tenho o nome do autor para adicionar os devidos créditos aos mesmos.

Veja na Listagem 3, alguns métodos a serem

Page 11: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 2011 11

usados (existem mais na unit disponibilizada com os fontes).

Listagem 3. Lib da aplicação

procedure AbreForm(aClasseForm: TComponentClass; aForm: TForm);begin {: método para abrir formulários } Application.CreateForm(aClasseForm, aForm); try aForm.ShowModal; finally aForm.Free; end;end;

procedure ZebrarGrid(aGrid: TDBGrid; Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);begin if odd(aGrid.DataSource.DataSet.RecNo) then begin aGrid.Canvas.Font.Color:= clBlack; aGrid.Canvas.Brush.Color:= clScrollBar; end else begin aGrid.Canvas.Font.Color:= clBlack; aGrid.Canvas.Brush.Color:= clWhite; end; aGrid.Canvas.FillRect(Rect); aGrid.Canvas.TextOut(Rect.Left+2, Rect.Top, Column.Field.AsString);end;

function Busca (Busca, Text: string): Boolean;begin

Figura 7. Cadastro de clientes com pesquisa

{: Pesquisa um caractere na string, retornando se achou} Result := (Pos(Busca, Text) > 0);end;

function GeraSenha (aQuant: integer): string;var i: integer;const str = ‘1234567890ABCDEFGHIJKLMNOP QRSTUVWXYZ abcdefghijklmno pqrstuvwxyz’;begin for i:= 1 to aQuant do begin Randomize; Result := Result + str[Random(Length(str))+1]; end;end;

function DateValidate(const aData: string): boolean;begin try StrToDate(aData); Result := True; except

Result := False; end;end;

function ValidaCGC(num: string): boolean;var n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12: integer; d1,d2: integer; digitado, calculado: string;begin n1 := StrToInt(num[1]); n2 := StrToInt(num[2]); n3 := StrToInt(num[3]); n4 := StrToInt(num[4]); n5 := StrToInt(num[5]); n6 := StrToInt(num[6]); n7 := StrToInt(num[7]); n8 := StrToInt(num[8]); n9 := StrToInt(num[9]); n10 := StrToInt(num[10]); n11 := StrToInt(num[11]); n12 := StrToInt(num[12]); d1 :=n12*2+n11*3+n10*4+n9*5+n8*6+n7*7+n6*8+n5*9+n4*2+n3*3+n2*4+n1*5; d1 := 11-(d1 mod 11); if d1>=10 then

Page 12: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 201112

d1 := 0; d2 := d1*2+n12*3+n11*4+n10*5+n9*6+n8*7+n7*8+n6*9+n5*2+n4*3+n3*4+n2*5+n1*6; d2 := 11-(d2 mod 11); if d2>=10 then d2 := 0; calculado := IntToStr(d1) + IntToStr(d2); digitado := num[13]+num[14]; Result := (calculado = digitado);end;

function ValidaCPF(num: string): boolean;var n1,n2,n3,n4,n5,n6,n7,n8,n9: integer; d1,d2: integer; digitado, calculado: string;begin n1 := StrToInt(num[1]); n2 := StrToInt(num[2]); n3 := StrToInt(num[3]); n4 := StrToInt(num[4]); n5 := StrToInt(num[5]); n6 := StrToInt(num[6]); n7 := StrToInt(num[7]); n8 := StrToInt(num[8]); n9 := StrToInt(num[9]); d1 := n9*2+n8*3+n7*4+n6*5+n5*6+n4*7+n3*8+n2*9

+n1*10; d1 := 11-(d1 mod 11); if d1>=10 then d1 := 0; d2 := d1*2+n9*3+n8*4+n7*5+n6*6+n5*7+n4*8+n3*9+n2*10+n1*11; d2 := 11-(d2 mod 11); if d2>=10 then d2 := 0; calculado := IntToStr(d1) + IntToStr(d2); digitado := num[10]+num[11]; Result := (calculado = digitado);end;

function RemoveAcento(Str: string): string;const ComAcento = ‘àâêôûãõáéíóúç üÀÂÊÔÛÃÕÁÉÍÓÚÇÜ’; SemAcento = ‘aaeouaoaeioucu AAEOUAOAEIOUCU’;var x: integer;begin for x := 1 to Length(Str) do if Pos(Str[x],ComAcento)<>0 then

É Técnico em Processamento de Dados, desenvolvedor Delphi/C# para aplicações Web com ASP.NET e Windows com Win32 e Windows Forms. Palestrante da 4ª edição da Borland Conference (BorCon).

Autor de mais de 60 artigos e de mais de 300 vídeos aulas publicadas em revistas e sites especializados. É consultor da FP2 Tecnologia (www.fp2.com.br) onde ministra cursos de programação e banco de dados. É desenvolvedor da Paradigma Web Bussi-ness em Florianópolis-SC.

Sobre o autor

Luciano Pimenta

www.lucianopimenta.net

Str[x] := SemAcento[Pos(Str[x],ComAcento)]; Result := Str;end;

Os códigos são simples, mas muito úteis no dia a dia do desenvolver, como o que se encarrega de abrir o formulário passado como parâmetro. Pouparemos muitas linhas de código. Temos uma função para gerar senhas aleatórios, para “zebrar” um DBGrid (coloquei aqui, pois você pode querer zebrar todos os controles da aplicação), para a busca de um caractere dentro de uma string.

Temos também as funções “clássicas” para vali-dar números de CPF e CGC e para remover acentos de strings. No fonte que acompanha o artigo temos mais métodos e funções.

Conclusões

Iniciamos nesse artigo uma série para criação de aplicações client-serve no Delphi. Estamos criando uma aplicação parametrizada e com as facilidades que a POO permite, como herança, abstração, classes etc.

No próximo artigo iremos aprofundar mais nosso projeto, mostrando uma classe que fará a parte de manipulação dos dados, como inserção, exclusão e atualização. Um grande abraço a todos e até a próxima!

Page 13: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 2011 13

O que é Android?

Em poucas palavras, Android seria o Sistema Operacional que roda dentro dos celulares, tablets, netbooks. É um sistema que roda em cima do Kernel Linux e tem como objetivo ser uma plataforma flexível, aberta e de fácil migração para os fabricantes. Utiliza a linguagem Java para desenvolvimen-to, controlando o dispositivo via bibliotecas desenvolvidas pela Google.

Uma breve descrição da linguagem Java

A principal característica da linguagem Java é que os programas desenvolvidos por ela pode ser executado virtualmente em qualquer plataforma, principalmente em Windows, Linux e Mac. Signi-fica que o Java é ideal para expressar idéias em forma de programas universalmente aceitos, ou seja, não é apenas o código fonte que pode ser compartilhado, mas o próprio código executável

Primeiros Passos com o Android

denominado Bytecodes.

Esses Bytecodes não podem ser executados diretamente pelo sistema operacional em questão, daí a necessidade de uma máquina virtual, que é quem realmente executa o código binário resul-tante, inserindo uma camada de abstração entre o programa sendo executado e o sistema opera-cional, permitindo que o código se torne portátil.

Programas necessários

Vimos que para executar um programa são necessários dois passos básicos: A Compilação, que transforma o código fonte em bytecodes e a Interpretação pela máquina virtual.

Neste momento iremos baixar e instalar os programas necessários para podermos trabalhar com o Sistema Android. Vejamos a seguir com maiores detalhes:

JDK – Java Development Kit

O JDK possui as ferramentas necessárias para desenvolvimento de aplicações utilizando a lingua-gem Java. Constitui um conjunto de programas que engloba compilador, interpretador e utilitários em geral. Fornece um pacote de ferramentas básicas para o desenvolvimento de aplicações Java.

Segue a seguir o link para realizar o download deste kit, Ver Figura 01.

http://www.oracle.com/technetwork/java/javase/downloads/index.html

No nosso caso específico iremos fazer o download do JDK para Windows x86. A instalação do mesmo é simples, é o clássico next, next, next, install.

Android SDK – Software Development Kit

Com este Kit de ferramentas podemos criar diversas aplicações para plataformas do sistema Android. Este Kit permite que os desenvolvedores elaborem as aplicações para os aparelhos que

Page 14: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 201114

utilizam este sistema operacional.

Segue a seguir o link para realizar o download do mesmo, Ver Figura 01.

http://developer.android.com/sdk/index.html

No caso deste exemplo baixaremos a segunda versão para Windows, com o executável incluso, com o nome de “installer_r15-windows.exe”.

A instalação do mesmo não há segredos, no final aparecerá uma tela parecida com a da Figura 02. Nesta parte da instalação é exibido os pacotes que faltam ser instalados, no nosso caso temos apenas 6 pacotes. Portanto, clique no botão “Install 6 Packages...”

Veja a figura 02.

A Figura 03 aparece uma lista de itens para serem instalados. Clique em “Accept All” para acei-tar todos e prosseguirmos com nossa instalação.

Atenção: A Atualização pode demorar um pouco, isto depende da velocidade da conexão da internet utilizada.

Figura 03: Instalação dos Pacotes.

Eclipse

O Eclipse é uma IDE para desenvolvimento de programas em Java ou Andoird. É uma ferramenta poderosa que nos possibilita explorar facilmente as tarefas desejadas. O mais interessante é que o Eclipse é mantido por uma comunidade Open Source.

Segue a seguir o link para realizar o download desta ferramenta,.

http://www.eclipse.org/downloads/

Neste caso faremos o download do “Eclipse IDE for Java Developers”. Após o término do do-wnload extraia o conteúdo do arquivo para o local desejado, notem que não é necessário instalação,

Figura 01: Download do Android SDK.

Figura 02: Carregando os pacotes.

pois os arquivos rodam direto da pasta onde foram descompactados. Fica a dica criar apenas um atalho para o executável “eclipse.exe”.

O primeiro passo a fazer quando é iniciado o Eclipse seria configurar o ADT Plugin. Este é neces-sário para que possamos trabalhar com o sistema Android, para isto clique no menu “Help” e logo em seguida em “Install New Software”. Clique no botão “Add” e preencha com os seguintes dados:

Name: ADT Plugin

Location: https://dl-ssl.google.com/android/

eclipse/

Figura 04: Instalação do ADT Plugin.

Após clicar no botão “OK” selecione “Develo-per Tool e avance. O próximo passo irá aparecer uma lista de ferramentas que serão baixadas. Avance e logo após o término clique em Finalizar e reinicie o Eclipse.

Page 15: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 2011 15

Figura 05: Configurações Finais.

Figura 06: Android SDK and AVD Manager.

Figura 08: Criando um novo Projeto.

O último passo seria alterar as configurações no Eclipse para que aponte para a pasta de insta-lação do SDK Android, para isto acesse o Menu “Windows” e em “Preferences” localize o item “Android”. No botão “Browse...” indique o caminho correto. Finalmente temos tudo configurado para que nosso exemplo funcione corretamente. Ver Figura 08.

Veja a figura 05.

Para que funcione nosso exemplo devemos criar um Dispositivo Virtual para que possamos rodar a aplicação. Um dispositivo virtual nada mais é que um emulador.

Na região superior do eclipse escolha o item “Opens the Android SDK and AVD Manager” para criarmos nossa máquina virtual clicando no botão “New”.

Ver Figura 06.

A etapa seguinte podemos conferir na Figura 07.

Figura 07: Criando um Dispositivo Virtual.

Name: Android_2_2Size: 512

Finalizamos clicando no botão “Create AVD”. Prontinho, temos um dispositivo Virtual configu-rado para executar programas feitos para Android.

Criando um exemplo

O primeiro passo seria criar um novo Projeto,

para isto clique em File/New Project. Logo em seguida escolha “Android Project”. Preencheremos com os seguintes dados, ver Figura 08.

Em “Name” deixe como Android_Example. Na opção Contents deixaremos como “Create new Pro-ject in Workspace”, em Build Target trabalharemos com a versão 2.2 do Android.

Em propriedades deixamos como:

Application name: Android_Example

Package name: Android.Android_Example

Ativity: Android_ExampleActivity

Min SDK Version: 8

Veremos em Package Explorer que nosso pro-jeto foi criado. Clique na aba “res” em “layout” e logo em seguida no “main.xml”. Neste momento estamos vendo nossa tela do Android. O Eclipse nos possibilita muitos recursos para trabalhar, o que nos proporciona uma facilidade para se de-senvolver aplicações. Ver Figura 09.

Page 16: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 201116

Figura 09: IDE de desenvolvimento.

Thiago Cavalheiro Montebugnoli é tecnólogo, formado pela Faculdade de Tecnologia de Botucatu – SP (FATEC) foi consultor técnico do The Club, já desenvolveu softwares utilizando a plataforma .NET, Delphi junto com Banco de Dados SQL Server e Firebird. Atualmente trabalha no Centro de Proces-samento de Dados da Prefeitura Municipal de Itaí-SP. Possui as seguintes certificações: MCP - Microsoft Certified Professional, MCTS - Microsoft Certi-fied Technology Specialist, MCAD - Microsoft Certified Application Developer e MCSD - Microsoft Certified Solution Developer.

Sobre o autor

Thiago Cavalheiro Montebugnoli

[email protected]

Veja a figura 09.

Dê um clique na guia main.xml, agora você poderá ver o código XML de nossa aplicação, vá na linha android:text=”@string/hello” e modifique o “@string/hello” pelo texto que você quer que seja escrito na tela.

Depois disso, salve e clique com o botão direito do mouse e vá em “Run As”, selecione “Android Ap-plication” e por final clique em “ok”, será carregada a tela da máquina virtual do Android.

Ver Figura 10.

Conclusões

A intenção deste artigo foi de preparar o am-biente para desenvolver aplicativos para o Sistema Android. Vimos que são muitas configurações e instalações para que possamos trabalhar com o mesmo. No final foi montado um exemplo clássico dos clássicos, o denominado “Hello Word!” ou como queiram chamar. O Java se perpetua como uma linguagem poderosa e flexível no mundo da programação, permitindo escrever programas para praticamente todas as plataformas existentes no mercado.

Abraços e até o mês que vem!

Figura 10: Exemplo em Run-time.

Page 17: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 2011 17

Atualmente tem crescido o número de aplicações pré-projetadas e adaptáveis a qualquer ambiente, que trabalham baseadas com requisição dos dados do servidor, que compõem funções que são somente aces-sadas por programação, sendo conhecidas como API’s, elas disponibilizam uma série de funções, sendo que cada uma compõe uma determinada característica da aplicação, faci-litando a adaptação da aplicação ao ambiente que é definido.

No caso do Google Maps, ela é uma das API’s mais utilizadas no mundo, principal-mente por desenvolvedores para Web, onde facilita o acesso a informações relevantes sobre endereçamento, mantendo sempre a atualização destes dados, pois “terceiri-zamos” o serviço para o Google, por assim dizendo, ou seja, todo conteúdo é retornado de acordo com funções e dados vindos da base dos servidores da Google, que chega aos usuários via Internet.

Utilizando a API do G o o g l e M a p s e m Aplicações Delphi

A grande vantagem das API’s fica por conta da padronização, o que traz menos instabilidade e maior controle na criação, evitando duplicidade de código e facilitando o processo de criação para o desenvolvedor.

Neste artigo veremos como utilizar a API do Google Maps utilizando dentro do Delphi as linguagens de marcação HTML e CSS, e o JavaScript, que é a principal ferramenta de desenvolvimento Web para transferência de informações entre o cliente e o servidor, o que aumenta em muito a resposta às requisições de dados, mas ela pode ser criada em mui-tas outras linguagens que tem suporte para requisição de dados direto do cliente para o servidor, assim como o AJAX e o ActionScript, que voltado para desenvolvedores para apli-cativos baseados em Flash.

Para ver o resultado do artigo utilizare-mos fundamentalmente 3 Edits, 2 Buttons, 2 Checkbox e 1 WebBrowser, que será o respon-sável por exibir a API e seus controladores.

Iniciando a leitura da API

O primeiro passo é criar uma constante que irá armazenar o arquivo HTML

constPagina: String =

Explicando a Estrutura HTML

Para utilizar qualquer API existente precisare-mos fazer com que o Delphi interprete uma página HTML, para isso declaramos uma constante do tipo String que receberá a página HTML, que, a cada linha iniciada e finalizada será incluída uma apóstrofe (‘) e para concatenar utilizamos o sinal de mais (+).

Dentro de nosso formulário HTML, vamos declarar no cabeçalho (<head>) todas as funções que serão utilizadas para exibir e pesquisar os

Page 18: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 201118

endereços no mapa.

‘<html>’+‘ <head>’+

Na Propriedade Script (<script>), declaramos todo(s) o(s) script(s) utilizado(s), neste caso uti-lizaremos 2, um que fará a requisição direto do servidor do Google Maps, habilitando a visualização e consulta à API do aplicativo.

‘ <script type=”text/javascript” src=”http://maps.google.com/maps/api/js?sensor=true”></script>’+

Depois de feita a requisição com o servidor da API vamos configurar os dados pelo JavaScript que está dentro do formulário HTML

‘ <script type=”text/javascript”>’+

Aqui estamos declarando 4variáveis globais do JavaScript que serão utilizadas em várias funções, para pegar o valor do ponto do geocoder, que é o motor do Google Maps, e o mapa que servem para retornar o ponto onde o usuário selecionou na pes-quisa no mapa e as variáveis trafego e ciclista, que servem para habilitar e desabilitar a visualização destes complementos.

‘ var geocoder;’+‘ var mapa;’+‘ var trafego;’+‘ var ciclista;’+

Vamos utilizar uma função chamada de “Inicia-lizando”, que servirá exatamente para instanciar o geocoder, a latitude e longitude, as opções iniciais do mapa, com suas configurações predefinidas ao carregar o mapa, além de também instanciar e jogar nas variáveis as opções que habilitam o modo de visualização do mapa para ciclistas e de tráfego.

‘ function Inicializando(){ ‘+‘ geocoder = new google.maps.Geocoder();’+‘ var latlng = new google.maps.LatLng(-23.088523, -48.923337);’+‘ var myOptions = {‘+‘ zoom: 16, ‘+‘ center: latlng,’+‘ mapTypeId: google.maps.MapTypeId.ROADMAP’+‘ }; ‘+‘ mapa = new google.maps.Map(document.getElementById(“mapa”), myOptions);’+‘ trafego = new google.maps.TrafficLayer();’+‘ ciclista = new google.maps.BicyclingLayer();’+‘ } ‘+

O passo seguinte é criar uma nova função que fará uma requisição à base de dados da API cha-mando o Marcador, que é utilizado como referencia na pesquisa do usuário, para isso faremos com que a função verifique se o geocoder estiver na mesma posição que o endereço solicitado ele instancia um novo componente do marcador na posição onde foi indicada, caso não seja possível ou não encontre a posição ele irá retorna uma mensagem informando o problema de acordo com o status da busca retornada pela API.

‘ function Marcador(address) { ‘+‘ if (geocoder) {‘+‘ geocoder.geocode({‘+‘ address: address’+‘ },’+‘

function(results, status) { ‘+‘ if (status == google.maps.GeocoderStatus.OK) {‘+‘ mapa.setCenter(results[0].geometry.location);’+‘ var marker = new google.maps.Marker({‘+‘ mapa: mapa,’+‘ position: results[0].geometry.location’+‘ });’+‘ } else {‘+‘ alert(“O Google Maps não responde pela seguinte situação: “ + status);’+‘ }’+‘ });’+‘ }’+‘ }’+

E para que possamos pesquisar no mapa de acordo com as coordenadas geográficas de latitude e de longitude, criamos uma função que instancia um novo parâmetro de latitude e longi-tude, centralizando e posicionando de acordo com os parâmetros que serão passados pelo usuário exibindo um titulo de acordo com a latitude e os idiomas determinados.

‘ function PesquisaCoordenadas(Lat, Lang) { ‘+‘ var latlng = new google.maps.LatLng(Lat,Lang);’+‘ mapa.setCenter(latlng);’+‘ var marker = new google.maps.Marker({‘+‘ position: latlng, ‘+‘ mapa: mapa,’+‘ title: Lat+”,”+Lang’+

Page 19: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 2011 19

‘ });’+‘ }’+

E por fim criamos as funções que exibem e ocultam a exibição das opções de Visualização de trafego e para Ciclistas, chamando elas dentro do ID “mapa”, que é listada no corpo (<body>) do arquivo HTML, e por fim fechamos a tag do script e do cabeçalho.

‘ function HabilitaTrafego(){‘+‘ trafego.setMap(mapa);’+‘ }’+‘’+‘ function DesabilitaTrafego(){‘+‘ trafego.setMap(null);’+‘ }’+‘’+‘ function HabilitaCiclista(){‘+‘ ciclista.setMap(mapa);’+‘ }’+‘’+‘ function DesabilitaCiclista (){‘+‘ ciclista.setMap(null);’+‘ }’+‘’+‘ </script> ‘+‘ </head> ‘+

Obs: As funções que habilitam os dados de tráfego e para ciclistas só podem ser visu-alizadas com todos seus recursos nos trechos vistos somente do mapa dos Estados Unidos.

Vamos definir agora o corpo do programa, ou seja a parte que é visível da página HTML, definindo no evento “onload” do corpo da página que será executada a função de inicialização do JavaScript

que contém os parâmetros iniciais para carregar a API na aplicação, e criamos uma ID com o nome de “mapa”, pois é pela ID que o javaScript reconhece onde deve ser executado suas funções, e com o CSS marcamos a largura (“width”) e altura (“height”) sempre em 100%, para que quando seja chamada a página dentro do WebBrowser ela ocupe toda a extensão do componente, independente do seu tamanho, e por fim fechamos o corpo (<body>) e finalizamos o arquivo HTML (<HTML>)

‘ <body bgcolor=”#000000” onload=”Inicializando()”> ‘+‘ <div id=”mapa” style=”width:100%; height:100%; border: 3px solid #FFD800;”></div> ‘+‘ </body> ‘+‘</html>’;

Criada a página HTML vamos definir como executar a partir dos componentes do Delphi, primeiramente, no evento OnCreate vamos utilizar uma variável do tipo MemoryStream, que permi-tirá o Delphi enviar e receber dados para a API do Google Maps, instanciamos e no WebBrowser definimos que será enviada uma página em branco, e dentro do bloco try...finally enviamos para a va-riável os dados iniciais que são determinados pelo JavaScript, logo liberamos a variável da memória com o método “Free”.

procedure TForm1.FormCreate(Sender: TObject);var aStream: TMemoryStream;begin aStream:= TMemoryStream.Create; WebBrowser1.Navigate(‘about:blank’); try aStream.WriteBuffer(Pointer (Pagina)^, Length(Pagina)); aStream.Seek(0, soFromBeginning);

(WebBrowser1.Document as IPersistStreamInit).Load(TStreamAdapter.Create(aStream)); finally aStream.Free; end; HTMLWindow:= (WebBrowser1.Document as IHTMLDocument2).parentWindow; end;end;

Obs: Para que seja possível controlar componente como os dados de uma página HTML é preciso declarar um parâmetro do tipo IHTMLWindow2 na cláusula private, de preferencia, uma vez que será somente utilizado pelo WebBrowser da página com a API, e para habilitar os controles ActiveX devemos declarar na clausula uses dentro de implementation o parametro ActiveX;.

No evento OnClick do botão para busca por endereços iremos fazer com a função do JavaScript leia o conteúdo da Edit de busca onde utilizamos uma variável do tipo String para que armazene o conteúdo informado no Edit e que a partir do comando HTMLWindow.execScript será executado a função do JavaScript de acordo com os dados passados pela Edit.

procedure TForm1.btnEnderecoClick(Sender: TObject);var address: string;begin address:= edtEndereco.Text; address:= StringReplace(StringReplace(Trim(address), #13, ‘ ‘, [rfReplaceAll]), #10, ‘ ‘,

Page 20: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 201120

[rfReplaceAll]); HTMLWindow.execScript(Format(‘Marcador(%s)’,[QuotedStr(address)]), ‘JavaScript’);end;

Para que seja realizada a pesquisa de acordo com as coordenadas vamos definir e unir a função do JavaScript com os seus parâmetros sendo dados pelos valores de cada Edit

procedure TForm1.btnCoordenadasClick(Sender: TObject);beginHTMLWindow.execScript(Format(‘PesquisaCoordenadas(%s,%s)’,[edtLatitude.Text,edtLongitude.Text]), ‘JavaScript’);end;

E para que possamos habilitar e desabilitar cada Script utilizamos o component Combobox para o Gráfico para ciclistas e de Tráfego e é feita uma verificação de acordo com a condição, sendo que se o ComboBox está marcado Habilita a função, caso contrário desabilita.

procedure TForm1.cbComCiclistaClick(Sender: TObject);begin if cbCiclista.Checked then HTMLWindow.execScript(‘HabilitaCiclista()’, ‘JavaScript’) else HTMLWindow.execScript(‘DesabilitaCiclista()’, ‘JavaScript’);end;

procedure TForm1.cbComTrafegoClick(Sender: TObject);

begin if cbTrafego.Checked then HTMLWindow. execScript (‘HabilitaTrafego()’, ‘JavaScript’) else HTMLWindow.execScript(‘DesabilitaTrafego()’, ‘JavaScript’);end;

Ao aplicar todas estas funções o componente está pronto, devendo carregar ao inicializar e trazer os registros predefinidos na função de inicialização do JavaScript

Conclusão

Este componente com a API pode ser utilizada com varias finalidades, desde uma consulta simples a uma localidade até traçar rotas e definir pontos preferenciais, caso queira mais informações sobre como trabalhar com a API do Google Maps visite http://code.google.com/intl/pt-BR/apis/maps/index.html.

Consultor Técnico The Club.

Sobre o autor

Eduardo Massud

[email protected]

Page 21: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 2011 21

Page 22: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 201122

MÉTODOS RAVEReportde A a Z

IINSERT – insere texto em um buffer de

memória em BufPos. BufPos deve ser 0 para inserir o buffer inteiro antes.

Example (Delphi)

MemoBuf.Insert(0,’Este texto é o primeiro agora.’);

INSERT MEMO BUF – insere um MemoBuf em um BurPos dentro do buffer

de memória atual.

Example (Delphi)

MemoBuf1.InsertMemoBuf(10,MemoBuf2);

IS VALID CHAR – determina se um caracter é um caracter válido para o código de barras que está sendo impresso.

Example (Delphi)

// o seguinte retorna falso porque somente 2 de 5 suportam números. Code2of5.IsValidCar(‘A’);

LF – Esse método executa uma mudança de linha que se move a posição vertical do cursor de texto para baixo pela distância especificada pela propriedade LineHeight. Também incrementa a propriedade LineNum. Se as colunas estiverem em uso e o cursor de texto for movido para baixo da SectionBottom atual, o cursor de texto é colocado na parte superior da próxima coluna. A parte superior da próxima coluna é definida pela configura-ção da SectionTop.

Example (Delphi)

RvNDRWriter1.LF;

L

Page 23: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 2011 23

LINES LEFT – retorna o número de linhas que podem ser impressas acima da SectionBottom atual, incluindo a linha atual.

Example (Delphi)

if RvNDRWriter1.LinesLeft < 3 then beginRvNDRWriter1.NewPage;end; { if }

LINE TO – este método desenha uma linha usando a caneta atual a partir de uma posição prévia do cursor gráfico para o ponto especificado por (X,Y).

Example (Delphi)

with RvNDRWriter1 do beginMoveTo( 1.0, 1.0 );LineTo( 3.0, 3.0 );MoveTo( 1.0, 3.0 );LineTo( 3.0, 1.0 );end; { with}

LOAD FROM FILE – carrega um buffer de memória com o conteúdo de um arquivo de texto. Para carregar texto RTF usar RTFLoadFile.

Example (Delphi)

MemoBuf1.LoadFromFile(‘Letter.Txt’);

LOAD FROM STREAM – carrega o buffer de memória de um processo para um BufSize número de bytes.

Example (Delphi)

MemoBuf1.LoadFromStream( MyStream, StreamSize );

LOAD RAVE BLOB – carrega o projeto armazenado em Stream para um formulário da aplicação. Não é preciso chamar esta função uma vez que o método normal de carregamento de um projeto de relatório é através do editor de propriedades

TRvProject. StoreRAV .

Example (Delphi)

RvProject1.LoadRaveBlob( MyStream );

MACRO – Esta função insere uma ma-cro em seu relatório. A macro será inserida no momento da saída do relatório (em visu-alização ou impressora) e não no momento da geração do relatório. Utilize este método com todos os métodos de impressão. Para uma lista de MacroID ver a definição do tipo de TMacroID.

Example (Delphi)

// Imprime a página atual e o total de páginas.PrintRight(Macro(midCurrentPage) + ‘ of ‘ +Macro(midTotalPages), 8.0);

MEMO HEIGHT LEFT – retorna a altura necessária para imprimir o buffer de memória para a fonte atual entre PrintStart e PrintEnd. Deve-se inicializar o TMemoBuf.BaseReport antes de chamar este método.

Example (Delphi)

MemoBuf.BaseReport := Sender as TBaseReport;HeightLeft := MemoBuf.MemoHeightLeft;

MEMO LINES – retorna o número de linhas necessário para imprimir o buffer de memória MemoBuf para a fonte atual entre PrintStart e PrintEnd.

Example (Delphi)

// Salva o número de linha necessário para imprimir o memo. LinesLeft := RvNDRWriter1.MemoLines(MyMemo);

MEMO LINES LEFT – retorna o núme-ro de linhas necessário para imprimir o buffer de memória para a fonte atual entre PrintStart e PrintEnd.. Deve-se inicializar o TMemoBuf.BaseReport antes de chamar este método.

Example (Delphi)

MemoBuf.BaseReport := Sender as TBaseReport;LinesLeft := MemoBuf.MemoLinesLeft;

MOVE TO – move a posição do cursor gráfico atual para o ponto especificado por (X,Y).

Example (Delphi)

RvNDRWriter1.MoveTo( NewX, NewY );

M

Page 24: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 201124

NNEW COLUMN – cria uma nova co-

luna em adição às colunas já existentes (que estavam usando os métodos SetColumns ou SetColumnWidth). Se não houver espaço suficiente na página atual, este método criará uma com as configurações atuais na próxima página.

Example (Delphi)

RvNDRWriter1.NewColumn;

NEW LINE – Esse método executa um retorno de carro (CR), seguido de uma alimentação de linha (LF), e em seguida, redefine as tabs.

Example (Delphi)

RvNDRWriter1.NewLine;

NEW PAGE – este método encerra a página atual e inicia a impressão em nova página. OnPrintFooter é chamado antes que a página atual termine. Os eventos OnPrintHea-der e OnNewPage serão chamados depois que a nova página tenha sido criada.

Example (Delphi)

RvNDRWriter1.NewPage;

NEW PARA – inicia um novo parágrafo quando exporta para HTML ou RTF. Difere do método NewLine porque insere um retorno físico do carro no documento RTF ou HTML.

Example (Delphi)

RvNDRWriter1.NewPara;

NEXT PAGE – Este método vai para e imprime a página ao lado da janela de visualização. O manipulador de eventos OnPageChange será chamado se o número atual de páginas mudar.

Example (Delphi)

RvRenderPreview1.NextPage;

NO PRINTERS – esta função retorna True se não houver nenhuma impressora definida no sistema Windows atual e False se houver. TRvRenderPrinter não funciona sem um driver de impressora instalado, en-tretanto, TRVNDRWriter e TRvRenderPreview funciona.

Example (Delphi)

// Configurar a impressão para modo paisagem.if NoPrinters then beginNoPrinterPageHeight := 8.5;NoPrinterPageWidth := 11.0;end; { if }

OPEN – este método abre o arquivo de projeto de relatório definido pelo ProjectFile para torná-lo disponível para impressão ou modificação.

O

PIE – este método desenha uma fatia de torta dentro de uma elipse limitada pelo retângulo definido por (X1,Y1) e (X2,Y2). A fa-tia começa na interseção da linha desenhada entre o centro da elipse ((X1+X2) / 2.0,(Y1+Y2) / 2.0) e o ponto (X3, Y3) e é desenhada no sentido anti-horário (para esquerda) até al-cançar a interseção da linha desenhada entre o centro da elipse e o ponto (X4, Y4).

Example (Delphi)

SetBrush(clBlack, bsHorizontal, nil);Pie(3.25,1.0,5.25,3.0,5.25,2.0,0.0,0.0);SetBrush(clBlack, bsVertical, nil);Pie(3.25,1.0,5.25,3.0,0.0,0.0,3.25,7.0);SetBrush(clBlack, bsBDiagonal, nil);Pie(3.25,1.0,5.25,3.0,3.25,7.0,5.25,2.0);

POLYGON – este método desenha um polígono usando a caneta atual definida pelos pontos contidos em um array Points aberto. Também fecha a forma entre o primeiro e o último pontos e preenche-o usando o pincel atual.

Example (Delphi)

RvNDRWriter1.Polygon( [CreatePoint(1.0,2.0), CreatePoint(2.0,3.0), CreatePoint(5.0,2.0)]);

POLYLINE – este método desenha uma série de linhas usando a caneta atual conectando os pontos definidos no array

P

Page 25: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 2011 25

Points aberto.

Example (Delphi)

PolyLineArr[1] := CreatePoint( 0 , -1 );PolyLineArr[2] := CreatePoint(-0.59, 0.81);PolyLineArr[3] := CreatePoint( 0.95, -0.31);PolyLineArr[4] := CreatePoint(-0.95, -0.31);PolyLineArr[5] := CreatePoint( 0.59, 0.81);PolyLineArr[6] := CreatePoint( 0 , -1);Polyline(PolyLineArr);

POP FONT – este método define a fonte para a configuração que foi por último empurrada por PushFont. PopFont retorna false se não existir mais fontes na pilha.

Example (Delphi)

PushFont;SetFont(‘Arial’,10);PrintLn(‘This is in Arial’);PopFont;

POP POS – configura a posição do cursor de texto para a configuração que foi a última a ser empurrada por PushPos. PosPos retorna False se não existirem mais posições na pilha.

Example (Delphi)

PushPos;PrintXY(4,1.5,’Name’);PopPos;

POP TABS – configura as guias para a configuração anterior à passada por PushTabs.

PopTabs retorna false se não existirem mais guias na pilha.

PREV PAGE – este método imprime a página anterior à janela de visualização. O evento OnPageChange será chamado se os números da página corrente mudarem.

Example (Delphi)

RvRenderPreview1.PrevPage;

PRINT – este método imprime a string, Text, na posição atual do cursor de texto. Se a string contiver algum caracter tab o mé-todo Tab será chamado com os parâmetros padrão. O cursor texto é deixado no fim da string impressa.

Example (Delphi)

RvNDRWriter1.Print(‘Hello World!’);

PRINT BITMAP – este método impri-me a string, Text, na posição atual do cursor de texto. Se a string contiver algum caracter tab o método Tab será chamado com os pa-râmetros padrão. O cursor texto é deixado no fim da string impressa.

Example (Delphi)

RvNDRWriter1.Print(‘Hello World!’);

PRINT BITMAP RECT – Este método vai chamar o bitmap na tela da impressora,

esticado ou encolhido para caber dentro do retângulo definido pelos pontos (X1, Y1) e (X2, Y2).

Example (Delphi)

Bitmap := TBitmap.Create;Bitmap.LoadFromFile(‘RpDEMO.BMP’);PrintBitmapRect(5.375,3.5,7.375,5.5,Bitmap);Bitmap.Free;

PRINT BLOCK – imprime Texto na linha atual começando em Pos. O texto terá alinhamento justificado dentro da área defi-nida por Width.

Example (Delphi)

PrintBlock(‘This is block justified text’,0.5,4.0);

PRINT CENTER – imprime a string Texto, na linha atual centralizada horizontal-mente na posição Pos.

Example (Delphi)

PrintCenter(‘Text centered at 2.0’, 2.0);

PRINT CHAR JUSTIFY – Esse método imprime uma seqüência de caracteres de tex-to, justificado em Pos com relação à primeira ocorrência de ch em Texto. Isso pode ser útil para as colunas de impressão de números, alinhadas pelo ponto decimal, quando pode haver um número variável de dígitos depois da vírgula.

Example (Delphi)

Page 26: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 201126

Consultora Técnica The Club.

Sobre o autor

Leonora Golin

[email protected]

// Imprime o número justificado pelo ponto decimal.PrintCharJustify(NumStr,’.’,4.25);

PRINT DATA – este método imprime a string Value diretamente para a impres-sora. Pode ser útil para enviar comandos de impressão específicos para fazer coisas que normalmente não são suportadas pelo driver de impressora Windows (exemplo (Delphi) formulários eletrônicos ou comandos HP-GL).

Atenção: Incluir qualquer comando es-pecífico para impressora em relatórios pode tornar os relatórios inutilizáveis em outros sistemas de computador. Usar este método apenas em situações apropriadas.

Nota: Esta propriedade pode ser usada para enviar tags HTML fora de texto para a página que não seja alterada de alguma forma pelo Rave.

Example (Delphi)

RvNDRWriter1.PrintData( SpecialCodes );

PRINT DATA STREAM – Este procedi-mento irá enviar bytes BufSize do Stream dire-tamente para a impressora. Se BufSize for 0, o conteúdo restante do Stream será enviado.

Nota: Dependendo do conteúdo dos dados enviados para a impressora, este comando pode causar que os relatórios se-jam incompatíveis entre diferentes marcas de impressoras. Há também várias funções da impressora que são incompatíveis com o driver de impressora do Windows e não devem ser usadas.

Example (Delphi)

MyFileStream :=

TFileStream.Create(‘PAGE.PCL’, fmOpenRead);PrintDataStream(MyFileStream,0);MyFileStream.Free;

PRINT FIM A – imprime um FIM A PostNet a um local X,Y dado.

Example (Delphi)

PostNetBC1.PrintFimA(3.5,0.5);

PRINT FIN B – este método imprime um FIM B PostNet em um local X,Y dado.

Example (Delphi)

PostNetBC1.PrintFimB(3.5,0.5);

PRINT FIN C – este método imprime um FIM C PostNet em um dado local X,Y.

Example (Delphi)

PostNetBC1.PrintFimC(3.5,0.5);

PRINT FOOTER – imprime a string Texto, logo acima da SectionBottom atual, justificada, entre as atuais SectionLeft e SectionRight.

Example (Delphi)

PrintFooter(‘Date 01/20/95’, pjRight);

PRINT HEADER – imprime a string Tex-to, logo abaixo da atual SectionTop justificada, entre as correntes SectionLeft e SectionRight.

Example (Delphi)

PrintHeader( ‘Report Header Text’, pjCenter);

PRINT HEIGHT – este método imprime o buffer de memória para a altura especifi-cada pelo parâmetro Height. Se Height for ) então todas as linhas no buffer de memória serão impressas. Se PrintTabs é verdadeiro, então PrintHeight imprime linhas de tabs vazias para cada linha que o buffer de me-mória imprime.

Nota: se o buffer de memória inteiro não for impresso, a posição interna do MemoBuf será configurada para o último caracter que foi impresso. Isto permite que o buffer de memória continue em outra página.

Nota: deve-se inicializar o TMemoBuf.BaseReport antes de chamar este método.

Page 27: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 2011 27

Page 28: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 201128

Dicas DELPHIIntegrando ListView com Dataset

O componente ListView do Delphi, embora pouco utilizado, é bastante versátil e possui um visual bem interessante que pode ser integrado aos nossos projetos.

Porém o mesmo sempre acaba sendo preterido em favor do DBGrid para exibição de dados provenientes de um dataset, devido a facilidade de integra-ção entre o Dbgrid e componentes Dataset.

O que muitos desenvolvedores talvez não saibam é que podemos integrar o componente ListView do Delphi com componentes Dataset de forma relati-vamente fácil. É o que estarei mostrando no exemplo a seguir.

Criando a aplicação exemplo

Nesse exemplo, estaremos utilizando os seguintes componentes:

ListView (Aba Win32):

Name lsExemploViewStyle vsReport

ClientDataset (Aba Data Access):

Name CdsExemplo

FileName C:\Arquivos de programas\Arquivos Comuns\Borland Shared\Data\Employee.xml

Além desses componentes, insira também um Button e altere seu caption para “Carregar Dados”

O layout do exemplo deverá ficar como na imagem 1:

Veja a fiura 01.

Iremos criar agora as duas funções que farão a integração do ListView com o Dataset.

A primeira coloca os dados no mesmo e a segunda formata as colunas do ListView de acordo com valores determinados.

Veja o código:

procedure DataSetinListView(Dataset:TDataSet;ListView:TListView);

// Parâmetros:// Dataset: Fonte dos dados para preenchimanto do ListView.// pode ser qualquer componente descendente de TDataset. Exemplos:// Clientdataset, SqlDataset, AdoDataset, Query, Table, entre outros...

// ListView: Componente do tipo TListview onde serão carregados os dados.

var i:integer; lsItem:TListItem;begin

// Percorremos os campos do Dataset para criar as colunas // relativas a cada campo do dataset for i:=0 to Dataset.FieldCount-1 do ListView.Columns.Add.Caption:=Dataset.Fields[i].DisplayLabel;

// Abrimos e colocamos o dataset no primeiro registro Dataset.Open; Dataset.First;

Figura 01

Page 29: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 2011 29

// Varremos os registros no dataset e vamos inserindo // os dados como itens e subitens do listview while not(Dataset.Eof)do begin

lsItem:=ListView.Items.Add;

lsItem.Caption:=Dataset.Fields[0].Value;

for i:=1 to Dataset.FieldCount-1 do if not(Dataset.Fields[i].IsNull)then lsItem.SubItems.Add(Dataset.Fields[i].Value);

Dataset.Next;

end; end;

procedure AdjustListViewColumns(ListView:TListView;NumberofColumns:Integer;WidthColumns:array of Integer);

// Parâmetros:// ListView: Componente listview que terá suas colunas ajustadas.// NumberofColumns: Numero de colunas a serem ajustadas.// WidthColumns: array com os valores desejados para as colunas.

var i:Integer;begin

// Varremos as colunas do ListView e aplicamos os valores // do array um a um. for i:=0 to NumberofColumns-1 do ListView.Columns[i].Width:=WidthColumns[i];end;

Para finalizar, no evento OnClick do botão que inserimos no formulário faça:

procedure TForm1.Button1Click(Sender: TObject);begin DataSetinListView(ClientDataSet1,ListView1); AdjustListViewColumns(ListView1,5,[50,150,150,150,150]);end;

Veja na imagem 2 o aplicativo em execução:

Conclusão

Vimos nesse exemplo que a integração do componente ListView com components Dataset pode ser feita de forma fácil e com isso temos mais uma excelente opção de componente visual para exibirmos informações em nossos sistemas.

Abraços !

Page 30: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 201130

VerticalHorizontal

Page 31: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 2011

Page 32: The Club - megazine · Primeiros passos com Android Editorial Halloween ou dia das Outubro é o mês em que celebramos o 13 bruxas. Para quem trabalha com progra-mação, não é

novembro 2011