Você está na página 1de 32

maio 2012

maio 2012

ndice
04
Android

14

Android Uma abordagem sobre persistncia de


dados

Autor: Thiago C.
Montebugnoli

C#

Delphi

Editorial

05

Drag and Drop com formulrios MDI no Delphi

Autor: Lucas Vieira de


Oliveira

09

Linguagem C# - Arrays, ArrayList e List

Autor: Marcos Csar


Silva

Delphi
Delphi - Parte III

Autor: Luciano
Pimenta

20
Desafio The Club

Dicas

28

Legenda

30

Iniciante
Intermedirio
Avanado
maio 2012

03

Bem-vindo
Av. Prof Celso Ferreira da Silva, 190
Jd. Europa - Avar - SP - CEP 18.707-150
Informaes e Suporte: (14) 3732-1529

Ol amigos do The Club, estamos aqui mais um ms trabalhando


duro para oferecer uma revista cada vez melhor e com um contedo mais diversificado.
O nosso maior compromisso sempre oferecer artigos e dicas
que sejam de grande utilidade.
Nesta edio nosso consultor tcnico Lucas de Oliveira traz um
artigo de como implementar o recurso Drag and Drop com formulrios MDI no Delphi, um artigo interessante para quem deseja
saber um pouco mais sobre este assunto.

Internet

http://www.theclub.com.br
Cadastro: cadastro@theclub.com.br
Suporte: suporte@theclub.com.br
Informaes: info@theclub.com.br
Skype Cadastro: theclub_cadastro
Skype Suporte: theclub_linha1
theclub_linha2
theclub_linha3

www.twitter.com/theclubbr

J o colaborador Luciano Pimenta continua sua trajetria com


o curso de Delphi XE2, trazendo informaes bsicas e essenciais
para o aprendizado.
Marcos Csar Silva aborda temas relacionados a linguagem C#,
escrevendo um pequeno artigo de como usar Array, ArrayList e
List.
Eu continuo escrevendo sobre o Sistema Android, sendo que
neste ms fao uma abordagem geral sobre assuntos relacionados
a persistncia de dados utilizando o Banco de Dados SQLite.
No deixem de conferir a seo de Dicas Delphi, que como
sempre vem nos ajudando nas dvidas do dia-a-dia.
Em nome de toda a equipe, obrigado a todos e boa leitura.
Um Forte abrao,

Copyright The Club 2012


Diretor Tcnico
Marcos Csar Silva
Diagramao
Eduardo Massud
Arte
Vitor M. Rodrigues
Reviso
Eliziane Valentim
Colunistas
Lucas de Oliveira
Luciano Pimenta
Thiago Cavalheiro Montebugnoli
Marcos Csar Silva

Impresso e acabamento:
GRIL - Grfica e Editora
Taquarituba-SP - Tel. (14) 3762-1345
Reproduo

Thiago Montebugnoli - Editor Chefe


thiago@theclub.com.br

04

maio 2012

A utilizao, reproduo, apropriao, armazenamento em banco


de dados, sob qualquer forma ou meio, de textos, fotos e outras
criaes intelectuais em cada publicao da revista The Club
Megazine so terminantemente proibidos sem autorizao
escrita dos titulares dos direitos autorais.
Delphi marca registrada da Borland International,
as demais marcas citadas so registradas
pelos seus respectivos proprietrios.

Delphi

Drag and Drop


com formulrios
MDI no Delphi
O conceito de arrastar e soltar
bastante conhecido pelos usurios de Windows, pois simplifica e muito a utilizao da
aplicao pelo usurio final. O Delphi permite
utilizar esta prtica em componentes derivados da classe TControls, atravs de alguns
eventos, propriedades e mtodos especficos
que auxiliam o procedimento desta ao.

importante compreender que para

utilizar esta ao de um formulrio at outro, as


propriedades FormStyle de ambos devem estar
configuradas como fsMDIChild.

Entendendo o conceito do drag on


drop

A ao comea com o click do mouse
sobre o componente de origem chamando o
mtodo BeginDrag(), e o encerramento tambm

controlado pelo objeto de origem a partir do evento


onEndDrag onde se define qual objeto receber o
objeto arrastado.

No objeto de destino, configura-se o
evento onDragOver que ir verificar se o parmetro
Source corresponde com o objeto de origem da
ao para poder aceitar com o mtodo Accept,
e tambm o evento onDragDrop que ir ativar o
mtodo EndDrop do objeto de origem.

maio 2012

05

Explicando o exemplo

A ideia principal que ao abrir a tela
de pedidos de clientes o usurio possa abrir ao
mesmo tempo a tela de cadastro (isso explica a
configurao de FormStyle = fsMDIChild).
Tendo as duas telas lado a lado, o usurio
poder consultar um produto e arrast-lo para a
tela de pedidos, assim chamando a tela de cadastro
de itens j em modo de insero, e ainda com o
produto arrastado j implementado ao campo que
refere-se ao produto do item.

O conceito bem simples e pode ser
implementado de vrias outras formas, neste
exemplo, poderamos fazer o mesmo com o cliente
do pedido, porm o conceito seria o mesmo.

4. O formulrio de cadastro de produtos


com a propriedade FormStyle = fsMDIChild,
dever conter um DataSource, um DBGrid
(desabilitado para edio), um DBNavigator,
um campo de busca, e os campos para o
cadastro dos produtos, na figura 1 segue um
layout de exemplo do formulrio de Cadastro
de produtos;

5. O Formulrio de pedidos com a propriedade FormStyle = fsMDIChild, ser dividido


em duas partes por ser mestre / detalhe. A
parte de cima ter um DataSource configurado
para a tabela de pedidos, um DBNavigator e
os campos de cadastro da tabela de pedidos.
Na parte de baixo, far referncia tabela de
itens e ter um outro DataSource, um DBGrid
(desabilitado para edio), mais trs botes
para gerenciar esses itens.

Figura 1 Exemplo da tela de Cadastro de


Produtos (Origem)

Pr-requisitos

Para este exemplo alguns requisitos
j devero estar em funcionamento, para que se
possa seguir com o exemplo, so eles:

1. Banco de dados com as tabelas


PRODUTOS, PEDIDOS e ITENS, se possvel j
alimentada com alguns registros para futuros
testes. Tendo um relacionamento mestre /
detalhe entre as tabelas PEDIDOS e ITENS,
onde item o detalhe do pedido;

Na figura 2 segue um layout de exemplo do


formulrio de pedidos;

6. Para editar os itens do pedidos ter


tambm um formulrio com a propriedade
FormStyle = fsNormal, ou seja, ele ser exibido
com o mtodo ShowModal. Dever ter um
DataSource configurado com a tabela de itens
e os devidos campos para o preenchimento
dos registros de itens.

Figura 2 Exemplo da tela de Pedidos (Destino)

Na figura 3 segue um exemplo de layout para


a tela de cadastro de itens de pedido.
2. Uma conexo com a base de dados
atravs de um DataModule. As providersFlags
devidamente configuradas. Neste exemplo, o
auto incremento dos campos chave feito pela
aplicao;

3. Um formulrio principal com a propriedade FormStyle = fsMDIForm, com um


menu fazendo a chamada dos demais formulrios Child;

06

maio 2012

Codificando o objeto de origem



O Objeto de origem do Drag on Drop se
encontra no formulrio de cadastro de produtos,
ele o DBGrid (Name = dbgPesquisa, Options/
dgEditing = False).
O usurio ir arrastar um campo do dbgPesquisa ao clicar em uma de suas clulas, ento o nosso
drag on drop ter incio no evento onCellClick do
dbgPesquisa, implemente o cdigo da listagem
um neste evento.

Figura 3 Exemplo da tela de cadastro de


Itens de Pedidos

procedure TfmProdutos.
dbgPesquisa
CellClick
(Column: TColumn);
begin
{

Objeto de Origem Ao de inicializar o


dragdrop
Inicializa o processo
de dragdrop ao clicar em
uma celula da grid
}
dbgPesquisa.
BeginDrag(True);
end;

