megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C#...

32
agosto 2012

Transcript of megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C#...

Page 1: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 2012

Page 2: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 2012

Page 3: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 2012 03

Desafio The ClubDicas

30

Android Delphi

DelphiC#

Delphi Parte V

índiceCriando aplicações com FireMonkey e acesso a

banco de dados no Delphi XE2

Editorial

1004Linguagem C# - Criando Classes e Objetos

05Android - Lendo e Carregando Arquivo Texto

15

28

21

LegendaInicianteIntermediárioAvançado

Autor: Lucas Vieira de Oliveira

Autor: Thiago C. Montebugnoli

Autor: Marcos César Silva

Autor: Luciano Pimenta

Page 4: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 201204

Bem-vindo

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

pelos seus respectivos proprietários.

Thiago Montebugnoli - Editor [email protected]

Salve! Salve! Neste mês a revista The Club comemora no dia 5 de Agosto o Dia Internacional da Cerveja, tendo como propósito principal a possibilidade de unir amigos e familiares para saborear com responsabilidade esta maravilhosa bebida.

Tão bom quanto uma cerveja gelada em uma sexta-feira agitada estão os artigos dos colunistas e colaboradores deste mês.

Marcos César Silva nos ensina a Criar Classes e Objetos de uma forma simples e prática na Linguagem C#, servindo de base para outros tipos de linguagens.

Nosso colaborador mensal Luciano Pimenta traz a quinta parte da seqüência dos artigos do Curso de Delphi XE para Iniciantes, tendo também muitas informações para os que já possuem um pouco mais de experiência com o Delphi.

Já o consultor técnico Lucas de Oliveira continua firme e forte abordando assuntos de grande importância e relevância no suporte técnico, sendo que neste mês ele cria exemplos de aplicações com FireMonkey junto com acesso a banco de dados.

O FireMonkey é uma VCL turbinada que torna possível criar for-mulários mais interativos. Eu continuo minha jornada com artigos relacionados ao Sistema Android criando um exemplo prático de como se deve ler e carregar arquivos do tipo texto.

A seção de “Dicas Delphi” está sempre nos disponibilizando os melhores macetes e assuntos abordados neste mês de Agosto.

Um Forte abraço,

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 2012

Diretor TécnicoMarcos César Silva

DiagramaçãoEduardo Massud

ArteVitor M. Rodrigues

RevisãoEliziane Valentim

ColunistasLucas de OliveiraLuciano Pimenta

Thiago Cavalheiro MontebugnoliMarcos César Silva

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: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 2012 05

C#

Linguagem C# Criando Classes e Objetos

Nesta importante etapa abordo um conceito geral de Classes e Objetos na lin-guagem C# aproveitando para descrever os tipos mais importantes ao decorrer do nosso aprendizado. Na Programação Orientada a Objetos (POO) tudo é baseado em classes e objetos, sendo que o conceito é universal e imprescindível, qualquer que seja a linguagem em que esta seja aplicada.

A POO procura estabelecer um modelo de

programação que aproxima o desenvolvedor do mundo real. Seguiremos enfatizando os principais conceitos e posteriormente um exemplo prático do uso de Classes e Objetos.

Conceito Geral de Classes e Objetos

Uma classe é uma unidade do sistema e dentro dela estão definidos atributos e métodos, que são respectivamente as informações que uma classe pode armazenar e ações que elas podem

desempenhar.

Para ficar mais fácil o entendimento, um atri-buto possui as mesmas funcionalidades de uma variável, assim como um método o mesmo que um procedimento ou função. A diferença fundamental entre classe e objeto reside no fato da classe conter as definições do que essa nova unidade irá fazer e o objeto ser um caso especial de uma classe. É importante saber que enquanto exista apenas uma definição de classe, podem existir diversos objetos baseados numa classe.

Page 6: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 201206

A imagem 01 ilustra de uma forma mais didá-tica o que estou descrevendo.

Conceito de Atributos

Na realidade, os denominados atributos nada mais são do que as variáveis da classe, os locais que guardarão as informações referentes aquela classe. Quando um objeto é criado a partir de uma classe, neste momento os atributos passam a ter informações específicas assumindo estados espe-ciais, ou seja, de uma forma geral este é o momento onde são atribuídos os valores. Existem dois tipos de atributos, os que permitem acesso externo ao da classe e os que não permitem, são denomina-dos respectivamente de “Públicos” e “Privados”. Aproveitando este tópico, falaremos de um recurso importante da POO, o Encapsulamento de dados, que significa uma proteção às suas propriedades. De uma forma geral, estes conceitos são melhores compreendidos seguindo o exemplo a seguir.

Exemplo:

//Declaração do atributo do tipo “string” e “private” private string nome;

A linguagem C#, junto com o Visual Studio possui inúmeros macetes que nos auxilia diaria-

mente. Podemos então encapsular estas proprie-dades com a ajuda do “Refactor”, clicando com o botão direito em “nome” escolhendo “Refactor/Encapsulate Field...”

Ver Figura 02.

Logo após aparecerá uma janela com os se-guintes dizeres. Ver Imagem 03.

Figura 03: Encapsulate Field.

Por padrão a Propriedade “nome” virá com a primeira letra em maiúsculo, isto serve para diferenciar da propriedade privada criada ante-riormente. Clique no botão “Ok” para prosseguir com o código a seguir.

//Encapsulamento do atributo Público Nomepublic string Nome{ get { return nome; } set { nome = value; }}

Deixamos o atributo “Nome” dinâmico, pois poderemos retornar e atribuir valores dinamica-mente com os operadores “Get” e “Set” respec-tivamente, permitindo criar regras e lógicas para acesso a dados e público permitindo uma visibili-dade e acessibilidade externa à Classe. Usaremos este recurso para fins didáticos, sem nenhuma regra adicional.

Conceito de Métodos

São as funções e Procedimentos dentro da classe. Realizam operações sobre as informações contidas nos atributos de uma classe. Os métodos podem ser entendidos como mensagens trocadas entre diferentes objetos. Assim como os atributos, os métodos também podem ser do tipo público ou privado.

Exemplo:

//Declaração do método Cadastrar(), do tipo “void” e “public”

public void Cadastrar(){ MessageBox.Show("Cadastrando sócio... "); }

Métodos do tipo “void” podem ser compara-dos aos procedimentos, ou seja, não retornam ne-nhum valor. Já para retornar algum dado veremos o exemplo a seguir.

Exemplo:

//Declaração do método ConfirmarCadastro(), do tipo “bool” e “public”

public bool ConfirmarCadastro(int tipo){ if (tipo == 1) return true; else return true;}

O método criado anteriormente está retornan-do um valor do tipo Booleano utilizando a cláusula “return”, que significa retorno.

Construtores e Destrutores

Toda classe criada deverá possuir dois mé-todos: o Construtor (Construct) que é chamado no momento quando instanciamos a Classe e o Destrutor (Destruct) quando liberamos o objeto

Figura 01: Classe e Objeto.

Figura 02: Refactor/Encapsulate Field.

Page 7: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 2012 07

criado por esta classe da memória.

No C# temos o denominado “Garbage Col-lector”, trocando em miúdos seria um “Coletor de Lixos”. Ele é responsável pela destruição de todo objeto que não é mais utilizado, sendo um recurso capaz de oferecer uma solução automatizada ao gerenciamento de memória.

Exemplo:

//Construtorpublic Socio(){ MessageBox.Show("Objeto Criado com sucesso!");}

//Destrutor~Socio()da classe{

}

O método Construtor será invocado quan-do instanciamos a Classe “Socio” e para fins de aprendizado achei interessante demonstrar a sintaxe do Destrutor, que normalmente não precisamos nos preocupar, pois contamos com o recurso “Garbage Collector” citado anteriormente.

Tipos de Classes

Na Programação Orientada a Objetos contamos com diversos tipos de classes como: Públicas, Privadas, Protegidas, Estáticas, Abs-tratas, Seladas, Herdadas entre outras, sendo que todas possuem recursos que se encaixam ao decorrer da análise do projetista. Nesta eta-pa abordarei os principais conceitos referentes a este assunto

Pública (Public)

As classes públicas, assim como os atribu-tos e métodos, permitem que qualquer pessoa instancie objetos. O nome da classe é precedi-

do pelo nível de acesso (public) seguindo pela palavra chave “class”.

Exemplo:

