Você está na página 1de 272

Fábio José de Gondra Ramos

gondraf@hotmail.com
Delphi 2005 for win32 Página 1 de 272

Capitulo I – Definições

Sistema Operacional: Conjunto de pequenos softwares capazes de controlar as diversas funções


de um hardware.

Exemplos: WINDOWS, LINUX, DOS, UNIX... etc

Linguagem: Conjunto de códigos capazes de descrever uma ação a ser realizada por um
processador ou sistema computacional.

Linguagem estruturada: É toda linguagem onde as linhas de comando seguem uma seqüência
lógica continua ou em rotinas interligadas entre si.

Exemplos: CLIPPER, BASIC, FORTRAN, NATURAL, C... etc

Linguagem orientada a objeto: É a linguagem onde se utilizam formas gráficas (Objetos) com
características próprias e independentes, capazes de realizar um procedimento através de uma ação
que assim o determine.

Exemplos: DELPHI, VISUAL BASIC,... etc

Constantes: São informações que possuem um valor predefinido, que não se altera durante um
processo.

As constantes podem ser classificadas em numéricas ou alfanuméricas também conhecidas como


strings:

Exemplo Constante Tipo Característica


A:=5 5 Numérica Aceita cálculos numéricos
A:= B*30 30 Numérica Se apresenta sempre fora de aspas
A:=’Delphi’ ‘Delphi’ String Se apresenta sempre entre aspas
A:=’Delphi ‘+’2005’ ‘Delphi’ e ‘2005’ String Aceita cálculos lógicos

Variáveis: São posições definidas na memória e reservadas para guardar dados ou resultados de
cálculos.

As variáveis podem ser:

Tipo Descrição Exemplo


Variant Assume qualquer valor V1: Variant;
Integer Assume um valor inteiro I: Integer;
Real ou Doublé Assume um valor real D: Double;
String Assume um valor string (alfa-numérico) S: string;
Boolean ou Lógico Assume um valor lógico B:Boolean;

Com exceção das variáveis do tipo variant, toda variável possui uma faixa de abrangência para
guardar valores, dependo a capacidade de armazenamento a variável pode ser:

Faixa de abrangência Formato


Variável Integer
De Até Sinal Bits
Integer/Longint -2.147.483.648 2.147.483.647 Positivo/Negativo 32
Longword/Cardinal 0 4.294.967.295 Positivo 32
Byte 0 255 Positivo 8
Int64 -263 2631 Positivo/Negativo 64
Shortint -128 128 Positivo/Negativo 8
Smallint -32.768 32.767 Positivo/Negativo 16
Word 0 65.535 Positivo 16
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 2 de 272

Variável Real Faixa de abrangência Formato


ou Doublé De Até Dígitos Bits
Real -5 * 10324 1,7 * 10308 1516 64
Real48 -2,9 *1039 1,7 * 1038 1112 48
45
Single -1,5 * 10 3,4 * 1038 78 32
324
Doublé -5 * 10 1,7 * 10308 1516 64
4951
Extended -3,6 * 10 1,1 * 104932 1920 80
63
Comp -2 + 1 263 - 1 1920 64
18
Currency -9 * 10 9 * 1018 1920 64

Variável String Faixa de abrangência Memória ocupada


Char 1 caracter 1 byte
String / ShortString 255 caracteres De 2 até 256 bytes
AnsiString Aproximadamente 231 caracteres De 4 bytes até 4 gigabytes
WideString Aproximadamente 230 caracteres De 4 bytes até 4 gigabytes

Variável Faixa de valores Formato


Lógica Verdadeiro False Tipo associado Bits
Boolean 1 0 Byte 8
ByteBool Diferente de 0 0 Byte 8
WordBool Diferente de 0 0 Word 16
LongBool Diferente de 0 0 Integer/Longint 32

As variáveis serão sempre representadas por letras, podendo ou não, serem seguidas por outras
letras ou números e nunca estarão entre de aspas.

Exemplos:
Nome:String;
A1:Integer;
Preço_de_custo:Currency.

Operadores: São símbolos ou expressões capazes de gerar um cálculo lógico ou aritmético.

Os operadores são classificados segundo seu cálculo, podendo ser:

• Atribuição: Atribuir valores a uma variável ou propriedade de um objeto;


• Aritmético: Efetuam cálculos aritméticos;
• Lógicos: Efetuam cálculos lógicos;
• Relacionais: Efetuam cálculos relacionais;
• Set: São operadores predefinidos em funções; ou
• @ retorna o endereço de uma variável, função, procedimento ou método.

Operadores de atribuição:

Operador Exemplo
: Variável:Integer

Operadores aritméticos:

Operador Operação Tipo do operando Tipo Resultante Exemplo


+ Adição Inteiro, real Inteiro, real X+Y
- Subtração Inteiro, real Inteiro, real Result - 1
* Multiplicação Inteiro, real Inteiro, real P * 45
/ Divisão Inteiro, real Real X/2
Div Inteiro da divisão Inteiro Inteiro Total div x
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 3 de 272

Mod Resto da divisão Inteiro Inteiro Y mod 6

Observação: O operador + quando utilizado com dados string provocará a concatenação destes.

Exemplo:

A,B,C:String;
A:= ‘Curso de ‘;
B:=’Delphi’;
C:=A+B;

C resulta em Curso de Delphi.

Operadores lógicos:

Operador Operação Tipo do operando Tipo Resultante Exemplo


Not negação Boolean Boolean not (C in MySet)
And conjuncão Boolean Boolean D and (T > 0)
Or disjunção Boolean Boolean A or B
Xor disjunção exclusiva Boolean Boolean A xor B

Operadores set:

Operador Operação Tipo do operando Tipo Resultante Exemplo


+ união set set Set1 + Set2
- diferença set set S-T
* intersecção set set S*T
<> desigualdade set Boolean MySet <> S1
>= superset set Boolean S1 >= S2
<= subset set Boolean Q <= MySet
= igualdade set Boolean S2 = MySet
In membership set, ordinal Boolean A in Set1

Operadores relacionais:

Operador Operação Tipo do operando Tipo Resultante Exemplo


= igualdade simple, class, class reference, Boolean A=I
interface, string, packed string
<> desigualdade simple, class, class reference, Boolean X<>Y
interface, string, packed string
> maior que simple, string, packed string, Boolean X>Y
PChar
< menor que simple, string, packed string, Boolean X<Y
PChar
>= maior ou igual simple, string, packed string, Boolean X>=Y
PChar
<= menor ou igual simple, string, packed string, Boolean X<=Y
PChar

Dados: São todas as informações fornecidas pelo usuário.

Banco de Dados: São meios lógicos de armazenamento de dados.

Os bancos de dados geralmente são criados separadamente dos aplicativos e são acessados por
estes a partir de ferramentas que interagem com gerenciadores específicos para cada tipo.

Rotina: É a descrição de cada parte integrante de um aplicativo.


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 4 de 272

As rotinas visam dividir um aplicativo em pequenas partes capazes de transcrever e executar uma
tarefa específica, como exemplo, suponha que uma distribuidora de livros resolva controlar seus
pedidos às editoras e o volume de livros repassados aos seus clientes e para facilitar este trabalho,
resolve dividi-lo em seções:

Seção Funções Rotinas


1–Identificar as editoras 1-Cadastro de editoras
Compras 2-Identificar os livros das editoras 2-Cadastro de livros
3-Escolher os livros e comprar 3-Entrada dos livros
1-Identificar os clientes 1-Cadastro de clientes
Vendas
2-Separar e entregar os livros escolhidos 2-Saída dos livros

Procedimento: É cada uma das ações realizadas por uma rotina:

Exemplo:

Rotina Procedimentos
1. Verificar se editora já foi cadastrada
2. Se não foi cadastrada, então pegar uma nova ficha
Cadastro de editoras 3. Transcrever os dados da editora para a ficha
4. Confirmar a veracidade dos dados
5. Se dados conferem então colocar a ficha no arquivo.

Comandos: São termos, palavras reservadas, que servem para transcrever os procedimentos
humanos aplicados a uma rotina para linguagem compreendida pelo computador.

Estruturas: São comandos que dispostos em certa ordem executam uma função comum.
Geralmente as estruturas apresentam um início e um fim e dentre estes são descritos
procedimentos.

As estruturas podem ser classificadas em:

1) Estrutura de bloco: É a estrutura que controla o projeto e cada procedimento nele descrito,
determinando seu início e fim. O bloco também pode conter declarações de constantes, tipos,
variáveis, procedimentos, e funções; estas declarações têm que preceder a parte de declaração
do bloco.
2) Estruturas de decisão: Provocam desvios no fluxo do projeto de acordo com a entrada
fornecida pelo usuário ou resultante de um cálculo.
3) Estruturas de loop ou laço: Provocam a repetição de um ou vários procedimentos de acordo
com uma condição previamente descrita.
4) Estruturas consecutivas: Executa uma sucessão de declarações constituintes.
5) Estruturas de exceção: Desvia o fluxo do projeto quando ocorre um erro na execução normal
de um programa ou outro evento a interrompa.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 5 de 272

Capitulo II – Componentes básicos da orientação a objetos

Classe: São moldes através dos quais criamos objetos.

Exemplo:

type
TFprincipal = class(TForm)
Panel1: TPanel;
Label1: TLabel;
Label2: TLabel;

Objeto: Abstração que agrupa características e comportamentos.

Exemplo:

object BitBtn1: TBitBtn


Left = 168
Top = 240
Width = 199
Height = 31
Caption = '&Confirmar e encaminhar'
TabOrder = 4
OnClick = BitBtn1Click
Glyph.Data = {76060000424D}
End;

Instância: É o objeto propriamente dito. Possui características próprias.

Propriedade: Define as característica dos objetos de uma classe.

Exemplo:

Método: Define o comportamento dos objetos de uma classe.


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 6 de 272

Mensagem: Representa uma ação do objeto ou uma mudança de estado. Define a comunicação
entre objetos.

Interface: Conjunto de mensagens que define o comportamento de um objeto (Protocolo).

Evento: É um gatilho que quando disparado pelo usuário realiza um procedimento.

Exemplo: (Evento OnClick do objeto Button1 montado sobre o formulário Form1)

procedure TForm1.Button1Click(Sender: TObject);


begin
Form1.Color:=clYellow;
end;

Procedimento: É a ação a ser realizada após o disparo de um evento.

Exemplo: (Procedimento disparado pelo evento OnClick do objeto Button1)

procedure TForm1.Button1Click(Sender: TObject);


begin
Form1.Color:=clYellow;
end;

Tempo de Projeto: É o tempo utilizado pelo desenvolvedor durante a confecção do projeto.

Tempo de Execução: É o tempo utilizado pelo usuário final para execução do projeto após o
término da sua confecção ou pelo desenvolvedor para realização de testes.

Capitulo III – Apresentação do Delphi 2005

Tela de Abertura

Módulos carregados
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 7 de 272

VCL Form Application for WIN 32


Barra de Ferramentas

Menu Principal Página de Códigos

Gerente do projeto

Caixa de
Estrutura

Object
Inspector

Barra de status Paleta de objetos


Formulário
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 8 de 272

Object Inspector: É a conexão entre o a parte visual (Form) e a parte codificada (Unit) de sua
aplicação.
Botão minimizar

Botão fechar

Caixa de seleção de objetos

Paleta de eventos

Paleta de propriedades

No Object inspector encontram-se duas abas: Propriedades (Properties) e eventos (Events), onde
a primeira determina as características do objeto selecionado e a segunda indica quais são os
eventos suportados por este objeto. Além das abas encontra-se uma outra região indicativa do
nome e da classe do objeto selecionado.

Caixa de estruturas (Structure): É a região do DELPHI onde se apresentam todos os objetos


dispostos em um formulário (Form).

Botão minimizar

Botão Fechar

Mover para baixo

Mover para cima

Excluir objeto

Incluir objeto

Objetos

A Paleta de Componentes: É a principal barra de ferramenta, pois contem barras que classificam
e guardam os componentes (objetos) que serão utilizados durante o desenvolvimento de projetos
em Delphi.

Os componentes contidos nas abas da paleta de componentes são alvos de nosso estudo, portanto,
serão apresentados conforme sua necessidade nos capítulos a seguir.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 9 de 272

Botão minimizar

Botão fechar

Botão filtrar

Botão desfazer seleção

Botão habilitar/desabilitar
categoria

Categoria selecionada

Objetos da categoria

Gerente do projeto (Project Manager): Mostra todo o projeto disposto em forma de árvore
permitindo acesso a página de códigos ou formulário, bem como permite a localização de objetos,
procedimentos e funções contidas no projeto.
Botão minimizar
Botão minimizar
Seleciona projeto

Remove unit/form do
projeto

Inclui nova unit/form


ao projeto

Unit/form do projeto

Modelo do projeto

Explorador de base de
dados
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 10 de 272

O Formulário:

Form: O mesmo que


formulário, é a região
onde serão dispostos os
objetos, nas linguagens
estruturadas
representariam a tela do
projeto.

Unit: É a região onde se escrevem os procedimentos, é a parte estrutural do Delphi também


chamada de página de códigos.

Barra de rolagem

Linhas de códigos

Mostra a unit

Mostra o form

Mostra o histórico

Tecla insert

Número da coluna

Número da linha
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 11 de 272

Estrutura de uma Unit:

Unit <identificador>;

Interface
{Especifica o que será exportado pela UNIT a fim de ser utilizados
por outros módulos}

[uses <lista de units>;]

<seções de declaração>

Implementation
{Declaração de Variáveis, Constante e tipos locais a UNIT e
Implementação dos métodos.

[uses <lista de units>;]

<definições>

[Initialization
{Código executado automaticamente quando um aplicativo que utiliza
a UNIT é executado}
<instruções>]

[Finalization
{Código executado automaticamente quando um aplicativo que utiliza
a UNIT é finalizado}
<instruções>]

end.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 12 de 272

Capitulo IV – Os primeiros contatos

Para entender o funcionamento de uma linguagem orientada a objeto, imagine a seguinte


proposição:

- Em uma rua movimentada foi colocado um semáforo para controlar o tráfego de veículos e
próximo a este existe uma cabine de onde um agente o trânsito determina o momento em que as
luzes deverão ser acesas.

- Assim de acordo com o botão pressionado


pelo agente de uma determinada luz do
semáforo ascende e as demais apagam.

- Podemos então dizer que cada botão é um


objeto utilizado pelo agente, da mesma forma,
o semáforo também pode ser considerado como
objeto.

- Se o semáforo é um objeto então ele possui


algumas propriedades, por exemplo: o
semáforo possui luzes que podem ascender em
cores distintas desse modo “cor” seria uma propriedade do semáforo e a cor acessa seria sua
característica.

Resumindo temos:
Objeto Evento Procedimento
Botão Verde Clicar Cor do semáforo = Verde
Botão Amarelo Clicar Cor do semáforo = Amarelo
Botão Vermelho Clicar Cor do semáforo = Vermelho

Prática 01: O primeiro projeto

Objeto Propriedade Evento Procedimento


Button1 Caption = Verde OnClick Panel1.Color:=clgreen;
Button2 Caption = Amarelo OnClick Panel1.Color:=clyellow;
Button3 Caption = Vermelho OnClick Panel1.Color:=clred;

Uma vez montado o projeto pressione ou F9 para executá-lo.


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 13 de 272

Prática 02: Alterando algumas propriedades do formulário.

Para alterar a cor, “propriedade color”, usaremos os botões 1, 2 e 3, conforme descrito a seguir:

Objeto Propriedade Evento Procedimento


Button1 Caption = Amarelo OnClick Form1.Color:=clyellow;
Button2 Caption = Verde OnClick Panel1.Color:=clgreen;
Button3 Caption = Vermelho OnClick Panel1.Color:=clred;

Para alterar a largura, “propriedade height”, usaremos os botões 4 e 5, conforme descrito a seguir:

Objeto Propriedade Evento Procedimento


Button4 Caption = Mais Largo OnClick form1.Height:=form1.Height+1;
Button5 Caption = Menos Largo OnClick form1.Height:=form1.Height+1;

Para alterar o comprimento, “propriedade width”, usaremos os botões 6 e 7, conforme descrito a


seguir:

Objeto Propriedade Evento Procedimento


Button6 Caption = Mais Largo OnClick form1.Width:=form1.Width+1;
Button7 Caption = Menos Largo OnClick form1.Width:=form1.Width-1;

Para alterar a altura, “propriedade top”, usaremos os botões 8 e 9, conforme descrito a seguir:

Objeto Propriedade Evento Procedimento


Button8 Caption = Mais Alto OnClick form1.Top:=form1.Top-1;
Button9 Caption = Mais Baixo OnClick form1.Top:=form1.Top+1;

Uma vez montado o projeto pressione ou F9 para executá-lo.

Prática 03 - Exercício 01: O objetivo dessa prática é alterar algumas propriedades do objeto
TPanel, clicando sobre os botões.

Complete a tabela e escreva os procedimentos conforme o formulário a seguir:


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 14 de 272

Formulário:

Objeto Propriedade Valor Evento Procedimento


Button1 Caption OnClick
Button2 Caption OnClick
Button3 Caption OnClick
Button4 Caption OnClick

Capitulo V – Estruturas

Estrutura é um conjunto de ações interligadas entre si contendo um comando que caracteriza o seu
início e um outro seu fim as estruturas controlam todo o projeto, provocam tomadas de decisões,
controlam repetições, deviam o fluxo do projeto e controlam as possíveis exceções.

As estruturas podem ser classificadas em:

6) Estrutura de bloco: É a estrutura que controla o projeto e cada procedimento nele descrito,
determinando seu início e fim. O bloco também pode conter declarações de constantes, tipos,
variáveis, procedimentos, e funções; estas declarações têm que preceder a parte de declaração
do bloco.
7) Estruturas de decisão: Provocam desvios no fluxo do projeto de acordo com a entrada
fornecida pelo usuário ou resultante de um cálculo.
8) Estruturas de loop ou laço: Provocam a repetição de um ou vários procedimentos de acordo
com uma condição previamente descrita.
9) Estruturas consecutivas: Executa uma sucessão de declarações constituintes.
10) Estruturas de exceção: Desvia o fluxo do projeto quando ocorre um erro na execução normal
de um programa ou outro evento a interrompa.

a) Estrutura de bloco:
Esta estrutura é sempre composta pelos comandos Begin ... End, onde o primeiro determina o
início da estrutura e o segundo o seu fim.
Um ponto e vírgula após um comando indicam que ainda existem comandos ou declarações
pertencentes a estrutura, porém quando o comando End é sucedido do ponto e vírgula indica o fim
da estrutura.
O uso do ponto ao final após o End, indica o fechamento do projeto.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 15 de 272

Exemplo 01:

Para entender a estrutura de bloco tomemos como exemplo um fato cotidiano de acordar, pegar o
carro e ir até o trabalho.

Inicio
Rotina despertar;
Inicio
Acordar;
Forrar a cama;
Sair do quarto;
Estruturas

Fim;
Rotina asseio;
Estrutura Princpal

Inicio
Escovar os dentes;
Tomar banho;
Fim;
Rotina alimentação;
Secundárias

Inicio;
Preparar a comida;
Sentar a mesa;
Comer;
Fim;
Rotina trabalhar;
Inicio;
Pegar o carro;
Ir ao trabalho;
Desligar o carro;
Trabalhar;
Fim;
Fim.

Exemplo 02:

Somar 02 números e mostrar o resultado:

Rotina somar dois números;


Declarar A,B,C como variáveis numéricas;
Inicio
Estrutura bloco

Perguntar qual o primeiro número;


Ler o número e guardar em A;
Perguntar qual o segundo número;
Ler o número e guardar em B;
Fazer C = A + B;
Mostrar C;
Fim;

Prática 04:Baseado no exemplo 02, montaremos um projeto para somar dois números inteiros.

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Soma de dois números
Label1 Caption Primeiro número:
Label2 Caption Segundo número:
Label3 Caption Resultado:
Edit1 Text Vazio (null) OnKeyPres Edit1KeyPress
s
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 16 de 272

Edit2 Text Vazio (null) OnKeyPres Edit2KeyPress


s
Button1 Caption Soma OnClick Button1Click

Formulário:

Procedimentos:

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);


begin
if not (key in ['0'..'9']) then key:=#0;
end;
Variável Key
Tipo caracter
procedure TForm1.Edit2KeyPress(Sender: TObject; var Key: Char); Guarda a tecla
begin pressionada
if not (key in ['0'..'9']) then key:=#0;
end;
Verifica se a tecla pressionada
procedure TForm1.Button1Click(Sender: TObject); Está entre 0 e 9
var A,B,C:integer;
begin
A:=strtoint(edit1.Text); Variáveis A, B e C do tipo
B:=strtoint(edit2.Text); inteira
C:=A+B;
Label3.Caption:='Resultado:'+inttostr(C); A função strtoint(string):integer;
end; Converte um valor string em um
valor inteiro

A função inttostr(integer):string;
Converte um valor inteiro em um
valor string

Comentários:

Pratica 05 – Exercício 02: Monte um projeto capaz de calcular a média aritmética entre 4
números inteiros quaisquer.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 17 de 272

Condições propostas: Deve-se travar o teclado evitando-se a digitação de caracteres não


numéricos.

b) Estruturas de decisão:

Muitas vezes em um projeto o processador precisa decidir entre dois ou mais valores, para tanto o
desenvolvedor deverá dirigir o fluxo do projeto de acordo com a entrada fornecida pelo usuário ou
resultante de um cálculo.
As estruturas de decisão utilizam operadores relacionais, podendo também fazer uso de operadores
lógicos.

As estruturas de decisões podem ser classificadas em:

• Estrutura de decisão única, utilizam a estrutura If...then...Else;


• Estrutura de decisão múltipla, utiliza a estrutura Case...Else...End;

- Estrutura If ... Then ... Else…: (Se... Então... Senão...)

Na estrutura If ... Then ... Else a decisão é única e quando for verdadeira os comandos que
estiverem após o Then serão executados, enquanto os comandos que estiverem após o else serão
desprezados. Caso a condição seja falsa os comando existente após o then serão desprezados
sendo executados apenas os comandos que estiverem após o Else.

Para entender melhor esta estrutura de decisão imagine um interruptor de uma lâmpada.
Quando o interruptor é fechado permite a passagem da corrente elétrica, acendendo a lâmpada e
quando ele é aberto, interrompe-se a passagem da corrente elétrica e a lâmpada não acende.

Assim:

Início
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 18 de 272

Indique a posição do interruptor;


Se a posição o interruptor é fechada então
A lâmpada está acessa
Senão
A lâmpada está apagada
Fim

Pratica 06: Acendendo uma lâmpada:

Baseado na explicação acima monte o seguinte projeto.

Formulário:

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 06
Panel1 Caption Vazio (null)
Panel1 Color clBlack
RadioGroup1 Caption Interruptor OnClick RadioGroup1Click
Acender a lâmpada
RadioGroup1 Items
Apagar a lâmpada
RadioGroup1 ItemIndex 1

Procedimentos:

procedure TForm1.RadioGroup1Click(Sender: TObject);


begin
if RadioGroup1.ItemIndex=0 then
panel1.Color:=clyellow
else
panel1.Color:=clblack;
end;

Comentários:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 19 de 272

Prática 07: O objetivo desta prática é descobrir se um número é par ou ímpar, calcular sua raiz
quadrada, definir se é exata ou inexata e separar a parte inteira da parte decimal.

Formulário:

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 07
Label1 Caption Digite um número:
Label2 Caption Resultado:
Label3 Caption Raiz:
Label4 Caption Parte inteira:
Label5 Caption Parte decimal:
Edit1 Text Vazio (null) OnKeyPres Edit1KeyPress
s
Edit2 Text Vazio (null)
Edit3 Text Vazio (null)
Edit4 Text Vazio (null)
Button1 Caption Verificar OnClick Button1Click
GroupBox1 Caption Resultados:
GroupBox1 Enabled False
RadioButton1 Caption Exata
RadioButton2 Caption Inexata

Procedimentos:

procedure TForm1.Button1Click(Sender: TObject);


var valoremreal:real;
valordaraiz:real;
parteinteira:real;
partefracionaria:real;
begin
valoremreal:=strtofloat(edit1.Text);
valordaraiz:=sqrt(valoremreal);
edit2.Text:=floattostr(valordaraiz);
parteinteira:=int(valordaraiz);
partefracionaria:=valordaraiz-parteinteira;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 20 de 272

if strtoint(edit1.Text) mod 2 =0 then


label2.Caption:=edit1.Text+' é um número par'
else
label2.Caption:=edit1.Text+' é um número impar';
if partefracionaria=0 then
begin
radiobutton1.Checked:=true;
edit3.Text:=floattostr(parteinteira);
edit4.Text:='0';
end
else
begin
radiobutton2.Checked:=true;
edit3.Text:=floattostr(parteinteira);
edit4.Text:=floattostr(partefracionaria);
end;
end;

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);


begin
if not (key in ['0'..'9']) then key:=#0;
end;

Comentários:

Pratica 08 – Exercício 03: Monte um projeto onde o usuário informe o nome do aluno e 04 notas,
obtendo como saída, a média aritmética das notas fornecidas e situação em que o aluno se
encontra, baseando-se na condição abaixo.
Condições propostas: O aluno será aprovado se obter uma média >= 6.

- Estrutura Case... of... Else… End: (Caso... de... Senão... Fim)

Na estrutura Case ... of... Else ... End a decisão é baseada em múltipla escolha sendo executados
apenas os comandos que satisfaçam a condição.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 21 de 272

Atenção: A estrutura Case...of... Else... End, só aceita condições com valores inteiros.
Para entender melhor o funcionamento desta estrutura imagine um semáforo controlando o fluxo
de veículos, a cada cor acessa uma mensagem é enviada ao motorista e como apenas uma cor
acende por vez, o motorista nunca receberá mais que uma mensagem ao mesmo tempo.

Pratica 09: Controlando o trânsito.

Formulário:

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 09 OnActivate Form1Activate
Image1 Picture ’c:\delphi 2005\pratica 09\ carro1.bmp’
Image1 Autosize True
Timer1 Enabled False OnTimer Timer1Timer
RadioGroup1 Caption Semáforo OnClick RadioGroup1Click
Pare
RadioGroup1 Items Atenção
Siga
RadioGroup1 ItemIndex 0
Shape1 Shape stCircle
Shape2 Shape stCircle
Shape3 Shape stCircle
Shape1 Brush.Color clBtnface
Shape2 Brush.Color clBtnface
Shape3 Brush.Color clRed

Variáveis:
Clausula Variável Tipo
Private Carro Integer

Procedimentos:

procedure TForm1.FormActivate(Sender: TObject);


begin
carro:=0;
end;

procedure TForm1.Timer1Timer(Sender: TObject);


begin
case carro of
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 22 de 272

0:begin
image1.Picture.LoadFromFile('c:\delphi 2005\pratica 09\carro1.bmp');
carro:=1;
end;
1:begin
image1.Picture.LoadFromFile('c:\delphi 2005\pratica 09\carro2.bmp');
carro:=0;
end;
end;
end;

procedure TForm1.RadioGroup1Click(Sender: TObject);


begin
case radiogroup1.ItemIndex of
0:begin
timer1.Enabled:=false;
shape1.Brush.Color:=clbtnface;
shape2.Brush.Color:=clbtnface;
shape3.Brush.Color:=clred;
end;
1:begin
timer1.Enabled:=true;
timer1.Interval:=500;
shape1.Brush.Color:=clbtnface;
shape2.Brush.Color:=clyellow;
shape3.Brush.Color:=clbtnface;
end;
2:begin
timer1.Enabled:=true;
timer1.Interval:=50;
shape1.Brush.Color:=clgreen;
shape2.Brush.Color:=clbtnface;
shape3.Brush.Color:=clbtnface;
end;
end;
end;

Comentários:

Pratica 10: Promovendo descontos

Esta prática visa calcular o valor a ser cobrado por uma empresa de cópias de acordo com a
quantidade de xérox retiradas em um mês conforme a tabela abaixo:

Quantidade de cópias Valor por cópia


Até 50 R$ 0,10
De 51 a 100 R$ 0,08
De 101 a 150 R$ 0,06
Acima de150 R$ 0,05
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 23 de 272

Formulário:

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 10
Quantidade de xérox na OnKeyPres
LabeledEdit1 EditLabelCaption Testatecla
primeira semana s
LabeledEdit1 LabelPosition lpLeft
Quantidade de xérox na OnKeyPres
LabeledEdit2 EditLabelCaption Testatecla
segunda semana s
LabeledEdit2 LabelPosition lpLeft
Quantidade de xérox na OnKeyPres
LabeledEdit3 EditLabelCaption Testatecla
terceira semana s
LabeledEdit3 LabelPosition lpLeft
Quantidade de xérox na OnKeyPres
LabeledEdit4 EditLabelCaption Testatecla
quarta semana s
LabeledEdit4 LabelPosition lpLeft
Label1 Caption Total de xérox:
Label2 Caption Valor por xérox:
Label3 Caption Total a pagar:
StaticText1 Caption 0
StaticText1 BorderStyle sbsSuken
StaticText2 Caption 0
StaticText2 BorderStyle sbsSuken
StaticText3 Caption 0
StaticText3 BorderStyle sbsSuken
BitBtn1 Caption Calcular
C:\Arquivos de programas\
arquivos comuns\ borland
BitBtn1 Glyph OnClick BitBtn1Click
shared\images\buttons\
calculat.bmp

Procedimentos:

procedure TForm1.testatecla(Sender: TObject; var Key: Char);


begin
if not (key in ['0'..'9',#8]) then key:=#0;
end;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 24 de 272

procedure TForm1.BitBtn1Click(Sender: TObject);


var valor,total:real;
soma:integer;
begin
if (labelededit1.Text='') or (labelededit2.Text='') or (labelededit3.Text='') or (labelededit4.Text='')
then
showmessage('Existe pelo menos uma semana sem quantidade!')
else
begin
soma:=strtoint(labelededit1.Text)+strtoint(labelededit2.Text)+strtoint(labelededit3.Text)+strtoint(labelededit4.Text);
case soma of
0..49:valor:=0.10;
50..99:valor:=0.08;
100..150:valor:=0.06;
else valor:=0.05;
end;
statictext1.Caption:=inttostr(soma);
statictext2.Caption:=formatfloat('R$0.00',valor);
total:=soma*valor;
statictext3.Caption:=formatfloat('R$0.00',total);
end;
end;

Comentários:

Pratica 11 – Exercício 04: Uma empresa resolve realizar uma promoção com descontos entre 10 e
40 por cento de acordo com o total a ser pago pelo cliente conforme a tabela a seguir:

Valor total comprado Percentual de desconto


Até R$ 100,00 10%
De R$ 101,00 a R$ 250,00 20%
De R$ 251,00 a R$ 300,00 30%
Acima de R$ 300,00 40%

c) Estruturas de loop ou laço:

Muitas vezes em um projeto o desenvolvedor necessita repetir um determinado procedimento de


forma controlada, a esta repetição denominamos laço ou loop.deverá dirigir o fluxo do projeto de
acordo com uma condição previamente descrita.

São três as estruturas de laço:

• Repeat... Until; (Repita... até)


• While... do; (Enquanto... faça)
• For... to... do // For... downto… do. (Para... até... faça)

- Repeat... Until: O Repeat executa sua sucessão de declarações constituintes continuamente e


testa a expressão depois de cada repetição. Quando o resultado da expressão é satisfeita, o repeat
termina. A sucessão sempre é executada pelo menos uma vez porque expressão não é avaliada até
depois da primeira repetição.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 25 de 272

Pratica 12: Demonstração do Repeat ... Until;

Formulário:

Objeto Propriedade Valor Evento Procedimento


Label1 Caption Indique o número de repetições:
Edit1 Text Vazio (null) OnKeyPress Edit1KeyPress
Button1 Caption Aplicar OnClick Button1Click

Procedimentos:

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);


begin
if (key< chr(48)) or (key > chr(57)) then key:=chr(0);
end;

procedure TForm1.Button1Click(Sender: TObject);


var i:integer;
begin
i:=1;
listbox1.Clear;
repeat
listbox1.Items.Add('Repetição nº:'+inttostr(i));
inc(i);
until strtoint(edit1.Text)<i;
end;

Comentários:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 26 de 272

- While... do: Executa sua sucessão de declarações constituintes continuamente e testa a expressão
antes de cada repetição. Quando o resultado da expressão é não é mais satisfeita, o while termina.

Para entender melhor o funcionamento desta estrutura proceda da seguinte maneira.

Abra o projeto anterior e altere o procedimento OnClick do objeto Button1 para:

procedure TForm1.Button1Click(Sender: TObject);


var i:integer;
begin
i:=0;
listbox1.Clear;
while strtoint(edit1.Text)>i do
begin
inc(i);
listbox1.Items.Add('Repetição nº:'+inttostr(i));
end;
end;

Comentários:

- For... to... do // For... downto... do: Executa sua sucessão de declarações constituintes
continuamente até que o valor inicial atinja o valor final, através de uma incrementação, (clausula
to), ou decrementação, (clausula downto), quando o valor final é alcançado, o for termina.

Para entender melhor o funcionamento desta estrutura proceda da seguinte maneira.

Abra o projeto anterior e altere o procedimento OnClick do objeto Button1 para:

procedure TForm1.Button1Click(Sender: TObject);


var i:integer;
begin
listbox1.Clear;
for i:=1 to strtoint(edit1.Text) do
listbox1.Items.Add('Repetição nº:'+inttostr(i));
end;

Comentários:

Pratica 13 – Exercício 05: Usando a estrutura de laço monte um projeto capaz e fazer a
combinação de 15 números aleatórios para gerar cartões da sena.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 27 de 272

d) Estruturas consecutivas:

Executa uma sucessão de declarações baseadas em condições onde se referenciam objetos,


classes, campos, procedimentos ou propriedades.

Comando: With... do (Com... faça)

Para entender melhor o funcionamento desta estrutura monte o projeto descrito a seguir.

Pratica 14: Demonstração do With...do

Formulário:

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 14
Label1 Caption Tamanho da fonte:
Label2 Caption Largura da borda:
Label3 Caption Nome da fonte:
Label4 Caption Rótulo:
Label5 Caption Cor da fonte:
Label6 Caption Cor do painel:
Button1 Caption Aplicar OnClick Button1Click

Procedimentos:

procedure TForm1.Button1Click(Sender: TObject);


begin
with panel1 do
begin
font.Size:=strtoint(edit1.Text);
font.Color:=colorbox1.Selected;
font.Name:=edit3.Text;
caption:=edit4.Text;
Color:=colorbox2.Selected;
end;
end;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 28 de 272

Comentários:

e) Estruturas de exceção: Desvia o fluxo do projeto quando ocorre um erro ou outra interrupção
na execução normal de um programa.

Estruturas:

• try... except (Tentar… Exceptualmente)


• try... finally (Tentar… Finalmente)

- Try… Except – Tenta executar um bloco de comandos caso não consiga, o fluxo geraria uma
interrupção que tenderia a interromper a execução do projeto, com o uso do except um
segundo bloco tentará ser executado.

Exemplo:

try
X := Y/Z;
except
on EZeroDivide do HandleZeroDivide;
end;

- Esta declaração tenta dividir Y por Z, mas se uma exceção é encontrada é chamada uma
rotina nomeada HandleZeroDivide de EZeroDivide, (erro:divisão por zero).
- Try… finally – Tenta executar um bloco, se uma interrupção provocar uma
parada no fluxo de execução do projeto, o uso do finally o interpretará como fim do
processo executando um segundo bloco de comandos.

Exemplo:

Reset(F);
try
... // process file F
finally
CloseFile(F);
end;

Capitulo VI – Bancos de dados:

Os bancos de dados são estruturas capazes de armazenar informações fornecidas por usuários para
utilizações futuras, a bem da verdade os dados serão armazenados em tabelas e estas por sua vez
comporão estruturas maiores denominadas bancos ou bases de dados.

Para que uma linguagem consiga abrir, ler ou armazenar dados em uma tabela é necessário a
presença de uma ferramenta conhecida como gerenciador de bancos de dados.

Como exemplo de gerenciadores de bancos de dados temos:

• BDE Administrator (Borland Database Engine);


• MSSQL (Microsoft Structure Query Linguage).
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 29 de 272

O BDEAdministrator:

Introdução ao Borland DataBase Engine

O BDE é uma ferramenta utilizada para fazer a conectividade entre o Delphi, C++Builder®,
IntraBuilder®, Paradox® for Windows, e Visual dBASE® for Windows.

Arquitetura: A arquitetura do BDE inclui numerosos serviços compartilhados utilizados pelos


drives de banco de dados e outras funções. O conteúdo incluído nos drives do BDE habilita acesso
consistente para fontes de dados standards: Paradoxo, dBASE, FoxPro, ACCESS, e bancos de
dados de texto. Você pode adicionar os drivers Microsoft ODBC e criar através do Borland SQL
vínculos com outros servidores de SQL, inclusive Informix, DB2, InterBase, Oracle, e Sybase.
Junto com seus drivers de banco de dados e API consistente, BDE dá para a Microsoft Windows
95 e Windows NT Aplication um acesso direto inclusive de compartilhamento a múltiplas fontes
de dados.

Orientação a Objeto: BDE é orientado a objeto. Em tempo de execução o fomentador de


aplicação interage com BDE criando vários objetos. Estes objetos de runtime manipulam entidades
de banco de dados, como Tables e Querys. A Interface de Programa de Aplicação extensa do BDE
(API) escrita direto em C e C++ aperfeiçoaram o acesso ao BDE e seus drives embutidos para
dBASE, Paradox, FoxPro, ACCESS, e bancos de dados de texto.

Alias: É um “pseudônimo”, um nome e um conjunto de parâmetros que descrevem um recurso de


Network, (cadeia de trabalho). Aplicações de BDE usam pseudônimos para conectar se com
bancos de dados compartilhados. Um alias não é exigido para endereços de bancos de dados locais,
mas será exigido endereçar um banco de dados de SQL.

Aba de definições (DataBases): Nesta aba são definidos os alias que indicarão onde serão
definidos os tipos, os drives, o local, a forma de acesso e comportamento das bases de dados que
poderão se acessadas mediante o chamamento do alias.

Aba de configurações (Configuration): Nesta aba são definidos as configurações dos drives e
comportamento do sistema.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 30 de 272

Os drives carregados pelo BDE são divididos em dois grupos: Native e ODBC, descritos a seguir:

Forma de acesso Estrutura


Paradox
DB2
DBase
FoxPro
Informix
Nativo
Interbase
MSAccess
MSSQL
Oracle
Sybase
SQLServer
Microsoft Access Driver
Microsoft Text Driver
Microsoft Excel Driver
ODBC Microsoft dBase Driver
Microsoft Paradox Driver
Microsoft Visual FoxPro Driver
Microsoft FoxPro VFP Driver
Microsoft VFP dBase Driver

Usaremos este gerenciador com o drive nativo paradox em nossos exemplos.

Configurando o Drive Paradox:

Net Dir: Determina o local onde será armazenado o arquivo PDOXUSRS.NET;

Version: Informa a versão interna do drive;

Type: Tipo do servidor para o qual este drive conecta. Pode ser SERVER (servidor de SQL) ou
FILE (standard, arquivo baseado em servidor).

LangDriver: Informa o idioma do drive;

Block Size: Determina o tamanho do bloco resevado para aramazenamento das tabelas Paradox,
Os blocos ocupam múltiplos de 1024 bytes dispostos nos seguintes níveis:

Nível 5 and 7 1024, 2048, 4096, 16384 e 32768


Nível 3 and 4 1024, 2048 e 4096
Default: 2048
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 31 de 272

Fill Factor: Porcentagem de bloco de disco atual que deve ser enchido antes do Paradox alocar
outro bloco de disco para arquivos de índice. Pode ser qualquer inteiro que varia de 1 a 100.
Default: 95

Nota: valores Menores oferecem desempenho melhor mas aumentam o tamanho de índices.
Valores maiores dão arquivos de índice menores mas aumentam o tempo para criação de um
índice.

Level: Determina o formato utilizado na criação de tabelas Paradox temporárias:

Nivel 7 tabelas Paradox para Windows 32-bit;


Nivel 5 tabelas Paradoxo 5.0;
Nivel 4 formato de tabelas STANDARD introduzido em Paradox 4.0
Nivel 3 formato de tabelas usadas por Paradox 3.5 e versões anteriores
Default: Nível 4.

Para usar campos Blob, índices secundários, e integridade referente, especifique Paradox nível 4
ou nível 5. Você pode usar o nível mais baixo possível para forçar a compatibilidade para um nivel
anterior. Só escolha Nível 7 se você precisa das características de posicionamento avançadas
aplicadas para aquele formato de tabela.

StrictIntegrty: Integridade Referente, Especificações das tabelas Paradox se podem ser


modificadas usando aplicações que não se apóiam na integridade referente (como, Paradoxo 4.0).
por exemplo, se TRUE você estará impossibilitado mudar uma tabela com integridade referente
que usa Paradox 4.0; se FALSE, você pode mudar a tabela, mas você arrisca a integridade de seus
dados. Default: TRUE.

Para acessarmos as tabelas que utilizam este gerenciador utilizaremos os componentes da paleta
BDE.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 32 de 272

O MSSQL Server:

Para acessarmos as tabelas que utilizam este gerenciador utilizaremos os componentes da paleta
dbGo.

OBS: Para utilizar qualquer uma destas estruturas os gerenciadores devem estar instalados no
equipamento de desenvolvimento.

Capitulo VII – O DataBase Desktop (DBD):

Uma das principais finalidades das linguagens de programação é a de controlar o armazenamento


de informações de forma permanente, isto é, a possuir a capacidade de incluir, excluir ou alterar
informações mantidas em um meio. A este meio chamaremos de tabela.
Ao se trabalhar com armazenamento de dados, dois softwares deverão estar instalados no
computador, o primeiro capaz de criar tabelas e segundo capaz de torná-las acessíveis ao delphi.

O DataBase Desktop é um utilitário que nos permite cria, ver, ordenar, modificar “Tables”
(Tabelas de dados) e “Query” (Tabelas de consultas) nos formatos Paradox, dBASE, e SQL.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 33 de 272

Visão geral do DBD (versão:7.0):

Menu

Barra de
ferramentas

Área de
trabalho

Barra de
status

No menu encontramos os seguintes comandos:

Comando Descrição
File Menu de controle de arquivos
Edit Menu de edição de arquivos e preferências
Tools Menu de ferramentas
Window Menu de exibição de janelas
Help Menu de ajuda do DBD

O comando file apresenta a seguinte lista de subcomandos:

Subcomando Descrição
New Cria uma nova tabela, query ou SQL
Open Abre uma tabela, query ou SQL
Close Fecha uma tabela, query ou SQL
Save Salva uma tabela, query ou SQL
Save As... Salva uma tabela, query ou SQL em outra
Working Directory... Define um diretório como de trabalho
Private Directory... Define um diretório como privado

Caso a opção open seja selecionada os comandos do menu serão alteradas como veremos a seguir.

O comando edit apontara para preferências enquanto a opção open não for aberta e se encarregará
de determinar as preferência de edição do usuário, porém se a opção open estiver ativa os
comandos do menu serão alterados.

O comando tools apresenta a seguinte lista de subcomandos:

Subcomando Descrição
Alias manager.. Ativa o gerenciador de Alias, isto é, abrirá o
Borland DataBase Engine (BDE), gerenciador de
bases de dados da Borland
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 34 de 272

Utilities Ativa uma lista de funções capazes de realizar cópias, adição,


subtração, fornecer informações, zerar, classificar, renomear e
reestruturar tabelas.
Password Cria senhas para acessos a tabelas

O comando window estará inabilitado até que a opção open seja ativada e apresentará a seguinte
lista de subcomandos:
Subcomando Descrição
Cascade Exibirá as janelas das tabelas na forma de cascata
Tile top and bottom Exibirá as janelas das tabelas uma abaixo da outra
Side by side Exibirá as janelas das tabelas uma ao lado da outra
Arrange icons Organizará as janelas em icones
Close all Fecha todas as janelas

O comando help abrirá a ajuda do DBD.

Para se criar uma tabela precisaremos de alguns conceitos básicos:

Dados: São todas as informações fornecidas pelo usuário.


Campos: São espaços predeterminados onde serão armazenados os dados.
Registros ou Recordes: É o conjunto de campos.
Chaves: São ordens de classificação dos registros.

A forma de armazenamento dos dados juntamente com a grande quantidade de aplicativos capazes
de criar tabelas, associadas as diversas linguagens de programação existentes, fizeram com que
surgissem várias estruturas ou tipos de tabelas, cada uma com sua características próprias. Por essa
razão o desenvolvedor terá que identificar e ajustar o delphi àquela que melhor lhe convir.

Capitulo VIII – Trabalhando com o DataBase Desktop:

Para iniciarmos o trabalho com o DBD, criaremos uma nova pasta na unidade c: e a chamaremos
de “Delphi 2005”, em seguida devemos analisar os dados que serão armazenados. Nesta análise
devem ser levados em consideração os seguintes pontos:

Número do campo (Field Roster): É uma classificação onde são ordenados os campos.

Nome do campo (Field Name): Determina o nome que será usado para identificação do campo.

Tipo (Type): Determina o tipo do dado que será aceito pelo campo.

Tamanho (Size): Determina o número máximo de caracteres fornecidos pelo usuário.

Chave (Key): Determina se o campo é chave de índice da tabela.

Os tipos dos dados disponíveis variarão de acordo com a estrutura escolhida, no nosso caso,
iniciaremos com a estrutura Paradox em sua versão 7.0.

Tipo do campo Símbolo Tamanho Valor suportado


Alpha A 1 - 255 Letras, números, símbolos especiais como
%, &, #, or = ou qualquer outro carácter ASCII
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 35 de 272

Number N --- Um campo que pode conter só números, um sinal, e


um ponto de fração decimal.
Money $ --- Formata os números para forma de moeda com até
seis dígitos após a vírgula.
Short S --- Qualquer número inteiro entre -32767 e 32767
Long Integer I --- Qualquer número inteiro na faixa que vai de
-2147483648 a 2147483647
Date D --- Guarda datas entre 1 de Janeiro de 9999 AC até 31
de Dezembro 9999 AD.
Time T --- Guarda horas no formato DD:MM:AAAA
Timestamp @ --- Guarda a data e hora atual
Memo M 1 - 240** Guarda arquivos memo
Formatted Memo F 0 - 240** Guarda arquivos formatted memo
Graphic G 0 - 240*** Guardam imagens nos formatos .BMP, .PCX, .TIF,
.GIF, e .EPS.
OLE O 0 - 240*** Armazena tipos diferentes de dados, como imagens,
som, documentos, e assim por diante. O campo de
OLE lhe proporciona um modo para ver e
manipular estes dados dentro do Paradox. Você não
precisa especificar um tamanho para campos de
OLE porque eles não são armazenados na tabela,
mas em arquivos separados.
Logical L --- Campos lógicos contêm valores que representam
verdadeiro ou falso (True ou False).
Autoincrement + --- Campos autoincrement contêm um inteiro longo, é
um campo somente de leitura (não editável). A
tabela começa com o número 1 e soma um número
para cada registro subseqüente.
Apagando um registro não muda os valores de
campo de outros registros.
Binary B 0 - 240*** Campos binários só devem ser usados por usuários
avançados que precisam trabalhar com dados que a
tabela não consegue interpretar, isto é, a tabela não
pode exibir ou pode interpretar campos binários.
Um uso comum de um campo binário é armazenar
som. Campos binários não requerem um tamanho
porque eles são armazenados em um arquivo
separado (o .MB arquivam), não na tabela.
Bytes Y 1 - 255 Campos de bytes só devem ser usados por usuários
avançados que precisam trabalhar com dados que a
tabela não consegue interpretar, isto é, a tabela não
pode interpretar campos bytes. Um uso comum de
um campo binário é armazenar códigos de barra ou
tiras magnéticas. Campos de bytes distintos,
campos binários requerem um tamanho porque eles
são armazenados na tabela e não em um arquivo
separado, permitindo acesso mais rápido.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 36 de 272

BCD # 0 - 32* Campos BCD contêm dados numéricos em formato


BCD (Codigo Decimal Binário). Use campos BCD
quando você quer executar cálculos com um nível
mais alto de precisão que aquele disponível com o
uso de outros campos numéricos. Cálculos em
campos BCD não são executados tão depressa
quanto em outros campos numéricos.
O campo tipo BCD é provido principalmente para
compatibilidade com outras aplicações que usam
dados BCD. A tabela interpreta dados BCD
corretamente de outras aplicações que usam BCD.
Porém, quando a tabela executa cálculos com dados
BCD, converte os dados para o tipo de flutuante,
devolvendo o resultado para BCD.

* Número de dígitos depois do ponto de fração decimal;


* * Campos Memo ou Formated Memo podem ter um tamanho virtual. O valor especificado se
refere ao tamanho da Base de dados do arquivo memo da tabela (1 a 240 caracteres para memo e 0
a 240 caracteres para formated memo). O memo inteiro é armazenado fora da tabela. Por exemplo,
se você especifica um valor de 45 ao campo, o Banco de dados guarda os primeiros 45 caracteres
na tabela e armazena o campo de memo inteiro em outro arquivo (com a extensão .MB).

* * * Opcional

Obs: Se todos seus memos são menores que um determinado tamanho (por exemplo, 200 caráter),
você pode economizar espaço e tempo fixando o tamanho de campo de memo igual ou maior que
este tamanho. O Banco de dados guarda na tabela o memo inteiro se ele é menor que o tamanho
determinado.

A partir deste conhecimento criaremos uma tabela simples conforme a descrição abaixo:

Nome do campo Tipo Tamanho Chave Descrição


Guarda o número da
Identidade Alfanumérico 10 Sim
identidade
CPF Alfanumérico 14 Guarda o número do C.P.F.
Nome Alfanumérico 50 Guarda o nome
Nascimento Data Guarda a data de nascimento
Logradouro Alfanumérico 50 Guarda o nome da rua
Numero Numérico Guarda o numero da casa
Guarda dados
Complemento Alfanumérico 50
complementares
Bairro Alfanumérico 30 Guarda o nome do bairro
Cidade Alfanumérico 30 Guarda o nome da cidade
Estado Alfanumérico 2 Guarda o nome do estado
CEP Alfanumérico 10 Guarda o número do cep
Ativo Lógico Guarda a situação

Crie a pasta: “C:\Delphi 2005\Tabelas”, agora abra o DBD e escolha as opções: “File”; “New” e
“Table”:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 37 de 272

Aponte o tipo da tabela para Paradox 7, conforme a figura acima e click sobre OK;
Aparecerá a janela de edição de tabelas em Paradox, preencha conforme a tabela descrita
anteriormente.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 38 de 272

Após a montagem a sua tabela deverá


ter a seguinte forma:

Click sobre o botão Save As em seguida localize a pasta “C:\Delphi 2005\Tabelas”;


Dê o nome de “Pessoal” à tabela e click em salvar.

Exercício 06: Agora crie uma tabela com base nas instruções abaixo e salve no diretório C:\Delphi
2005\Tabelas com o nome de acessos:

Campo Tipo Tamanho Chave


Usuario Alpha 30 Sim
Senha Alpha 6
Nivel de acesso Number

Incrementando registros de uma tabela:

Para se incluir registros a uma tabela sem conduto ter que fazer um projeto para isso, proceda da
seguinte maneira:

a) Abra a tabela; Opção: File seguida das opções Open e Table;


b) Uma vez a aberta a tabela o menu sofrerá uma alteração passando a ter os seguintes
comandos:

Comando Descrição
File Menu de controle de arquivos
Edit Menu de edição de arquivos e preferências
Tools Menu de ferramentas
View Menu de visualização de registros
Table Menu de controle sobre a tabela
Record Menu de controle sobre registros da tabela
Window Menu de exibição de janelas
Help Menu de ajuda do DBD

c) Com a tabela aberta escolha a opção Edit Data do comando Table ou pressione F9:
d) A gravação será automática sempre que houver um deslocamento a nível de registro.

Navegando pelos registros de uma tabela:

Para se navegar sobre os registros de uma tabela sem conduto ter que fazer um projeto para isso,
proceda da seguinte maneira:

a) Abra a tabela; Opção: File seguida das opções Open e Table;


b) Em seguida utilize as opções do comando Record para navegar:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 39 de 272

Opção Tecla de atalho Descrição


Next F12 vai para o Próximo registro
Previous F11 vai para o registro Anterior
First Ctrl+F11 vai para o Primeiro registro
Last Ctrl+F12 vai para o Último registro

Excluindo registros de uma tabela:

Para se excluir os registros de uma tabela sem conduto ter que fazer um projeto para isso, proceda
da seguinte maneira:

c) Abra a tabela; Opção: File seguida das opções Open e Table;


d) Em seguida coloque a tabela sob a forma de edição localize o registro que deseja excluir e
pressione Ctrl+Del.

Organizando os registros de uma tabela:

Um índice é um arquivo que determina a ordem em uma tabela. O paradox, o dBASE, e o SQL
usam índices para organizar os registros em uma tabela, mas os índices deles/delas trabalham
diferentemente. Os índices podem ser primários ou secundários. No paradox, o índice primário é
chamado também a chave (KEY).

Criando índices secundários:

Os índices secundários geralmente são criados durante a confecção da tabela, portanto se a tabela
já existir teremos que reestruturá-la.
No processo de reestruturação se alterarmos a forma dos campos ou excluirmos algum campo, os
dados contidos nestes deverão ser ajustados para a nova forma do campo ou serão perdidos se o
campo for excluído, no entanto, a criação de índices secundários não afetaram, “a princípio”, os
dados armazenados.
Para se criar índices secundários em uma tabela sem conduto ter que fazer um projeto para isso,
proceda da seguinte maneira:

a) Escolha a opção restructure no comando Tools:


b) Em seguida abra a tabela.

Para melhor entendimento criaremos dois índices secundários: o primeiro Unique (sem repetições
válidas), para o campo CPF e o segundo Maintained, (com repetições válidas), para o campo
Nome da tabela “Pessoal.db”.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 40 de 272

Uma vez aberta a tabela selecione a opção Secundary Indexes, na caixa de rolagem Table
Properties;
Em seguida click sobre o botão Define. Surgirá então a janela de definições descrita a seguir:

Selecione o campo CPF e click sobre a


seta de adição, em seguida marque a opção
Unique na caixa Index options.
Uma vez definido o campo e a opção do
índice clica-se sobre o botão OK e
informa-se o nome para o arquivo de
índice.

Sugestão: Monte o nome do índice


associando o campo a terminação idx, por
exemplo:
CPFIDX

Agora proceda de maneira semelhante para o campo Nome, alterando, porém, a opção do índice
para Maintained na caixa Index options e salvando com o nome: NOMIDX

Observações: As opções Case sensitive e Descending, promovem a distinção de maiúsculas e


minúsculas no primeiro caso, e organiza a tabela de forma decrescente no segundo caso.

Exercício 07: Abra a tabela Acessos.db e inclua 03 registros.

Capitulo IX – Incluindo tabelas em um formulário:

Existem duas maneiras de se trabalhar com tabelas em formulários: a primeira delas introduz a
tabela diretamente sobre o formulário onde se vai trabalhar, e a segunda consiste em utilizar-se de
um tipo especial de formulário denominado Data-Module. Geralmente usam-se os data-module’s
quando a tabelas são compartilhadas entre vários formulários.

O Data-Module: Como já mencionamos o Data-Module é um tipo especial de formulário, onde se


colocam as tabelas a serem utilizadas no projeto.

O data-module possui apenas dois eventos:

OnCreate – Ocorre sempre que uma aplicação inicializa o data-module.


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 41 de 272

Por exemplo: Se um data-module contém os componentes database ou table e dataset, uma


aplicação pode estabelecer uma conexão com o banco de dados ou com as tabelas imediatamente.
Se o módulo de dados contém Timer, (cronômetros), a aplicação pode os inicializar.

OnDestroy – Ocorre sempre que o data-module foi destruído.

Por exemplo: Pode-se se escrever um procedimento que autorize o fechamento de tabelas, neste
evento, e sempre que o data-module for destruído, ele fechará as tabelas antes de se destruir.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 42 de 272

Com relação as propriedades, convêm mencionar a seguinte:

OldCreateOrder – Está propriedade do tipo boolean, apresenta False como default, o que
assegura que o evento Oncreate seja executado após a finalização das instâncias dos demais
construtores e que o evento OnDestroy seja executado antes das instâncias dos demais destructors.

Pratica 15: Incluindo uma senha

Após a criação da tabela “Acessos”, precisaremos criar o data module, e neste inserir objetos
capazes de acessar a tabela, porem, definiremos um “ALIAS”, (atalho para a pasta onde estão as
tabelas), e o chamaremos de dados.

Alias: É um “pseudônimo”, um nome e um conjunto de parâmetros que descrevem um recurso de


Network, (cadeia de trabalho). Aplicações de BDE usam pseudônimos para conectar se com
bancos de dados compartilhados.

Criando um alias paradox:

1- Selecione a opção Object no menu opções e nesta selecione New ou pressione Ctr+N:

2- Após a abertura da janela apresentada


ao lado, selecione Standard como
Database Driver Name (nome do drive
para a base de dados);

3- Click em Ok para confirmar o drive;

4 – Agora altere o nome do Alias de


Standard para dados;

Quando se cria um Alias indicando Standard como disponibilizados três drives:

PARADOX: Paradox, para tabelas .DB;


DBASE: dBASE e FoxPro, para tabelas .DBF;
ASCIIDRV: ASCII text, para tabelas .TXT.

Em seguida configuraremos as opções para o alias criado para o drive escolhido:

TYPE: Tipo do servidor para o qual este drive conecta;


PATH: É o caminho onde o banco de dados está armazenado;
DEFAULT DRIVER: Drive padrão: PARADOX, DBASE ou ASCIIDRV;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 43 de 272

ENABLE BCD: Specifica se BDE traduz campos numéricos e decimais em valores de ponto
flutuantes ou valores em decimal codificado binário (BCD). Valores de BCD eliminam os erros de
arredondamento associados com matemática de ponto flutuante (exemplo: 3 * (2/3) resultando em
2.00000000001). Quando ENABLE BCD é fixado para TRUE, decimais e campos numéricos são
convertidos para BCD. Default é FALSE.

5- Para as nossas tabelas configuraremos os parâmetros do alias conforme a tabela abaixo:

Parâmetro Valor
TYPE STANDARD
DEFAULT DRIVER PARADOX
ENABLE BCD FALSE
PATH C:\Delphi 2005\Tabelas

6- Agora resta-nos apenas salvar o nosso alias: Opções: Object e Save As.

Agora que já temos um alias criado partiremos para a criação o data module.

Criando o data module:

i) Crie uma nova aplicação para win32;


ii) Click em File // New // Other

iii) Click em Delphi Projects // Delphi Files;


iv) Selecione o ícone Data Module e pressione OK.

Formulário Data Module:

Objeto Propriedade Valor Evento Procedimento


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 44 de 272

Data-module Name DM
Data-module OnCreate DatamoduleCreate
Data-module OnDestroy DatamoduleDestroy
Table1 Name TAcessos
Table1 DatabaseName Dados
Table1 TableName Acessos.DB
DataSource1 Name DSAcessos
DataSource1 DataSet TAcessos

Alteradas as propriedades deve-se indicar quais campos da tabela estarão disponíveis ao projeto.

Dê um click duplo no objeto TAcessos e selecione Add All Fiels:

Procedimentos:

procedure TDM.DataModuleCreate(Sender: TObject);


begin
TAcessos.Open;
end;

procedure TDM.DataModuleDestroy(Sender: TObject);


begin
TAcessos.Close;
end;

Digitados os procedimentos, Salve o data moule com o nome UDM.

Agora que o data module está pronto montaremos um formulário para entrada do usuário e sua
senha.

Formulário:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 45 de 272

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 15
Form1 OnActivate Form1Activate
Panel1 Caption Vazio (null)
Panel1 Border Style bsSingle
Panel1 BevelInner bvLowered
Panel1 BevelOuter bvRaised
Panel1 BevelWidth 2
Panel1 BorderWidth 2
Label1 Caption Usuário:
Label2 Caption Senha:
Edit1 Text Vazio (null)
Edit2 Text Vazio (null)
BitBtn1 Caption Verificar OnClick BitBtn1Click
C:\arquivos de programas\
BitBtn1 Glyph arquivos comuns\Borland Shared
\Images\Buttons\Key
BitBtn2 Caption Cancelar OnClick BitBtn2Click
C:\arquivos de programas\
BitBtn1 Glyph arquivos comuns\Borland Shared
\Images\Buttons\DoorOpen

Clausula Variável Tipo Valor Parâmetro


Private Tentativas Integer
Uses Acrescentar UDM

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ExtCtrls,udm;

private
tentativas:integer;

Procedimentos:

procedure TFSenha.FormActivate(Sender: TObject);


begin
tentativas:=0;
end;

procedure TFSenha.BitBtn1Click(Sender: TObject);


begin
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 46 de 272

if tentativas=3 then // Tentativas=3?


begin
MessageDlg('Acesso Negado!',mtinformation,[mbCancel],0); // Emitir mensagem
Halt; // Encerrar projeto
end
else
begin
dm.TAcessos.SetKey; // Ativa a chave de índices
dm.TAcessosUsuario.Text:=edit1.Text; // Atribui usuário campo.chave
dm.TAcessos.GotoKey; // Busca chave
if dm.TAcessosUsuario.Text=Edit1.Text then // campo.chave=usuário?
begin
if dm.TAcessosSenha.Text=Edit2.Text then // campo.senha=senha?
showmessage('acesso permitido!') // Chama o formulario de menu
else
begin
tentativas:=tentativas+1; // Incrementar Tentativas em 1
MessageDlg('Senha Inválida!',mterror,[mbok],0); // Emitir mensagem
edit2.Text:=''; // Zerar entrada da senha
edit2.SetFocus; // Retornar a entrada da senha
end;
end
else
begin
inc(tentativas,1); // Incrementar Tentativas em 1
MessageDlg('Usuário não autorizado!',mterror,[mbok],0); // Emitir mensagem
Edit1.Text:=''; // Zerar entrada do usuário
Edit1.SetFocus; // Retornar a entrada do usuário
end;
end;
end;

procedure TFSenha.BitBtn2Click(Sender: TObject);


begin
Halt; // Fecha projeto
end;

Comentários:

Capitulo X – Incluindo menus em um formulário:

A montagem de menus é algo bastante comum em aplicativos que seguem os padrões Windows,
isto é, aplicativos que se executam em janelas.

Os menus do delphi se classificam em dois tipos:

MainMenu: Menu principal, é fixo e normalmente ocupa a posição superior da janela do


aplicativo.
PopUpMenu: Menu flutuante, é móvel e ativo com o pressionamento do botão direito do mouse,
são geralmente utilizados como menus auxiliares.

Tanto no MainMenu como no PopupMenu, existem duas propriedades que trabalharam da mesma
forma: Items: usada para criar os itens do menu e Images: usada para colocar ícones ao lado dos
itens do menu.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 47 de 272

Os itens criados nos MainMenu e PopUpMenu se comportam como novos objetos e possuem
propriedades e eventos próprios.

Prática 16 – Montando um formulário de controle

Formulário:

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 16
Form1 Name Fpratica16
Image1 AutoSize True
Image1 Stretch True
Image1 Align alClient
Image1 Picture C:\Delphi 2005\images\Borland1
&Cadastros
C&lientes
&Produtos
&Fornecedores
F&uncionarios
&Movimentos
&Entradas
&Saídas
C&onsultas
Mainmenu1 Items &Cadastros
C&lientes
&Produtos
&Fornecedores
F&uncionarios
&Movimentos
&Entradas
&Saídas
&Sair

Após a digitação dos procedimentos salve a unit com o nome Upratica16

Comentários:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 48 de 272

Capitulo XI – Trabalhando com mais de um formulário:

É comum na maioria dos projetos a presença de vários formulários, tanto pelo fato da quantidade
de objetos utilizados, como por uma questão de lógica e organização.

Os formulários precisam ser abertos e após seu uso novamente fechados para evitar seu acúmulo
na memória do computador.

a)Abertura de formulário:

Comandos: Show;
ShowModal.

O comando Show abre um formulário em uma janela, mantendo disponível as janelas abertas
anteriores a atual
O comando ShowModal abre um formulário em uma janela, não permitindo acesso às janelas
abertas anteriores a atual.

Prática 17 – Anexando formulários:

Observe as práticas 16 e 17, verifique que de certo modo eles se completam. O que vamos fazer
agora é anexar estas duas práticas em um único projeto, dando assim uma visão maior sobre
projetos em delphi.

Para anexar as práticas, proceda da seguinte forma:

1. Abra a prática 16;


2. Na barra de ferramentas click sobre Add file to project;

3. Selecione a unit Upratica16 e click em ok;

Pronto as duas práticas agora pertencem ao mesmo projeto, no entanto, precisamos criar uma
interface entre seus códigos e seu formulários.

Para criar tal interface utilizamos ao final da clausula USES da unit do projeto de senhas,
incluímos Upratica16, que corresponde ao nome da unit da pratica 16:

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ExtCtrls,udm,Upratica16;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 49 de 272

Embora as unit´s estejam interligadas, precisamos chamar o formulário da pratica 16 caso o


usuário seja aceito e sua senha seja válida, para isso altere a linha 55 do procedimento Click do
bitbtn1 do formulário FSenha para:

Antes da alteração Após a alteração


Linha Procedimento Linha Procedimento
54 if dm.TAcessosSenha.Text=Edit2.Text then 54 if dm.TAcessosSenha.Text=Edit2.Text then
55 showmessage('acesso permitido!') 55 Fpratica16.Show
56 else 56 Else

Antes e executar vamos salvar como um novo projeto:

No menu principal click sobre File e escolha a opção: Save projet as..., dando-lhe o nome de
pratica17.

Comentários:

Observe a linha 55 da página de códigos do formulário FSenha:

Fpratica16.Show

Execute o projeto e mova a janela do menu principal de forma a enxergar o formulário de senha,
em seguida clique sobre ele.

Comentários:

Agora substitua a linha 55 da página de códigos do formulário FSenha por:

Fpratica16.ShowModal

Execute o projeto e mova a janela do menu principal de forma a enxergar o formulário de senha,
em seguida clique sobre ele.

Comentários:

b) Fechamento de formulário:

Comandos: Close;
Halt.

O comando Close retornando à janela aberta anteriormente.


O comando Halt fecha todas as janelas de um projeto, juntamente com todas as bases de dados,
encerrando a aplicação e retirando-a da memória.

Inclua ao projeto o evento click no objeto Sair1, este objeto foi criado pelo delphi quando
incluímos o item Sair no mainmenu1.

procedure TForm1.Sair1Click(Sender: TObject);


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 50 de 272

begin
Close;
end;

Execute o projeto e clique em sair.

Comentários:

Substitua o comando Close do Sair1Click por Halt e execute o projeto

Comentários:

Capitulo XII – Estruturando um projeto:

Para facilitar o trabalho com vários formulários geralmente se faz um esboço de visualização, onde
se divide o projeto em blocos de acordo com sua aplicabilidade:

A seguir está demonstrado um diagrama simples, para leitura de registros de uma tabela
armazenada em um banco de dados, incrementar registros e atualizar a tabela.

Observe a presença de rotinas em cada processo. A estas rotinas podem estar associados
formulários e unit´s ou simplesmente unit´s quando se tratarem de funções ou processos internos
de máquina.

A seguir está demonstrado um algoritmo simples, para leitura de registros de uma tabela
armazenada em um banco de dados, incrementar registros e atualizar a tabela.

1-Início
2-Localiza base de dados
3-Identifica a tabela
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 51 de 272

4-É possível abrir a tabela?


4.1-Se não:
4.1.1-Identificar a razão
4.1.2-Informar ao usuário
4.2-Se sim:
4.2.1-Ativar chave de índices
5-Definir ação:
6-Caso ação:
 Inclusão de novos registros:
1-Abrir formulário
2-Preparar campos de formulário
3-Entrar com dado
4-Buscar chave
5-Chave existe?
6-Se sim:
6.1-Mostrar dados
6.2-Informar ao usuário
6.3-Voltar para definição de ação 5
7-Se não:
7.1-Entrar com valores
7.2-Criticar valores
7.3-Preparar tabelas para recebimento de dados
7.4-Gravar dados
7.5-Dados gravados com sucesso?
7.6-Informar usuário
7.7-Incluir novos registros?
7.7.1-Se sim:
7.7.1.1-Retornar para ação  - 2
7.7.2-Se não:
7.7.2.1-Voltar para definição de ação 5
 Alteração de registros:
1-Abrir formulário
2-Preparar campos de formulário
3-Entrar com dado
4-Buscar chave
5-Chave existe?
6-Se sim:
6.1-Mostrar valores
6.2-Alterar valores
6.3-Criticar valores
6.4-Preparar tabelas para recebimento de dados
6.5-Gravar dados
6.6-Dados gravados com sucesso?
6.7-Informar usuário
6.8-alterar outros registros?
6.8.1-Se sim:
6.8.1.1-Retornar para ação  - 2
6.8.2-Se não:
6.8.2.1-Voltar para definição de ação
7-Se não:
7.1-Informar ao usuário
7.2-Voltar para definição de ação 5
 Exclusão de registros:
1-Abrir formulário
2-Preparar campos de formulário
3-Entrar com dado
4-Buscar chave
5-Chave existe?
6-Se sim:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 52 de 272

6.1-Mostrar valores
6.2-Exclui dados?
6.2.1-Se sim:
6.2.1.1-Excluir dados
6.2.1.2-Dados excluídos com sucesso?
6.2.1.2.1-Se sim:
6.2.1.2.1.1-Informar ao usuário
6.2.1.2.1.2-Excluir outros registros?
6.2.1.2.1.2.1-Se sim:
6.2.1.2.1.2.1.1-Retornar para ação  - 2
6.2.1.2.1.2.2-Se não:
6.2.1.2.1.2.2.1-Voltar p/ definição de ação 5
6.2.1.2.2-Se não:
6.2.1.2.2.1-Informar ao usuário
6.2.1.2.2.2-Voltar para äefinição de ação 5
6.2.2-Se não:
6.2.2.1-Voltar para definição de ação 5
7-Se não:
7.1-Informar ao usuário
7.2-Excluir outro?
7.2.1-Se sim:
7.2.1.1-Retornar para ação  - 2
7.2.2-Se não:
7.2.2.1-Voltar para definição de ação 5
8-Fim dos casos
9-Finalizar?
9.1-Se sim:
9.1.1-Fechar tabela
9.1.2-Fechar formulário
9.2- Se não:
9.2.1- Voltar para definição de ação 5
Fim

Observações: O algoritmo descrito acima poderá ser escrito de maneiras diferentes, dependendo
apenas da linha de raciocínio do desenvolvedor.

Capitulo XIII – Incluindo, localizando e excluindo dados de uma tabela em tempo de execução:

Observando a prática 17 notamos que falta dá continuidade às opções apresentadas pelo


mainmenu, onde cada opção possui rotinas próprias agrupadas em blocos denominados de
cadastros, movimentos e consultas. Cada bloco, por sua vez representa um formulário e uma
página de código. A prática a seguir visa montar um desses formulários, o cadastro de clientes, que
tem como objetivo inclui, excluir e consultar registros de uma base e clientes.

Para podermos escrever estas rotinas precisamos primeiro montar a tabela:


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 53 de 272

Tabela de clientes:

Índices secundários:

Feita a tabela vamos para o delphi onde abriremos a prática 17 e salvamos como prática 18:

Agora criaremos o formulário para cadastros de clientes:


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 54 de 272

Prática 18 – Cadastro de clientes:

Com o projeto Pratica18 aberto, crie um novo formulário:

Agora monte o seguinte formulário:

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Cadastro de clientes OnActivate FormActivate
Label1 Visible False
Label2 Caption Bairro
Label3 Caption Cidade
Label4 Caption Estado
Label5 Caption CEP
Label6 Caption Telefone
Ebleft=true
ebTop=true
EdgeBorders
ebRight=true
ToolBar1 ebBottom=true
Images ImageList1
ShowCaptions True
List True
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 55 de 272

Name novo OnClick novoClick


Toolbutton1
Caption Novo
Toolbutton2 Name primeiro OnClick primeiroClick
Caption Primeiro
Toolbutton3 Name anterior OnClick anteriorClick
Caption Anterior
Toolbutton4 Name proximo OnClick proximoClick
Caption Proximo
Toolbutton5 Name ultimo OnClick ultimoClick
Caption Ultimo
Toolbutton6 Name salvar OnClick salvarClick
Caption Salvar
Toolbutton7 Name excluir OnClick excluirClick
Caption Excluir
Toolbutton8 Name localizar OnClick localizarClick
Caption Localizar
Toolbutton9 Name fechar OnClick fecharClick
Caption Fechar
Name ecodigo OnExit ecodigoExit
Labelededit1 EditLabel.Caption Código
LabelPosition lpleft
Align alBottom
Panel1
Enabled False
Label7 Caption Buscar
Align alBottom OnDblClick DBGrid1DblClick
DBGrid1 DataSource DM.DSClientes
ReadOnly True
BitBtn1 Caption Aplicar OnClick BitBtn1Click
Name elocaliza OnClick elocalizaClick
Caption Localizar por:
Cliente
RadioGroup1
Código
Items.Strings
CPF
CNPJ
MaskEdit1 Name ebuscar
Name etipo OnClick etipoClick
Caption Tipo
RadioGroup2 Columns 2
Físico
Items.Strings
Jurídico
Name ebairro
Sorted True
13 de julho
Aruana
ComboBox1
Atalaia
Items.Strings
Centro
Jabotiana
Santa Tereza
Name ecpf_cnpj
MaskEdit2
Visible False
Name ecliente
LabeledEdit2 EditLabel.Caption Cliente
LabelPosition lpleft
Name erg_insestadual
EditLabel.Caption Código
LabeledEdit3
LabelPosition lpleft
Visible False
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 56 de 272

Name elogradouro
LabeledEdit4 EditLabel.Caption Logradouro
LabelPosition lpleft
Name ecomplemento
LabeledEdit5 EditLabel.Caption Complemento
LabelPosition lpleft
LabeledEdit6 Name enumero
EditLabel.Caption Número
LabelPosition lpleft
Name ecidade
Sorted True
Aracaju
ComboBox2 Estância
Items.Strings Itabaiana
Nossa Senhora da
Glória
Name eestado
Sorted True
AL
ComboBox3 AM
Items.Strings BA
PE
SE
Name ecep
EditMask 99999-999
MaskEdit3
MaxLength 9
Text Vazio (null)
Name etelefone
EditMask (99)9999-9999
MaskEdit4
MaxLength 13
Text Vazio (null)
Name mensagens
Panel2 Align alBottom
Caption Defina uma ação
ImageList1

Procedimentos:

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, Mask, Grids, DBGrids, StdCtrls, ExtCtrls, ToolWin, ImgList,
Buttons, udm, db;

private
acao:integer;

procedure TFclientes.FormActivate(Sender: TObject);


begin
//desabilitação dos botões
salvar.Enabled:=false;
excluir.Enabled:=false;
// limpeza dos campos
ecodigo.Text:='';
etipo.ItemIndex:=-1;
ebairro.Text:='';
ecpf_cnpj.Text:='';
ecliente.Text:='';
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 57 de 272

erg_insestadual.Text:='';
elogradouro.Text:='';
ecomplemento.Text:='';
enumero.Text:='';
ecidade.Text:='';
eestado.Text:='';
ecep.Text:='';
etelefone.Text:='';
//inicialização da acao
acao:=0;
//abertura da tabela
dm.TClientes.Open;
end;

procedure TFclientes.novoClick(Sender: TObject);


begin
//definicao da acao
acao:=1;
//informando ao usuário
mensagens.Caption:='Rotina de inclusão de registros';
// limpeza dos campos
ecodigo.Text:='';
etipo.ItemIndex:=-1;
ebairro.Text:='';
ecpf_cnpj.Text:='';
ecliente.Text:='';
erg_insestadual.Text:='';
elogradouro.Text:='';
ecomplemento.Text:='';
enumero.Text:='';
ecidade.Text:='';
eestado.Text:='';
ecep.Text:='';
etelefone.Text:='';
//direcionando o focus
ecodigo.SetFocus;
end;

procedure TFclientes.primeiroClick(Sender: TObject);


begin
//definicao da acao
acao:=2;
// localização do primeiro registro
dm.TClientes.First;
//transferencia dos dados da tabela para o formulario
ecodigo.Text:=dm.TClientesCodigo.Text;
etipo.ItemIndex:=dm.TClientesTipo.Value;
ebairro.Text:=dm.TClientesBairro.Text;
ecpf_cnpj.Text:=dm.TClientesCpf_cnpj.Text;
ecliente.Text:=dm.TClientesCliente.Text;
erg_insestadual.Text:=dm.TClientesRg_insestaudal.Text;
elogradouro.Text:=dm.TClientesLogradouro.Text;
ecomplemento.Text:=dm.TClientesComplemento.Text;
enumero.Text:=dm.TClientesNumero.Text;
ecidade.Text:=dm.TClientesCidade.Text;
eestado.Text:=dm.TClientesEstado.Text;
ecep.Text:=dm.TClientesCep.Text;
etelefone.Text:=dm.TClientesTelefone.Text;
//informando ao usuário
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 58 de 272

mensagens.Caption:='Rotina de navegação de registros';


end;

procedure TFclientes.anteriorClick(Sender: TObject);


begin
//definicao da acao
acao:=2;
// localização do registro anterior
dm.TClientes.Prior;
//transferencia dos dados da tabela para o formulario
ecodigo.Text:=dm.TClientesCodigo.Text;
etipo.ItemIndex:=dm.TClientesTipo.Value;
ebairro.Text:=dm.TClientesBairro.Text;
ecpf_cnpj.Text:=dm.TClientesCpf_cnpj.Text;
ecliente.Text:=dm.TClientesCliente.Text;
erg_insestadual.Text:=dm.TClientesRg_insestaudal.Text;
elogradouro.Text:=dm.TClientesLogradouro.Text;
ecomplemento.Text:=dm.TClientesComplemento.Text;
enumero.Text:=dm.TClientesNumero.Text;
ecidade.Text:=dm.TClientesCidade.Text;
eestado.Text:=dm.TClientesEstado.Text;
ecep.Text:=dm.TClientesCep.Text;
etelefone.Text:=dm.TClientesTelefone.Text;
//informando ao usuário
mensagens.Caption:='Rotina de navegação de registros';
end;

procedure TFclientes.proximoClick(Sender: TObject);


begin
//definicao da acao
acao:=2;
// localização do proximo registro
dm.TClientes.Next;
//transferencia dos dados da tabela para o formulario
ecodigo.Text:=dm.TClientesCodigo.Text;
etipo.ItemIndex:=dm.TClientesTipo.Value;
ebairro.Text:=dm.TClientesBairro.Text;
ecpf_cnpj.Text:=dm.TClientesCpf_cnpj.Text;
ecliente.Text:=dm.TClientesCliente.Text;
erg_insestadual.Text:=dm.TClientesRg_insestaudal.Text;
elogradouro.Text:=dm.TClientesLogradouro.Text;
ecomplemento.Text:=dm.TClientesComplemento.Text;
enumero.Text:=dm.TClientesNumero.Text;
ecidade.Text:=dm.TClientesCidade.Text;
eestado.Text:=dm.TClientesEstado.Text;
ecep.Text:=dm.TClientesCep.Text;
etelefone.Text:=dm.TClientesTelefone.Text;
//informando ao usuário
mensagens.Caption:='Rotina de navegação de registros';
end;

procedure TFclientes.ultimoClick(Sender: TObject);


begin
//definicao da acao
acao:=2;
// localização do ultimo registro
dm.TClientes.Last;
//transferencia dos dados da tabela para o formulario
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 59 de 272

ecodigo.Text:=dm.TClientesCodigo.Text;
etipo.ItemIndex:=dm.TClientesTipo.Value;
ebairro.Text:=dm.TClientesBairro.Text;
ecpf_cnpj.Text:=dm.TClientesCpf_cnpj.Text;
ecliente.Text:=dm.TClientesCliente.Text;
erg_insestadual.Text:=dm.TClientesRg_insestaudal.Text;
elogradouro.Text:=dm.TClientesLogradouro.Text;
ecomplemento.Text:=dm.TClientesComplemento.Text;
enumero.Text:=dm.TClientesNumero.Text;
ecidade.Text:=dm.TClientesCidade.Text;
eestado.Text:=dm.TClientesEstado.Text;
ecep.Text:=dm.TClientesCep.Text;
etelefone.Text:=dm.TClientesTelefone.Text;
//informando ao usuário
mensagens.Caption:='Rotina de navegação de registros';
end;

procedure TFclientes.salvarClick(Sender: TObject);


begin
//informando ao usuário
mensagens.Caption:='Rotina de gravação de registros';
//critica de permissão
if ecodigo.Text='' then
showmessage('Codigo não informado ou inexistente!')
else
begin
if acao=1 then
dm.TClientes.Append; // cria um registro em branco
dm.TClientes.Edit; // coloca a tabela em modo de edição, alteração
// transfere dados do formulario para a tabela
dm.TClientesCodigo.Text:=ecodigo.Text;
dm.TClientesTipo.Value:=etipo.ItemIndex;
dm.TClientesBairro.Text:=ebairro.Text;
dm.TClientesCpf_cnpj.Text:=ecpf_cnpj.Text;
dm.TClientesCliente.Text:=ecliente.Text;
dm.TClientesRg_insestaudal.Text:=erg_insestadual.Text;
dm.TClientesLogradouro.Text:=elogradouro.Text;
dm.TClientesComplemento.Text:=ecomplemento.Text;
dm.TClientesNumero.Text:=enumero.Text;
dm.TClientesCidade.Text:=ecidade.Text;
dm.TClientesEstado.Text:=eestado.Text;
dm.TClientesCep.Text:=ecep.Text;
dm.TClientesTelefone.Text:=etelefone.Text;
// grava dados
dm.TClientes.Post;
// mensagem ao usuario
showmessage('Registro salvo!');
end;
//desabilitação dos botões
salvar.Enabled:=false;
excluir.Enabled:=false;
// limpeza dos campos
ecodigo.Text:='';
etipo.ItemIndex:=-1;
ebairro.Text:='';
ecpf_cnpj.Text:='';
ecliente.Text:='';
erg_insestadual.Text:='';
elogradouro.Text:='';
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 60 de 272

ecomplemento.Text:='';
enumero.Text:='';
ecidade.Text:='';
eestado.Text:='';
ecep.Text:='';
etelefone.Text:='';
//inicialização da acao
acao:=0;
end;

procedure TFclientes.excluirClick(Sender: TObject);


begin
//informando ao usuário
mensagens.Caption:='Rotina de exclusão de registros';
//informação ao usuario
showmessage('Registro excluído');
// exclusão do registro
dm.TClientes.Delete;
//desabilitação dos botões
salvar.Enabled:=false;
excluir.Enabled:=false;
// limpeza dos campos
ecodigo.Text:='';
etipo.ItemIndex:=-1;
ebairro.Text:='';
ecpf_cnpj.Text:='';
ecliente.Text:='';
erg_insestadual.Text:='';
elogradouro.Text:='';
ecomplemento.Text:='';
enumero.Text:='';
ecidade.Text:='';
eestado.Text:='';
ecep.Text:='';
etelefone.Text:='';
//inicialização da acao
acao:=0;
end;

procedure TFclientes.ecodigoExit(Sender: TObject);


begin
if ecodigo.Text<>'' then
begin
// vericando se alguma acao foi definida
case acao of
0:begin
//informando ao usuario
showmessage('Nenhuma acao foi definida');
mensagens.Caption:='Defina uma ação';
end;
1:begin
//verificando se o registro já existe
dm.TClientes.Locate('codigo',ecodigo.Text,[locaseinsensitive]);
if ecodigo.Text=dm.TClientesCodigo.Text then
begin
// informando ao usuario
showmessage('Registro já existe');
// mostranddo os dados
ecodigo.Text:=dm.TClientesCodigo.Text;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 61 de 272

etipo.ItemIndex:=dm.TClientesTipo.Value;
ebairro.Text:=dm.TClientesBairro.Text;
ecpf_cnpj.Text:=dm.TClientesCpf_cnpj.Text;
ecliente.Text:=dm.TClientesCliente.Text;
erg_insestadual.Text:=dm.TClientesRg_insestaudal.Text;
elogradouro.Text:=dm.TClientesLogradouro.Text;
ecomplemento.Text:=dm.TClientesComplemento.Text;
enumero.Text:=dm.TClientesNumero.Text;
ecidade.Text:=dm.TClientesCidade.Text;
eestado.Text:=dm.TClientesEstado.Text;
ecep.Text:=dm.TClientesCep.Text;
etelefone.Text:=dm.TClientesTelefone.Text;
//redefinindo acao
acao:=2;
mensagens.Caption:='Ação redefinda para navegação';
//redefinição dos botões
salvar.Enabled:=false;
excluir.Enabled:=true;
end
else
begin
//redefinição dos botões
salvar.Enabled:=true;
excluir.Enabled:=false;
end;
end;
2:begin
//verificando se o registro já existe
dm.TClientes.Locate('codigo',ecodigo.Text,[locaseinsensitive]);
if ecodigo.Text=dm.TClientesCodigo.Text then
begin
// mostrando os dados
ecodigo.Text:=dm.TClientesCodigo.Text;
etipo.ItemIndex:=dm.TClientesTipo.Value;
ebairro.Text:=dm.TClientesBairro.Text;
ecpf_cnpj.Text:=dm.TClientesCpf_cnpj.Text;
ecliente.Text:=dm.TClientesCliente.Text;
erg_insestadual.Text:=dm.TClientesRg_insestaudal.Text;
elogradouro.Text:=dm.TClientesLogradouro.Text;
ecomplemento.Text:=dm.TClientesComplemento.Text;
enumero.Text:=dm.TClientesNumero.Text;
ecidade.Text:=dm.TClientesCidade.Text;
eestado.Text:=dm.TClientesEstado.Text;
ecep.Text:=dm.TClientesCep.Text;
etelefone.Text:=dm.TClientesTelefone.Text;
//redefinição dos botões
salvar.Enabled:=true;
excluir.Enabled:=true;
end
else
begin
// informando ao usuario
showmessage('Registro não existe');
//redefinição dos botões
salvar.Enabled:=false;
excluir.Enabled:=false;
end;
end;
end;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 62 de 272

end;
if ecodigo.Text='' then
begin
// redefinindo acao
acao:=0;
mensagens.Caption:='Defina uma ação';
//redefinição dos botões
salvar.Enabled:=false;
excluir.Enabled:=false;
end;
end;

procedure TFclientes.etipoClick(Sender: TObject);


begin
case etipo.ItemIndex of
-1:begin
label1.Visible:=false;
ecpf_cnpj.Visible:=false;
erg_insestadual.Visible:=false;
end;
0:begin
label1.Caption:='C.P.F.:';
label1.Visible:=true;
ecpf_cnpj.EditMask:='999.999.999-99;0';
ecpf_cnpj.Visible:=true;
erg_insestadual.EditLabel.Caption:='R.G.:';
erg_insestadual.Visible:=true;
end;
1:begin
label1.Caption:='C.N.P.J.:';
label1.Visible:=true;
ecpf_cnpj.EditMask:='99.999.999/9999-99;0';
ecpf_cnpj.Visible:=true;
erg_insestadual.EditLabel.Caption:='I.Est.:';
erg_insestadual.Visible:=true;
end;
end;
end;

procedure TFclientes.fecharClick(Sender: TObject);


begin
//fechamento da tabela
dm.TClientes.Close;
// fechamento do formulário
fclientes.Close;
end;

procedure TFclientes.localizarClick(Sender: TObject);


begin
panel1.Enabled:=true;
elocaliza.ItemIndex:=0;
ebuscar.EditMask:='';
ebuscar.Text:='';
end;

procedure TFclientes.elocalizaClick(Sender: TObject);


begin
case elocaliza.ItemIndex of
0:begin
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 63 de 272

// ajustando a chave de índices


dm.TClientes.IndexName:='idcliente';
dm.TClientes.SetKey;
dm.TClientes.First;
//configurando campo de busca
ebuscar.EditMask:='';
ebuscar.Text:='';
ebuscar.Width:=ecliente.Width;
end;
1:begin
// ajustando a chave de índices
dm.TClientes.IndexName:='';
dm.TClientes.SetKey;
dm.TClientes.First;
//configurando campo de busca
ebuscar.EditMask:='9999999;0';
ebuscar.Text:='';
ebuscar.Width:=ecodigo.Width;
end;
2:begin
// ajustando a chave de índices
dm.TClientes.IndexName:='';
dm.TClientes.SetKey;
dm.TClientes.First;
//configurando campo de busca
ebuscar.EditMask:='999.999.999-99;0';
ebuscar.Text:='';
ebuscar.Width:=ecpf_cnpj.Width;
end;
3:begin
// ajustando a chave de índices
dm.TClientes.IndexName:='';
dm.TClientes.SetKey;
dm.TClientes.First;
//configurando campo de busca
ebuscar.EditMask:='99.999.999/9999-99;0';
ebuscar.Text:='';
ebuscar.Width:=ecpf_cnpj.Width;
end;
end;
end;

procedure TFclientes.BitBtn1Click(Sender: TObject);


begin
case elocaliza.ItemIndex of
0:dm.TClientes.FindNearest([ebuscar.Text]);
1:dm.TClientes.FindNearest([strtoint(ebuscar.Text)]);
2,3:dm.TClientes.Locate('CPF_CNPJ',ebuscar.Text,[locaseinsensitive]);
end;
end;

procedure TFclientes.DBGrid1DblClick(Sender: TObject);


begin
// mostrando os dados
ecodigo.Text:=dm.TClientesCodigo.Text;
etipo.ItemIndex:=dm.TClientesTipo.Value;
ebairro.Text:=dm.TClientesBairro.Text;
ecpf_cnpj.Text:=dm.TClientesCpf_cnpj.Text;
ecliente.Text:=dm.TClientesCliente.Text;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 64 de 272

erg_insestadual.Text:=dm.TClientesRg_insestaudal.Text;
elogradouro.Text:=dm.TClientesLogradouro.Text;
ecomplemento.Text:=dm.TClientesComplemento.Text;
enumero.Text:=dm.TClientesNumero.Text;
ecidade.Text:=dm.TClientesCidade.Text;
eestado.Text:=dm.TClientesEstado.Text;
ecep.Text:=dm.TClientesCep.Text;
etelefone.Text:=dm.TClientesTelefone.Text;
//redefinição dos botões
salvar.Enabled:=true;
excluir.Enabled:=true;
//redefinindo a ação
acao:=2;
end;

Comentários:

Exercício 08 – Crie um cadastro de produtos e um cadastro de fornecedores.

Capitulo XIV – Respondendo a mensagens

Observe os comportamentos dos botões salvar e excluir na prática 18, uma vez pressionados o
usuário perde o controle sobre a ação, isto é, não existe um pedido de confirmação, o registro será
salvo ou excluído.

As mensagens são funções especiais definidas pelo delphi onde o desenvolvedor passa
informações de advertência, erro ou instruções ao usuário.

As instruções podem ser classificadas em:

• Mensagens simples ou avisos; e


• Mensagens de diálogo.

- As mensagens simples ou avisos, são geralmente utilizadas para passar informações ao


usuários onde não se necessitem de confirmação para executar ou cancelar um processamento.

- As mensagens de diálogos, são aquelas que necessitam da confirmação do usuário para


execução ou cancelamento de um processo.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 65 de 272

Mensagens simples ou avisos:

Comando: ShowMessage(dado string);

Mensagens de diálogo:

Comandos: MessageDlg; e
MessageDlgPos.

MessageDlg: Exibe uma caixa de diálogo no centro de tela. Utilize MessageDlg para expor uma
caixa de mensagem e obter a resposta do usuário.

Sintaxe:

MessageDlg(Msg: String; DlgType: TMsgDlgType; Botões: TMsgDlgButtons; HelpCtx: Longint);

Descrição:

Variável Tipo Descrição


Msg String é o conteúdo da mensagem
DlgType TMsgDlgType indica o propósito do diálogo
Botões TMsgDlgButtons indicam que botões devem aparecer na caixa de mensagem
especifica o contexto ID para o tópico de ajuda que deverá
HelpCtx Longint aparecer quando o usuário clica o botão de ajuda ou aperta
F1 enquanto o diálogo é exibido

MessageDlg: Devolve o valor do botão que o usuário selecionou. A tabela seguinte lista os valores
de TMsgDlgBtn por cada tipo de botão que pode aparecer na caixa de mensagem, e o valor
correspondente que é devolvido se o usuário seleciona aquele botão:

Botão pressionado Resposta


mbOk mrOk
mbCancel mrCancel
mbYes mrYes
mbNo mrNo
mbAbort mrAbort
mbRetry mrRetry
mbIgnore mrIgnore

Prática 19 – Utilizando o comando messagedlg

Formulário:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 66 de 272

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 19
Caption Indique o tipo da mensagem OnClick RadioGroup1Click
Informação
RadioGroup1 Atenção
Items Erro
Confirmação

Procedimentos:

procedure TForm1.RadioGroup1Click(Sender: TObject);


begin
case radiogroup1.ItemIndex of
0:messagedlg('Você deve informar todos os dados!',mtinformation,[mbyes,mbno],0);
1:messagedlg('Cuidado! risco de perder os dados.',mtwarning,[mbyes,mbno],0);
2:messagedlg('Não posso salvar os dados!',mterror,[mbretry,mbcancel],0);
3:messagedlg('Confirma exclusão dos dados!',mtconfirmation,[mbyes,mbno],0);
end;
end;

Comentários:

Prática 20 – Utilizando o comando messagedlg

Formulário:

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 20
BitBtn1 Caption Excluir

Procedimentos:

procedure TForm1.BitBtn1Click(Sender: TObject);


begin
if messagedlg('Confirma exclusão?',mtconfirmation,[mbyes,mbno],0)=mryes then
showmessage('Exclusão confirmada!')
else
showmessage('Exclusão cancelada!');
end;

Comentários:

Prática 21 – Utilizando o comando messagedlgpos

Formulário:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 67 de 272

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 21
BitBtn1 Caption Aplicar Click BitBtn1Click
Labelededit1 Caption Indique a coluna da mensagem
Labelededit2 Caption Indique a linha da mensagem

Procedimentos:

procedure TForm1.BitBtn1Click(Sender: TObject);


begin
messagedlgpos('Mensagem na linha:'+ labelededit2.Text + ' e na coluna:'+ labelededit1. Text,
mtinformation,[mball,mbno],0,strtoint(labelededit1.Text),strtoint(labelededit2.Text));
end;

Comentários:

Exercício 09 – Na prática 18, inclua na rotina de exclusão uma mensagem de confirmação para
decisão do usuário.

Capitulo XV – Rotinas especiais (Procedures e Funções)

Observe a prática 18, note que existem rotinas que se repetem várias vezes durante a confecção da
página de código:

// limpeza dos campos


// transferencia dos dados da tabela para o formulário
// mostrando os dados

Observe agora o procedimento elocalizarclick, note que os comandos utilizados para ajustar a
chave e índices e configurar os campos de busca são comuns para cada uma das opções case,
mudando-se apenas o seu valor.

Como sabemos os procedimentos ocorridos na linguagem orientada a objetos são independentes,


portanto uma única rotina escrita poderá ser utilizada por diversos objetos e por diversas vezes,
quando este procedimento realizar um cálculo qualquer (lógico ou aritmético) e devolver algum
valor ao objeto que o disparou teremos uma função, porém se nenhum valor for devolvido a este
objeto teremos uma procedure.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 68 de 272

Para criar a procedure limparcampos, precisamos reservar um espaço na memória para sua
colocação, assim utilizaremos a cláusula Var para sua declaração, a cláusula implementation para
sua descrição.

Abra a pratica 18 e nela o formulário FClientes, para criar o procedimento limparcampos proceda a
seguinte descrição.

Na cláusula Var inclua: procedure limparcampos();

var
Fclientes: TFclientes;
procedure Limparcampos();

Na cláusula implementation inclua: procedure limparcampos() e digite seu conteúdo.

procedure limparcampos();
begin
with fclientes do
begin
ecodigo.Text:='';
etipo.ItemIndex:=-1;
ebairro.Text:='';
ecpf_cnpj.Text:='';
ecliente.Text:='';
erg_insestadual.Text:='';
elogradouro.Text:='';
ecomplemento.Text:='';
enumero.Text:='';
ecidade.Text:='';
eestado.Text:='';
ecep.Text:='';
etelefone.Text:='';
end;
end;

Agora que a procedure já foi criada é só chamá-la, para isso localize o comentário \\ limpeza dos
campos, nos procedimentos da unit de fclientes, substitua as linhas que executam a limpeza por
limparcampos();, conforme descrição.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 69 de 272

Localize Substitua por Nos Procedimentos


// limpeza dos campos
ecodigo.Text:='';
etipo.ItemIndex:=-1;
ebairro.Text:='';
ecpf_cnpj.Text:='';
ecliente.Text:=''; FormActivate
erg_insestadual.Text:=''; NovoClick
Limparcampos();
elogradouro.Text:=''; SalvarClick
ecomplemento.Text:=''; ExcluirClick
enumero.Text:='';
ecidade.Text:='';
eestado.Text:='';
ecep.Text:='';
etelefone.Text:='';

As rotinas // transferencia dos dados da tabela para o formulário e // mostrando os dados, fazem a
mesma coisa, portanto podem ser substituídas por uma procedure que denominaremos de
procedure mostrardados(),

Na cláusula Var inclua: procedure mostrardados();

var
Fclientes: TFclientes;
procedure Limparcampos();
procedure Mostrardados();

Na cláusula implementation inclua: procedure mostrardados() e digite seu conteúdo.

procedure Mostrardados();
begin
with fclientes do
begin
ecodigo.Text:=dm.TClientesCodigo.Text;
etipo.ItemIndex:=dm.TClientesTipo.Value;
ebairro.Text:=dm.TClientesBairro.Text;
ecpf_cnpj.Text:=dm.TClientesCpf_cnpj.Text;
ecliente.Text:=dm.TClientesCliente.Text;
erg_insestadual.Text:=dm.TClientesRg_insestaudal.Text;
elogradouro.Text:=dm.TClientesLogradouro.Text;
ecomplemento.Text:=dm.TClientesComplemento.Text;
enumero.Text:=dm.TClientesNumero.Text;
ecidade.Text:=dm.TClientesCidade.Text;
eestado.Text:=dm.TClientesEstado.Text;
ecep.Text:=dm.TClientesCep.Text;
etelefone.Text:=dm.TClientesTelefone.Text;
end;
end;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 70 de 272

Agora substitua as linhas que mostram os dados por mostrardados();, conforme descrição.

Localize Substitua por Nos procedimentos


// mostrando os dados ou
// transferencia dos dados da tabela para o formulário
codigo.Text:=dm.TClientesCodigo.Text;
etipo.ItemIndex:=dm.TClientesTipo.Value;
ebairro.Text:=dm.TClientesBairro.Text; primeiroClick
ecpf_cnpj.Text:=dm.TClientesCpf_cnpj.Text; anteriorClick
ecliente.Text:=dm.TClientesCliente.Text; proximoClick
erg_insestadual.Text:=dm.TClientesRg_insestaudal.Text; mostrardados() ultimoClick
elogradouro.Text:=dm.TClientesLogradouro.Text; ecodigoExit
ecomplemento.Text:=dm.TClientesComplemento.Text; DBGrid1DblClick
enumero.Text:=dm.TClientesNumero.Text;
ecidade.Text:=dm.TClientesCidade.Text;
eestado.Text:=dm.TClientesEstado.Text;
ecep.Text:=dm.TClientesCep.Text;
etelefone.Text:=dm.TClientesTelefone.Text;

Depois que montamos algumas procedures e substituímos no nosso projeto observamos que um
grande número de linhas foram suprimidos, porém ainda há mais por fazer.

Observe o evento elocalizaClick, note que para cada valor do item.index os objetos que sofrem
alterações são os mesmos, apenas os valores atribuídos se alteram, este tipo de comportamento
sugere que de acordo com o item escolhido devemos informar seu valor.

Criaremos então uma função onde passaremos os objetos que sofrerão alterações e seus valores e a
denominaremos de função ajustabusca.

function ajustabusca(tabela:TTable;editmascara:TMaskedit;indice,mascara,texto:string;campo:tlabelededit):boolean;

Nesta função são criadas algumas variáveis representando objetos do formulário e outras
representando os possíveis valores que eles possam assumir:

Variável Tipo Valor


Tabela TTable Assume o valor de uma Table
Editmascara TMaskEdit Assume o valor de um MaskEdit
Índice String Guarda um valor string
Mascara String Guarda um valor string
Texto String Guarda um valor string
Campo TLabeledEit Assume o valor de um Labelededit

Obs: Os nomes atribuídos as variáveis de uma função não são convencionados, cabe ao
programador usar a nomeclatura que melhor lhe convir.

Como estamos utilizando uma variável tipo TTable teremos que acrescer a biblioteca DBTables
na cláusula uses da unit do formulário de clientes.

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, Mask, Grids, DBGrids, StdCtrls, ExtCtrls, ToolWin, ImgList,
Buttons, udm, db, DBTables;

Agora na cláusula var acrescemos a declaração da função:


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 71 de 272

var
Fclientes: TFclientes;
procedure Limparcampos();
procedure Mostrardados();
function ajustabusca(tabela:TTable;editmascara:TMaskedit;indice,mascara,texto:string;campo:tlabelededit):boolean;

Em seguida descrevemos a função na cláusula implementation:

function ajustabusca(tabela:TTable;editmascara:TMaskedit;indice,mascara,texto:string;campo:tlabelededit):boolean;
begin
tabela.IndexName:=indice;
tabela.SetKey;
tabela.First;
editmascara.EditMask:=mascara;
editmascara.Text:='';
editmascara.Width:=campo.Width;
result:=true;
end;

Uma vez descrita a função, vamos aplicar ao evento elocalizaClick:

procedure TFclientes.elocalizaClick(Sender: TObject);


begin
case elocaliza.ItemIndex of
0:ajustabusca(dm.TClientes,ebuscar,'idcliente','','',ecliente);
1:ajustabusca(dm.TClientes,ebuscar,'','9999999;0','',ecodigo);
2:ajustabusca(dm.TClientes,ebuscar,'','999.999.999-99;0','',erg_insestadual);
3:ajustabusca(dm.TClientes,ebuscar,'','99.999.999/9999-99;0','',erg_insestadual);
end;
end;

Comentários:

Capitulo XVI – Localizando dados em uma tabela

De nada adianta incluir dados em uma tabela se não tiver um meio de localizar o que foi incluído.
Para isso alguns métodos foram incorporados ao delphi:
Uso de coringa

Uso de parâmetro
Uso de Chave

Método Características

Gotokey Sim Não Não Localiza um único registro com exatidão


GotoNearest Sim Não Não Localiza o registro que mais se assemelha
FindKey Sim Não Não Localiza um único registro com exatidão
FindNearest Sim Não Não Localiza o registro que mais se assemelha
Locate Não Não Sim Localiza um registro com base em um dado ou parte deste
Localiza um registro com base no número de registro
RecNo Não Não Não
ou informa o número do registro atual
First Não Não Não Localiza o primeiro registro da tabela
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 72 de 272

Prior Não Não Não Localiza o registro anterior ao atual


Next Não Não Não Localiza o registro seguinte ao atual
Last Não Não Não Localiza o último registro da tabela
Filtered Não Não Não Habilita/desabilita o uso de filtros
Filter Não Não Sim Separa um grupo de registros segundo uma condição

Prática 22 – Localizando registros (métodos GotoKey, GotoNearest, FindKey, FindNearest)

Abra a pratica 18 e inclua 10 registros no cadastro de clientes, em seguida feche a pratica e inicie
uma nova aplicação.

Formulário:

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 22 OnActivate Form1Activate
Caption Método OnClick RadioGroup1Click
GotoKey
RadioGroup1 GotoNearest
Items FindKey
FinNearest
Método GotoKey
Caption ou FindKey
GroupBox1
Name GB1
Método
Caption GotoNearest ou
GroupBox2 FindNearest
Name GB2
EditLabel.Caption Código:
LabeledEdit1
LabelPosition Lpleft
EditLabel.Caption Cliente:
LabeledEdit2
LabelPosition Lpleft
BitBtn1 Caption Localizar OnClick BitBtn1Click
BitBtn2 Caption Localizar OnClick BitBtn2Click
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 73 de 272

Name TClientes
Table1 DataBaseName Dados
TableName Clientes.DB
DataSource1 DataSet TClientes
Label1 Caption Código
Label2 Caption Cliente
Label3 Caption Cpf / cnpj
Label4 Caption Rg /I.Estaudal
Label5 Caption Logradouro
Label6 Caption Número
Label7 Caption Complemento
Label8 Caption Bairro
Label9 Caption Cidade
Label10 Caption Estado
Label11 Caption Cep
Label12 Caption Telefone
DbGrid1 DataSource DataSource1
DataSource DataSource1
DBEdit1
DataField Código
DataSource DataSource1
DBEdit2
DataField Cliente
DataSource DataSource1
DBEdit3
DataField Cpf_cnpj
DataSource DataSource1
DBEdit4
DataField Rg_inestadual
DataSource DataSource1
DBEdit5
DataField Logradouro
DataSource DataSource1
DBEdit6
DataField Numero
DataSource DataSource1
DBEdit7
DataField Complemento
DataSource DataSource1
DBEdit8
DataField Bairro
DataSource DataSource1
DBEdit9
DataField Cidade
DataSource DataSource1
DBEdit10
DataField Estado
DataSource DataSource1
DBEdit11
DataField Cep
DataSource DataSource1
DBEdit12
DataField Telefone

Rotinas especiais Nome


Função Vergroupbox

Procedimentos:

function vergroupbox(bg1,bg2:TGroupBox;ver1,ver2:boolean):boolean;
begin
bg1.Visible:=ver1;
bg2.Visible:=ver2;
result:=true;
end;

procedure TForm1.FormActivate(Sender: TObject);


begin
vergroupbox(gb1,gb2,false,false);
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 74 de 272

tclientes.Open;
radiogroup1.ItemIndex:=-1;
end;

procedure TForm1.RadioGroup1Click(Sender: TObject);


begin
if (radiogroup1.ItemIndex=0) or (radiogroup1.ItemIndex=2) then
vergroupbox(gb1,gb2,true,false)
else
vergroupbox(gb1,gb2,false,true);
end;

procedure TForm1.BitBtn1Click(Sender: TObject);


begin
tclientes.IndexName:='';
tclientes.SetKey;
if radiogroup1.ItemIndex=0 then
begin
tclientescodigo.Text:=labelededit1.Text;
tclientes.GotoKey;
end
else
tclientes.FindKey([labelededit1.Text]);
end;

procedure TForm1.BitBtn2Click(Sender: TObject);


begin
tclientes.IndexName:='idcliente';
tclientes.SetKey;
if radiogroup1.ItemIndex=0 then
begin
tclientescodigo.Text:=labelededit2.Text;
tclientes.GotoNearest;
end
else
tclientes.FindNearest([labelededit2.Text]);
end;

Comentários:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 75 de 272

Prática 23 – Localizando registros (métodos Recnº)

Formulário:

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 23 OnActivate Form1Activate
Caption Método RecNº
GroupBox1
Name GB1
EditLabel.Caption Registro:
LabeledEdit1
LabelPosition Lpleft
BitBtn1 Caption Localizar OnClick BitBtn1Click
Name TClientes
Table1 DataBaseName Dados
TableName Clientes.DB
DataSource1 DataSet TClientes
Label1 Caption Código
Label2 Caption Cliente
Label3 Caption Cpf / cnpj
Label4 Caption Rg /I.Estaudal
Label5 Caption Logradouro
Label6 Caption Número
Label7 Caption Complemento
Label8 Caption Bairro
Label9 Caption Cidade
Label10 Caption Estado
Label11 Caption Cep
Label12 Caption Telefone
Caption Registro nº:
Name Registros
Label13
Font.size 14
Font.style Fsbold
DbGrid1 DataSource DataSource1
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 76 de 272

DataSource DataSource1
DBEdit1
DataField Código
DataSource DataSource1
DBEdit2
DataField Cliente
DataSource DataSource1
DBEdit3
DataField Cpf_cnpj
DataSource DataSource1
DBEdit4
DataField Rg_inestadual
DataSource DataSource1
DBEdit5
DataField Logradouro
DataSource DataSource1
DBEdit6
DataField Numero
DataSource DataSource1
DBEdit7
DataField Complemento
DataSource DataSource1
DBEdit8
DataField Bairro
DataSource DataSource1
DBEdit9
DataField Cidade
DataSource DataSource1
DBEdit10
DataField Estado
DataSource DataSource1
DBEdit11
DataField Cep
DataSource DataSource1
DBEdit12
DataField Telefone

Procedimentos:

procedure TForm1.FormActivate(Sender: TObject);


begin
tclientes.Open;
registros.Caption:='Registro n°:'+inttostr(tclientes.RecNo);
gb1.Visible:=false;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);


begin
tclientes.RecNo:=strtoint(labelededit1.Text);
registros.Caption:='Registro n°:'+inttostr(tclientes.RecNo);
gb1.Visible:=false;
end;

procedure TForm1.Button1Click(Sender: TObject);


begin
gb1.Visible:=false;
tclientes.First;
registros.Caption:='Registro n°:'+inttostr(tclientes.RecNo);
end;

procedure TForm1.Button2Click(Sender: TObject);


begin
gb1.Visible:=false;
tclientes.Prior;
registros.Caption:='Registro n°:'+inttostr(tclientes.RecNo);
end;

procedure TForm1.Button3Click(Sender: TObject);


begin
gb1.Visible:=false;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 77 de 272

tclientes.Next;
registros.Caption:='Registro n°:'+inttostr(tclientes.RecNo);
end;

procedure TForm1.Button4Click(Sender: TObject);


begin
gb1.Visible:=false;
tclientes.Last;
registros.Caption:='Registro n°:'+inttostr(tclientes.RecNo);
end;

procedure TForm1.Button5Click(Sender: TObject);


begin
gb1.Visible:=true;
end;

Comentários:

Prática 24 – Localizando registros (métodos Locate)

Formulário:

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 24 OnActivate Form1Activate
Caption Método Locate
GroupBox1
Name GB1
EditLabel.Caption Valor::
LabeledEdit1
LabelPosition Lpleft
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 78 de 272

BitBtn1 Caption Localizar OnClick BitBtn1Click


Name TClientes
Table1 DataBaseName Dados
TableName Clientes.DB
DataSource1 DataSet TClientes
Caption Campos:
Código
RadioGroup1 Cliente
Items CPF_CNPJ
RG_Ins.Estadual
Caption Parâmetro:
RadioGroup2 Case Insensitive (completo)
Items Partial Key (Parcial)
Label1 Caption Código
Label2 Caption Cliente
Label3 Caption Cpf / cnpj
Label4 Caption Rg /I.Estaudal
Label5 Caption Logradouro
Label6 Caption Número
Label7 Caption Complemento
Label8 Caption Bairro
Label9 Caption Cidade
Label10 Caption Estado
Label11 Caption Cep
Label12 Caption Telefone
DbGrid1 DataSource DataSource1
DataSource DataSource1
DBEdit1
DataField Código
DataSource DataSource1
DBEdit2
DataField Cliente
DataSource DataSource1
DBEdit3
DataField Cpf_cnpj
DataSource DataSource1
DBEdit4
DataField Rg_inestadual
DataSource DataSource1
DBEdit5
DataField Logradouro
DataSource DataSource1
DBEdit6
DataField Numero
DataSource DataSource1
DBEdit7
DataField Complemento
DataSource DataSource1
DBEdit8
DataField Bairro
DataSource DataSource1
DBEdit9
DataField Cidade
DataSource DataSource1
DBEdit10
DataField Estado
DataSource DataSource1
DBEdit11
DataField Cep
DataSource DataSource1
DBEdit12
DataField Telefone

Procedimentos:

procedure TForm1.FormActivate(Sender: TObject);


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 79 de 272

begin
tclientes.Open;
radiogroup1.ItemIndex:=-1;
radiogroup2.ItemIndex:=-1;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);


begin
case radiogroup1.ItemIndex of
0:begin
if radiogroup2.ItemIndex=0 then
tclientes.Locate('codigo',labelededit1.Text,[locaseinsensitive])
else
tclientes.Locate('codigo',labelededit1.Text,[lopartialKey]);
end;
1:begin
if radiogroup2.ItemIndex=0 then
tclientes.Locate('cliente',labelededit1.Text,[locaseinsensitive])
else
tclientes.Locate('cliente',labelededit1.Text,[lopartialKey]);
end;
2:begin
if radiogroup2.ItemIndex=0 then
tclientes.Locate('cpf_cnpj',labelededit1.Text,[locaseinsensitive])
else
tclientes.Locate('cpf_cnpj',labelededit1.Text,[lopartialKey]);
end;
3:begin
if radiogroup2.ItemIndex=0 then
tclientes.Locate('rg_inestaudal',labelededit1.Text,[locaseinsensitive])
else
tclientes.Locate('rg_inestaudal',labelededit1.Text,[lopartialKey]);
end;
end;
end;

Comentários:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 80 de 272

Prática 25 – Localizando registros (métodos Filter)

Formulário:

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 25
Caption Método Filter
GroupBox1
Name GB1
EditLabel.Caption Epressão:
LabeledEdit1
LabelPosition Lpleft
BitBtn1 Caption Localizar OnClick BitBtn1Click
Name TClientes
Table1 DataBaseName Dados
TableName Clientes.DB
DataSource1 DataSet TClientes
Label1 Caption Código
Label2 Caption Cliente
Label3 Caption Cpf / cnpj
Label4 Caption Rg /I.Estaudal
Label5 Caption Logradouro
Label6 Caption Número
Label7 Caption Complemento
Label8 Caption Bairro
Label9 Caption Cidade
Label10 Caption Estado
Label11 Caption Cep
Label12 Caption Telefone
DbGrid1 DataSource DataSource1
DataSource DataSource1
DBEdit1
DataField Código
DataSource DataSource1
DBEdit2
DataField Cliente
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 81 de 272

DataSource DataSource1
DBEdit3
DataField Cpf_cnpj
DataSource DataSource1
DBEdit4
DataField Rg_inestadual
DataSource DataSource1
DBEdit5
DataField Logradouro
DataSource DataSource1
DBEdit6
DataField Numero
DataSource DataSource1
DBEdit7
DataField Complemento
DataSource DataSource1
DBEdit8
DataField Bairro
DataSource DataSource1
DBEdit9
DataField Cidade
DataSource DataSource1
DBEdit10
DataField Estado
DataSource DataSource1
DBEdit11
DataField Cep
DataSource DataSource1
DBEdit12
DataField Telefone

Procedimentos:

procedure TForm1.BitBtn1Click(Sender: TObject);


begin
tclientes.Close;
tclientes.Filtered:=false;
tclientes.Filter:=labelededit1.Text;
tclientes.Filtered:=true;
tclientes.Open;
end;

Comentários:

Exercício 10 – Crie consultas para o seu projeto

Agora que vimos algumas práticas de consultar dados de uma tabela, inclua no menu de consultas
do projeto Pratica 18.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 82 de 272

Capitulo XVII – Relacionando tabelas

A relação entre tabelas consiste basicamente na interligação entre os campos das tabelas a se
relacionar, pode ser sincrônica, quando os campos relacionais das duas tabelas sofrem alterações
simultaneamente, ou não sincrônica quando apenas o campo de uma das tabelas sofre alteração.

Existem objetos capazes de criar relações entre tabelas, porém estes objetos exigem que os campos
sejam do mesmo tipo.

Existe também uma Linguagem EStruturada de Questões (Consultas), definida e conhecida como
SQL, baseada nas estruturas das tabelas e capazes de gerar relacionamentos entre elas.

Além dos objetos e do SQL, as relações também podem ser feitas através de métodos,
procedimentos ou funções capazes de associarem campos de tabelas diferentes.

Para entendermos os relacionamentos entre tabelas vamos criar 03 tabelas e salva-las no alias
dados.

Tabela de materiais:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 83 de 272

Com a tabela criada preencha os seguintes registros:

Tabela de Vendas:

Com a tabela criada preencha os seguintes registros:

Tabela de itens

Com a tabela criada preencha os seguintes registros:


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 84 de 272

Prática 26 – Relacionamento I

Anexe a unit dm.pas a esta pratica e inclua os seguintes objetos:

Objeto Name DataBaseName TableName Dataset


Table1 TMateriais Dados Materiais.db
Table2 TVendas Dados Vendas.db
Table3 TItens Dados Itens.db
DataSource1 DSMateriais TMateriais
DataSource2 DSVendas TVendas
DataSource3 DSItens TItens

Formulário:

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 26 OnActivate Form1Activate
Height 200
ScrollBox1
Width 400
Height 200
ScrollBox2
Width 400
ScrollBox3 Height 200
Width 400
ScrollBox4 Height 200
Width 400
Caption Clientes
Align AlTop
Alignment AlCenter
StaticText1
Color clBlue
Font.size 12
Font.color clWhite
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 85 de 272

Caption Cupons
Align AlTop
Alignment AlCenter
StaticText2
Color clBlue
Font.size 12
Font.color clWhite
Caption Itens do cupom
Align AlTop
Alignment AlCenter
StaticText3
Color clBlue
Font.size 12
Font.color clWhite
Caption Materiais
Align AlTop
Alignment AlCenter
StaticText4
Color clBlue
Font.size 12
Font.color clWhite
Label1 Caption Código
Label2 Caption Classe
Label3 Caption Produto
Label4 Caption Preço de custo
Label5 Caption Preço de venda
Label6 Caption Saldo
DataSource DSMateriais
DBEdit1
DataField Código
DataSource DSMateriais
DBEdit2
DataField Classe
DataSource DSMateriais
DBEdit3
DataField Produto
DataSource DSMateriais
DBEdit4
DataField Preço de custo
DataSource DSMateriais
DBEdit5
DataField Preço de venda
DataSource DSMateriais
DBEdit6
DataField Saldo
DBGrid1 DataSource DSClientes
DBGrid2 DataSource DSVendas
DBGrid2 DataSource DSItens

Inclua a biblioteca DB na claúsula USES

Procedimentos:

procedure TForm1.DBGrid1DblClick(Sender: TObject);


var filtro:string;
begin
filtro:='Cliente='+dm.TClientesCodigo.Text;
dm.TVendas.Close;
dm.TVendas.Filtered:=false;
dm.TVendas.Filter:=filtro;
dm.TVendas.Filtered:=true;
dm.TVendas.Open;
end;

procedure TForm1.DBGrid3DblClick(Sender: TObject);


var filtro1:string;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 86 de 272

begin
filtro1:='Cupom='+dm.TVendasCupom.Text;
dm.TItens.Close;
dm.TItens.Filtered:=false;
dm.TItens.Filter:=filtro1;
dm.TItens.Filtered:=true;
dm.TItens.Open;
end;

procedure TForm1.DBGrid4DblClick(Sender: TObject);


begin
dm.TMateriais.Locate('codigo',dm.TItensMaterial.Text,[locaseinsensitive]);
end;

Comentários:

Prática 27 – Relacionamento II

Adicione a unit dm.pas a esta pratica.

Formulário:

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 27 OnActivate Form1Activate
Bitbtn1 Caption Adicionar OnClick Bitbtn1Click
Bitbtn2 Caption Salvar OnClick Bitbtn2Click
Bitbtn3 Caption Novo OnClick Bitbtn3Click
Label1 Caption Cliente
Label2 Caption Material
Label3 Caption Itens
Label4 Caption Vendas
Label4 Caption Material Quantidade
LabeledEdit1 Caption N° do cupom
LabeledEdit1 Name Cupom
LabeledEdit2 Caption Total do cupom
LabeledEdit2 Name Totalcupom
LabeledEdit3 Caption Preço de venda
LabeledEdit3 Name Pvenda
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 87 de 272

LabeledEdit4 Caption Quantidade


LabeledEdit4 Name Quantidade
DBLookupComboBox1 ListSource Dm.DSMateriais
DBLookupComboBox1 KeyField Código
DBLookupComboBox1 ListField Produto
DBLookupComboBox2 ListSource Dm.DSClientes
DBLookupComboBox2 KeyField Código
DBLookupComboBox2 ListField Cliente
DBGrid1 DataSource Dm.DSItens
DBGrid2 DataSource Dm.DSVendas
GroupBox1 Caption Itens vendidos:
ListBox1 Name LB1
ListBox2 Name LB2

Procedimentos:

procedure TForm1.FormActivate(Sender: TObject);


begin
dm.TMateriais.Open;
dm.TVendas.Open;
dm.TItens.Open;
dm.TClientes.Open;
end;

procedure TForm1.BitBtn3Click(Sender: TObject);


var proximo:integer;
begin
dm.TVendas.Last;
proximo:=dm.TVendas.RecNo+1;
cupom.Text:=inttostr(proximo);
lb1.Clear;
lb2.Clear;
end;

procedure TForm1.DBLookupComboBox1Click(Sender: TObject);


begin
pvenda.Text:=dm.TMateriaisPreodeVenda.Text;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);


var stotal:real;
begin
if totalcupom.Text='' then totalcupom.Text:='0';
if quantidade.Text='' then quantidade.Text:='0';
stotal:=strtofloat(quantidade.Text)*strtofloat(pvenda.Text);
totalcupom.Text:=floattostr(stotal+strtofloat(totalcupom.Text));
lb1.Items.Add(dm.TMateriaisCodigo.Text);
lb2.Items.Add(quantidade.Text);
end;

procedure TForm1.BitBtn2Click(Sender: TObject);


var i:integer;
begin
for i:=0 to lb1.Count-1 do
begin
dm.TItens.Append;
dm.TItens.Edit;
dm.TItensCupom.Text:=cupom.Text;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 88 de 272

dm.TItensMaterial.Text:=lb1.Items.Strings[i];
dm.TItensQuantidade.Text:=lb2.Items.Strings[i];
dm.TItens.Post;
end;
dm.TVendas.Append;
dm.TVendas.Edit;
dm.TVendasCupom.Text:=cupom.Text;
dm.TVendasCliente.Text:=dm.TClientesCodigo.Text;
dm.TVendasData.AsDateTime:=date;
dm.TVendasValor.Text:=totalcupom.Text;
dm.TVendasVencimento.AsDateTime:=date+30;
dm.TVendas.Post;
end;

Comentários:

Capitulo XVIII – O SQL

As vezes temos a necessidade de criar tabelas auxiliares para fins de consultas ou impressão,
tabelas que terão um tempo de vida curto e que tendem a ser criadas pelo projeto em tempo de
execução e a ser excluída tão logo o projeto seja fechado se não forem salvas.

Estas tabelas recebem o nome de Query e se originam de Tabelas já existentes, normalmente as


query baseiam-se em uma Linguagem Estruturada de Questões, conhecida com SQL, (Structured
Query Linguage), que compõem-se de comandos simples:

• SELECT – Seleciona um, algum, ou todos os campos de uma ou algumas tabelas;


• FROM – Especifica as tabelas a serem usadas pelo SELECT;
• WHERE – Especifica uma condição a ser usada na seleção dos campos;
• ORDER BY – Determina a classificação, isto é, a ordem em que os campos devem ser
mostrados;
• GROUP BY – Cria grupos onde serão organizados os campos;
• HAVING – Determina uma condição para um GROUP BY;
• UNION – Promove a união de dois ou mais SELECT’s promovendo uma única saída;

A relação entre as query’s e o SQL é única, isto é, ao se gerar uma query de maneira manual,
através do DataBase Desktop, automaticamente a esta query será adicionada um script SQL, o que
nos possibilita afirmar que podemos alterar em tempo de execução toda a forma de uma query,
bastando somente para isto alterar os parâmetros da SQL.

Criando uma query pelo DataBase Desktop

Abra o DBD e escolha a opção: File... New... QBE Query...;


Selecione o alias Dados e escolha a tabela Clientes.DB;
Click em Abrir:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 89 de 272

Dê um click sobre o checkbox da tabela: “Clientes.DB”;

Esta pronta a nossa query.

Para verificar o resultado execute-a pressionando sobre o botão: Run Query:

Para verificar os parâmetros da SQL pressione sobre o botão: Show SQL:

SELECT DISTINCT Codigo, Tipo, Cliente, Cpf_cnpj, Rg_insestaudal, Logradouro, Numero,


Complemento, Bairro, Cidade, Estado, Cep, Telefone
FROM ":Dados:Clientes.DB"
ORDER BY Codigo, Tipo, Cliente, Cpf_cnpj, Rg_insestaudal, Logradouro, Numero,
Complemento, Bairro, Cidade, Estado, Cep, Telefone

A clausula DISTINCT é opcional e indica que o nome dos campos não se repetem para a tabela
indicada pela clausula FROM.

Click sobre o botão Run SQL e observe o resultado de nossa query:

Criando uma relação entre duas tabelas através do query de modo interativo

Novamente entraremos no DBD e criarem uma nova query com base na tabela Clientes.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 90 de 272

Em seguida click no botão Add Table e escolha no alias curso a tabela Vendas.DB e selecione
todos os seus campos:

Agora criaremos uma relação entre estas duas tabelas pressionado o botão join Tables e clicando
sobre os campos Codigo de Clientes.DB e logo em seguida no campo Cliente de Vendas.db:

Agora observe o resultado obtido clicando sobre o botão Run Query.

Veremos agora como está a arrumação do nosso SQL, click em Show SQL.

SELECT DISTINCT D.Codigo, D.Tipo, D.Cliente, D.Cpf_cnpj, D.Rg_insestaudal,


D.Logradouro, D.Numero, D.Complemento, D.Bairro, D.Cidade, D.Estado, D.Cep, D.Telefone,
D1.Cupom, D1.Cliente, D1.Data, D1.Valor, D1.Vencimento
FROM ":Dados:Clientes.DB" D, ":Dados:Vendas.DB" D1
WHERE
(D1.Cliente = D.Codigo)
ORDER BY D.Codigo, D.Tipo, D.Cliente, D.Cpf_cnpj, D.Rg_insestaudal, D.Logradouro,
D.Numero, D.Complemento, D.Bairro, D.Cidade, D.Estado, D.Cep, D.Telefone, D1.Cupom,
D1.Cliente, D1.Data, D1.Valor, D1.Vencimento

Observe a presença das letras D e d1 que aparecem antes dos nomes dos campos nas clausulas
SELECT, WHERE e ORDER BY e depois dos nomes das tabelas na clausula FROM. Estas
letras representam os ALIAS criados pelo SQL para este exemplo.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 91 de 272

Observe também que ao criarmos um JOIN no campo Cliente da tabela Vendas.DB e no campo
Codigo da tabela Clientes.DB, criamos uma relação entre elas, esta relação se apresenta no SQL
através da clausula WHERE.

Criando uma relação entre três tabelas através do query de modo interativo

Novamente entraremos no DBD e criarem uma nova query com base na tabela Clientes.DB que
está armazenada em C:\Curso de delphi ou simplesmente Alias Curso:

Em seguida click no botão Add Table e escolha no alias curso a tabela Vendas.DB e selecione
todos os seus campos:

Em seguida click no botão Add Table e escolha a tabela Itens.DB e selecione todos os seus
campos:

Agora criaremos uma relação entre estas duas tabelas pressionado o botão join Tables e clicando
sobre os campos Codigo de Clientes.DB e logo em seguida no campo Cliente de Vendas.db,
novamente pressione o botão Join Tables e selecione os campos Cupom de Vendas.DB e Cupom
em Itens.DB:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 92 de 272

Uma vez criadas as relações, verifique como ficaram os parâmetros do SQL:

SELECT DISTINCT D.Codigo, D.Tipo, D.Cliente, D.Cpf_cnpj, D.Rg_insestaudal,


D.Logradouro, D.Numero, D.Complemento, D.Bairro, D.Cidade, D.Estado, D.Cep, D.Telefone,
D1.Cupom, D1.Cliente, D1.Data, D1.Valor, D1.Vencimento, D2.Ctrl, D2.Cupom, D2.Material,
D2.Quantidade
FROM ":Dados:Clientes.DB" D, ":Dados:Vendas.DB" D1, ":Dados:Itens.DB" D2
WHERE
(D1.Cliente = D.Codigo)
AND (D2.Cupom = D1.Cupom)
ORDER BY D.Codigo, D.Tipo, D.Cliente, D.Cpf_cnpj, D.Rg_insestaudal, D.Logradouro,
D.Numero, D.Complemento, D.Bairro, D.Cidade, D.Estado, D.Cep, D.Telefone, D1.Cupom,
D1.Cliente, D1.Data, D1.Valor, D1.Vencimento, D2.Ctrl, D2.Cupom, D2.Material, D2.Quantidade

Observe a presença do operador AND na clausula WHERE, pois os joins criados durante a
confecção do query estão representados por esta clausula.

Prática 28 – Criando o relacionamento entre as tabelas clientes, vendas, itens e materias em


tempo de execução

Formulário:

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 28 OnActivate Form1Activate
DataBaseName Dados
Query1
SQL Strings...
DataSource1 DataSet Query1
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 93 de 272

Query1.SQL Strings...

SELECT *
FROM Clientes A, Vendas B, Itens C, Materiais D
WHERE (A.Codigo=B.Cliente) and (B.Cupom=C.Cupom) and (C.Material=D.Codigo)

Procedimentos:

procedure TForm1.FormActivate(Sender: TObject);


begin
query1.Open;
end;

Comentários:

Prática 29 – Selecionando todas as compras de um cliente

Formulário:

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 29 OnActivate Form1Activate
Query1 DataBaseName Dados
DataSet Query1
DataSource1
Name DSQuery
DataBaseName Dados
Table1
TableName Clientes
DataSet Table1
DataSource2
Name DSTable
Label1 Caption Cliente
BitBtn1 Caption Aplicar OnClick Bitbtn1Click
DBGrid1 DataSource DSQuery
ListSource DSTable
DBLookupCombobox1 KeyField Código
ListField Cliente

Procedimentos:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 94 de 272

procedure TForm1.Button1Click(Sender: TObject);


begin
query1.Open;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);


var condicao:string;
begin
query1.SQL.Clear;
query1.SQL.Add('SELECT *');
query1.SQL.Add('FROM Clientes A, Vendas B, Itens C, Materiais D');
query1.SQL.Add('WHERE (A.Codigo=B.Cliente) and (B.Cupom=C.Cupom) and
(C.Material=D.Codigo) and (A.cliente='''+table1cliente.Text+''''+')');
query1.Open;
end;

procedure TForm1.FormActivate(Sender: TObject);


begin
table1.Open;
end;

Comentários:

Operadores WHERE

Classe Operador Operação


+ Adição
- Subtração
Aritméticos
* Multiplicação
/ Divisão
= Igual a
<> Diferente de
> Maior que
Comparação
< Menor que
>= Maior ou igual
<= Menor ou igual
AND União
Lógicos OR Intersecção
NOT Negação
Especiais IN Contido em uma lista
BETWEEN e AND Compreendido em uma faixa
EXISTS Cria uma subconsulta baseada na clausula WHERE
LIKE Permite o uso de mascaras
IS NULL Verifica a presença de campos vazios
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 95 de 272

Exemplos de consultas

01 – Consulta materiais com saldo maior que 100

Select material, saldo


From materiais
Where saldo>100

02 – Consulta materiais com saldo maior que 100 e menor que 500

Select material, saldo


From materiais
Where saldo>100 and saldo<500

03 – Consulta materiais e saldo em ordem crescente

Select material, saldo


From materiais
Order by saldo

04 – Consulta materiais e saldo em ordem decrescente

Select material, saldo


From materiais
Order by saldo desc

05 – Consulta materiais com campo saldo vazio

Select material, saldo


From materiais
Where saldo is null

06 – Consulta materiais com campo saldo preenchido

Select material, saldo


From materiais
Where saldo is not null

07 – Consulta materiais e saldo cujo material comece com C

Select material, saldo


From materiais
Where material like “C %”

08 – Consulta materiais e saldo cujo material possua a string ANEL

Select material, saldo


From materiais
Where material like “%ANEL %”

09 – Consulta materiais e saldo cujo material termine com NADOR

Select material, saldo


From materiais
Where material like “ %NADOR”
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 96 de 272

10 – Consulta clientes que morem em SE e AL

Select cliente, estado


From clientes
Where estado IN (“SE”, “AL”)

Funções SQL Função


UPPER Retorna a consulta em maiúscula
AVG Retorna a média dos valores armazenados um campo
MIN Retorna o menor valor armazenado em um campo
MAX Retorna o maior valor armazenado em um campo
SUM Retorna a soma dos valores armazenados em um campo

Exemplos de consultas

01 – Maiúsculas

Select Upper(material), saldo


From materiais

02 – Média

Select Avg(saldo)
From materiais

03 – Mínimo

Select Min(saldo)
From materiais

04 – Máximo

Select Max(saldo)
From materiais

05 – Soma

Select Sum(saldo)
From materiais
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 97 de 272

Capitulo XIX – Trabalhando com mídias

O delphi através de suas bibliotecas consegue criar interfaces com diversos softwares, dentre estes
softwares de interpretação de arquivos AVI, BMP,WMW e MID.

Prática 30 – Lendo mídias com uso de objetos

O MediaPlayer é um objeto que simula o Windows Média Player.

Crie uma nova aplicação e inclua um novo formulário ao já existente.

Inclua na clausula USES a biblioteca MPlayer e a Unit2.

Formulário:

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 30
MediaPlayer1 Visible False
Name RGWav Click RGWavClick
Caption Arquivos WAV
Telefone
RadioGroup1
Impressora
Items
Sim
Não
Name RGAvi Click RGAviClick
Caption Arquivos AVI
RadioGroup2 Delphi
Items Microsoft
Cool
RadioGroup3 Name RGMid Click RGMdiClick
Caption Arquivos MID
Música 1
Items Música 2
Música 3
Name RGWmw Click RGWmwClick
Caption Arquivos WMW
RadioGroup4 WMV 1
Items WMV 2
WMV 3
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 98 de 272

Crie a função: Function ativaplay(som:TMediaPlayer;arquivo:String):boolean; na clausula VAR

Procedimentos:

Function ativaplay(som:TMediaPlayer;arquivo:String):boolean;
begin
som.Close;
som.FileName:=arquivo;
som.Open;
som.Play;
result:=true;
end;

procedure TForm1.RGWavClick(Sender: TObject);


begin
ativaplay(mediaplayer1,'\Delphi 2005\midias\Wav\'+rgwav.Items.Strings[rgwav.itemindex]+'.WAV');
end;

procedure TForm1.RGAviClick(Sender: TObject);


begin
ativaplay(mediaplayer1,'\Delphi 2005\midias\Avi\'+rgavi.Items.Strings[rgavi.itemindex]+'.AVI');
end;

procedure TForm1.RGMidClick(Sender: TObject);


begin
ativaplay(mediaplayer1,'\Delphi 2005\midias\Mid\'+rgmid.Items.Strings[rgmid.itemindex]+'.MID');
end;

procedure TForm1.RGWmvClick(Sender: TObject);


begin
ativaplay(mediaplayer1,'\Delphi 2005\midias\Wmv\'+rgwmv.Items.Strings[rgwmv.itemindex]+'.WMV');
end;

Comentários:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 99 de 272

Prática 31 – Tocando sons wave via função

Neste projeto utilizaremos a biblioteca MMSystem, que será a responsável pelas funções:
SndPlaySound e PlaySound que farão o papel do mediaplayer, no entanto estas funções só
conseguem abrir os arquivos WAV.

Não esqueça de incluir a biblioteca MMSystem à clausula Uses do projeto:

Formulário:

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 31
Name RGSN Click RGsndClick
Utilizando método
Caption
SNDPLAYSOUND
RadioGroup1 Telefone
Impressora
Items
Sim
Não
RadioGroup1 Name RGplay Click RGplayClick
Utilizando método
Caption
PLAYSOUND
Telefone
Impressora
Items
Sim
Não

Procedimentos:
procedure TForm1.RGSNDClick(Sender: TObject);
var arquivo:Pchar;
begin
arquivo:=PChar('\Delphi 2005\midias\Wav\'+rgsnd.Items.Strings[rgsnd.itemindex]+'.WAV');
SndPlaySound(arquivo,SND_ASYNC);
end;
procedure TForm1.RGPlayClick(Sender: TObject);
var arquivo:Pchar;
begin
arquivo:=PChar('\Delphi 2005\midias\Wav\'+rgplay.Items.Strings[rgplay.itemindex]+'.WAV');
PlaySound(arquivo,2,SND_ASYNC);
end;

Comentários:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 100 de 272

Capitulo XX – Trabalhando com diálogos:

Os Diálogos são objetos que criam vínculos com funções internas do windows, os diálogos
disponíveis controlam as fontes, cores, arquivos e impressoras que por ventura estajam
incorporados ao sistema computacional.

Prática 32 – Trabalhando com diálogos

Formulário:

Objeto Propriedade Valor Evento Procedimento


Caption Trabalhando com
Form1
Dialog’s
GroupBox1 Caption Arquivo
GroupBox2 Caption Imagem
RichEdit1 Lines
RichEdit1 Align alClient
Image1 Align alClient
Image1 Stretch True
Novo
Arquivo Abrir
Salvar
Abrir
Imagem
Salvar
Alterar fonte
MainMenu1
Alterar cor
Texto
Localizar
Substituir
Impressão Imprimir
Ajustar impressora
Sair

Procedimentos:

procedure TForm1.Abrir1Click(Sender: TObject);


begin
if opendialog1.Execute=true then
richedit1.Lines.LoadFromFile(opendialog1.FileName);
end;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 101 de 272

procedure TForm1.Salvar1Click(Sender: TObject);


begin
if SaveDialog1.Execute=true then
RichEdit1.Lines.SaveToFile(SaveDialog1.FileName);
end;

procedure TForm1.Abrir2Click(Sender: TObject);


begin
if OpenPictureDialog1.Execute=true then
image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
end;

procedure TForm1.Salvar2Click(Sender: TObject);


begin
if SavePictureDialog1.Execute=true then
Image1.Picture.SaveToFile(SavePictureDialog1.FileName);
end;

procedure TForm1.Novo1Click(Sender: TObject);


begin
RichEdit1.Clear;
end;

procedure TForm1.Alterarfonte1Click(Sender: TObject);


begin
if FontDialog1.Execute=true then
RichEdit1.Font:=FontDialog1.Font;
end;

procedure TForm1.Alterarcor1Click(Sender: TObject);


begin
if ColorDialog1.Execute=true then
Richedit1.Color:=ColorDialog1.Color;
end;

procedure TForm1.Localizar1Click(Sender: TObject);


begin
FindDialog1.Position := Point(RichEdit1.Left + RichEdit1.Width, RichEdit1.Top);
FindDialog1.Execute;
end;

procedure TForm1.FindDialog1Find(Sender: TObject);


var
FoundAt: LongInt;
StartPos, ToEnd: Integer; // define o início e o fim do texto procurado
begin
with RichEdit1 do
begin
{começa a procura depois da seleção atual se há um
caso contrário, começa do início do texto}
if SelLength <> 0 then
StartPos := SelStart + SelLength
else
StartPos := 0;
{ToEnd é o tamanho a partir do StartPos para o fim do texto no RichEdit}
ToEnd := Length(Text) - StartPos;
FoundAt := FindText(FindDialog1.FindText, StartPos, ToEnd,[stMatchCase]);
if FoundAt <> -1 then
begin
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 102 de 272

SetFocus;
SelStart := FoundAt;
SelLength := Length(FindDialog1.FindText);
end;
end;
end;

procedure TForm1.Substituir1Click(Sender: TObject);


begin
FindDialog1.Position := Point(RichEdit1.Left + RichEdit1.Width, RichEdit1.Top);
ReplaceDialog1.Execute;
end;

procedure TForm1.ReplaceDialog1Replace(Sender: TObject);


var
SelPos: Integer;
begin
with TReplaceDialog(Sender) do
begin
{Procura o texto com busca em case-sensitive no RichEdit1}
SelPos := Pos(FindText, RichEdit1.Lines.Text);
if SelPos > 0 then
begin
RichEdit1.SelStart := SelPos - 1;
RichEdit1.SelLength := Length(FindText);
{Substitui o texto selecionado pelo texto indicado}
RichEdit1.SelText := ReplaceText;
end
else MessageDlg('Concluída', mtError, [mbOk], 0);
end;
end;

procedure TForm1.Imprimir1Click(Sender: TObject);


begin
if PrintDialog1.Execute=true then RichEdit1.Print('Impressão do Arquivo');
end;

procedure TForm1.Ajustarimpressora1Click(Sender: TObject);


begin
PrinterSetupDialog1.Execute;
end;

procedure TForm1.Sair1Click(Sender: TObject);


begin
Halt;
end;

Comentários:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 103 de 272

Considerações:

Existem algumas propriedades dos diálogos devem ser mencionadas por se tratarem de
propriedades de uso constante nos tratamentos de diálogos:

Propriedade Descrição Diálogo


OpenDialog
Indica o nome do arquivo que deverá ser aberto ou SaveDialog
FileName
salvo por um diálogo OpenPictureDialog
SavePictureDialog
OpenDialog
Indica qual o tipo de arquivo (extensão) deverá ser SaveDialog
Filter
filtrado OpenPictureDialog
SavePictureDialog
OpenDialog
Indica qual o diretório inicial para busca ou SaveDialog
InitialDir
gravação de arquivo OpenPictureDialog
SavePictureDialog
ReplaceDialog
FindText Indica o texto que deverá ser procurado
FindDialog

Capitulo XXI – Trabalhando unidades, pastas e arquivos:

As vezes em um projeto é necessário se localizar uma pasta para gravação de um arquivo ou


localizar um arquivo para exclusão ou cópia, tais procedimentos feitos por um operador de micro,
seriam realizados a nível de sistema operacional, no entanto, um desenvolvedor um pouco mais
experiente poderá, entretanto, executar estes procedimentos a nível de projeto, seja utilizando
objetos destinados para tal ou carregando ferramentas Shell do próprio windows.

Prática 33 – Localizando e executando arquivos via objetos

Formulário:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 104 de 272

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 33
Label1 Unidade:
Label2 Pasta:
Label3 Filtro:
Label4 Arquivos:
DriveComboBox1 DirList DirectoryListBox1
DirectoryListBox1 FileList FileListBox1
FilterComboBox1 FileList FileListBox1
FileListBox1 Filter Ver abaixo Click FileListBox1Click
StatusBar1 SimplePanel True
BitBtn1 Caption Abrir Click BitBtn1Click
BitBtn2 Caption Fechar Click BitBtn2Click

Propriedade filter do FilterComboBox1:

Procedimentos:

procedure TForm1.FileListBox1Click(Sender: TObject);


begin
StatusBar1.SimpleText:=FileListBox1.FileName;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);


var arquivo:PChar;
begin
case filtercombobox1.ItemIndex of
0:arquivo:=pChar('c:\windows\notepad.exe '+StatusBar1.SimpleText);
2:arquivo:=pChar('c:\arquivos de programas\internet explorer\iexplore.exe '+StatusBar1.SimpleText);
3:arquivo:=pChar(StatusBar1.SimpleText);
end;
winexec(arquivo,SW_Show); // Executa um aplicativo baseado no windows
end;

procedure TForm1.BitBtn2Click(Sender: TObject);


begin
close;
end;
Comentários:

Prática 34 – Um gerenciador de arquivos


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 105 de 272

Formulário:

Objeto Propriedade Valor Evento Procedimento


Caption Pratica 34
Form1
Menu MainMenu1
Caption Endereço:
Panel1
Align alTop
ShellListView ShellListView1
ShellTreeView ShellTreeView1
ShellComboBox1
Root rfDesktop
UseShellImages True
ShellListView ShellListView1
ShellComboBox ShellComboBox1
ShellTreeView1
Root rfDesktop
Align alLeft
ShellComboBox ShellComboBox1
ShellTreeView ShellTreeView1
ShellListView1
PopUpMenu PopUpMenu1
Align alClient
Caption Nova Pasta:
Panel2 Alignment alLeftJustify
Visible False
Edit1 Text Vazio (null)
BitBtn1 Caption Ok Click BitBtn1Click
PopUpMenu1 Items Nova Pasta
Images ImageList1
Arquivo
Criar Nova Pasta
Fechar
MainMenu1 Visualizar
Items
Detalhes
Ícones pequenos
Ícones grandes
Lista

Procedimentos:

procedure TForm1.Detalhes1Click(Sender: TObject);


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 106 de 272

begin
ShellListView1.ViewStyle:=vsReport; // Ajusta para detalhes
end;

procedure TForm1.Iconespequenos1Click(Sender: TObject);


begin
ShellListView1.ViewStyle:=vsSmallIcon; // Ajusta para icones pequenos
end;

procedure TForm1.Iconesgrandes1Click(Sender: TObject);


begin
ShellListView1.ViewStyle:=vsIcon; // Ajusta para icones grandes
end;

procedure TForm1.Lista1Click(Sender: TObject);


begin
ShellListView1.ViewStyle:=vsList; // Ajusta para lista
end;

procedure TForm1.Criarnovapasta1Click(Sender: TObject);


begin
panel3.Visible:=true;
edit1.Text:=ShellTreeView1.Path+'\'; //copia o caminho para edit1
edit1.SetFocus;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);


begin
MKDir(edit1.Text); // Cria diretório
panel3.Visible:=false;
end;

procedure TForm1.Fechar1Click(Sender: TObject);


begin
close;
end;

Comentários:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 107 de 272

Prática 35 – Outro gerenciador de arquivos

Formulário:

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 35 OnCreate Form1Create
Name StatusBar1
Align alTop
Panel1
Color clNavy
Font.Color clWhite
Name Floppy
Image1
Visible False
Name Fixed
Image2
Visible False
Name Network
Image3
Visible False
Name CDRom
Image4
Visible False
Name RamDisk
Image5
Visible False
ScrollBox1 Align alClient
DirectoryOutline1 OnChange DirectoryOutline1Change
Align alClient OnChange FileList1Change
PopupMenu PopArquivos
FileList1
ShowGlyphs True
OnMouseDown FileList1MouseDown
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 108 de 272

TabSet1 Align alBottom


Align alBottom
ScrollBox2
Visible False
Name Arquivo
Label1
Caption Arquivo
Name Caminho
Label2
Caption Caminho
Name Modificacoes
Label3
Caption Modificacoes
Align alTop
BorderStyle sbsSunken
Caption Propriedades
StaticText1
Color clNavy
Font.Color clWhite
Font.Style [fsBold]
GroupBox1 Caption Attributos
Name ReadOnly
CheckBox1
Caption &Read Only
Name Archive
CheckBox2
Caption &Archive
Name System
CheckBox3
Caption &System
Name Hidden
CheckBox4
Caption &Hidden
BitBtn1 Caption OK OnClick BitBtn1Click
Align alBottom
ScrollBox3
Visible False
Name diretorio
Label4
Caption Diretorio
Label5 Caption De
Label6 Caption Para
Align alTop
BorderStyle sbsSunken
Caption Move, Renomeia,
StaticText2 Copia
Color clNavy
Font.Color clWhite
Font.Style [fsBold]
Edit1 Name Origem
Edit2 Name Destino
BitBtn2 Caption OK OnClick BitBtn2Click
Name PopArquivos
Abrir OnClick Abrir1Click
Mover OnClick MoveCopiaRenomeia
PopupMenu1 Copiar OnClick MoveCopiaRenomeia
Items
Deletar OnClick Deletar1Click
Renomear OnClick MoveCopiaRenomeia
Propriedades OnClick Propriedades1Click
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 109 de 272

Procedimentos:

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, FileCtrl,
Grids, Outline, DirOutln, Tabs, ExtCtrls, Menus, Consts, ShellAPI, RtlConsts, Buttons;

private
// Procedimentos e funções criadas
procedure ConfirmChange(const ACaption, FromFile, ToFile: string);
procedure CopyFile(const FileName, DestName: string);
procedure MoveFile(const FileName, DestName: string);
function GetFileSize(const FileName: string): LongInt;
function FileDateTime(const FileName: string): TDateTime;
function HasAttr(const FileName: string; Attr: Word): Boolean;
function ExecuteFile(const FileName, Params, DefaultDir: string; ShowCmd: Integer): THandle;

type // Identificadores de erro


EInvalidDest = class(EStreamError); // Destino inválido
EFCantMove = class(EStreamError); // Impossivel movimento

implementation

const // Mensagens de erro


SInvalidDest = 'Destino %s não existe'; // Destino inválido
SFCantMove = 'Impossível mover o arquivo %s'; // Impossivel movimento

procedure TForm1.Sair1Click(Sender: TObject);


begin
Close;
end;

procedure TForm1.FormCreate(Sender: TObject);


var
Drive: Char;
AddedIndex: Integer;
begin
for Drive := 'a' to 'z' do
begin
case GetDriveType(PChar(Drive + ':\')) of // Verifica o tipo do drive
DRIVE_REMOVABLE: // Diskete
AddedIndex := TabSet1.Tabs.AddObject(Drive, Floppy.Picture.Graphic);
DRIVE_FIXED: // Winchester
AddedIndex := TabSet1.Tabs.AddObject(Drive, Fixed.Picture.Graphic);
DRIVE_CDROM: // CDRom
AddedIndex := TabSet1.Tabs.AddObject(Drive, CDRom.Picture.Graphic);
DRIVE_RAMDISK: // RamDrive
AddedIndex := TabSet1.Tabs.AddObject(Drive, RamDisk.Picture.Graphic);
DRIVE_REMOTE: // Drive de rede
AddedIndex := TabSet1.Tabs.AddObject(Drive, Network.Picture.Graphic);
else
AddedIndex := 0;
end;
if UpCase(Drive) = FileList1.Drive then
TabSet1.TabIndex := AddedIndex;
end;
end;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 110 de 272

procedure TForm1.TabSet1Change(Sender: TObject; NewTab: Integer;


var AllowChange: Boolean);
begin
if not (csDesigning in ComponentState) then
begin
AllowChange := True;
try
DirectoryOutline1.Drive := TabSet1.Tabs[NewTab][1];
except
on EInOutError do // Verifica erro de entrada e saída
begin
AllowChange := False;
DirectoryOutline1.Drive := TabSet1.Tabs[TabSet1.TabIndex][1];
raise;
end;
end;
end;
end;

procedure TForm1.DirectoryOutline1Change(Sender: TObject);


begin
FileList1.Directory := DirectoryOutline1.Directory;
StatusBar1.Caption := DirectoryOutline1.Directory;
end;

procedure TForm1.FileList1Change(Sender: TObject);


var
Nomedoarquivo,Nomedodiretorio,Tamanho: string;
begin
nomedodiretorio:=DirectoryOutline1.Directory;
with FileList1 do
begin
if ItemIndex >= 0 then
begin
Tamanho:= Items[ItemIndex];
Nomedoarquivo := Format('%s, %d bytes', [tamanho, GetFileSize(tamanho)]);
StatusBar1.Caption:=Nomedodiretorio+'\'+Nomedoarquivo;
end
else StatusBar1.Caption := '';
end;
end;

procedure TForm1.TabSet1MeasureTab(Sender: TObject; Index: Integer; var TabWidth: Integer);


var
BitmapWidth: Integer;
begin
// Este Procedimento determina o comprimento das abas do TabSet
BitmapWidth := TBitmap(TabSet1.Tabs.Objects[Index]).Width;
Inc(TabWidth, 2 + BitmapWidth);
end;

procedure TForm1.TabSet1DrawTab(Sender: TObject; TabCanvas: TCanvas; R: TRect; Index:


Integer; Selected: Boolean);
var
Bitmap: TBitmap;
begin
// Este procedimento mostra a imagem na aba do TabSet
Bitmap := TBitmap(TabSet1.Tabs.Objects[Index]);
with TabCanvas do
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 111 de 272

begin
Draw(R.Left, R.Top + 4, Bitmap);
TextOut(R.Left + 2 + Bitmap.Width, R.Top + 2, TabSet1.Tabs[Index]);
end;
end;

procedure TForm1.Arquivo1Click(Sender: TObject);


var
FileSelected: Boolean;
begin
// Este procedimento habilita uma ação do PopArquivo para o arquivo selecionado
FileSelected := FileList1.ItemIndex >= 0;
Abrir1.Enabled := FileSelected;
Deletar1.Enabled := FileSelected;
Copiar1.Enabled := FileSelected;
Mover1.Enabled := FileSelected;
Renomear1.Enabled := FileSelected;
Propriedades1.Enabled := FileSelected;
end;

procedure TForm1.Deletar1Click(Sender: TObject);


begin
with FileList1 do
if MessageDlg('Delete '+FileName+'?', mtConfirmation,[mbYes,mbNo],0)=mrYes then
if DeleteFile(FileName) then Update; // Deleta o arquivo e atualiza a lista
end;

procedure TForm1.Propriedades1Click(Sender: TObject);


var
Attributes, NewAttributes: Word;
begin
// Este procedimento mostra os atributos do arquivo
scrollBox2.Visible:=true;
Arquivo.Caption := FileList1.Items[FileList1.ItemIndex];
Caminho.Caption := FileList1.Directory;
Modificacoes.Caption := DateTimeToStr(FileDateTime(FileList1.FileName));
Attributes := FileGetAttr(Arquivo.Caption);
ReadOnly.Checked := (Attributes and faReadOnly) = faReadOnly;
Archive.Checked := (Attributes and faArchive) = faArchive;
System.Checked := (Attributes and faSysFile) = faSysFile;
Hidden.Checked := (Attributes and faHidden) = faHidden;
end;

procedure TForm1.ConfirmChange(const ACaption, FromFile, ToFile: string);


begin
// Este procedimento confirma a copia, a renomeação ou o movimento de um arquivo
if MessageDlg(Format('%s %s to %s?', [ACaption, FromFile, ToFile]),mtConfirmation, [mbYes, mbNo], 0) = mrYes then
begin
if ACaption='Mover' then MoveFile(FromFile, ToFile) // Movimento do arquivo
else if ACaption='Copiar' then CopyFile(FromFile, ToFile) // Copia do arquivo
else if ACaption='Renomear' then RenameFile(FromFile, ToFile);// Renomeia
FileList1.Update; // Atualiza lista
showmessage('Operação executada!'); // informa ao usuário
end;
end;

procedure TForm1.MoveCopiaRenomeia(Sender: TObject);


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 112 de 272

begin
// Este procedimento define as ações de copia, movimento ou renomeação
ScrollBox3.Visible:=true;
if Sender = Mover1 then StaticText2.Caption := 'Mover'
else if Sender = Copiar1 then StaticText2.Caption := 'Copiar'
else if Sender = Renomear1 then StaticText2.Caption := 'Renomear'
else Exit;
Diretorio.Caption := DirectoryOutline1.Directory;
Origem.Text := FileList1.FileName;
Destino.Text := '';
end;

procedure TForm1.Abrir1Click(Sender: TObject);


begin
// Este procedimento executa um arquivo
with FileList1 do
begin
if HasAttr(FileName,faDirectory) then DirectoryOutline1.Directory := FileName else
ExecuteFile(FileName,'',Directory,SW_SHOW);
end;
end;

procedure TForm1.FileList1MouseDown(Sender: TObject; Button: TMouseButton;


Shift: TShiftState; X, Y: Integer);
begin
end;

// Procedimentos externos

procedure TForm1.CopyFile(const FileName, DestName: string);


var
CopyBuffer: Pointer; { buffer de copia }
BytesCopied: Longint;
Source, Dest: Integer; { Títulos }
Len: Integer;
Destination: TFileName; { nome do caminho de destino }
const
ChunkSize: Longint = 8192; { copia em blocos de 8K 8x1024 bytes}
begin
// Este procedimento copia o arquivo em blocos
Destination := ExpandFileName(DestName); { expande o caminho de destino }
if HasAttr(Destination, faDirectory) then { se destino é um diretorio... }
begin
Len := Length(Destination); // Tamanho do destino
if Destination[Len] = '\' then
Destination := Destination + ExtractFileName(FileName) { ...clone do nome arquivo }
else
Destination := Destination + '\' + ExtractFileName(FileName); { ...clone do nome do arquivo }
end;
GetMem(CopyBuffer, ChunkSize); { aloca o buffer }
try
Source := FileOpen(FileName, fmShareDenyWrite); { abre arquivo de origem }
if Source < 0 then raise EFOpenError.CreateFmt(SFOpenError, [FileName]);
try
Dest := FileCreate(Destination); { cria arquivo de saída; se existir sobrepõe}
if Dest < 0 then raise EFCreateError.CreateFmt(SFCreateError, [Destination]);
try
repeat
BytesCopied := FileRead(Source, CopyBuffer^, ChunkSize); { lê Bloco }
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 113 de 272

if BytesCopied > 0 then { Já foi lido tudo?... }


FileWrite(Dest, CopyBuffer^, BytesCopied); { ...escreve bloco }
until BytesCopied < ChunkSize; { continue até o fim do bloco }
finally
FileClose(Dest); { fechar o arquivo de destino }
end;
finally
FileClose(Source); { fechar o arquivo de origem }
end;
finally
FreeMem(CopyBuffer, ChunkSize); { liberar o buffer }
end;
end;

procedure TForm1.MoveFile(const FileName, DestName: string);


var
Destination: string;
begin
// Este procedimento movimenta o arquivo
Destination := ExpandFileName(DestName); { expande o caminho de destino }
if not RenameFile(FileName, Destination) then { renomeia o arquivo de destino }
begin
if HasAttr(FileName, faReadOnly) then { O arquivo é somente de leitura?... }
raise EFCantMove.Create(Format(SFCantMove, [FileName])); {Não é possível mover ou deletar}
CopyFile(FileName, Destination); { copia o arquivo para destino...}
end;
end;

function TForm1.GetFileSize(const FileName: string): LongInt;


var
SearchRec: TSearchRec;
begin
// Esta função calcula e retorna o tamanho do arquivo
try
if FindFirst(ExpandFileName(FileName), faAnyFile, SearchRec) = 0 then
Result := SearchRec.Size
else Result := -1;
finally
SysUtils.FindClose(SearchRec);
end;
end;

function TForm1.FileDateTime(const FileName: string): System.TDateTime;


begin
// Retorna a data de criação do arquivo
Result := FileDateToDateTime(FileAge(FileName));
end;

function TForm1.HasAttr(const FileName: string; Attr: Word): Boolean;


var
FileAttr: Integer;
begin
// Captura os atributos do arquivo
FileAttr := FileGetAttr(FileName);
if FileAttr = -1 then FileAttr := 0;
Result := (FileAttr and Attr) = Attr;
end;

function TForm1.ExecuteFile(const FileName, Params, DefaultDir: string;ShowCmd: Integer):THandle;


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 114 de 272

var
zFileName, zParams, zDir: array[0..79] of Char;
begin
// Executa o arquivo através de um comando SHELL
Result:=ShellExecute(Application.MainForm.Handle,nil,
StrPCopy(zFileName,FileName),StrPCopy(zParams, Params),
StrPCopy(zDir,DefaultDir),ShowCmd);
end;

procedure TForm1.BitBtn1Click(Sender: TObject);


begin
ScrollBox2.Visible:=false;
end;

procedure TForm1.BitBtn2Click(Sender: TObject);


begin
// confirma se ação é de copia, renomeação ou movimento
if Destino.Text <> '' then
ConfirmChange(StaticText2.Caption, Origem.Text, Destino.Text);
ScrollBox3.Visible:=false;
end;

Comentários:

Capitulo XXII – Trabalhando com gráficos:

TChart é o componente mais importante em biblioteca de TeeChart. TChart deriva de TPanel e


herda toda sua funcionalidade. Em resumo, TChart é um standard componente básico do TPanel
com muitas capacidades específicas para desenhos com propósitos gráficos.

Você pode criar gráficos em tempo de projeto ou em run time.


Os componentes TeeChart também podem estar em uma Forma de ActiveX, e dividem-se em três
componentes básicos:

• TChart – Contido na paleta Additional, gera gráficos dinâmicos com valores randômicos ou
informados.
• TDBChart – Contido na paleta Data Controls, gera gráficos dinâmicos com valores obtidos de
uma Tabela ou Query.
• TQRChart – Contido na paleta QReport, introduz gráficos em um relatório gerado pelo
QuickReport.

Para a criação do TChart ou TDBChart, existem muitos passos comuns. Descreveremos a seguir
tais passos.

1. Crie um novo formulário e inclua um objeto TChart ou TDBChart;


2. Ajuste o tamanho do Chart, para sua melhor visualização;
3. Com o botão direito do mouse, click sobre o Chart;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 115 de 272

- About TeeChart – Informa sobre o TeeChart;


- Edit Chart – Abre a tela de edição do Chart;

- Print Preview – Ajusta a impressora e permite a impressão de um Chart;


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 116 de 272

- Export Chart – Envia um Chart para a memória ou arquivo de imagem;

4. Click sobre Edit Chart;


5. Click sobre a aba Chart e nesta escolha a aba Series;
6. Click sobre ADD... para começar a adição de novas séries:
7. Escolha as series que comporão nosso gráfico;
8. Os passos seguintes serão pessoais e dependerão do projeto.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 117 de 272

Para melhor entendimento dos Chart’s faremos agora a nossa prática.

Prática 36 – Criando gráficos:

Formulário:

Objeto Propriedade Valor Evento Procedimento


Form1 Caption Pratica 36
Caption Vazio (null)
Align alBottom
Panel1
Name Panelanimacao
Visible False
Caption Vazio (null)
Align alBottom
Panel2
Name PanelZoom
Visible False
Caption Vazio (null)
Align alBottom
Panel3
Name Panel3D
Visible False
Name Animar OnClick animarClick
CheckBox1
Caption Animar Pizza
Name Dimensao OnClick dimensaoClick
CheckBox2 Caption 3D
Checked True
Name Velocidade
Max 30
TrackBar1
Min 1
Position 5
Label1 Caption Lento
Label2 Caption Rápido
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 118 de 272

Caption Fechar OnClick FechaanimacaoClick


BitBtn1
Name Fechaanimacao
Caption Mais Zoom OnClick ZoommaisClick
BitBtn2
Name Zoommais
Caption Menos Zoom OnClick ZoommenosClick
BitBtn3
Name Zoommenos
Caption Fechar FechazoomClick
BitBtn4
Name Fechazoom
Label3 Caption Percentual de 3D:
Label4 Caption Rotação:
Label5 Caption Perspectiva:
Label6 Caption Inclinação:
Text 15 OnChange percentual3dChange
Edit1
Name Percentual3D
Text 360 OnChange RotacaoChange
Edit2
Name Rotacao
Text 0 OnChange PerspectivaChange
Edit3
Name Perspectiva
Text 0 OnChange InclinacaoChange
Edit4
Name Inclinacao
Name UpDpercentual
Max 100
UpDown1 Min 1
Associate Percentual3D
Position 15
Name UpDRotacao
Max 360
UpDown2 Min 0
Associate Rotacao
Position 360
Name UpDPerspectiva
Max 360
UpDown3 Min 0
Associate Perspectiva
Position 0
Name UpDInclinacao
Max 360
UpDown4 Min 0
Associate Inclinacao
Position 0
Caption Fechar OnClick Fecha3dClick
BitBtn5
Name Fecha3d
Caption Valores
GroupBox1
Visible False
Text Vazio (null)
Edit5
Name Valor
Text Vazio (null)
Edit6
Name Descricao
Caption Anexar OnClick AnexarClick
BitBtn6
Name Anexar
Caption Fechar OnClick FecharvaloresClick
BitBtn7
Name FechaValores
Timer1 Interval 10 OnTimer Timer1Timer
Button2 OnClick Button2Click
Chart1 Ver a seguir
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 119 de 272

Informar
OnClick Informarvalores1Click
valores
Configurar Animar OnClick Animar1Click
Zoom OnClick Zoom1Click
3D e
OnClick 3Deposicoes1Click
posicoes
Gráfico
de OnClick Grficodebarras1Click
MainMenu1 Items
Barras
Visualizar
Gráfico
OnClick Grficodereas1Click
de Áreas
Gráfico
OnClick Grficopizza1Click
de Pizza
Gráfi
co de OnClick Grficodelinhas1Click
Linhas

Para ajustar o nosso chart, prossiga da seguinte forma:

1 – Inclua um objeto Chart ao formulário;


2 – Altere a propriedade Align para alClient;
3 – Dê um click duplo sobre o chart, ou dê um click com o botão direito do mouse e selecione Edit Chart...
4 – Selecione a aba Chart;
5 – Na aba Chart selecione Series;
6 – Selecione ADD...
7 – Da galeria inclua uma série do tipo Bar;
8 – Altere o título da série incluída para Barras;
9 – Da galeria inclua uma série do tipo Area;
10 – Altere o título da série incluída para Areas;
11 – Da galeria inclua uma série do tipo Pie;
12 – Altere o título da série incluída para Pizza;
13 – Da galeria inclua uma série do tipo Fast Line;
14 – Altere o título da série incluída para Linhas;

Uma vez ajustadas as propriedades descreveremos os procedimentos.

Criação de função:

Para determinar qual série deverá ser ativa, criamos uma função capaz ativar e desativar uma série:

Var
Form1: TForm1;
Function ativachart(grafico:TChart;numero:integer):Boolean;
implementation

Function ativachart(grafico:TChart;numero:integer):Boolean;
var i:integer;
begin
for i:=0 to 3 do grafico.Series[i].Active:=false; // desativa todas as séries
grafico.Series[numero].Active:=true; // ativa a série indicada por número
grafico.Visible:=true; // mostra o gráfico
result:=true;
end;

Procedimentos:

procedure TForm1.Grficodebarras1Click(Sender: TObject);


var tt:TchartTitle;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 120 de 272

begin
ativachart(chart1,0); // indica que a série 0 deverá ser ativa
end;

procedure TForm1.Grficodereas1Click(Sender: TObject);


begin
ativachart(chart1,1); // indica que a série 1 deverá ser ativa
end;

procedure TForm1.Grficopizza1Click(Sender: TObject);


begin
ativachart(chart1,2); // indica que a série 2 deverá ser ativa
end;

procedure TForm1.Grficodelinhas1Click(Sender: TObject);


begin
ativachart(chart1,3); // indica que a série 3 deverá ser ativa
end;

procedure TForm1.Button2Click(Sender: TObject);


var i,t,c:integer;
begin
groupbox1.Visible:=false; // oculta o groupbox1
series1.Clear; // Limpa a série1, deletando seus valores
series2.Clear; // Limpa a série2, deletando seus valores
series3.Clear; // Limpa a série3, deletando seus valores
series4.Clear; // Limpa a série4, deletando seus valores
for t:=0 to 3 do
begin
// o laço abaixo carrega os valores do listbox1 e listbox2 nas séries1,2,3 e 4 do Chart
for i:=0 to listbox1.Count-1 do
chart1.Series[t].Add(strtoint(listbox1.Items.Strings[i]),listbox2.Items.Strings[i],clTeeColor);
end;
end;

procedure TForm1.Informarvalores1Click(Sender: TObject);


begin
listbox1.Clear; // limpa o listbox1
listbox2.Clear; // limpa o listbox2
valor.Text:=’’; // zera valor
descricao.Text:=’’; // zera descricao
GroupBox1.Visible:=true; // mostra o groupbox1
end;

procedure TForm1.animarClick(Sender: TObject);


begin
// verifica se o checkbox animar foi clicado
if animar.Checked=true then chart1.AnimatedZoom:=true;
chart1.AnimatedZoomSteps:=2;
end;

procedure TForm1.Timer1Timer(Sender: TObject);


var t:longint;
begin
// se o checkbox está ativo efetua a rotação da serie3 (pizza) a cada 10 ms
if animar.Checked=true then
begin
series3.Rotate(velocidade.Position);
end;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 121 de 272

end;

procedure TForm1.Animar1Click(Sender: TObject);


begin
Panelanimacao.Visible:=true; // mostra o panel de animação
end;

procedure TForm1.ZoommaisClick(Sender: TObject);


begin
Chart1.ZoomPercent(110); // aumenta o gráfico em 110%
end;

procedure TForm1.ZoommenosClick(Sender: TObject);


begin
chart1.ZoomPercent(80); // diminui o gráfico para 80%
end;

procedure TForm1.Zoom1Click(Sender: TObject);


begin
panelzoom.Visible:=true; // mostra o panel de zoom
end;

procedure TForm1.FechazoomClick(Sender: TObject);


begin
panelzoom.Visible:=false; // oculta o panel de zoom
end;

procedure TForm1.FechaanimacaoClick(Sender: TObject);


begin
Panelanimacao.Visible:=false; // oculta o panel de animação
end;

procedure TForm1.AnexarClick(Sender: TObject);


begin
listbox1.Items.Add(valor.Text); // adiciona valor ao listbox1
listbox2.Items.Add(descricao.Text); // adiciona descrição ao listbox2
valor.Text:=’’;
descricao.Text:=’’;
end;

procedure TForm1.FecharvaloresClick(Sender: TObject);


var i,t,c:integer;
begin
groupbox1.Visible:=false; // oculta o groupbox1
series1.Clear; // apaga os valores da serie1
series2.Clear; // apaga os valores da serie2
series3.Clear; // apaga os valores da serie3
series4.Clear; // apaga os valores da serie4
for t:=0 to 3 do
begin
// o laço abaixo adiciona valores as series
for i:=0 to listbox1.Count-1 do
Chart1.Series[t].Add(strtoint(listbox1.Items.Strings[i]),listbox2.Items.Strings[i],clTeeColor);
end;
end;

procedure TForm1.dimensaoClick(Sender: TObject);


begin
// habilita / desabilita os objetos contidos no panel3d de acordo com o valor de dimensao (CheckBox)
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 122 de 272

chart1.View3D:=dimensao.Checked;
Label3.Enabled:=dimensao.Checked;
Label4.Enabled:=dimensao.Checked;
Label5.Enabled:=dimensao.Checked;
Label6.Enabled:=dimensao.Checked;
Percentual3d.Enabled:=dimensao.Checked;
UpDPercentual.Enabled:=dimensao.Checked;
Rotacao.Enabled:=dimensao.Checked;
UpDRotacao.Enabled:=dimensao.Checked;
Perspectiva.Enabled:=dimensao.Checked;
UpDPerspectiva.Enabled:=dimensao.Checked;
Inclinacao.Enabled:=dimensao.Checked;
UpDInclinacao.Enabled:=dimensao.Checked;
end;

procedure TForm1.percentual3dChange(Sender: TObject);


begin
chart1.Chart3DPercent:=strtoint(percentual3d.Text);// ajusta o tamanho do chart
end;

procedure TForm1.RotacaoChange(Sender: TObject);


begin
// ajusta o ângulo de rotação do chart
Chart1.View3DOptions.Rotation:=strtoint(rotacao.Text);
end;

procedure TForm1.PerspectivaChange(Sender: TObject);


begin
// ajusta a perspectiva do chart
Chart1.View3DOptions.Perspective:=strtoint(perspectiva.Text);
end;

procedure TForm1.InclinacaoChange(Sender: TObject);


begin
// ajusta a inclinação do chart
Chart1.View3DOptions.Tilt:=Strtoint(inclinacao.Text);
end;

procedure TForm1.Fecha3dClick(Sender: TObject);


begin
Panel3d.Visible:=false; // oculta o panel3d
end;

procedure TForm1.N3Deposicoes1Click(Sender: TObject);


begin
Panel3d.Visible:=true; // mostra o panel3d
end;

Comentários:

Prática 37 – Criando gráficos com tabelas:

Este projeto tem como finalidade gerar um gráfico utilizando o objeto dbchart com dados obtidos
através de uma tabela ou query, portanto crie uma base de dados contendo os campos descritos a
seguir.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 123 de 272

Field Name Type Size Key


Descricao Alpha 10
Valor Short

Uma vez criada a tabela, salve na pasta C:/Delphi 2005/tabelas e carregue dados conforme tabela

abaixo:

Descricao Valor
João 16
Ana 9
Paula 6
Pedro 14
Carlos 10

O objeto dbchart possui a mesma função do chart, porém os valores utilizados nas possíveis series
serão obtidos dos registros contidos na tabela, sempre que um valor armazenado em um campo
sofrer uma alteração, esta variação será transferida para o dbchart.

Montagem do Formulário:

Propriedades:

Objeto Propriedade Valor Evento Procedimento


Caption Pratica 36 OnActivate FormActivate
Form1
OnClose FormClose
Panel1 Align alLeft
Panel2 Align alClient
CheckBox1 Caption Legenda OnClick CheckBox1Click
Checked True
CheckBox2 Caption Marcas OnClick CheckBox2Click
Checked True
GroupBox1 Align alBottom
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 124 de 272

Caption Estilo das marcas


Valor
Percentual
RadioGroup1 Items Título OnClick RadioGroup1Click
Título e Valor
Título e percentual
ItemIndex 0
Name Tgrafico
Table1 DatabaseName Dados
TableName Grafico.db
DataSource1 DataSet Tgrafico
Align alClient
DBGrid1
DataSource DataSource1
Align alClient
DBChart1 Adicione uma Pie
SeriesList
Serie

Em DBChart1, na aba Series, selecione Data Source e ajuste as opções conforme a figura abaixo:

Terminado os ajustes das propriedades devemos descrever os procedimentos necessários para


controlar o nosso projeto.

Procedimentos:

procedure TForm1.FormActivate(Sender: TObject);


begin
Tgrafico.Open; // abre a tabela sempre que o form é ativo
end;

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


begin
Tgrafico.Close; // fecha a tabela antes de fechar o formulário
end;

procedure TForm1.CheckBox1Click(Sender: TObject);


begin
// mostra ou oculta a legenda de acordo com o marco de checagem do checkbox1
series1.ShowInLegend:=checkbox1.Checked;
end;

procedure TForm1.CheckBox2Click(Sender: TObject);


begin
// mostra ou oculta as marcas de acordo com o marco de checagem do checkbox2
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 125 de 272

series1.marks.Visible:=Checkbox2.Checked;
end;

procedure TForm1.RadioGroup1Click(Sender: TObject);


begin
// Este procedimento determina o estilo das marcas a serem mostradas
case radiogroup1.ItemIndex of
0:series1.Marks.Style:=smsValue;
1:series1.Marks.Style:=smsPercent;
2:series1.Marks.Style:=smsLabel;
3:series1.Marks.Style:=smsLabelValue;
4:series1.Marks.Style:=smsLabelPercent;
end;
end;

Comentários:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 126 de 272

Capitulo XXIII – Literatura complementar

Literatura 01 – Criando o arquivo de ajuda

O Help ou arquivo de ajuda está constituído por três arquivos básicos:

• O arquivo de projeto (.HPJ);


• O arquivo de conteúdo (.CNT); e
• O arquivo de texto no formato rich-text (.RTF).
Cada um dos três arquivos contém instruções especiais que controlam a construção e o
comportamento do arquivo de ajuda gerado.
Antes de você criar o arquivo de projeto ou o arquivo de conteúdo, você precisa compor o texto de
ajuda propriamente dito. Este arquivo consiste de texto simples com a ajuda de alguns caracteres
especiais e outros atributos de formatação que definem os tópicos de ajuda e os relacionamentos
entre eles.

Você organiza o texto por tópicos, colocando cada tópico em uma página separada. Dentro de cada
tópico, você usa notas de rodapé com caracteres customizados para denotar o título de um tópico,
seu número, sua seqüência de navegação, e suas entradas no índice. Você usa atributos especiais de
texto para denotar links de um tópico para outro.

Caracteres especiais e atributos de texto usados na composição de arquivos de ajuda

Símbolo/Atributo Significado
Define o identificador do tópico que será usado para se fazer referência a este
#
tópico
$ Define o título do tópico
K Define uma entrada no índice ou um conjunto de entradas (palavras chave)
+ Define a ordem deste tópico na seqüência de navegação
Duplo sublinhado Define um salto para outro tópico
Texto escondido Identifica o tópico para onde saltar

Construindo o arquivo texto de ajuda

Utilizando o Microsoft Word criaremos quatro tópicos sendo: três tópicos simples, e um tópico de
conteúdo, e em seguida criaremos links entre eles e definiremos entradas no índice para cada um
deles.

Vamos iniciar digitando o primeiro tópico:

Tópico 1

Este é o texto de ajuda do tópico 1. Logo a seguir você verá outros tópicos.

Criando o identificador do tópico

Posicione o cursor exatamente antes da palavra Tópico e insira uma nota de rodapé com o
caractere #. Isto irá denotar o identificador do tópico ou a string de contexto. Digite Tópico1 no
texto da nota de rodapé. Os outros tópicos que estabelecerem links com este irão usar este
identificador para criar o link.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 127 de 272

Criando o título do tópico

Reposicione o cursor antes da palavra Tópico e insira uma nota de rodapé com o caractere $.
Digite Tópico 1 no texto da nota de rodapé. O Word permite pesquisar tópicos usando seus títulos,
então é uma boa idéia colocar títulos nos tópicos. O título que você especificar para um tópico é
exibido na lista de histórico do WinHelp, na caixa de diálogo Pesquisa, e no menu Bookmark.
Usualmente, o título que você especificar deverá ser o mesmo que o texto da primeira linha do
tópico.

Você pode formatar a primeira linha do tópico como qualquer título. Você pode usar um tamanho
de fonte maior e negrito para destacá-lo.

Criando as palavras chaves do tópico

Insira uma nota de rodapé com o caractere K antes da palavra Tópico e digite Tópico1;Tópico
1;Primeiro. Estas entradas irão aparecer no índice do arquivo de ajuda, e ajudarão os usuários a
encontrar mais facilmente os tópicos de interesse.

Criando os tópicos restantes

Insira uma quebra de página após o texto do tópico. Todas as definições de tópicos terminam com
uma quebra de página.

Agora que o Tópico1 está definido, você pode criar os dois tópicos restantes de acordo com o texto
abaixo:

Tópico 2

Tópico 3

Insira as notas de rodapé para o identificador, o título e palavras chaves destes dois tópicos. Use o
mesmo tipo de notas de rodapé customizadas que você usou para o Tópico 1 e não esqueça de
formatar a primeira linha de cada tópico de maneira a salientá-la e inserir uma quebra de página
entre eles. Na tabela abaixo você verá como ficam as notas de rodapé dos três tópicos:
Notas de rodapé dos tópicos de exemplo
Símbolo Tópico 1 Tópico 2 Tópico 3
# Tópico1 Tópico2 Tópico3
$ Tópico 1 Tópico 2 Tópico 3
K Tópico1; Tópico 1; Primeiro Tópico2; Tópico 2; Segundo Tópico3; Tópico
3; Terceiro;
Último

Linkando dois tópicos

Depois que os tópicos foram criados, você pode linkar o segundo com o primeiro. Posicione o
cursor logo após a palavra primeiro no segundo tópico (sem espaços). Digite Tópico1, e então
selecione a palavra Tópico1 e esconda-a com o comando Formatar/Fonte/Oculto. A seguir
selecione a palavra primeiro e formate-a com duplo sublinhado usando o comando
Formatar/Fonte/Sublinhado/Duplo. Isto irá transformar a palavra primeiro em um link para o
Tópico 1. Quando o usuário clicar nela, o Tópico 1 será exibido.

Agora crie dois links como foi feito anteriormente, porém no Tópico 3 e usando as palavras
primeiro e segundo, e use sublinhado simples ao invés de usar sublinhado duplo. O link na palavra
primeiro deverá chamar o Tópico 1 e o link na palavra segundo deverá chamar o Tópico 2. A
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 128 de 272

diferença deste tipo de link para o anterior, é que este não salta diretamente para o tópico, mas sim
exibe-o em uma janela pop-up.

Criando o tópico de conteúdo

Até agora já criamos os tópicos do arquivo de ajuda e os links entre eles, agora você precisa criar
um tópico chamado Conteúdo no seu arquivo de ajuda. Este tópico consiste em nada mais do que o
título e links para os outros tópicos.

O compilador de help assume que o tópico de conteúdo é o primeiro no arquivo contendo o texto
de ajuda, então insira uma quebra de página no começo do seu arquivo. E digite o seguinte texto:

Conteúdo do arquivo de ajuda de exemplo

Tópico 1

Tópico 2

Tópico 3

Depois disto, crie as notas de rodapé como você já fez anteriormente e nas três use apenas o texto
Conteúdo.

Depois das notas de rodapé, basta linkar cada um dos tópicos usando o sublinhado duplo.

Agora, só falta mais uma coisa a fazer antes de passarmos para os arquivos de projeto e conteúdo.
Você precisa determinar a ordem em que o usuário irá mover-se seqüencialmente através dos
tópicos no seu arquivo de ajuda. Posicione o cursor imediatamente depois da palavra exemplo no
tópico de conteúdo e insira uma nota de rodapé com o caractere + e no seu texto digite auto. Repita
este processo para os outros três tópicos. A especificação auto diz ao compilador de ajuda para
numerar os tópicos seqüencialmente conforme eles aparecem no arquivo de ajuda. Você poderia
informar um número de seqüência fixo para cada tópico, mas usar auto é mais flexível pois permite
a inserção de mais tópico sem precisar reorganizar a seqüência dos demais tópicos.

Depois que você terminar de especificar a seqüência de navegação, você terminou o arquivo com o
texto de ajuda. Salve o arquivo no formato rich-text (RTF) com o nome de teste.rtf.

Criando o arquivo de conteúdo da ajuda

Utilizaremos o aplicativo Help Workshop ou simplesmente HCW.EXE, que é o aplicativo


distribuído pela Borland para criação de arquivos de ajuda:

Help Author

A primeira coisa que você precisa fazer é habilitar a opção Help Author no menu File. Habilitar
esta opção libera vários benefícios. Primeiro, faz com que diversas informações adicionais sobre
seu sistema de ajuda seja exibida enquanto você o está construindo, como o número dos tópicos de
ajuda como se você navegasse através deles. Segundo, ele habilita que você se mova para trás e
para frente no seu arquivo de ajuda (sem considerar se você habilitou os botões de navegação)
usando Ctrl+Shift+Left e Ctrl+Shift+Right. Você pode mover-se para o começo ou o fim do seu
arquivo de ajuda usando Ctrl+Shif+Home e Ctrl+Shift+End.

A seguir, clique na opção New no menu File e selecione Help Contents. A Figura 1 lhe mostra a
tela resultante.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 129 de 272

Digite ./teste.hlp na caixa Default filename. Digite Arquivo de ajuda de exemplo na caixa Default
title. A seguir, clique o botão Add Above e digite Conteúdo do arquivo de ajuda de exemplo na
caixa Title do diálogo que irá aparecer, e Conteúdo na caixa Topic ID. Clique OK para salvar.

A seguir, clique o botão Add Below e repita o processo para os três tópicos que você criou.

O diálogo de definição de conteúdo do Help Workshop

Depois de ter adicionado o último tópico à lista, você está pronto para salvar seu arquivo de
conteúdo. Salve-o juntamente com o arquivo RTF com o nome de teste.cnt.

Criando o arquivo de projeto da ajuda

Selecione New no menu File e selecione Help Project. A primeira coisa que o Help Workshop
faz é lhe pedir o nome do arquivo do projeto. Posicione no diretório onde você colocou os outros
arquivos e digite teste para o nome do arquivo, então clique no botão Save. O Help Workshop
adicionará a extensão HPJ para este arquivo. A Figura 2 lhe mostra a tela resultante.

Adicionando seus arquivos .RTF e .CNT ao projeto

Clique o botão Options e especifique Conteúdo para Default topic e Arquivo de ajuda de exemplo
para Help title, então clique em Compression e especifique Maximum. A seguir, clique em Files
e especifique seu teste.rtf na caixa Rich Text Format files (.RTF), e seu teste.cnt na caixa
Contents file (.CNT). Depois disto, salve suas configurações clicando em OK para sair do
diálogo.

Adicionando botões de navegação ao projeto

Clique o botão Windows, e então digite main no diálogo Create a Window. Clique OK para
salvar seu novo tipo de janela. Uma vez de volta para o diálogo Window Properties, clique o
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 130 de 272

botão Buttons e marque o checkbox Browse. Isto irá habilitar os botões de navegação do
WinHelp fazendo com que você possa navegar através de sua ajuda usando a seqüência que você
definiu anteriormente. Clique OK para salvar suas alterações.

O TESTE.HPJ como ele aparece inicialmente no Help Workshop

Mapeando os identificadores de tópicos

Antes de retornar à tela principal do Help Workshop, clique o botão Map. A seguir, clique Add, e
digite Conteúdo na caixa Topic ID e 0 (zero) na caixa Mapped numeric-value. Isto permite que
os elementos da aplicação para a qual esta ajuda está sendo desenvolvida possam exibir o conteúdo
da ajuda quando o usuário solicita a ajuda sensitiva ao contexto. Clique OK para salvar seu
mapeamento.

Agora repita o procedimento para os demais tópicos, usando os seguintes valores para Tópic ID e
Mapped numeric-values respectivamente: Tópico1 e 100, Tópico2 e 200 e Tópico3 e 300. É uma
boa idéia deixar um espaço grande entre seus tópicos para que você consiga adicionar novos
tópicos entre eles sem reorganizá-los. Estes número serão usados em sua aplicação para linkar
elementos do programa com o sistema de ajuda.

Quando você terminar o mapeamento dos tópicos, você está pronto para salvar o projeto e
compilá-lo. Clique o botão Save and Compile que está na parte inferior da tela. A Figura 3 mostra
os resultados da compilação.

Testando seu arquivo de ajuda

Você pode facilmente testar seu arquivo de ajuda sem sair do Help Workshop. Selecione Run
WinHelp no menu File, e você verá o diálogo View Help File. O drop-down Mapped Topic ID
permite a você simular uma aplicação passando um identificador de ajuda de contexto para o
WinHelp.

O log do compilador mostra o resultado da compilação do projeto


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 131 de 272

Clique o botão View Help para abrir o seu arquivo de ajuda recentemente criado. Você deverá ver
o tópico Conteúdo.

Linkando o arquivo de ajuda com a sua aplicação

O passo final ao integrar ajuda Windows com a sua aplicação é linkar o arquivo de ajuda com a sua
aplicação e configurar a ajuda de contexto corretamente.

Carregue o Delphi e selecione Project/Options no menu. Depois selecione Application. Você


verá que a entrada para o arquivo de ajuda está em branco. Informe o nome do arquivo de ajuda
neste espaço e clique OK.

Agora basta colocar o número identificador do tópico na propriedade HelpContext de cada


componente que você queira e pronto.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 132 de 272

Literatura 02 – O Rave Report

Preparando a Aplicação

Tomando como base a nossa aplicação final, vamos selecionar o Data Module dados e colocar
nele 3 componentes da palheta Rave:

RvProject: Responsável pela ligação entre o projeto Delphi e o projeto de relatórios Rave.

RvDataSetConnection: Exporta um DataSet do projeto Delphi para o projeto Rave.

RvSystem:Responsável pelo envio do relatório para a impressora ou para a tela de Preview.

Configuração dos componentes Rave na aplicação Delphi

RvDataSetConnection Name: rvdsEmp


DataSet: Table1

RvSystem Name: rvsysEmp


TitlePreview: Previsão do Relatório
TitleSetup: Opções de Impressão
TitleStatus: Status de Impressão

RvProject Name: rvprjEmp


Engine: rvsysEmp

Agora execute um duplo clique sobre o componente RvProject para abrir o Rave Visual Designer.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 133 de 272

Rave Visual Designer

Configurações Gerais

File - New
File Save: Empregados.rav

Palhetas de
Barra de componentes
ferramentas

Painel da
Árvore de
objetos

Painel de
Propriedades

A Página

Na Árvore de Objetos, selecione RaveProject e, no Painel de Propriedades, altere a propriedade Units


para unMM (milímetros)
Explicação sobre a
propr. atual
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 134 de 272

Na Árvore de Objetos, selecione Report Library, e dentro dele selecione Report1. No Painel de
Propriedades, altere as propriedades:

FullName: Relatório Geral de Empregados


Name: rptEmpGeral

Ainda na Árvore de Objetos, selecione Page1 e no Painel de Propriedades, configure as seguintes


propriedades.

Acesso aos Dados


Para termos acesso aos dados que iremos imprimir, precisamos criar um Data Object. Para isso
você seleciona File - New Data Object, ou então clica no botão correspondente da barra de

ferramentas - . Aparecerá a tela:

Selecione Direct Data View. Isto nos dará acesso


aos DataSets criados dentro do nosso projeto Delphi.
Depois clique Next.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 135 de 272

Aparecerão todos os componentes


RvDataSetConnection que colocamos no
projeto Delphi, no nosso caso, apenas 1.
Selecione-o e clique Finish.

Na Árvore de Objetos, veremos todos os campos de


tbEmp. Selecione DataView1 e altere as
propriedades mostradas acima.

Desenhando o Relatório

Nas palhetas de componentes, selecione a palheta Report e traga para a Página um componente

Region . Ele determina e delimita a área de impressão da página.

Redimensione o componente Region de modo que ocupe quase toda a área da folha. Deixe uma
área livre no final da página, lá criaremos nosso rodapé de página.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 136 de 272

componente Region
redimensionado

rodapé de página

Nas palhetas de componentes, selecione a palheta Report e traga para Region1 um objeto Band -

- e um objeto DataBand - . Eles serão usados para criarmos as áreas de impressão do


relatório.

Eles aparecerão no topo de Region1.

Com o objeto Band1 selecionado, altere as seguintes propriedades:


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 137 de 272

BandStyle:

Selecione:

Body Header (Cabeçalho)

First (Primeira página)


New Page (Nova página)

ControllerBand: DataBand1
Name: PageHeader
Selecione o objeto Band2 e altere as propriedades:
DataView: dvEmp
Name: Detalhe

Os ícones à esquerda de cada banda mudarão, como mostra a figura.

Traga um componente BitMap da


palheta Standard e coloque sobre a
banda de cabeçalho.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 138 de 272

Altere a sua propriedade Image, selecionando uma figura do disco. Altere também a propriedade
MatchSide para msBoth, isto fará a figura ocupar toda a área do componente.

Para colocar os títulos no cabeçalho de página, utilize o componente Text - -da palheta
Standard. Altere as propriedades:

Text: RELATÓRIO GERAL DE FUNCIONÁRIOS


FontJustify: pjCenter
Font: Aumente o tamanho da fonte, o seu nome e estilo de acordo com a sua preferência.
Aumente a largura e a posição do componente Text para que fique centralizado horizontalmente.
Coloque um subtítulo com o nome da sua empresa.
Para exibir a data de impressão do relatório, traga para o cabeçalho um componente DataText da
palheta Report. Na sua propriedade DataField, clique nos pontinhos...
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 139 de 272

Em Report Variables, selecione DateShort


Clique no botão Insert Report Var e a variável selecionada será inserida no quadro Data Text.

Depois escreva em Data Text, um título para a variável que foi inserida.

Para colocarmos uma linha separando o cabeçalho do restante da página, selecione a palheta

Drawing e traga um componente HLine - . Utilize as propriedades LineWidth, Color etc..


para configurá-la como desejado.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 140 de 272

Agora vamos montar a banda de detalhe. Este relatório será um relatório no formato de ficha,
semelhante a um crachá. Por isso não teremos cabeçalho de colunas.

Traga para a banda de detalhe, um componente BitMap da palheta Standard. Altere seu tamanho e
posição como mostra a figura.

Altere as propriedades:
DataView: dvEmp
DataField: FOTO
Vamos agora montar os títulos dos campos que aparecerão na banda de detalhe. Para isso, traga 6
componentes Text da palheta Standard e configure-os como mostra a figura.

Com a tecla CONTROL pressionada, arraste cada campo da


Árvore de Objetos, para a posição correspondente na banda
de detalhe.

Aparecerá um componente DataText, devidamente


configurado para exibir o campo.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 141 de 272

Pressione a tecla F9 para ver como está o resultado do relatório.


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 142 de 272

Capitulo XXIV – Dicas da internet

As dicas contidas neste material foram colhidas em sites da internet, portanto, nem todas as dicas
aqui contidas foram testadas no delphi 2005

Dica Descrição Pág


1. Pintar um Bitmap diretamente no Canvas do Form 145
2. Verificar se a impressora está ligada 146
3. Obter a letra do drive onde está o Windows 146
4. Mostrar o nome do EXE no caption do form 146
5. Fazer pesquisa incremental apenas com DBGrid 147
6. Obter tipo de uma propriedade 148
7. Consulta SQL que usa a data do sistema 148
8. Abrir uma conecção Dial-Up 149
9. Pintar uma imagem JPG no form 149
10. Executar comando do MS DOS 149
11. Formatar CEP 150
12. Permitir cancelar processo demorado 150
13. Descobrir se uma data é fim do mês 151
14. Programar teclas de atalho do Windows 151
15. Obter o tipo de dado de um valor no Registro do Windows 152
16. Obter a célula de um StringGrid que está sob o cursor do mouse 153
17. Limpar todas as células de um StringGrid 154
18. Programar meu aplicativo para abrir arquivos a partir do Windows Explorer 154
19. Consultar por mês de um campo data 154
20. Criando tabelas via SQL 156
21. Obter nomes dos campos de uma tabela 157
22. Nomeando um relatório no spool de impressão do Windows 157
23. Obter tamanho de um arquivo 158
24. Ocultar aplicação da lista de tarefas CTRL+ALT+DEL 158
25. Obter path de um Alias do BDE 158
26. Ativar a proteção de tela do Windows 159
27. Desligar/Ligar monitor 159
28. Abrir e fechar o drive de CD ROM 159
29. Impedir que o form seja arrastado para fora das margens da tela 159
30. Mostrar mensagem mesmo que esteja no Prompt do DOS 160
31. Copiar todos os registros de uma tabela para o Clipboard 160
32. Copiar um registro de uma tabela para o Clipboard 161
33. Criar sub diretório no diretório do EXE 161
34. Ocultar o aplicativo do CTRL+ALT+DEL 162
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 143 de 272

35. Personalizar a caixa de mensagem de exceções (erro) do Delphi 162

36. Implementar procedure Delay do Pascal no Delphi 163


37. Enviar comandos de rolagem vertical para um TMemo 163
38. Criar uma DLL de Bitmaps e usa- la 164
39. Construir a barra de título do form com um Panel 165
40. Criar form sem título que possa ser arrastado 165
41. Obter status da memória do sistema 166
42. Definir data/hora de um arquivo 166
43. Mostrar o diálogo About (Sobre) do Windows 167
44. Ocultar/exibir o cursor do mouse 167
45. Converter de Hexadecimal para Inteiro 168
46. Mudar a cor de um DBEdit dentro de um DBCtrlGrid de acordo com uma condição 168
47. Colocar uma ProgressBar da StatusBar 168
48. Executar um programa e aguardar sua finalização antes de continuar 169
49. Simular o pressionamento de uma combinação de teclas (ex: Ctrl+F2) 170
50. Simular o pressionamento de uma tecla 170
51. Ligar/desligar a tecla Caps Lock 171
52. Verificar se uma determinada tecla está pressionada 171
53. Verificar o estado de NumLock e CapsLock 172
54. Configurar linhas de diferentes alturas em StringGrid 172
55. Adicionar o evento OnClick do DBGrid 172
56. Criar caixas de diálogo em tempo de execução 173
57. Converter a primeira letra de um Edit para maiúsculo 174
58. Verificar se uma string contém uma hora válida 175
59. Verificar se uma string contém um valor numérico válido 175
60. Mostrar uma mensagem durante um processamento 175
61. Mostrar um cursor de ampulheta durante um processamento 176
62. Ler e escrever dados binários no Registro do Windows 176
63. Mudar a resolução do vídeo via programação 178
64. Ler e escrever dados no Registro do Windows 178
65. Adicionar barra de rolagem horizontal no ListBox 179
66. Simular um CharCase no DBGrid 180
67. Verificar se uma string é uma data válida 180
68. Fazer pesquisa incremental com DBGrid e Edit 180
69. Adicionar zeros à esquerda de um número 181
70. Limpar um campo tipo data via programação 181
71. Implementar um campo auto incremental via programação 182
72. Obter o endereço IP do Dial Up 182
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 144 de 272

73. Exibir a caixa de diálogo padrão de solicitação de senha do banco de dados 183

74. Obter a versão da biblioteca ComCtl32.DLL (usada na unit ComCtrls do Delphi) 183
75. Implementar rotinas assembly em Pascal 184
76. Exibir o diálogo About do Windows 184
77. Obter a linha e coluna atual em um TMemo 185
78. Exibir um arquivo de ajuda do Windows 185
79. Obter o valor de uma variável de ambiente 185
80. Determinar se uma janela (form) está maximizada 186
81. Determinar se o cursor do mouse está em determinado controle 186
82. Determinar se o aplicativo está minimizado 187
83. Fechar um aplicativo com uma mensagem de erro fatal 187
84. Usar o evento OnGetText de um TField 187
85. Maximizar um form de forma que cubra toda a tela, inclusive a barra de tarefas 188
86. Verificar, via programação, se Local Share do BDE está TRUE 188
87. Criar um EXE que seja executado apenas através de outro EXE criado por mim 188
88. Resolver "Internal error near: IBCheck" do Interbase 5.1.1 Server no NT 189
89. Inverter os botões do mouse 189
90. Obter/definir o tempo máximo do duplo click do mouse 190
91. Obter os atributos de um arquivo/diretório 190
92. Obter o espaço total e livre de um disco 190
93. Obter o tipo de um drive (removível, fixo, CD ROM, unidade de rede, etc) 191
94. Obter informações de um volume/disco (label, serial, sistema de arquivos, etc) 192
95. Alterar o nome de volume (Label) de um disco 192
96. Saber quais as unidades de disco (drives) estão presentes 192
97. "truncar" valores reais para apenas n casas decimais 193
98. Excluir todos os registros de uma tabela (como DELETE ALL do Clipper) 193
99. Saber se o sistema está usando 4 dígitos para o ano 194
100. Imprimir caracteres acentuados diretamente para a impressora 194
101. Imprimir texto justificado com formatação na impressora Epson LX300 194
102. Formatar um disquete através de um programa Delphi 195
103. Alterar (e restaurar) o tamanho da página na impressora 196
104. Reproduzir um arquivo de som WAV sem o TMediaPlayer 197
105. Obter o nome do usuário e da empresa informado durante a instalação do Windows 197
106. Mostrar uma barra de progresso enquanto copia arquivos 197
107. Copiar arquivos usando o Shell do Windows 197
108. Descobrir o código ASCII de uma tecla 198
109. Evitar que seu programa apareça na barra de tarefas 198
110. Usar eventos de som do Windows 199
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 145 de 272

111. Mudar a coluna ativa em um DBGrid via programação 199

112. Fechar o Windows a partir do seu programa 199


113. Carregar um cursor animado (.ani) 199
114. Enviar um arquivo para a lixeira 200
115. Obter o número do registro atual 200
116. Trabalhar com Filter de forma mais prática 200
117. Reproduzir um arquivo WAV 201
118. Executar um programa DOS e fecha- lo em seguida 201
119. Fechar um programa a partir de um programa Delphi 201
120. Colocar Hint's de várias linhas 201
121. Reproduzir um vídeo AVI em um Form 202
122. Separar (filtrar) caracteres de uma string 202
123. Colocar zeros à esquerda de números 203
124. Copiar arquivos usando curingas (*.*) 203
125. Copiar arquivos 203
126. Trabalhar com cores no formato string 204
127. Verificar se determinado programa está em execução (Word, Delphi, etc) 204
128. Excluir arquivos usando curingas (*.*) 204
129. Gerar uma tabela no Word através do Delphi 205
130. Obter a quantidade de registros total e visível de uma tabela 206
131. Evitar que um programa seja executado mais de uma vez 206
132. Executar um "COMMIT" no Delphi 207
133. Posicionar Form's em relação ao Desktop do Windows 207
134. Saber a resolução de tela atual 208
135. Verificar se uma unidade de disco (disk drive) está preparada 208
136. Salvar/restaurar o tamanho e posição de Form's 209
137. Definir a quantidade de registros a ser impressa em uma página do QuickReport 210
138. Onde encontrar tutoriais sobre construção de componentes em Delphi 210
139. Para que servem OnGetEditMask, OnGetEditText e OnSetEditText do TStringGrid 210
140. Mostrar um Form de LogOn antes do Form principal 211
141. Limitar a região de movimentação do mouse 212
142. Descobrir o nome de classe de uma janela do Windows 212
143. Ocultar/exibir a barra de tarefas do Windows 213
144. Evitar a proteção de tela durante seu programa 213
145. Fazer a barra de título ficar intermitente (piscante) 213
146. Posicionar o cursor do mouse em um controle 214
147. Criar cores personalizadas (sistema RGB) 215
148. Adicionar uma nova fonte no Windows 215
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 146 de 272

149. Saber se a impressora atual possui determinada fonte 215

150. Saber se determinada Font está instalada no Windows 215


151. Acertar a data e hora do sistema através do programa 215
152. ENTER em vez de TAB no formulário, no DBGrid e no StringGrid 216
153. Simular a vírgula através do ponto do teclado numérico 216
154. Paralizar um programa durante n segundos 217
155. Criar uma tabela (DB, DBF) através do seu programa 217
156. Verificar se um diretório existe 218
157. Verificar se um arquivo existe 218
158. Criar um Alias temporário através do seu programa 218
159. Criar um Alias através do seu programa 218
160. Icone na Barra de Tarefas 220
161. Abrir arquivos com aplicativo associado 221
162. Adiciona a barra invertida a um texto selecionado 222
163. Apagar um subdiretório 222
164. Como verificar se um arquivo existe? 223
165. Compara dois arquivos textos 223
166. Copiando arquivos de diretório para diretório 224
167. Copiando Um Arquivo Com Um Gauge 224
168. Exibindo as propriedades do arquivo 226
169. Lendo e gravando arquivos de texto 227
170. Procurando um arquivo em todo o HD 228
171. Acessando o banco de dados Oracle a partir do Delphi 230
172. Alterando o NetDir via programação 233
173. Apagando todos os registros da tabela 234
174. Armazenando sons, vídeos em bancos de dados 234
175. Backup & Restauração 235
176. Como acessar pelo Delphi, tabelas no Acess 236
177. Como alterar o driver de acesso do access no bde automaticamente 236
178. Como converter DBF para Paradox e Acess para Paradox 237
179. Como importar dados de um arquivo texto para uma Tabela 237
180. Evitando o erro de Key Violation 238
181. Gravar imagem JPG em tabela Paradox 239
182. Ler imagem JPG da tabela Paradox 240
183. Listando os campos da tabela num Memo 240
184. PARADOX EM REDE 240
185. Alterando a fonte de determinado registro em um DBGrid 241
186. Alterando cor de linha de um DBGrid 241
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 147 de 272

187. DbGrid Zebrado 241


188. Procura e substituição de string num campo memo 242
189. Sql relacionada com a primeira letra 242
190. Consultar por mês de um campo data 243
191. Colocar o mes por extenso 244
192. Retornar quantidade de dias meses e anos entre duas datas 245
193. Alinhar Panel ao Centro do Formulário 245
194. Coloração Gradiente no Form 245
195. Como Criar Forms em Tempo de Execução 246
196. Como evitar efeito de maximização 246
197. Como Saber se o aplicativo já foi aberto 247
198. Criando janelas não retangulares 247
199. Form com um furo 247
200. Formulário Transparente 247
201. Texto Na Diagonal e Girando 248
202. Como Bloquear Mouse e Teclado 249
203. Detectando o Numero Serial do HD 249
204. Como desenhar um Bitmap num form 250
205. Converte um arquivo JPEG em BMP 250
206. Carregar um cursor animado (*.ani) 251
207. Como pegar a posição do mouse na tela 251
208. Como Alterar o Volume do Som do Computador Com o Delphi 251
209. Gravando Sons do Microfone Com o Delphi 252
210. Como converter decimal para romanos 252
211. Alinhar Texto do Edit À Direita 253
212. Como Limpar Todos os Edit's de um Form de uma só vez? 253
213. Baixando arquivos da internet 253
214. Chamar um e-mail pelo Delphi 254

Pintar um Bitmap diretamente no Canvas do Form

- Declare a variavel Bmp na seção private:

private
Bmp: TBitmap;

- Coloque um botão no Form e no evento OnClick digite:

Bmp:= TBitMap.Create;
try
Bmp.LoadFromFile('c:\teste\arquivo.bmp');
Canvas.Draw(0,0, Bmp);
finally
Bmp.Free;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 148 de 272

end;

Verificar se a impressora está ligada

Os possíveis parâmetros para esta função são:


1 - para LPT1
2 - para LPT2
3 - para LPT3
4 - para LPT4

function tbTestLPT(Port: byte): boolean;


var
Pto : Word;
Rdo : byte;
begin
Pto := Port -1;
asm
MOV DX,Pto
MOV AX,$0200 {AH := $02 : Leer el estado de la impresora}
INT $17
MOV Rdo,AH {Guarda el estado en AL}
end;
Result := Rdo = 144;
end;

Observações:
Provavelmente esta função não funcionará em Windows NT devido ao acesso em baixo nível.

Obter a letra do drive onde está o Windows

Inclua na seção uses: Windows

function GetWindowsDrive: Char;


var
S: string;
begin
SetLength(S, MAX_PATH);
if GetWindowsDirectory(PChar(S), MAX_PATH) > 0 then
Result := string(S)[1]
else
Result := #0;
end;

{ Exemplo de uso: }

procedure TForm1.Button1Click(Sender: TObject);


begin
Caption := GetWindowsDrive;
end;

Mostrar o nome do EXE no caption do form

{ Esta função extrai apenas o nome do arquivo passado, sem path e extensão }

function Titulo(Nome: String): String;


var
N, D: String;
begin
N := ExtractFileName(Nome); { Retira o path }
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 149 de 272

D := ChangeFileExt(N,''); { Retira a extensão }

{ Coloca a primeira letra em maiúscula e o resto em minúscula }

Titulo := UpperCase(Copy(D,1,1)) +
LowerCase(Copy(D,2,Length(D)-1));
end;

{ No OnCreate do form, coloque: }

procedure TForm1.FormCreate(Sender: TObject);


begin
Caption := Titulo(ParamStr(0));
end;

Fazer pesquisa incremental apenas com DBGrid

- Coloque no form: TTable, TDataSource, TDBGrid e TLabel.


- Ajuste as propriedades do Table1:
DatabaseName = seu alias
TableName = sua tabela
Active = true

- Ajuste as propriedades do DataSource1:


DataSet = Table1

- Ajuste as propriedades do DBGrid1:


DataSource = DataSource1
Options -> dgEditing = false
ReadOnly = true

* Pode também ajustar a propriedades Columns para escolher


as colunas que serão exibidas.

- Na seção private da unit declare:


private
FTexto: string;

- No evento OnCreate do form coloque:


FTexto := '';
Label1.Caption := '';

- No evento OnKeyPress do DBGrid1:

procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);


begin
if Key in [#8, #32..#255] then begin
if Key = #8 then { BackSpace }
FTexto := Copy(FTexto, 1, Length(FTexto)-1)
else
FTexto := FTexto + Key;

{ Posiciona na coluna Nome }


Table1.FieldByName('Nome').FocusControl;

{ Escolhe o índice e procura }


Table1.IndexFieldNames := 'Nome';
Table1.FindNearest([FTexto]);
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 150 de 272

{ Mostra o texto procurado }


Label1.Caption := FTexto;
end;
end;

Observações
No nosso exemplo estamos pesquisando através do campo "Nome". Para esta pesquisa precisamos
de um índice com este campo.

Obter tipo de uma propriedade

Inclua na seção uses: TypInfo

{ Esta função retorna uma string com o nome do tipo de dado de uma propriedade. Exemplos de
retornos:

PropType(Button1, 'Caption'); // Retorna 'TCaption'


PropType(Edit1, 'Width'); // Retorna 'Integer';
PropType(Edit1, 'Color'); // Retorna 'TColor';}

function PropType(const Obj: TObject; const PropName: string): string;


var
Info: PPropInfo;
begin
Info := GetPropInfo(Obj.ClassInfo, PropName);
if Assigned(Info) then
Result := Info^.PropType^.Name
else
Result := '';
end;

{ Exemplo de uso:
- Coloque um TButton e um TEdit;
- No OnClick do Button1 coloque o código abaixo;
- Execute, digite 'Caption' no Edit1 e clique em Button1.}

procedure TForm1.Button2Click(Sender: TObject);


begin
ShowMessage(PropType(Button1, Edit1.Text));
end;

Consulta SQL que usa a data do sistema

Query.Close;
Query.SQL.Text := 'select * from Tabela where CampoData <= :Hoje';
Query.ParamByName('Hoje').AsDate := Date;
Query.Open;
Observações:
Este exemplo foi testado com tabelas Paradox, mas deve funcionar na maioria dos bancos de dados
com pouca ou nenhuma alteração.

Abrir uma conecção Dial-Up

Inclua na seção uses: Windows

{ A função abaixo abre a caixa de diálogo de conecção com a rede Dial-Up. O parâmetro "name"
é o nome da conecção previamente configurada.}

procedure DialUpConnect(const Name: string);


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 151 de 272

begin
WinExec(PChar('rundll32.exe rnaui.dll,RnaDial ' + Name), SW_SHOW);
end;

{ Exemplo de uso: }

procedure TForm1.Button1Click(Sender: TObject);


begin
DialUpConnect('NomeDaConecção');
end;

Pintar uma imagem JPG no form

Inclua na seção uses: Graphics, JPeg

Para trabalhar com arquivos JPG você precisa usar um objeto TPicture, assim como colocar no
uses a unit JPeg. Siga os passos abaixo para pintar uma imagem JPG no form:

- No evento OnPaint do form coloque o código abaixo:

procedure TForm1.FormPaint(Sender: TObject);


var
Imagem: TPicture;
begin
Imagem := TPicture.Create;
try
Imagem.LoadFromFile('c:\teste\foto.jpg');
Canvas.StretchDraw(ClientRect, Imagem.Graphic);
finally
Imagem.Free;
end;
end;

- E no evento OnResize do form, coloque:

procedure TForm1.FormResize(Sender: TObject);


begin
Repaint;
end;
Observações
Não se esqueça de trocar o nome do arquivo JPG conforme sua necessidade. Este exemplo foi
elaborado usando Delphi4.

Executar comando do MS-DOS

Usando WinExec você pode executar qualquer comando do DOS.


Para isto chame o COMMAND.COM passando como parâmetro a linha de comando a ser
executada. O parâmetro /C é opcional e faz com que a janela do DOS seja fechada assim que o
comando terminar.

No exemplo abaixo estou executando a seguinte linha de comando: DIR C:\*.*

WinExec('COMMAND.COM /C DIR C:\*.*', SW_SHOW);


Observações
Para que a janela do DOS não seja exibida, use SW_HIDE no lugar de SW_SHOW.

Formatar CEP

{ Esta função forma CEP como: 99.999-999 }


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 152 de 272

function tbFormataCEP(const CEP: string): string;


var
I: integer;
begin
Result := '';
for I := 1 to Length(CEP) do
if CEP[I] in ['0'..'9'] then
Result := Result + CEP[I];
if Length(Result) <> 8 then
raise Exception.Create('CEP inválido.')
else
Result :=
Copy(Result, 1, 2) + '.' +
Copy(Result, 3, 3) + '-' +
Copy(Result, 6, 3);
end;

=== Para testar ===

- Coloque um Edit e um Button no form;


- No evento OnClick do Button coloque a instrução abaixo:

Edit1.Text := tbFormataCEP(Edit1.Text);

Observações
Para formatar outros códigos como CPF, CGC, etc., pode-se usar a mesma idéia.

Permitir cancelar processo demorado

Em aplicativos para Windows é comum, em processamentos demorados, o programa mostrar uma


janela de diálogo avisando que o processo pode levar um tempo extra. Nesta mesma janela
normalmente coloca-se também um botão "Cancelar" que dá ao usuário a opção aguardar ou
desistir do processo. Para fazer isto em um aplicativo Delphi, siga os passos abaixo:

- Vamos considerar em nosso exemplo que o processamento ocorre


na unit do Form1.

- Declare, na seção public do Form1, uma variável boolean.

public;
Cancelar: boolean;

- Crie um novo form (vou chamá-lo de Form2);


- Coloque um botão neste novo form. Programe o OnClick deste botão conforme abaixo:

Form1.Cancelar := true;

- Na parte onde ocorre o loop do processamento demorado coloque algo como:

try
{ Antes de começar o processamento }
Form2.Caption := 'Processamento demorado...';
Form2.Show;

{ No início do loop "Cancelar" precisa ser false }


Cancelar := false;

{ Aqui inicia o loop do processamento demorado }


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 153 de 272

while {...} do begin

{ ... Processa algo aqui... }

{ Permite que o programa processe mensagens do Windows }


Application.ProcessMessages;

{ Se a variável "Cancelar" foi alterada para true... }


if Cancelar then begin
ShowMessage('Operação cancelada pelo usuário.');
Break; { Sai do loop }
end;
end;
finally
Form2.Close;
end;
Observações
Não se esqueça de que o Form1 precisa usar Form2 e vice-versa.

Descobrir se uma data é fim do mês

Inclua na seção uses: SysUtils

{ Esta função retorna true se a data passada como parâmetro


é fim de mês. Retorna false caso contrário. }

function tbFimDoMes(const Data: TDateTime): boolean;


var
Ano, Mes, Dia: Word;
begin
DecodeDate(Data +1, Ano, Mes, Dia);
Result := Dia = 1;
end;

Programar teclas de atalho do Windows

Inclua na seção uses: Windows, Dialogs

- No evento OnCreate do form coloque o código abaixo:

procedure TForm1.FormCreate(Sender: TObject);


begin
if not RegisterHotkey(Handle, 1, MOD_CONTROL or MOD_ALT, VK_F11) then
ShowMessage('Erro ao programar Ctrl+Alt+F11');
if not RegisterHotkey(Handle, 2, MOD_CONTROL or MOD_ALT, VK_F12) then
ShowMessage('Erro ao programar Ctrl+Alt+F12');
end;

- No evento OnDestroy do form coloque o código abaixo:

procedure TForm1.FormDestroy(Sender: TObject);


begin
UnRegisterHotkey(Handle, 1);
UnRegisterHotkey(Handle, 2);
end;

- Declere a procedure abaixo na seção private:

private
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 154 de 272

procedure WMHotkey(var Msg: TWMHotkey); message WM_HOTKEY;

- Abaixo da palavra implementation escreva a procedure:

procedure TForm1.WMHotkey(var Msg: TWMHotkey);


begin
case Msg.HotKey of
1: WinExec('calc.exe', SW_SHOW);
2: ShowMessage('Ctrl+Alt+F12 foram pressionadas');
end;
end;

- Execute este programa e experimente pressionar Ctrl+Alt+F11


ou Ctrl+Alt+F12.
Observações
Se a combinação de teclas já estiver em uso (num atalho, por exemplo), não será possível usá-la
em nossa aplicação. Existem outras formas de implementar teclas de atalho em programas escritos
em Delphi, mas a forma apresentada é bastante funcional.

Obter o tipo de dado de um valor no Registro do Windows

Inclua na seção uses: Registry, Dialogs

- Coloque um botão no form;


- Altere o evento OnClick do botão conforme abaixo:

procedure TForm1.Button1Click(Sender: TObject);


const
cRegPath = 'System\CurrentControlSet\control\FileSystem';
cRegValue = 'ACDriveSpinDown';
var
Reg: TRegistry;
S: string;
begin
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.OpenKey(cRegPath, false) then begin
case Reg.GetDataType(cRegValue) of
rdUnknown: S := 'Tipo Desconhecido';
rdString: S := 'String';
rdExpandString: S := 'ExpandString';
rdInteger: S := 'Inteiro';
rdBinary: S := 'Binário';
end;
ShowMessage(S);
end else
ShowMessage('Erro ao abrir chave do Registro');
finally
Reg.Free;
end;
end;
Observações
A unit Dialogs foi acrescentada no uses somente para podermos usar a procedure ShowMessage.

Obter a célula de um StringGrid que está sob o cursor do mouse

Inclua na seção uses: Windows


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 155 de 272

Esta procedure pega a linha e coluna da célula onde estiver o mouse. Valores negativos para
Linha ou Coluna indicam que o mouse está fora da área cliente do StringGrid

procedure MouseCell(Grid: TStringGrid;


var Coluna, Linha: integer);
var
Pt: TPoint;
begin
GetCursorPos(Pt);
Pt := Grid.ScreenToClient(Pt);
if PtInRect(Grid.ClientRect, Pt) then
Grid.MouseToCell(Pt.X, Pt.Y, Coluna, Linha)
else begin
Coluna := -1;
Linha := -1;
end;
end;

Exemplo de uso:
- Coloque um botão no form;
- Altere o evento OnClick deste botão como abaixo:

procedure TForm1.Button1Click(Sender: TObject);


var
Coluna, Linha: integer;
begin
MouseCell(StringGrid1, Coluna, Linha);
if (Coluna >= 0) and (Linha >= 0) then
Caption := 'Coluna: ' + IntToStr(Coluna) + ' - ' +
'Linha: ' + IntToStr(Linha);
else
Caption := 'O mouse não está no StringGrid';
end;

Para testar:
- Execute o programa;
- Posicione o cursor do mouse sobre alguma célula do
StringGrid;
- Pressione TAB até chegar ao botão e pressione ENTER;
- O resultado será mostrado no Caption do form;

Observações
Note que a procedure MouseCell usa um valor negativo (-1) para coluna e linha se o mouse não
estiver sobre o StringGrid.

Limpar todas as células de um StringGrid

Existem três métodos que podemos aplicar para limpar um StringGrid.

{ Limpando uma célula de cada vez: }

procedure TForm1.Button1Click(Sender: TObject);


var
I, J: integer;
begin
with StringGrid1 do
for I := 0 to ColCount -1 do
for J := 0 to RowCount -1 do
Cells[I,J] := '';
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 156 de 272

end;

{ Limpando uma linha de cada vez: }

procedure TForm1.Button2Click(Sender: TObject);


var
I: integer;
begin
with StringGrid1 do
for I := 0 to RowCount -1 do
Rows[I].Clear;
end;

{ Limpando uma coluna de cada vez: }

procedure TForm1.Button3Click(Sender: TObject);


var
I: integer;
begin
with StringGrid1 do
for I := 0 to ColCount -1 do
Cols[I].Clear;
end;
Observações
Em todos os exemplos estamos limpando o StringGrid completamente, inclusive linhas e colunas
fixas. Para preservar linhas ou colunas fixas troque os valores iniciais de I ou J conforme a
necessidade.

Programar meu aplicativo para abrir arquivos a partir do Windows Explorer

Inclua na seção uses: Registry

Para fazer isto será necessária a criação de algumas chaves no Registro do Windows. O exemplo
abaixo cria todas as chaves necessárias.

- Coloque um TButton e no evento OnClick dele coloque o


código abaixo:

procedure TForm1.Button1Click(Sender: TObject);


var
Reg: TRegistry;
begin
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_CLASSES_ROOT;
Reg.LazyWrite := false;

Define o nome interno (ArquivoAluno) e uma legenda que aparecerá no Windows Explorer
(Arquivo do Aluno)
Reg.OpenKey('ArquivoAluno', true);
Reg.WriteString('', 'Arquivo do Aluno');
Reg.CloseKey;

{ Define o comando a ser executado quando abrir um arquivo pelo Windows Explorer
(NomeDoExe %1). O símbolo
%1 indica que o arquivo a ser aberto será passado como primeiro parâmetro para o aplicativo -
ParamStr(1). }
Reg.OpenKey('ArquivoAluno\shell\open\command', true);
Reg.WriteString('', ParamStr(0) + ' %1'); { NomeDoExe %1 }
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 157 de 272

Reg.CloseKey;

{ Define o ícone a ser usado no Windows Explorer:


0 - primeiro ícone do EXE
1 - segundo ícone do EXE, etc }
Reg.OpenKey('ArquivoAlunol\DefaultIcon', true);
Reg.WriteString('', ParamStr(0) + ',0'); { 0 = primeiro ícone }
Reg.CloseKey;

{ Define as extensões de arquivos que serão abertos pelo aplicativo }

{ *.dpg }
Reg.OpenKey('.dpg', true);
Reg.WriteString('', 'ArquivoAluno');
Reg.CloseKey;

{ *.alu }
Reg.OpenKey('.alu', true);
Reg.WriteString('', 'ArquivoAluno');
Reg.CloseKey;
finally
Reg.Free;
end;
end;

- Coloque um TMemo;
- No evento OnShow do Form coloque o código abaixo:

procedure TForm1.FormShow(Sender: TObject);


begin
{ Se o primeiro parâmetro for um nome de arquivo existente... }
if FileExists(ParamStr(1)) then
{ Carrega o conteúdo do arquivo no memo }
Memo1.Lines.LoadFromFile(ParamStr(1));
end;

*** Para testar ***


- Execute este programa;
- Clique no botão para criar as chaves no Registro do Windows;
- Feche o programa;
- Crie alguns arquivos com as extensões .dpg e .alu;
- Vá ao Windows Explorer e procure pelos arquivos criados;
- Experimente dar um duplo-clique sobre qualquer dos arquivos com uma das extensões acima.
Observações
Existem outros recursos que poderão ser configurados. Porém, para começar, este já é um bom
exemplo.

Consultar por mês de um campo data

Use uma Query como abaixo:


- Coloque no form os seguintes componentes:
* TQuery
* TDataSource
* TDBGrid
* TEdit
* TButton

- Altere as propriedades dos componentes como abaixo:


* Query1.DatabaseName = (alias do BDE)
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 158 de 272

* DataSource1.DataSet = Query1
* DBGrid1.DataSource = DataSource1

- Coloque o código abaixo no evento OnClick de Button1:

Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Add('select * from dCli');
Query1.SQL.Add('where extract(month from DataNasc) = :Mes');
Query1.ParamByName('Mes').AsInteger := StrToInt(Edit1.Text);
Query1.Open;

- Execute. Digite um número de 1 a 12 no Edit e clique no


botão.
Observações
Os números de 1 a 12 representam, respectivamente, os meses de Janeiro a Dezembro. Este
exemplo foi testado com Delphi4, BDE5 e tabela Paradox7.

Criando tabelas via SQL

Inclua na seção uses: dbTables

- Coloque um TButton no form;


- Escreve no OnClick do Button como abaixo:

procedure TForm1.Button1Click(Sender: TObject);


var
Q: TQuery;
begin
Q := TQuery.Create(Application);
try
Q.DatabaseName := 'SF';
with Q.SQL do begin
Add('Create Table Funcionarios');
Add('( Codigo AutoInc,');
Add(' Nome Char(30),');
Add(' Salario Money,');
Add(' Depto SmallInt,');
Add(' Primary Key (Codigo) )');
end;
Q.ExecSQL;
finally
Q.Free;
end;
end;
Observações
Este exemplo foi testado com banco de dados Paradox, porém deverá funcionar em vários outros
bancos de dados com pouca ou nenhuma alteração.

Obter nomes dos campos de uma tabela

Inclua na seção uses: dbTables, Classes, Forms

A função abaixo obtém os nomes de todos os campos de uma tabela do banco de dados.

procedure tbGetFieldNames(const DBName, TblName: string;


List: TStringList);
var
I: integer;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 159 de 272

begin
List.Clear;
with TTable.Create(Application) do
try
DatabaseName := DBName;
TableName := TblName;
with FieldDefs do begin
Update;
for I := 0 to Count -1 do
List.Add(Items[I].Name);
end;
finally
Free;
end;
end;

=== Exemplo de uso ===

- Coloque um TMemo e um TButton no Form;


- Coloque o código abaixo no evento OnClick do Button:

procedure TForm1.Button1Click(Sender: TObject);


var
List: TStringList;
begin
List := TStringList.Create;
try
tbGetFieldNames(Edit1.Text, Edit2.Text, List);
Memo1.Lines.Assign(List);
finally
List.Free;
end;
end;

Nomeando um relatório no spool de impressão do Windows

Inclua na seção uses: Printers

Antes de enviar seu relatório, faça assim:

Printer.Title := 'Nome do relatório';


Observações
Esta solução aplica-se perfeitamente aos relatórios feitos usando o objeto Printer. Nos casos de
geradores de relatórios, estes provavelmente possuem uma propriedade equivalente.

Obter tamanho de um arquivo

Inclua na seção uses: SysUtils

{ A função abaixo retorna o tamanho do arquivo, ou -1 se o arquivo não for encontrado }

function tbFileSize(const FileName: string): integer;


var
SR: TSearchRec;
I: integer;
begin
I := FindFirst(FileName, faArchive, SR);
try
if I = 0 then
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 160 de 272

Result := SR.Size
else
Result := -1;
finally
FindClose(SR);
end;
end;

Ocultar aplicação da lista de tarefas - CTRL+ALT+DEL

- Declare a função abaixo antes da palavra implementation:

function RegisterServiceProcess(dwProcessID, dwType: Integer):


Integer; stdcall; external 'KERNEL32.DLL';

- Coloque dois botões no Form;


- No evento OnClick do Button1 coloque:

RegisterServiceProcess(GetCurrentProcessID, 1);

- No evento OnClick do Button2 coloque:

RegisterServiceProcess(GetCurrentProcessID, 0);

=== Para testar ===

Clique no Button1 e pressione CTRL+ALT+DEL. O seu programa não aparecerá na lista.

Clique no Button2 e pressione CTRL+ALT+DEL. Agora seu programa aparecerá na lista.

Obter path de um Alias do BDE

Inclua na seção uses: BDE

{ A função abaixo retorna o path (caminho) de um Alias do BDE }

function GetAliasPath(AliasName: String):String;


var
dbDes: DBDesc;
begin
Result:='';
DBiInit(Nil);// invoca o BDE , se não inicializado
If DbiGetDatabaseDesc(PChar(AliasName), @dbDes)= DBIERR_NONE then
with dbDes do
Result:=StrPas(szPhyName);
DBiExit;// Libera o BDE
end;

Observações
Se a unit em que essa rotina for colocada utilizar as units DB e DBTABLES, as chamadas a
DbiInit() e DbiExit() poderão ser omitidas.

Ativar a proteção de tela do Windows

Inclua na seção uses: Windows

{ Ativa a proteção de tela do Windows, se estiver configurada. }

SendMessage(Application.Handle, WM_SYSCOMMAND, SC_SCREENSAVE, 0);


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 161 de 272

Desligar/Ligar monitor

Inclua na seção uses: Windows

No Win95 podemos desligar o monitor afim de economizar energia elétrica. Normalmente este
recurso é controlado pelo próprio Windows. Porém sua aplicação Delphi também pode fazer isto.
O exemplo abaixo desliga o monitor, aguarde 5 segundos e religa monitor.

SendMessage(Application.Handle, WM_SYSCOMMAND, SC_MONITORPOWER, 0);


Sleep(5000); { Aguarde 5 segundos }
SendMessage(Application.Handle, WM_SYSCOMMAND, SC_MONITORPOWER, -1);

Observações
Este recurso pode não funcionar dependendo da configuração do sistema.

Abrir e fechar o drive de CD-ROM

Inclua na seção uses: MMSystem

{ Para abrir }
mciSendString('Set cdaudio door open wait', nil, 0, handle);

{ Para fechar }
mciSendString('Set cdaudio door closed wait', nil, 0, handle);

Impedir que o form seja arrastado para fora das margens da tela

- Na seção Private declare a procedure abaixo:

private
procedure WMMove(var Msg: TWMMove); message WM_MOVE;

- Abaixo da palavra implementation escreva a procedure abaixo:

procedure TForm1.WMMove(var Msg: TWMMove);


begin
if Left < 0 then
Left := 0;
if Top < 0 then
Top := 0;
if Screen.Width - (Left + Width) < 0 then
Left := Screen.Width - Width;
if Screen.Height - (Top + Height) < 0 then
Top := Screen.Height - Height;
end;

Para testar:

- Execute o programa e tente arrastar o form para fora das margens da tela e veja o que acontece.

Mostrar mensagem mesmo que esteja no Prompt do DOS

Inclua na seção uses: Windows

Antes de mostrar a mensagem, coloque sua aplicação na frente das demais.

SetForegroundWindow(Application.Handle);
ShowMessage('Teste');
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 162 de 272

Copiar todos os registros de uma tabela para o Clipboard

Inclua na seção uses: Clipbrd

Siga os passos abaixo:

- Crie seu form normalmente, colocando DataSource, Table e demais componentes;


- Coloque um botão e no evento OnClick deste botão coloque o código abaixo:

procedure TForm1.Button1Click(Sender: TObject);


const
SeparadorCampoValor = ': ';
SeparadorCampo = #13#10; { Quebra de linha }
SeparadorRegistro = '===========' + #13#10;
var
S: string;
I: integer;
begin
S := '';
Table1.First;
while not Table1.EOF do begin
for I := 0 to Table1.FieldCount -1 do
S := S + Table1.Fields[I].FieldName + SeparadorCampoValor +
Table1.Fields[I].AsString + SeparadorCampo;
S := S + SeparadorRegistro;
Table1.Next;
end;
Clipboard.AsText := S;
end;

Para testar:
- Execute este aplicativo;
- Clique no botão;
- Vá em outro aplicativo (ex: MS-Word) e mande colar (Ctrl+V).
Observações
CUIDADO! Não use este recurso com tabelas grandes, pois poderá usar memória
demasiadamente. No teste que fiz, o tamanho da string S atingiu 20K e funcionou normalmente.
Mas isto pode variar de uma máquina para outra.

Copiar um registro de uma tabela para o Clipboard

Inclua na seção uses: Clipbrd

Siga os passos abaixo:

- Crie seu form normalmente, colocando DataSource, Table e demais componentes;


- Coloque um botão e no evento OnClick deste botão coloque o código abaixo:

procedure TForm1.Button1Click(Sender: TObject);


const
SeparadorCampoValor = ': ';
SeparadorCampo = #13#10; { Quebra de linha }
var
S: string;
I: integer;
begin
S := '';
for I := 0 to Table1.FieldCount -1 do
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 163 de 272

S := S + Table1.Fields[I].FieldName + SeparadorCampoValor +Table1.Fields[I].AsString +


SeparadorCampo;

Clipboard.AsText := S;
end;

Para testar:
- Execute este aplicativo;
- Clique no botão;
- Vá em outro aplicativo (ex: MS-Word) e mande colar (Ctrl+V).

Criar sub-diretório no diretório do EXE

Inclua na seção uses: FileCtrl, SysUtils

Primeiramente vamos conhecer algumas funções do Delphi que precisaremos usá-las:

ParamStr(Indice) - Retorna valores passados na linha de comando quando executamos o programa.


Se o valor de Indice for 0 (zero) será retornado o caminho+nome do EXE.

ExtractFilePath(NomeArq) - Retorna o caminho (path) do nome de arquivo informado.

Exemplo:
S := 'C:\NomeDir\Programa.exe';
ExtractFilePath(S); { retorna: 'C:\NomeDir\' }

DirectoryExists(CaminhoDir) - Retorna true se o diretório informado existe. False em caso


contrário.

CreateDir(CaminhoDir) - Tenta criar o diretório informado.


Se conseguir, retorna true. Caso contrário retorna false.

Agora que sabemos como trabalham estas funções, vamos escrever uma função que precisamos
para criar um sub-diretório conforme proposto.

function CriaSubDir(const NomeSubDir: string): boolean;


var
Caminho: string;
begin
Caminho := ExtractFilePath(ParamStr(0)) + NomeSubDir;
if DirectoryExists(Caminho) then
Result := true
else
Result := CreateDir(Caminho);
end;

Exemplo de uso:

- Chame a função no evento OnCreate do form:

procedure TForm1.FormCreate(Sender: TObject);


begin
if not CriaSubDir('MeuSubDir') then
ShowMessage('Não foi possível criar o sub-diretório MeuSubDir.');
end;

Ocultar o aplicativo do CTRL+ALT+DEL

Inclua no implementation de seu programa a seguinte linha:


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 164 de 272

function RegisterServiceProcess(dwProcessID, dwType: Integer):


Integer; stdcall; external 'KERNEL32.DLL';

e depois no OnCreate ponha a seguinte linha:

RegisterServiceProcess(GetCurrentProcessID, 1);

Isso vai fazer o programa nao aparecer no CTRL+ALT+DEL, mas seu form principal vai continuar
aparecendo. Para ocultar também o form, basta por no OnCreate antes da linha acima a seguinte
linha:

Application.ShowMainForm:=False;

Observações
Segundo o autor desta resposta, esta solução foi testada em Win95, mas também deve funcionar
em Win98. Não sabe se funciona em NT.

Personalizar a caixa de mensagem de exceções (erro) do Delphi

Siga os passos abaixo:

- Declare um método (procedure) na seção private do form principal conforme abaixo:

private
procedure ManipulaExcecoes(Sender: TObject; E: Exception);

- Vá até a seção implementation e implemente este método, conforme o exemplo:

procedure TForm1.ManipulaExcecoes(Sender: TObject; E: Exception);


begin
MessageDlg(E.Message + #13#13 +
'Suporte técnico:'#13 +
'tecnobyte@ulbrajp.com.br',
mtError, [mbOK], 0);
end;

- No evento OnCreate do Form principal escreva o código abaixo:

procedure TForm1.FormCreate(Sender: TObject);


begin
Application.OnException := ManipulaExcecoes;
end;

=== Para testar ===

- Coloque um Button no form;


- No evento OnClick deste botão coloque o código abaixo:

procedure TForm1.Button1Click(Sender: TObject);


begin
StrToInt('ABCD'); { Isto provoca uma exception }
end;
Observações
Cuidado! Não coloque código que possa gerar exceção na rotina que manipula as exceções, pois se
ocorrer uma exceção neste rotina, esta será chamada recursivamente até estourar a pilha.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 165 de 272

Implementar procedure Delay do Pascal no Delphi

Inclua na seção uses: Windows, Forms

procedure Delay(MSec: Cardinal);


var
Start: Cardinal;
begin
Start := GetTickCount;
repeat
Application.ProcessMessages;
until (GetTickCount - Start) >= MSec;
end;

=== Exemplos de uso: ===

Delay(1000); { Aguarda 1 segundo }


Delay(5000); { Aguarda 5 segundos }
Delay(60000); { Aguarda 60 segundos - 1 minuto }
Observações
Além da procedure Delay criada acima, o programador Delphi pode usar também a API do
Windows Sleep. Há porém uma diferença: Delay permite que que o programa continue a processar
as mensagens do Windows (mouse, teclado, etc).

Enviar comandos de rolagem vertical para um TMemo

Inclua na seção uses: Windows

Utilizando mensagens do Windows isto é fácil. Vejamos algums exemplos:

SendMessage(Memo1.Handle, WM_VSCROLL, SBPAGEDOWN, 0);

Onde:
Memo1.Handle = manipulador da janela do Memo1.
WM_VSCROLL = Mensagem do Windows - rolagem vertical.
SB_PAGEDOWN = Comanndo de rolagem - página para baixo.

Outros exemplos:

{ Página para cima }


SendMessage(Memo1.Handle, WM_VSCROLL, SBPAGEUP, 0);

{ Linha para baixo }


SendMessage(Memo1.Handle, WM_VSCROLL, SBLINEDOWN, 0);

{ Linha para cima }


SendMessage(Memo1.Handle, WM_VSCROLL, SBLINEUP, 0);
Observações
Além desta técnica existem API's do Windows que fazem um trabalho equivalente.

Criar uma DLL de Bitmaps e usá-la

Siga os passos abaixo para criar a DLL de bitmaps:

- Crie um arquivo de recursos (.RES) contendo os Bitmaps.


Use o Image Editor do Delphi para criar este arquivo.
Salve-o com o nome BMPS.RES na pasta onde será salvo o projeto do Delphi;
- Crie um novo projeto no Delphi;
- Remova todos os forms do projeto;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 166 de 272

- Salve este projeto com o nome DLLBmp.dpr;


- Abra o arquivo de projeto (DLLBmp.dpr) e altere para ficar somente com as linhas abaixo:

{$R BMPS.RES}
library DLLBmp;
end.

- Compile o projeto (Ctrl+F9). Será criado o arquivo DLLBmp.DLL.


- Feche o projeto atual e crie um novo projeto;
- Salve-o na mesma pasta que salvou o anterior, mas com outro nome qualquer;
- Coloque no form um Edit e um Button;
- No evento OnClick do Button coloque o código abaixo:

procedure TForm1.Button1Click(Sender: TObject);


var
Bmp: TBitmap;
HandleDLL: THandle;
begin
{ Carrega a DLL }
HandleDLL := LoadLibrary('DLLBmp.DLL');
if HandleDLL = 0 then
ShowMessage('Não foi possível carregar DLLBmp.DLL')
else
try
Bmp := TBitmap.Create;
try
Bmp.Handle := LoadBitmap(HandleDLL, PChar(Edit1.Text));
if Bmp.Handle = 0 then
ShowMessage('Não foi possível carregar o Bitmap.')
else
{ Pinta o Bitmap no form }
Canvas.Draw(0, 0, Bmp);
finally
Bmp.Free;
end;
finally
{ Libera a DLL }
FreeLibrary(HandleDLL);
end;
end;

=== Para testar ===

- Execute este projeto;


- Digite no Edit1 o nome que foi dado ao Bitmap no arquivo
de recursos (.RES);
- Clique no botão. O bitmap deverá ser pintado no form.
Observações
O arquivo DLL poderá ser colocado na pasta onde estiver o EXE, no diretório do Windows ou
ainda no sub-diretório System do Windows. Além de bitmaps podemos colocar qualquer outro tipo
de recurso em DLL's.

Construir a barra de título do form com um Panel

Pegue o arquivo tbtitle.zip na seção Download do IntereSite: www.ulbrajp.com.br/~tecnobyte

Criar form sem título que possa ser arrastado

Siga os passos abaixo:


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 167 de 272

- Crie um novo projeto;


- Mude as seguintes propriedades do Form1:
BorderStyle = bsNone, FormStyle = fsStayOnTop,
- Coloque um Label;
- Coloque um Timer;
- Altere o evento OnTimer do Timer1 conforme abaixo:

procedure TForm1.Timer1Timer(Sender: TObject);


begin
Label1.Caption := TimeToStr(Time);
end;

- Altere o evento OnCreate do Form1 conforme abaixo:

procedure TForm1.FormCreate(Sender: TObject);


begin
Width := 80;
Height := 40;
Label1.Left := 10;
Label1.Top := 10;
end;

- Vá na seção private do Form1 e declare a procedure abaixo:

private
procedure WMNCHitTest(var Msg: TMessage);
message WM_NCHitTest;
public
{ Public declarations }
end;

- Vá na seção implementation e escreva a procedure abaixo:

implementation

{$R *.DFM}

procedure TForm1.WMNCHitTest(var Msg: TMessage);


begin
if GetAsyncKeyState(VK_LBUTTON) < 0 then
Msg.Result := HTCAPTION
else
Msg.Result := HTCLIENT;
end;

- Execute e experimente arrastar form com o mouse.


Observações
Para fechar este aplicativo pressione Alt+F4. Uma alternativa mais elegante é colocar um menu
local (PopupMenu) com um comando para fechar.

Obter status da memória do sistema

Inclua na seção uses: Windows, SysUtils

- Coloque um TMemo no form


- Coloque um TButton no form e altere seu OnClick conforme abaixo:

procedure TForm1.Button1Click(Sender: TObject);


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 168 de 272

const
cBytesPorMb = 1024 * 1024;
var
M: TMemoryStatus;
begin
M.dwLength := SizeOf(M);
GlobalMemoryStatus(M);
Memo1.Clear;
with Memo1.Lines do begin
Add(Format('Memória em uso: %d%%',
[M.dwMemoryLoad]));
Add(Format('Total de memória física: %f MB',
[M.dwTotalPhys / cBytesPorMb]));
Add(Format('Memória física disponível: %f MB',
[M.dwAvailPhys / cBytesPorMb]));
Add(Format('Tamanho máximo do arquivo de paginação: %f MB',
[M.dwTotalPageFile / cBytesPorMb]));
Add(Format('Disponível no arquivo de paginação: %f MB',
[M.dwAvailPageFile / cBytesPorMb]));
Add(Format('Total de memória virtual: %f MB',
[M.dwTotalVirtual / cBytesPorMb]));
Add(Format('Memória virtual disponível: %f MB',
[M.dwAvailVirtual / cBytesPorMb]));
end;
end;

Definir data/hora de um arquivo

Inclua na seção uses: SysUtils

Esta função altera a data e hora de um arquivo. Se obter sucesso retorna true, caso contrário
retorna false.

function DefineDataHoraArq(NomeArq: string; DataHora: TDateTime): boolean;


var
F: integer;
begin
Result := false;
F := FileOpen(NomeArq, fmOpenWrite or fmShareDenyNone);
try
if F > 0 then
Result := FileSetDate(F, DateTimeToFileDate(DataHora)) = 0;
finally
FileClose(F);
end;
end;

{ Exemplo de uso 1: Usa a data atual do sistema (Now) }

if DefineDataHoraArq('c:\teste\logo.bmp', Now) then


ShowMessage('Data/Hora do arquivo definida com sucesso.')
else
ShowMessage('Não foi possível definir data/hora do arquivo.');

{ Exemplo de uso 2: Usa uma data fixa }


var
DataHora: TDateTime;
begin
{ Define a data para 5-Fev-1999 e a hora para 10:30 }
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 169 de 272

DataHora := EncodeDate(1999, 2, 5) + EncodeTime(10, 30, 0, 0);

if DefineDataHoraArq('c:\teste\logo.bmp', DataHora) then


ShowMessage('Data/Hora do arquivo definida com sucesso.')
else
ShowMessage('Não foi possível definir data/hora do arquivo.');
end;

Mostrar o diálogo About (Sobre) do Windows

Inclua na seção uses: ShellApi

procedure TForm1.Button1Click(Sender: TObject);


begin
ShellAbout(Handle, 'Sistema Financeiro', 'Marcelo Senger',
Application.Icon.Handle);
end;
Observações
Dica enviada por: Marcelo Senger

Ocultar/exibir o cursor do mouse

Inclua na seção uses: Windows

- Escreva a função abaixo:

function MouseShowCursor(const Show: boolean): boolean;


var
I: integer;
begin
I := ShowCursor(LongBool(true));
if Show then begin
Result := I >= 0;
while I < 0 do begin
Result := ShowCursor(LongBool(true)) >= 0;
Inc(I);
end;
end else begin
Result := I < 0;
while I >= 0 do begin
Result := ShowCursor(LongBool(false)) < 0;
Dec(I);
end;
end;
end;

- Exemplos de uso:

MouseShowCursor(false); { Oculta o cursor }

MouseShowCursor(true); { Exibe o cursor }

Converter de Hexadecimal para Inteiro

Inclua na seção uses: SysUtils

var
I: integer;
begin
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 170 de 272

I := StrToInt('$' + Edit1.Text);
{...}
end;
Observações
No Delphi, um número na notação decimal deve iniciar com o símbolo $.

Mudar a cor de um DBEdit dentro de um DBCtrlGrid de acordo com uma condição

- Monte o form normalmente colocando DataSource, Table, DBCtrlGrid e os DBEdit's, DBText's,


etc.
- Escreva no manipulador do evento OnPaintPanel do DBCtrlGrid conforme abaixo:

procedure TForm1.DBCtrlGrid1PaintPanel(DBCtrlGrid: TDBCtrlGrid;


Index: Integer);
begin
if Table.FieldByName('NomeDoCampo').AsFloat < 0 then
DBEdit1.Font.Color := clRed
else
DBEdit1.Font.Color := clBlue;
end;
Observações
Neste exemplo mudamos a cor da fonte do componente DBEdit, Porém, pode-se também mudar a
cor do próprio componente (DBEdit1.Color).

Colocar uma ProgressBar da StatusBar

- Coloque uma StatusBar no form.


- Adicione dois paineis na StatusBar (propriedade Panels).
- Ajuste as propriedades do primeiro painel conforme abaixo:
Style = psOwnerDraw
Width = 150

- Coloque uma ProgressBar no form e mude sua propriedade Visible para false.

- No evento OnDrawPanel da StatusBar digite o código abaixo:

procedure TForm1.StatusBar1DrawPanel(StatusBar: TStatusBar;


Panel: TStatusPanel; const Rect: TRect);
begin
{ Se for o primeiro painel... }
if Panel.Index = 0 then begin
{ Ajusta a tamanho da ProgressBar de acordo com
o tamanho do painel }
ProgressBar1.Width := Rect.Right - Rect.Left +1;
ProgressBar1.Height := Rect.Bottom - Rect.Top +1;
{ Pinta a ProgressBar no DC (device-context) da StatusBar }
ProgressBar1.PaintTo(StatusBar.Canvas.Handle, Rect.Left, Rect.Top);
end;
end;

- Coloque um Button no form


- Digite no evento OnClick do Button o código abaixo:

procedure TForm1.Button1Click(Sender: TObject);


var
I: integer;
begin
for I := ProgressBar1.Min to ProgressBar1.Max do begin
{ Atualiza a posição da ProgressBar }
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 171 de 272

ProgressBar1.Position := I;
{ Repinta a StatusBar para forçar a atualização visual }
StatusBar1.Repaint;
{ Aguarda 50 milisegundos }
Sleep(50);
end;

{ Aguarde 500 milisegundos }


Sleep(500);

{ Reseta (zera) a ProgressBar }


ProgressBar1.Position := ProgressBar1.Min;
{ Repinta a StatusBar para forçar a atualização visual }
StatusBar1.Repaint;
end;

- Execute e clique no botão para ver o resultado.


Observações
Com um pouco de criatividade podemos fazer outras coisas interessantes usando o evento
OnDrawPanel da StatusBar.

Executar um programa e aguardar sua finalização antes de continuar

Inclua na seção uses: Windows

function ExecAndWait(const FileName, Params: string; const WindowState: Word): boolean;


var
SUInfo: TStartupInfo;
ProcInfo: TProcessInformation;
CmdLine: string;
begin
{ Coloca o nome do arquivo entre aspas. Isto é necessário devido aos espaços contidos em nomes
longos }
CmdLine := '"' + Filename + '"' + Params;
FillChar(SUInfo, SizeOf(SUInfo), #0);
with SUInfo do begin
cb := SizeOf(SUInfo);
dwFlags := STARTF_USESHOWWINDOW;
wShowWindow := WindowState;
end;
Result := CreateProcess(nil, PChar(CmdLine), nil, nil, false,
CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil,
PChar(ExtractFilePath(Filename)), SUInfo, ProcInfo);

{ Aguarda até ser finalizado }


if Result then begin
WaitForSingleObject(ProcInfo.hProcess, INFINITE);
{ Libera os Handles }
CloseHandle(ProcInfo.hProcess);
CloseHandle(ProcInfo.hThread);
end;
end;

- Exemplo de uso:

ExecAndWait('c:\windows\notepad.exe', '', SW_SHOW);


Observações
Não se esqueça de informar o caminho (path) do arquivo completo. Esta função foi desenvolvida
para Delphi 32 bits (2, 3, 4,...).
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 172 de 272

Simular o pressionamento de uma combinação de teclas (ex: Ctrl+F2)

Inclua na seção uses: Windows

{ Mantém pressionada CTRL }


keybd_event(VK_CONTROL, 0, KEYEVENTF_EXTENDEDKEY or 0, 0);

{ Pressiona F2 }
keybd_event(VK_F2, 0, 0, 0);

{ Libera (solta) CTRL }


keybd_event(VK_CONTROL, $45, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP,
0);
Observações
Neste exemplo pressionamos Ctrl+F2. Não se esqueça das teclas que precisam manter
pressionadas: Ctrl, Alt, Shift.

Simular o pressionamento de uma tecla

Inclua na seção uses: Windows

A API keybd_event do Windows serve para fazer isto. No exemplo abaixo estamos simulando o
pressionamento da tecla F2:

keybd_event(VK_F2, 0, 0, 0);

Para testar faça o exemplo a seguir:

- Mude a propriedade KeyPreview do form para true.


- Escreva no evento OnKeyDown do form como abaixo:

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;


Shift: TShiftState);
begin
if Key = VK_F2 then
ShowMessage('F2 pressionada');
end;

- Coloque um botão e escreva no OnClick (do botão) como abaixo:

procedure TForm1.Button1Click(Sender: TObject);


begin
keybd_event(VK_F2, 0, 0, 0);
end;
Observações
Consulte as constantes para os códigos das teclas (ex: VK_RETURN, VK_DOWN, etc).

Ligar/desligar a tecla Caps Lock

Inclua na seção uses: Windows

{ Esta função liga/desliga Caps Lock, conforme o parãmetro State }

procedure tbSetCapsLock(State: boolean);


begin
if (State and ((GetKeyState(VK_CAPITAL) and 1) = 0)) or ((not State) and
((GetKeyState(VK_CAPITAL) and 1) = 1)) then
begin
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 173 de 272

keybd_event(VK_CAPITAL, $45, KEYEVENTF_EXTENDEDKEY or 0, 0);


keybd_event(VK_CAPITAL,$45, KEYEVENTF_EXTENDEDKEY or
KEYEVENTF_KEYUP, 0);
end;
end;

{ Exemplos de uso: }

tbSetCapsLock(true); { Liga Caps Lock }

tbSetCapsLock(false); { Desliga Caps Lock }


Observações
Aparentemente, podemos usar esta mesma técnica para ligar/desligar Num Lock. Neste caso
trocaríamos VK_CAPITAL por VK_NUMLOCK. Por incrível que pareça não funcionou (pelo
menos no teste que fiz). E tem mais: isto está na documentação do (R)Windows.

Verificar se uma determinada tecla está pressionada

Inclua na seção uses: Windows

{ Esta função retorna true se a tecla informada estiver pressionada. False em caso contrário. }

function tbKeyIsDown(const Key: integer): boolean;


begin
Result := GetKeyState(Key) and 128 > 0;
end;

{ Exemplos de uso: }

if tbKeyIsDown(VK_CONTROL) then
{ Tecla Ctrl pressionada }

if tbKeyIsDown(VK_MENU) then
{ Tecla Alt pressionada }

if tbKeyIsDown(VK_SHIFT) then
{ Tecla Shift pressionada }

if tbKeyIsDown(VK_F2) then
{ Tecla F2 pressionada }
Observações
Qualquer tecla pode ser verificada. Para isto basta saber o código virtual (Virtual Key Code) da
tecla.

Verificar o estado de NumLock e CapsLock

Inclua na seção uses: Windows

{ Esta função retorna true se a tecla informada estiver ligada. False em caso contrário }

function tbKeyIsOn(const Key: integer): boolean;


begin
Result := GetKeyState(Key) and 1 > 0;
end;

{ Exemplo de uso: }

if tbKeyIsOn(VK_NUMLOCK) then
{ ... NumLock está ligada }
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 174 de 272

else
{ ... NumLock está desligada }
Observações
Qualquer tecla que possua os estados On/Off pode ser verificada. Basta, para isto, saber seu
código. O código de CapsLock é VK_CAPITAL.

Configurar linhas de diferentes alturas em StringGrid

- Coloque o StringGrid no form.


- No evento OnCreate do form coloque o código abaixo:

procedure TForm1.FormCreate(Sender: TObject);


begin
StringGrid1.RowHeights[0] := 15;
StringGrid1.RowHeights[1] := 20;
StringGrid1.RowHeights[2] := 50;
StringGrid1.RowHeights[3] := 35;
end;
Observações
Cuidado para não especificar uma linha inexistente.

Adicionar o evento OnClick do DBGrid

- Monte seu form normalmente, colocando o DBGrid e demais componentes;


- Vá na seção "private" da unit e declare a procedure abaixo:

private
procedure DBGridClick(Sender: TObject);

- Logo após a palavra "implementation", escreva a procedure:

implementation

{$R *.DFM}

procedure TForm1.DBGridClick(Sender: TObject);


begin
ShowMessage('Clicou no DBGrid.');
end;

- Coloque as instruções abaixo no evento OnCreate do Form:

procedure TForm1.FormCreate(Sender: TObject);


begin
DBGrid1.ControlStyle :=
DBGrid1.ControlStyle + [csClickEvents];
TForm(DBGrid1).OnClick := DBGridClick;
end;

Observações
O segredo principal desta dica está OnCreate do Form. A primeira instrução ativa o evento
OnClick. A segunda instrução acessa o manipulador do evento OnClick. Para isto precisamos tratar
o DBGrid como se fosse Form, pois o evento OnClick está declarado como protegido (protected)
na classe TDBGrid.

Criar caixas de diálogo em tempo de execução

Inclua na seção uses: Forms, StdCtrls, Buttons


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 175 de 272

A função abaixo demonstra a criação de uma caixa de diálogo que pode ser usada para permitir ao
usuário digitar o seu nome:

{ Esta função retorna true se for pressionado OK e false em caso contrário. Se for OK, o texto
digitado pelo usuário será copiado para a variável Nome }

function ObterNome(var Nome: string): boolean;


var
Form: TForm; { Variável para o Form }
Edt: TEdit; { Variável para o Edit }
begin
Result := false; { Por padrão retorna false }
{ Cria o form }
Form := TForm.Create(Application);
try
{ Altera algumas propriedades do Form }
Form.BorderStyle := bsDialog;
Form.Caption := 'Atenção';
Form.Position := poScreenCenter;
Form.Width := 200;
Form.Height := 150;
{ Coloca um Label }
with TLabel.Create(Form) do begin
Parent := Form;
Caption := 'Digite seu nome:';
Left := 10;
Top := 10;
end;
{ Coloca o Edit }
Edt := TEdit.Create(Form);
with Edt do begin
Parent := Form;
Left := 10;
Top := 25;
{ Ajusta o comprimento do Edit de acordo com a largura do form }
Width := Form.ClientWidth - 20;
end;
{ Coloca o botão OK }
with TBitBtn.Create(Form) do begin
Parent := Form;
{ Posiciona de acordo com a largura do form }
Left := Form.ClientWidth - (Width * 2) - 20;
Top := 80;
Kind := bkOK; { Botão Ok }
end;
{ Coloca o botão Cancel }
with TBitBtn.Create(Form) do begin
Parent := Form;
Left := Form.ClientWidth - Width - 10;
Top := 80;
Kind := bkCancel; { Botão Cancel }
end;
{ Exibe o form e aguarda a ação do usuário. Se for OK... }
if Form.ShowModal = mrOK then begin
Nome := Edt.Text;
Result := true;
end;
finally
Form.Free;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 176 de 272

end;
end;

Para chamar esta função siga o exemplo abaixo:

procedure TForm1.Button1Click(Sender: TObject);


var
S: string;
begin
if ObterNome(S) then
Edit1.Text := S;
end;
Observações
Os componentes Label, Edit (var Edt) e BitBtn's (botões) não são destruídos explicitamente
(Componente.Free). Isto não é necessário, pois ao criá-los informei como proprietário o Form (ex:
TLabel.Create(Form)). Neste caso, estes componentes são destruídos automaticamente ao destruir
o Form (Form.Free).

Converter a primeira letra de um Edit para maiúsculo

with Edit2 do
if Text <> '' then
Text := AnsiUpperCase(Text[1]) + Copy(Text, 2, Length(Text));

Isto pode ser colocado, por exemplo, no OnExit do Edit.

Você pode também converter durante a digitação. Para isto


coloque o código abaixo no evento OnKeyPress do Edit:

if Edit1.SelStart = 0 then
Key := AnsiUpperCase(Key)[1]
else
Key := AnsiLowerCase(Key)[1];

Verificar se uma string contém uma hora válida

- Use a função abaixo:

function StrIsTime(const S: string): boolean;


begin
try
StrToTime(S);
Result := true;
except
Result := false;
end;
end;

Verificar se uma string contém um valor numérico válido

- Use uma das funções abaixo, conforme o tipo de dado que se quer testar:

function StrIsInteger(const S: string): boolean;


begin
try
StrToInt(S);
Result := true;
except
Result := false;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 177 de 272

end;
end;

function StrIsFloat(const S: string): boolean;


begin
try
StrToFloat(S);
Result := true;
except
Result := false;
end;
end;

Mostrar uma mensagem durante um processamento

- Crie um form com a mensagem. Um pequeno form com um Label já é suficiente. Aqui vou
chamá-lo de FormMsg.
- Vá em Project|Options e passe o FormMsg de "Auto-create forms" para "Available forms".
- Abaixo vou simular um processamento demorado, usando a API Sleep:

procedure TForm1.Button1Click(Sender: TObject);


var
Form: TFormMsg;
I: integer;
begin
Form := TFormMsg.Create(Self);
try
Form.Label1.Caption := 'Processamento demorado...';
Form.Show;
for I := 1 to 5 do begin
Form.UpDate;
Sleep(1000); { Aguarda um segundo }
end;
finally
Form.Free;
end;
end;
Observações
A função Sleep é uma API do Windows e serve para paralisar a aplicação por um determinado
dempo. Este tempo é em milisegundos.

Mostrar um cursor de ampulheta durante um processamento

- Salve o cursor atual


- Defina o novo cursor (crHourGlass é ampulheta)
- Faça o processamento
- Restaure o cursor.

var
PrevCur: TCursor;
begin
PrevCur := Screen.Cursor;
try
Screen.Cursor := crHourGlass;
{ Coloque aqui as instruções do processamento }
finally
Screen.Cursor := PrevCur;
end;
end;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 178 de 272

Observações
Existem diversos outros cursores pré-definidos no Delphi. Dê uma olhada na propriedade Cursor
de um componente visual para ver uma lista de todos eles. Você poderá também criar o seu próprio
cursor.

Ler e escrever dados binários no Registro do Windows

Inclua na seção uses: Registry

Coloque no Form:
- três edits;
- dois botões.

Logo abaixo da palavra implementation declare:

type

{ Declara um tipo registro }


TFicha = record
Codigo: integer;
Nome: string[40];
DataCadastro: TDateTime;
end;

- Escreva o evento OnClick do Button1 conforme abaixo:

procedure TForm1.Button1Click(Sender: TObject);


var
Reg: TRegistry;
Ficha: TFicha;
begin
{ Coloca alguns dados na variável Ficha }
Ficha.Codigo := StrToInt(Edit1.Text);
Ficha.Nome := Edit2.Text;
Ficha.DataCadastro := StrToDate(Edit3.Text);

Reg := TRegistry.Create;
try
{ Define a chave-raiz do registro }
Reg.RootKey := HKEY_CURRENT_USER;

{ Abre uma chave (path). Se não existir cria e abre. }


Reg.OpenKey('Cadastro\Pessoas\', true);

{ Grava os dados (o registro) }


Reg.WriteBinaryData('Dados', Ficha, SizeOf(Ficha));
finally
Reg.Free;
end;
end;

- Escreva o evento OnClick do Button2 conforme abaixo:

procedure TForm1.Button2Click(Sender: TObject);


var
Reg: TRegistry;
Ficha: TFicha;
begin
Reg := TRegistry.Create;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 179 de 272

try
{ Define a chave-raiz do registro }
Reg.RootKey := HKEY_CURRENT_USER;

{ Se existir a chave (path)... }


if Reg.KeyExists('Cadastro\Pessoas') then
begin
{ Abre a chave (path) }
Reg.OpenKey('Cadastro\Pessoas', false);

{ Se existir o valor... }
if Reg.ValueExists('Dados') then
begin
{ Lê os dados }
Reg.ReadBinaryData('Dados', Ficha, SizeOf(Ficha));
Edit1.Text := IntToStr(Ficha.Codigo);
Edit2.Text := Ficha.Nome;
Edit3.Text := DateToStr(Ficha.DataCadastro);
end else
ShowMessage('Valor não existe no registro.')
end else
ShowMessage('Chave (path) não existe no registro.');
finally
Reg.Free;
end;
end;
Observações
Qualquer tipo de dado pode ser gravado e lido de forma binária no registro do Windows. Para isto
você precisa saber o tamanho do dado. Para dados de tamanho fixo, use SizeOf(). Lembrete: não
grave dados muito extensos no Registro do Windows (ex: imagens), pois isto prejudicará o
desempenho do sistema.

Mudar a resolução do vídeo via programação

- Coloque um ListBox no form


- Modifique o OnCreate do form assim:

procedure TForm1.FormCreate(Sender: TObject);


var
i : Integer;
DevMode : TDevMode;
begin
i := 0;
while EnumDisplaySettings(nil,i,Devmode) do begin
with Devmode do
ListBox1.Items.Add(Format('%dx%d %d Colors',
[dmPelsWidth,dmPelsHeight, 1 shl dmBitsperPel]));
Inc(i);
end;
end;

- Coloque um botão no form


- Altere o evento OnClick do botão conforme abaixo:

procedure TForm1.Button1Click(Sender: TObject);


var
DevMode : TDevMode;
begin
EnumDisplaySettings(nil,Listbox1.ItemIndex,Devmode);
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 180 de 272

ChangeDisplaySettings(DevMode,0);
end;

Ler e escrever dados no Registro do Windows

Inclua na seção uses: Registry

- Coloque no form dois edits e dois botões.


- No evento OnClick do Button1 escreva o código abaixo:

procedure TForm1.Button1Click(Sender: TObject);


var
Reg: TRegistry;
begin
Reg := TRegistry.Create;
try
{ Define a chave-raiz do registro }
Reg.RootKey := HKEY_CURRENT_USER;
{ Abre a chave (path). Se não existir, cria e abre. }
Reg.OpenKey('MeuPrograma\Configuração', true);
{ Escreve um inteiro }
Reg.WriteInteger('Numero', StrToInt(Edit1.Text));
{ Escreve uma string }
Reg.WriteString('Nome', Edit2.Text);
finally
Reg.Free;
end;
end;

- No evento OnClick do Button2, escreva:

procedure TForm1.Button2Click(Sender: TObject);


var
Reg: TRegistry;
begin
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_CURRENT_USER;
if Reg.KeyExists('MeuPrograma\Configuração') then
begin
Reg.OpenKey('MeuPrograma\Configuração', false);

if Reg.ValueExists('Numero') then
Edit1.Text := IntToStr(Reg.ReadInteger('Numero'))
else
ShowMessage('Não existe valor com o nome "Numero"');

if Reg.ValueExists('Nome') then
Edit2.Text := Reg.ReadString('Nome')
else
ShowMessage('Não existe valor com o nome "Nome"');

end else
ShowMessage('Não existe a chave no registro');
finally
Reg.Free;
end;
end;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 181 de 272

Observações
Use o aplicativo RegEdit.exe do windows para ver o registro. Cuidado para não alterar as
configurações do Windows!

Adicionar barra de rolagem horizontal no ListBox

{ - Coloque um ListBox no form;


- Altere o OnCreate do Form conforme abaixo:}

procedure TForm1.FormCreate(Sender: TObject);


var
I, Temp, MaxTextWidth: integer;
begin
{ Adiciona algumas linhas no ListBox }
Listbox1.Items.Add('Linha 1');
Listbox1.Items.Add('Linha 2, longa para que seja necessária a barra de rolagem horizontal');
Listbox1.Items.Add('Linha 3');

if Listbox1.Items.Count > 1 then begin

{ Obtém o comprimento, em pixels, da linha mais longa }


MaxTextWidth := 0;
for I := 0 to Listbox1.Items.Count - 1 do begin
Temp := ListBox1.Canvas.TextWidth(ListBox1.Items[I]);
if Temp > MaxTextWidth then
MaxTextWidth := Temp;
end;

{ Acrescenta a largura de um "W" }


MaxTextWidth := MaxTextWidth + Listbox1.Canvas.TextWidth('W');

{ Envia uma mensagem ao ListBox }


SendMessage(ListBox1.Handle, LB_SETHORIZONTALEXTENT, MaxTextWidth, 0);
end;
end;

{ Para ocultar use a instrução abaixo: }

SendMessage(ListBox1.Handle, LB_SETHORIZONTALEXTENT, 0, 0);

Simular um CharCase no DBGrid

Para converter a digitação para maiúsculo, coloque isto no evento OnKeyPress do DBGrid:

Key := AnsiUpperCase(Key)[1];

Para converter para minúsculo, troque por:

Key := AnsiLowerCase(Key)[1];

Verificar se uma string é uma data válida

Escreva a função abaixo:

function tbStrIsDate(const S: string): boolean;


begin
try
StrToDate(S);
Result := true;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 182 de 272

except
Result := false;
end;
end;

Para testar:
- Coloque um Edit no form;
- Coloque um Button;
- No evento OnClick do botão coloque o código abaixo:

if tbStrIsDate(Edit1.Text) then
ShowMessage(Edit1.Text + ' é data válida.')
else
ShowMessage(Edit1.Text + ' NÃO é data válida.');

Fazer pesquisa incremental com DBGrid e Edit

- Crie um índice na tabela com campo a ser usado na pesquisa.

Coloque no Form:

- Um DataSource
- Um Table
- Um DBGrid
- Um Edit

Altere as seguintes propriedades:

- DataSource1.DataSet = Table1
- Table1.DatabaseName = 'NomeDoAlias'
- Table1.TableName = 'NomeDaTabela'
- Table1.IndexFieldNames = 'NomeDoCampo'
- Table1.Active = true
- DBGrid1.DataSource = DataSource1

Escreva a instrução abaixo no evento OnChange do Edit:

Table1.FindNearest([Edit1.Text]);
Observações
Este exemplo considera que o campo seja tipo string. Para outros tipos de campos pode ocorrer
erro dependendo dos valores digitados no Edit1.

Adicionar zeros à esquerda de um número

Existem várias formas. Vejamos uma:

function tbStrZero(const I: integer; const Casas: byte): string;


var
Ch: Char;
begin
Result := IntToStr(I);
if Length(Result) > Casas then begin
Ch := '*';
Result := '';
end else
Ch := '0';
while Length(Result) < Casas do
Result := Ch + Result;
end;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 183 de 272

{ Exemplo de como usá-la: }

var
S: string;
Numero: integer;
{...}
begin
{...}
S := tbStrZero(Numero, 6);
{...}
end;
Observações
Se o comprimento desejado (Casas) não for suficiente para conter o número, serão colocados
asteriscos.

Limpar um campo tipo data via programação

Table1.FieldByName('Data').Clear;

{ ou }

Table1.FieldByName('Data').AsString := '';
Observações
Podemos usar este recurso para limpar também campos numéricos, string, etc.

Implementar um campo auto-incremental via programação

Inclua na seção uses: dbTables

procedure tbAutoInc(Table: TTable; const FieldName: string);


var
Q: TQuery;
begin
if not Table.FieldByName(FieldName).IsNull then
Exit;
Q := TQuery.Create(nil);
try
Q.DatabaseName := Table.DatabaseName;
Q.SQL.Add('select max(' + FieldName + ') from ' + Table.TableName);
Q.Open;
try
Table.FieldByName(FieldName).AsInteger := Q.Fields[0].AsInteger +1;
finally
Q.Close;
end;
finally
Q.Free;
end;
end;

{ Chame esta procedure no evento BeforePost de um Table: }


procedure TForm1.Table1BeforePost(DataSet: TDataSet);
begin
tbAutoInc(Table1, 'Codigo');
end;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 184 de 272

Observações
A função acima incrementa o campo somente se estiver vazio. Assim podemos dar ao usuário a
opção de digitar neste campo ou deixá-lo vazio para que seja auto-incrementado. Existem várias
outras formas de implementar este recurso.

Obter o endereço IP do Dial-Up

Inclua na seção uses: WinSock

{ Esta função retorna o endereço IP do Dial-Up. }

function GetLocalIP : string;


type
TaPInAddr = array [0..10] of PInAddr;
PaPInAddr = ^TaPInAddr;
var
phe : PHostEnt;
pptr : PaPInAddr;
Buffer : array [0..63] of char;
I : Integer;
GInitData : TWSADATA;
begin
WSAStartup($101, GInitData);
Result := '';
GetHostName(Buffer, SizeOf(Buffer));
phe :=GetHostByName(buffer);
if phe = nil then Exit;
pptr := PaPInAddr(Phe^.h_addr_list);
I := 0;
while pptr^[I] <> nil do begin
result:=StrPas(inet_ntoa(pptr^[I]^));
result := StrPas(inet_ntoa(pptr^[I]^));
Inc(I);
end;
WSACleanup;
end;
Observações
Se o endereço IP for designado pelo servidor, a cada conecção teremos um endereço IP diferente
e, obviamente, se não estivermos conectados, não conseguiremos obtê-lo.

Exibir a caixa de diálogo padrão de solicitação de senha do banco de dados

Inclua na seção uses: DbPwDlg

{ Coloque um botão no form e escreve seu evento OnClick como abaixo }

procedure TForm1.Button1Click(Sender: TObject);


var
pw: TPasswordDialog;
begin
pw := TPasswordDialog.Create(Self);
try
pw.Caption := 'Banco de Dados';
pw.GroupBox1.Caption := 'Senha';
pw.AddButton.Caption := '&Adicionar';
pw.RemoveButton.Caption := '&Remover';
pw.RemoveAllButton.Caption := 'Remover &Tudo';
pw.OKButton.Caption := '&OK';
pw.CancelButton.Caption := '&Cancelar';
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 185 de 272

pw.ShowModal;
finally
pw.Free;
end;
end;
Observações
As senhas adicionadas nesta caixa de diálogo são adicionadas na sessão (TSession) atual. Isto é útil
quando colocamos senha em tabelas Paradox, ou mesmo quando trabalhamos com banco de dados
Client Servidor, e queremos que o usuário digite a senha de acesso. Se não fizermos desta forma,
nem adicionarmos via programação as senhas necessárias, esta caixa de diálogo será mostrada
quando o programa tentar abrir uma tabela com senha. A grande vantagem aqui é que podemos
traduzir os Caption's dos componentes.

Obter a versão da biblioteca ComCtl32.DLL (usada na unit ComCtrls do Delphi)

Inclua na seção uses: ComCtrls

{ A versão desta biblioteca determina a aparência de alguns controles do Delphi, tais como
ToolBar e CoolBar. O exemplo abaixo obtém a versão desta biblioteca.
Para este exemplo, coloque um TEdit e um TButton no Form.
O evento OnClick do botão escreva o código abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


var
Ver: Cardinal;
MaiorVer, MenorVer: Word;
begin
Ver := GetComCtlVersion;
MaiorVer := HiWord(Ver);
MenorVer := LoWord(Ver);
Edit1.Text := IntToStr(MaiorVer) + '.' + IntToStr(MenorVer);
end;
Observações
Normalmente, a versão 4.72 está presente quando o Internet Explorer 4 está instalado.

Implementar rotinas assembly em Pascal

{ O Delphi permite a implementação de rotinas assembly mescladas ao código Pascal. Não


entrarei em detalhes minuciosos, mas darei alguns exemplos básicos de como implementar rotinas
simples que retornam números inteiros.}

{ Soma dois inteiros de 8 bits }


function Soma8(X, Y: byte): byte;
asm
mov al, &X
add al, &Y
end;

{ Soma dois inteiros de 16 bits }


function Soma16(X, Y: Word): Word;
asm
mov ax, &X
add ax, &Y
end;

{ Soma dois inteiros de 32 bits }


function Soma32(X, Y: DWord): DWord;
asm
mov eax, &X
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 186 de 272

add eax, &Y


end;

{Achamada a estas funções são feitas da mesma forma que chamamos uma função Pascal.
Exemplo: }
var
A: byte;
begin
A := Soma8(30, 25); { A = 55 }
end;

Exibir o diálogo About do Windows

Inclua na seção uses: Windows

{ About padrão do Windows }


ShellAbout(Handle, 'Windows', '', 0);

{ Personalizada }
ShellAbout(Handle, 'NomePrograma',
'Direitos autorais reservados a'#13'Fulano de Tal',
Application.Icon.Handle);

Obter a linha e coluna atual em um TMemo

{ === SOLUÇÃO 1 === }

{ Esta procedure obtém a linha e coluna atual de um TMemo }


procedure tbGetMemoLinCol(Memo: TMemo; var Lin, Col: Cardinal);
begin
with Memo do begin
Lin := Perform(EM_LINEFROMCHAR, SelStart, 0);
Col := SelStart - Perform(EM_LINEINDEX, Lin, 0);
end;
end;

{ Use-a como abaixo: }

var
Lin, Col: Cardinal;
begin
tbGetMemoLinCol(Memo1, Lin, Col);
{ ... }
end;

{ === SOLUÇÃO 2 === }

var
Lin, Col: integer;
begin
Lin := Memo1.CaretPos.y;
Col := Memo1.CaretPos.x;
{...}
end;

Exibir um arquivo de ajuda do Windows

Inclua na seção uses: Windows


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 187 de 272

{ Você precisa saber:


- Caminho e nome do arquivo;
- A estrutura do arquivo de Help.
No exemplo abaixo abre o arquivo de ajuda da Calculadora do Windows e vai para o tópico n.
100}

procedure TForm1.Button1Click(Sender: TObject);


begin
WinHelp(0, 'c:\Win95\Help\Calc.hlp', HELP_CONTEXT, 100);
end;
Observações
Para utilizar um arquivo de ajuda em seu programa desenvolvido em Delphi, basta usar os recursos
do próprio Delphi. O exemplo acima é somente para mostrar o uso de uma API para este fim.

Obter o valor de uma variável de ambiente

Inclua na seção uses: Windows

{ Esta função recebe o nome da variável de ambiente que queremos acessar e retorna uma string
com seu valor, ou uma string vazia se a variável não existir. }

function tbGetEnvVar(const VarName: string): string;


var
I: integer;
begin
Result := '';

{ Obtém o comprimento da variável }


I := GetEnvironmentVariable('PATH', nil, 0);

if I > 0 then begin


SetLength(Result, I);
GetEnvironmentVariable('PATH', PChar(Result), I);
end;
end;

{ Para usá-la, faça como neste exemplo: }


Edit1.Text := tbGetEnvVar('PATH');

Determinar se uma janela (form) está maximizada

Inclua na seção uses: Windows

if IsZoomed(Form1.Handle) then
{ Form1 está maximizado }
else
{ Form2 NÃO está maximizado }

Determinar se o cursor do mouse está em determinado controle

Inclua na seção uses: Windows

{ Os exemplos abaixo verificam se o cursor do mouse está em


Button1: }

{ Solução 1: }
var
Pt: TPoint;
Rct: TRect;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 188 de 272

begin
GetCursorPos(Pt);
GetWindowRect(Button1.Handle, Rct);
if PtInRect(Rct, Pt) then
{ Está no botão }
else
{ NÃO está no botão }
end;

{ Solução 2: }
var
Pt: TPoint;
begin
GetCursorPos(Pt);
if WindowFromPoint(Pt) = Button1.Handle then
{ Está no botão }
else
{ Não está no botão }
end;
Observações
A API GetWindowRect obtém o retângulo (TRect) ocupado por uma janela. Podemos usar
GetClientRect para obter o somente da parte cliente da janela. Podemos também usar a propriedade
BoundsRect que existe na maioria dos componentes visuais, ou mesmo informar qualquer outro
retângulo da tela. Se usarmos a propriedade BoundsRect, precisaremos converter as coordenadas
clientes para coordenadas de tela (com a função ClientToScreen). Um lembrete: a solução 2 só
poderá ser aplicada a controles ajanelados.

Determinar se o aplicativo está minimizado

Inclua na seção uses: Windows

if IsIconic(Application.Handle) then
{ Minimizado }
else
{ Não minimizado }

Observações
Pode-se verificar qualquer janela (form). Só um lembrete: quando clicamos no botão de minimizar
do form principal, na verdade ele é oculto e o Application é que é minizado.

Fechar um aplicativo com uma mensagem de erro fatal

Inclua na seção uses: Windows

procedure TForm1.Button1Click(Sender: TObject);


begin
FatalAppExit(0, 'Erro fatal na aplicação.');
end;
Observações
A função FatalAppExit é uma API do Windows. Esta mostra uma caixa de diálogo (normalmente
branca) com a mensagem passada no segundo parâmetro. Quando a caixa de diálogo é fechada a
aplicação é finalizada. O evento OnCloseQuery dos forms não são chamados quando usamos esta
função.

Usar o evento OnGetText de um TField

- Adicione todos os campos no Field Editor;


- Clique no campo "Tipo";
- Vá ao Object Inspector e dê um duplo-click
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 189 de 272

no evento OnGetText;
- Neste evento, digite o código abaixo:

procedure TForm1.Table1TipoGetText(Sender: TField; var Text: String; DisplayText: Boolean);


begin
if DisplayText then begin
case Table1Tipo.AsInteger of
1: Text := 'Promissória';
2: Text := 'Duplicata';
3: Text := 'Boleto';
else
Text := 'Desconhecido';
end;
end else
Text := Table1Tipo.AsString;
end;
Observações
Ao exibir será exibido os nomes. Mas ao digitar continue com os 1, 2, 3, etc. Para usar este recurso
em relatórios, acesse a propriedade DisplayText em vez de AsString para obter o valor do campo.

Maximizar um form de forma que cubra toda a tela, inclusive a barra de tarefas

{ É um "maximizar" com jeitinho brasileiro... mas funciona. No evento OnShow do form coloque
o código abaixo: }

Top := 0;
Left := 0;
Width := Screen.Width;
Height := Screen.Height;

Verificar, via programação, se Local Share do BDE está TRUE

Inclua na seção uses: Registry, SysUtils, Windows

{ Esta função retorna true se Local Share estiver "TRUE". Caso contrário, retorna false. }

function tbBDELocalShare: boolean;


const
BdeKey = 'SOFTWARE\Borland\Database Engine\Settings\SYSTEM\INIT';
Ident = 'LOCAL SHARE';
var
Reg: TRegistry;
begin
Result := false;
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.OpenKey(BdeKey, False) then
if Reg.ValueExists(Ident) then
Result := UpperCase(Reg.ReadString(Ident)) = 'TRUE';
finally
Reg.Free;
end;
end;

{ Use-a como abaixo: }


if tbBDELocalShare then
{ Local Share está TRUE }
else
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 190 de 272

{ Local Share está FALSE }


Observações
A função acima faz a verificação no registro do Windows. Por isto está sujeita a falha caso o BDE
coloque as configurações em outro local (é o caso do BDE salvar as configurações no formato do
Windows 3.x). O ideal seria usar uma API do BDE, mas até o momento não conheço uma que
retorne esta informação. Caso alguém saiba, queira por gentileza nos informar.

Criar um EXE que seja executado apenas através de outro EXE criado por mim

Inclua na seção uses: Windows

Antes da linha "Application.Initialize;" de Prog1.dpr (programa a ser chamado), coloque o


código abaixo:}

if ParamStr(1) <> 'MinhaSenha' then begin


{ Para usar ShowMessage, coloque Dialogs no uses }
ShowMessage('Execute este programa através de Prog2.EXE');
Halt; { Finaliza }
end;

{ No Form1 de Prog2 (programa chamador) coloque um botão e escreva o OnClick deste botão
como abaixo:}

procedure TForm1.Button1Click(Sender: TObject);


var
Erro: Word;
begin
Erro := WinExec('Pro2.exe MinhaSenha', SW_SHOW);
if Erro <= 31 then { Se ocorreu erro... }
ShowMessage('Erro ao executar o programa.');
end;
Observações
Aqui o parâmetro passado foi 'MinhaSenha'. Você deverá trocar 'MinhaSenha' por algo que apenas
você saiba (uma senha). Caso uma pessoa conheça esta senha, será possível chamar este programa
passando-a como parâmetro. Neste caso sua "trava" estará violada.

Resolver "Internal error near: IBCheck" do Interbase 5.1.1 Server no NT

Esse erro: 'Internal error near: IBCheck' acontece apenas


em algumas máquinas NT 4.

Na hora da instalação, é criada uma chave com valor errado.

Entre no registry do Windows e altere a opção, PATH de binário


para string, da chave:

HKEY_CURRENT_USER\Environment

Inverter os botões do mouse

Inclua na seção uses: Windows

{ Para inverter: }
SwapMouseButton(true);

{ Para voltar ao normal: }


SwapMouseButton(false);
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 191 de 272

Obter/definir o tempo máximo do duplo-click do mouse

Inclua na seção uses: Windows

{ - Coloque um botão no form e escreva seu OnClick como abaixo: }

procedure TForm1.Button6Click(Sender: TObject);


var
Tempo: Cardinal;
begin
{ Obtém }
Tempo := GetDoubleClickTime;
ShowMessage(IntToStr(Tempo) + ' milisegundos');

{ Define }
SetDoubleClickTime(300);
end;
Observações
Um duplo-click nada mais é que dois cliques consecutivos (óbvio). Porém estes dois cliques
podem ser interpretados de duas formas: dois cliques isolados ou um duplo-click. Para o Windows
resolver esta situação, ele usa o que chamo de "tempo máximo do duplo-click". Se o intervalo entre
o primeiro e o segundo click for menor ou igual a esse tempo, então houve duplo-click. E você
pode alterar este tempo. O padrão do Windows é 500 milisegundos. Um tempo muito curto (ex:
100), faz com que o duplo-click tenha que ser muito rápido (quase impossível), enquanto muito
longo (ex: 2000) faz com que o Windows interprete dois clicks isolados como duplo-click.

Obter os atributos de um arquivo/diretório

Inclua na seção uses: Windows

{ No form:
- Coloque um memo;
- Coloque um edit;
- Coloque um botão e escreva seu OnClick como abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


var
Attr: DWord;
begin
Memo1.Clear;
Attr := GetFileAttributes(PChar(Edit1.Text));
if Attr > 0 then
with Memo1.Lines do begin
if (Attr and FILE_ATTRIBUTE_ARCHIVE) > 0 then
Add('Archive');
if (Attr and FILE_ATTRIBUTE_COMPRESSED) > 0 then
Add('Compressed');
if (Attr and FILE_ATTRIBUTE_DIRECTORY) > 0 then
Add('Directory');
if (Attr and FILE_ATTRIBUTE_HIDDEN) > 0 then
Add('Hidden');
if (Attr and FILE_ATTRIBUTE_NORMAL) > 0 then
Add('Normal');
if (Attr and FILE_ATTRIBUTE_OFFLINE) > 0 then
Add('OffLine');
if (Attr and FILE_ATTRIBUTE_READONLY) > 0 then
Add('ReadOnly');
if (Attr and FILE_ATTRIBUTE_SYSTEM) > 0 then
Add('System');
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 192 de 272

if (Attr and FILE_ATTRIBUTE_TEMPORARY) > 0 then


Add('Temporary');
end;
end;

Obter o espaço total e livre de um disco

Inclua na seção uses: Windows

{ - Coloque um memo (TMemo) no form;


- Coloque um botão e altere seu OnClick como abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


var
SetoresPorAgrup, BytesPorSetor, AgrupLivres,
TotalAgrup: DWord;
begin
Memo1.Clear;
if GetDiskFreeSpace('C:\', SetoresPorAgrup,
BytesPorSetor, AgrupLivres, TotalAgrup) then
with Memo1.Lines do begin
Add('Setores por agrupamento: ' + IntToStr(SetoresPorAgrup));
Add('Bytes por setor: ' + IntToStr(BytesPorSetor));
Add('Agrupamentos livres: ' + IntToStr(AgrupLivres));
Add('Total de agrupamentos: ' + IntToStr(TotalAgrup));
Add('----- Resumo -----');
Add('Total de bytes: ' +
IntToStr(TotalAgrup * SetoresPorAgrup * BytesPorSetor));
Add('Bytes livres: ' +
IntToStr(AgrupLivres * SetoresPorAgrup * BytesPorSetor));
end;
end;

{ O exemplo acima retorna as medidas em Bytes, Setores e


Agrupamentos. Se preferir algo mais simples,
use funções do Delphi. Veja: }

Memo1.Lines.Add('Total de bytes: ' + IntToStr(DiskSize(3)));


Memo1.Lines.Add('Bytes livres: ' + IntToStr(DiskFree(3)));

{ Onde o parâmetro (3) é o número da unidade, sendo


1=A, 2=B, 3=C, ... }
Observações
Para usar as funções DiskSize e DiskFree coloque SysUtils em uses.

Obter o tipo de um drive (removível, fixo, CD-ROM, unidade de rede, etc)

Inclua na seção uses: Windows, Dialogs

{ - Coloque um edit (Edit1) e um botão no form;


- Altere o OnClick do botão conforme abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


var
S: string;
Tipo: byte;
begin
Tipo := GetDriveType(PChar(Edit1.Text[1] + ':\'));
case Tipo of
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 193 de 272

0: S := 'Tipo indeterminado';
1: S := 'Drive não existe';
DRIVE_REMOVABLE: S := 'Disco removível';
DRIVE_FIXED: S := 'Disco Fixo';
DRIVE_REMOTE: S := 'Unidade de rede';
DRIVE_CDROM: S := 'CD-ROM';
DRIVE_RAMDISK: S := 'RAM Disk';
else
S := 'Erro';
end;
ShowMessage(S);
end;

{ Para pegar o tipo da unidade atual troque...}


Tipo := GetDriveType(PChar(Edit1.Text[1] + ':\'));
{ por }
Tipo := GetDriveType(nil);
Observações
Para testar digite a letra do drive no Edit1 e clique no botão. A unit Dialogs foi colocada no uses
apenas por causa da procedure ShowMessage. Para exibir todas as unidades existentes e seus
respectivos tipos, use a função tbGetDrives (da pergunta 64) em conjunto com este exemplo.

Obter informações de um volume/disco (label, serial, sistema de arquivos, etc)

Inclua na seção uses: Windows, System

{ - Coloque um memo (TMemo) no form;


- Coloque um botão e escreve seu evento OnClick como abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


var
SLabel, SSysName: PChar;
Serial, FileNameLen, X: DWord;
begin
Memo1.Clear;
GetMem(SLabel, 255);
GetMem(SSysName, 255);
try
GetVolumeInformation('C:\', SLabel, 255,
@Serial, FileNameLen, X, SSysName, 255);
with Memo1.Lines do begin
Add('Nome do volume (Label): ' + string(SLabel));
Add('Número Serial: ' + IntToHex(Serial, 8));
Add('Tamanho máximo p/ nome arquivo: ' +
IntToStr(FileNameLen));
Add('Sistema de Arquivos: ' + string(SSysName));
end;
finally
FreeMem(SLAbel, 255);
FreeMem(SSysName, 255);
end;
end;

Alterar o nome de volume (Label) de um disco

Inclua na seção uses: Windows

{ Da unidade C: }
SetVolumeLabel('c:\', 'NovoLabel');
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 194 de 272

{ Da unidade atual: }
SetVolumeLabel(nil, 'NovoLabel');

Saber quais as unidades de disco (drives) estão presentes

Inclua na seção uses: Windows

{ A função abaixo retorna uma string contendo as letras de unidades de discos presentes. }

function tbGetDrives: string;


var
Drives: DWord;
I: byte;
begin
Result := '';
Drives := GetLogicalDrives;
if Drives <> 0 then
for I := 65 to 90 do
if ((Drives shl (31 - (I - 65))) shr 31) = 1 then
Result := Result + Char(I);
end;

{ Para saber se uma determinada unidade está presente, basta fazer algo como: }
if Pos('A', tbGetDrives) > 0 then
ShowMessage('Unidade A: presente.')
else
ShowMessage('Unidade A: ausente.');
Observações
A string retornada pela função tbGetDrives está sempre em letras maiúsculas.

"truncar" valores reais para apenas n casas decimais

{ Às vezes você precisa considerar apenas duas casas de valores reais, mas o Delphi não oferece
algo pronto para isto. Se usarmos funções como Round que vem com o Delphi, o valor será
arredondado (e não truncado). Com Round() o valor abaixo será 135.55 (e não 135.54) com duas
casas decimais.}

ValorReal := 135.54658;

{ Somente a parte inteira - nenhuma casa decimal }


X := Trunc(ValorReal); // X será 135

{ Duas casas }
X := Trunc(ValorReal * 100) / 100; // X será 135.54

{ Três casas }
X := Trunc(ValorReal * 1000) / 1000; // X será 135.5465
Observações
Isto pode não funcionar se ValorReal for muito alto. Isto por causa da multiplicação que poderá
estourar a capacidade do tipo em uso. Lembre-se: os tipos reais aceitam valores muuuiiiito altos.

Excluir todos os registros de uma tabela (como DELETE ALL do Clipper)

procedure tbDBDeleteAll(const DataSet: TDataSet);


begin
with DataSet do
while RecordCount > 0 do
Delete;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 195 de 272

end;

{ Chame-a como nos exemplos abaixo: }


tbDBDeleteAll(Table1);
ou
tbDBDeleteAll(Query1);
Observações
Se houver um filtro ou range ativo, somente os registros filtrados serão excluídos. Portanto é
diferente de Table1.EmptyTable. Esta função poderá ser chamada no evento BeforeDelete do
Table (ou Query) principal em um formulário mestre-detalhe para excluir os itens (da parte
detalhe).

Saber se o sistema está usando 4 dígitos para o ano

{ Para não correr o risco de surpresas desagradáveis, é melhor que seu programa em Delphi
verifique se o Windows está ajustado para trabalhar com 4 dígitos para o ano. Assim seu
programa pode alertar o usuário quando o ano estiver sendo representado com apenas 2 dígitos.
A função abaixo retorna true se estiver ajustado para 4 dígitos.}

function Is4DigitYear: Boolean;


begin
result:=(Pos('yyyy',ShortDateFormat)>0);
end;

Imprimir caracteres acentuados diretamente para a impressora

{ Usando comandos da impressora podemos fazer isto de uma forma bastante simples. Quando
enviamos o caractere ASCII número 8 (oito) para a impressora, a cabeça de impressão retrocede
uma posição, pois este caractere é o BackSpace.
Então podemos imprimir a letra sem acento e, sem seguida, voltar e imprimir o acento desejado.
Vejamos um exemplo:

- Coloque um botão no form;


- Altere o evento OnClick deste botão conforme abaixo:}

procedure TForm1.Button2Click(Sender: TObject);


var
F: TextFile;
begin
AssignFile(F, 'LPT1');
Rewrite(F);
try
{ Regra: caractere sem acento + chr(8) + acento }
WriteLn(F, 'Este e' + #8 + '''' + ' um teste.');
WriteLn(F, 'Acentuac' + #8 + ',a' + #8 + '~o.');
WriteLn(F, 'Vovo' + #8 + '^');
WriteLn(F, 'U' + #8 + '''' + 'ltimo.');
WriteLn(F, #12); // Eject
finally
CloseFile(F);
end;
end;
Observações
Usando este recurso, a acentuação não fica excelente, mas melhora bastante.

Imprimir texto justificado com formatação na impressora Epson LX-300


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 196 de 272

{ A impressora Epson LX-300 dispõe de um comando que justifica o texto. Este recurso é
interessante, pois com ele podemos continuar a enviar os comandos de formatação de caracteres
como condensado, negrito, italico, expandido, etc.

Para o exemplo abaixo:


- Coloque um botão no form;
- Altere o evento OnClick deste botão como abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


const
cJustif = #27#97#51;
cEject = #12;

{ Tamanho da fonte }
c10cpi = #18;
c12cpi = #27#77;
c17cpi = #15;
cIExpandido = #14;
cFExpandido = #20;
{ Formatação da fonte }
cINegrito = #27#71;
cFNegrito = #27#72;
cIItalico = #27#52;
cFItalico = #27#53;
var
Texto: string;
F: TextFile;
begin
Texto := c10cpi +
'Este e um teste para impressora Epson LX 300. ' + 'O objetivo e imprimir texto justificado
sem deixar ' + 'de usar formatacao, tais como: ' + cINegrito + 'Negrito, ' + cFNegrito +
cIItalico + 'Italico, ' + cFItalico + c17cpi + 'Condensado (17cpi), ' + c10cpi + c12cpi + '12 cpi, '
+ c10cpi + cIExpandido + 'Expandido.' + cFExpandido + ' Este e apenas um exemplo, mas
voce podera adapta-lo ' + 'a sua realidade conforme a necessidade.';

AssignFile(F, 'LPT1');
Rewrite(F);
try
WriteLn(F, cJustif, Texto);
WriteLn(F, cEject);
finally
CloseFile(F);
end;
end;
Observações
Este recurso de justificação da Epson LX-300 pode ser usado em qualquer linguagem de
programação.

Formatar um disquete através de um programa Delphi

{ Coloque o código abaixo imediatamente abaixo da palavra implementation: }

const
SHFMT_ID_DEFAULT = $FFFF;

{ Opções de formatação }
SHFMT_OPT_QUICKFORMAT = $0000; { Formatação rápida }
SHFMT_OPT_FULL = $0001; { Formatação completa }
SHFMT_OPT_SYSONLY = $0002; { Copia sistema }
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 197 de 272

{ Códigos de errros }
SHFMT_ERROR = $FFFFFFFF; { Ocorreu erro }
SHFMT_CANCEL = $FFFFFFFE; { Foi cancelado }
SHFMT_NOFORMAT = $FFFFFFFD; { Não formatou }

function SHFormatDrive(Handle: HWND; Drive, ID, Options: Word):


LongInt; stdcall; external 'shell32.dll' name 'SHFormatDrive'

{ Coloque um botão no form e altere o evento OnClick dele


conforme abaixo: }

procedure TForm1.Button3Click(Sender: TObject);


var
Erro: DWord;
Msg: string;
begin
Erro := SHFormatDrive(Handle, 0, SHFMT_ID_DEFAULT, SHFMT_OPT_QUICKFORMAT);
case Erro of
SHFMT_ERROR: Msg := 'Ocorreu um erro.';
SHFMT_CANCEL: Msg := 'A formatação foi cancelada.';
SHFMT_NOFORMAT: Msg := 'Não foi possível formatar.';
else
Msg := 'Disco formatado com sucesso.';
end;
ShowMessage(Msg);
end;
Observações
Para formatação completa troque SHFMT_OPT_QUICKFORMAT por SHFMT_OPT_FULL. O
segundo parâmetro (zero no exemplo) indica a unidade, sendo que A é 0 (zero), B é 1, etc.

Alterar (e restaurar) o tamanho da página na impressora

Inclua na seção uses: tbPrn

{ - Peque em nosso Download o arquivo tbPrn.zip. Ele contém a unit tbPrn.pas, onde está a
função tbPrnSetPaperSize
usada no exemplo abaixo;

- Adicione a unit tbPrn.pas em seu projeto;


- Siga o exemplo abaixo para criar seus relatórios
usando o TPrinter.}

procedure TForm1.Button1Click(Sender: TObject);


var
Papel: TtbPrnPaper;
begin
Papel.Size := 256; // 256 é o tam. personalizado
Papel.Width := 2100; // 21 cm
Papel.Height := 1000; // 10 cm
Papel := tbPrnSetPaperSize(Papel);
try
Printer.BeginDoc;
try
{ coloque aqui os comandos para impressão }
finally
Printer.EndDoc;
end;
finally
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 198 de 272

tbPrnSetPaperSize(Papel); // Restaura o tamanho


end;
end;

{ Papel.Size refere-se ao tamanho do papel. Veja alguns:


0 - Default
1 - Letter
5 - Legal
8 - A3
9 - A4
11 - A5
256 - Custom (personalizado) }
Observações
Só será necessário informar Papel.Height e Papel.Width quando Papel.Size for 256.

Reproduzir um arquivo de som WAV sem o TMediaPlayer

Inclua na seção uses: MMSystem

{ Síncrona: aguarda terminar a reprodução para continuar: }


SndPlaySound('C:\Win95\Media\Office97\Lembrete.wav', SND_SYNC);

{ Assíncrona: a execução continua normalmente enquanto ocorre a reprodução: }


SndPlaySound('C:\Win95\Media\Office97\Lembrete.wav', SND_ASYNC);

{ Contínua: a reprodução é repetida num efeito de loop.


Este tipo de reprodução precisa ser assíncrona: }
SndPlaySound('C:\Win95\Media\Office97\Lembrete.wav', SND_ASYNC or SND_LOOP);

{ Interrompe uma reprodução contínua: }


SndPlaySound(nil, 0);
Observações
A reprodução contínua pode ser usada, por exemplo, para altertar o usuário em uma situação
extremamente crítica. Se o equipamento não possuir placa de som, o arquivo não será reproduzido.

Obter o nome do usuário e da empresa informado durante a instalação do Windows

Inclua na seção uses: Registry

{ Coloque um botão no form e altere seu evento OnCkick como abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


var
Reg: TRegIniFile;
S: string;
begin
Reg := TRegIniFile.Create('SOFTWARE\MICROSOFT\MS SETUP (ACME)\');
try
S := Reg.ReadString('USER INFO','DefName','');
S := S + #13;
S := S + Reg.ReadString('USER INFO','DefCompany','');
ShowMessage(S);
finally
Reg.free;
end;
end;

Mostrar uma barra de progresso enquanto copia arquivos


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 199 de 272

Veja a próxima

Copiar arquivos usando o Shell do Windows

Inclua na seção uses: ShellApi

{ - Coloque um botão no form e altere o evento OnClick deste botão conforme abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


var
Dados: TSHFileOpStruct;
begin
FillChar(Dados,SizeOf(Dados), 0);
with Dados do
begin
wFunc := FO_COPY;
pFrom := PChar('c:\teste\*.txt');
pTo := PChar('a:\');
fFlags:= FOF_ALLOWUNDO;
end;
SHFileOperation(Dados);
end;
Observações
Esta forma de copiar arquivos oferecem várias vantagens. O Shell avisa para pôr um próximo disco
quando o atual estiver cheio. Mostra a barra de progresso. Pode copiar arquivos usando máscara de
uma forma extremamente simples.

Descobrir o código ASCII de uma tecla

{ - Coloque um Label no form (Label1);


- Mude a propriedade KeyPreview do form para true;
- Altere o evento OnKeyDown do form como abaixo: }

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;


Shift: TShiftState);
begin
Label1.Caption :=
Format('O código da tecla pressionada é: %d', [Key]);
end;
Observações
Para testar execute e observe o Label enquanto pressiona as teclas desejadas.

Evitar que seu programa apareça na barra de tarefas

Inclua na seção uses: Windows

{ Você já observou a caixa "Propriedades", aquela que mostra as propriedades de um arquivo no


Windows Explorer, não aparece na lista do Alt+Tab e tampouco na barra de tarefas?

Isto ocorre porque ela funciona como uma ToolWindow, enquanto os demais aplicativos
funcionam como AppWindow. Porém podemos mudar o comportamento de nossos programas
feito em Delphi
para que se comportem como uma ToolWindow também. Para experimentar, crie um novo
projeto e altere o Project1.dpr como abaixo (não esqueça do uses): }

program Project1;

uses
Forms, Windows,
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 200 de 272

Unit1 in 'Unit1.pas' {Form1};

{$R *.RES}

var
ExtendedStyle : Integer;
begin
Application.Initialize;

ExtendedStyle := GetWindowLong(Application.Handle, gwl_ExStyle);


SetWindowLong(Application.Handle, gwl_ExStyle, ExtendedStyle or
ws_Ex_ToolWindow and not ws_Ex_AppWindow);

Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Observações
Ao executar observe a barra de tarefas e teste o Alt+Tab (seu programa não estará lá!).

Usar eventos de som do Windows

{ Evento Som Padrão }


MessageBeep(0); { ou Beep; }

{ Evento Parada Crítica }


MessageBeep(16);

{ Evento Pergunta }
MessageBeep(32);

{ Evento Exclamação }
MessageBeep(48);

{ Evento Asterisco }
MessageBeep(64);

Mudar a coluna ativa em um DBGrid via programação

{ Usando número da coluna (zero é a primeira coluna): }


DBGrid1.SelectedIndex := 0;

{ Usando o nome do campo }


DBGrid1.SelectedField := Table1.FieldByName(Edit2.Text);
Observações
Aconselho usar o nome do campo quando o que importa é o campo e não a posição. Use o número
da coluna somente quando o que importa é a posição, e não o campo.

Fechar o Windows a partir do seu programa

{ Reinicia o Windows }
ExitWindowsEx(EWX_REBOOT, 0);

{ Desliga o Windows }
ExitWindowsEx(EWX_SHUTDOWN, 0);

{ Força todos os programa a desligarem-se }


ExitWindowsEx(EWX_FORCE, 0);
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 201 de 272

Carregar um cursor animado (.ani)

{ Altere o evento OnCreate do Form conforme abaixo: }

procedure TForm1.FormCreate(Sender: TObject);


begin
Screen.Cursors[1] :=
LoadCursorFromFile('c:\win95\cursors\globe.ani');
Button1.Cursor := 1;
end;
Observações
Para este exemplo é necessário ter o arquivo de cursor conforme apontado e também ter, no form,
um Button1. Para usar este cursor em outros componentes basta atribuir à propriedade Cursor do
componente em questão o valor 1 (um). Exemplo: Edit1.Cursor := 1; Form1.Cursor := 1;, etc.

Enviar um arquivo para a lixeira


Inclua na seção uses: ShellApi

{ Coloque a procedure abaixo na seção implementation }

procedure ArqParaLixeira(const NomeArq: string; var MsgErro: string);


var
Op: TSHFileOpStruct;
begin
MsgErro := '';
if not FileExists(NomeArq) then begin
MsgErro := 'Arquivo não encontrado.';
Exit;
end;
FillChar(Op, SizeOf(Op), 0);
with Op do begin
wFunc := FO_DELETE;
pFrom := PChar(NomeArq);
fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_SILENT;
end;
if ShFileOperation(Op) <> 0 then
MsgErro := 'Não foi possível enviar o arquivo para a lixeira.';
end;

{ - Coloque um botão no Form;


- Altere o evento OnClick do botão conforme abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


var
S: string;
begin
ArqParaLixeira('c:\Diretorio\Teste.doc', S);
if S = '' then
ShowMessage('O arquivo foi enviado para a lixeira.')
else
ShowMessage(S);
end;

Obter o número do registro atual

Table1.RecNo()

Trabalhar com Filter de forma mais prática


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 202 de 272

Se você está habituado a usar este código no filter...

Table1.Filter := 'Nome = '''+ Edit1.Text + '''';


ou
Table1.Filter := 'Data = ''' + DateToStr(Date) + '''';

Tente usar este:

Table1.Filter := 'Nome = ' + QuotedStr(Edit1.Text);


ou
Table1.Filter := 'Data = ' + QuotedStr(DateToStr(Date));
Observações
A função QuitedStr() coloca apóstrofos envolvendo a string. Se houver um apóstrofo como parte
da string, ela o subtitui por dois apóstrofos, para que seja corretamente interpretado.

Reproduzir um arquivo WAV

Inclua na seção uses: MMSystem

PlaySound('C:\ArqSom.wav', 1, SND_ASYNC);
Observações
Troque o nome do arquivo (C:\ArqSom.wav) pelo arquivo desejado.

Executar um programa DOS e fechá-lo em seguida

{ Coloque isto no evento OnClick de um botão: }

WinExec('command.com /c programa.exe',sw_ShowNormal);

{ Se quizer passar parâmetros pasta adicioná-los após o nome do programa. Exemplo: }

WinExec('command.com /c programa.exe param1 param2',sw_ShowNormal);


Observações
Se quizer que a janela do programa não apareça, troque sw_ShowNormal por sw_Hide.

Fechar um programa a partir de um programa Delphi

{ - Coloque um botão no form e altere seu evento OnClick conforme abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


var
Janela: HWND;
begin
Janela := FindWindow('OpusApp'), nil);
if Janela = 0 then
ShowMessage('Programa não encontrado')
else
PostMessage(Janela, WM_QUIT, 0, 0);
end;
Observações
Este exemplo fecha o MS Word 97 se estiver aberto. A mensagem WM_QUIT fecha o programa
da forma "ignorante". Isto significa que se houver dados não salvos, o programa a ser fechado não
oportunidade para salvá-los. Uma alternativa mais suave é trocar a mensagem WM_QUIT por
WM_CLOSE. Veja as perguntas 18 e 36.

Colocar Hint's de várias linhas

{ - Coloque um TButton no Form; - Altere o evento OnCreate do Form como abaixo: }


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 203 de 272

procedure TForm1.FormCreate(Sender: TObject);


begin
Button1.Hint := 'Linha 1 da dica' + #13 +
'Linha 2 da dica' + #13 +
'Linha 3 da dica';
Button1.ShowHint := true;
end;

Reproduzir um vídeo AVI em um Form

{ - Crie um novo projeto. Este já deverá ter o Form1;


- Adicione um novo Form (Form2);
- Coloque, no Form1, um TMediaPlayer (paleta System)
e um botão;
- Altere o evento OnClick do botão como abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


begin
with MediaPlayer1 do begin
FileName := 'c:\speedis.avi';
Open;

{ Ajusta tamanho do Form }


with MediaPlayer1.DisplayRect do begin
Form2.ClientHeight := Bottom - Top;
Form2.ClientWidth := Right - Left;
end;

Display := Form2;
Form2.Show;
Play;
end;
end;
Observações
Em vez de ajustar o Form ao vídeo, podemos ajustar o vídeo ao Form. Para isto troque o trecho
with..end; por MediaPlayer1.DisplayRect := Form2.ClientRect;

Separar (filtrar) caracteres de uma string

{ Abaixo da palavra implementation digite: }

type
TChars = set of Char;

function FilterChars(const S: string; const ValidChars: TChars): string;


var
I: integer;
begin
Result := '';
for I := 1 to Length(S) do
if S[I] in ValidChars then
Result := Result + S[I];
end;

{ Para usar a função:


- Coloque um botão no Form;
- Altere o evento OnClick deste botão conforme abaixo: }

procedure TForm1.Button4Click(Sender: TObject);


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 204 de 272

begin
{ Pega só letras }
ShowMessage(FilterChars('D63an*%i+/e68l13',
['A'..'Z', 'a'..'z']));
{ Pega só números }
ShowMessage(FilterChars('D63an*%i+/e68l13', ['0'..'9']));
end;

Observações
Se quizer usar este função em outras unit's, coloque a declaração do tipo TChars na seção interface.
Coloque aí também uma declaração da função FilterChars. E não se esqueça da cláusula uses.

Colocar zeros à esquerda de números

{ Isto coloca zeros à esquerda do número até completar 6 casas }


S := FormatFloat('000000', 5);

Observações
"S" precisa ser uma variável string.

Copiar arquivos usando curingas (*.*)

{ - Coloque um Button no Form;


- Altere o evento OnClick deste Button conforme abaixo: }

procedure TForm1.Button2Click(Sender: TObject);


var
SR: TSearchRec;
I: integer;
Origem, Destino: string;
begin
I := FindFirst('c:\Origem\*.*', faAnyFile, SR);
while I = 0 do begin
if (SR.Attr and faDirectory) <> faDirectory then begin
Origem := 'c:\Origem\' + SR.Name;
Destino := 'c:\Destino\' + SR.Name;
if not CopyFile(PChar(Origem), PChar(Destino), true) then
ShowMessage('Erro ao copiar ' + Origem + ' para ' + Destino);
end;
I := FindNext(SR);
end;
end;
Observações
No exemplo acima, se o arquivo já existir no destino, a função falha (não copia). Para que a função
possa sobreescrever o arquivo destino (caso exista), altere o último parâmetro de CopyFile para
false. CUIDADO! Se um arquivo for sobreescrito.

Copiar arquivos

{ - Coloque um Button no Form;


- Altere o evento OnClick deste Button conforme abaixo: }

procedure TForm1.Button2Click(Sender: TObject);


var
Origem, Destino: string;
begin
Origem := 'c:\Origem\NomeArq.txt';
Destino := 'c:\Destino\NomeArq.txt';
if not CopyFile(PChar(Origem), PChar(Destino), true) then
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 205 de 272

ShowMessage('Erro ao copiar ' + Origem + ' para ' + Destino);


end;
Observações
No exemplo acima, se o arquivo já existir no destino, a função falha (não copia). Para que a função
possa sobreescrever o arquivo destino (caso exista), altere o último parâmetro de CopyFile para
false. CUIDADO! Se um arquivo for sobreescrito, estará perdido para sempre!.

Trabalhar com cores no formato string

procedure TForm1.Button3Click(Sender: TObject);


begin
{ Exibe as cores atuais dos Edit's }
ShowMessage(ColorToString(Edit1.Color));
ShowMessage(ColorToString(Edit2.Color));

{ Altera as cores dos Edit's }


Edit1.Color := StringToColor('clBlue');
Edit2.Color := StringToColor('$0080FF80');
end;

Verificar se determinado programa está em execução (Word, Delphi, etc)

{ Coloque um Button no Form e altere o evento OnClick deste como abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


begin
{ Verifica o Delphi }
if FindWindow('TAppBuilder', nil) > 0 then
ShowMessage('O Delphi está aberto')
else
ShowMessage('O Delphi NÃO está aberto');

{ Verifica o Word }
if FindWindow('OpusApp', nil) > 0 then
ShowMessage('O Word está aberto')
else
ShowMessage('O Word NÃO está aberto');

{ Verifica o Excell }
if FindWindow('XLMAIN', nil) > 0 then
ShowMessage('O Excell está aberto')
else
ShowMessage('O Excell NÃO está aberto');
end;
Observações
Há uma margem de erro nesta verificação: pode haver outros programas que possuam uma janela
com os mesmos nomes. Você mesmo pode criar aplicativos em Delphi e, propositadamente, criar
uma janela com um destes nomes. Veja a pergunta nº 18.

Excluir arquivos usando curingas (*.*)

{ - Coloque um Button no Form;


- Altere o evento OnClick do Button conforme abaixo: }

procedure TForm1.Button2Click(Sender: TObject);


var
SR: TSearchRec;
I: integer;
begin
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 206 de 272

I := FindFirst('c:\Teste\*.*', faAnyFile, SR);


while I = 0 do begin
if (SR.Attr and faDirectory) <> faDirectory then
if not DeleteFile('c:\Teste\' + SR.Name) then
ShowMessage('Não consegui excluir c:\Teste\' + SR.Name);
I := FindNext(SR);
end;
end;
Observações
No exemplo acima todos os arquivos do diretório c:\Teste serão excluídos. CUIDADO! Arquivos
excluídos desta forma não vão para a lixeira.

Gerar uma tabela no Word através do Delphi

Inclua na seção uses: ComObj

{ - Coloque um botão no Form;


- Altere o evento OnClick do botão conforme abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


var
Word: Variant;
begin
{ Abre o Word }
Word := CreateOleObject('Word.Application');
try
{ Novo documento }
Word.Documents.Add;
try
{ Adiciona tabela de 2 linhas e 3 colunas }
Word.ActiveDocument.Tables.Add(
Range := Word.Selection.Range,
NumRows := 2,
NumColumns := 3);
{ Escreve na primeira célula }
Word.Selection.TypeText(Text := 'Linha 1, Coluna 1');
{ Próxima célula }
Word.Selection.MoveRight(12);
{ Escreve }
Word.Selection.TypeText(Text := 'Linha 1, Coluna 2');
Word.Selection.MoveRight(12);
Word.Selection.TypeText(Text := 'Linha 1, Coluna 3');
Word.Selection.MoveRight(12);
Word.Selection.TypeText(Text := 'Linha 2, Coluna 1');
Word.Selection.MoveRight(12);
Word.Selection.TypeText(Text := 'Linha 2, Coluna 2');
Word.Selection.MoveRight(12);
Word.Selection.TypeText(Text := 'Linha 2, Coluna 3');
{ Auto-Formata }
Word.Selection.Tables.Item(1).Select; { Seleciona a 1º tabela }
Word.Selection.Cells.AutoFit; { auto-formata }
{ Imprime 1 cópia }
Word.ActiveDocument.PrintOut(Copies := 1);
ShowMessage('Aguarde o término da impressão...');
{ Para salvar... }
Word.ActiveDocument.SaveAs(FileName := 'c:\Tabela.doc');
finally
{ Fecha documento }
Word.ActiveDocument.Close(SaveChanges := 0);
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 207 de 272

end;
finally
{ Fecha o Word }
Word.Quit;
end;
end;
Observações
Foram usados neste exemplo o Delphi4 e MS-Word97, testado por mim no delphi 2005 Word
2003

Obter a quantidade de registros total e visível de uma tabela

Inclua na seção uses: DbiProcs

Os componentes TTable e TQuery possuem a propriedade RecordCount que indicam a quantidade


de registros da tabela.No entanto esta propriedade é dependente de filtros, ou seja, se tivermos uma
tabela com dez registros com campo "Codigo" de 1 a 10 e aplicarmos o filtro mostrado a seguir, a
propriedade RecordCount retornará 5 e não 10.

Table1.Filter := 'Codigo <= 5';


Table1.Filtered := true;

Se quizermos obter a quantidade total de registros, independentemente de filtros, devemos usar


uma API do BDE
conforme abaixo:

var
Total: integer;
begin
Check(DbiGetRecordCount(Table1.Handle, Total));
ShowMessage('Total de registros: ' + IntToStr(Total));
end;
Observações
Para testar o exemplo acima, o Table1 precisa estar aberto.

Evitar que um programa seja executado mais de uma vez

{ Muitos programas Windows permitem apenas uma cópia em execução de cada vez. Isto é
interessante principalmente quando é um grande aplicativo, pois duas cópias ao mesmo tempo
usuaria muito mais memória. Em aplicativos desenvolvidos em Delphi podemos ter esta
característica.
Vejamos:

- Crie um novo projeto;


- Mude o "Name" do Form1 para DPGFormPrinc;
- Altere o código-fonte do arquivo Project1.dpr
conforme abaixo: }

program Project1;

uses
Forms, Windows,
Unit1 in 'Unit1.pas' {DPGFormPrinc};

{$R *.RES}

var
Handle: THandle;
begin
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 208 de 272

Handle := FindWindow('TDPGFormPrinc', nil);


if Handle <> 0 then begin { Já está aberto }
Application.MessageBox('Este programa já está aberto. A cópia ' +
'anterior será ativada.', 'Programa já aberto', MB_OK);
if not IsWindowVisible(Handle) then
ShowWindow(Handle, SW_RESTORE);
SetForegroundWindow(Handle);
Exit;
end;
Application.Initialize;
Application.CreateForm(TDPGFormPrinc, DPGFormPrinc);
Application.Run;
end.
Observações
Para testar este programa você deverá compilar o projeto e fechar o Delphi. Depois, procure o
Project1.exe (projeto compilado) usando o Windows Explorer e tente executá-lo mais de uma vez e
veja o que acontece. Mas porque alterar o name do form principal para "DPGFormPrinc"? Este
poderia ser qualquer outro nome, mas preferi usar as iniciais do meu nome (DPG). Procurei deixar
um nome bem pessoal para não correr o risco de colocar um nome que possa ser encontrado em
outro aplicativo do Windows. Por exemplo: se deixar Form1, será bem fácil encontrar outro
aplicativo feito em Delphi que possua uma janela com este nome, o que causaria problema.

Executar um "COMMIT" no Delphi

Inclua na seção uses: DbiProcs

{ Se estiver usando TTable, coloque nos eventos AfterPost e AfterDelete a seguinte linha: }
dbiSaveChanges(Table1.Handle);
{ Para TQuery, a instrução é semelhante: }
dbiSaveChanges(Query1.Handle);

Posicionar Form's em relação ao Desktop do Windows

{ Quando usamos a propridade Position de um Form para centralizá-lo estamos sujeitos a um


inconveniente: dependendo da posição/tamanho da barra de tarefas do Windows, o nosso Form
poderá ficar parcialmente coberto por ela. Uma forma eficaz de resolver este problema é
posicionar o form considerando apenas a área livre do Desktop. Vejamos este exemplo:

- Crie um novo projeto;


- Na seção implementation digite a procedure abaixo:}

procedure FormPos(Form: TForm; const Horz, Vert: byte);


{ Horz: 1=esquerda, 2=centro, 3=direita
Vert: 1=topo, 2=centro, 3=em baixo }
var
R: TRect;
begin
if not SystemParametersInfo(SPI_GETWORKAREA, 0, @R, 0) then
R := Rect(0, 0, Screen.Width, Screen.Height);
with Form do
case Horz of
1: Form.Left := 0;
2: Form.Left := (R.Right - R.Left - Width) div 2;
3: Form.Left := R.Right - Width;
end;
with Form do
case Vert of
1: Form.Top := 0;
2: Form.Top := (R.Bottom - R.Top - Height) div 2;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 209 de 272

3: Form.Top := R.Bottom - Height;


end;
end;

{ - Coloque dois TEdit's: Edit1 e Edit2;


- Coloque um TButton e altere o evento OnClick deste
conforme abaixo:}

procedure TForm1.Button1Click(Sender: TObject);


begin
FormPos(Form1, StrToInt(Edit1.Text), StrToInt(Edit2.Text));
end;
Observações
Para testar, execute este exemplo e experimente digitar números de 1 a 3 em ambos os Edit's e
clique no Button para ver o resultado. O Edit1 indica a posição horizontal (esquerda, centro e
direita) e o Edit2 indica a posição vertical (topo, centro e em baixo).

Saber a resolução de tela atual

{ Coloque um TButton no Form e altere o evento OnClick deste botão como abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


begin
ShowMessage('Largura: ' + IntToStr(Screen.Width) + #13 +
'Altura: ' + IntToStr(Screen.Height));
end;
Observações
O objeto Screen contém várias informações importantes: largura e altura da tela, fontes instaladas
no Windows, etc.

Verificar se uma unidade de disco (disk-drive) está preparada

Inclua na seção uses: System, SysUtils

{ - Crie um novo projeto;


- Na seção implementation da Unit1 digite a função abaixo: }

function DriveOk(Drive: Char): boolean;


var
I: byte;
begin
Drive := UpCase(Drive);
if not (Drive in ['A'..'Z']) then
raise Exception.Create('Unidade incorreta');
I := Ord(Drive) - 64;
Result := DiskSize(I) >= 0;
end;

{ - Coloque no Form1 um TEdit (Edit1)


- Coloque no Form1 um TButton
- Altere o evento OnClick do Button1 conforme abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


begin
if DriveOk(Edit1.Text[1]) then
ShowMessage('Drive OK')
else
ShowMessage('Drive não preparado');
end;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 210 de 272

Observações
Para testar você deverá executar o exemplo e digitar no Edit a letra do drive a ser testado (não
precisa os dois-pontos). Após digitar, clique no Button1.

Salvar/restaurar o tamanho e posição de Form's

{ Crie uma nova Unit conforme abaixo: }


unit uFormFunc;

interface
uses Forms, IniFiles, SysUtils, Messages, Windows;

procedure tbLoadFormStatus(Form: TForm; const Section: string);


procedure tbSaveFormStatus(Form: TForm; const Section: string);

implementation

procedure tbSaveFormStatus(Form: TForm; const Section: string);


var
Ini: TIniFile;
Maximized: boolean;
begin
Ini := TIniFile.Create(ChangeFileExt(
ExtractFileName(ParamStr(0)),'.INI'));
try
Maximized := Form.WindowState = wsMaximized;
Ini.WriteBool(Section, 'Maximized', Maximized);
if not Maximized then begin
Ini.WriteInteger(Section, 'Left', Form.Left);
Ini.WriteInteger(Section, 'Top', Form.Top);
Ini.WriteInteger(Section, 'Width', Form.Width);
Ini.WriteInteger(Section, 'Height', Form.Height);
end;
finally
Ini.Free;
end;
end;

procedure tbLoadFormStatus(Form: TForm; const Section: string);


var
Ini: TIniFile;
Maximized: boolean;
begin
Maximized := false; { Evita msg do compilador }
Ini := TIniFile.Create(ChangeFileExt(
ExtractFileName(ParamStr(0)),'.INI'));
try
Maximized := Ini.ReadBool(Section, 'Maximized', Maximized);
Form.Left := Ini.ReadInteger(Section, 'Left', Form.Left);
Form.Top := Ini.ReadInteger(Section, 'Top', Form.Top);
Form.Width := Ini.ReadInteger(Section, 'Width', Form.Width);
Form.Height := Ini.ReadInteger(Section, 'Height', Form.Height);
if Maximized then
Form.Perform(WM_SIZE, SIZE_MAXIMIZED, 0);
{ A propriedade WindowState apresenta Bug. Por isto usei a mensagem WM_SIZE }
finally
Ini.Free;
end;
end;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 211 de 272

end.

{ Em cada formulário que deseja salvar/restaurar:


- Inclua na seção uses: uFormFunc
- No evento OnShow digite:
tbLoadFormStatus(Self, Self.Name);
- No evento OnClose digite:
tbSaveFormStatus(Self, Self.Name);}
Observações
O arquivo INI terá o nome do executável e extensão INI e será salvo no diretório do Windows. A
palavra Self indica o Form relacionado com a unit em questão. Poderia ser, por exemplo, Form1,
Form2, etc. Onde aparece Self.Name poderá ser colocado um nome a sua escolha. Este nome será
usado como SectionName no arquivo INI e deve ser idêntico no evento OnShow e OnClose de um
mesmo Form, porém para cada Form deverá ser usado um nome diferente.

Definir a quantidade de registros a ser impressa em uma página do QuickReport

Ou seja, gostaria que, ao visualizar ou imprimir um relatório do Quick Report, saia em cada página
apenas um registro, mesmo que o espaço permita mais de um.

Existem pelo menos duas formas de resolver este problema:

1. A forma mais simples consiste em alterar a altura (Height) da banda Detail do nosso relatório de
modo que a altura total da página seja inferior a duas vezes a altura da banda. Desta forma, cada
registro será impresso em uma nova página, teoricamente por falta de espaço na página atual.

2. Uma outra forma mais sofisticada é usar o evento AfterPrint da banda Detail. Nele testamos se
ainda não chegou no fim da tabela e, caso positivo, pedimos uma nova página:

if not Table1.EOF then


QuickRep1.NewPage;

Deve existir outras alternativas, mas as duas anteriores funcionaram bem nos testes realizados.

Onde encontrar tutoriais sobre construção de componentes em Delphi

Pegue apostila no download.

Para que servem OnGetEditMask, OnGetEditText e OnSetEditText do TStringGrid

O evento OnGetEditMask ocorre quando entramos no modo de edição. Neste momento podemos
verificar em qual linha/coluna se encontra o cursor e então, se quiser, poderá especificar uma
máscara de edição. Exemplo:

procedure TForm1.StringGrid1GetEditMask(Sender: TObject; ACol,


ARow: Integer; var Value: String);
begin
if (ARow = 1) and (ACol = 1) then
Value := '(999) 999-9999;1;_'; // Telefone
end;

O evento OnGetEditText ocorre também quando entramos no modo de edição. Neste momento
podemos manipularmos o texto da célula atual (linha/coluna) e então podemos simular algo tal
como uma tabela onde opções podem ser digitadas através de números. Exemplo:

procedure TForm1.StringGrid1GetEditText(Sender: TObject; ACol,


ARow: Integer; var Value: String);
begin
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 212 de 272

if (ARow = 1) and (ACol = 2) then begin


if StringGrid1.Cells[ACol, ARow] = 'Ótimo' then
Value := '1'
else if StringGrid1.Cells[ACol, ARow] = 'Regular' then
Value := '2'
else if StringGrid1.Cells[ACol, ARow] = 'Ruim' then
Value := '3';
end;
end;

O evento evento OnSetEditText ocorre quando saímos do modo de edição. Neste momento
podemos manipular a entrada e trocar por um texto equivalente. Normalmente usamos este evento
em conjunto com o evento OnGetEditText. Exemplo:

procedure TForm1.StringGrid1SetEditText(Sender: TObject; ACol,


ARow: Integer; const Value: String);
begin
if (ARow = 1) and (ACol = 2) then begin
if Value = '1' then
StringGrid1.Cells[ACol, ARow] := 'Ótimo'
else if Value = '2' then
StringGrid1.Cells[ACol, ARow] := 'Regular'
else if Value = '3' then
StringGrid1.Cells[ACol, ARow] := 'Ruim'
end;
end;
Observações
Para testar o exemplo anterior crie um novo projeto e coloque no Form1 um TStringGrid. Mude os
três eventos mencionados conforme os exemplos. Execute e experimente digitar nas céluas 1 e 2 da
primeira linha (na parte não fixada, é claro!).

Mostrar um Form de LogOn antes do Form principal

{ * Crie um novo Projeto. Este certamente terá o Form1.


* Adicione um novo Form (Form2).
* Coloque no Form2 dois botões TBitBtn.
* Mude a propriedade Kind do BitBtn1 para bkOK.
* Mude a propriedade Kind do BitBtn2 para bkCancel.
* Vá no menu "Project/Options" na aba "Forms" e passe o
Form2 de "Auto-create Forms" para "Available Forms".
* Abra o arquivo Project.dpr (menu Project/View Source).
* Altere o conteúdo deste arquivo conforme abaixo:}

program Project1;

uses
Forms, Controls,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2};

{$R *.RES}

var
F: TForm2;

begin
F := TForm2.Create(Application);
try
if F.ShowModal = mrOK then begin
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 213 de 272

Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end;
finally
F.Free;
end;
end.
Observações
O Form2 do exemplo é o Form de LogOn. Este deverá ser preparado para que se possa escolher o
usuário, digitar a senha, etc.

Limitar a região de movimentação do mouse

Inclua na seção uses: Windows

{ Coloque um botão no form e altera o evento OnClick dele


conforme abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


var
R: TRect;
begin
{ Pega o retângulo da área cliente do form }
R := GetClientRect;
{ Converte as coordenadas do form em coordenadas da tela }
R.TopLeft := ClientToScreen(R.TopLeft);
R.BottomRight := ClientToScreen(R.BottomRight);
{ Limita a região de movimentação do mouse }
ClipCursor(@R);
ShowMessage('Tente mover o mouse para fora da área cliente do Form');
{ Libera a movimentação }
ClipCursor(nil);
end;
Observações
Cuidado! Isto pode irritar o usuário do seu programa.

Descobrir o nome de classe de uma janela do Windows

Muitas vezes precisamos saber qual o nome de classe de uma determinada janela. Quando são
janelas desenvolvidas por nós, você olha no código-fonte. Mas e se não for, como é o caso do
Delphi?

Por exemplo:

Para verificar se o Delphi está sendo executado, procuramos no Windows pela janela cujo nome de
classe seja TAppBuilder. Mas como verificar então se o Internet Explorer está sendo executado?
Precisaremos saber o nome de classe da janela deste programa. Então o que fazer?

Use o TBWinName. Pegue-o no download de www.ulbrajp.com.br/usuario/tecnobyte

Ocultar/exibir a barra de tarefas do Windows

Inclua na seção uses: Windows

{ Coloque no Form dois Botões: BotaoOcultar e BotaoExibir. No evento OnClick do


BotaoOcultar escreva: }

procedure TForm1.BotaoOcultarClick(Sender: TObject);


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 214 de 272

var
Janela: HWND;
begin
Janela := FindWindow('Shell_TrayWnd', nil);
if Janela > 0 then
ShowWindow(Janela, SW_HIDE);
end;

{ No evento OnClick do BotaoExibir escreva: }

procedure TForm1.BotaoExibirClick(Sender: TObject);


var
Janela: HWND;
begin
Janela := FindWindow('Shell_TrayWnd', nil);
if Janela > 0 then
ShowWindow(Janela, SW_SHOW);
end;

{ Execute e teste, clicando em ambos os botões }


Observações
A tarefa mais difícil é descobrir o nome de classe da janela da barra de tarefa do Windows, mas
isto é fácil se você usar o TBWinName. Pegue-o no link download de
www.ulbrajp.com.br/usuario/tecnobyte O resto é usar as APIs do Windows para manipulação de
Janelas. Veja a pergunta nº 18.

Evitar a proteção de tela durante seu programa

Inclua na seção uses: Windows

{ Na seção "private" do Form principal acrescente: }


procedure AppMsg(var Msg: TMsg; var Handled: Boolean);

{ Na seção "implementation" acrescente (troque TForm1 para


o nome do seu form principal): }
procedure TForm1.AppMsg(var Msg: TMsg; var Handled: Boolean);
begin
if (Msg.Message = wm_SysCommand) and
(Msg.wParam = sc_ScreenSave) then
Handled := true;
end;

{ No evento "OnCreate" do form principal, coloque: }


Application.OnMessage := AppMsg;

Fazer a barra de título ficar intermitente (piscante)

Inclua na seção uses: Windows

{ Coloque um TTimer no Form desejado. Define a propriedade Interval do Timer para 1000
(1segundo). Modifique o evento OnTimer do Timer conforme abaixo: }

procedure TForm1.Timer1Timer(Sender: TObject);


begin
FlashWindow(Handle, true);
FlashWindow(Application.Handle, true);
end;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 215 de 272

Posicionar o cursor do mouse em um controle

Inclua na seção uses: Windows

{ Digite a procedure abaixo imediatamente após a palavra implementation no código do seu


formulário. }

procedure MouseParaControle(Controle: TControl);


var
IrPara: TPoint;
begin
IrPara.X := Controle.Left + (Controle.Width div 2);
IrPara.Y := Controle.Top + (Controle.Height div 2);
if Controle.Parent <> nil then
IrPara := Controle.Parent.ClientToScreen(IrPara);
SetCursorPos(IrPara.X, IrPara.Y);
end;

{ Para testar, coloque no Form um botão e troque o name dele para btnOK e modifique o evento
OnShow do Form conforme abaixo: }

procedure TForm1.FormShow(Sender: TObject);


begin
MouseParaControle(btnOk);
end;
Observações
A função "MouseParaControle" recebe um parâmetro do tipo TControl. Isto significa que você
poderá passar para ela qualquer controle do Delphi, tais como: TEdit, TButton, TSpeedButton,
TPanel, etc. Pode ser até mesmo o próprio Form.

Criar cores personalizadas (sistema RGB)

{ Coloque um TButton no form e escreva o evento OnClick deste como abaixo: }


procedure TForm1.Button1Click(Sender: TObject);
var
Vermelho, Verde, Azul: byte;
MinhaCor: TColor;
begin
Vermelho := 0;
Verde := 200;
Azul := 150;
MinhaCor := TColor(RGB(Vermelho, Verde, Azul));
Form1.Color := MinhaCor;
end;
Observações
A quantidade de cada cor primária é um número de 0 a 255. Observe que a cor retornada pela
função RGB() está no formato do Windows (ColorRef); é por isto que fiz a conversão
TColor(RGB(...)).

Adicionar uma nova fonte no Windows

{ Coloque o código abaixo no OnClick de um botão }


AddFontResource(PChar('c:\MyFonts\Monospac.ttf'));
Observações
Troque o nome do arquivo do exemplo anterior pelo nome desejado. Arquivos de fonte possuem
uma das seguintes extensões: FON, FNT, TTF, FOT. Veja também a pergunta nº 10.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 216 de 272

Saber se a impressora atual possui determinada fonte

Inclua na seção uses: Printers

{ Coloque este código no OnClick de um botão }


with Printer.Fonts do
if IndexOf('Draft 10cpi') >= 0 then
ShowMessage('A impressora possui a fonte.')
else
ShowMessage('A impressora NÃO possui a fonte.');
Observações
Isto pode ser útil quando queremos usar fonte da impressora quando for uma matricial ou fonte do
Windows quando for uma Jato de Tinta ou Laser. Veja também a pergunta nº 10.

Saber se determinada Font está instalada no Windows

{ Coloque este código no OnClick de um botão }


with Screen.Fonts do
if IndexOf('Courier New') >= 0 then
ShowMessage('A fonte está instalada.')
else
ShowMessage('A fonte não está instalada.');
Observações
Veja também a pergunta nº 11.

Acertar a data e hora do sistema através do programa

{ Coloque dois TEdit no form.


Coloque um TButton no form e altere o evento OnClick
deste botão como abaixo:}
procedure TForm1.Button1Click(Sender: TObject);
var
DataHora: TSystemTime;
Data, Hora: TDateTime;
Ano, Mes, Dia,
H, M, S, Mil: word;
begin
Data := StrToDate(Edit1.Text);
Hora := StrToTime(Edit2.Text);
DecodeDate(Data, Ano, Mes, Dia);
DecodeTime(Hora, H, M, S, Mil);
with DataHora do begin
wYear := Ano;
wMonth := Mes;
wDay := Dia;
wHour := H;
wMinute := M;
wSecond := S;
wMilliseconds := Mil;
end;
SetLocalTime(DataHora);
end;
Observações
No Edit1 digite a nova data e no Edit2 digite a nova hora.

ENTER em vez de TAB no formulário, no DBGrid e no StringGrid

{ Mude a propriedade "KeyPreview" do Form para true. }


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 217 de 272

{ No evento "OnKeyPress" do Form acrescente o código abaixo: }

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);


begin
if Key = #13 then begin
Key := #0;
Perform(WM_NEXTDLGCTL, 1, 0);
end;
end;

{ Em StringGrid, escreva o evento OnKeyPress como abaixo: }

procedure TForm1.StringGrid1KeyPress(Sender: TObject; var Key: Char);


begin
if Key = #13 then
StringGrid1.Perform(WM_KEYDOWN, VK_TAB, 0);
end;

{ Em DBGrid, escreva o evento OnKeyPress como abaixo: }

procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);


begin
if Key = #13 then
DBGrid1.Perform(WM_KEYDOWN, VK_TAB, 0);
end;
Observações
É bom lembrar que a tecla ENTER no Windows tem seu papel já bem definido quando se trata de
caixa de diálogo: executar a ação padrão, normalmente o botão OK. Se não tomar cuidado poderá
confundir o usuário, em vez de ajudá-lo.

Simular a vírgula através do ponto do teclado numérico

{ Na seção "private" do Form principal acrescente: }


procedure AppMsg(var Msg: TMsg; var Handled: Boolean);

{ Na seção "implementation" acrescente (troque TForm1 para o nome do seu form principal): }
procedure TForm1.AppMsg(var Msg: TMsg; var Handled: Boolean);
begin
if Msg.Message = WM_KEYDOWN then
if Msg.wParam = 110 then
Msg.wParam := 188;
end;

{ No evento "OnCreate" do form principal, coloque: }


Application.OnMessage := AppMsg;

{ Uma segunda alternativa (José Geraldo - ES):


Coloque o código abaixo no evento OnKeyPress do componente onde se quer a conversão (Edit,
DBEdit, etc). Neste caso a conversão funcionará apenas neste componente (óbvio). }

if Key = '.' then Key = DecimalSeparator;


Observações
Na primeira alternativa, sempre que for pressionado o ponto do teclado numérico (da direita do
teclado), este será convertido para vírgula, independentemente do controle que estiver em foco. Já
na segunda, o ponto pode ser de qualquer lugar do teclado.

Paralizar um programa durante n segundos

Inclua na seção uses: Windows


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 218 de 272

{ Pausa por 1 segundo }


Sleep(1000);

{ Pausa por 10 segundos }


Sleep(10000);
Observações
Esta pausa não é interrompida pelo pressionamento de alguma tecla, como acontecia com InKey()
do Clipper.

Criar uma tabela (DB, DBF) através do seu programa

Inclua na seção uses: dbTables, DB

procedure CriaTabelaClientes;
var
Tabela: TTable;
begin
Tabela := TTable.Create(Application);
try
Tabela.DatabaseName := 'C:\';
{ ou Tabela.DatabaseName := 'NomeAlias'; }

Tabela.TableName := 'Clientes.DB';
Tabela.TableType := ttParadox; { ou ttDBase }

{ Somente Delphi4 }
if Tabela.Exists then { Se a tabela já existe... }
Exit;
{***}

{ Cria a tabela }
Tabela.FieldDefs.Add('Codigo', ftInteger, 0, true);
Tabela.FieldDefs.Add('Nome', ftString, 30, true);
Tabela.FieldDefs.Add('DataNasc', ftDate, 0, false);
Tabela.FieldDefs.Add('RendaMes', ftCurrency, 0, false);
Tabela.FieldDefs.Add('Ativo', ftBoolean, 0, true);
{ etc, etc, etc }
Tabela.CreateTable;

{ Cria os Índices }
Tabela.AddIndex('ICodigo', 'Codigo', [ixPrimary, ixUnique]);
Tabela.AddIndex('INome', 'Nome', [ixCaseInsensitive]);
{ etc, etc, etc }
finally
Tabela.Free;
end;
end;
Observações
Para verificar se o arquivo já existe na versão 3 ou anterior do Delphi, você deverá usar a função
"FileExists" do Delphi.

Verificar se um diretório existe

Inclua na seção uses: FileCtrl, Dialogs

if DirectoryExists('C:\MEUSDOCS') then
ShowMessage('O diretório existe')
else
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 219 de 272

ShowMessage('O diretório não existe');

Verificar se um arquivo existe

Inclua na seção uses: SysUtils, Dialogs

if FileExists('c:\carta.doc') then
ShowMessage('O arquivo existe')
else
ShowMessage('O arquivo não existe');

Criar um Alias temporário através do seu programa

Inclua na seção uses: DB

{ Enxergar somente configurações da sessão atual }


Session.ConfigMode := cmSession;
{ Adicionar o Alias }
Session.AddStandardAlias('MeuAlias', 'C:\DirProg', 'PARADOX');

Criar um Alias através do seu programa

Inclua na seção uses: DB

{ se o alias não existir... }


if not Session.IsAlias('MeuAlias') then
begin
{ Adiciona o alias }
Session.AddStandardAlias('MeuAlias', 'C:\DirProg', 'PARADOX');
{ Salva o arquivo de configuração do BDE }
Session.SaveConfigFile;
end;
Observações
Para criar um alias do dBase troque a string 'PARADOX' por 'DBASE'. No caso acima usei como
path o caminho "C:\DirProg", mas se você quiser poderá trocar este caminho por
ExtractFilePath(ParamStr(0)) para que o alias seja direcionado para o local onde está seu .EXE.
Neste último caso será necessário incluir na seção uses: SysUtils, System.

Icone na Barra de Tarefas

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs ,ShellAPI, Menus;

const
wm_IconMessage = wm_User;

type
TForm1 = class(TForm)
PopupMenu1: TPopupMenu;
Lloyd1: TMenuItem;
close1: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure close1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Lloyd1Click(Sender: TObject);
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 220 de 272

private
procedure IconTray (var Msg: TMessage);
message wm_IconMessage;
{ Private declarations }
public
{ Public declarations }
nid: TNotifyIconData;
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);


begin
// carrega o ícone inicial
Icon.Handle := LoadIcon (HInstance, 'MAINICON');
// preenche os dados da estrutura NotifyIcon
nid.cbSize := sizeof (nid);
nid.wnd := Handle;
nid.uID := 1; // Identificador do ícone
nid.uCallBAckMessage := wm_IconMessage;
nid.hIcon := Icon.Handle;
nid.szTip := 'LloydSoft';
nid.uFlags := nif_Message or
nif_Icon or nif_Tip;
Shell_NotifyIcon (NIM_ADD, @nid);
end;

procedure TForm1.IconTray (var Msg: TMessage);


var
Pt: TPoint;
begin
if Msg.lParam = wm_rbuttondown then
begin
GetCursorPos (Pt);
// SetForegroundWindow (Handle);
PopupMenu1.Popup (Pt.x, Pt.y);
end;
end;

procedure TForm1.close1Click(Sender: TObject);


begin
form1.close;
end;

procedure TForm1.FormDestroy(Sender: TObject);


begin
nid.uFlags := 0;
Shell_NotifyIcon (NIM_DELETE, @nid);
end;
procedure TForm1.Lloyd1Click(Sender: TObject);
begin
Showmessage('LloydSoft é D+'); {Menu Popup}
end;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 221 de 272

end.

Icone na Barra de Tarefas

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs ,ShellAPI, Menus;

const
wm_IconMessage = wm_User;

type
TForm1 = class(TForm)
PopupMenu1: TPopupMenu;
Lloyd1: TMenuItem;
close1: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure close1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Lloyd1Click(Sender: TObject);

private
procedure IconTray (var Msg: TMessage);
message wm_IconMessage;
{ Private declarations }
public
{ Public declarations }
nid: TNotifyIconData;
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);


begin
// carrega o ícone inicial
Icon.Handle := LoadIcon (HInstance, 'MAINICON');
// preenche os dados da estrutura NotifyIcon
nid.cbSize := sizeof (nid);
nid.wnd := Handle;
nid.uID := 1; // Identificador do ícone
nid.uCallBAckMessage := wm_IconMessage;
nid.hIcon := Icon.Handle;
nid.szTip := 'LloydSoft';
nid.uFlags := nif_Message or
nif_Icon or nif_Tip;
Shell_NotifyIcon (NIM_ADD, @nid);
end;

procedure TForm1.IconTray (var Msg: TMessage);


var
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 222 de 272

Pt: TPoint;
begin
if Msg.lParam = wm_rbuttondown then
begin
GetCursorPos (Pt);
// SetForegroundWindow (Handle);
PopupMenu1.Popup (Pt.x, Pt.y);
end;
end;

procedure TForm1.close1Click(Sender: TObject);


begin
form1.close;
end;

procedure TForm1.FormDestroy(Sender: TObject);


begin
nid.uFlags := 0;
Shell_NotifyIcon (NIM_DELETE, @nid);
end;

procedure TForm1.Lloyd1Click(Sender: TObject);


begin
Showmessage('LloydSoft é D+'); {Menu Popup}
end;
end.

Abrir arquivos com aplicativo associado

Inclua a unit SHELLAPI na clausula uses do seu form.

procedure TForm1.ExecFile(F: String);


var
r: String;
begin
case ShellExecute(Handle, nil, PChar(F), nil, nil, SW_SHOWNORMAL) of
ERROR_FILE_NOT_FOUND: r := 'The specified file was not found.';
ERROR_PATH_NOT_FOUND: r := 'The specified path was not found.';
ERROR_BAD_FORMAT: r := 'The .EXE file is invalid (non-Win32 .EXE or error in .EXE
image).';
SE_ERR_ACCESSDENIED: r := 'Windows 95 only: The operating system denied access to the
specified file.';
SE_ERR_ASSOCINCOMPLETE: r := 'The filename association is incomplete or invalid.';
SE_ERR_DDEBUSY: r := 'The DDE transaction could not be completed because other DDE
transactions were being processed.';
SE_ERR_DDEFAIL: r := 'The DDE transaction failed.';
SE_ERR_DDETIMEOUT: r := 'The DDE transaction could not be completed because the request
timed out.';
SE_ERR_DLLNOTFOUND: r := 'Windows 95 only: The specified dynamic-link library was not
found.';
SE_ERR_NOASSOC: r := 'There is no application associated with the given filename extension.';
SE_ERR_OOM: r := 'Windows 95 only: There was not enough memory to complete the
operation.';
SE_ERR_SHARE: r := 'A sharing violation occurred.';
else
Exit;
end;
ShowMessage(r);
end;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 223 de 272

Utilize a função assim:

procedure TForm1.Button1Click(Sender: TObject);


begin
ExecFile('c:\windows\ladrilhos.bmp');
end;

Adiciona a barra invertida a um texto selecionado

function AddBarra(S: string): string;


var
Temp: string;
begin
Temp := S;
if S[Length(Temp)] <> '\' then
Temp := Temp + '\';
Result := Temp;
end;

Apagar um subdiretório

Inclua a unit SHELLAPI na clausula uses do seu form.

procedure DeleteDir( hHandle : THandle; Const sPath : String );


var
OpStruc: TSHFileOpStruct;
FromBuffer, ToBuffer: Array[0..128] of Char;
begin
fillChar( OpStruc, Sizeof(OpStruc), 0 );
FillChar( FromBuffer, Sizeof(FromBuffer), 0 );
FillChar( ToBuffer, Sizeof(ToBuffer), 0 );
StrPCopy( FromBuffer, sPath);
With OpStruc Do
Begin
Wnd:= hHandle;
wFunc:=FO_DELETE;
pFrom:= @FromBuffer;
pTo:= @ToBuffer;
fFlags:= FOF_NOCONFIRMATION;
fAnyOperationsAborted:=False;
hNameMappings:=nil;
//lpszProgressTitle:=nil;
End;
ShFileOperation(OpStruc);
end;

Utilize a função assim:

procedure TForm1.Button1Click(Sender: TObject);


begin
DeleteDir( Self.Handle,'C:\TESTE');
end;

Como verificar se um arquivo existe?

If not(fileexists('c:\windows\nuvens.bmp')) then Showmessage('Arquivo inexistente');


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 224 de 272

Compara dois arquivos textos

procedure TForm1.Button1Click(Sender: TObject);


var
filename1 : string;
filename2 : string;
begin
filename1 := Edit1.Text;
filename2 := Edit2.Text;
compfile(filename1, filename2);
showmessage('Veja o resultado no arquivo c:Tempdiff.txt');
end;

procedure tform1.compfile(filename1, filename2 : string);


var
f1 : system.textfile;
f2 : system.textfile;
diff : system.textfile;
buf1 : string;
buf2 : string;
l : integer;
begin
assignfile(f1, filename1);
assignfile(f2, filename2);
assignfile(diff, 'c:Tempdiff.txt');
reset(f1);
reset(f2);
rewrite(diff);
l := 1;
while not eof(f1) do
begin
readln(f1, buf1);
readln(f2, buf2);
if not (compstr(buf1, buf2) )then
begin
writeln(diff, 'line: '+ inttostr(l) + '-' + buf1);
writeln(diff, 'line: '+ inttostr(l) + '-' + buf2);
writeln(diff, ' ');
end;
inc(l);
end;
closefile(f1);
closefile(f2);
closefile(diff);
end;

function tform1.compstr(s1, s2 : string) : boolean;


var
i : integer;
btemp : boolean;
begin
btemp := true;
if (length(s1) <> length(s2)) then begin
btemp := false;
end{if}
else begin
for i:= 1 to length(s1) do begin
if (s1[i] <> s2[i]) then begin
btemp := false;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 225 de 272

exit;
end;{if}
end;{for}
end;{else}
result := btemp;
end;

Copiando arquivos de diretório para diretório

procedure CopyDir(const cFrom, cTo : string);


var
OpStruc : TSHFileOpStruct;
frombuf, tobuf : array[0..128] of Char;
begin
FillChar(frombuf, Sizeof(frombuf), 0);
FillChar(tobuf, Sizeof(tobuf), 0);
StrPCopy(frombuf, cFrom);
StrPCopy(tobuf, cTo);
with OpStruc do
begin
Wnd := Application.Handle;
wFunc := FO_COPY;
pFrom := @frombuf;
pTo := @tobuf;
fFlags := FOF_NOCONFIRMATION or FOF_RENAMEONCOLLISION;
fAnyOperationsAborted := False;
hNameMappings := nil;
lpszProgressTitle := nil;
end; // with
ShFileOperation(OpStruc);
end; // CopyDir

Copiando Um Arquivo Com Um Gauge

Muitas vezes, quando temos a necessidade de copiar um arquivo de um lugar para outro, é
interessante mostrar ao usuário o andamento da cópia.
Para tal, coloque em sua aplicação um gauge (optei por um gauge, mas poderia muito bem ser uma
progressbar) e um botão para iniciar a cópia. No código onClick do botão, coloque este código.
Neste exemplo, o programa cria um diretório de back-up cujo nome do mesmo é a data da cópia no
formato AAAAMMDD. No nosso exemplo, chamei o gauge de ga_copia.

procedure Tfrm_Manut.bt_backupClick(Sender: TObject);


var
strArqOrigem, // Nome do arquivo de origem da cópia
strArqDestino: string; // Nome do arquivo de destino da cópia
wDia,wMes,wAno: Word;
begin
try
// Aciona o indicativo de progresso da cópia
ga_copia.Visible := True;
ga_copia.Progress := 0;
// Monta os nomes de arquivo - Primeiro recupera de um AdoConnection
// o nome do arquivo a ser copiado
strArqOrigem := dm_spark.ADO_Spark.Properties[7].Value;
// Agora vai montar o nome do arquivo de destino.
DecodeDate(Date, wAno, wMes, wDia);
strArqDestino := 'C:\prodata\copia\' + FormatFloat('0000', WAno);
strArqDestino := strArqDestino + FormatFloat('00', wMes);
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 226 de 272

strArqDestino := strArqDestino + FormatFloat('00', wDia);


strArqDestino := strArqDestino + '\' + ExtractFileName(strArqOrigem);
// Desconecta o banco de dados
dm_spark.ADO_Spark.Close;
Repaint;
// Inicia a cópia
CopyFile(strArqOrigem, strArqDestino);
finally
// Reconecta o banco de dados
dm_spark.ADO_Spark.Open;
ga_copia.Visible := False;
end;
end;

Agora que já definimos como e quando a cópia será disparada, vamos definir a procedure copyfile
que é o motor da nossa cópia de arquivo. Esta procedure é que vai fazer a cópia e incrementar o
Gauge.

procedure Tfrm_Manut.CopyFile(Source, Destination: string);


var
FromF,ToF: file of byte;
Buffer: array[0..4096] of char;
NumRead: Integer;
FileLength: LongInt;
NewPath: string;
begin
// Antes de copiar, verifica se já existe o diretório
// Caso o diretório não exista, o mesmo vai ser criado
NewPath := ExtractFilePath(Destination);
if not DirectoryExists(NewPath) then
begin
CreateDir(NewPath);
end
else
begin
if FileExists(Destination) then
begin
if Application.MessageBox('O arquivo-destino da cópia de segurança já existe ' + #13#10 +
'Deseja sobrepôr o mesmo com a nova cópia ?', 'Segurança',
MB_YESNO + MB_ICONQUESTION) = MRNO then
Exit;
end;
end;
// Copia o arquivo
// Abre o arquivo de origem e cria o arquivo destino
AssignFile(FromF, Source);
Reset(FromF);
AssignFile(ToF, Destination);
ReWrite(ToF);
FileLength := FileSize(FromF);
with ga_copia do
begin
MinValue := 0;
MaxValue := FileLength;
while FileLength > 0 do
begin
BlockRead(FromF, Buffer[0], SizeOf(Buffer), NumRead);
FileLength := FileLength - NumRead;
BlockWrite(ToF, Buffer[0], NumRead);
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 227 de 272

AddProgress(NumRead);
end;
CloseFile(FromF);
CloseFile(ToF);
end;
end;

Exibindo as propriedades do arquivo

A dica abaixo apresenta o código de implementação para exibir na tela uma janela padrão
Windows de propriedades do arquivo.

Para implementar este procedimento é necessário acrescentar a unit ShellAPI.As propriedades do


arquivo são armazenadas numa estrutura chamada TShellExecuteInfo, que corresponde a um
registro com os campos: tamanho do arquivo (cbSize), atributos (fMask), nome (lpFile) , shell
(lpVerb) e modo de apresentação da janela (nShow).O primeiro passo do procedimento é zerar
todas a propriedades da Shell ( FillChar(S,SizeOf(S),0) ), segundo passo é atualizar estas
propriedades (With S do ) em relação ao arquivo indicado (Arq :String) e o terceiro passo é abrir a
janela de propriedades com os valores atualizados (ShellExecuteEx(@S)).

Código Completo:

Procedure Propriedades(Arq:String);
Var
s:TShellExecuteInfo;
Begin
FillChar(S,SizeOf(S),0);
With S do Begin
cbSize := SizeOf(S);
fMask := SEE_MASK_FLAG_NO_UI or SEE_MASK_INVOKEIDLIST or
SEE_MASK_NOCLOSEPROCESS;
wnd := Handle;
lpVerb := 'properties';
lpFile := Pchar(Arq);
nShow := sw_ShowNormal;
End;
ShellExecuteEx(@S);
End;

Lendo e gravando arquivos de texto

Existem vários métodos em Delphi para gravar arquivos texto a partir de informações gravadas em
bases de dados ou para ler arquivos texto e armazená-los em bases de dados. Esta dica apresenta
um destes métodos: o uso de TextFiles.

TextFile é um tipo de dado pré-definido no Delphi e corresponde ao tipo Text do Turbo Pascal e
do Object Pascal.

Inicialmente para acessar um arquivo de texto, você precisa definir uma variável tipo TextFile, no
local que você achar mais apropriado, da seguinte forma:

var arq: TextFile;


Vamos precisar também de uma variável tipo string para armazenar cada linha lida do arquivo:

var linha: String;


Antes de se iniciar a leitura do arquivo, precisamos associar a variavel TextFile com um arquivo
fisicamente armazenado no disco:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 228 de 272

AssignFile ( arq, 'C:\AUTOEXEC.BAT' );


Reset ( arq );
A rotina AssignFile faz a associação enquanto Reset abre efetivamente o arquivo para leitura.
AssignFile corresponde à Assign do Turbo Pascal. Em seguida é necessário fazer uma leitura ao
arquivo, para isto utilizaremos a procedure ReadLn:

ReadLn ( arq, linha );


O comando acima lê apenas uma linha de cada vez, assim precisamos de um loop para efetuar
várias leituras até que o arquivo acabe. Para verificar o fim do arquivo, utilizaremos a função Eof:

while not Eof ( arq ) do


Agora uma rotina quase completa para fazer a leitura de um arquivo texto. Esta rotina recebe como
parâmetro o nome do arquivo que será lido:

procedure percorreArquivoTexto ( nomeDoArquivo: String );


var arq: TextFile;
linha: String;
begin
AssignFile ( arq, nomeDoArquivo );
Reset ( arq );
ReadLn ( arq, linha );
while not Eof ( arq ) do
begin
{ Processe a linha lida aqui. }
{ Para particionar a linha lida em pedaços, use a função Copy. }
ReadLn ( arq, linha );
end;
CloseFile ( arq );
end;
E também uma rotina quase completa para gravação de um arquivo texto. Esta rotina recebe como
parâmetro o nome do arquivo que será gravado e uma tabela (TTable) de onde os dados serão
lidos:

procedure gravaArquivoTexto ( nomeDoArquivo: String; tabela: TTable );


var arq: TextFile;
linha: String;
begin
AssignFile ( arq, nomeDoArquivo );
Rewrite ( arq );
tabela.First;
while not tabela.Eof do
begin
Write ( arq, AjustaStr ( tabela.FieldByName ( 'Nome' ).AsString, 30 ) );
Write ( arq, FormatFloat ( '00000000.00', tabela.FieldByName ( 'Salario' ).AsFloat ) );
WriteLn ( arq );
tabela.Next;
end;
CloseFile ( arq );
end;
Note nesta segunda rotina, a substituição de Reset por Rewrite logo após o AssignFile. Rewrite
abre o arquivo para escrita, destruindo tudo que houver lá anteriormente .

Note também o uso de Write e WriteLn para gravar dados no arquivo texto.

Finalmente note o uso de AjustaStr e FormatFloat para garantir que campos string e numericos
sejam gravados com um número fixo de caracteres. FormatFloat é uma rotina do próprio Delphi
enquanto AjustaStr está definida abaixo:

function AjustaStr ( str: String; tam: Integer ): String;


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 229 de 272

begin
while Length ( str ) < tam do
str := str + ' ';
if Length ( str ) > tam then
str := Copy ( str, 1, tam );
Result := str;
end;
O uso da função AjustaStr é fundamental quando você estiver gravando arquivos texto com
registros de tamanho fixo a partir de bases de dados Paradox que usualmente não preenchem
campos string com espaços no final.

Procurando um arquivo em todo o HD

interface

type
PRecInfo=^TRecInfo;
Trecinfo=record
prev:PRecInfo;
fpathname:string;
srchrec:Tsearchrec;
end;

implememtation

function TForm1.RecurseDirectory(fname:string):tstringlist;
var
f1,f2:Tsearchrec;
p1,tmp:PRecInfo;
fwc:string;
fpath:string;
fbroke1,fbroke2:boolean;
begin
result:=tstringlist.create;
fpath:=extractfilepath(fname);
fwc:=extractfilename(fname);
new(p1);
p1.fpathname:=fpath;
p1.prev:=nil;
fbroke1:=false;
fbroke2:=false;
while(p1<>nil) do
begin
if (fbroke1=false) then
if (fbroke2=false) then
begin
if (findfirst(fpath+'*',faAnyfile,f1)<>0) then
break;
end
else if (findnext(f1)<>0) then
begin
repeat
findclose(f1);
if (p1=nil) then
break;
fpath:=p1.fpathname;
f1:=p1.srchrec;
tmp:=p1.prev;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 230 de 272

dispose(p1);
p1:=tmp;
until (findnext(f1)=0);
if (p1=nil) then
break;
end;
if((f1.Name<>'.') and (f1.name<>'..') and ((f1.Attr and fadirectory)=fadirectory)) then
begin
fbroke1:=false;
new(tmp);
with tmp^ do
begin
fpathname:=fpath;
srchrec.Time:=f1.time;
srchrec.Size:=f1.size;
srchrec.Attr:=f1.attr;
srchrec.Name:=f1.name;
srchrec.ExcludeAttr:=f1.excludeattr;
srchrec.FindHandle:=f1.findhandle;
srchrec.FindData:=f1.FindData;
end;
tmp.prev:=p1;
p1:=tmp;
fpath:=p1.fpathname+f1.name+'\';
if findfirst(fpath+fwc,faAnyfile,f2)=0 then
begin
result.add(fpath+f2.Name);
while(findnext(f2)=0) do
result.add(fpath+f2.Name);
findclose(f2);
end;
fbroke2:=false;
end
else
begin
if (findnext(f1)<>0) then
begin
findclose(f1);
fpath:=p1.fpathname;
f1:=p1.srchrec;
fbroke1:=false;
fbroke2:=true;
tmp:=p1.prev;
dispose(p1);
p1:=tmp;
end
else
begin
fbroke1:=true;
fbroke2:=false;
end;
end;
end;
fpath:=extractfilepath(fname);
if findfirst(fname,faAnyfile,f1)=0 then
begin
result.add(fpath+f2.Name);
while(findnext(f1)=0) do
result.add(fpath+f2.Name);
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 231 de 272

findclose(f1);
end;
end;

//Chame a funcao deste jeito:

procedure TForm1.Button1Click(Sender: TObject);


var
l1:Tstringlist;
begin
l1:=tstringlist.create;
listbox1.items.clear;
listbox1.Items.BeginUpdate;
l1:=recursedirectory1('C:\*.exe');
listbox1.items.assign(l1);
freeandnil(l1);
listbox1.Items.endUpdate;
end;

Acessando o banco de dados Oracle a partir do Delphi


Em vista de muitos hoje possuírem sistemas rodando com banco de dados Oracle, resolvemos
publicar em detalhes todos passos necessários para se conectar a um banco Oracle a partir do
Delphi de modo nativo (usando BDE) e através do ODBC. Temos observado também que dúvidas
sobre este assunto estão sempre presentes nas listas de discussão sobre Delphi e sobre Oracle.

Utilizamos com bons resultados as versões do Delphi 2.0 até a 4.0, BDE versões 4.5 e 5.0, e o
Oracle7 Workgroup Server Release 7.3.2.1. Naturalmente tais informações serão de grande ajuda
para configuração em outras versões.

Passos:
1 - Caso tenha instalado em sua máquina algum cliente do Oracle 16 bits, poderá ter algum tipo de
conflito com drives de 32 bits. Portanto, desinstale todos os clientes Oracle e instale somente o
cliente Oracle 32 bits. Normalmente isto é feito a partir do CD de instalação do Oracle executando
o programa d:\win95\install\setup.exe

2 - Ao executar o instalador do cliente Oracle para Windows 95, você deverá de inicio informar o
idioma (o mesmo que foi informado durante a instalação do próprio banco), tendo o English como
padrão.

3 - Entre com o nome da empresa e o diretório onde serão armazenados os arquivos do cliente
Oracle.

4 - Será solicitado o tipo da instalação. Escolha a opção "Selective Products Install".

5 - Será apresentada uma lista dos produtos ou componentes disponíveis. Apesar de poder instalar
todos, serão apenas necessários para a conexão com o banco Oracle a partir do Delphi os seguintes
componentes:

Sql *Net Client (para criação do alias no cliente Oracle)

Oracle Installer (para instalar/remover componentes)

6 - Selecione os protocolos desejados para comunicação com o banco, ou poderá deixar


selecionado a sugestão do instalador e prosseguir.

7 - Após completar 100% da instalação, você visualizará os componentes instalados:

Oracle Installer
Oracle Named Pipes Adapter (protocolo de acordo com sua rede)
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 232 de 272

Oracle SPX Adapter (protocolo de acordo com sua rede)

Oracle TCP/IP Adapter (protocolo de acordo com sua rede)

Required Support Files

Sql *Net Client

8 - Saia do instalador. Não será necessário reiniciar a máquina por enquanto.

9 - Clique no botão iniciar -> programas -> Oracle for windows 95 -> Sql Net Easy Configuration

10 - Selecione "Add Database Alias", e clique OK

11 - Informe na sequência:

Database Alias (nome na sua máquina que representará o acesso ao banco)

Escolha o Protocolo (normalmente TCP/IP)

TCP/IP Host Name (informe o numero IP do servidor Oracle)

Database Instance (nome da instância do banco, consulte o DBA)

12 - Clique em "yes" e saia do Sql Net Easy Configuration

13 - Chame o BDE Administrator, e clique na guia Configuration -> Drivers ->Native e selecione
ORACLE. Como sugestão use as seguintes configurações:

VERSION
4.0
TYPE
SERVER
DLL32
SQLORA32.DLL
VENDOR INIT
ORA73.DLL
DRIVER FLAG
(DEIXAR VAZIO)
TRACE MODE
0
BATCH COUNT
200
BLOB SIZE
32
BLOBS TO CACHE
64
ENABLE BCD
FALSE
ENABLE INTEGERS
FALSE
ENABLE SCHEMA CACHE
FALSE
LANGDRIVER
(DEIXAR VAZIO)
LIST SYNONYMS
NONE
MAX ROWS
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 233 de 272

–1
NET PROTOCOL
TNS
OBJECT MODE
TRUE
OPEN MODE
READ/WRITE
ROWSET SIZE
20
SCHEMA CACHE DIR
(DEIXAR VAZIO)
SCHEMA CACHE SIZE
8
SCHEMA CACHE TIME
–1
SERVER NAME
(COLOQUE O NOME DA INSTANCIA DO BANCO, DEFAULT: ORCL)
SQLPASSTHRU MODE SHARED
AUTOCOMMIT
SQLQRYMODE
SERVER
USER NAME
(NOME DE USUARIO, OPCIONAL)

14 - Clique no item de menu Object -> Apply

15 - Agora precisamos apenas criar um Alias que será enxergado no Delphi. Para isso, clique na
guia Database, clique com o botão direito do mouse sobre o item da lista ´Databases´ e selecione a
opção ´New´. Escolha a opção ORACLE. Entre com o nome do Alias, que pode ser qualquer um
que não exista. Agora altere do lado esquerdo na guia Definition, no item SERVER NAME, e
coloque o nome do Database Alias que você criou no Sql Net Easy Configuration.

16 - Clique no item de menu Object -> Apply

17 - Reinicialize seu computador.

18 - Ok, agora basta abrir o Delphi e utilizar este Alias como qualquer outro!

Alterando o NetDir via programação:


Muitas vezes precisamos alterar o NetDir do BDE para que nossas aplicações funcionem
corretamente. E com poucas linhas de código você poderá deixar para que sua própria aplicação
faça isso.

Abaixo está uma rotina para alterar o NetDir de acordo com o drive informado como parâmetro:

uses BDE; // não esqueça de incluir esta unit

// ChangeNetDir
procedure ChangeNetDir(Drive: Char);
var
hCur: hDBICur;
Config: CFGDesc;
Cont: Boolean;
begin
if DbiInit(nil) = DBIERR_NONE then
begin
hCur := nil;
if DbiOpenCfgInfoList(nil, dbiREADWRITE, cfgPersistent,
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 234 de 272

'\DRIVERS\PARADOX\INIT', hCur) = DBIERR_NONE then


begin
if DbiSetToBegin(hCur) = DBIERR_NONE then
begin
Cont := True;
while Cont do
begin
if (DbiGetNextRecord(hCur, dbiWRITELOCK, @Config, nil)
<> DBIERR_NONE) then
Cont := False
else if StrIComp(Config.szNodeName, 'NET DIR') = 0 then
begin
StrPCopy(Config.szValue, Drive + ':\');
DbiModifyRecord(hCur, @Config, True);
Cont := False
end;
end;
end;
end;
DbiExit();
end;
end;
O uso deste procedimento pode ser assim:

procedure TForm1.Button1Click(Sender: TObject);


begin
ChangeNetDir('H');
end;

Apagando todos os registros da tabela

Para apagar os registros de uma tabela utiliza-se a função delete.

Através de um comando de repetição (While) é possível excluir todos os registros da tabela,


usando como flag a quantidade de registros existentes na tabela (RecordCount > 0).

Código Completo:

Procedure ApagarTodosReg(Origem:TDataSet);
Begin
With Origem do
While RecordCount > 0 do
Delete;
End;
Como Usar:

ApagarTodosReg(Table1);
ou ApagarTodosReg(Query1);

Armazanando sons, vídeos em bancos de dados

Um dos recursos mais interessantes nos bancos de dados atuais é a possibilidade de armazenar
recursos multimídia juntamente com outras informações. Dessa forma, é possível criar registros
com informações mais ricas sobre um determinado assunto. Por exemplo, pode-se armazenar
informações sobre um funcionário juntamente com a sua própria foto. No Paradox, por exemplo,
existe um tipo de campo destinado especialmente para esse fim.

No entanto, as possibilidades vão muito além do que o simples armazenamento de imagens. É


possível armazenar sons, filmes ou qualquer tipo de arquivo, usando o "obscuro" campo BLOB
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 235 de 272

(Binary Large Object), que permite que qualquer arquivo seja "embutido" no banco de dados. Na
verdade, o conteúdo do arquivo não é armazenado no registro em si, mas num arquivo separado
que é manipulado internamente pelo banco de dados.

Trabalhar com esse tipo de campo no Delphi é muito simples, mas não tão óbvio à primeira vista.
A manipulação de campos BLOB, diferentemente dos campos comuns, não deve ser feita
diretamente, mas sim por meio do objeto TBlobField, descendente do TField, que disponibiliza
recursos especiais para esse fim. Para isso, você deve sempre se referir ao campo BLOB no código
como sendo um TBlobField, utilizando typecasting.

Vamos supor que você tenha um arquivo de som MyWave.wav que será armazenado no campo
"SOM" da tabela "MyTable". Para carregar o conteúdo do arquivo no campo SOM, basta fazer
assim:

TBlobField(MyTable.FieldByName('SOM')).LoadFromFile('MeuWave.wav');
Neste exemplo, você usou o recurso de typecasting para manipular o campo como sendo um
objeto TBlobField, carregando o arquivo através do método LoadFromFile que existe nesse objeto.
Fácil, não é?

Se você quiser salvar o conteúdo do campo "SOM" no arquivo "MyWaveCopy.wav", basta fazer
assim:

TBlobField(MyTable.FieldByName('SOM')).SaveToFile('MyWaveCopy.60wav');
Para remover o conteúdo do campo "SOM" (limpá-lo), você também deve usar um método
apropriado:

TBlobField(MyTable.FieldByName('SOM')).Clear;
Para saber se o campo SOM possui algum conteúdo, use a propriedade IsNull:

with MyTable do
if not TBlobField(FieldByName('SOM')).IsNull then
TBlobField(FieldByName('SOM')).SaveToFile('MyWaveCopy.wav');
A maneira mais simples de utilizar o conteúdo de um campo BLOB já armazenado é primeiro
gravá-lo novamente em um arquivo em disco, usando o método SaveToFile, e depois manipulá-lo
normalmente. No caso de um conteúdo em formato wave, por exemplo, você deve primeiro gravá-
lo num arquivo .wav, e então reproduzí-lo através do TMediaPlayer ou pela função SndPlaySound.

Usando os mesmos métodos, você também pode armazenar e manipular filmes AVI,
apresentações, documentos, enfim, o que a sua imaginação mandar. Mas tenha em mente que o
armazenamento de arquivos de som ou outros tipos vai aumentar consideravelmente o tamanho do
seu banco de dados, por isso esse recurso deve ser utilizado com cuidado. Uma boa medida para
reduzir esse problema é compactar o arquivo antes de armazená-lo. Para utilizá-lo depois, basta
gerar o arquivo novamente em disco e descompactá-lo. Para saber quanto um campo BLOB está
ocupando num registro do seu arquivo, em bytes, use a propriedade BlobSize:

TBlobField(MyTable.FieldByName('SOM')).BlobSize;
Obs: Para armazenar imagens ou texto em formato RichText (RTF), use os tipos GRAPHIC e
FORMATED MEMO do Paradox, que são destinados a esses tipos de dados. O Delphi também
possui objetos para a manipulação desses campos: TGraphicField e TMemoField, ambos
descendentes do TBlobField.

Backup & Restauração

Para efetuar a cópia:

procedure TFormCopia.BitBtn1Click(Sender: TObject);


var
I: Integer;
begin
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 236 de 272

Database1.Connected:=True; // Database para controle


Table2.DatabaseName:=DirectoryListBox1.Directory; // Seleciona local de destino da cópia
with Session1 do
begin
Active:=True;
GetTableNames('AliasName','*.*',True,True,Memo1.Lines); // Retorna o nome das tabelas
end;
for I:= 0 to Memo1.Lines.Count - 1 do
begin
Table1.TableName:=Memo1.Lines[I]; // Tabela origem
Table2.TableName:=Memo1.Lines[I]; // Tabela destino
BatchMove1.Execute;
end;
end;
Para efetuar a restauração:

procedure TFormRestaura.BitBtn1Click(Sender: TObject);


var
I: Integer;
begin
Database1.Connected:=True;
Table2.DatabaseName:=DirectoryListBox1.Directory; // Origem da restauração
with Session1 do
begin
Active:=True;
GetTableNames(Table2.DatabaseName,'*.*',True,True,Memo1.Lines); // Retorna nomes das
tabelas
end;
for I:= 0 to Memo1.Lines.Count - 1 do
begin
Table1.TableName:=Memo1.Lines[I]; // Tabela origem

Table2.TableName:=Memo1.Lines[I]; // Tabela destino BatchMove1.Execute;


end;
end;

Após restaurar por este método, você deve recriar os índices.

Como acessar pelo Delphi, tabelas no Acess

Primeiro crie um alias apontando para o diretorio onde está o arquivo mdb do access, este
apontamento deve ser testado clicando no botão connectt. Se funcionar, pode fechar salvando o
novo alias. Caso contrário verifique se o diretório está correto e se o arquivo mdb existe neste
diretório.

Bem, após isso, vá no delphi, abra um projeto novo, coloque um componente tdatabase, uma
query, um datasource e um dbgrid. Após isso clique duas vezes no componente tdatabase, após
clicar, aparecerá um formulário, informe o nome que deseja dar ao database em name, em alias
name, clique na seta e escolha o alias criado anteriormente, depois clique em defaults, se quiser
uma senha para acesso ao banco, procure a palavra PASSWORD dentro da janela que foi
preenchida com comandos quando você clicou em defaults, e digite a senha desejada, se não quiser
senha deixe em branco. Após fazer isto, clique em OK. Bem, agora vá em propriedades do
tdatabase e clique em conectt, ele vai pedir um usuário e uma senha, se não colocou password,
basta clicar em ok que ele se conectará e caso tenha uma password digite-a. Uma vez conectado, vá
na query, na propriedade strings, coloque a instrução SELECT acessando a tabela que está dentro
do arquivo MDB. Veja bem, não é para colocar o arquivo mdb mas sim uma ou mais das tabelas
que estão dentro do MDB. Depois disso na propriedade database, escolha o nome que deu ao seu
database, se você fez tudo correto, o nome dele tem que estar na lista. Bom, agora active a query.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 237 de 272

Após isso vá no datasource e conecte-o á query, e depois vá no dbgrid e sete o datasource para o
datasource criado. Se fez tudo correto e se a tabela tiver dados, você os verá no dbgrid.

Como alterar o driver de acesso do access no bde automaticamente

procedure ChangeAccessDLL32(Dll : String); // Altera a Propriedade do


BDE\Drivers\Native\MSACCESS\Dll32
var
Reg : TRegistry;
begin
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.OpenKey('\Software\Borland\DataBase
Engine\Settings\Drivers\MSACCESS\INIT', True)
then Reg.WriteString('DLL32',Dll);
finally
Reg.CloseKey;
Reg.Free;
end;
end;

-------> Use de preferência no OnCreate do Form ou DataModule da seguinte

forma:

ChangeACCESSDll32('IDDA3532.DLL'); // Mudando a DLL de acesso ao ACCESS

Como converter DBF para Paradox e Acess para Paradox

A) ACCESS PARA PARADOX

DIGAMOS QUE VOCÊ TENHA UM BANCO DE DADOS EM ACCESS CHAMADO


DISCOTECA.MDB E QUE NELE TENHA VÁRIAS TABELAS, VAMOS CONVERTER
APENAS UMA, QUE NO NOSSO EXEMPLO SE CHAMA: AUTORES, E QUE SE
QUISESSEMOS CONVERTER OUTRAS O PROCEDIMENTO SERIA EXATAMENTE O
MESMO.

Abra o database desktop e crie um alias chamado DISCO, informe o drive desejado como
ACCESS, veja bem é ACCESS e não microsoft access drive, tá legal ???, depois no campo
database que se abriu bem abaixo, indique o diretorio onde se encontra o banco do access exemplo:
c:\discoteca\dados\discoteca.mdb, para testar e ver se está correto clique no botão conectt, se der
algum erro é porque não existe o caminho ou o arquivo mdb informado no campo database.

Uma vez que conectou, feche o alias e vá em file no menu da database desktop, clique em new e
depois em sql file, na janela que se abre digite select * from autores, uma vez que digitou a
instrução, clique no botão Query que está em cima há direita, ele tem um ponto de interrogação
preto, bom depois de clicar se abrirá uma tela, bem no meio tem table type com duas opções:
PARADOX E DBASE, ESCOLHA PARADOX, depois vá onde está table name bem no meio da
tela, digite o diretório e o nome do arquivo que quer que receba a tabela do access convertida,
pronto, quando fizer isso ela já estará convertida, com o nome que você deu com extensão db. Ou
seja você tem uma tabela paradox com os dados que estavam em autores dentro do banco do
access.

B) DBF PARA PARADOX

Abrir o database desktop, abra uma nova qbe e procure o diretorio onde está o dbf.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 238 de 272

Uma vez escolhido, clique nele, aparecerá um retangulo como quadrinhos ao lado de cada campo,
clique no primeiro quadrado que marcará todos automaticamente. Feito isso clique na paleta onde
está escrito Query e vá em propriedades, aparecerá um form onde você pode escolher entre
paradox ou dbase, escolha paradox e logo embaixo digite o diretorio e o nome da tabela que voce
quer criar, tecle o raizinho para rodar a query que então ele converterá para paradox.

Como importar dados de um arquivo texto para uma Tabela

var
sArquivo: TextFile;
Entrada, sArq2: string;
iLinha: integer;
begin
tblCep.Open;
tblCepLoc.Open;
bCancelaImport := False;
AssignFile(sArquivo, FileNameEdit1.FileName);
sArq2 := After('Cep_Loc.txt',FileNameEdit1.FileName);

iLinha := 0;
if FileNameEdit1.FileName = 'C:\Download\Ceps\Cep_loc.txt' then begin
// Arquivo de Localidades
RzProgressBar1.TotalParts := 0;
RzProgressBar1.TotalParts := NumLinhasArq(FileNameEdit1.FileName);

Reset(sArquivo);
Readln(sArquivo,Entrada);
while not Eoln(sArquivo) do begin
Inc(iLinha);
Readln(sArquivo,Entrada);

// 0 = Base Total e 2 = Inclusao


if (copy(Entrada,90,1) = '0') or (copy(Entrada,90,1) = '2') then
begin
tblCepLoc.Append;
tblCepLoc.FieldByName('cep_ChvLocal').AsString :=
copy(Entrada,1,6);
tblCepLoc.FieldByName('cep_Cidade').AsString :=
copy(Entrada,7,60);
tblCepLoc.FieldByName('cep_UF').AsString := copy(Entrada,75,2);
try
tblCepLoc.Post;
except
tblCepLoc.Cancel;
end;
end
else if (copy(Entrada,90,1) = '1') then begin // Exclusao
if tblCepLoc.Locate('cep_ChvLocal', copy(Entrada,1,6),
[loPartialKey]) then
tblCepLoc.Delete;
end
else if (copy(Entrada,90,1) = '3') then begin // Alteracao
if tblCepLoc.Locate('cep_ChvLocal', copy(Entrada,1,6),
[loPartialKey])
then begin
tblCepLoc.Edit;
tblCepLoc.FieldByName('cep_Cidade').AsString :=
copy(Entrada,7,60);
tblCepLoc.FieldByName('cep_UF').AsString :=
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 239 de 272

copy(Entrada,75,2);
end;
try
tblCepLoc.Post;
except
tblCepLoc.Cancel;
end;
end;
RzProgressBar1.PartsComplete := iLinha;
Application.ProcessMessages;
if bCancelaImport then
Break;
end;
CloseFile(sArquivo);
end;

Evitando o erro de Key Violation

A dica abaixo apresenta o código para evitar que o programa pare e envie uma mensagem padrão
de erro por Key Violation (Chave Primária).

Para isto, o código deve ser inserido no evento OnPostError do componente de banco de dados
(Table ou Query).

Toda vez que ocorrer um erro de gravação no banco de dados este evento será executado, sendo
que na variável de parâmetro "E" deste procedimento é armazenado a mensagem que será
apresentada na tela.

No caso de Key Violation a mensagem é exatamente esta: "Key violation.".

Para realizar um tratamento deste erro, testa-se se a mensagem ocorrida é "Key violation.', se for
verdadeiro o processo de gravação é abortado (Action := daAbort).

Código Completo:

Procedure TForm1.Table1PostError(DataSet: TDataSet; E: EDatabaseError;var Action:


TDataAction);
Var
ErroMens :String;
begin
ErroMens := E.Message;
if ErroMens = 'Key violation.' then begin ShowMessage('Chave Primária Inválida !');
action := daAbort;
end;
end;

Gravar imagem JPG em tabela Paradox

Procedure Grava_Imagem_JPEG(Tabela:TTable; Campo:TBlobField;


Foto:TImage; Dialog:TOpenPictureDialog);
var BS:TBlobStream;
MinhaImagem:TJPEGImage;
Begin
Dialog.InitialDir := 'c:\temp';
Dialog.Execute;
if Dialog.FileName <> '' Then
Begin
if not (Tabela.State in [dsEdit, dsInsert]) Then
Tabela.Edit;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 240 de 272

BS := TBlobStream.Create((Campo as TBlobField), BMWRITE);


MinhaImagem := TJPEGImage.Create;
MinhaImagem.LoadFromFile(Dialog.FileName);
MinhaImagem.SaveToStream(BS);
Foto.Picture.Assign(MinhaImagem);
BS.Free;
MinhaImagem.Free;
Tabela.Post;
DBISaveChanges(Tabela.Handle);
End;
End;

procedure TForm1.Button1Click(Sender: TObject);


begin
Grava_Imagem_JPEG(TbClientes,TbClientesCli_Foto, Image1,
OpenPictureDialog1);
// TbClientes é o nome de alguma Tabela
// TbClientesCli_Foto é um variavel da tabela do tipo Blob
// Image1 é um componente
// OpenPictureDialog1 é o componente para abrir a figura
end;

Ler imagem JPG da tabela Paradox

Procedure Le_Imagem_JPEG(Campo:TBlobField; Foto:TImage);


var BS:TBlobStream;
MinhaImagem:TJPEGImage;
Begin
if Campo.AsString <> '' Then
Begin
BS := TBlobStream.Create((Campo as TBlobField), BMREAD);
MinhaImagem := TJPEGImage.Create;
MinhaImagem.LoadFromStream(BS);
Foto.Picture.Assign(MinhaImagem);
BS.Free;
MinhaImagem.Free;
End
Else Foto.Picture.LoadFromFile('c:\temp\limpa.jpg');
End;

procedure TForm1.Button1Click(Sender: TObject);


begin
Le_Imagem_JPEG(TbClientesCli_Foto, Image1);
// TbClientesCli_Foto é um variavel da tabela do tipo Blob
// Image1 é um componente
end;

Listando os campos da tabela num Memo

A implementação da função abaixo permite inserir os campos de uma tabela num componente
TMemo.

Para que a função funcione é necessário que as units StdCtrls e DbTables tenham sido declaradas.

Os campos que serão listados, são aqueles que foram declarados através da operação de duplo
clique no componente Table e opção ADD Fields.

Código Completo:
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 241 de 272

Procedure ListaCampos(TB:Ttable;M:Tmemo);
Begin
M.Lines.Assign(TB.ListField);
End;
Exemplo:

Procedure TForm1.Button1Click(Sender:TObject);
Begin
ListaCampos(Table1,Memo1);
end;

PARADOX EM REDE

Arquivos Paradox podem ser compartilhados em rede. Para que isto ocorra devemos :

·Adicionar o DATABASE ENGINE CONFIGURATION (BDE CONFIG)

·Selecionar a página DRIVERS

·Selecionar o driver PARADOX e alterar o parâmetro NET DIR para o local onde serão gravados
os arquivos de controle para compartilhamento. Por exemplo, "G:\MEUAPLIC", onde G :
corresponde ao drive de rede e MEUAPLIC, o diretório aonde está o aplicativo (executável)

·Depois selecionar a página SYSTEM

·Alterar o parâmetro LOCAL SHARE para TRUE. Após isto o BDE controlará o
compartilhamento de arquivos PARADOX em rede

Alterando a fonte de determinado registro em um DBGrid

Para trocar a fonte de um DBGrid, utilize a rotina abaixo no evento OnDrawDataCell:

if Tabela.FieldByName ('Salario').Value >= 10000 then


begin
DbGrid1.Canvas.Font.Color := clRed;
DbGrid1.Canvas.Font.Style := [fsBold];
end;
DbGrid1.DefaultDrawDataCell(Rect, Field, State);
No caso, somente os registros com salário maior que R$ 10.000,00 ficarão com cor vermelha e
em negrito.

Nota: Não é necessário mover o ponteiro da tabela para colorir os registros.

Alterando cor de linha de um DBGrid

Coloque a propriedade defaultdrawdata do dbgrid em FALSE

No evento onDrawColumnCell do seu grid coloque o seguinte:

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject;


const
Rect: TRect; DataCol: Integer; Column: TColumn;
State: TGridDrawState);
begin
If table1PRAZO.Value > DATE then // condição
Dbgrid1.Canvas.Font.Color:= clFuchsia; // coloque aqui a cor desejada
Dbgrid1.DefaultDrawDataCell(Rect, dbgrid1.columns[datacol].field, State);
end;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 242 de 272

DbGrid Zebrado

O exemplo abaixo mostra como deixar cada linha do componente DBGrid de uma cor diferente,
dando assim um efeito zebrado. O controle é feito no evento OnDrawColumnCell.

unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Db, DBTables, Grids,
DBGrids, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
DBGrid1: TDBGrid;
Table1: TTable;
DataSource1: TDataSource;
procedure DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer;
Column: TColumn; State: TGridDrawState);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;

implementation
{$R *.DFM}

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol:


Integer; Column: TColumn; State: TGridDrawState);
begin
If odd(Table1.RecNo) then
begin
DBGrid1.Canvas.Font.Color:= clWhite;
DBGrid1.Canvas.Brush.Color:= clGreen;
end
else
begin
DBGrid1.Canvas.Font.Color:= clBlack;
DBGrid1.Canvas.Brush.Color:= clWhite;
end;
DBGrid1.Canvas.FillRect(Rect);
DBGrid1.Canvas.TextOut(Rect.Left+2,Rect.Top,Column.Field.AsString);
end;

Procura e substituição de string num campo memo

Procedure TForm1.Button1Click (Sender: TObject);


Begin
FindReplace(Edit1.Text,Edit2.Text, Memo1);
end;

Procedure FindReplace (const Enc, subs: String; Var Texto: TMemo);


Var
i, Posicao: Integer;
Linha: string;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 243 de 272

Begin
For i:= 0 to Texto.Lines.count - 1 do
begin
Linha := Texto. Lines[i];
Repeat
Posicao:=Pos(Enc,Linha);
If Posicao > 0 then
Begin
Delete(Linha,Posicao,Length(Enc));
Insert(Subs,Linha,Posicao);
Texto.Lines[i]:=Linha;
end;
until Posicao = 0;
end;
end;

Criando tabelas via SQL

Inclua na seção uses: dbTables

- Coloque um TButton no form;

- Escreve no OnClick do Button como abaixo:

procedure TForm1.Button1Click(Sender: TObject);


var
Q: TQuery;
begin
Q := TQuery.Create(Application);
try
Q.DatabaseName := 'SF';
with Q.SQL do begin
Add('Create Table Funcionarios');
Add('( Codigo AutoInc,');
Add(' Nome Char(30),');
Add(' Salario Money,');
Add(' Depto SmallInt,');
Add(' Primary Key (Codigo) )');
end;
Q.ExecSQL;
finally
Q.Free;
end;
end;
Observações
Este exemplo foi testado com banco de dados Paradox, porém deverá funcionar em vários outros
bancos de dados com pouca ou nenhuma alteração.

Sql relacionada com a primeira letra

query1.active := false;
query1.sql.clear;
query1.sql.add('select * from estrucpr where upper(portugues)like "LETRA%" ');
query1.active:= true;
PRIMEIRA LETRA "LETRA%"

ULTIMA LETRA "%LETRA"

QUE CONTENHA A LETRA "%LETRA%"


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 244 de 272

Consultar por mês de um campo data

Use uma Query como abaixo:

- Coloque no form os seguintes componentes:

* TQuery
* TDataSource
* TDBGrid
* TEdit
* TButton

- Altere as propriedades dos componentes como abaixo:

* Query1.DatabaseName = (alias do BDE)


* DataSource1.DataSet = Query1
* DBGrid1.DataSource = DataSource1

- Coloque o código abaixo no evento OnClick de Button1:

Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Add('select * from dCli');
Query1.SQL.Add('where extract(month from DataNasc) = :Mes');
Query1.ParamByName('Mes').AsInteger := StrToInt(Edit1.Text);
Query1.Open;
- Execute. Digite um número de 1 a 12 no Edit e clique no botão.

Observações

Os números de 1 a 12 representam, respectivamente, os meses de Janeiro a Dezembro. Este


exemplo foi testado com Delphi4, BDE5 e tabela Paradox7.

Colocar o mes por extenso

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
function MesExtenso( Mes:Word ) : string;
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 245 de 272

{$R *.DFM}

function TForm1.MesExtenso( Mês:Word ) : string; const meses : array[0..11] of PChar =


('Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro','Outubro',
'Novembro', 'Dezembro');
begin
result := meses[mes-1];
End;

procedure TForm1.Button1Click(Sender: TObject);


begin
label1.Caption := MesExtenso(3);
end;

end.

Como retornar quantidade de dias meses e anos entre duas datas

Procedure EntreDatas(DataFinal,DataInicial : TDate ; var Anos,Meses,Dias : Integer) ;

// Retorna a diferença em Dias,Meses e Anos entre 2 datas


Function Calcula(Periodo : Integer) : Integer ;
var
intCont : Integer ;
begin
intCont := 0 ;
Repeat
Inc(intCont) ;
DataFinal := IncMonth(DataFinal,Periodo * -1) ;
Until DataFinal < DataInicial ;
DataFinal := IncMonth(DataFinal,Periodo) ;
Inc(intCont,-1) ;
Result := intCont ;
End ;
begin
if DataFinal <= DataInicial then
begin
Anos := 0 ;
Meses := 0 ;
Dias := 0 ;
exit ;
end;
Anos := Calcula(12) ;
Meses := Calcula(1) ;
Dias := Round(DataFinal - DataInicial) ;
end;

Alinhar Panel Ao Centro do Formulário

procedure AlinharPanel(AForm: TForm; APanel: TPanel; ACentro: Boolean);


begin
if ACentro then
begin
APanel.Left := (AForm.ClientWidth div 2) - (APanel.Width div 2);
APanel.Top := (AForm.ClientHeight div 2) - (APanel.Height div 2);
end
else
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 246 de 272

begin
APanel.Left := (AForm.ClientWidth + 100);
APanel.Top := (AForm.ClientHeight + 100);
end;
APanel.Update;
AForm.Update;
end;

Coloração Gradiente no Form


procedure TForm1.FormPaint(Sender: TObject);
var
altura, coluna: Word;
begin
altura := (ClientHeight + 255) div 256;
for coluna := 0 to 255 do
with Canvas do
begin
Brush.Color := RGB(coluna, 0, 0); { Modifique para obter cores diferentes }
FillRect(Rect(0, coluna * altura, ClientWidth, (coluna + 1) * altura)) ;
end;
end;

procedure TForm1.FormResize(Sender: TObject);


begin
Invalidate;
end;

Como Criar Forms Em Tempo de Execução

Para você economizar memória, pode-se criar os forms de sua aplicação somente no momento da
execução. Na criação do Form você define se ele é MODAL ou NÃO MODAL. Para Isso observe
os seguintes códigos:

MODAL - Mostra form em modo exclusivo

procedure TForm1.Button1Click(Sender: TObject);


begin
Application.CreateForm(TForm2, Form2);{Carrega form na memória}
Form2.ShowModal;{Mostra form em modo exclusivo}
Form2.Free; {Libera Memória}
end;
NÃO MODAL - Mostra form em modo não exclusivo

procedure TForm1.Button1Click(Sender: TObject);


begin
Application.CreateForm(TForm2, Form2);{Carrega form na memória}
Form2.ShowModal;{Mostra form em modo exclusivo}
end;
No evento OnClose do Form2 coloque o seguinte código.

procedure TForm2.FormClose (Sender: Tobject; var Action : TCloseAction);


begin
Action:= caFree;
end;
Aliado a este código, você deve alterar no delphi, no menu Options, opção Project. Mudando os
forms a serem criados dinamicamente da coluna Auto-Create Forms para Avaliable Forms.

Como evitar efeito de maximização


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 247 de 272

Se você já desenvolveu uma aplicação MDI com um formulário MDIChild que tem que ser exibido
em estado Maximizado (WindowState=wsMaximized), provavelmente você já se deparou com
aquele deselegante problema em que o usuário acompanha a maximização do seu formulário. Para
evitar isto, faça o seguinte:

Antes de criar o seu formulário para a exibição, utilize LockWindowUpdate(Handle);


Após a criação do formulário, utilize LockWindowUpdate(0);
Com isto, você dará um efeito mais profissional às suas aplicações.

Exemplo:

procedure MainForm.ItemArqCadFor(Sender: TObject);


begin
LockWindowUpdate(Handle);
with TFrmCadFor.Create(self) do Show;
LockWindowUpdate(0);
end;

Como Saber se o aplicativo ja foi aberto

Como saber se o aplicativo já foi aberto

Insira o código abaixo dentro do arquivo .DPR de sua aplicação

{$R *.RES}
begin
Application.Title := '';
Application.HelpFile := '';
if HPrevInst = 0 then
begin
F_Splash := TF_Splash.create(Application);
F_Splash.Show;
Application.CreateForm(TF_Menu, F_Menu);
Application.CreateForm(TF_Error, F_Error);
Application.CreateForm(TF_Form1, F_From1);
Application.CreateForm(TF_Form2, F_Form2j);
Application.Run;
end
else
messagedlg('O sistema já foi nicializado!',mtinformation,[mbok],0);
end.

Criando janelas não retangulares

Para criar uma janela não retangular, voce deve criar uma Região do Windows e usar a função da
API SetWindowRgn, desta maneira:

var
hR : THandle;
begin
{cria uma Região elíptica}
hR := CreateEllipticRgn(0,0,100,200);
SetWindowRgn(Handle,hR,True);
end;

Form com um furo

var
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 248 de 272

Region, Region2 : hrgn;


begin
Form1.FormStyle:= fsStayOnTop;
Region := CreaterectRgn(0,0,width,height);
Region2 := CreateEllipticRgn(30,30,100,100);
CombineRgn(region, region, region2, RGN_DIFF);
SetWindowRgn(handle, region, true);
end;

Formulário Transparente

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Label1: TLabel;
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormShow(Sender: TObject);


begin
Brush.Style := BsClear;
end;
end.

Texto Na Diagonal e Girando

procedure TForm1.Button1Click(Sender: TObject);


var
lf: TLogFont;
tf: TFont;
i: integer;
begin
with Form1.Canvas do
begin
Font.Name := 'Verdana';
Font.Size := 16;
tf := TFont.Create;
tf.Assign(Font);
GetObject(tf.Handle, sizeof(lf), @lf);
lf.lfOrientation := 1000;
end;
for i := 900 downto 1 do
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 249 de 272

begin
lf.lfEscapement := i;
tf.Handle := CreateFontIndirect(lf);
Form1.Canvas.Font.Assign(tf);
Form1.Canvas.TextOut(200, Height div 2, 'Retirado da Internet');
//Sleep(10); //Este pode cria um Delay na execução
end;
tf.Free;
end;

Para testar essa dica coloque um Timer sete o interval para 5000 e um Botão e coloque o código
abaixo!
o código travará o mouse e teclado por 5 segundos!

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Timer1: TTimer;
procedure Button1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
procedure BlockInput(ABlockInput : boolean); stdcall; external 'USER32.DLL';
var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);


begin
BlockInput(True);
Timer1.Enabled:=True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);


begin
BlockInput(false);
Timer1.Enabled:=false;
end;

end.

Detectando o Numero Serial do HD

Function SerialNum(FDrive:String) :String;


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 250 de 272

Var
Serial:DWord;
DirLen,Flags: DWord;
DLabel : Array[0..11] of Char;
begin
Try GetVolumeInformation(PChar(FDrive+':\'),dLabel,12,@Serial,DirLen,Flags,nil,0);
Result := IntToHex(Serial,8);
Except Result :='';
end;
end;

Como desenhar um Bitmap num form

var
Form1: TForm1;
Bmp: TBitmap;
implementation
{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);


begin
Bmp:=TBitmap.Create;
Bmp.Loadfromfile('c:\windows\nuvens.bmp');
end;

procedure TForm1.TForm1.FormPaint(Sender: TObject);


begin
Canvas.Draw(50,50,Bmp);
end;

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


begin
Bmp.Free;
end;

Converte um arquivo JPEG em BMP

function JpgToBmp(cImage: String): Boolean;


// Requer a Jpeg declarada na clausua uses da unit
var
MyJPEG : TJPEGImage;
MyBMP : TBitmap;
begin
Result := False;
if fileExists(cImage+'.Jpeg') then
begin
MyJPEG := TJPEGImage.Create;
with MyJPEG do
begin
try
LoadFromFile(cImage+'.Jpeg');
MyBMP := TBitmap.Create;
with MyBMP do
begin
Width := MyJPEG.Width;
Height := MyJPEG.Height;
Canvas.Draw(0,0,MyJPEG);
SaveToFile(cImage+'.Bmp');
Free;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 251 de 272

Result := True;
end;
finally
Free;
end;
end;
end;
end;

Carregar um cursor animado (*.ani)

const
cnCursorID1 = 1;
begin
Screen.Cursors[ cnCursorID1 ] :=
LoadCursorFromFile('c:\win95\cursors\cavalo.ani' );
Cursor := cnCursorID1;
end;

Como pegar a posição do mouse na tela

Para obter os valores das coordenadas do mouse de qualquer parte da tela, basta que se utiliza a
função da API do Windows GetCursorPos. Esta função é interessante pois oferece ao programador
os valores (x,y) de qualquer ponto da tela e não somente da aplicação.

Para implementação, esta função pode ser utilizada da seguinte maneira:

procedure TForm1.Timer1Timer(Sender: TObject);


var
pt: TPoint;
begin
GetCursorPos(pt); // Pega a posição atual do mouse;
//Mostra os valores das coordenadas do mouse
label1.caption := IntToStr(pt.x) + ',' + IntToStr(pt.y);
end;

Como Alterar o Volume do Som do Computador Com o Delphi

a função usada para alterar o som é a waveOutSetVolume( hwo, dwVolume) que fica na unit
MMSystem.

Não é fácil alterar o volume com o Delphi. Não é só colocar uma TrackBar e associar com o MCI.
Para alterar o volume no computador você envia uma integer tipo assim: 0x5555FFFF

Os quatro dígitos F seriam o lado esquerdo do som o os quatro dígitos 5 seriam o lado direito, em
diferentes computadores eles se invertem, mas este é só um exemplo.

os valores vão de 0000 até FFFF, assim: 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F

considere o A como um 10, o B como 11, o C como 12 e assim em diante até o F que seria 15, o
volume máximo ou seja se você colocar 0xFFFFFFFF iria ficar os dois lados no volume máximo e
se colocasse 0x00000000 iria ficar tudo mudo.

Então aqui vai um exemplo:


Insira dois Edits e um Button
na seção uses coloque MMSystem.
faça o botão assim:

procedure TForm1.Button1Click(Sender: TObject);


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 252 de 272

var
s: string;
begin
s := '0x' + Edit1.Text + Edit2.Text;
MMSystem.waveOutSetVolume(0, StrToInt(s));
end;

Gravando Sons do Microfone Com o Delphi

Primeiro você deve ter uma placa de som e microfone, ambos devidamente instalados no seu PC.
Se não tiver um mic, vai lá na SantaIfigênia que você encontra um bom com 5 reais.

Agora coloque um componente TMediaPlayer que se encontra na pasta System, depois coloque
três botões e um edit no Form.

Abra o Gravador de som do Windows e sem gravar nada salve o arquivo vazio como
C:\SOM.WAV, normalmente este arquivo é temporário até salvar o arquivo pricipal. (somente
arquivos WAV são salvos, alias, se alguém souber qual função de uma das DLL do Windows
Media Player 8.0 que converte WAV para MP3, ME MANDA UM EMAIL!!!)

Agora coloque os seguintes comandos:

Na propriedade Text do Edit1 coloque o arquivo wave que você salvou - C:\SOM.WAV

procedure TForm1.Button1Click(Sender: TObject);


begin
MediaPlayer1.Open;
end;

procedure TForm1.Button2Click(Sender: TObject);


begin
MediaPlayer1.Save;
end;

procedure TForm1.Button3Click(Sender: TObject);


begin
MediaPlayer1.FileName := Edit1.Text;
end;

Agora compile o programa e abra-o, clique no Button3 para associar o arquivo que você criou ao
MCI, feche todos os aplicativos de midía que estiverem abertos (eles impedem de que abra o MCI)
e clique no Button1 para abrir o dispositivo MCI, se algo estiver errado ele não vai abrir, depois de
abrir, 4 botões vão ser liberados no TMediaPlayer1, com o microfone ligado clique na bola
vermelha para começar à gravar, para pausar a gravação clique no segundo botão o amarelo, e para
ouvir o som gravado clique no primeiro botão verde o Play, agora para salvar o arquivo clique no
Button2, vá ver o arquivo C:\SOM.WAV, antes ele estava vazio agora está com sua gravação.

Como converter decimal para romanos

function DecToRoman( Decimal: LongInt ): String;


{Converte um numero decimal em algarismos romanos}
const
Romans: Array[1..13] of String = ( 'I', 'IV', 'V', 'IX', 'X', 'XL', 'L', 'XC', 'C', 'CD', 'D', 'CM', 'M' );
Arabics: Array[1..13] of Integer =( 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000);
var
i: Integer;
scratch: String;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 253 de 272

begin
scratch := '';
for i := 13 downto 1 do
while ( Decimal >= Arabics[i] ) do
begin
Decimal := Decimal - Arabics[i];
scratch := scratch + Romans[i];
end;
Result := scratch;
end;

Alinhar Texto do Edit À Direita

//ALINHAR TEXTO DO EDIT À DIREITA


procedure TForm1.Edit1Exit(Sender: TObject);
var
n: Integer;
c: TCanvas;
h: HWND;
// pode se usar Form1.Canvas se for a mesma fonte do Edit
begin
c := TCanvas.Create;
c.Handle := GetDeviceContext(h);
c.Font := Edit1.Font;
n := round((Edit1.Width - c.TextWidth(Edit1.Text) - 8) / c.TextWidth(\ ' \'));
Edit1.Text := stringofchar(\ ' \', n) + Edit1.Text;
end;

procedure TForm1.Edit1Enter(Sender: TObject);


begin
Edit1.Text := Trim(Edit1.Text);
end;

Como Limpar Todos os Edit's de um Form de uma só vez?

Procedure LimpaEdit;
var
i : Integer;
begin
for i := 0 to ComponentCount -1 do
if Components[i] is TEdit then
begin
TEdit(Components[i]).Text := '';
end;
end;

procedure LimpaEdit (Form: TForm);


var
i : Integer;
begin
for i := 0 to Form.ComponentCount - 1 do
if Form.Components[i] is TCustomEdit then
(Form.Components[i] as TCustomEdit).Clear;
end;

Baixando arquivos da internet

Esta dica serve para quem deseja criar um sistema que atualize seus softwares via internet, e
também para quem faz jogos online, ou seja, jogos que exigem a conexão com a internet para
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 254 de 272

serem jogados, pode precisar de um meio rápido, fácil e desburocratizado para baixar arquivos de
um site ou de um lugar qualquer da rede. Veja só como é simples e sem contra indicações fazer
isso:

function DownloadFile(Source, Dest: string): Boolean;


begin
try
Result:= UrlDownloadToFile(nil, PChar(source),PChar(Dest), 0, nil) = 0;
except
Result:= False;
end;
end;
Para usar esta function é preciso declarar Urlmon na seção uses da unit. Depois basta fazer uma
chamada padrão:

if DownloadFile ('http://www.onde.com/arq.htm','c:\arq.htm') then


ShowMessage('Download Concluído.');

Chamar um e-mail pelo Delphi

Uses Shellapi

procedure TForm1.Button1Click(Sender: TObject);


var Mail : String;
begin
Mail := 'mailto:lloydsoft@ieg.com.br';
ShellExecute(GetDesktopWindow,'open',pchar(Mail),nil,nil,sw_ShowNormal);
end;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 255 de 272

Principais Procedimentos e Funções Pré definidas

procedure Beep;
Toca um beep

procedure ChDir(S: string);


Troca o diretório corrente para o diretório especificado em S.
begin
{$I-}
{ Change to directory specified in Edit1 }
ChDir(Edit1.Text);
if IOResult <> 0 then
MessageDlg('Cannot find directory', mtWarning, [mbOk], 0);
end;

function Chr(X: Byte): Char;


Retorna o caracter com o código ASCII X
begin
Canvas.TextOut(10, 10, Chr(65)); { The letter 'A'}
end;

function Concat(s1 [, s2,..., sn]: string): string;


Concatena as strings
var
S: string;
begin
S := Concat('ABC', 'DEF'); { 'ABCDE' }
end;

function Copy(S: string; Index, Count: Integer): string;


Retorna uma substring de S, começando a partir de Index e tendo Count caracters
The Copy function returns a substring of a string.
var S: string;
begin
S := 'ABCDEF';
S := Copy(S, 2, 3);&#9;{ 'BCD' }
end;

function CreateDir(const Dir: string): Boolean;


Cria um novo diretório e retorna o sucesso da operação

function Date: TDateTime;


Retorna a Data atual
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := 'Today is ' + DateToStr(Date);
end;

function DateToStr(Date: TDateTime): string;


Converte Data para String
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := DateToStr(Date);
end;

function DayOfWeek(Date: TDateTime): Integer;


Retorna o dia da semana especificado entre 1 e 7, onde domigo é um e Sábado é 7
procedure TForm1.Button1Click(Sender: TObject);
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 256 de 272

var
ADate: TDateTime;
begin
ADate := StrToDate(Edit1.Text);
Label1.Caption := 'Day ' + IntToStr(DayOfWeek(ADate)) + ' of the week';
end;

procedure DecodeDate(Date: TDateTime; var Year, Month, Day: Word);


Quebra os valores especificados no parâmetro Date em Year, Month e Day.
procedure TForm1.Button1Click(Sender: TObject);
var
Present: TDateTime;
Year, Month, Day, Hour, Min, Sec, MSec: Word;
begin
Present:= Now;
DecodeDate(Present, Year, Month, Day);
Label1.Caption := 'Today is Day ' + IntToStr(Day) + ' of Month '
+ IntToStr(Month) + ' of Year ' + IntToStr(Year);
DecodeTime(Present, Hour, Min, Sec, MSec);
Label2.Caption := 'The time is Minute ' + IntToStr(Min) + ' of Hour '
+ IntToStr(Hour);
end;

procedure DecodeTime(Time: TDateTime; var Hour, Min, Sec, MSec: Word);


Quebra os valores especificados em Time nos par6ametros Hour, Min, Sec e MSec.
procedure TForm1.Button1Click(Sender: TObject);
var
Present: TDateTime;
Year, Month, Day, Hour, Min, Sec, MSec: Word;
begin
Present:= Now;
DecodeDate(Present, Year, Month, Day);
Label1.Caption := 'Today is Day ' + IntToStr(Day) + ' of Month '
+ IntToStr(Month) + ' of Year ' + IntToStr(Year);
DecodeTime(Present, Hour, Min, Sec, MSec);
Label2.Caption := 'The time is Minute ' + IntToStr(Min) + ' of Hour '
+ IntToStr(Hour);
end;

procedure Delete(var S: string; Index, Count:Integer);


Remove a substring de Count caracters da string S partir da posição Index
var
s: string;
begin
s := 'Honest Abe Lincoln';
Delete(s,8,4);
Canvas.TextOut(10, 10, s);&#9;{ 'Honest Lincoln' }
end;

function DeleteFile(const FileName: string): Boolean;


Apaga o arquivo FileName do disco. Se o arquivo não puder ser apagado a função retorna False.
DeleteFile('DELETE.ME');

function DirectoryExists(Name: string): Boolean;


Verifica se Name diretorio existe

function DiskFree(Drive: Byte): Integer;


Retorna o número de bytes livre no driver especificado em Drive.
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 257 de 272

Onde : 0 = Corrente, 1 = A, 2 = B,...


DiskFree retorna –1 se o driver for inválido
var
S: string;
begin
S := IntToStr(DiskFree(0) div 1024) + ' Kbytes free.';
Canvas.TextOut(10, 10, S);
end;

function DiskSize(Drive: Byte): Integer;


Retorna o tamanho em bytes do driver especificado.
Onde : 0 = Corrente, 1 = A, 2 = B,...
DiskFree retorna –1 se o driver for inválido
var
S: string;
begin
S := IntToStr(DiskSize(0) div 1024) + ' Kbytes capacity.';
Canvas.TextOut(10, 10, S);
end;

function EncodeDate(Year, Month, Day: Word): TDateTime;


Retorna uma Data formada por Year, Month e Day
procedure TForm1.Button1Click(Sender: TObject);
var
MyDate: TDateTime;
begin
MyDate := EncodeDate(83, 12, 31);
Label1.Caption := DateToStr(MyDate);
end;

function EncodeTime(Hour, Min, Sec, MSec: Word): TDateTime;


Retorna a Hora formada por Hour, Min, Sec e MSec
procedure TForm1.Button1Click(Sender: TObject);
var
MyTime: TDateTime;
begin
MyTime := EncodeTime(0, 45, 45, 7);
Label1.Caption := TimeToStr(MyTime);
end;

function ExtractFileDir(const FileName: string): string;


Retorna o diretório adequado para ser passado para as funções CreateDir, GetCurrentDir,
RemoveDir e SetCurrentDir.
O resultado da função é uma string vazia se FileName não contiver um drive e um caminho.

function ExtractFileDrive(const FileName: string): string;


Retorna uma string contendo o drive do path de um arquivo.

function ExtractFileExt(const FileName: string): string;


Retorna a extensão do arquivo FileName

function ExtractFileName(const FileName: string): string;


Retorna o nome do arquivo
Form1.Caption := 'Editing '+ ExtractFileName(FileName);

function ExtractFilePath(const FileName: string): string;


Retorna o Path de um arquivo
ChDir(ExtractFilePath(FileName));
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 258 de 272

function FileAge(const FileName: string): Integer;


Retorna a data e a hora de um arquivo num valor que pode ser convertido para TDateTime através
da função FileDateToDateTime. Retorna –1 se o arquivo não existir

function FileExists(const FileName: string): Boolean;


Retorna verdade se o arquivo existir
if FileExists(FileName) then
if MsgBox('Do you really want to delete ' + ExtractFileName(FileName)
+ '?'), []) = IDYes then DeleteFile(FileName);

function FileSize(var F): Integer;


Retorna o tamanho de um arquivo, para usar FileSize o arquivo deve esta aberto. Se o arquivo
estiver vazio FileSize(F) retorna 0. F é uma variavel do tipo arquivo. FileSize não pode ser usada
com arquivo texto
var
f: file of Byte;
size : Longint;
S: string;
y: integer;
begin
if Opendialog1.Execute then begin
AssignFile(f, Opendialog1.FileName);
Reset(f);
size := FileSize(f);
S := 'File size in bytes: ' + IntToStr(size);
y := 10;
Canvas.TextOut(5, y, S);
y := y + Canvas.TextHeight(S) + 5;
S := 'Seeking halfway into file...';
Canvas.TextOut(5, y, S);
y := y + Canvas.TextHeight(S) + 5;
Seek(f,size div 2);
S := 'Position is now ' + IntToStr(FilePos(f));
Canvas.TextOut(5, y, S);
CloseFile(f);
end;
end;

procedure FillChar(var X; Count: Integer; value: Byte);


Preenche um vetor com determinado caracter. Value pode ser um byte ou char
var
S: array[0..79] of char;
begin
{ Set to all spaces }
FillChar(S, SizeOf(S), ' ');
end;

function FloatToStr(Value: Extended): string;


Converte um valor em ponto flutuante (real) para uma string

procedure ForceDirectories(Dir: string);


Cria multiplos diretórios de uma só vez
procedure TForm1.Button1Click(Sender: TObject);
var
Dir: string;
begin
Dir := 'C:\APPS\SALES\LOCAL';
ForceDirectories(Dir);
if DirectoryExists(Dir) then
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 259 de 272

Label1.Caption := Dir + ' was created'


end;

function FormatDateTime(const Format: string; DateTime: TDateTime): string;


Formata o valor DateTime usando o formato de Format. Os especificadores de formato abaixo são
válidos
Specifier&#9;Displays
c&#9;Displays the date using the format given by the ShortDateFormat global variable, followed
by the time using the format given by the LongTimeFormat global variable. The time is not
displayed if the fractional part of the DateTime value is zero.
d&#9;Displays the day as a number without a leading zero (1-31).
dd&#9;Displays the day as a number with a leading zero (01-31).
ddd&#9;Displays the day as an abbreviation (Sun-Sat) using the strings given by the
ShortDayNames global variable.
dddd&#9;Displays the day as a full name (Sunday-Saturday) using the strings given by the
LongDayNames global variable.
ddddd&#9;Displays the date using the format given by the ShortDateFormat global variable.
dddddd&#9;Displays the date using the format given by the LongDateFormat global variable.
m&#9;Displays the month as a number without a leading zero (1-12). If the m specifier
immediately follows an h or hh specifier, the minute rather than the month is displayed.
mm&#9;Displays the month as a number with a leading zero (01-12). If the mm specifier
immediately follows an h or hh specifier, the minute rather than the month is displayed.
mmm&#9;Displays the month as an abbreviation (Jan-Dec) using the strings given by the
ShortMonthNames global variable.
mmmm&#9;Displays the month as a full name (January-December) using the strings given by the
LongMonthNames global variable.
yy&#9;Displays the year as a two-digit number (00-99).
yyyy&#9;Displays the year as a four-digit number (0000-9999).
h&#9;Displays the hour without a leading zero (0-23).
hh&#9;Displays the hour with a leading zero (00-23).
n&#9;Displays the minute without a leading zero (0-59).
nn&#9;Displays the minute with a leading zero (00-59).
s&#9;Displays the second without a leading zero (0-59).
ss&#9;Displays the second with a leading zero (00-59).
t&#9;Displays the time using the format given by the ShortTimeFormat global variable.
tt&#9;Displays the time using the format given by the LongTimeFormat global variable.
am/pm&#9;Uses the 12-hour clock for the preceding h or hh specifier, and displays 'am' for any
hour before noon, and 'pm' for any hour after noon. The am/pm specifier can use lower, upper, or
mixed case, and the result is displayed accordingly.
a/p&#9;Uses the 12-hour clock for the preceding h or hh specifier, and displays 'a' for any hour
before noon, and 'p' for any hour after noon. The a/p specifier can use lower, upper, or mixed case,
and the result is displayed accordingly.
ampm&#9;Uses the 12-hour clock for the preceding h or hh specifier, and displays the contents of
the TimeAMString global variable for any hour before noon, and the contents of the
TimePMString global variable for any hour after noon.
/&#9;Displays the date separator character given by the DateSeparator global variable.
:&#9;Displays the time separator character given by the TimeSeparator global variable.
'xx'/"xx"&#9;Characters enclosed in single or double quotes are displayed as-is, and do not affect
formatting.
Format specifiers may be written in upper case as well as in lower case letters--both produce the
same result.
If the string given by the Format parameter is empty, the date and time value is formatted as if a 'c'
format specifier had been given.
S := FormatDateTime('"The meeting is on" dddd, mmmm d, yyyy, ' +
'"at" hh:mm AM/PM', StrToDateTime('2/15/95 10:30am'));

function FormatFloat(const Format: string; Value: Extended): string;


Transforma um Float numa string usando a formatação contida em Format. Os especificadores de
formato abaixo são válidos
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 260 de 272

Specifier&#9;Represents
0&#9;Digit place holder. If the value being formatted has a digit in the position where the '0'
appears in the format string, then that digit is copied to the output string. Otherwise, a '0' is stored
in that position in the output string.
#&#9;Digit placeholder. If the value being formatted has a digit in the position where the '#'
appears in the format string, then that digit is copied to the output string. Otherwise, nothing is
stored in that position in the output string.
.&#9;Decimal point. The first '.' character in the format string determines the location of the
decimal separator in the formatted value; any additional '.' characters are ignored. The actual
character used as a the decimal separator in the output string is determined by the
DecimalSeparator global variable. The default value of DecimalSeparator is specified in the
Number Format of the International section in the Windows Control Panel.
,&#9;Thousand separator. If the format string contains one or more ',' characters, the output will
have thousand separators inserted between each group of three digits to the left of the decimal
point. The placement and number of ',' characters in the format string does not affect the output,
except to indicate that thousand separators are wanted. The actual character used as a the thousand
separator in the output is determined by the ThousandSeparator global variable. The default value
of ThousandSeparator is specified in the Number Format of the International section in the
Windows Control Panel.
E+&#9;Scientific notation. If any of the strings 'E+', 'E-', 'e+', or 'e-' are contained in the format
string, the number is formatted using scientific notation. A group of up to four '0' characters can
immediately follow the 'E+', 'E-', 'e+', or 'e-' to determine the minimum number of digits in the
exponent. The 'E+' and 'e+' formats cause a plus sign to be output for positive exponents and a
minus sign to be output for negative exponents. The 'E-' and 'e-' formats output a sign character
only for negative exponents.
'xx'/"xx"&#9;Characters enclosed in single or double quotes are output as-is, and do not affect
formatting.
;&#9;Separates sections for positive, negative, and zero numbers in the format string.
The locations of the leftmost '0' before the decimal point in the format string and the rightmost '0'
after the decimal point in the format string determine the range of digits that are always present in
the output string.
The number being formatted is always rounded to as many decimal places as there are digit
placeholders ('0' or '#') to the right of the decimal point. If the format string contains no decimal
point, the value being formatted is rounded to the nearest whole number.
If the number being formatted has more digits to the left of the decimal separator than there are
digit placeholders to the left of the '.' character in the format string, the extra digits are output
before the first digit placeholder.
To allow different formats for positive, negative, and zero values, the format string can contain
between one and three sections separated by semicolons.
One section: The format string applies to all values.
&#9;Two sections: The first section applies to positive values and zeros, and the second section
applies to negative values.
&#9;Three sections: The first section applies to positive values, the second applies to negative
values, and the third applies to zeros.
If the section for negative values or the section for zero values is empty, that is if there is nothing
between the semicolons that delimit the section, the section for positive values is used instead.
If the section for positive values is empty, or if the entire format string is empty, the value is
formatted using general floating-point formatting with 15 significant digits, corresponding to a call
to FloatToStrF with the ffGeneral format. General floating-point formatting is also used if the
value has more than 18 digits to the left of the decimal point and the format string does not specify
scientific notation.
0&#9;&#9;&#9;1234&#9;&#9;-1234&#9;&#9;1&#9;&#9;0
0.00 &#9;&#9;&#9;1234.00&#9;&#9;-1234.00&#9;&#9;0.50&#9;&#9;0.00
#.## &#9;&#9;&#9;1234&#9;&#9;-1234&#9;&#9;.5&#9;
#,##0.00&#9;&#9;&#9;1,234.00&#9;&#9;-1,234.00&#9;0.50&#9;&#9;0.00
#,##0.00;(#,##0.00)&#9;1,234.00&#9;&#9;(1,234.00)&#9;0.50&#9;&#9;0.00
#,##0.00;;Zero &#9;&#9;1,234.00&#9;&#9;-1,234.00&#9;0.50&#9;&#9;Zero
0.000E+00 &#9;&#9;1.234E+03&#9;-1.234E+03&#9;5.000E-01&#9;0.000E+00
#.###E-0 &#9;&#9;1.234E3&#9;&#9;-1.234E3&#9;5E-1&#9;&#9;0E0
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 261 de 272

function Frac(X: Real): Real;


Retorna a parte fracional do parâmetro X
var
R: Real;
begin
R := Frac(123.456); { 0.456 }
R := Frac(-123.456); { -0.456 }
end;

function GetCurrentDir: string;


Retorna uma string contendo o diretório corrente

procedure GetDir(D: Byte; var S: string);


Rerorna o diretório corrente do driver especificado.
O onde D pode ser :
Value&#9;Drive
0&#9;Corrente
1&#9;A
2&#9;B
3&#9;C
var
s : string;
begin
GetDir(0,s); { 0 = Current drive }
MessageDlg('Current drive and directory: ' + s, mtInformation, [mbOk] , 0);
end;

procedure Inc(var X [ ; N: Longint ] );


Incrementa de uma ou N unidades o parâmetro X
var
IntVar: Integer;
LongintVar: Longint;
begin
Inc(IntVar);&#9;&#9;{ IntVar := IntVar + 1 }
Inc(LongintVar, 5);&#9;{ LongintVar := LongintVar + 5 }
end;

function IncMonth(const Date: TDateTime; NumberOfMonths: Integer): TDateTime;


Retorna Date acrescido ou decrescido de NumberOfMonths meses.

function InputBox(const ACaption, APrompt, ADefault: string): string;


Exibe uma Caixa de Entrada onde o usuário pode digitar uma string.
ACaption representa o título do Input Box e APrompt é o título do edit e ADefault representa o
valor inicial do Edit.
uses Dialogs;
procedure TForm1.Button1Click(Sender: TObject);
var
InputString: string;
begin
InputString:= InputBox('Input Box', 'Prompt', 'Default string');
end;

function InputQuery(const ACaption, APrompt: string; var Value: string): Boolean;


Semelhante ao InputBox, sendo que retorna True se o usuário fechou a O InputBox com OK e
False se fechou com Cancel ou ESC. E Value armazena a string digitada.
procedure TForm1.Button1Click(Sender: TObject);
var
NewString: string;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 262 de 272

ClickedOK: Boolean;
begin
NewString := 'Default String';
Label1.Caption := NewString;
ClickedOK := InputQuery('Input Box', 'Prompt', NewString);
if ClickedOK then { NewString contains new input string }
Label1.Caption := 'The new string is ''' + NewString + '''';
end;

procedure Insert(Source: string; var S: string; Index: Integer);


Insere uma string em outra a partir da posição Index
var
S: string;
begin
S := 'Honest Lincoln';
Insert('Abe ', S, 8); { 'Honest Abe Lincoln' }
end;

function IntToHex(Value: Integer; Digits: Integer): string;


Converte o inteiro Value num Hexadecimal (Base 16). Digits indica o número mínimo de dígitos
Hexa a serem retornados
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit2.Text := IntToHex(StrToInt(Edit1.Text), 6);
end;

function IntToStr(Value: Integer): string;


Trasnforma um Inteiro numa String
procedure TForm1.Button1Click(Sender: TObject);
var
Value: Integer;
begin
Value := 1234;
Edit1.Text := IntToStr(Value);
end;

function IsValidIdent(const Ident: string): Boolean;


Indica se um identificador é válido para o Pascal

function Length(S: string): Integer;


retorna o número de caracters usados na string S
var
S: string;
begin
S := 'The Black Knight';
Canvas.TextOut(10, 10, 'String Length = ' + IntToStr(Length(S)));
end;

function MaxIntValue(const Data: array of Integer): Integer;


Retorna o maior inteiro de um vetor

function MaxValue(const Data: array of Double): Double;


Retorna o maior valor de um vetor

function Mean(const Data: array of Double): Extended;


Retorna a média aritmética de um vetor

function MessageDlg(const Msg: string; AType: TMsgDlgType;


AButtons: TMsgDlgButtons; HelpCtx: Longint): Word;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 263 de 272

Exibe uma Caixa de Mensagem e obtem uma resposta do usuário.


Onde
Msg : Mensagem
AType : Tipo da caixa de mensagem
Value&#9;Meaning
mtWarning&#9;A message box containing a yellow exclamation point symbol.
mtError&#9;&#9;A message box containing a red stop sign.
mtInformation&#9;A message box containing a blue "i".
mtConfirmation&#9;A message box containing a green question mark.
mtCustom&#9;A message box with no bitmap. The caption of the message box is the name of the
application's executable file.
AButtons : Quais botões aparecerão na caixa de mensagem
Value&#9;&#9;&#9;&#9;Meaning
mbYes&#9;&#9;&#9;A button with the text 'Yes' on its face
mbNo&#9;&#9;&#9;A button with the text 'No' on its face
mbOK&#9;&#9;&#9;A button with the text 'OK' on its face
mbCancel&#9;&#9;A button with the text 'Cancel' on its face
mbHelp&#9;&#9;&#9;A button with the text 'Help' on its face
mbAbort&#9;&#9;A button with the text 'Abort' on its face
mbRetry&#9;&#9;&#9;A button with the text 'Retry' on its face
mbIgnore&#9;&#9;A button with the text 'Ignore' on its face
mbAll&#9;&#9;&#9;A button with the text 'All' on its face
mbYesNoCancel&#9;&#9;Puts Yes, No, and Cancel buttons in the message box
mbOkCancel&#9;&#9;Puts t OK and Cancel buttons in the message box
mbAbortRetryIgnore&#9;Puts Abort, Retry, and Ignore buttons in the message box
MessageDlg returns the value of the button the user selected. These are the possible return values:
Return &#9;values
mrNone&#9;&#9;mrAbort&#9;&#9;mrYes
mrOk&#9;&#9;mrRetry&#9;&#9;mrNo
mrCancel&#9;mrIgnore&#9;mrAll
procedure TForm1.Button1Click(Sender: TObject);
begin
if MessageDlg('Welcome to my Object Pascal application. Exit now?',
mtConfirmation, [mbYes, mbNo], 0) = mrYes then
begin
MessageDlg('Exiting the Object Pascal application.', mtInformation,
[mbOk], 0);
Close;
end;
end;

function MessageDlgPos(const Msg: string; AType: TMsgDlgType;


AButtons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer): Word;
Semelhante a MessageDlg exceto por permitir indicar a posição na qual a janela será exibida
procedure TForm1.Button1Click(Sender: TObject);
begin
MessageDlgPos('Are you there?',mtConfirmation, mbYesNoCancel, 0, 200, 200);
end;

function MinIntValue(const Data: array of Integer): Integer;


Retorna o menor inteiro do vetor

function MinValue(const Data: array of Double): Double;


Retorna o menor valor de um vetor

procedure MkDir(S: string);


Cria um novo diretório
uses Dialogs;
begin
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 264 de 272

{$I-}
{ Get directory name from TEdit control }
MkDir(Edit1.Text);
if IOResult <> 0 then
MessageDlg('Cannot create directory', mtWarning, [mbOk], 0)
else
MessageDlg('New directory created', mtInformation, [mbOk], 0);
end;

function Now: TDateTime;


Retorna a data e a hora corrente
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := 'The date and time is ' + Str(Now);
end;

function Ord(X): Longint;


Retorna a ordem de um valor ordinal
uses Dialogs;
type
Colors = (RED,BLUE,GREEN);
var
S: string;
begin
S := 'BLUE has an ordinal value of ' + IntToStr(Ord(BLUE)) + #13#10;
S := 'The ASCII code for "c" is ' + IntToStr(Ord('c')) + ' decimal';
MessageDlg(S, mtInformation, [mbOk], 0);
end;

function Pi: Extended;


Retorna o valor de PI
3.1415926535897932385.

function Pos(Substr: string; S: string): Integer;


Procura por uma sub-string numa string e retorna a posição da primeira ocorrência ou zero se não
encontrou
var S: string;
begin
S := ' 123.5';
{ Convert spaces to zeroes }
while Pos(' ', S) > 0 do
S[Pos(' ', S)] := '0';
end;

function Power(Base, Exponent: Extended): Extended;


Potência

function Pred(X);
Retorna o predecessor de um ordinal
uses Dialogs;
type
Colors = (RED,BLUE,GREEN);
var
S: string;
begin
S := 'The predecessor of 5 is ' + IntToStr(Pred(5)) + #13#10;
S := S + 'The successor of 10 is ' + IntToStr(Succ(10)) + #13#10;
if Succ(RED) = BLUE then
S := S + 'In the type Colors, RED is the predecessor of BLUE.';
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 265 de 272

MessageDlg(S, mtInformation, [mbOk], 0);


end;

function Random [ ( Range: Integer) ];


Retorna um valor Randômico
0 <= X < Range.
var
I: Integer;
begin
Randomize;
for I := 1 to 50 do begin
{ Write to window at random locations }
Canvas.TextOut(Random(Width), Random(Height), 'Boo!');
end;
end;

procedure Randomize;
Inicializa o modo Randomico
var
I: Integer;
begin
Randomize;
for I := 1 to 50 do begin
{ Write to window at random locations }
Canvas.TextOut(Random(Width), Random(Height), 'Boo!');
end;
end;

function RemoveDir(const Dir: string): Boolean;


Remove um diretório retornando True caso tenha conseguido e False caso contrário

procedure Rename(var F; Newname);


F is a variable of any file type. Newname is a string-type expression or an expression of type
PChar
uses Dialogs;
var
f : file;
begin
Opendialog1.Title := 'Choose a file... ';
if Opendialog1.Execute then begin
SaveDialog1.Title := 'Rename to...';
if SaveDialog1.Execute then begin
AssignFile(f, Opendialog1.FileName);
Canvas.TextOut(5, 10, 'Renaming ' + Opendialog1.FileName + ' to ' +
SaveDialog1.FileName);
Rename(f, SaveDialog1.FileName);
end;
end;
end;

function RenameFile(const OldName, NewName: string): Boolean;


Renomeia arquivos e retorna o sucesso ou insucesso
The following code renames a file:
if not RenameFile('OLDNAME.TXT','NEWNAME.TXT') then
ErrorMsg('Error renaming file!');

procedure RmDir(S: string);


Remove um diretório
uses Dialogs;
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 266 de 272

begin
{$I-}
{ Get directory name from TEdit control }
RmDir(Edit1.Text);
if IOResult <> 0 then
MessageDlg('Cannot remove directory', mtWarning, [mbOk], 0)
else
MessageDlg('Directory removed', mtInformation, [mbOk], 0);
end;

function Round(X: Extended): Longint;


Arredonda um número real

function SelectDirectory(var Directory: string; Options: TSelectDirOpts; HelpCtx:


Longint):Boolean;
Exibe um Caixa de Dialogo para seleção de Diretório. O Diretório passado para a função aparece
como diretório corrente e o diretório escolhido é retonado no mesmo Diretório (Directory). O valor
do diretório corrente não é alterado
These are the possible values that can be added to the Options set:
Value&#9;&#9;Meaning
sdAllowCreate&#9;An edit box appears to allow the user to type in the name of a directory that
does not exist. This option does not create a directory, but the application can access the Directory
parameter to create the directory selected if desired.
sdPerformCreate&#9;Used only when Options contains sdAllowCreate. If the user enters a
directory name that does not exist, SelectDirectory creates it.
sdPrompt&#9;Used when Options contains sdAllowCreate. Displays a message box that informs
the user when the entered directory does not exist and asks if the directory should be created. If the
user chooses OK, the directory is created if Options contains sdPerformCreate. If Options does not
contain sdPerformCreate, the directory is not created: the application should create it when
SelectDirectory returns.
The function returns True if the user selected a directory and chose OK, and False if the user chose
Cancel or closed the dialog box without selecting a directory.
This example uses a button on a form. When the user clicks the button, a Select Directory dialog
box appears. The current directory displayed in the dialog box is C:\MYDIR. The user can select a
directory from the directory list, or enter a new directory in the edit box. If the user enters a new
directory, a message box asks the user if the directory should be created. If the user chooses Yes,
the directory is created. If the user chooses No, the message box goes away without creatubg the
directory. The name of the directory the user selects appears as the caption of the label:
uses FileCtrl;
procedure TForm1.Button1Click(Sender: TObject);
var
Dir: string;
begin
Dir := 'C:\MYDIR';
if SelectDirectory(Dir, [sdAllowCreate, sdPerformCreate, sdPrompt]) then
Label1.Caption := Dir;
end;

function SetCurrentDir(const Dir: string): Boolean;


Torna o Dir o diretório corrente e retorna o sucesso da operação

procedure SetLength(var S: string; NewLength: Integer);


Coloca um novo tamanho para uma string
S[0] := NewLength.

procedure ShowMessage(const Msg: string);


Exibe uma mensagem ao usuário
procedure TForm1.Button1Click(Sender: TObject);
begin
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 267 de 272

ShowMessage('Push this button');


end;

function Sqr(X: Extended): Extended;


Retorna o quadrado de X

function Sqrt(X: Extended): Extended;


Retorna a raiz quadrada de X

function StrComp(Str1, Str2 : PChar): Integer;


Compara duas strings em case sensitivity
Return value&#9;Condition
<0&#9;if Str1< Str2
=0&#9;if Str1= Str2
>0&#9;if Str1 > Str2

function StringOfChar(Ch: Char; Count: Integer): string;


Retorna uma string contendo Count caracters Ch
S := StringOfChar('A', 10);
{sets S to the string 'AAAAAAAAAA'}

function StrToDate(const S: string): TDateTime;


Converte uma string em data
procedure TForm1.Button1Click(Sender: TObject);
var
ADate: TDateTime;
begin
ADate := StrToDate(Edit1.Text);
Label1.Caption := DateToStr(ADate);
end;

function StrToDateTime(const S: string): TDateTime;


Converte uma string para o formato DateTime
procedure TForm1.Button1Click(Sender: TObject);
var
ADateAndTime: TDateTime;
begin
ADateAndTime := StrToDateTime(Edit1.Text);
Label1.Caption := DateTimeToStr(ADateAndTime);
end;

function StrToFloat(const S: string): Extended;


Converte uma string num Float

function StrToInt(const S: string): Integer;


Converte uma string num inteiro
procedure TForm1.Button1Click(Sender: TObject);
var
S: string;
I: Integer;
begin
S := '22467';
I := StrToInt(S);
Inc(I);
Edit1.Text := IntToStr(I);
end;

function StrToTime(const S: string): TDateTime;


Converte uma string em hora
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 268 de 272

procedure TForm1.Button1Click(Sender: TObject);


var
ATime: TDateTime;
begin
ATime := StrToTime(Edit1.Text);
Label1.Caption := TimeToStr(ATime);
end;

function Succ(X);
Retorna o sucessor de um ordinal
uses Dialogs;
type
Colors = (RED,BLUE,GREEN);
var
S: string;
begin
S := 'The predecessor of 5 is ' + IntToStr(Pred(5)) + #13#10;
S := S + 'The successor of 10 is ' + IntToStr(Succ(10)) + #13#10;
if Succ(RED) = BLUE then
S := S + 'In the type Colors, RED is the predecessor of BLUE.';
MessageDlg(S, mtInformation, [mbOk], 0);
end;

function Sum(const Data: array of Double): Extended register;


Calcula a soma de dos elementos de um vetor

function SumInt(const Data: array of Integer): Integer register;


Calcula a soma dos elementos de um vetor de inteiros

function Time: TDateTime;


Retorna a hora corrente
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := 'The time is ' + TimeToStr(Time);
end;

function TimeToStr(Time: TDateTime): string;


Converte hora para string
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := TimeToStr(Time);
end;

function Trim(const S: string): string;


Retira os espaços em brancos a esquerda e a direita da string S

function TrimLeft(const S: string): string;


Retira os espaços em brancos a esquerda da string S

function TrimRight(const S: string): string;


Retira os espaços em brancos a direita da string S

function Trunc(X: Extended): Longint;


Retorna a parte inteira de um número

function UpCase(Ch: Char): Char;


Converte o caracter Ch em maiúscula
uses Dialogs;
var
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 269 de 272

s : string;
i : Integer;
begin
{ Get string from TEdit control }
s := Edit1.Text;
for i := 1 to Length(s) do
s[i] := UpCase(s[i]);
MessageDlg('Here it is in all uppercase: ' + s, mtInformation, [mbOk], 0);
end;

function UpperCase(const S: string): string;


Converte a string S em maiúsculas
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
begin
for I := 0 to ListBox1.Items.Count -1 do
ListBox1.Items[I] := UpperCase(ListBox1.Items[I]);
end;

Consulte outras dicas no CD ou pesquise na internet.


Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 270 de 272

ÍNDICE

Assunto Pág.
Capitulo I – Definições 1
Sistema Operacional 1
Linguagem 1
Linguagem estruturada 1
Linguagem orientada a objeto 1
Constantes 1
Variáveis 1
Operadores 2
Dados 3
Banco de Dados 3
Rotina 4
Procedimento 4
Comandos 4
Estruturas 4
Capitulo II – Componentes básicos da orientação a objetos 5
Classe 5
Objeto 5
Instância 5
Propriedade 5
Método 5
Mensagem 6
Interface 6
Evento 6
Procedimento 6
Tempo de Projeto 6
Tempo de Execução 6
Capitulo III – Apresentação do Delphi 2005 6
Tela de Abertura 6
VCL Form Application for WIN 32 7
Object Inspector 8
Caixa de estruturas (Structure) 8
A Paleta de Componentes 8
Gerente do projeto (Project Manager) 9
O Formulário 10
A Unit 10
Estrutura de uma Unit 11
Capitulo IV – Os primeiros contatos 12
Prática 01: O primeiro projeto 12
Prática 02: Alterando algumas propriedades do formulário 13
Prática 03 - Exercício 01 13
Capitulo V – Estruturas 14
Estrutura de bloco 14
Prática 04 15
Pratica 05 – Exercício 02 16
Estruturas de decisão 17
Pratica 06: Acendendo uma lâmpada 18
Prática 07 19
Pratica 08 – Exercício 03 20
Pratica 09: Controlando o trânsito 21
Projeto 10: Promovendo descontos 22
Pratica 11 – Exercício 04 24
Estruturas de loop ou laço 24
Pratica 12: Demonstração do Repeat ... Until 25
Pratica 13 – Exercício 05 26
Estruturas consecutivas 27
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 271 de 272

Pratica 14: Demonstração do With...do 27


Estruturas de exceção 28
Capitulo VI – Bancos de dados 28
O BDEAdministrator 29
O MSSQL Server 32
Capitulo VII – O DataBase Desktop (DBD) 32
Capitulo VIII – Trabalhando com o DataBase Desktop 34
Exercício 06 37
Incrementando registros de uma tabela 37
Navegando pelos registros de uma tabela 37
Excluindo registros de uma tabela 38
Organizando os registros de uma tabela 38
Criando índices secundários 38
Exercício 07 39
Capitulo IX – Incluindo tabelas em um formulário 39
O Data-Module 39
Pratica 15: Incluindo uma senha 40
Criando um alias paradox 40
Criando o data module 41
Capitulo X – Incluindo menus em um formulário 44
Prática 16 – Montando um formulário de controle 45
Capitulo XI – Trabalhando com mais de um formulário 46
Prática 17 – Anexando formulários 46
Capitulo XII – Estruturando um projeto 48
Capitulo XIII – Incluindo, localizando e excluindo dados de uma tabela em tempo de execução 50
Prática 18 – Cadastro de clientes 52
Exercício 08 – Crie um cadastro de produtos e um cadastro de 62
fornecedores
Capitulo XIV – Respondendo a mensagens 62
Prática 19 – Utilizando o comando messagedlg 63
Prática 20 – Utilizando o comando messagedlg 64
Prática 21 – Utilizando o comando messagedlgpos 65
Exercício 09 65
Capitulo XV – Rotinas especiais (Procedures e Funções) 65
Capitulo XVI – Localizando dados em uma tabela 69
Prática 22 – Localizando registros (métodos GotoKey, GotoNearest,
FindKey, FindNearest) 70

Prática 23 – Localizando registros (métodos Recnº) 73


Prática 24 – Localizando registros (métodos Locate) 75
Prática 25 – Localizando registros (métodos Filter) 78
Exercício 10 – Crie consultas para o seu projeto 79
Capitulo XVII – Relacionando tabelas 80
Prática 26 – Relacionamento I 82
Prática 27 – Relacionamento II 84
Capitulo XVIII – O SQL 86
Criando uma query pelo DataBase Desktop 86
Criando uma relação entre duas tabelas através do query de modo interativo 87
Criando uma relação entre três tabelas através do query de modo interativo 89
Prática 28 – Criando o relacionamento entre as tabelas clientes, vendas,
90
itens e materias em tempo de execução
Prática 29 – Selecionando todas as compras de um cliente 91
Operadores WHERE 92
Exemplos de consultas 93
Capitulo XIX – Trabalhando com mídias 95
Prática 30 – Lendo mídias com uso de objetos 95
Prática 31 – Tocando sons wave via função 97
Capitulo XX – Trabalhando com diálogos
98
Fábio José de Gondra Ramos
gondraf@hotmail.com
Delphi 2005 for win32 Página 272 de 272

Prática 32 – Trabalhando com diálogos 98


Capitulo XXI – Trabalhando unidades, pastas e arquivos 101
Prática 33 – Localizando e executando arquivos via objetos 101
Prática 34 – Um gerenciador de arquivos 104
Prática 35 – Outro gerenciador de arquivos 105
Capitulo XXII – Trabalhando com gráficos 112
Prática 36 – Criando gráficos 115
Prática 37 – Criando gráficos com tabelas 121
Capitulo XXIII – Literatura complementar 124
Literatura 01 – Criando o arquivo de ajuda 124
Literatura 02 – O Rave Report 130
Capitulo XXIV – Dicas da internet 140