atribuimos os valores
nos devidos Tfields dos
datasets
e tambm fazemos a
chamada do evento onclick
do btnIncluir item.
}
if (Target <> nil) then
if (dm.cdsItens.State
= dsBrowse) then
begin
dm.cdsItens.

Listagem 1 Objeto Origem Inicia o Drag


on Drop


Como j foi dito, o prprio objeto de
origem ir controlar tambm o fim da ao drag
on drop, entende-se com isso que o dbgPesquisa
ir descrever o que ir acontecer aps o objeto
de destino aceitar a ao, ou seja, aps finalizar
a ao, iremos dar um insert na tabela de itens j
implementando o valor da chave do produto e o
nome do mesmo para o campo virtual da tabela de
itens.
Veja o cdigo a ser implementado no evento
onEndDrag do dbgPesquisa na listagem 2.

procedure TfmProdutos.
dbgPesquisaEndDrag
(Sender, Target: TObject;
X,
Y: Integer);
begin
{
Objeto de Origem ao de finalizar o Drag
Drop
Define o procedimento
a ser tomado aps
finalizar a ao de
dragdrop
(quando solta o click
do mouse)
Como estamos
trabalhando com registros
da base de dados

Insert;
dm.cdsItensID_
PRODUTO.AsInteger:=
dm.cdsProdutosID_PRODUTO.
AsInteger;
fmPedidos.
btnIncluir.Click;
fmPedidos.Show;
fmPedidos.
dbgItensPedido.SetFocus;
end;
end;

Listagem 2 Objeto de origem dizendo os


procedimentos a ser tomado aps finalizar a ao

At aqui j configuramos o nosso objeto
de origem, agora o prximo passo codificarmos
o destino da ao drag on drop.
Vale lembrar que os dois formulrios estaro
utilizando cdigos entre si, ou seja, devem estar
declarados cada um na uses do outro, para fazer a
utilizao desses cdigos.

Codificando o objeto de destino



Seguindo o conceito do exemplo, o produto dever ser arrastado at a grid de itens na tela
de pedidos de clientes, ou seja, o nosso objeto de
destino ser a DBGrid (Name = dbgItem, Options/
dgEditing = False) que exibe os dados da tabela de
itens.

Importante saber que os botes de inse-

rir, editar e excluir item j devem estar funcionando


at este ponto, pois iremos usufruir do cdigo do
boto inserir ao trmino da ao como visto na
listagem 2.

Neste objeto, sero acionados dois
eventos para que a ao se realize corretamente.
No evento onDragOver, verifica se o parmetro
Source (indica o objeto de origem) confere com
o objeto esperado, se sim, atribui-se o valor True
para o mtodo Accept.
No evento onDragDrop, aps ser aceito o objeto arrastado da incio a finalizao do processo
chamando o mtodo EndDrag do objeto de origem
e passando um parmetro True, dizendo que a
partir desse ponto pode-se realizar os procedimentos contidos no evento onEndDrag do objeto
de origem.
Veja na listagem 3 os cdigos para implementar neste dois eventos do dgbItens.

procedure TfmPedidos.
dbgItensDragDrop(
Sender, Source: TObject;
X,
Y: Integer);
begin
{
Objeto Destino - Ao
de confirmao para o
DragDrop
Aps aceitar o objeto
arrastado, chama-se o
mtodo
EndDrag do objeto de
origem para finalizar a
ao DragDrop
}
if (Source = fmProdutos.
dbgPesquisa) then
fmProdutos.
dbgPesquisa.EndDrag(True);
end;
procedure TfmPedidos.
dbgItensDragOver(
Sender, Source: TObject;
X,

maio 2012

07

Y: Integer; State:
TDragState; var Accept:
Boolean);
begin
{
Objeto de Destino
- ao de verificar se
aceita o DragDrop
Verifica se o
componente sendo arrastado
pode
ser solto neste objeto
- Destino
}
if (Source = fmProdutos.
dbgPesquisa) then
Accept:= true;
end;

Listagem 3 Objeto de destino aceitando e


finalizando a ao drag on drop

Depois de realizadas estas codificaes
o exemplo estar pronto para o teste, execute o
projeto e abra ambas as telas de pedidos e cadastro
de produtos, insira um novo pedido com seus dados
E para inserir os itens basta clicar em um produto da tela de cadastro e levar o cursor do mouse
at a grid de itens na tela de pedidos, o cursor do
mouse assumir uma outra forma durante esta
ao, ao clicar na grid de itens, ser disparado o
evento onClick do Boto Incluir e assim ser aberta
a tela de cadastro de itens.
Veja na figura 4 este exemplo em tempo de
execuo.

Concluso

Figura 4. Projeto em Tempo de Execuo

perceber pelos procedimentos que ocorrem ao


trmino da ao, que apenas demos um insert na
tabela de itens e atribuimos ao campo ID_PRODUTO da tabela de itens o valor do ID_PRODUTO da
tabela de produtos.

Com base neste exemplo pode-se criar
outras funcionalidades para as suas aplicaes,
que facilitar a vida do usurio final, sem muitas

A nica exigncia para esta prtica entre forms


no Delphi, que sejam do tipo MDIChild.

Espero ter ajudado com as informaes
deste artigo, at a proxima.

Sobre o autor
Lucas Vieira de Oliveira


Com este artigo foi exemplificado uma
das vrias formas de se trabalhar com a ao de
arrastar e soltar utilizando o Delphi e seus formulrios do tipo MDI.
Trabalhando com registros da base de dados,
ou seja, de uma forma ilusria para o usurio ocorre
o evento Arrastar e soltar, porm como podemos
08

linhas de cdigos, apenas reutilizando eventos j


existentes de alguns botes ou outros objetos dos
forms.

maio 2012

Consultor Tcnico The Club.

suporte@theclub.com.br

Linguagem C#

Arrays, ArrayList
e List
Continuando com nossos artigos relacionados ao C#, escreverei
um pouco sobre os denominados
Arrays e das classes ArrayList e
List. De uma forma geral, estas
colees admitem insero e manipulao de vrios itens em seu
interior, podendo acess-los atravs
de ndices ou chaves. Mas qual seria
diferena entre eles? Falarei um
pouco de cada estrutura seguido de
exemplos prticos.

Crie uma aplicao Windows Forms


adicionando alguns componentes no
formulrio. A tela dever ficar idntica
a Imagem 01.

Array
So colees de dados de um mesmo
tipo, como por exemplo: texto ou inteiro.
Figura 01: Formulrio de Exemplos.
Uma caracterstica dos Arrays
que eles so estticos, ou seja, depois
maio 2012

09

de declarado no conseguimos aumentar o seu tamanho ou a quantidade de


posies em tempo de execuo.
A classe Array utiliza o Namespace System que j vem declarado por
padro.

Sintaxe:
Declarao da varivel:

<tipo>[] <variavel> = new


<tipo>[10];

Onde <tipo> o tipo de dados utilizado, <variavel> a varivel e String[10]


a quantidade de espao reservada na
memria.
Este Array ter capacidade de armazenar 10 posies.

Alimentando o Vetor:
<variavel>[0] = Valor;

J para armazenar comearemos pelo


ndice [0].
Percorrendo o Vetor:

foreach (var item in


valores)
{
//Recuperamos o item
}

Para recuperarmos todos os valores


podemos fazer um Foreach ou se desejarmos podemos tambm recuperar dados de um especfico ndice deste vetor.
Exemplo (Figura 02)

10

maio 2012

Figura 02: Exemplo de Array.

#region Trabalhando com


Arrays

valores_string[9] =
TESTE 09;

private void button1_


Click(object sender,
EventArgs e)
{
String[] valores_
string = new String[10];
valores_string[0]
TESTE 00;
valores_string[1]
TESTE 01;
valores_string[2]
TESTE 02;
valores_string[3]
TESTE 03;
valores_string[4]
TESTE 04;
valores_string[5]
TESTE 05;
valores_string[6]
TESTE 06;
valores_string[7]
TESTE 07;

foreach (var item in


valores_string)
{
listBox1.Items.
Add(item);
}
}

#endregion

ArrayList

=
=
=

So colees que podem ser de


diferentes tipos podendo armazenar valores inteiros, reais, booleanos, objetos,
textos, entre outros.

=
=

valores_string[8] =
TESTE 08;

Outra diferena que so dinmicos,


permitindo a insero de elementos em
Run-time pelo mtodo Add().
O namespace System.Collection
o responsvel por trabalhar com este
tipo de coleo.

foreach (var item in


valores)
{
listBox1.Items.
Add(item);
}
}
#endregion