public class Socio{ // Códigos da Classe}

Neste caso temos uma classe pública chamada “Socio”.

Privada (Private)

Seguindo a mesma lógica dos atributos e métodos, as classes privadas não permitem acesso externo.

A sintaxe de criação pode ser conferida a seguir.

Exemplo:

private class Socio{ // Códigos da Classe}Ouclass Socio{ // Códigos da Classe}

Existem duas maneiras para declaração de classes privadas, a primeira utilizando a palavra “private” e a segunda sem nenhuma referência.

Com o exemplo citado anteriormente fica mais fácil a visualização.

Instanciáveis

Este tipo de classe é o mais utilizado, ou seja, toda vez que precisarmos criar um objeto, é necessário instanciá-lo, podendo assim criar vários objetos desta mesma classe.

Exemplo de criação:

Public class Socio{ //atributos estáticos private string nome; public string Nome { get { return nome;} set { nome = value;} }}

Exemplo de utilização:

Socio soc = new Socio();soc.Nome = "Thiago Montebugnoli";

Estáticas

Quando utilizamos estes tipos de classes, de-veremos por obrigação, possuir todos os atributos como estáticos. A principal característica destas classes é não permitir realizar a instância de um objeto, ou seja, quando for utilizá-la basta fazer referência aos membros para poder trabalhar com os mesmos.

Exemplo de criação:

Public static class Socio{ //atributos estáticos private static string nome; public static string Nome { get { return Socio.nome;} set { Socio.nome = value;} }}

Exemplo de utilização:

Socio.nome = “Thiago Montebugnoli”

Page 8: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 201208

Na sua utilização basta atribuir o valor dese-jado. Como foi dito anteriormente, a instancia já é criada automaticamente quando executamos o programa, podendo ser utilizada em todos os pon-tos do software. A principal vantagem no uso desta classe é a automatização na criação da instância.

Criando um Exemplo prático

Crie uma aplicação “Windows Forms” e adi-cione um botão no formulário. A tela deverá ficar idêntica a Imagem 04.

Figura 04: Tela de Exemplo.

A partir de agora vou detalhar todas as etapas de como se deve criar uma classe e usá-la logo em seguida, para isto clique em cima da solução e com o botão direito escolha “Add/New Item...” e na região esquerda em “Visual C# Items” escolha “Code” e em seguida “Class”. Aproveite e clique no botão “Add”. Ver Imagem 05.

Figura 05: Adicionando uma Classe no projeto.

O Visual Studio por padrão cria apenas o namespace “Classes”, e a classe “Socio”. Vou criar uma classe pública e logo em seguida instanciá-la. A Imagem 01 nos ilustra de uma forma clara de como irá ficar nossa classe “Socio” e o código abaixo abrange de uma forma prática todas as etapas explicadas an-teriormente.

//Namespaces utilizadosusing System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Windows.Forms;

namespace Classes{ //Classe pública public class Socio { //Construtor da classe public Socio() { MessageBox.Show("Objeto Criado com sucesso!"); }

//Destrutor da classe ~Socio() {

}

//Atributos/Propriedades Privadas Encapsuladas private string nome; private string cpf; private string rg; private DateTime nascimento; private string telefone; private string endereco;

//Atributos/Propriedades Públicas Encapsuladas public string Nome { get { return nome;} set { nome = value;} } public

string Cpf { get { return cpf; } set { cpf = value; } }

public string Rg { get { return rg; } set { rg = value; } }

public DateTime Nascimento { get { return nascimento; } set { nascimento = value; } }

public string Telefone { get { return telefone; } set { telefone = value; } }

public string Endereco { get { return endereco; } set { endereco = value; } }

//Métodos públicos public void Cadastrar() { MessageBox.Show(string.Format("Cadastrando sócio...\r\nNome: {0}, - Rg: {1}, Cpf: {2}",nome,rg,cpf)); }

public bool ConfirmarCadastro(int

Page 9: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 2012 09

tipo) { if (tipo == 1) return true; else return true; }

public bool ValidarSocio(int tipo) { if (tipo == 1) return true; else return true; }

public void Alterar() { MessageBox.Show("Alterando sócio..."); } }}

No formulário criado iremos instanciar um

objeto da classe “Socio” e logo em seguida o código comentado correspondente.

private void button1_Click(object sender, EventArgs e){ //Instanciando um objeto Socio soc = new Socio();

//Inserindo atributos soc.Nome = "Thiago Montebugnoli"; soc.Rg = "41.999.999-9"; soc.Cpf = "312.999.999-99"; soc.Nascimento = DateTime.

Parse("15/11/1984"); soc.Telefone = "(14)

9999-9999"; soc.Endereco = "Rua Fulano de Tal, 999"; //Invocando métodos soc.Cadastrar();

if (soc.ConfirmarCadastro(1)) MessageBox.Show("Cadastro Confirmado!");

if (soc.ValidarSocio(1)) MessageBox.Show("Sócio Validado!"); soc.Alterar();}

O primeiro passo foi criado o objeto “soc” usando a palavra reservada “new”, logo em seguida definimos os atributos e invocamos os métodos. A Figura 06, 07 e 08 nos dá uma boa idéia do funcio-namento de uma classe em “Run-Time” .

Figura 06: Passo 01 - Construtor.

Conclusão

Neste artigo procurei separar em duas etapas, a primeira com conceitos básicos de Programação Orientada a Objetos (POO) e a outra com um exem-plo prático e de fácil entendimento.

Vou continuar com conceitos e dicas sobre este assunto nos próximos artigos.

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

Consultor de Sistemas na consultoria de sistemas Da-taSmart e Consultor Técnico do The Club, Bacharel em Ciência da Computação, MBA em Gestão Empresarial, Certificações MCAD (Microsoft Certified Application Developer) e MCSD.NET (Microsoft Certified Solution Developer .NET)

Sobre o autor

Marcos César Silva

[email protected]

Figura 07: Passo 02 – Atribuindo Valores e Executando Métodos.

Page 10: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 201210

Criando aplicações com FireMonkey e acesso a banco de dados no Delphi XE2

Este artigo tem como foco, criar uma aplicação de exemplo utilizando a platafor-ma FireMonkey, a tecnologia LiveBindings, a tecnologia DBExpress e o Servidor de banco de dados FireBird. Serão abordados com mais profundidade os temas FireMonkey e LiveBindings que são novidade da nova IDE do Delphi, a XE2. Vamos então conhecer um pouco sobre essas novas tecnologias que foram acopladas ao Delphi.

O que é o FireMonkey?

O Delphi XE2 chegou ao mercado repleto de novidades. E uma das mais cobiçadas pela comu-

nidade Delphi é o FireMonkey. Este framework chamou a atenção dos usuários Delphi por suas excelentes características.

O FireMonkey é uma nova plataforma de de-senvolvimento do Delphi XE2, com ela é possível criar aplicações e distribuí-las para plataformas Windows 32 bits, Windows 64 bits, Mac OS X e iOS (iPhone). Além disso, o FireMonkey possibilita criar uma aplicação mais rica em visual, além é claro de criar gráficos em 3D, similares as animações criadas em Flash que são utilizadas em muitas páginas da web.

O FireMonkey não deixa nada a desejar, nem se tratando em desempenho de aplicações, pois utiliza de todo o poder da CPU e também da GPU (Unidade de Processamento Gráfico) para aplica-

ções em 3D, assim sendo, não precisa se preocupar com o desempenho de suas aplicações FireMonkey.

São quatro tipos de projetos FireMonkey para o Delphi XE2, são eles:

1. FireMonkey 3D Application;2. FireMonkey 3D iOS Application;3. FireMonkey HD Application; 4. FireMonkey HD iOS Application.

Tendo em vista estas opções de projetos, percebe que FireMonkey HD Application dentre as demais é a que mais coincide com a tradicional VCL, os projetos para aplicações iPhone se percebe facilmente, e os projetos para aplicações com grá-ficos em 3D também fica fácil se perceber. Neste artigo será exemplificado mais a frente, a forma que mais se coincide com a VCL.

Page 11: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 2012 11

Conexão a dados através da DBEx-press

Na VCL, tradicional plataforma de desenvolvi-mento mais utilizada pelos usuários Delphi em apli-cações com acesso a dados, utiliza-se, entre outras tecnologias, a DBExpress para acessar um banco de dados pela aplicação. Dentro de um DataModule distribui-se os componentes utilizados para este acesso, que são sequencialmente o TSQLConnec-tion e o TSQLDataSet ou TSQLQuery. Para garantir melhor desempenho, utiliza-se também a combina-ção de alguns componentes da palheta DataAccess, o TDataSetProvider e o TClientDataSet. Com estes componentes devidamente configurados, já terá uma conexão persistente com um banco de dados.

Continuando a linha de raciocínio, na VCL, depois de configurados os componentes de acesso aos dados, é necessário utilizar um componente TDataSource dentro do formulário onde será feita a manipulação dos dados, este que será a origem dos dados no formulário. Para exibir os dados no formulário faz-se o uso de componentes DataWa-res, como DBEdit, EDbText entre outros da palheta DataControls.

Estes têm em comum duas propriedades, onde se configuram o DataSource ao qual estará vincula-do e o DatField que é propriamente dito o Campo da tabela que o componente irá exibir e manipular no formulário. Estando tudo isso configurado, o formulário está pronto para exibir e manipular os dados em tempo de execução.

Até aqui não tem nenhuma mudança, como foi dito esta é uma das formas mais tradicionais de conexão a banco de dados utilizada em Delphi. Esta seria uma conexão para uma VCL, mas e se fosse uma aplicação FireMonkey, o que mudaria? A resposta é bem simples, não mudaria nada que se refere à conexão de banco de dados, ou seja, poderá continuar utilizando forma tradicional.

O que muda realmente, é que o FireMonkey não conta com os componentes DataWares da pa-lheta DataControls, o DBEdit, o DBText, etc... Sendo assim, para exibir os dados num formulários serão utilizados os componentes da palheta Standard. Neste ponto surge a necessidade de se utilizar a outra novidade da versão XE2 do Delphi, a tecno-logia LiveBindings (Ligações ao vivo).

O que é LiveBindings?

LiveBindings é baseado em expressões relacio-nais, é um novo recurso de ligação de dados que foi adicionado a IDE do Delphi XE2 para apoiar tanto a VCL quanto o FireMonkey, utiliza-se de expressões para fazer a ligação de um objeto a outro por meio de suas propriedades.

O conceito principal destas ligações está em identificar o objeto de origem e o objeto de contro-le (o destino dos dados), além é claro de configurar as expressão de origem do objeto de origem e a expressão de controle. Estas configurações podem ser feitas no pelo ObjectInspector nas propriedades do objeto de controle.

Tendo em vista que estas ligações envolvem um objeto de origem e um objeto de controle, podemos ter três situações sobre o fluxo dos dados, sabendo que Source e Control são respectivamente os objetos de origem e de controle:

1. dirSouceToControl;2. dirControlToSouce;3. dirBidirectional. As opções acima são configuradas na proprie-

dade Direction do componente BindExpression relacionado ao objeto de controle, não se atente em entender isso agora, no exemplo será explica-do esta ligação com mais detalhes, o importante agora é saber que o fluxo de dados de uma ligação LiveBindings pode ser tanto da origem para o controle quanto do controle para a origem, ou ainda os dois ao mesmo tempo, marcando a opção dirBidirectional.

Ao criar uma expressão de ligação pelo Objec-tInspector, é adicionado ao formulário automati-camente um componente BindingList, que arma-zenará e gerenciará todas as expressões presentes neste formulário. Outro componente importante é o BindScope, o qual gera um escopo de ligação entre os componentes. No caso de ligação a dados, ou seja, a um TDataSouce, usa-se o BindScopeDB.

Um exemplo simples de LiveBindings seria passar o texto digitado em um TEdit para ao Cap-tion de um TLabel, neste caso o TEdit é a origem dos dados, ou seja, a configuração de ligação entre os componentes será feita toda no TLabel pela propriedade LiveBindings.

Neste ponto se for um projeto montado na plataforma FireMonkey, listará nesta propriedade duas opções, ‘New LiveBinding’ e ‘Link To DB Field’, se for uma projeto em VCL apenas aparecerá a primeira opção. Seguindo o exemplo, escolha a opção ‘New LiveBinding’, aparecerá uma janela

para selecionar o tipo de componente que deseja criar, selecione TBindExpression e clique em ‘Ok’.

Aparecerá mais uma propriedade no Objec-tInspector do TLabel, denominada BindExpressio-nLabel11. Agora será definido a ligação entre os objetos, marque os seguintes valores nas seguintes propriedades do Label1:

1. ControlExpression = Text (Na plataforma FireMonkey não é mais Caption);

2. Direction = dirSourceToControl;3. SourceComponent = Edit1;4. SourceExpression = Text.

Até aqui já está configurado a ligação, porém resta agora apenas notificar o mecanismo de ex-pressão, que irá atualizar os objetos conforme as alterações em suas propriedades, para isso basta apenas uma linha de código. No evento onChange do Edit1, coloque a seguinte codificação:

BindingsList1.Notify(Edit1, ‘Text’);

O método Notify, irá notificar aos mecanismos de expressões as mudanças que ocorreram na pro-priedade Text, o segundo parâmetro do método, do componente Edit1 que é o Primeiro parâmetro do método. Pronto este primeiro exemplo já está funcional, pode executá-lo e ver o que acontece com acontece com a Label1 depois que digitar algo na caixa de texto. Veja na figura 1 o exemplo em execução.

Figura 1 – Exemplo de LiveBindings na plata-

forma VCL

Com este pequeno exemplo, espero ter escla-recido a funcionalidade do recurso LiveBindings, agora podemos ter exemplo base do artigo onde será criado um projeto FireMonkey HD Application que fará conexão a um banco de dados FireBird através da tecnologia DBExpress.

Page 12: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 201212

Exemplo prático do FireMonkey com ligação ao banco de dados FireBird

Agora descreverei os passos para a criação do exemplo prático deste artigo, serão divididos em etapas para facilitar o entendimento e a possibili-dade do leitor pular uma etapa em que já possua o conhecimento específico como a conexão à base de dados.

Criação do banco de dados

Por motivo de organização, crie uma pasta com o nome do projeto ‘Escolar’ e dentro dela outra pasta onde será salvo o banco de dados, pode nomeá-la como ‘Banco’, se necessário pode até criar uma pasta para organizar as fon-tes do projeto, mas isto fica a critério de cada um, uma boa organização agiliza e muito na localização de arquivos pertinentes ao projeto.

Crie um banco de dados firebird com o nome ESCOLAR, que será usado a fim de exemplificar este artigo, e uma tabela ALUNOS com os seguintes campos:

CREATE TABLE ALUNOS ( ID_ALUNO INTEGER NOT NULL, NOME VARCHAR (60) CHARACTER SET NONE COLLATE NONE, DATA_NASCIMENTO DATE, CPF VARCHAR (15) CHARACTER SET NONE COLLATE NONE, CIDADE VARCHAR (60) CHARACTER SET NONE COLLATE NONE, UF CHAR (2) CHARACTER SET NONE COLLATE NONE, TELEFONE VARCHAR (15) CHARACTER SET NONE COLLATE NONE);

ALTER TABLE ALUNOS ADD CONSTRAINT PK_ALUNOS PRIMARY KEY (ID_ALUNO);CREATE UNIQUE INDEX PK_ALUNOS ON ALUNOS (ID_ALUNO);

Listagem 1: Banco de dados Escolar

Criação do projeto FireMonkey HD Application - Delphi

O próximo passo é abrir o Delphi XE2 e criar um novo projeto FireMonkey HD Application - Delphi. Salve na pasta ‘Fontes’ que está dentro da pasta ‘Escolar’ o projeto com o nome ESCOLAR.dproj, e salve a primeira Unit com o nome de unAlunos.pas. Esta será a Unit que manipulará os dados da tabela Alunos presente no banco de dados. Altera a propriedade Name do Form1 para ‘frmAlunos’.

Conexão da aplicação à base de dados através de um DataModule

Para fazer a conexão da aplicação criada com a base de dados, crie um DataModule pelo menu ‘File/New/Other’ e na janela New Itens seleciona no menu à esquerda ‘Delphi Projects/Delphi Files’, serão listados à direita os itens a serem adicionados ao projeto, escolha DataModule e clique em Ok. Altere a propriedade Name do DataModule1 para DM e salve a Unit com o nome unDm.

Através do mecanismo DataExplorer, localizado à direita da tela, crie uma nova conexão FireBird clicando com o botão direito em seguida New Con-nection, de o nome de ESCOLAR. Para especificar o caminho do banco de dados, clique com o botão direito na conexão que acabou de criar e selecione a opção Modify Connection, informe a localização do arquivo do banco de dados, o nome de usuário e a senha de acesso do mesmo, e teste a conexão. Caso de algum erro verifique se o caminho está certo, caso seja necessário antes do caminho es-pecifique o IP ou o nome do computador, exemplo ‘NomedoPC-PC:C:\ESCOLAR\Banco\ESCOLAR.FDB’.

Configurando os componentes DBEx-press

Coloque um componente TSQLConnection da palheta DBExpress e configure a propriedade ConnectionName para ESCOLAR, marque false em LoginPrompt e de o nome de CONEXAO. Agora coloque no DM um componente TSQLDataSet tam-bém da palheta DBExpress, altere seu Name para sdsAlunos, defina em ConnectionName a conexão Escolar, e coloque em CommandText a SQL ‘SELECT * FROM ALUNOS’. Carregue os Fields do sdsAlunos e configure suas propriedades ProvidersFlags. Adicione mais um componente ao DM, agora um

TDataSetProvider da palheta DataAccess, dê o nome de dspAlunos, em UpDateMode selecione upWhereKeyOnly e para finalizar as configurações deste componente selecione a propriedade opções e marque True em poAllowCommandText. Agora para finalizar e possibilitar o acesso dos dados em memória local, de forma desconectada com o servidor de banco de dados, coloque um compo-nente TClientDataSet da palheta DataAccess, altere a propriedade Name para cdsAlunos e selecione em ProviderName o dspAlunos. Até este ponto, o mecanismo de acesso e manipulação aos dados está pronto. O que resta fazer é carregar os Fields do cdsAlunos e configurá-los da mesma forma como os Fields do sdsAlunos.

Como o cdsAlunos irá trabalhar com os dados em memória local, para poder gravar no banco de dados às atualizações feitas nele é preciso chamar o método ApplyUpDates passando o parâmetro -1 ou 0 (zero) nos eventos AfterPost e AfterDelete, veja na listagem 2 um exemplo:

procedure TDM.cdsAlunosAfterDelete(DataSet: TDataSet);begin cdsAlunos.ApplyUpdates(-1);end;

Listagem 2 – Método ApplyUpDates do cd-sAlunos

Criando um layout para o frmAlunos e ligando-o ao DM

Até este ponto do exemplo não tem novi-dades para quem já trabalha com a tecnologia DBExpress, pois a conexão com o banco de dados, como foi dito antes, continua sendo feita da forma tradicional. Porém, agora temos que vincular os Fields do cdsAlunos, que se encontra no DM, a um componente TDataSource, que será adicionado no frmAlunos, ou seja, o frmAlunos terá que ter a declaração da unDm em sua cláusula Uses, isto pode ser feito visualmente pelo menu ‘File/Use Unit’, depois basta selecionar a unDm e confirmar clicando em Ok. Logo após adicione um DataSource ao frmAlunos e altere o Name dele para dsAlunos, este será a origem dos dados deste formulário, na propriedade DataSet selecione pelo combo a opção DM.cdsAlunos. Na VCL isto garantiria que qualquer componente DataWare, da palheta DataControls,

Page 13: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 2012 13

ligado ao dsAlunos poderia manipular um Field sem maiores complicações, bastaria apenas confi-gurar no componente o dsAlunos e o Field que ele representaria. Como estamos criando um projeto pela plataforma FireMonkey, isso já não é possível devido ao fato de não contarmos com estes com-ponentes DataWares, por isso teremos que fazer o uso do novo recurso de ligações LiveBindings, para podermos configurar os componentes visuais comuns para estarem gerenciando os dados a partir de expressões.

Para poder fazer um vinculo das expressões LiveBindings com o dsAlunos teremos é claro que definir um escopo para estas ligações, sendo assim adicione ao formulário um TBindScopeDB, altere seu Name para BindScopeDB e na propriedade DataSource selecione o dsAlunos, com isso qual-quer componente visual através da propriedade LiveBinding terá acesso aos Fields do cdsAlunos e poderá manipulá-los.

Agora vamos definir um layout para o frmA-lunos, veja na figura 2 uma sugestão, neste exem-plo será utilizado um BindNavigator da palheta LiveBindings, que tem a mesma funcionalidade de um DBNavigator, neste componente é neces-sário apenas configurar a propriedade BindScope selecionando o recém-criado BindScopeDB. Será necessário também adicionar os componentes de edição e visualização dos campos da tabela de alu-nos, neste caso iremos adicionar seis componentes TEdit lembrando de alterar a propriedades Name de cada um seguindo um padrão, por exemplo edtIdAluno, edtNome, edtDataNascimento, edtCPF, edtCidade e edtTelefone. Assim ficará mais fácil fazer a chamada deste componentes nas linhas de código. Coloque também um componente TCom-boEdit da palheta Additinonal, este tem a mesma função do combobox comum, onde se preenche uma lista de itens, estes que serão os valores a serem armazenados no banco de dados, altere o Name deste componente para cbeUF, e adicione as siglas das UFs na propriedade item separando cada uma por uma quebra de linha com o botão Enter, lembrando que o campo UF foi definido com o tipo Char (2), limitando o armazenamento a apenas 2 caracteres. Para listar os registros cadastrados no banco, em VCL usa-se um DBGrid, neste exemplo em Firemonkey será usado um TStringGrid, aletre seu Name para sgAlunos, mais a frente explicarei como fazer sua ligação com os dados.

Para finalizar o layout do frmAlunos, restam apenas distribuir os rótulos (Labels) de cada componente.

Agora vamos fazer as configurações LiveBin-

dings dos componentes, para que possibilite o acesso aos dados.

Figura 2 – Sugestão de layout para o frmAlunos

Configurando as ligações dos compo-nentes com o recurso LiveBindings

Tendo todos os componentes visuais ajustados ao layout do formulário, agora vamos fazer os vín-culos com os componentes de acesso aos dados via LiveBindings. Baseando-se na nomenclatura suge-rida dos componentes, selecione o componente edtIdAluno e na janela ObjectInspector localize a propriedade LiveBinding, ao clicar na combo serão listadas duas opções como mostra a figura 3, a opção NewLiveBinding seria para o caso de fazer uma ligação manualmente como foi mostrado no primeiro exemplo onde se informava a Contro-lExpression, a Direction, o SourceComponent e a SourceExpression, porém como neste exemplo as ligações serão feitas aos Fields do cdsAlunos escolheremos a segunda opção, Link to DB Field, abrirá uma janela listando os Fields vinculados ao BindScopeDB, ver figura 4, agora basta selecionar, neste caso, o Field ID_ALUNO e pressionar Ok. Faça isso para todos os componentes TEdit, defi-nindo corretamente seus BindLinks para os Fields correspondentes. No cbeUF (TComboEdit) depois de inserido as siglas das UFs na lista de itens, basta criar um BindLink para o campo UF da tabela, da mesma forma que foi feito com o edtIdAluno.

Figura 3 - Link to DB Field

Ao criar o primeiro DBLink, automaticamente é criado no formulário um componente TBin-dingsList, este é responsável por listar todas as expressões Binding presentes no formulário, pode--se também através deste componente editar as expressões listadas, alterando suas propriedades

de forma desvinculadas aos componentes de con-trole. Entenda que o BindingList utiliza o mesmo mecanismo de uma ActionList, ele agrupa todos os controles Bindings facilitando a visualização dos mesmos, veja na figura 5 a lista dos componentes do frmAlunos que é aberta logo após dar dois cliques no componente BindingsList.

Figura 5 - Lista de componentes Bindings

Para configurar a sgAlunos (TStringGrid) muda um pouco, mas continua seguindo a mesma linha de raciocínio dos BindLinks, porém a opção será Link to DB DataSource. Ao selecionar esta opção será aberta novamente a janela New DB Link para selecionar em qual o escopo está ligado o dsAlunos, neste exemplo temos apenas um escopo, mas po-deriam ser mais conforme as necessidades forem surgindo. Ao criar o BindLink para o sgAlunos, já está praticamente pronto nosso projeto, basta apenas realizar alguns ajustes para melhorar a forma de exibição dos dados na grid, logo abaixo da propriedade LiveBinding do componente sgAlunos, surgiu uma nova propriedade chamada DBLinks-gAlunos1, esta propriedade será criada em todos os componentes, ela se refere de fato ao BindLink vinculado ao objeto selecionado, neste caso o sgAlunos, iremos utilizar a propriedade Columns. Da mesma forma que no tradicional DBGrid da VCL, pode-se adicionar os campos do cdsAlunos na grid de forma manual, podendo assim definir a largura e o título da coluna de cada Field. Então

Figura 4 - New DB Link

Page 14: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 201214

clique na propriedade Columns e abrirá a janela para o gerenciamento das colunas da grid, basta clicar no botão inserir e selecionar os campos um a um, definindo suas propriedades, ver tabela 1.

Tabela 1 – Propriedades das colunas da sgAlunos

Ao preencher todas as propriedades das colu-nas da sgAlunos, nosso exemplo está quase pronto, basta alguns ajustes para uma melhor performan-ce. O ideal é que a conexão ao banco de dados seja aberta apenas uma vez ao abrir o formulário principal e fecha quando o mesmo seja encerrado. Como neste exemplo temos apenas uma tela, esta fará a função de abrir e fechar a conexão e também abrir e fechar o ClientDataSet utilizado na manipu-lação dos dados do formulário, o cdsAlunos. Para que isso seja possível, basta apenas duas linhas de códigos no evento onCreate e duas no evento onClose do frmAlunos. Veja a listagem 3.

procedure TfrmAlunos.FormClose(Sender: TObject; var Action: TCloseAction);begin

DM.cdsAlunos.Close; DM.CONEXAO.Connected := False;

end;

procedure TfrmAlunos.FormCreate(Sender: TObject);begin

DM.CONEXAO.Connected := True; DM.cdsAlunos.Open;

end;

Listagem 3 – Códigos de manipulação da co-nexão e do cdsAlunos na aplicação

Estes códigos garantem o desempenho do projeto em execução, mas temos que ter em mente a ordem de criação formulários na aplicação, acesse o menu do Delphi ‘Project/Options’ selecione a opção Forms e veja à direita a ordem em que será feito o auto-create, se o DM estiver em segundo lugar no seu projeto, arraste-o para a primeira posição, para que seja criado antes do frmAlunos e pressione Ok. Isso é feito para prevenir um futuro erro de execução. Veja que é feito o uso do DM no formulário de alunos, para abrir e fechar a conexão e o cdsAlunos, sendo assim isto não seria possível se o formulário de alunos fosse criado antes do DM, por isso o DM deve ser criado antes do formulá-rio. Agora sim, nosso exemplo está funcionando, pode fazer alguns cadastros de teste, note que a cada alteração nos componentes a grid vai sendo atualizada automaticamente como se fosse uma DBGrid mesmo. Veja na figura 6 a aplicação sendo executada.

Conclusão

Procurei mostrar neste artigo, de uma forma introdutória, um exemplo de como trabalhar com duas novas tecnologias do Delphi XE2, o Fire-Monkey e o recurso LiveBindings, para fazer uma aplicação com acesso à banco de dados. Vimos que mesmo num projeto FireMonkey a conexão via DBExpress mantém a mesma forma de trabalhar, alterando somente a forma de ligar os componen-tes visuais com os de acesso aos dados.

Além disso, ainda é possível fazer muitas outras coisas com o Firemonkey, como foi dito na introdução, é uma tecnologia bastante inovadora e cheia de recursos para os usuários distribuírem em suas aplicações. E está abrindo novas portas para os desenvolvedores adeptos ao Delphi.

Espero que tenham gostado do artigo, um abraço a todos e até a próxima.

Figura 6 - Projeto em tempo de execução

Consultor Técnico The Club.

Sobre o autor

Lucas Vieira de Oliveira

[email protected]

Page 15: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 2012 15

Android

Lendo e Carregando Arquivo Texto

Neste mês abordarei um pouquinho de como podemos criar e car-regar arquivos do tipo texto no Android armazenando estas informações no cartão SD do dispositivo. Montaremos um exemplo prático abordando recursos como: Criar e utilizar o evento Onclick() do botão, Utilização da classe “Java.IO” para manipulação de arquivos, entre outros recursos que poderão ser acompanhados ao decorrer da leitura.

Opções de Armazenamento

O Android nos fornece diversas formas para salvar os dados, sendo que a solução depende da necessidade, podendo assumir as seguintes formas:

SharedPreferences: Armazenar dados particulares primitivos em pares chave-valor.

Internal Storage: Armazenar dados privados na memória do dispositivo.

External Storage: Armazenar dados públicos sobre o armazenamento externo compartilhado.

SQLite DataBases: Armazenar dados estruturados em um banco de dados.

Como foi dito no início do artigo, usaremos a opção “External Storage”, que significa Armazenamento externo.

External Storage – Armazenamento Externo

Page 16: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 201216

Os dispositivos compatíveis com o sistema Android suporta uma memória externa compartilhada que podemos utilizar para diversas tarefas, como por exemplo manipular arquivos do tipo texto. Podendo ser um cartão SD ou uma memória interna não removível. Os arquivos salvos para o armazenamento externo são de leitura para todos podendo ser modificado pelo usuário.

Comandos úteis:

Environment.getExternalStorageState() : Comando necessário para veri-ficar se a mídia está disponível.

Environment.getExternalStorageDirectory(): comando para abrir um di-retório que representa a raiz do armazenamento externo, usando o diretório:

/Android/dados/<nome do pacote>/arquivos

Criando um exemplo prático

O lay-out da aplicação se dividirá em duas partes, a primeira iremos criar um arquivo do tipo texto e salvá-lo no cartão SD, já a segunda escolheremos o arquivo para posteriormente carregá-lo em um EditText.

Para isto abra seu Eclipse e clique em “File/New/Android Project” e crie um projeto em Android, recomendo a criação na versão 2.2 ou 2.3.

Adicionando permissões

Um detalhe importante para esse projeto é que será necessário habilitar a permissão “WRITE_EXTERNAL_STORAGE” no arquivo manifest, pois graças a essa permissão que seu aplicativo pode gravar arquivos no SD Card. Dê um duplo clique no arquivo “AndroidManifest.xml” e na aba “Permissions” clique no botão “Add” para adicionar o código a seguir. Ver Imagem 01.

android.permission.WRITE_EXTERNAL_STORAGE

Esta permissão indica que podemos salvar dados em um dispositivo

externo, o código deverá ficar parecido com o a seguir.

<?xml version=”1.0” encoding=”utf-8”?><manifest xmlns:android=”http://schemas.android.com/apk/res/android” package=”pct.Android_txt” android:versionCode=”1” android:versionName=”1.0”> <uses-sdk android:minSdkVersion=”8” />

<application android:icon=”@drawable/icon” android:label=”@string/app_name”>

<activity android:name=”.Android_txtActivity” android:label=”@string/app_name”> <intent-filter> <action android:name=”android.intent.action.MAIN” /><category android:name=”android.intent.category.LAUNCHER” /> </intent-filter> </activity> </application><uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE”/> </manifest>

Criando a interface gráfica

Trabalharemos com os componentes padrões do Android, como: TextView, EditText, Button e Spinner. A imagem 02 nos dá uma noção melhor de como os componentes deverão estar dispostos em nosso arquivo principal “main.xml”.

Podemos conferir o código XML correspondente logo em seguida.

<?xml version=”1.0” encoding=”utf-8”?><LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android” android:orientation=”vertical” android:layout_width=”fill_parent” android:layout_height=”fill_parent” android:weightSum=”1”>

Figura 01: Android Manifest Permissions.

Page 17: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 2012 17

<TextView android:text=”Diretório:” android:id=”@+id/txtRoot2” android:layout_width=”wrap_content” android:layout_height=”wrap_content”/> <TextView android:text=”Nome do arquivo txt:” android:layout_width=”wrap_content” android:layout_height=”wrap_content”/> <EditText android:id=”@+id/edtNomeArq” android:text=”” android:layout_width=”match_parent” android:layout_height=”wrap_content”/> <TextView android:text=”Texto do arquivo a ser salvo:” android:layout_width=”wrap_content” android:layout_height=”wrap_content”/> <EditText android:id=”@+id/edtSalvar” android:text=”” android:layout_width=”match_

parent” android:singleLine=”false” android:gravity=”top” android:lines=”5” android:layout_height=”120dp”/> <Button android:text=”Salvar txt” android:onClick=”click_Salvar” android:layout_height=”wrap_content” android:layout_width=”115dp” android:layout_gravity=”center_horizontal”/> <TextView android:text=” “ android:id=”@+id/txtPreencher” android:layout_width=”fill_parent” android:layout_height=”wrap_content”/> <LinearLayout android:layout_width=”fill_parent” android:gravity=”center_vertical” android:layout_height=”wrap_content”> <Spinner android:id=”@+id/spListarArquivos” android:layout_width=”220dp” android:layout_weight=”10” android:layout_height=”50dp”/> <Button android:layout_weight=”1.0” android:text=”Carregar txt” android:onClick=”click_Carregar” android:layout_width=”115dp” android:layout_height=”wrap_content”/> </LinearLayout> <TextView android:text=”Texto do arquivo a ser carregado:” android:layout_width=”wrap_content” android:layout_height=”wrap_content”/>

Figura 02: Disposição dos componentes.

Page 18: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 201218

<EditText android:id=”@+id/edtLer” android:text=”” android:layout_width=”match_parent” android:singleLine=”false” android:gravity=”top” android:lines=”5” android:layout_height=”120dp”/></LinearLayout>

Podemos rodar o exemplo e teremos uma tela parecida com a da Figura 03.

Figura 03: Lay-Out da aplicação.

Codificando o Exemplo

Usaremos alguns pacotes adicionais, sendo necessário adicioná-los ao projeto.

import java.io.BufferedReader;import java.io.File;import java.io.FileOutputStream;import java.io.FileReader;import java.util.ArrayList;import android.os.Environment;import android.view.View;import android.widget.ArrayAdapter;import android.widget.Spinner;import android.widget.TextView;import android.widget.Toast;

Criaremos também algumas variáveis ao decorrer do desenvolvimento, confiram a seguir:

private TextView txtRoot;private TextView txtNomeArq;private TextView txtSalvar;private TextView txtLer;private Spinner SpnListarArquivos;private ArrayList<String> Arquivos = new ArrayList<String>();

No evento OnCreate() faremos atribuições às variáveis e invocaremos o método Listar() seguido de um Try..Catch.

public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); try { setContentView(R.layout.main); txtRoot = (TextView) findViewById(R.id.txtRoot2); txtNomeArq = (TextView) findViewById(R.id.edtNomeArq); txtSalvar = (TextView) findViewById(R.id.edtSalvar); txtLer = (TextView) findViewById(R.id.edtLer); SpnListarArquivos = (Spinner) findViewById(R.id.spListarArquivos); txtRoot.append(ObterDiretorio()); Listar(); } catch (Exception e) { Mensagem(“Erro : “ + e.getMessage()); } }}

Achei necessário criar uma função Padrão Mensagem (), a qual será responsável notificar o usuário. Esta classe “Toast” se difere da “AlertDialog.Builder” pois a mesma apenas informa no rodapé inferior da tela do Android o ocorrido e logo em seguida desaparece, achei interessante usar este tipo de recurso para fins de aprendizado, podemos conferir a seguir o método que recebe como parâmetro uma String.

Page 19: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 2012 19

private void Mensagem(String msg) {Toast.makeText(getApplicationContext(),

msg, Toast.LENGTH_SHORT).show();}

O próximo método nos retorna o diretório de armazenamento externo.

private String ObterDiretorio(){ File root = android.os.Environment.getExternalStorageDirectory(); return root.toString();}

O método Listar() preencherá o componente Spinner com os arquivos do tipo “.txt” salvos no diretório externo. Usamos os tipos de variáveis File e File[], sendo respectivamente responsáveis por obter o diretório e os arquivos deste diretório. Adicionamos os arquivos em um “Array” para posteriormente utilizá-los.

public void Listar(){ File diretorio = new File(ObterDiretorio()); File[] arquivos = diretorio.listFiles();

if(arquivos != null) { int length = arquivos.length; for(int i = 0; i < length; ++i) { File f = arquivos[i]; if(f.isFile()) { Arquivos.add(f.getName()); } } ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_dropdown_item_1line, Arquivos); SpnListarArquivos.setAdapter(arrayAdapter); } }