List

Figura 03: Exemplo de ArrayList.

Sintaxe:

{
//Recuperamos o item
}

Declarao da varivel:

<ArrayList> <variavel> =
new <ArrayList>();

Onde <ArrayList> a classe ArrayList em questo e <variavel> a varivel utilizada.


Importante notar que no definimos
quantidade nenhuma de elementos.
Alimentando o Vetor:

<variavel>.Add(Valor);

Neste caso inserimos qualquer tipo


de dados.
Percorrendo o Vetor:
foreach (var item in
valores)

Utilizamos o mesmo procedimento


citado anteriormente.

#region Trabalhando com


ArrayList
private void button2_
Click(object sender,
EventArgs e)
{
ArrayList valores =
new ArrayList();
valores.Add(The
Club);
valores.Add(10);
valores.Add(20.5);
valores.Add(false);
valores.Add(true);
valores.
Add(Programadores);
valores.Add(25.5f);

O List uma mistura das melhores


caractersticas do Array com o ArrayList, pois com ela possumos uma
classe fortemente tipada (permite apenas um tipo de dados) e dinmica. Ela
se torna mais gil que a ArrayList por
economizar tempo em converso nos
denominados Boxing e Unboxing, se
destacando como uma tima opo para
quem quer agilidade e praticidade. O
namespace System.Collection tambm
o responsvel por trabalhar com este
tipo de coleo.

Sintaxe:
Declarao da varivel:

<List><tipo> <variavel> =
new <List><tipo>();

Onde <List> a classe List, <tipo>


o tipo de dado utilizado e <variavel> a
varivel utilizada.
Alimentando o Vetor:

<variavel>.Add(Valor);

Inserimos valores inteiros.


Percorrendo o Vetor:

maio 2012

11

foreach (var item in


valores)
{
listBox1.
Items.Add(item);
}
}
#endregion

Concluso
Neste artigo procurei demonstrar de
uma forma simples e direta a utilizao
dos principais tipos de colees de dados
em C#.
Figura 04: Exemplo de List.

foreach (var item in


valores)
{
//Recuperamos o item
}

Utilizamos o mesmo procedimento


citado anteriormente.

Estes exemplos so de extrema importncia para nosso aprendizado, pois


atravs destes poderemos continuar
com a caminhada no aprendizado desta
poderosa linguagem.

valores.
Add(1000000);
valores.
Add(10000000);
valores.
Add(100000000);
valores.
Add(1000000000);

Fica a a dica, abrao e at o ms


que vem!

Exemplo (Ver Figura 04)

#region Trabalhando com


List
private void button3_
Click(object sender,
EventArgs e)
{
List<int> valores =
new List<int>();
valores.Add(1);
valores.Add(10);
valores.Add(100);
valores.Add(1000);
valores.Add(10000);
valores.Add(100000);

12

maio 2012

Sobre o autor
Marcos Csar Silva
Consultor de Sistemas na consultoria de sistemas DataSmart e Consultor Tcnico do The Club, Bacharel em Cincia
da Computao, MBA em Gesto Empresarial, Certificaes
MCAD (Microsoft Certified Application Developer) e MCSD.
NET (Microsoft Certified Solution Developer .NET)

marcos@theclub.com.br

maio 2012

13

ANDROID
Uma abordagem
sobre persistncia
de dados

Ol amigos do The Club, tivemos outros artigos relacionados a persistncia de dados em banco no Sistema Android. Neste artigo vou procurar
detalhar um pouco mais dos recursos utilizados nos artigos anteriores e
conhecer outros para se trabalhar com Banco de Dados. Estas informaes
se tornam primordiais para quem est comeando a aprender este tipo
de linguagem de programao. Continuaremos trabalhando com o SQLite,
lembrando que o mesmo responsvel por persistir os dados no Banco.
O foco deste artigo permitir que os senhores montem uma tela simples
de cadastro e outra de consulta persistindo e trabalhando com os dados.

Criando um novo Projeto


Seguindo os mesmos passos dos artigos anteriores para criar um novo
projeto bem simples, clique em File/New/Project Android e configure as
propriedades da seguinte maneira:
Nome do Projeto: Android_BancoDados
Verso: Android 2.2
Aplicao: Android_BancoDados
Nome Pacote: pct. Android_BancoDados
Atividade: Android_BancoDadosActivity
Verso SDK: 8
14

maio 2012

Figura 01: Configuraes Iniciais.

A configurao dever ficar idntica a Imagem 01.


Para finalizar esta etapa clique em Finish.

Importando as telas
O passo seguinte seria aproveitarmos as telas e boa parte da codificao
do artigo Navegando entre Telas do Ms de Maro de 2012.
A diferena que estaremos persistindo os dados no Banco de Dados, ao
invs de salvar na memria em uma classe. Ver Imagem 02.

android:id=@+id/linearLayout5
android:layout_height=67dp>
<Button android:text= Anterior
android:id=@+id/btAnterior
android:layout_height=wrap_
content android:layout_
width=160dp></Button>
<Button android:text=Posterior
android:id=@+id/btPosterior
android:layout_width=160dp
android:layout_height=wrap_
content></Button>
</LinearLayout>

Implementando o mtodo para inicializar os componentes


Achei interessante e prtico criar um mtodo para iniciar os objetos
utilizados ao longo no desenvolvimento. So as mesmas variveis utilizadas
anteriormente, por isto no entrarei em detalhes.

Figura 02: Telas importadas do artigo do ms de Maro.


A Tela de Consulta possuir mais dois botes para navegao entre os
registros. Ver Imagem 03 e em seguida o cdigo XML correspondente.
<LinearLayout
android:layout_width=match_parent

public void InicializaObjetos()


{
//Variveis utilizadas no
Cadastro

rgCursos = (RadioGroup)
findViewById(R.id.rgCursos);
rbLiteDelphi = (RadioButton)
findViewById(R.id.rbLiteDelphi);
rbLiteC = (RadioButton)
findViewById(R.id.rbLiteC);
rbProfessional = (RadioButton)
findViewById(R.id.rbProfessional);
rbStudent = (RadioButton)
findViewById(R.id.rbStudent);
txtCliente = (EditText)
findViewById(R.id.edtCliente);
txtCidade = (EditText)
findViewById(R.id.edtCidade);
spEstado = (Spinner)
findViewById(R.id.spnEstado);

//Variveis utilizadas na
Consulta
txtCli = (TextView)
findViewById(R.id.lbCliente);
txtCid = (TextView)
findViewById(R.id.lbCidade);
txtEst = (TextView)
findViewById(R.id.lbEstado);
txtCur = (TextView)
findViewById(R.id.lbProduto);
txtCod = (TextView)
findViewById(R.id.lbCodigo);
}

Implementando o mtodo para Abrir ou Criar o Banco de


Dados
Figura 03: Tela de Consulta.
maio 2012

15

Para darmos continuidade ao artigo abra nossa Activity em Android_


BancoDados\src\pct.Android_BancoDados\Android_BancoDadosActivity.java.
Importaremos duas classes responsveis pela manipulao de dados,
sendo:

Iniciamos o mtodo com um try/catch para validar a criao ou abertura


do BD. Usaremos o mtodo OpenOrCreateDatabase para criar o Banco de
Dados contendo os seguintes parmetros:

Import android.database.sqlite.SQLiteDatabase: Seria o Banco de Dados


propriamente dito, ou seja, responsvel por armazenar as informaes.
Import android.database.Cursor: Esta classe responsvel por manipular,
navegar entre os registros do Banco de Dados.
Logo em seguida criaremos os objetos dentro da Activity.
SQLiteDatabase BancoDados = null;
Cursor cursor;

Devemos tambm criar um mtodo responsvel por abrir ou criar o


Banco de Dados.
public void AbreouCriaBancoDados()
{
try
{
BancoDados = openOrCreateDatabase
(DBTHECLUB,
MODE_WORLD_
READABLE, null);
String sql = CREATE TABLE IF NOT
EXISTS TB_THECLUB

+(COD_CLI INTEGER
PRIMARY KEY, +
NOM_CLI TEXT, END_CLI TEXT, TEL_
CLI TEXT, PRO_CLI TEXT);

BancoDados.execSQL(sql);
Mensagem(Mensagem, Banco Criado
com Sucesso!);

}

catch (Exception e)

{
Mensagem(Mensagem, Erro ao criar
ou abrir o Banco de Dados!);
}
}
public void Mensagem(String Titulo,
String Mensagem)
{
AlertDialog.Builder infoResultado
= new
AlertDialog.
Builder(Android_BancoDadosActivity.
this);
infoResultado.setTitle(Titulo);
infoResultado.
setMessage(Mensagem);
infoResultado.
setNeutralButton(Ok,null);
infoResultado.show();
}
16

maio 2012

A prxima etapa ns escrevemos a instruo SQL para criar a tabela de


TB_THECLUB caso j no exista em nosso Banco de Dados. O comando BancoDados.execSql(sql) responsvel por esta tarefa.
Utilizamos um mtodo j abordado em outros artigos para podermos exibir
uma mensagem informativa ao usurio, obtendo ou no sucesso na criao
ou abertura de nosso Banco de Dados SQLite.

Implementando o mtodo para Buscar os dados


Este mtodo ir realizar a consulta SQL no SQLite retornando os dados
para o Cursor.
public void BuscarDados()
{
try
{
cursor = BancoDados.
query(TB_THECLUB,
new string[]
{NOM_CLI,CID_
CLI,EST_CLI,PRO_CLI},
null,
null,
null,
null,
null);


if (cursor.
getCount()!= 0 )

{

cursor.
moveToFirst();

}
}
catch (Exception e)
{
MensagemAlerta(Mensagem, Erro ao
buscar dados no Banco de Dados!);
}
}

Iniciamos o mtodo com um try/catch para validar a obteno dos dados


usando o mtodo Query.
Neste caso atribumos nossa consulta ao Cursor instanciado no incio
do artigo. Explicarei todos os argumentos na tabela a seguir.

Argumentos do Mtodo BancoDados.query()


O mtodo cursor.GetCount() nos permite descobrir se possumos ou
no registros, J o cursor.MoveToFirst() nos desloca para o primeiro Registro
da tabela.

Implementando o Mtodo para Mostrar os Dados


Quando executamos uma consulta com o BD armazenamos os dados no
cursor, portanto agora precisamos recuperar os registros para poder mostrar
em um textbox por exemplo.
Veja a seguir o mtodo que faz exatamente esta tarefa.
public void MostrarDados()
{

txtCod.setText(cursor.
getString(cursor.
getColumnIndex(COD_CLI)));
txtCli.setText(cursor.
getString(cursor.
getColumnIndex(NOM_
CLI)));
txtCid.
setText(cursor.getString(cursor.
getColumnIndex(CID_CLI)));
txtEst.setText(cursor.
getString(cursor.
getColumnIndex(EST_CLI)));
txtCur.setText(cursor.
getString(cursor.
getColumnIndex(PRO_CLI)));
}

O mtodo GetString() retorna uma string a partir de um index. Portanto


utilizamos o GetColumnIndex() passando como parmetro o nome do campo
para obter o registro correspondente.

Implementando o mtodo para Gravar os Dados


A rotina GravarDados nos permite persistir os dados no SQLite. Sempre
quando trabalhamos com Banco de Dados recomendvel utilizar o try/Catch.
Segue a seguir a instruo.
public void GravarDados()
{

try

String strPro = ;

switch (rgCursos.
getCheckedRadioButtonId())

{
case R.id.rbLiteDelphi : strPro
= The Club
Lite (Delphi) R$59,90;

break;

case R.id.rbLiteC : strPro = The
Club Lite (Delphi) - R$59,90;

break;

case R.id.rbProfessional : strPro =
The Club Lite (Delphi) - R$59,90;

break;

case R.id.rbStudent : strPro = The
Club Lite
(Delphi) - R$59,90;

break;
}

String sql = INSERT INTO TB_
THECLUB (NOM_CLI, CID_CLI, EST_CLI,
PRO_CLI) VALUES (

+ txtCliente.getText().
toString() +,

+ txtCidade.getText().
toString()+,

+ spEstado.
getSelectedItem().toString()+,

+ strPro+);


BancoDados.execSQL(sql);
MensagemAlerta(Mensagem, Dados
salvos com Sucesso!);

}

catch (Exception e)

{
MensagemAlerta(Mensagem, Erro ao
gravar dados no Banco de Dados!+e.
toString());
}
finally

{

BancoDados.close();

}
}