Criando o método Salvar()

Ao clicarmos no botão Salvar executaremos o método “Click_Salvar”, usa-remos um Try..Catch, onde transformamos o texto digitado em um “Array de Bytes” e com o método “Write” inserimos os dados seguido de uma notificação ao usuário. Com o método Listar() atualizaremos o Spinner com o nome dos arquivos “.txt”. Ver Imagem 04.

public void click_Salvar(View v){ String lstrNomeArq; File arq; byte[] dados; try { lstrNomeArq = txtNomeArq.getText().toString(); arq = new File(Environment.getExternalStorageDirectory(), lstrNomeArq); FileOutputStream fos; dados = txtSalvar.getText().toString().getBytes(); fos = new FileOutputStream(arq); fos.write(dados); fos.flush(); fos.close(); Mensagem(“Texto Salvo com sucesso!”);

Figura 04: Salvando o Arquivo .txt.

Page 20: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 201220

Listar(); } catch (Exception e) { Mensagem(“Erro : “ + e.getMessage()); } }

Criando o método Carregar()

Já o método carregar, continuaremos a utilizar o Try..Catch, sendo que de primeiro momento pegamos o item que está selecionado no componente Spinner, limpamos o campo “txtLer” e logo em seguida efetuamos uma leitura linha a linha do arquivo carregando para a caixa de texto toda a informação lida. Ver Imagem 05.

public void click_Carregar(View v){ String lstrNomeArq; File arq; String lstrlinha; try {

lstrNomeArq = SpnListarArquivos.

getSelectedItem().toString(); txtLer.setText(“”); arq = new File(Environment.getExternalStorageDirectory(), lstrNomeArq);BufferedReader br = new BufferedReader(new FileReader(arq)); while ((lstrlinha = br.readLine()) != null) { if (!txtLer.getText().toString().equals(“”)) { txtLer.append(“\n”); } txtLer.append(lstrlinha); } Mensagem(“Texto Carregado com sucesso!”); } catch (Exception e) { Mensagem(“Erro : “ + e.getMessage()); } }

Conclusão

Este artigo nos demonstrou os conceitos básicos e essenciais para tra-balhar com arquivos textos no Sistema Android. Procurei demonstrar alguns recursos diferentes dos abordados nos meses anteriores a fim de aumentar nosso leque de aprendizado.

Vou ficando por aqui, um forte abraço e até o mês que vem!

Figura 05: Carregando o Arquivo .txt.

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]

Page 21: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 2012 21

D e l p h i Parte V

Vimos no artigo anterior, o inicio dos exemplos sobre banco de dados. Nesse artigo veremos mais dicas sobre desenvolvimento de aplica-ções cliente/server com dbExpress no Delphi, onde a principal será a parametrização dos cadastros.