O mtodo BancoDados.execSQL() responsvel por montar a instruo


de Insert no BD.
O que fazemos de diferente aqui que recuperamos os dados das respectivas variveis (nome,cidade,estado e produto) e finalizando a instruo com
uma mensagem informativa ao usurio.
O mtodo BancoDados.close() limpa o objeto da memria no permitindo recri-lo desnecessariamente.

maio 2012

17

Implementando os mtodos RegistroAnterior e RegistroPosterior


Estes mtodos so reponsveis por realizar a navegao entre os registros
de nosso Banco de Dados. Novamente implementamos o Try/Catch, s que
neste caso informaremos ao usurio caso no exista mais registros para navegao que ele est no primeiro ou ltimo registro de nossa tabela.
public void RegistroAnterior()
{

try

{

cursor.moveToPrevious();

MostrarDados();
}

catch (Exception e)

{
MensagemAlerta(Mensagem, Voc est no
primeiro registro!);
}
}
public void RegistroPosterior()
{

try

{

cursor.moveToNext();

MostrarDados();
}

catch (Exception e)

{
MensagemAlerta(Mensagem, Voc est no
ltimo registro!);
}
}

O mtodo que faz este trabalho de navegao o cursor.moveToPrevious() e o cursor.moveToNext(), sendo que o primeiro se movimenta para
o registro anterior e o segundo para o posterior. Logo em seguida invocaremos
o mtodo MostrarDados() para preencher nossos respectivos objetos.

Mtodos ChamaMenuPrincipal(), ChamaCadastro() e ChamaConsulta()


Estas rotinas j foram abordadas em artigos anteriores. Neste artigo foram
implementadas novas funcionalidades para as mesmas.
public void ChamaMenuPrincipal()
{

setContentView(R.layout.main);

ChamaCadastro();
ChamaConsulta()
}
public void ChamaCadastro()
{
Button btCadastrar = (Button)
findViewById(R.id.btCadastrar);
btCadastrar.setOnClickListener(new View.
OnClickListener()
18

maio 2012

{

@Override

public void onClick(View v)

{
setContentView(R.layout.
cadastro);
btEfetuar = (Button) findViewById(R.
id.btnEfetuar);
btEfetuar.setOnClickListener(new View.
OnClickListener()

{
@Override
public void
onClick(View arg0)
{

AbreouCriaBancoDados();

InicializaObjetos();

GravarDados();
}
});

Button btVoltarCadastro = (Button)
findViewById(R.id.btVoltarCadastro);
btVoltarCadastro.setOnClickListener(new
View.OnClickListener()

{

@Override
public void
onClick(View v)


{

ChamaMenuPrincipal();
}

}
);

}
});
}

O boto Efetuar encarregado de persistir os dados, ento nele que


chamamos o mtodo AbreouCriaBancoDados() para abrir ou criar a estrutura,
logo em seguida Inicializamos os objetos com o mtodo InicializaObjetos() e
finalizamos com o GravarDados(). Ver Imagem 04.
public void ChamaConsulta()
{
Button btConsultar = (Button)
findViewById(R.id.btConsultar);
btConsultar.setOnClickListener(new View.
OnClickListener()
{

@Override

public void onClick(View v)

{
setContentView(R.layout.
consulta);
AbreouCriaBancoDados();

InicializaObjetos();

BuscarDados();

MostrarDados();

Button btAnterior = (Button) findViewById(R.

}
);


}
}
);
}