Imagine o nosso cadastro de clientes tenha algo em torno de 500 registros, o que não é nada de tão absurdo.

Pelo que construímos até agora, terí-amos o DBNavigator para navegar entre os registros, o que não tem nenhuma facilidade.

Vamos alterar o projeto para que as consultas sejam parametrizadas e pos-samos modificar o cadastro. Teremos assim, performance da aplicação pois teremos em memória apenas os registros necessários para a edição dos dados.

Parametrizando as consultas

Page 22: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 2012

Para parametrizar as consultas preci-samos modificar a consulta SQL adicio-nando o parâmetro que desejamos. Veja no código a seguir, como ficará a consulta para o cliente.

select nCdCliente, sNmCliente, tDtNascimento, nVlLimite from CLIENTE where nCdCliente = :nCdCliente

Assim, criamos um parâmetro para a consulta (basta ter dois pontos antes). Ao fechar o editor, a propriedade Params do SQLDataset mapeia os parâmetros adicionados no SQL (Figura 1).

Configure o parâmetro para o tipo correto, nesse exemplo, ftInteger. Preci-samos “repassar” esse parâmetro para o ClientDataSet. Para isso, basta clicar com o botão direito no componente e escolher a opção Fetch Params. Pronto. Para conferir, acesse a propriedade Pa-ras do cdsCliente, ela deve ter a mesma configuração do dsCliente.

Agora, se abrirmos a aplicação você notará que nenhum registro é mostra-do. Obviamente, devido a mudança do SQL. Como podemos então mostrar os dados? Precisamos ter uma consulta auxiliar para buscarmos o registro que precisamos mudar.

Isso já introduz um conceito impor-tante no nosso projeto, o de performan-ce. Não precisamos retornar todos os

registros do cadastro (imagine 5, 10 mil registros) para modificar um apenas. Vamos retornar para o cadastro, apenas o registro que desejamos alterar.

Modificando o cadastro de cliente

Precisamos mudar o layout do ca-dastro de clientes. Precisamos adicionar uma pesquisa para que possamos retor-nar o registro que o usuário vai alterar. Vamos criar abas para o cadastro, onde teremos uma para o cadastro em si e outra para um grid de pesquisa.

Adicione um PageControl no formu-

lário e insira dois TabSheets. Crie uma aba com o texto: “Dados gerais” e outra como “Pesquisa”. Na aba Dados gerais adicione os controles de tela (podemos remover o DBNavigator). Veja na Figura 2 como ficou o cadastro.

Veja que nosso cadastro ficou mais

bonito. Agora, precisamos configurar a aba de pesquisa. Adicione um Edit, um Grid e um DataSource. Faça a ligação do DataSource com o grid. Veja na Figura 3 a aba de pesquisa.

Precisamos configurar uma consulta para ser usado na pesquisa do cadastro. Nesse tipo de pesquisa, não precisamos retornar uma quantidade grande de da-dos, precisamos apenas o código e um campo referente a descrição do cadastro (neste caso, o nome do cliente).

Vamos criar outro Data Module para conter os componentes para as pesqui-sas que vamos usar na aplicação. Fica a seu critério para usar apenas um Data Module, apenas atente para colocar o novo Data Module a ser criado na inicia-lização do projeto.

Pesquisas auxiliares

Figura 1. Configurando o parâmetro do cadastro de cliente

Figura 2. Usando abas no cadastro de clientes

Figura 3. Aba de pesquisa no cadastro de cliente

Page 23: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 2012

Crie um novo Data Module e adicione um SQLDataSet, um DataSetProvider e um ClientDataSet. Veja os componentes dispostos na Figura 4.

Figura 4. Data Module para os components de pesquisa

Aperte Alt + F11 para abrir o editor Use unit. Escolha DM. Você deve estar perguntando: “Nos componentes de pes-quisa, também preciso ter um trio para cada pesquisa?”. E a resposta é? Não.

Se vamos utilizar o ClientDataSet para pesquisar, não precisamos do trio, pois os outros componentes tem a responsa-bilidade de incluir dados no banco, como já comentamos.

Precisamos apenas configurar os componentes, como fizemos antes (vin-cular os componentes via propriedades) e modificar uma propriedade do DataSe-tProvider para que o ClientDataSet possa gerenciar a consulta SQL para trazer os dados para o componente.

Altere para true a propriedade Op-tions > poAllowCommandText do ds-pPesquisa. Agora, a consulta SQL para retornar os dados, vamos escrevê-la na propriedade CommandText do cdsPes-quisaCliente. Note que não temos um editor como o SQLDataSet, mas podemos digitar o SQL.

Digite o seguinte comando:

select nCdCliente, sNmCliente

from CLIENTE where UPPER(sNmCliente) like :sNmCliente

Veja que retornamos apenas dois campos e usamos o like, pois vamos fazer uma pesquisa parcial pelo nome do cliente. Configure o parâmetro para o tipo ftString.

Pesquisa parcial

Agora vamos mudar nossa tela de cadastro. Configure o DataSource para o cdsPesquisaCliente. No evento OnKeyDo-wn do Edit, digite o código da Listagem 1.

Listagem 1. Executando a consulta com parâmetros

if (Key = VK_RETURN) thenbegin DMPesquisa.cdsPesquisaCliente.Close; DMPesquisa.cdsPesquisaCliente.Params[0].AsString := UpperCase(‘%’+ edtPesquisa.Text + ‘%’); DMPesquisa.cdsPesquisaCliente.Open;end;

Veja que verificamos se o usuário usou a tecla ENTER, para executar o código. A seguir, fechamos o ClientDataSet e preenchemos o parâmetro configurado. Note que como usamos o comando Upper no SQL, também precisamos repassar o valor digitado em maiúsculo para uma perfeita comparação.

É importante notar, o tipo do parâmetro (string). Precisamos configurar o tipo correto, então usamos o AsString. No ClientDataSet do cadastro, o parâmetro é do tipo inteiro, então, quando fizermos essa filtragem precisamos usar a configuração correta (AsInteger).

Por fim, chamamos o Open para mostrar os dados retornados. Execute a aplicação e

faça pesquisas na aba. Ao entrar na aba e apertar ENTER, todos os registros são retor-nados. Poderíamos fazer uma restrição para que o usuário não possa fazer pesquisa sem digitar uma quantidade mínima de caracteres.

Isso auxilia, pois caso o cadastro possua muitos registros, o trafego da rede seria grande. O código seria:

if (Key = VK_RETURN) thenbegin if Length(edtPesquisa.Text) < 3 then ShowMessage(‘Digite no mínimo 3 caracteres.’) else ...

Digite algum valor e aperte ENTER e visu-alize os registros que atendem ao parâmetro digitado (Figura 5).

Figura 5. Cadastro com pesquisa auxiliar

Agora, precisamos configurar para que ao usuário dar um duplo clique no grid, ao escolher um registro, possamos filtrar os dados para o cadastro e mostrar o mesmo ao usuário. No evento OnDblClick do grid, adicione o código da Listagem 2.

Listagem 2. Filtrando o registro escolhido no grid

if (DMPesquisa.cdsPesquisaCliente.RecordCount > 0) thenbegin DM.cdsCliente.Close; DM.cdsCliente.Params[0].AsInteger :=

Page 24: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 201224

DMPesquisa.cdsPesquisaCliente.FieldByName(‘nCdCliente’).AsInteger; DM.cdsCliente.Open; pgCadastro.ActivePage := tabDados;end;

Primeiro, verificamos se existem registros no grid para executar a filtragem. Preen-chemos o parâmetro do componente de cadastro, com o valor do código presente no componente de pesquisa. Por fim, mostramos a aba de cadastro. Execute e teste a aplicação (Figura 6).

Figura 6. Pesquisa e filtragem do cadastro

Modificando o cadastro de empre-gados

Você pode pensar, as modificações no cadastro de empregados têm as mesmas características do cadastro de clientes. Em parte sim. Precisamos criar a pesquisa, alte-rar a consulta do cadastro, criar parâmetro e alterar o layout.

Mas se você recordar, no cadastro de empregados, temos um relacionamento com o setor, onde adicionamos um ComboBox para o usuário escolher o setor. OK, o cadas-tro de setor é pequeno, não valeria a pena a modificação, mas nesse caso, vou mostrar a alteração para fins de conhecimento.

Vamos remover o controle (ComboBox) e vamos criar uma consulta auxiliar (com uma nova tela) para o usuário pesquisar o setor que deseja. Assim, nosso cadastro estará parametrizado, otimizando a performance do mesmo.

Precisamos fazer uma modificação na consulta de empregados, para trazer, o nome do setor, pois temos que mostrar o nome (caso o cadastro tenha relacionamento) para o usuário. A Listagem 3 mostra o novo coman-do SQL do dsEmpregado no DM.

Listagem 3. Alterando a consulta de em-pregado para retornar o setor

select EMPREGADO.nCdEmpregado, EMPREGADO.nCdSetor, EMPREGADO.nPcComissao, EMPREGADO.sNmEmpregado, EMPREGADO.tDtAdmissao, SETOR.sNmSetorfrom EMPREGADO INNER JOIN SETOR ON SETOR.nCdSetor = EMPREGADO.nCdSetorwhere EMPREGADO.nCdEmpregado = :nCdEmpregado

Nota: Qualquer modificação feita no editor do SQL ou mesmo diretamente no comando, através da propriedade CommandText, o parâmetro deve ser reconfigurado, tanto no SQLDataSet, quanto no ClientDataSet.

Agora, precisamos configurar correta-mente o Field do novo campo (sNmSetor), para que o dbExpress não tente atualizar o mesmo quando for salvar o registro. Desmar-que todas as opções marcadas para o TField sNmSetor, assim, o dbExpress não tentará inserir/atualizar o mesmo.

Na tela de cadastro, adicione um DBText para mostrar o nome do setor (Figura 7).

Figura 7. Alterando o campo Setor no cadastro de empregado

Após as alterações, faça testes na apli-cação para visualizar o nome do setor na pesquisa (Figura 8).

Figura 8. Mostrando o nome do setor no cadastro

Agora, e quando quisermos alterar o setor? Vamos criar uma tela de pesquisa de setor. Crie um novo formulário e adicione os seguintes componentes: RadioGroup, DBGrid, Edit, Labels. Monte o formulário conforme a Figura 9.

Crie um componente para pesquisa de setor, semelhante aos de pesquisa de clien-te e empregado. Vincule o componente ao DataSource da tela, e esse ao DBGrid. No evento OnKeyDown do Edit, digite o código da Listagem 4.

Listagem 4. Código para pesquisa de setores

if Key = VK_RETURN thenbegin

Page 25: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 2012 25

DMPesquisa.cdsPesquisaSetor.Close; DMPesquisa.cdsPesquisaSetor.CommandText := ‘’;

if RadioGroup1.ItemIndex = 0 then begin if IsNumero(edtPesquisa.Text) then DMPesquisa.cdsPesquisaSetor.CommandText := ‘select nCdSetor, sNmSetor from SETOR where nCdSetor = ‘ + edtPesquisa.Text else ShowMessage(‘Digite um número para pesquisar por código’); end else begin if Length(edtPesquisa.

Text) < 3 then ShowMessage(‘Digite

no mínimo 3 caracteres.’) else DMPesquisa.cdsPesquisaSetor.CommandText := ‘select nCdSetor, sNmSetor from SETOR where

UPPER(sNmSetor) like ‘ + UpperCase(QuotedStr(‘%’ + edtPesquisa.Text + ‘%’)); end; DMPesquisa.cdsPesquisaSetor.Open;end;

Note que de acordo com o que for escolhido no RadioGroup, mudamos o con-teúdo do SQL passado para a propriedade CommandText. Para a pesquisa parcial (pelo nome do setor), implementamos uma vali-dação como já mostramos anteriormente. O comando QuotedStr, adiciona aspas simples (‘’) na consulta SQL, pois estamos trabalhando com string.

Para o código, criamos uma function que retorna se o valor digitado é um número para que não ocorra erro quando pesquisar-mos por código, sendo o que foi digitado é uma string. Veja na Listagem 5 o código do IsNumero.

Listagem 5. Função para validar se o valor é número

function IsNumero(sNumero: string): boolean;

begin try StrToInt(sNumero);

Result := true; except Result := false; end;end;

Qual a lógica da função. Executamos o comando que transforma uma string em nú-mero, dentro de um bloco try...exception, que caso ocorra erro, o código que será executado estará dentro do except. Assim, se nenhum erro ocorrer, o result será verdadeiro, senão, será falso.

Agora, no OnDblClick do grid para fechar-mos o formulário com o seguinte código:

if DMPesquisa.cdsPesquisaSetor.RecordCount > 0 thenbegin Close; ModalResult := mrOk;end;

Verificamos se existem registros no com-ponente de pesquisa, e depois o primeiro código fecha o formulário de pesquisa, já o segundo, indica o resultado que será verifi-cado no formulário que chamará a tela de pesquisa.

Para entender, adicione um botão no cadastro de empregados. Adicione o código da Listagem 6.

Listagem 6. Código para chamar o formu-lário de pesquisa

Application.CreateForm(TfrmPesquisarSetor, frmPesquisarSetor);try frmPesquisarSetor.ShowModal; if frmPesquisarSetor.ModalResult = mrOk then begin DM.cdsEmpregado.Edit;

Figura 9. Tela de pesquisa de setor

Page 26: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 201226

DM.cdsEmpregadosNmSetor.AsString := DMPesquisa.cdsPesquisaSetor.FieldByName(‘sNmSetor’).AsString; DM.cdsEmpregadonCdSetor.AsInteger := DMPesquisa.cdsPesquisaSetor.FieldByName(‘nCdSetor’).AsInteger; end;finally frmPesquisarSetor.Free;end;

Após a chamada do formulário (Show-Modal) verificamos o retorno do formulário através da propriedade ModalResult. Se o usuário não escolher nenhum registro, fechar o formulário, não precisamos executar o có-digo para alterar o nome do setor.

Caso o mesmo escolha um registro no grid, vamos chamar o método Edit do Clien-tDataSet de cadastro e atribuindo os valores para o nome do setor e o código do setor do cadastro de empregados. Veja na Figura 10 temos a aplicação em execução.

Finalizando as alterações

Pra finalizar, precisamos implementar os botões para inserir um novo, salvar ou excluir os registros da tela. Veja na Figura 11 como

ficará o layout dos cadastros.

Na Listagem 7 temos o código dos botões.

Listagem 7. Código dos botões

Novo

DM.cdsEmpregado.Insert;

Salvar

try DM.cdsEmpregado.Post; ShowMessage(‘Registro salvo com sucesso.’);except on E: Exception do ShowMessage(‘Ocorreu um erro: ‘ + E.Message);end;

Excluir

if (MessageDlg(‘Deseja excluir?’, mtConfirmation, [mbYes, mbNo], 0) = mrYes)

then DM.cdsEmpregado.Delete;

O botão Novo simplesmente chama o In-sert do ClientDataSet. Já no Salvar, colocamos um bloco try...except para que caso ocorra algum erro, uma mensagem com a descrição do erro, seja mostrada ao usuário.

O Excluir pede a confirmação da exclusão para o usuário e caso afirmativo, exclui o registro. Para excluir o registro no banco, pre-cisamos chamar o mesmo código que usamos no evento AfterPost visto no artigo anterior.

No DM, adicione o seguinte código no evento AfterDelete do cdsEmpregado (faça o mesmo para o cdsCliente):

cdsEmpregado.ApplyUpdates(0);

Faça todos os testes na aplicação: novo registro, salve e exclua. Faça as modificações no outro cadastro.

Novo cadastro e o que vem pela frente

Figura 11. Botões de cadastro

Figura 10. Alterando o setor com a pesquisa auxiliar

Page 27: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 2012 27

Agora que já aprendeu como fazer um cadastro simples parametrizado e como usar pesquisa auxiliar no cadastro, implemente o mesmo para a tabela PRODUTO. Adiantando o que teremos no próximo artigo, vamos criar um cadastro máster/detail, com o cadastro de vendas e seus respectivos itens.