No ChamaConsulta() tambm inicializamos o mtodo AbreouCriaBancoDados(), logo em seguida o InicializaObjetos(). O prximo passo utilizamos o
BuscarDados() e por final o MostrarDados(). Como nesta tela utilizamos mais
outros dois controles para navegao entre os registros, ento aqui o local
de chamar o RegistroAnterior() e o RegistroPosterior(), ambos para navegao
entre os dados. Ver Imagem 05.

Figura 04: Tela de Cadastro Finalizada.

id.btAnterior);
btAnterior.setOnClickListener(new View.
OnClickListener()
{
@Override
public void
onClick(View arg0)
{

RegistroAnterior();
}
}
);

Button btPosterior = (Button)
findViewById(R.id.btPosterior);
btPosterior.setOnClickListener(new View.
OnClickListener()
{
@Override
public void
onClick(View arg0)
{

RegistroPosterior();
}
}
);

Button btVoltarConsulta = (Button)
findViewById(R.id.btVoltarConsulta);
btVoltarConsulta.setOnClickListener(new
View.OnClickListener()

{
@Override
public void
onClick(View v)
{

ChamaMenuPrincipal();
}

Figura 05: Tela de Consulta Finalizada.

Concluso
Procurei neste artigo abordar de uma forma simples a persistncia de
dados utilizando o sistema Android. Dividi em pequenas rotinas cada estrutura
para podermos dar uma maior abordagem sobre o assunto. Finalizamos duas
telas principais, uma de Cadastro e outra de Consulta.
Abrao e at o ms que vem!

Sobre o autor
Thiago Cavalheiro Montebugnoli
Thiago Cavalheiro Montebugnoli tecnlogo, formado pela Faculdade
de Tecnologia de Botucatu SP (FATEC) foi consultor tcnico 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 Processamento de Dados da Prefeitura Municipal de Ita-SP. Possui as seguintes
certificaes: MCP - Microsoft Certified Professional, MCTS - Microsoft Certified Technology Specialist, MCAD - Microsoft Certified Application Developer
e MCSD - Microsoft Certified Solution Developer.

thiago@theclub.com.br

maio 2012

19

Delphi

Parte III
Vimos no artigo anterior, um
pouco sobre os tipos de dados suportados pelo Delphi, assim como
estruturas de cdigo para desenvolvimento de projetos com Delphi.
Nesse artigo, vamos conhecer uma
das melhores bibliotecas de componentes visuais das ferramentas
de desenvolvimento, a VCL (Visual
Library Component).

A VCL acompanha o Delphi desde a


sua primeira verso e a cada nova verso
da ferramenta, aprimora e cria novos
componentes. E tambm, a grande notcia, que podemos criar nossos prprios
componentes, alm de estender os j
existentes.
Na continuao do nosso curso, vamos aprender a criar um componente.

Tool Palette
20

maio 2012

Os componentes da VCL ficam na


Tool Pallete, onde esto organizados
por categorias (tambm chamadas de
abas). Como podemos ver na Figura 1,
com algumas categorias.
Essas so apenas algumas das categorias que temos, a VCL composta
de muitos outros componentes. Vamos
conhecer os principais nesse artigo, alm
de mostrar seu funcionamento.

basta usar a propriedade ItemIndex. Para


o ListBox, se desejarmos que mais de
um item seja selecionado, basta alterar
MultiSelect para true e o usurio segurar a tecla CTRL ao clicar nos itens para
selecionar mais de um.
Os menus so bem simples de serem
criados, basta adicionar um MainMenu
no formulrio e dar um duplo clique no
mesmo.

Figura 1. Algumas abas da Tool Palette do Delphi XE2

Aba Standard
A aba possui os componentes mais
comuns para criao de aplicaes
Win32 no Delphi.
Label (rtulo), Edit (caixa de texto),
Button (boto), ComboBox (caixa de
combinao), ListBox (caixa de seleo),
MainMenu e PopupMenu (menu e menu
de contexto), Panel (container para outros componentes) etc.
O Edit e o Label so fceis de entender, como j vimos nos exemplos do artigo anterior. Fica uma dica interessante
para a validao que faz o Edit, onde
podemos configurar para que o mesmo
aceite somente nmeros, alterando a
propriedade NumberOnly para true.

pois a necessidade que temos de apenas clicar no mesmo.

Um editor ser aberto e para criar


o menu, basta digitar o nome que ser
mostrado na propriedade Caption. Assim, o menu superior ser criado e voc
pode criar a hierarquia do mesmo.
Veja na Figura 4 o menu sendo criado.

Para mostrar uma imagem, use a propriedade ImageIndex, juntamente com a


vinculao de um controle ImageList no
propriedade Images.
Outra propriedade interessante a
Style, onde podemos configurar o boto
no estilo Vista/7 com uma descrio auxiliar. Temos tambm no Style uma configurao para que seja mostrada uma lista
suspensa, usando o tipo bsSplitButton.
Depois, basta configurar a propriedade DropDownMenu com um PopupMenu
para ter as opes ao clicar no boto
(Figura 3).

Veja o resultado na Figura 2 caso o


usurio tente digitar caracteres que no
seja nmeros.

Figura 4. Criando a estrutura dos menus

Voc tambm pode configurar imagens para o menu, basta vincular a


propriedade Images do MainMenu para
um ImageList. Aps, nos itens do menu,
escolha a imagem na propriedade ImageIndex. A imagem exibida somente
em tempo de execuo.
A configurao do PopupMenu
idntica, com apenas a diferena que no
temos menus superiores (menus pais),

Figura 3. Button com estilos diferentes


Figura 2. Validao do Edit para aceitar somente
nmeros

O Button possui poucas configuraes em relao a sua funcionalidade,

Para o ListBox e ComboBox, temos a


propriedade Items onde preenchemos
os valores que queremos que aparea no
controle. Para saber o ndice selecionado,

Figura 5. Opes do BitBtn e SpeedButton

maio 2012

21

mas a configurao dos itens, com nome


e imagens a mesma. Para integrar um
PopupMenu com um controle (ou at
mesmo o formulrio), basta vincular o
componente a propriedade PopupMenu.

Expanded.
Vamos configurar a imagem dos painis e dar ttulos aos mesmos (propriedade Caption), exemplificado pela Figura 7.

Os outros componentes presentes


nessa aba sero mostrados no decorrer
do curso, para que no fique cansativo,
mostrar todos.

Aba Additional
Nessa aba, encontramos alguns
componentes com visual mais arrojado,
vamos dizer assim. Temos dois tipos
de botes, o BitBtn e o SpeedButton.
O primeiro possui uma propriedade
chamada Kind, onde de acordo com a
opo escolhido, um tipo de imagem
mostrada.
J no SpeedButton, temos a aparncia de um boto flat, de acordo com a
propriedade Flat do mesmo. Veja na Figura 5 as opes do BitBtn e SpeedButton
Um componente presente em novas
verses do Delphi o ButtonedEdit. Com
ele, podemos adicionar em uma caixa
de texto dois botes, usando imagens.
Os botes podem ficar alinhados a direta ou esquerda. Pessoalmente, achei o
controle muito legal, pois utilizo em sistemas, botes para realizarem consultas
auxiliares, onde o boto de pesquisa fica
ao lado da caixa de texto.
Com o ButtonedEdit, basta indicar
uma imagem para o boto direito e terei
uma caixa de texto, que indica que tenho
uma consulta para realizar ali. Sobre os
eventos dos botes, temos os OnRightButtonClick e o OnLeftButtonClick, logicamente um evento Click para cada boto.
No controle, temos ainda a propriedade para somente nmeros do Edit
(ButtonedEdit descende de TCustomEdit), podemos indicar um Hint para o
boto etc. Veja na Figura 6 o controle.
Para configurar essas imagens, primaio 2012

Figura 6. Usando o ButtonedEdit

meiro, temos que configurar um ImageList para a propriedade Images do ButtonedEdit. Aps, usando as propriedades
RightButton e LeftButton, configuramos
o ndice da imagem e tambm por fim,
configurando a propriedade Visible para
True.
Outro componente que acho muito
bom o CategoryPanelGroup, pois tem
a capacidade de criar painis e dentro
desses, adicionar controles. Com isso,
podemos fazer um painel de navegao
semelhante ao NavBar da sute DevExpress. Se voc no conhece o NavBar,
veja nesse link: www.devexpress.com/
Products/VCL/ExNavBar.
Vamos criar um painel de navegao
muito incrementado. Adicione o controle
em um formulrio. Adicione trs painis,
clicando com o boto direito e escolhendo Add Panel.
Na propriedade Images do CategoryPanelGroup, vamos vincular um
ImageList com imagens grandes, do
tipo 24x24 (referente ao tamanho da
imagem, que no componente ser configurado nas propriedades Height e Width), que so as imagens que aparecero
no ttulo dos painis.
Voc pode configurar a imagem que
vai aparecer quando o painel estiver
expandido ou recolhido, quando o
mouse passar sobre a imagem, tudo isso
usando as propriedades: XXHotImageIndex, XXImageIndex e XXPressedImageIndex, onde o XX indica ser Collapsed ou

Figura 7. Configurando ttulos e imagens do painel

Agora, vamos adicionar um Button


ao primeiro painel. Altere as seguintes
propriedades do Button: Align = alTop,
Style = bsCommandLink. Adicione um
ImageList no formulrio com imagens do
tamanho 16x16 ou a seu critrio.
As mesmas sero vinculadas aos
botes.
Vincule o ImageList ao boto, usando
a propriedades Images e adicione a imagem atravs da propriedade ImageIndex.
Para finalizar a configurao do boto,
vamos incluir um texto alternativo sobre
o Caption do boto, usando a propriedade CommandLinkHint.
Veja que temos um Caption e um
texto abaixo do mesmo. Esse padro
do Windows Vista/7, portanto essa configurao s funciona nesses Sistemas
Operacionais.
Claro, que poderamos ter uma ActionList (para que no conhece as facilidades da ActionList veremos isso adiante na
nossa srie de artigos) para concentrar
as regras dos botes, mas aqui, vamos
apenas copiar e colar os botes, alterando apenas Caption, CommandLinkHint e
ImageIndex.
Veja na Figura 8 como fica o componente na sua configurao final.

do hint, somente o ttulo e a imagem.


Assim, podemos mostrar vrias formas
diferentes, sem esquecer claro, de
colocar o caractere | para separar as
partes (Figura 9).

Width. Ainda na aba Win32 temos o


PageControl controle muito utilizado
para organizar melhor os componentes
visuais no formulrio.
Pra cada TabSheet (aba) do PageControl, voc configura a mesma individualmente, em suas propriedades e
adicionando componentes. Nas abas
podemos configurar imagens, usando um
ImageList e tambm mudar a orientao
das abas, podendo ficar em qualquer dos
4 lados do componente.

Figura 9. Hint com layout diferenciado


Figura 8. CategoryPanelGroup configurado

Outro controle bastante requisitado


pelos desenvolvedores um Hint mais incrementado. Controles visuais, possuem
uma propriedade chamada CustomHint,
nela vamos vincular um BallonHint para
mostrar dicas em formato de balo, com
ttulo, subttulo e imagens. Se voc no
quiser usar o CustomHint do controle,
no tem problema, seu hint continuar
funcionando perfeitamente.
No BallonHint, configuramos um ImageList atravs da propriedade Imagens.
Aps, vinculamos o BallonHint, atravs
do CustomHint do controle. Na propriedade Hint, escrevemos a dica que ser
mostrada. Podemos dividir o texto em
trs partes: a primeira o ttulo do Hint,
a segunda um texto auxiliar e a terceira,
a imagem que vamos usar.

Temos muitos componentes legais e


interessantes nessa aba, que teramos
que escrever um livro para falar de todos.
No decorrer do curso, ser mostrado
mais alguns e voc pode conseguir exemplos dos mesmos na internet.

Aba Win32

Um exemplo: uma agenda telefnica,


as abas so o alfabeto e voc tem um grid
onde ser modificado, de acordo com a
aba clicada (letra). Veja na Figura 11, um
exemplo dos controles.

Nessa aba, temos vrios componentes interessantes, como o ImageList, j


visto em muitos exemplos deste artigo.
Ele serve como um container para armazenar imagens e atravs de ndices
associ-las a outros componentes. Para
adicionar as imagens, basta dar um duplo
clique no componente e utilizar o editor
(Figura 10).
O tamanho das imagens definido
utilizando as propriedades Height e

Elas devem ser separadas pelo caractere pipe |, assim um hint pode
ser colocado com o seguinte valor:
Cadastro|Cadastro de Clientes|2. O
primeiro texto, ser o ttulo do balo, o
segundo a descrio do hint e o ltimo
o ndice da imagem que temos no ImageList vinculado ao BallonHint.
Se quisermos, podemos jogar
com essas trs opes, por exemplo:
Cadastro||2, no mostrar a descrio

Diferentemente do PageControl, o
TabControl, no trabalha com abas individuais. Voc adiciona as abas, usando a
propriedade Tabs (um TStrings) e qualquer componente adicionado, ser visualizado em todas as abas. Esse controle
serve para voc adicionar apenas alguns
controles e eles mudarem de acordo com
o clique de cada aba.

Figura 10. Editor para adicionar imagens no


ImageList

Figura 11. Usando TabControl e PageControl

Temos ainda nessa aba um ProgressBar (barra de progresso) para voc


informar ao usurio sobre determinado
processando com uma barra visual. Temos tambm uma StatusBar (barra de
status) que ajuda bastante para passar
informaes teis para o usurio, atravs
de seus painis. Veremos mais adiante,
um exemplo bem legal sobre esses dois
componentes.
maio 2012

Podemos citar ainda nessa aba os


componentes para calendrio: DateTimePicker e MonthCalendar. O primeiro,
mostra em uma caixa de texto uma data,
onde podemos clicar na imagem lateral e
escolher a data ou apenas digit-la com
formataes e validaes. O segundo
mostra um painel com as informaes
de data de um ms inteiro (Figura 12).

Figura 12. Componentes para trabalhar com datas


e horas no Delphi

A Toolbar (barra de botes) facilita


bastante o agrupamento de funcionalidades do seu software, onde podemos
increment-lo com imagens de fundo
(utilizando em conjunto com o Coolbar),
agrupamento de botes (onde somente
um boto pode ser marcado de cada vez)
e a customizao dos botes.

mostrar o assistente para personalizar a


barra de ferramentas.
Para mostrar o rtulo do boto utilize
a propriedade ShowCaptions da barra,
o rtulo aparece ao lado do cone. Selecione alguns botes e altere para True
a propriedade Grouped e em Style para
tbsCheck.
Quando o usurio clicar no boto, ele
ficar marcado, e sair desse estado
somente quando outro boto do grupo
for pressionado (no mesmo estilo dos
botes de alinhamento). Caso voc deseje que um boto fique pressionado e
somente com um novo clique do mouse,
volte ao estado normal (como por exemplo, os botes de formatao: negrito,
itlico, sublinhado), altere a propriedade
AlowAllUp para True e em Style configure
para tbsCheck.
Podemos criar botes ao estilo do
Run do Delphi, onde mostra um menu ao
clicar na seta do boto. Altere a propriedade Style do boto para tbsDropDown,
e ligue um PopupMenu na propriedade
DropDowMenu. Na Figura 13 temos
os exemplos citados anteriormente do
Toolbar.

Adicione um Toolbar no formulrio


e alguns botes (clique com o boto
direito e escolha New Button). Vamos
deixar a barra com a caracterstica de,
ao passarmos o mouse sobre os botes,
os cones mudam de cor.
Coloque dois ImageList no formulrio
e no primeiro adicione cones que sero
mostrados na barra. No segundo adicione os cones que aparecero quando o
mouse passar pelo boto (disponha-os
na mesma ordem do primeiro ImageList).
Na propriedade HotImages do Toolbar indique o ImageList2, e nas propriedades Images e DisabledImagens configure com o ImageList1. Rode e teste.
Para adicionar e remover os botes
da barra em tempo de execuo altere
a propriedade Customizable para True,
e depois (com a aplicao rodando) d
um duplo clique no componente. Isso ir
24

maio 2012

imagem do item e imagem para quando


o mesmo estiver selecionado. J com o
ListView voc tem que configurar colunas
e os itens a serem mostrados.
No ListView temos a opo de criar
grupos para os itens. Vale ressaltar que
essa funcionalidade esta presente apenas no ambiente do Windows Vista/7.
Adicione um ListView e crie dois grupos,
clicando com o boto direito e escolhendo o item Groups Editor. Em Header
indicamos o texto que ser mostrado
no grupo.
Crie uma coluna e alguns itens. No
editor de itens, agora temos mais uma
opo que se refere ao grupo ao qual o
item estar vinculado, como podemos
ver na Figura 14.

Figura 14. Vinculando o item ao grupo

Basta indicar as imagens que deseja


e temos um ListView com um layout com
grupos (Figura 15).

Figura 13. Configurando os botes da Toolbar

O ListView um controle onde podemos mostrar informaes em listas.


Um exemplo: o painel lateral direito
do Windows Explorer, onde aparecem
as pastas e arquivos. O do lado direito
o Treeview (tambm presente nessa
aba), que uma forma hierrquica de
apresentar informaes.
O Treeview basta acessar a propriedade Items e no editor, criar a estrutura
que desejar. Voc adicionar o texto,

Figura 15. ListView com grupos

Aba Data Controls


Na aba Data Controls temos os componentes mais comuns do Delphi (aba
Standard) que possuem a capacidade de

mostrar dados de uma consulta (tambm


conhecidos como componentes data-aware). Nessa aba encontramos componentes descentes de Edit, Label (DBText),
ListBox, ComboBox, etc. Alm claro do
DBGrid muito usado para mostrar dados
em forma de tabela.

Veja na Figura 16 o exemplo dos


controles da aba Data Controls.

Veremos mais adiante a utilizao de


vrios exemplos com os componentes.
Agora faremos um exemplo simples. Adicione um ClientDataSet e um DataSource
da aba Data Access (conheceremos mais
esses componente na parte de banco
de dados).
Clique com o boto direito no ClientDataSet e escolha Load from MyBase
table. Escolha um arquivo XML (temos
exemplos na instalao do Delphi). Aps
isso, os dados do XML ficam em memria
no ClientDataSet.
Para mostrar esses dados em componentes visuais, precisamos da ajuda
do DataSource que seria a ponte entre
a fonte de dados (ClientDataSet) e o
componente.
Use a propriedade DataSet do DataSource para escolher o ClientDataSet1.
Adicione alguns componentes da aba
Data Controls. Para alguns componentes,
como DBGrid e DBNavigator, precisamos configurar apenas a propriedade
DataSource.
Para outros, precisamos indicar o
campo da consulta que queremos mostrar, usando a propriedade DataField.
Para os controles ListBox e ComboBox,
usamos as mesmas propriedades, mas
que servem para salvar o respectivo
campo.
Se quisermos mostrar dados de um
consulta, nesses tipos de controles, devemos usar outros, o DBLookupListBox
e o DBLookupComboBox usando as
propriedades ListSource (para o DataSource), ListField (campo a ser mostrado)
e KeyField (normalmente o campo chave
que desejamos recuperar para salvar).

Figura 16. Componentes data-aware do Delphi

Dicas avanadas
Nessa seo vou mostrar algumas
dicas de componentes vistos anteriormente, que utilizando algumas linhas de
cdigo, podemos modificar seu layout,
adicionar imagens etc. Componentes,
como: ListBox, ComboBox, StatusBar
entre outros, no possuem uma propriedade para que possamos ligar um item
a uma imagem ou cone. Mas, podemos
mostrar essas imagens, pintando as
mesmas nos componentes, utilizando a
classe Canvas.
Para testar, coloque em um formulrio o ListBox e um ImageList. Adicione
alguns cones, altere a propriedade Style
do ListBox para lbOwnerDrawFixed e no
evento OnDrawItem adicione o cdigo
da Listagem 1.

Listagem 1. Pintado imagens no


ListBox

procedure TForm2.
ListBox1DrawItem
(Control:
TWinControl;
Index: Integer;
Rect: TRect; State:
TOwnerDrawState);

begin
ListBox1.Canvas.
FillRect(Rect);
ListBox1.Canvas.
TextOut(Rect.Left+18,
Rect.Top,
ListBox1.
Items[Index]);
ImageList1.
Draw(ListBox1.Canvas,
Rect.Left, Rect.Top,
Index);
end;

Esse cdigo pode ser adaptado para


qualquer componente onde podemos
utilizar a classe Canvas, como ComboBox,
CheckListBox, StatusBar etc (Figura 17).

Figura 17. Adicionando cones em ListBox, CheckListBox e ComboBox

Agora, vamos colocar uma barra de


progresso (ProgressBar) em um painel do
StatusBar. Adicione em um formulrio os
seguintes componentes: um StatusBar,
um ProgressBar e um Button.
Adicione painis no StatusBar, clicando com o boto direito no componente
e escolhendo Panels Editor. Altere a
propriedade Style do primeiro painel

Figura 18. ProgressBar dentro de um StatusBar com


cones nos painis

maio 2012

25

para psOwnerDraw. No evento OnDrawPanel do StatusBar digite o cdigo da


Listagem 2.
Listagem 2. Mostrando uma barra de
progresso em um painel

procedure TForm3.
StatusBar1DrawPanel
(StatusBar: TStatusBar;
Panel: TStatusPanel;
const Rect: TRect);
begin
if Panel.Index = 0 then
begin
ProgressBar1.Width :=
Rect.Right - Rect.Left +
1;
ProgressBar1.Height :=
Rect.Bottom - Rect.Top +
1;
ProgressBar1.
PaintTo(StatusBar.Canvas.
Handle,
Rect.Left, Rect.
Top);
end;
end;

No cdigo verificamos se o primeiro


painel, pois podemos colocar o ProgressBar em um painel e utilizar os demais
para outras tarefas. Agora no OnClick do
boto adicione o cdigo da Listagem 3.
Listagem 3. Configurando a barra de
progresso

procedure TForm3.
Button1Click
(Sender: TObject);
var
i: integer;
begin
for i := ProgressBar1.
Min to ProgressBar1.Max do
begin
ProgressBar1.Position
:= i;
StatusBar1.Repaint;

26

maio 2012

Sleep(10);
end;
ProgressBar1.Position :=
ProgressBar1.Min;
StatusBar1.Repaint;
end;

No cdigo, realizamos um lao entre


o valor mnimo e o valor mximo da barra
de progresso e incrementamos com valor
da varivel a sua posio (propriedade
Position), repintamos o StatusBar e damos uma pausa (Sleep).
Depois do lao colocamos a posio
da barra de progresso com o valor mnimo e repintamos novamente o StatusBar.
Por fim, altere para False a propriedade
Visible do ProgressBar. Rode a aplicao
e teste a barra de progresso no painel da
barra de status.
Para colocar cones nos painis da
StatusBar, utilize o mesmo cdigo do
exemplo do ListBox, apenas adaptando-o para utilizar as propriedades do
StatusBar e seus painis. Apenas tome
cuidado no evento OnDrawPanel, pois
nele estamos verificando o painel a ser
preenchido com a barra de progresso.
Veja no cdigo da Listagem 4, como seria
a adaptao.
Listagem 4. Mostrando a barra de
progresso e cones nos painis da StatusBar

if Panel.Index = 0 then

end
else
begin
StatusBar1.Canvas.
FillRect(Rect);
StatusBar1.Canvas.
TextOut(Rect.left + 18,
rect.Top, Panel.Text);
ImageList1.
Draw(StatusBar.
Canvas,rect.left,

rect.top,Panel.Index);
end;

Separamos o primeiro painel do


restante, onde sero mostrados os
cones, por que no podemos mostrar
cones e a barra de progresso ao mesmo
tempo. Veja na Figura 18 o exemplo em
execuo.
Podemos adicionar em um painel do
StatusBar o Hint (dica) do componente
selecionado ou que esta sendo mostrado
pelo mouse. Para isso altere a propriedade AutoHint do StatusBar para True, e a
propriedade Style do painel para psText.

Nota: O valor da propriedade


Hint do item de menu, caso possua
valor, tambm ser mostrado no
StatusBar quando o mouse passar
sobre o mesmo.

Outra dica que podemos fazer no


StatusBar seria mostrar ao usurio
quando as teclas CAPSLOCK, NUMLOCK
e SCROLLLOCK estejam ativadas ou desativadas. Para isso, basta verificarmos
a funo GetKeyState (passando como
parmetro a tecla desejada), e verificar o
valor retornado: par quando a tecla esta
ativada e mpar para desativada.
Para a tecla NUMLOCK podemos
utilizar o cdigo da Listagem 5 no evento
OnKeyDown do formulrio (alterando
tambm KeyPreview para True).

Listagem 5. Configurando teclas para


serem mostradas nos painis

procedure TForm4.
FormKeyDown
(Sender: TObject;
var Key: Word; Shift:
TShiftState);
begin

e cor do painel.
if odd (GetKeyState(VK_
NUMLOCK)) then
StatusBar1.Panels[1].
Text := NUM
else
StatusBar1.Panels[1].
Text := ;
end;

Para saber o cdigo das outras teclas


procure por Virtual key codes no Help do
Delphi. Rode a aplicao e ative/desative
as teclas para testar. E para finalizar, caso

deseje mudar a cor de fundo de um painel, basta adicionar o seguinte cdigo:

StatusBar1.Canvas.Brush.
Color := $00FFEECC;

Esse cdigo dever ser usado no


bloco de cdigo onde configuramos os
cones para os painis. A cor voc coloca a que for mais conveniente para seu
projeto. Veja na Figura 19 outra barra de
status, usando as configuraes de tecla

Concluses
Como j comentei, teramos que ter
um livro para mostrar todos os componentes da VCL. Tentei mostrar os mais
comuns e mais interessantes. Componentes que no mostrei nesse artigo
devero ser vistos no decorrer do curso,
como componentes para relatrios, aba
dbExpress, Ribbon etc.
Um grande abrao a todos e at a
prxima!

Sobre o autor
Luciano Pimenta

Figura 19. Ativando teclas e pintando o fundo do


painel

Tcnico em Processamento de Dados, desenvolvedor Delphi/C# para aplicaes


Web com ASP.NET e Windows com Win32 e Windows Forms. Palestrante da 4 edio
da Borland Conference (BorCon).
Autor de mais de 60 artigos e de mais de 300 vdeos aulas publicadas em revistas
e sites especializados. consultor da FP2 Tecnologia (www.fp2.com.br) onde ministra
cursos de programao e banco de dados. desenvolvedor da Paradigma Web Bussiness em Florianpolis-SC.

www.lucianopimenta.net

maio 2012

27

Dicas DELPHI

end;
end;

Funo que retorna o nmero de ocorrncias de uma substring dentro de uma string

Uses
StrUtils
function TForm1.OcorrenciaString(SubString,
StringPrincipal: String;
Sensitive: Boolean): Integer;
var
PosOcorrencia : Integer;
Sub, Principal : String;
begin
if (Sensitive) then
begin
Sub := SubString;
Principal := StringPrincipal;
end
else
begin


Um exemplo de utilizao: Considere o caminho C:\
Arquivos de Programas\Projeto\Reports, para saber o nvel da
pasta Reports utilize a \ como substring e faa a busca no
caminho completo, retornar o nmero trs correspondente ao
nvel da pasta. A varivel booleana Sensitive pode ser utilizada
com uma CheckBox, para habilitar e desabilitar o case-sensitive
da busca.

Como colocar captions nos botes do DBNavigator



O DBNavigator no tem propriedade caption,
porm, vamos criar uma classe chamada TCaptionNavigator e a partir dela atribuir as legendas dos botes de
navegao.

Coloque um DBNavigator no formulrio, e crie
uma nova classe na Unit.
var
Form1: TForm1;

Sub := LowerCase(SubString);
Principal :=
LowerCase(StringPrincipal);
end;
Result := 0;
//funo PosEx da biblioteca StrUtils,
//ela retorna a posio da primeira
ocorrncia

type
TCaptionNavigator = class(TDBNavigator);


No evento onCreate do formulrio vamos implementar o cdigo para adicionar os captions aos botes do DBNavigator. Preste ateno que criamos uma constante chamada
Captions que um array que receber os captions de cada
boto seguindo a ordem da esquerda para a direita. Em seguida
criaremos uma varivel chamada Boto, que far referncia aos
botes do DBNavigator. Veja na listagem 2 a implementao
do cdigo.

//de uma cadeia de caracteres dentro de


uma outra cadeia.
PosOcorrencia := PosEx(Sub, Principal, 1);
while (PosOcorrencia <> 0) do
begin
Inc(Result);
//dentro do loop indica-se a prxima
posio
PosOcorrencia := PosEx(Sub,
Principal, PosOcorrencia +
Length(SubString));

28

maio 2012

procedure TForm1.FormCreate(Sender:
TObject);
const
Captions : array[TNavigateBtn] of String
= (
Primeiro, Anterior,
Prximo,
ltimo, Incluir,
Excluir, Editar,
Salvar, Cancelar,
Atualizar);
var

Botao : TNavigateBtn;
begin
for Botao := nbFirst to nbRefresh do
begin
with TCaptionNavigator(DBNavigator1).
Buttons[Botao] do
begin
Caption := Captions[Botao];
end;
end;
end;

Concluso

Foi criado um lao de repetio para navegar um a um
entre os botes do DBNavigator, e assim adicionando a cada
boto seu respectivo caption.

Verificando a quantidade de energia restante na bateria

procedure TForm1.Button1Click(Sender:
TObject);
var
StatusBateria: TSystemPowerStatus;
begin
GetSystemPowerStatus(StatusBateria);
if Boolean(StatusBateria.ACLineStatus)
then
begin
ShowMessage(Este computador est
ligado fonte!);
end
else
begin
ShowMessage(Format(Energia restante
na bateria: %d %., [StatusBateria.
BatteryLifePercent]));
end;
end;

Gerador de Senhas Pronunciveis

function Senha: string;


const

consoantes: array [0..19] of Char =


(b, c, d, f, g, h, j,
k, l, m, n, p, r, s,
t, v, w, x, y, z);
vogais: array [0..4] of Char = (a,
e, i, o, u);
var
i: Integer;
begin
Result := ;
randomize;
for i := 1 to 4 do
begin
Result := Result +
consoantes[Random(19)];
Result := Result + vogais[Random(4)];
end;
end;

Atualizando todas as pginas do Internet Explorer ao mesmo


tempo

uses
MSHTML_TLB, SHDocVw_TLB;
procedure TForm1.Button1Clici(Sender:
TObject);
var
Janelas: IShellWindows;
Navegador: IWebbrowser2;
Disp: IDispatch;
Doc: IHTMLDocument2;
i: Integer;
begin
Janelas:= CoShellWindows.Create;
for i:= 0 to Janelas.Count do
begin
Disp:= Janelas.Item(i);
if Disp = nil then
Continue;
Disp.QueryInterface(iWebBrowser2,
Navegador);

if Navegador <> nil then

begin

Navegador.Document.
QueryInterface(IHTMLDocument2, Doc);
if Doc <> nil then
begin
Navegador:= Janelas.Item(i) as
IWebbrowser2;
Navegador.Refresh;
end;
end;
end;
end;
maio 2012

29

Horizontal

30

maio 2012

Vertical

maio 2012

maio 2012