Lembrando, para incluir os registros da tabela ITENS, precisamos ter o código da venda, presente na tabela VENDA, ou seja, precisamos incluir uma venda, recuperar seu código e inserir o mesmo quando salvar o item.

Como fazer isso? Dados em memória com o ClientDataSet. Além disso, precisamos de uma transação nisso, pois não podemos ter ITENS sem a VENDA e nem a VENDA sem seus ITENS. Veja que temos muito a aprender ainda.

Você deve estar perguntando: “Luciano, você sempre fala que o Delphi é produtivo, tem facilidades da programação OO, mas pelo que já vi até agora, tivemos dois cadastros (e teremos o terceiro), onde precisamos refazer layout e algumas validações, tipo replicando

É 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

código”.

Veremos nos próximos artigos algo bastante interessante e produtivo para apli-cações com Delphi, a facilidade que temos em criar telas de cadastros: a herança visual. Apenas para adiantar a ideia: teremos uma tela de cadastro padrão, com um layout (por exemplo, as abas e botões) comum para qualquer cadastro.

Nessa tela padrão, teremos código bas-tante genérico para ser usado independente de estarmos no cadastro de cliente, empre-gado ou qualquer outro. Vale a pena esperar.

Conclusão

Vimos nesse artigo, como utilizar de maneira correta, a criação de cadastros para-metrizados no Delphi para aplicações cliente/server. No próximo artigo, vamos criar uma característica muito comum em aplicações, o cadastro máster/detail.

Um grande abraço a todos e até a pró-xima!

Page 28: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 201228

Dicas DELPHIDBGrid com o scroll do mouse

Esta dica como o próprio título já propõem, se trata de trazer a funcio-nalidade do scroll do mouse para o componente DBGrid, facilitando assim a visualização dos registros, o que se torna um atrativo a mais para a aplicação aos olhos do usuário final.

Outra boa prática a ser utilizada, é a de criar esta funcionalidade num formulário base, ou seja, um formulário que servirá de base a outros formu-lários da aplicação, isto irá garantir que qualquer formulário que descender do formulário base tenha esta funcionalidade herdada.

Vamos então à codificação, iremos criar um procedimento para manipular uma mensagem que é enviada da aplicação ao Windows. Vamos partir da premissa que já tenha no formulário do Delphi um DBGrid conectado a um DataSource, este que por sua vez está ligado a um ClientDataSet que já esteja alimentando com os registros de uma tabela.

Então declare na sessão private da unit o procedimento.

private { Private declarations } procedure MsgWmKeyDown(var Msg: TMsg; var Handled: Boolean);

Após declarar o procedimento MsgWmKeyDown pressione as teclas (Crtl + Shift + C) para gerar o corpo do procedimento onde será implementado o seu código.

procedure TForm1.MsgWmKeyDown(var Msg: TMsg; var Handled: Boolean);var s: Smallint;begin if Msg.message = WM_MOUSEWHEEL then if (ActiveControl is TDBGrid) then begin

Msg.message := WM_KEYDOWN; Msg.lParam := 0;

s:= HiWord(Msg.wParam);

if s > 0 then Msg.wParam := VK_UP else Msg.wParam := VK_DOWN; end;end;

Neste procedimento verifica se a mensagem é WM_MOUSEWHEEL e logo em seguida verifica se o controle ativo é da classe TDBGrid. Depois vem os comandos para a ação do scroll do mouse.

Faça a chamada deste procedimento no evento onCreate do formulário da seguinte forma:

procedure TForm1.FormCreate(Sender: TObject);begin

Application.OnMessage := MsgWmKeyDown;

end;

Após adicionar o procedimento ao evento OnMessage da aplicação o exemplo está pronto e basta agora fazer seus testes, execute a aplicação e clique na DBGrid para ver a funcionalidade do exemplo.

Texto em 3D no Delphi com canvas

Com esta dica você poderá desenhar um texto em 3D no formulário com o canvas. Declare na sessão Private o seguinte código:

procedure imgPaintCanvas(RefCanvas: TCanvas; Texto: String; TamFonte, pHorizontal, pVertical: Integer);

Depois tecle Ctrl + Shift + C para gerar o corpo da procedure, e digite o seguinte código dentro do bloco begin e end:

procedure TfrmTexto3D.imgPaintCanvas(RefCanvas: TCanvas; Texto: String; TamFonte, pHorizontal, pVertical: Integer);Begin RefCanvas.Brush.Style := bsClear; RefCanvas.Font.Style := [fsBold]; RefCanvas.Font.Name := ‘Courier New’; RefCanvas.Font.Size := TamFonte; RefCanvas.Font.Color := clBlack; RefCanvas.TextOut(pHorizontal, pVertical, Texto); RefCanvas.Font.Color := clGray; RefCanvas.TextOut(pHorizontal - 1, pVertical - 1, Texto); RefCanvas.Font.Color := clSilver; RefCanvas.TextOut(pHorizontal - 2, pVertical - 2, Texto); RefCanvas.Font.Color := clBlack; RefCanvas.TextOut(pHorizontal - 3,

Page 29: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 2012 29

pVertical - 3, Texto);end;

Como podemos ver os parâmetros são de fácil compreensão, o RefCanvas se refere a qual propriedade de formulário será preenchida com o desenho, TamFonte se refere ao tamanho da fonte, pHorizontal e pVertical se referem sucessivamente ao ponto horizontal e vertical ao qual irá iniciar o desenho.

Para fazer o desenho em 3D, basta agora chamar este procedimento em algum evento do formulário passando os parâmetros corretamente, neste exemplo isso foi feito através de um clique de um TButton, veja o como foi feito a sua chamada na listagem abaixo:

procedure TfrmTexto3D.Button1Click(Sender: TObject);begin Texto3DCanvas(frmTexto3D.Canvas, ‘THE CLUB O MAIOR CLUBE DE PROGRAMADORES DO BRASIL’,15, 50, 50);end;

Ao visualizar com mais atenção o código do procedimento, fica claro que o mesmo pode ser customizado para atender qualquer cenário, espero que esta dica ajude de alguma forma até mais.

Converter número inteiro para ordinal por extenso

Esta dica se resume em uma função que recebe um parâmetro do tipo inteiro de no máximo três caracteres, para transcrevê-los em números ordinais por extenso, estes que serão o retorno da função do tipo String. Declare a função antes da diretiva Private.

function NumOrdinal(Numero: Integer): String; private

Tecle Ctrl + Shift + C para gerar o corpo da função. Serão declaradas algumas variáveis e constantes para poder manipular os dados corretamente, veja na seguinte listagem a implementação da função.

function TfrmNumerosOrdinais.NumOrdinal(Numero: Integer): String;var Conta : smallint; StrNumero, Texto : string;const Unidades: array[0..9] of string = (‘’, ‘Primeiro ‘, ‘Segundo ‘, ‘Terceiro ‘, ‘Quarto ‘, ‘Quinto ‘, ‘Sexto ‘, ‘Sétimo ‘,

‘Oitavo ‘, ‘Nono ‘); Dezenas: array[0..9] of string = (‘’, ‘Décimo ‘, ‘Vigésimo ‘, ‘Trigésimo ‘, ‘Quadragésimo ‘, ‘Quinquagésimo ‘, ‘Sexagésimo ‘, ‘Setuagésimo ‘, ‘Octogésimo ‘, ‘Novagésimo ‘); Centenas: array[0..9] of string = (‘’, ‘Centésimo ‘, ‘Ducentésimo ‘, ‘Tricentésimo ‘, ‘Quadringentésimo ‘, ‘Quingentésimo ‘, ‘Sexcentésimo ‘, ‘Septingentésimo ‘, ‘Octingentésimo ‘, ‘Noningentésimo ‘);

beginStrNumero := trim(IntToStr(Numero)); for Conta:= length(StrNumero) downto 1 do Begin if length(StrNumero) - Conta = 0 then Texto := Unidades[strtoint(copy(StrNumero, Conta, 1))]; if length(StrNumero) - Conta = 1 then Texto := Dezenas[strtoint(copy(StrNumero, Conta, 1))] + texto; if length(StrNumero) - Conta = 2 then Texto := Centenas[strtoint(copy(StrNumero, Conta, 1))] + texto; if length(StrNumero) - Conta > 2 then Texto := ‘Não sabe contar tanto, ainda. / ‘ + Texto;

end;

result:=texto;

end;

Para exemplificar a utilização desta função será adicionado no formulá-rio um TLabel, um TEdit e um TButton, veja na listagem Abaixo como fica a chamada da função:

procedure TfrmNumerosOrdinais.Button1Click(Sender: TOb-ject);

begin

if (Edit1.Text = ‘’) then Abort; Label1.Caption := NumOrdinal(StrToInt(Edit1.Text));

end;

Esta dica facilita o manuseio de números inteiros convertendo de maneira bem fácil para uma String de maneira ordinal. Espero ter ajudado com esta dica, até a próxima.

Page 30: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 201230

VerticalHorizontal

Page 31: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 2012

Page 32: megazine - The Club - O maior clube de programadores do ... · agosto 2012 05 C# Lngi uagem C# Criando Classes e Objetos Nesta importante etapa abordo um conceito geral de Classes

agosto 2012