delphi 2005 - básico

272
[email protected] Delphi 2005 for win32 Fábio José de Gondra Ramos 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: Variável Integer Faixa de abrangência Formato 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 -2 63 2 631 Positivo/Negativo 64 Shortint -128 128 Positivo/Negativo 8 Smallint -32.768 32.767 Positivo/Negativo 16 Word 0 65.535 Positivo 16

Upload: marcoaureliomarques

Post on 21-Jun-2015

1.232 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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ísticaA:=5 5 Numérica Aceita cálculos numéricosA:= B*30 30 Numérica Se apresenta sempre fora de aspasA:=’Delphi’ ‘Delphi’ String Se apresenta sempre entre aspasA:=’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 ExemploVariant 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:

Variável Integer Faixa de abrangência FormatoDe Até Sinal Bits

Integer/Longint -2.147.483.648 2.147.483.647 Positivo/Negativo 32Longword/Cardinal 0 4.294.967.295 Positivo 32Byte 0 255 Positivo 8Int64 -263 2631 Positivo/Negativo 64Shortint -128 128 Positivo/Negativo 8Smallint -32.768 32.767 Positivo/Negativo 16Word 0 65.535 Positivo 16

Page 2: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 2 de 272

Variável Real ou Doublé

Faixa de abrangência FormatoDe Até Dígitos Bits

Real -5 * 10324 1,7 * 10308 1516 64Real48 -2,9 *1039 1,7 * 1038 1112 48Single -1,5 * 1045 3,4 * 1038 78 32Doublé -5 * 10324 1,7 * 10308 1516 64Extended -3,6 * 104951 1,1 * 104932 1920 80Comp -263 + 1 263 - 1 1920 64Currency -9 * 1018 9 * 1018 1920 64

Variável String Faixa de abrangência Memória ocupadaChar 1 caracter 1 byteString / ShortString 255 caracteres De 2 até 256 bytesAnsiString Aproximadamente 231 caracteres De 4 bytes até 4 gigabytesWideString Aproximadamente 230 caracteres De 4 bytes até 4 gigabytes

Variável Lógica

Faixa de valores FormatoVerdadeiro False Tipo associado Bits

Boolean 1 0 Byte 8ByteBool Diferente de 0 0 Byte 8WordBool Diferente de 0 0 Word 16LongBool 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

Page 3: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 ExemploNot negação Boolean Boolean not (C in MySet)And conjuncão Boolean Boolean D and (T > 0)Or disjunção Boolean Boolean A or BXor 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 = MySetIn membership set, ordinal Boolean A in Set1

Operadores relacionais:

Operador Operação Tipo do operando Tipo Resultante Exemplo= igualdade simple, class, class reference,

interface, string, packed stringBoolean A=I

<> desigualdade simple, class, class reference, interface, string, packed string

Boolean X<>Y

> maior que simple, string, packed string, PChar

Boolean X>Y

< menor que simple, string, packed string, PChar

Boolean X<Y

>= maior ou igual simple, string, packed string, PChar

Boolean X>=Y

<= menor ou igual simple, string, packed string, PChar

Boolean X<=Y

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.

Page 4: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Compras1–Identificar as editoras 1-Cadastro de editoras2-Identificar os livros das editoras 2-Cadastro de livros3-Escolher os livros e comprar 3-Entrada dos livros

Vendas 1-Identificar os clientes 1-Cadastro de clientes2-Separar e entregar os livros escolhidos 2-Saída dos livros

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

Exemplo:

Rotina Procedimentos

Cadastro de editoras

1. Verificar se editora já foi cadastrada2. Se não foi cadastrada, então pegar uma nova ficha3. Transcrever os dados da editora para a ficha4. Confirmar a veracidade dos dados5. 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.

Page 5: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.

Page 6: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 7: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 7 de 272

VCL Form Application for WIN 32

Menu Principal

Barra de Ferramentas

Caixa de Estrutura

Object Inspector

Página de Códigos

Gerente do projeto

Paleta de objetos

Formulário

Barra de status

Page 8: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.

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).

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.

Botão minimizar

Botão fechar

Caixa de seleção de objetos

Paleta de propriedades

Paleta de eventos

Botão minimizar

Botão Fechar

Mover para baixo

Mover para cima

Excluir objeto

Incluir objeto

Objetos

Page 9: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 9 de 272

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 fechar

Botão filtrar

Botão desfazer seleção

Botão habilitar/desabilitar categoria

Categoria selecionada

Objetos da categoria

Botão minimizar

Botão minimizar

Seleciona projeto

Inclui nova unit/form ao projeto

Remove unit/form do projeto

Unit/form do projeto

Modelo do projeto

Explorador de base de dados

Page 10: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 11: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.

Page 12: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 = VerdeBotão Amarelo Clicar Cor do semáforo = AmareloBotão Vermelho Clicar Cor do semáforo = Vermelho

Prática 01: O primeiro projeto

Objeto Propriedade Evento ProcedimentoButton1 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.

Page 13: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 ProcedimentoButton1 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 ProcedimentoButton4 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 ProcedimentoButton6 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 ProcedimentoButton8 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:

Page 14: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 14 de 272

Formulário:

Objeto Propriedade Valor Evento ProcedimentoButton1 Caption OnClickButton2 Caption OnClickButton3 Caption OnClickButton4 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.

Page 15: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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; Fim; Rotina asseio; Inicio Escovar os dentes; Tomar banho; Fim; Rotina alimentação; 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 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 ProcedimentoForm1 Caption Soma de dois númerosLabel1 Caption Primeiro número:Label2 Caption Segundo número:Label3 Caption Resultado:Edit1 Text Vazio (null) OnKeyPres

sEdit1KeyPress

E s t r u t u r a P r i n c p a l

E s t r u t u r a s S e c u n d á r i a s Estrutura bloco

Page 16: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 16 de 272

Edit2 Text Vazio (null) OnKeyPress

Edit2KeyPress

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;

procedure TForm1.Edit2KeyPress(Sender: TObject; var Key: Char);begin if not (key in ['0'..'9']) then key:=#0;end;

procedure TForm1.Button1Click(Sender: TObject);var A,B,C:integer;begin A:=strtoint(edit1.Text); B:=strtoint(edit2.Text); C:=A+B; Label3.Caption:='Resultado:'+inttostr(C);end;

Comentários:

Pratica 05 – Exercício 02: Monte um projeto capaz de calcular a média aritmética entre 4 números inteiros quaisquer.

Variável KeyTipo caracterGuarda a tecla pressionada

Verifica se a tecla pressionadaEstá entre 0 e 9

Variáveis A, B e C do tipo inteira

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

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

Page 17: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 18: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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á apagadaFim

Pratica 06: Acendendo uma lâmpada:

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

Formulário:

Objeto Propriedade Valor Evento ProcedimentoForm1 Caption Pratica 06Panel1 Caption Vazio (null)Panel1 Color clBlackRadioGroup1 Caption Interruptor OnClick RadioGroup1Click

RadioGroup1 Items Acender a lâmpadaApagar 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:

Page 19: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 ProcedimentoForm1 Caption Pratica 07Label1 Caption Digite um número:Label2 Caption Resultado:Label3 Caption Raiz:Label4 Caption Parte inteira:Label5 Caption Parte decimal:Edit1 Text Vazio (null) OnKeyPres

sEdit1KeyPress

Edit2 Text Vazio (null)Edit3 Text Vazio (null)Edit4 Text Vazio (null)Button1 Caption Verificar OnClick Button1ClickGroupBox1 Caption Resultados:GroupBox1 Enabled FalseRadioButton1 Caption ExataRadioButton2 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;

Page 20: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.

Page 21: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 ProcedimentoForm1 Caption Pratica 09 OnActivate Form1ActivateImage1 Picture ’c:\delphi 2005\pratica 09\ carro1.bmp’

Image1 Autosize TrueTimer1 Enabled False OnTimer Timer1TimerRadioGroup1 Caption Semáforo OnClick RadioGroup1Click

RadioGroup1 ItemsPareAtençãoSiga

RadioGroup1 ItemIndex 0Shape1 Shape stCircleShape2 Shape stCircleShape3 Shape stCircleShape1 Brush.Color clBtnfaceShape2 Brush.Color clBtnfaceShape3 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

Page 22: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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ópiaAté 50 R$ 0,10De 51 a 100 R$ 0,08De 101 a 150 R$ 0,06Acima de150 R$ 0,05

Page 23: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 23 de 272

Formulário:

Objeto Propriedade Valor Evento ProcedimentoForm1 Caption Pratica 10

LabeledEdit1 EditLabelCaption Quantidade de xérox na primeira semana

OnKeyPress Testatecla

LabeledEdit1 LabelPosition lpLeft

LabeledEdit2 EditLabelCaption Quantidade de xérox na segunda semana

OnKeyPress Testatecla

LabeledEdit2 LabelPosition lpLeft

LabeledEdit3 EditLabelCaption Quantidade de xérox na terceira semana

OnKeyPress Testatecla

LabeledEdit3 LabelPosition lpLeft

LabeledEdit4 EditLabelCaption Quantidade de xérox na quarta semana

OnKeyPress Testatecla

LabeledEdit4 LabelPosition lpLeftLabel1 Caption Total de xérox:Label2 Caption Valor por xérox:Label3 Caption Total a pagar:StaticText1 Caption 0StaticText1 BorderStyle sbsSukenStaticText2 Caption 0StaticText2 BorderStyle sbsSukenStaticText3 Caption 0StaticText3 BorderStyle sbsSukenBitBtn1 Caption Calcular

BitBtn1 Glyph

C:\Arquivos de programas\ arquivos comuns\ borland shared\images\buttons\ calculat.bmp

OnClick BitBtn1Click

Procedimentos:

procedure TForm1.testatecla(Sender: TObject; var Key: Char);begin if not (key in ['0'..'9',#8]) then key:=#0;end;

Page 24: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 descontoAté 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.

Page 25: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 25 de 272

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

Formulário:

Objeto Propriedade Valor Evento ProcedimentoLabel1 Caption Indique o número de repetições:Edit1 Text Vazio (null) OnKeyPress Edit1KeyPressButton1 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:

Page 26: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.

Page 27: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 ProcedimentoForm1 Caption Pratica 14Label1 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;

Page 28: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 Ffinally 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).

Page 29: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.

Page 30: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Nativo

ParadoxDB2DBaseFoxProInformixInterbaseMSAccessMSSQLOracleSybase

ODBC

SQLServerMicrosoft Access DriverMicrosoft Text DriverMicrosoft Excel DriverMicrosoft dBase DriverMicrosoft Paradox DriverMicrosoft Visual FoxPro DriverMicrosoft FoxPro VFP DriverMicrosoft 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 32768Nível 3 and 4 1024, 2048 e 4096Default: 2048

Page 31: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 anterioresDefault: 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.

Page 32: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.

Page 33: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 33 de 272

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

No menu encontramos os seguintes comandos:

Comando DescriçãoFile Menu de controle de arquivosEdit Menu de edição de arquivos e preferênciasTools Menu de ferramentasWindow Menu de exibição de janelasHelp Menu de ajuda do DBD

O comando file apresenta a seguinte lista de subcomandos:

Subcomando DescriçãoNew Cria uma nova tabela, query ou SQLOpen Abre uma tabela, query ou SQLClose Fecha uma tabela, query ou SQLSave Salva uma tabela, query ou SQLSave As... Salva uma tabela, query ou SQL em outraWorking Directory... Define um diretório como de trabalhoPrivate 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çãoAlias manager.. Ativa o gerenciador de Alias, isto é, abrirá o

Borland DataBase Engine (BDE), gerenciador de bases de dados da Borland

Menu

Barra de ferramentas

Área de trabalho

Barra de status

Page 34: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 34 de 272

O comando window estará inabilitado até que a opção open seja ativada e apresentará a seguinte lista de subcomandos:

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 suportadoAlpha A 1 - 255 Letras, números, símbolos especiais como

%, &, #, or = ou qualquer outro carácter ASCII

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

Subcomando DescriçãoCascade Exibirá as janelas das tabelas na forma de cascataTile top and bottom Exibirá as janelas das tabelas uma abaixo da outraSide by side Exibirá as janelas das tabelas uma ao lado da outraArrange icons Organizará as janelas em iconesClose all Fecha todas as janelas

Page 35: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 32767Long Integer I --- Qualquer número inteiro na faixa que vai de

-2147483648 a 2147483647Date D --- Guarda datas entre 1 de Janeiro de 9999 AC até 31

de Dezembro 9999 AD.Time T --- Guarda horas no formato DD:MM:AAAATimestamp @ --- Guarda a data e hora atualMemo M 1 - 240** Guarda arquivos memoFormatted Memo F 0 - 240** Guarda arquivos formatted memoGraphic 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.

Page 36: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Identidade Alfanumérico 10 Sim Guarda o número da identidade

CPF Alfanumérico 14 Guarda o número do C.P.F.Nome Alfanumérico 50 Guarda o nomeNascimento Data Guarda a data de nascimentoLogradouro Alfanumérico 50 Guarda o nome da ruaNumero Numérico Guarda o numero da casa

Complemento Alfanumérico 50 Guarda dados complementares

Bairro Alfanumérico 30 Guarda o nome do bairroCidade Alfanumérico 30 Guarda o nome da cidadeEstado Alfanumérico 2 Guarda o nome do estadoCEP Alfanumérico 10 Guarda o número do cepAtivo 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”:

Page 37: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.

Page 38: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 ChaveUsuario Alpha 30 SimSenha Alpha 6Nivel 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çãoFile Menu de controle de arquivosEdit Menu de edição de arquivos e preferênciasTools Menu de ferramentasView Menu de visualização de registrosTable Menu de controle sobre a tabelaRecord Menu de controle sobre registros da tabelaWindow Menu de exibição de janelasHelp 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:

Page 39: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 39 de 272

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

Opção Tecla de atalho DescriçãoNext F12 vai para o Próximo registroPrevious F11 vai para o registro AnteriorFirst Ctrl+F11 vai para o Primeiro registroLast Ctrl+F12 vai para o Último registro

Page 40: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.

Page 41: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.

Page 42: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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;

Page 43: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 ValorTYPE STANDARDDEFAULT DRIVER PARADOXENABLE BCD FALSEPATH 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

Page 44: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 44 de 272

Data-module Name DMData-module OnCreate DatamoduleCreateData-module OnDestroy DatamoduleDestroyTable1 Name TAcessosTable1 DatabaseName DadosTable1 TableName Acessos.DBDataSource1 Name DSAcessosDataSource1 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:

Page 45: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 45 de 272

Objeto Propriedade Valor Evento ProcedimentoForm1 Caption Pratica 15Form1 OnActivate Form1ActivatePanel1 Caption Vazio (null)Panel1 Border Style bsSinglePanel1 BevelInner bvLoweredPanel1 BevelOuter bvRaisedPanel1 BevelWidth 2Panel1 BorderWidth 2Label1 Caption Usuário:Label2 Caption Senha:Edit1 Text Vazio (null)Edit2 Text Vazio (null)BitBtn1 Caption Verificar OnClick BitBtn1Click

BitBtn1 GlyphC:\arquivos de programas\ arquivos comuns\Borland Shared \Images\Buttons\Key

BitBtn2 Caption Cancelar OnClick BitBtn2Click

BitBtn1 GlyphC:\arquivos de programas\ arquivos comuns\Borland Shared \Images\Buttons\DoorOpen

Clausula Variável Tipo Valor ParâmetroPrivate Tentativas IntegerUses 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

Page 46: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 projetoend;

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.

Page 47: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 ProcedimentoForm1 Caption Pratica 16Form1 Name Fpratica16Image1 AutoSize TrueImage1 Stretch TrueImage1 Align alClientImage1 Picture C:\Delphi 2005\images\Borland1

Mainmenu1 Items

&Cadastros C&lientes &Produtos &Fornecedores F&uncionarios&Movimentos &Entradas &SaídasC&onsultas &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:

Page 48: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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;

Page 49: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çãoLinha Procedimento Linha Procedimento

54 if dm.TAcessosSenha.Text=Edit2.Text then 54 if dm.TAcessosSenha.Text=Edit2.Text then55 showmessage('acesso permitido!') 55 Fpratica16.Show56 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);

Page 50: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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ício2-Localiza base de dados3-Identifica a tabela

Page 51: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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ário2-Preparar campos de formulário3-Entrar com dado4-Buscar chave5-Chave existe?

6-Se sim:6.1-Mostrar dados6.2-Informar ao usuário6.3-Voltar para definição de ação 5

7-Se não:7.1-Entrar com valores7.2-Criticar valores7.3-Preparar tabelas para recebimento de dados7.4-Gravar dados7.5-Dados gravados com sucesso?7.6-Informar usuário7.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ário2-Preparar campos de formulário3-Entrar com dado4-Buscar chave5-Chave existe?

6-Se sim:6.1-Mostrar valores6.2-Alterar valores6.3-Criticar valores6.4-Preparar tabelas para recebimento de dados6.5-Gravar dados6.6-Dados gravados com sucesso?6.7-Informar usuário6.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ário7.2-Voltar para definição de ação 5

Exclusão de registros:1-Abrir formulário2-Preparar campos de formulário3-Entrar com dado4-Buscar chave5-Chave existe?

6-Se sim:

Page 52: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 52 de 272

6.1-Mostrar valores6.2-Exclui dados?

6.2.1-Se sim:6.2.1.1-Excluir dados6.2.1.2-Dados excluídos com sucesso?

6.2.1.2.1-Se sim:6.2.1.2.1.1-Informar ao usuário6.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ário6.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ário7.2-Excluir outro?7.2.1-Se sim:

7.2.1.1-Retornar para ação - 27.2.2-Se não:

7.2.2.1-Voltar para definição de ação 58-Fim dos casos9-Finalizar?

9.1-Se sim:9.1.1-Fechar tabela9.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:

Page 53: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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:

Page 54: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 ProcedimentoForm1 Caption Cadastro de clientes OnActivate FormActivateLabel1 Visible FalseLabel2 Caption BairroLabel3 Caption CidadeLabel4 Caption EstadoLabel5 Caption CEPLabel6 Caption Telefone

ToolBar1

EdgeBorders

Ebleft=trueebTop=trueebRight=trueebBottom=true

Images ImageList1ShowCaptions TrueList True

Page 55: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 55 de 272

Toolbutton1 Name novo OnClick novoClickCaption Novo

Toolbutton2 Name primeiro OnClick primeiroClickCaption Primeiro

Toolbutton3 Name anterior OnClick anteriorClickCaption Anterior

Toolbutton4 Name proximo OnClick proximoClickCaption Proximo

Toolbutton5 Name ultimo OnClick ultimoClickCaption Ultimo

Toolbutton6 Name salvar OnClick salvarClickCaption Salvar

Toolbutton7 Name excluir OnClick excluirClickCaption Excluir

Toolbutton8 Name localizar OnClick localizarClickCaption Localizar

Toolbutton9 Name fechar OnClick fecharClickCaption Fechar

Labelededit1Name ecodigo OnExit ecodigoExitEditLabel.Caption CódigoLabelPosition lpleft

Panel1 Align alBottomEnabled False

Label7 Caption Buscar

DBGrid1Align alBottom OnDblClick DBGrid1DblClickDataSource DM.DSClientesReadOnly True

BitBtn1 Caption Aplicar OnClick BitBtn1Click

RadioGroup1

Name elocaliza OnClick elocalizaClickCaption Localizar por:

Items.Strings

ClienteCódigoCPFCNPJ

MaskEdit1 Name ebuscar

RadioGroup2

Name etipo OnClick etipoClickCaption TipoColumns 2

Items.Strings FísicoJurídico

ComboBox1

Name ebairroSorted True

Items.Strings

13 de julhoAruanaAtalaiaCentroJabotianaSanta Tereza

MaskEdit2 Name ecpf_cnpjVisible False

LabeledEdit2Name eclienteEditLabel.Caption ClienteLabelPosition lpleft

LabeledEdit3

Name erg_insestadualEditLabel.Caption CódigoLabelPosition lpleftVisible False

Page 56: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 56 de 272

LabeledEdit4Name elogradouroEditLabel.Caption LogradouroLabelPosition lpleft

LabeledEdit5Name ecomplementoEditLabel.Caption ComplementoLabelPosition lpleft

LabeledEdit6 Name enumeroEditLabel.Caption NúmeroLabelPosition lpleft

ComboBox2

Name ecidadeSorted True

Items.Strings

AracajuEstânciaItabaianaNossa Senhora da Glória

ComboBox3

Name eestadoSorted True

Items.Strings

AL AM BA PE SE

MaskEdit3

Name ecepEditMask 99999-999MaxLength 9Text Vazio (null)

MaskEdit4

Name etelefoneEditMask (99)9999-9999MaxLength 13Text Vazio (null)

Panel2Name mensagensAlign alBottomCaption 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:='';

Page 57: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 58: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 59: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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:='';

Page 60: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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;

Page 61: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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;

Page 62: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 63: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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;

Page 64: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.

Page 65: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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:

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 RespostambOk mrOkmbCancel mrCancelmbYes mrYesmbNo mrNombAbort mrAbortmbRetry mrRetrymbIgnore mrIgnore

Prática 19 – Utilizando o comando messagedlg

Formulário:

Variável Tipo DescriçãoMsg String é o conteúdo da mensagemDlgType TMsgDlgType indica o propósito do diálogoBotões TMsgDlgButtons indicam que botões devem aparecer na caixa de mensagem

HelpCtx Longintespecifica o contexto ID para o tópico de ajuda que deverá aparecer quando o usuário clica o botão de ajuda ou aperta F1 enquanto o diálogo é exibido

Page 66: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 66 de 272

Objeto Propriedade Valor Evento ProcedimentoForm1 Caption Pratica 19

RadioGroup1

Caption Indique o tipo da mensagem OnClick RadioGroup1Click

ItemsInformaçãoAtençãoErroConfirmaçã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 ProcedimentoForm1 Caption Pratica 20BitBtn1 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:

Page 67: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 67 de 272

Objeto Propriedade Valor Evento ProcedimentoForm1 Caption Pratica 21BitBtn1 Caption Aplicar Click BitBtn1ClickLabelededit1 Caption Indique a coluna da mensagemLabelededit2 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.

Page 68: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.

Page 69: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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:=''; erg_insestadual.Text:=''; elogradouro.Text:=''; ecomplemento.Text:=''; enumero.Text:=''; ecidade.Text:=''; eestado.Text:=''; ecep.Text:=''; etelefone.Text:='';

Limparcampos();

FormActivateNovoClick SalvarClickExcluirClick

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;

Page 70: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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áriocodigo.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;

mostrardados()

primeiroClickanteriorClickproximoClickultimoClickecodigoExitDBGrid1DblClick

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 ValorTabela TTable Assume o valor de uma TableEditmascara TMaskEdit Assume o valor de um MaskEditÍndice String Guarda um valor stringMascara String Guarda um valor stringTexto 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:

Page 71: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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:

Método

Uso

de

Cha

ve

Uso

de

cori

nga

Uso

de

parâ

met

ro

Características

Gotokey Sim Não Não Localiza um único registro com exatidãoGotoNearest Sim Não Não Localiza o registro que mais se assemelhaFindKey Sim Não Não Localiza um único registro com exatidãoFindNearest Sim Não Não Localiza o registro que mais se assemelhaLocate Não Não Sim Localiza um registro com base em um dado ou parte deste

RecNo Não Não Não Localiza um registro com base no número de registro ou informa o número do registro atual

First Não Não Não Localiza o primeiro registro da tabela

Page 72: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 72 de 272

Prior Não Não Não Localiza o registro anterior ao atualNext Não Não Não Localiza o registro seguinte ao atualLast Não Não Não Localiza o último registro da tabelaFiltered Não Não Não Habilita/desabilita o uso de filtrosFilter 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 ProcedimentoForm1 Caption Pratica 22 OnActivate Form1Activate

RadioGroup1

Caption Método OnClick RadioGroup1Click

ItemsGotoKeyGotoNearestFindKeyFinNearest

GroupBox1 Caption Método GotoKey ou FindKey

Name GB1

GroupBox2 CaptionMétodo GotoNearest ou FindNearest

Name GB2

LabeledEdit1 EditLabel.Caption Código:LabelPosition Lpleft

LabeledEdit2 EditLabel.Caption Cliente:LabelPosition Lpleft

BitBtn1 Caption Localizar OnClick BitBtn1ClickBitBtn2 Caption Localizar OnClick BitBtn2Click

Page 73: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 73 de 272

Table1Name TClientesDataBaseName DadosTableName Clientes.DB

DataSource1 DataSet TClientesLabel1 Caption CódigoLabel2 Caption ClienteLabel3 Caption Cpf / cnpjLabel4 Caption Rg /I.EstaudalLabel5 Caption Logradouro Label6 Caption NúmeroLabel7 Caption ComplementoLabel8 Caption BairroLabel9 Caption CidadeLabel10 Caption EstadoLabel11 Caption CepLabel12 Caption TelefoneDbGrid1 DataSource DataSource1

DBEdit1 DataSource DataSource1DataField Código

DBEdit2 DataSource DataSource1DataField Cliente

DBEdit3 DataSource DataSource1DataField Cpf_cnpj

DBEdit4 DataSource DataSource1DataField Rg_inestadual

DBEdit5 DataSource DataSource1DataField Logradouro

DBEdit6 DataSource DataSource1DataField Numero

DBEdit7 DataSource DataSource1DataField Complemento

DBEdit8 DataSource DataSource1DataField Bairro

DBEdit9 DataSource DataSource1DataField Cidade

DBEdit10 DataSource DataSource1DataField Estado

DBEdit11 DataSource DataSource1DataField Cep

DBEdit12 DataSource DataSource1DataField Telefone

Rotinas especiais NomeFunçã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);

Page 74: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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:

Page 75: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 75 de 272

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

Formulário:

Objeto Propriedade Valor Evento ProcedimentoForm1 Caption Pratica 23 OnActivate Form1Activate

GroupBox1 Caption Método RecNºName GB1

LabeledEdit1 EditLabel.Caption Registro:LabelPosition Lpleft

BitBtn1 Caption Localizar OnClick BitBtn1Click

Table1Name TClientesDataBaseName DadosTableName Clientes.DB

DataSource1 DataSet TClientesLabel1 Caption CódigoLabel2 Caption ClienteLabel3 Caption Cpf / cnpjLabel4 Caption Rg /I.EstaudalLabel5 Caption Logradouro Label6 Caption NúmeroLabel7 Caption ComplementoLabel8 Caption BairroLabel9 Caption CidadeLabel10 Caption EstadoLabel11 Caption CepLabel12 Caption Telefone

Label13

Caption Registro nº:Name RegistrosFont.size 14Font.style Fsbold

DbGrid1 DataSource DataSource1

Page 76: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 76 de 272

DBEdit1 DataSource DataSource1DataField Código

DBEdit2 DataSource DataSource1DataField Cliente

DBEdit3 DataSource DataSource1DataField Cpf_cnpj

DBEdit4 DataSource DataSource1DataField Rg_inestadual

DBEdit5 DataSource DataSource1DataField Logradouro

DBEdit6 DataSource DataSource1DataField Numero

DBEdit7 DataSource DataSource1DataField Complemento

DBEdit8 DataSource DataSource1DataField Bairro

DBEdit9 DataSource DataSource1DataField Cidade

DBEdit10 DataSource DataSource1DataField Estado

DBEdit11 DataSource DataSource1DataField Cep

DBEdit12 DataSource DataSource1DataField 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;

Page 77: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 ProcedimentoForm1 Caption Pratica 24 OnActivate Form1Activate

GroupBox1 Caption Método LocateName GB1

LabeledEdit1 EditLabel.Caption Valor::LabelPosition Lpleft

Page 78: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 78 de 272

BitBtn1 Caption Localizar OnClick BitBtn1Click

Table1Name TClientesDataBaseName DadosTableName Clientes.DB

DataSource1 DataSet TClientes

RadioGroup1

Caption Campos:

ItemsCódigoClienteCPF_CNPJRG_Ins.Estadual

RadioGroup2Caption Parâmetro:

Items Case Insensitive (completo)Partial Key (Parcial)

Label1 Caption CódigoLabel2 Caption ClienteLabel3 Caption Cpf / cnpjLabel4 Caption Rg /I.EstaudalLabel5 Caption Logradouro Label6 Caption NúmeroLabel7 Caption ComplementoLabel8 Caption BairroLabel9 Caption CidadeLabel10 Caption EstadoLabel11 Caption CepLabel12 Caption TelefoneDbGrid1 DataSource DataSource1

DBEdit1 DataSource DataSource1DataField Código

DBEdit2 DataSource DataSource1DataField Cliente

DBEdit3 DataSource DataSource1DataField Cpf_cnpj

DBEdit4 DataSource DataSource1DataField Rg_inestadual

DBEdit5 DataSource DataSource1DataField Logradouro

DBEdit6 DataSource DataSource1DataField Numero

DBEdit7 DataSource DataSource1DataField Complemento

DBEdit8 DataSource DataSource1DataField Bairro

DBEdit9 DataSource DataSource1DataField Cidade

DBEdit10 DataSource DataSource1DataField Estado

DBEdit11 DataSource DataSource1DataField Cep

DBEdit12 DataSource DataSource1DataField Telefone

Procedimentos:

procedure TForm1.FormActivate(Sender: TObject);

Page 79: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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:

Page 80: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 80 de 272

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

Formulário:

Objeto Propriedade Valor Evento ProcedimentoForm1 Caption Pratica 25

GroupBox1 Caption Método FilterName GB1

LabeledEdit1 EditLabel.Caption Epressão:LabelPosition Lpleft

BitBtn1 Caption Localizar OnClick BitBtn1Click

Table1Name TClientesDataBaseName DadosTableName Clientes.DB

DataSource1 DataSet TClientesLabel1 Caption CódigoLabel2 Caption ClienteLabel3 Caption Cpf / cnpjLabel4 Caption Rg /I.EstaudalLabel5 Caption Logradouro Label6 Caption NúmeroLabel7 Caption ComplementoLabel8 Caption BairroLabel9 Caption CidadeLabel10 Caption EstadoLabel11 Caption CepLabel12 Caption TelefoneDbGrid1 DataSource DataSource1

DBEdit1 DataSource DataSource1DataField Código

DBEdit2 DataSource DataSource1DataField Cliente

Page 81: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 81 de 272

DBEdit3 DataSource DataSource1DataField Cpf_cnpj

DBEdit4 DataSource DataSource1DataField Rg_inestadual

DBEdit5 DataSource DataSource1DataField Logradouro

DBEdit6 DataSource DataSource1DataField Numero

DBEdit7 DataSource DataSource1DataField Complemento

DBEdit8 DataSource DataSource1DataField Bairro

DBEdit9 DataSource DataSource1DataField Cidade

DBEdit10 DataSource DataSource1DataField Estado

DBEdit11 DataSource DataSource1DataField Cep

DBEdit12 DataSource DataSource1DataField 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.

Page 82: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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:

Page 83: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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:

Page 84: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 DatasetTable1 TMateriais Dados Materiais.dbTable2 TVendas Dados Vendas.dbTable3 TItens Dados Itens.dbDataSource1 DSMateriais TMateriaisDataSource2 DSVendas TVendasDataSource3 DSItens TItens

Formulário:

Objeto Propriedade Valor Evento ProcedimentoForm1 Caption Pratica 26 OnActivate Form1Activate

ScrollBox1 Height 200Width 400

ScrollBox2 Height 200Width 400

ScrollBox3 Height 200Width 400

ScrollBox4 Height 200Width 400

StaticText1

Caption ClientesAlign AlTopAlignment AlCenterColor clBlueFont.size 12Font.color clWhite

Page 85: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 85 de 272

StaticText2

Caption CuponsAlign AlTopAlignment AlCenterColor clBlueFont.size 12Font.color clWhite

StaticText3

Caption Itens do cupomAlign AlTopAlignment AlCenterColor clBlueFont.size 12Font.color clWhite

StaticText4

Caption MateriaisAlign AlTopAlignment AlCenterColor clBlueFont.size 12Font.color clWhite

Label1 Caption CódigoLabel2 Caption ClasseLabel3 Caption ProdutoLabel4 Caption Preço de custoLabel5 Caption Preço de vendaLabel6 Caption Saldo

DBEdit1 DataSource DSMateriaisDataField Código

DBEdit2 DataSource DSMateriaisDataField Classe

DBEdit3 DataSource DSMateriaisDataField Produto

DBEdit4 DataSource DSMateriaisDataField Preço de custo

DBEdit5 DataSource DSMateriaisDataField Preço de venda

DBEdit6 DataSource DSMateriaisDataField Saldo

DBGrid1 DataSource DSClientesDBGrid2 DataSource DSVendasDBGrid2 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;

Page 86: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 ProcedimentoForm1 Caption Pratica 27 OnActivate Form1ActivateBitbtn1 Caption Adicionar OnClick Bitbtn1ClickBitbtn2 Caption Salvar OnClick Bitbtn2ClickBitbtn3 Caption Novo OnClick Bitbtn3ClickLabel1 Caption ClienteLabel2 Caption MaterialLabel3 Caption ItensLabel4 Caption VendasLabel4 Caption Material QuantidadeLabeledEdit1 Caption N° do cupomLabeledEdit1 Name CupomLabeledEdit2 Caption Total do cupomLabeledEdit2 Name TotalcupomLabeledEdit3 Caption Preço de vendaLabeledEdit3 Name Pvenda

Page 87: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 87 de 272

LabeledEdit4 Caption QuantidadeLabeledEdit4 Name QuantidadeDBLookupComboBox1 ListSource Dm.DSMateriaisDBLookupComboBox1 KeyField CódigoDBLookupComboBox1 ListField ProdutoDBLookupComboBox2 ListSource Dm.DSClientesDBLookupComboBox2 KeyField CódigoDBLookupComboBox2 ListField ClienteDBGrid1 DataSource Dm.DSItensDBGrid2 DataSource Dm.DSVendasGroupBox1 Caption Itens vendidos:ListBox1 Name LB1ListBox2 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;

Page 88: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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:

Page 89: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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, TelefoneFROM ":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.

Page 90: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.VencimentoFROM ":Dados:Clientes.DB" D, ":Dados:Vendas.DB" D1WHERE(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.

Page 91: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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:

Page 92: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.QuantidadeFROM ":Dados:Clientes.DB" D, ":Dados:Vendas.DB" D1, ":Dados:Itens.DB" D2WHERE(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 ProcedimentoForm1 Caption Pratica 28 OnActivate Form1Activate

Query1 DataBaseName DadosSQL Strings...

DataSource1 DataSet Query1

Page 93: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 93 de 272

Query1.SQL Strings...

SELECT *FROM Clientes A, Vendas B, Itens C, Materiais DWHERE (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 ProcedimentoForm1 Caption Pratica 29 OnActivate Form1ActivateQuery1 DataBaseName Dados

DataSource1 DataSet Query1Name DSQuery

Table1 DataBaseName DadosTableName Clientes

DataSource2 DataSet Table1Name DSTable

Label1 Caption ClienteBitBtn1 Caption Aplicar OnClick Bitbtn1ClickDBGrid1 DataSource DSQuery

DBLookupCombobox1ListSource DSTableKeyField CódigoListField Cliente

Procedimentos:

Page 94: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 94 de 272

procedure TForm1.Button1Click(Sender: TObject);begin query1.Open;end;

procedure TForm1.BitBtn1Click(Sender: TObject);var condicao:string;beginquery1.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

Aritméticos

+ Adição- Subtração* Multiplicação/ Divisão

Comparação

= Igual a<> Diferente de> Maior que< Menor que>= Maior ou igual<= Menor ou igual

LógicosAND UniãoOR Intersecção NOT Negação

Especiais IN Contido em uma listaBETWEEN e AND Compreendido em uma faixaEXISTS Cria uma subconsulta baseada na clausula WHERELIKE Permite o uso de mascarasIS NULL Verifica a presença de campos vazios

Page 95: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 95 de 272

Exemplos de consultas

01 – Consulta materiais com saldo maior que 100

Select material, saldoFrom materiaisWhere saldo>100

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

Select material, saldoFrom materiaisWhere saldo>100 and saldo<500

03 – Consulta materiais e saldo em ordem crescente

Select material, saldoFrom materiaisOrder by saldo

04 – Consulta materiais e saldo em ordem decrescente

Select material, saldoFrom materiaisOrder by saldo desc

05 – Consulta materiais com campo saldo vazio

Select material, saldoFrom materiaisWhere saldo is null

06 – Consulta materiais com campo saldo preenchido

Select material, saldoFrom materiaisWhere saldo is not null

07 – Consulta materiais e saldo cujo material comece com C

Select material, saldoFrom materiaisWhere material like “C %”

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

Select material, saldoFrom materiaisWhere material like “%ANEL %”

09 – Consulta materiais e saldo cujo material termine com NADOR

Select material, saldoFrom materiaisWhere material like “ %NADOR”

Page 96: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 96 de 272

10 – Consulta clientes que morem em SE e AL

Select cliente, estadoFrom clientesWhere estado IN (“SE”, “AL”)

Funções SQL FunçãoUPPER Retorna a consulta em maiúsculaAVG Retorna a média dos valores armazenados um campoMIN Retorna o menor valor armazenado em um campoMAX Retorna o maior valor armazenado em um campoSUM Retorna a soma dos valores armazenados em um campo

Exemplos de consultas

01 – Maiúsculas

Select Upper(material), saldoFrom 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

Page 97: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 ProcedimentoForm1 Caption Pratica 30MediaPlayer1 Visible False

RadioGroup1

Name RGWav Click RGWavClickCaption Arquivos WAV

Items

TelefoneImpressoraSimNão

RadioGroup2

Name RGAvi Click RGAviClickCaption Arquivos AVI

ItemsDelphiMicrosoftCool

RadioGroup3 Name RGMid Click RGMdiClickCaption Arquivos MID

ItemsMúsica 1Música 2Música 3

RadioGroup4

Name RGWmw Click RGWmwClickCaption Arquivos WMW

ItemsWMV 1WMV 2WMV 3

Page 98: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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:

Page 99: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 ProcedimentoForm1 Caption Pratica 31

RadioGroup1

Name RGSN Click RGsndClick

Caption Utilizando método SNDPLAYSOUND

Items

TelefoneImpressoraSimNão

RadioGroup1 Name RGplay Click RGplayClick

Caption Utilizando método PLAYSOUND

Items

TelefoneImpressoraSimNã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:

Page 100: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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:

Procedimentos:

procedure TForm1.Abrir1Click(Sender: TObject);begin if opendialog1.Execute=true then richedit1.Lines.LoadFromFile(opendialog1.FileName);end;

Objeto Propriedade Valor Evento Procedimento

Form1 Caption Trabalhando com Dialog’s

GroupBox1 Caption ArquivoGroupBox2 Caption ImagemRichEdit1 LinesRichEdit1 Align alClientImage1 Align alClientImage1 Stretch True

MainMenu1

ArquivoNovoAbrirSalvar

Imagem AbrirSalvar

Texto

Alterar fonteAlterar corLocalizarSubstituir

Impressão ImprimirAjustar impressora

Sair

Page 101: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 procuradobegin 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

Page 102: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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:

Page 103: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

FileName Indica o nome do arquivo que deverá ser aberto ou salvo por um diálogo

OpenDialogSaveDialogOpenPictureDialogSavePictureDialog

Filter Indica qual o tipo de arquivo (extensão) deverá ser filtrado

OpenDialogSaveDialogOpenPictureDialogSavePictureDialog

InitialDir Indica qual o diretório inicial para busca ou gravação de arquivo

OpenDialogSaveDialogOpenPictureDialogSavePictureDialog

FindText Indica o texto que deverá ser procurado ReplaceDialogFindDialog

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:

Page 104: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 104 de 272

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 windowsend;

procedure TForm1.BitBtn2Click(Sender: TObject);begin close;end;Comentários:

Prática 34 – Um gerenciador de arquivos

Objeto Propriedade Valor Evento ProcedimentoForm1 Caption Pratica 33Label1 Unidade:Label2 Pasta:Label3 Filtro:Label4 Arquivos:DriveComboBox1 DirList DirectoryListBox1DirectoryListBox1 FileList FileListBox1FilterComboBox1 FileList FileListBox1FileListBox1 Filter Ver abaixo Click FileListBox1ClickStatusBar1 SimplePanel TrueBitBtn1 Caption Abrir Click BitBtn1ClickBitBtn2 Caption Fechar Click BitBtn2Click

Page 105: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 105 de 272

Formulário:

Procedimentos:

procedure TForm1.Detalhes1Click(Sender: TObject);

Objeto Propriedade Valor Evento Procedimento

Form1 Caption Pratica 34Menu MainMenu1

Panel1 Caption Endereço:Align alTop

ShellComboBox1

ShellListView ShellListView1ShellTreeView ShellTreeView1Root rfDesktopUseShellImages True

ShellTreeView1

ShellListView ShellListView1ShellComboBox ShellComboBox1Root rfDesktopAlign alLeft

ShellListView1

ShellComboBox ShellComboBox1ShellTreeView ShellTreeView1PopUpMenu PopUpMenu1Align alClient

Panel2Caption Nova Pasta:Alignment alLeftJustifyVisible False

Edit1 Text Vazio (null)BitBtn1 Caption Ok Click BitBtn1ClickPopUpMenu1 Items Nova Pasta

MainMenu1

Images ImageList1

Items

Arquivo Criar Nova Pasta FecharVisualizar Detalhes Ícones pequenos Ícones grandes Lista

Page 106: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 106 de 272

begin ShellListView1.ViewStyle:=vsReport; // Ajusta para detalhesend;

procedure TForm1.Iconespequenos1Click(Sender: TObject);begin ShellListView1.ViewStyle:=vsSmallIcon; // Ajusta para icones pequenosend;

procedure TForm1.Iconesgrandes1Click(Sender: TObject);begin ShellListView1.ViewStyle:=vsIcon; // Ajusta para icones grandesend;

procedure TForm1.Lista1Click(Sender: TObject);begin ShellListView1.ViewStyle:=vsList; // Ajusta para listaend;

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:

Page 107: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 107 de 272

Prática 35 – Outro gerenciador de arquivos

Formulário:

Objeto Propriedade Valor Evento ProcedimentoForm1 Caption Pratica 35 OnCreate Form1Create

Panel1

Name StatusBar1Align alTopColor clNavyFont.Color clWhite

Image1 Name FloppyVisible False

Image2 Name FixedVisible False

Image3 Name NetworkVisible False

Image4 Name CDRomVisible False

Image5 Name RamDiskVisible False

ScrollBox1 Align alClientDirectoryOutline1 OnChange DirectoryOutline1Change

FileList1

Align alClient OnChange FileList1ChangePopupMenu PopArquivosShowGlyphs True

OnMouseDown FileList1MouseDown

Page 108: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 108 de 272

TabSet1 Align alBottom

ScrollBox2 Align alBottomVisible False

Label1 Name ArquivoCaption Arquivo

Label2 Name CaminhoCaption Caminho

Label3 Name ModificacoesCaption Modificacoes

StaticText1

Align alTopBorderStyle sbsSunkenCaption PropriedadesColor clNavyFont.Color clWhiteFont.Style [fsBold]

GroupBox1 Caption Attributos

CheckBox1 Name ReadOnlyCaption &Read Only

CheckBox2 Name ArchiveCaption &Archive

CheckBox3 Name SystemCaption &System

CheckBox4 Name HiddenCaption &Hidden

BitBtn1 Caption OK OnClick BitBtn1Click

ScrollBox3 Align alBottomVisible False

Label4 Name diretorioCaption Diretorio

Label5 Caption DeLabel6 Caption Para

StaticText2

Align alTopBorderStyle sbsSunkenCaption Move, Renomeia,

CopiaColor clNavyFont.Color clWhiteFont.Style [fsBold]

Edit1 Name OrigemEdit2 Name DestinoBitBtn2 Caption OK OnClick BitBtn2Click

PopupMenu1

Name PopArquivos

Items

Abrir OnClick Abrir1ClickMover OnClick MoveCopiaRenomeiaCopiar OnClick MoveCopiaRenomeiaDeletar OnClick Deletar1ClickRenomear OnClick MoveCopiaRenomeiaPropriedades OnClick Propriedades1Click

Page 109: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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;

Page 110: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 111: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 listaend;

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

Page 112: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

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

Page 113: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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;

Page 114: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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;

Page 115: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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;

Page 116: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.

Page 117: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 ProcedimentoForm1 Caption Pratica 36

Panel1

Caption Vazio (null)Align alBottomName PanelanimacaoVisible False

Panel2

Caption Vazio (null)Align alBottomName PanelZoomVisible False

Panel3

Caption Vazio (null)Align alBottomName Panel3DVisible False

CheckBox1 Name Animar OnClick animarClickCaption Animar Pizza

CheckBox2Name Dimensao OnClick dimensaoClickCaption 3DChecked True

TrackBar1

Name VelocidadeMax 30Min 1Position 5

Label1 Caption LentoLabel2 Caption Rápido

Page 118: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 118 de 272

BitBtn1 Caption Fechar OnClick FechaanimacaoClickName Fechaanimacao

BitBtn2 Caption Mais Zoom OnClick ZoommaisClickName Zoommais

BitBtn3 Caption Menos Zoom OnClick ZoommenosClickName Zoommenos

BitBtn4 Caption Fechar FechazoomClickName Fechazoom

Label3 Caption Percentual de 3D:Label4 Caption Rotação:Label5 Caption Perspectiva:Label6 Caption Inclinação:

Edit1 Text 15 OnChange percentual3dChangeName Percentual3D

Edit2 Text 360 OnChange RotacaoChangeName Rotacao

Edit3 Text 0 OnChange PerspectivaChangeName Perspectiva

Edit4 Text 0 OnChange InclinacaoChangeName Inclinacao

UpDown1

Name UpDpercentualMax 100Min 1Associate Percentual3DPosition 15

UpDown2

Name UpDRotacaoMax 360Min 0Associate RotacaoPosition 360

UpDown3

Name UpDPerspectivaMax 360Min 0Associate PerspectivaPosition 0

UpDown4

Name UpDInclinacaoMax 360Min 0Associate InclinacaoPosition 0

BitBtn5 Caption Fechar OnClick Fecha3dClickName Fecha3d

GroupBox1 Caption ValoresVisible False

Edit5 Text Vazio (null)Name Valor

Edit6 Text Vazio (null)Name Descricao

BitBtn6 Caption Anexar OnClick AnexarClickName Anexar

BitBtn7 Caption Fechar OnClick FecharvaloresClickName FechaValores

Timer1 Interval 10 OnTimer Timer1TimerButton2 OnClick Button2ClickChart1 Ver a seguir

Page 119: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 119 de 272

MainMenu1 Items

Configurar

Informar valores OnClick Informarvalores1Click

Animar OnClick Animar1ClickZoom OnClick Zoom1Click3D e posicoes OnClick 3Deposicoes1Click

Visualizar

Gráfico de Barras

OnClick Grficodebarras1Click

Gráfico de Áreas OnClick Grficodereas1Click

Gráfico de Pizza OnClick Grficopizza1Click

Gráfico de Linhas

OnClick Grficodelinhas1Click

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;

Page 120: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 120 de 272

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

procedure TForm1.Grficodereas1Click(Sender: TObject);begin ativachart(chart1,1); // indica que a série 1 deverá ser ativaend;

procedure TForm1.Grficopizza1Click(Sender: TObject);begin ativachart(chart1,2); // indica que a série 2 deverá ser ativaend;

procedure TForm1.Grficodelinhas1Click(Sender: TObject);begin ativachart(chart1,3); // indica que a série 3 deverá ser ativaend;

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 groupbox1end;

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;

Page 121: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 121 de 272

end;

procedure TForm1.Animar1Click(Sender: TObject);begin Panelanimacao.Visible:=true; // mostra o panel de animaçãoend;

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 zoomend;

procedure TForm1.FechazoomClick(Sender: TObject);begin panelzoom.Visible:=false; // oculta o panel de zoomend;

procedure TForm1.FechaanimacaoClick(Sender: TObject);begin Panelanimacao.Visible:=false; // oculta o panel de animaçãoend;

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)

Page 122: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 chartend;

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 panel3dend;

procedure TForm1.N3Deposicoes1Click(Sender: TObject);begin Panel3d.Visible:=true; // mostra o panel3dend;

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.

Page 123: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 123 de 272

Field Name Type Size KeyDescricao Alpha 10Valor Short

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

abaixo:

Descricao ValorJoão 16Ana 9Paula 6Pedro 14Carlos 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

Form1 Caption Pratica 36 OnActivate FormActivateOnClose FormClose

Panel1 Align alLeftPanel2 Align alClientCheckBox1 Caption Legenda OnClick CheckBox1Click

Checked TrueCheckBox2 Caption Marcas OnClick CheckBox2Click

Checked TrueGroupBox1 Align alBottom

Page 124: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 124 de 272

RadioGroup1

Caption Estilo das marcas

Items

ValorPercentualTítuloTítulo e ValorTítulo e percentual

OnClick RadioGroup1Click

ItemIndex 0

Table1Name TgraficoDatabaseName Dados TableName Grafico.db

DataSource1 DataSet Tgrafico

DBGrid1 Align alClientDataSource DataSource1

DBChart1Align alClient

SeriesList Adicione uma Pie 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 é ativoend;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);begin Tgrafico.Close; // fecha a tabela antes de fechar o formulárioend;

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

Page 125: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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:

Page 126: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

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.

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

Page 127: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 128: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.

Page 129: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 130: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 131: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.

Page 132: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.

Page 133: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 133 de 272

Rave Visual Designer

Configurações Gerais

File - New

File Save: Empregados.rav

Na Árvore de Objetos, selecione RaveProject e, no Painel de Propriedades, altere a propriedade Units para unMM (milímetros)

Painel da Árvore de objetos

Painel de Propriedades

Explicação sobre a propr. atual

A Página

Palhetas de componentesBarra de

ferramentas

Page 134: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 DadosPara 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.

Page 135: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.

Page 136: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 136 de 272

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:

rodapé de página

componente Region redimensionado

Page 137: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 137 de 272

BandStyle:

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.

Selecione:

Body Header (Cabeçalho)

First (Primeira página)

New Page (Nova página)

Page 138: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 139: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.

Page 140: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.

Page 141: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 141 de 272

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

Page 142: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 143: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 144: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 145: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 146: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 147: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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;

Page 148: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 LPT12 - para LPT23 - para LPT34 - 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 }

Page 149: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 150: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 150 de 272

{ Mostra o texto procurado } Label1.Caption := FTexto; end;end;

ObservaçõesNo 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);

Page 151: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesNã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çõesPara 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 }

Page 152: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesPara 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 }

Page 153: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesNã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

Page 154: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesSe 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çõesA 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

Page 155: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesNote 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] := '';

Page 156: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesEm 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 }

Page 157: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesExistem 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)

Page 158: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesOs 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çõesEste 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;

Page 159: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesEsta 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

Page 160: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 BDEend;

ObservaçõesSe 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);

Page 161: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesEste 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');

Page 162: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesCUIDADO! 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

Page 163: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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:

Page 164: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesSegundo 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 + '[email protected]', 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çõesCuidado! 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.

Page 165: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesAlé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çõesAlé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;

Page 166: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesO 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:

Page 167: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesPara 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);

Page 168: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 }

Page 169: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesDica 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

Page 170: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 170 de 272

I := StrToInt('$' + Edit1.Text); {...}end;ObservaçõesNo 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çõesNeste 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 }

Page 171: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesCom 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çõesNão se esqueça de informar o caminho (path) do arquivo completo. Esta função foi desenvolvida para Delphi 32 bits (2, 3, 4,...).

Page 172: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesNeste 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çõesConsulte 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

Page 173: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesAparentemente, 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çõesQualquer 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 }

Page 174: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 174 de 272

else { ... NumLock está desligada }ObservaçõesQualquer 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çõesCuidado 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çõesO 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

Page 175: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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;

Page 176: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesOs 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 doif 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;

Page 177: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesA 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;

Page 178: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 178 de 272

ObservaçõesExistem 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;

Page 179: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesQualquer 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);

Page 180: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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;

Page 181: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 181 de 272

ObservaçõesUse 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;

Page 182: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesEste 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;

Page 183: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 183 de 272

{ Exemplo de como usá-la: }

var S: string; Numero: integer; {...}begin {...} S := tbStrZero(Numero, 6); {...}end; ObservaçõesSe 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çõesPodemos 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;

Page 184: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 184 de 272

ObservaçõesA 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çõesSe 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';

Page 185: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 185 de 272

pw.ShowModal; finally pw.Free; end;end;ObservaçõesAs 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çõesNormalmente, 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, &Yend;

{ Soma dois inteiros de 16 bits }function Soma16(X, Y: Word): Word;asm mov ax, &X add ax, &Yend;

{ Soma dois inteiros de 32 bits }function Soma32(X, Y: DWord): DWord;asm mov eax, &X

Page 186: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 186 de 272

add eax, &Yend;

{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

Page 187: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesPara 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;

Page 188: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesA 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çõesPode-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çõesA 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

Page 189: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesAo 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

Page 190: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 190 de 272

{ Local Share está FALSE }ObservaçõesA 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çõesAqui 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 apenasem 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áriopara 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);

Page 191: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesUm 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');

Page 192: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesPara 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

Page 193: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesPara 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');

Page 194: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesA 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.5465ObservaçõesIsto 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;

Page 195: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 195 de 272

end;

{ Chame-a como nos exemplos abaixo: }tbDBDeleteAll(Table1);outbDBDeleteAll(Query1);ObservaçõesSe 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çõesUsando este recurso, a acentuação não fica excelente, mas melhora bastante.

Imprimir texto justificado com formatação na impressora Epson LX-300

Page 196: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesEste 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 }

Page 197: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesPara 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

Page 198: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesSó 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çõesA 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

Page 199: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesEsta 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çõesPara 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,

Page 200: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesAo 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çõesAconselho 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);

Page 201: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesPara 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 lixeiraInclua 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

Page 202: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 202 de 272

Se você está habituado a usar este código no filter...

Table1.Filter := 'Nome = '''+ Edit1.Text + '''';ouTable1.Filter := 'Data = ''' + DateToStr(Date) + '''';

Tente usar este:

Table1.Filter := 'Nome = ' + QuotedStr(Edit1.Text);ouTable1.Filter := 'Data = ' + QuotedStr(DateToStr(Date));ObservaçõesA 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çõesTroque 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çõesSe 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çõesEste 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: }

Page 203: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesEm 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);

Page 204: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesSe 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çõesNo 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

Page 205: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 205 de 272

ShowMessage('Erro ao copiar ' + Origem + ' para ' + Destino);end;ObservaçõesNo 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çõesHá 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

Page 206: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesNo 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);

Page 207: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 207 de 272

end; finally { Fecha o Word } Word.Quit; end;end;ObservaçõesForam 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 BDEconforme abaixo:

var Total: integer;begin Check(DbiGetRecordCount(Table1.Handle, Total)); ShowMessage('Total de registros: ' + IntToStr(Total));end; ObservaçõesPara 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

Page 208: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesPara 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;

Page 209: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesPara 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çõesO 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;

Page 210: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 210 de 272

ObservaçõesPara 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;

interfaceuses 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;

Page 211: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesO 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;_'; // Telefoneend;

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

Page 212: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesPara 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

Page 213: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 213 de 272

Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end; finally F.Free; end;end.ObservaçõesO 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çõesCuidado! 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);

Page 214: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesA 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;

Page 215: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesA 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çõesA 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çõesTroque 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.

Page 216: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesIsto 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çõesVeja 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çõesNo 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. }

Page 217: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesNa 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

Page 218: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 218 de 272

{ Pausa por 1 segundo }Sleep(1000);

{ Pausa por 10 segundos }Sleep(10000);ObservaçõesEsta 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çõesPara 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

Page 219: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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çõesPara 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);

Page 220: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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);beginform1.close;end; procedure TForm1.FormDestroy(Sender: TObject);begin nid.uFlags := 0; Shell_NotifyIcon (NIM_DELETE, @nid);end;procedure TForm1.Lloyd1Click(Sender: TObject);beginShowmessage('LloydSoft é D+'); {Menu Popup}end;

Page 221: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 222: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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);beginform1.close;end; procedure TForm1.FormDestroy(Sender: TObject);begin nid.uFlags := 0; Shell_NotifyIcon (NIM_DELETE, @nid);end; procedure TForm1.Lloyd1Click(Sender: TObject);beginShowmessage('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);varr: String;begincase ShellExecute(Handle, nil, PChar(F), nil, nil, SW_SHOWNORMAL) ofERROR_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.';elseExit;end;ShowMessage(r);end;

Page 223: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 223 de 272

Utilize a função assim: procedure TForm1.Button1Click(Sender: TObject);beginExecFile('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 );varOpStruc: TSHFileOpStruct;FromBuffer, ToBuffer: Array[0..128] of Char;beginfillChar( OpStruc, Sizeof(OpStruc), 0 );FillChar( FromBuffer, Sizeof(FromBuffer), 0 );FillChar( ToBuffer, Sizeof(ToBuffer), 0 );StrPCopy( FromBuffer, sPath);With OpStruc DoBeginWnd:= 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);beginDeleteDir( Self.Handle,'C:\TESTE');end;

Como verificar se um arquivo existe?

If not(fileexists('c:\windows\nuvens.bmp')) then Showmessage('Arquivo inexistente');

Page 224: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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;

Page 225: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 226: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 227: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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);Vars: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:

Page 228: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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;

Page 229: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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;

Page 230: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 231: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 DelphiEm 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)

Page 232: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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.0TYPE SERVERDLL32 SQLORA32.DLLVENDOR INIT ORA73.DLLDRIVER FLAG (DEIXAR VAZIO)TRACE MODE 0BATCH COUNT 200BLOB SIZE 32BLOBS TO CACHE 64ENABLE BCD FALSEENABLE INTEGERS FALSEENABLE SCHEMA CACHE FALSELANGDRIVER (DEIXAR VAZIO)LIST SYNONYMS NONEMAX ROWS

Page 233: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 233 de 272

–1NET PROTOCOL TNSOBJECT MODE TRUEOPEN MODE READ/WRITEROWSET SIZE 20SCHEMA CACHE DIR (DEIXAR VAZIO)SCHEMA CACHE SIZE 8SCHEMA CACHE TIME –1SERVER NAME (COLOQUE O NOME DA INSTANCIA DO BANCO, DEFAULT: ORCL)SQLPASSTHRU MODE SHARED AUTOCOMMITSQLQRYMODE SERVERUSER 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 // ChangeNetDirprocedure 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,

Page 234: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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);BeginWith Origem do While RecordCount > 0 doDelete;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

Page 235: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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);varI: Integer;begin

Page 236: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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);varI: 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.

Page 237: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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\Dll32var Reg : TRegistry;begin Reg := TRegistry.Create; try Reg.RootKey := HKEY_LOCAL_MACHINE; if Reg.OpenKey('\Software\Borland\DataBaseEngine\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.

Page 238: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

varsArquivo: TextFile;Entrada, sArq2: string;iLinha: integer;begintblCep.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 LocalidadesRzProgressBar1.TotalParts := 0;RzProgressBar1.TotalParts := NumLinhasArq(FileNameEdit1.FileName); Reset(sArquivo);Readln(sArquivo,Entrada);while not Eoln(sArquivo) do beginInc(iLinha);Readln(sArquivo,Entrada); // 0 = Base Total e 2 = Inclusaoif (copy(Entrada,90,1) = '0') or (copy(Entrada,90,1) = '2') thenbegintblCepLoc.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);trytblCepLoc.Post;excepttblCepLoc.Cancel;end;endelse if (copy(Entrada,90,1) = '1') then begin // Exclusaoif tblCepLoc.Locate('cep_ChvLocal', copy(Entrada,1,6),[loPartialKey]) thentblCepLoc.Delete;endelse if (copy(Entrada,90,1) = '3') then begin // Alteracaoif tblCepLoc.Locate('cep_ChvLocal', copy(Entrada,1,6),[loPartialKey])then begintblCepLoc.Edit;tblCepLoc.FieldByName('cep_Cidade').AsString :=copy(Entrada,7,60);tblCepLoc.FieldByName('cep_UF').AsString :=

Page 239: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 239 de 272

copy(Entrada,75,2);end;trytblCepLoc.Post;excepttblCepLoc.Cancel;end;end;RzProgressBar1.PartsComplete := iLinha;Application.ProcessMessages;if bCancelaImport thenBreak;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;BeginDialog.InitialDir := 'c:\temp';Dialog.Execute;if Dialog.FileName <> '' ThenBeginif not (Tabela.State in [dsEdit, dsInsert]) ThenTabela.Edit;

Page 240: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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);beginGrava_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 figuraend;

Ler imagem JPG da tabela Paradox

Procedure Le_Imagem_JPEG(Campo:TBlobField; Foto:TImage);var BS:TBlobStream;MinhaImagem:TJPEGImage;Beginif Campo.AsString <> '' ThenBeginBS := TBlobStream.Create((Campo as TBlobField), BMREAD);MinhaImagem := TJPEGImage.Create;MinhaImagem.LoadFromStream(BS);Foto.Picture.Assign(MinhaImagem);BS.Free;MinhaImagem.Free;EndElse Foto.Picture.LoadFromFile('c:\temp\limpa.jpg');End; procedure TForm1.Button1Click(Sender: TObject);beginLe_Imagem_JPEG(TbClientesCli_Foto, Image1);// TbClientesCli_Foto é um variavel da tabela do tipo Blob// Image1 é um componenteend;

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:

Page 241: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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);beginIf table1PRAZO.Value > DATE then // condiçãoDbgrid1.Canvas.Font.Color:= clFuchsia; // coloque aqui a cor desejadaDbgrid1.DefaultDrawDataCell(Rect, dbgrid1.columns[datacol].field, State);end;

Page 242: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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;interfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Db, DBTables, Grids, DBGrids, StdCtrls; typeTForm1 = 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;varForm1: TForm1; implementation{$R *.DFM} procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);beginIf odd(Table1.RecNo) thenbeginDBGrid1.Canvas.Font.Color:= clWhite;DBGrid1.Canvas.Brush.Color:= clGreen;endelsebeginDBGrid1.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);BeginFindReplace(Edit1.Text,Edit2.Text, Memo1);end; Procedure FindReplace (const Enc, subs: String; Var Texto: TMemo);Vari, Posicao: Integer;Linha: string;

Page 243: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 243 de 272

BeginFor i:= 0 to Texto.Lines.count - 1 dobeginLinha := Texto. Lines[i];RepeatPosicao:=Pos(Enc,Linha);If Posicao > 0 thenBeginDelete(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çõesEste 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%"

Page 244: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 usesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls; typeTForm1 = class(TForm)Button1: TButton;Label1: TLabel;procedure Button1Click(Sender: TObject);function MesExtenso( Mes:Word ) : string;private{ Private declarations }public{ Public declarations }end; varForm1: TForm1; implementation

Page 245: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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');beginresult := meses[mes-1];End; procedure TForm1.Button1Click(Sender: TObject);beginlabel1.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

Page 246: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 Formprocedure 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);beginApplication.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);beginApplication.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);beginAction:= 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

Page 247: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 248: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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

Page 249: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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;

Page 250: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 250 de 272

VarSerial:DWord;DirLen,Flags: DWord;DLabel : Array[0..11] of Char;beginTry GetVolumeInformation(PChar(FDrive+':\'),dLabel,12,@Serial,DirLen,Flags,nil,0);Result := IntToHex(Serial,8); Except Result :='';end;end;

Como desenhar um Bitmap num form

varForm1: 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 unitvar 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;

Page 251: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 251 de 272

Result := True; end; finally Free; end; end; end;end;

Carregar um cursor animado (*.ani)

constcnCursorID1 = 1;beginScreen.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);

Page 252: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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}constRomans: 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);vari: Integer;scratch: String;

Page 253: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 À DIREITAprocedure TForm1.Edit1Exit(Sender: TObject);var n: Integer; c: TCanvas; h: HWND; // pode se usar Form1.Canvas se for a mesma fonte do Editbegin 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; vari : 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);vari : Integer;beginfor i := 0 to Form.ComponentCount - 1 doif 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

Page 254: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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;beginMail := 'mailto:[email protected]';ShellExecute(GetDesktopWindow,'open',pchar(Mail),nil,nil,sw_ShowNormal);end;

Page 255: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 thenMessageDlg('Cannot find directory', mtWarning, [mbOk], 0);end; function Chr(X: Byte): Char;Retorna o caracter com o código ASCII XbeginCanvas.TextOut(10, 10, Chr(65)); { The letter 'A'}end; function Concat(s1 [, s2,..., sn]: string): string;Concatena as stringsvarS: string;beginS := 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 caractersThe Copy function returns a substring of a string.var S: string;beginS := '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 atualprocedure TForm1.Button1Click(Sender: TObject);beginLabel1.Caption := 'Today is ' + DateToStr(Date);end; function DateToStr(Date: TDateTime): string;Converte Data para Stringprocedure TForm1.Button1Click(Sender: TObject);beginLabel1.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 é 7procedure TForm1.Button1Click(Sender: TObject);

Page 256: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 256 de 272

varADate: TDateTime;beginADate := 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);varPresent: TDateTime;Year, Month, Day, Hour, Min, Sec, MSec: Word;beginPresent:= 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);varPresent: TDateTime;Year, Month, Day, Hour, Min, Sec, MSec: Word;beginPresent:= 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 Indexvars: string;begins := '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.

Page 257: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 257 de 272

Onde : 0 = Corrente, 1 = A, 2 = B,...DiskFree retorna –1 se o driver for inválidovarS: string;beginS := 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álidovarS: string;beginS := 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 Dayprocedure TForm1.Button1Click(Sender: TObject);varMyDate: TDateTime;beginMyDate := 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 MSecprocedure TForm1.Button1Click(Sender: TObject);varMyTime: TDateTime;beginMyTime := 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 arquivoForm1.Caption := 'Editing '+ ExtractFileName(FileName); function ExtractFilePath(const FileName: string): string;Retorna o Path de um arquivoChDir(ExtractFilePath(FileName));

Page 258: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 existirif FileExists(FileName) thenif 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 textovarf: file of Byte;size : Longint;S: string;y: integer;beginif Opendialog1.Execute then beginAssignFile(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 charvarS: 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ó vezprocedure TForm1.Button1Click(Sender: TObject);varDir: string;beginDir := 'C:\APPS\SALES\LOCAL';ForceDirectories(Dir);if DirectoryExists(Dir) then

Page 259: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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álidosSpecifier&#9;Displaysc&#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

Page 260: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 260 de 272

Specifier&#9;Represents0&#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;00.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;Zero0.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

Page 261: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 261 de 272

function Frac(X: Real): Real;Retorna a parte fracional do parâmetro XvarR: Real;beginR := 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;Drive0&#9;Corrente1&#9;A2&#9;B3&#9;Cvars : string;beginGetDir(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 XvarIntVar: Integer;LongintVar: Longint;beginInc(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);varInputString: string;beginInputString:= 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);varNewString: string;

Page 262: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 262 de 272

ClickedOK: Boolean;beginNewString := '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 IndexvarS: string;beginS := '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 retornadosprocedure TForm1.Button1Click(Sender: TObject);beginEdit2.Text := IntToHex(StrToInt(Edit1.Text), 6);end; function IntToStr(Value: Integer): string;Trasnforma um Inteiro numa Stringprocedure TForm1.Button1Click(Sender: TObject);varValue: Integer;beginValue := 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 SvarS: string;beginS := '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;

Page 263: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 263 de 272

Exibe uma Caixa de Mensagem e obtem uma resposta do usuário.OndeMsg : MensagemAType : Tipo da caixa de mensagemValue&#9;MeaningmtWarning&#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 mensagemValue&#9;&#9;&#9;&#9;MeaningmbYes&#9;&#9;&#9;A button with the text 'Yes' on its facembNo&#9;&#9;&#9;A button with the text 'No' on its facembOK&#9;&#9;&#9;A button with the text 'OK' on its facembCancel&#9;&#9;A button with the text 'Cancel' on its facembHelp&#9;&#9;&#9;A button with the text 'Help' on its facembAbort&#9;&#9;A button with the text 'Abort' on its facembRetry&#9;&#9;&#9;A button with the text 'Retry' on its facembIgnore&#9;&#9;A button with the text 'Ignore' on its facembAll&#9;&#9;&#9;A button with the text 'All' on its facembYesNoCancel&#9;&#9;Puts Yes, No, and Cancel buttons in the message boxmbOkCancel&#9;&#9;Puts t OK and Cancel buttons in the message boxmbAbortRetryIgnore&#9;Puts Abort, Retry, and Ignore buttons in the message boxMessageDlg returns the value of the button the user selected. These are the possible return values:Return &#9;valuesmrNone&#9;&#9;mrAbort&#9;&#9;mrYesmrOk&#9;&#9;mrRetry&#9;&#9;mrNomrCancel&#9;mrIgnore&#9;mrAllprocedure TForm1.Button1Click(Sender: TObject);beginif MessageDlg('Welcome to my Object Pascal application. Exit now?',mtConfirmation, [mbYes, mbNo], 0) = mrYes thenbeginMessageDlg('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á exibidaprocedure TForm1.Button1Click(Sender: TObject);beginMessageDlgPos('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óriouses Dialogs;begin

Page 264: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 264 de 272

{$I-}{ Get directory name from TEdit control }MkDir(Edit1.Text);if IOResult <> 0 thenMessageDlg('Cannot create directory', mtWarning, [mbOk], 0)elseMessageDlg('New directory created', mtInformation, [mbOk], 0);end; function Now: TDateTime;Retorna a data e a hora correnteprocedure TForm1.Button1Click(Sender: TObject);beginLabel1.Caption := 'The date and time is ' + Str(Now);end; function Ord(X): Longint;Retorna a ordem de um valor ordinaluses Dialogs;typeColors = (RED,BLUE,GREEN);varS: string;beginS := '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 PI3.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 encontrouvar S: string;beginS := ' 123.5';{ Convert spaces to zeroes }while Pos(' ', S) > 0 doS[Pos(' ', S)] := '0';end; function Power(Base, Exponent: Extended): Extended;Potência function Pred(X);Retorna o predecessor de um ordinaluses Dialogs;typeColors = (RED,BLUE,GREEN);varS: string;beginS := '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 thenS := S + 'In the type Colors, RED is the predecessor of BLUE.';

Page 265: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 265 de 272

MessageDlg(S, mtInformation, [mbOk], 0);end; function Random [ ( Range: Integer) ];Retorna um valor Randômico0 <= X < Range.varI: Integer;beginRandomize;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 RandomicovarI: Integer;beginRandomize;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 PCharuses Dialogs;varf : file;beginOpendialog1.Title := 'Choose a file... ';if Opendialog1.Execute then beginSaveDialog1.Title := 'Rename to...';if SaveDialog1.Execute then beginAssignFile(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 insucessoThe following code renames a file:if not RenameFile('OLDNAME.TXT','NEWNAME.TXT') thenErrorMsg('Error renaming file!'); procedure RmDir(S: string);Remove um diretóriouses Dialogs;

Page 266: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 266 de 272

begin{$I-}{ Get directory name from TEdit control }RmDir(Edit1.Text);if IOResult <> 0 thenMessageDlg('Cannot remove directory', mtWarning, [mbOk], 0)elseMessageDlg('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 é alteradoThese are the possible values that can be added to the Options set:Value&#9;&#9;MeaningsdAllowCreate&#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);varDir: string;beginDir := 'C:\MYDIR';if SelectDirectory(Dir, [sdAllowCreate, sdPerformCreate, sdPrompt]) thenLabel1.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 stringS[0] := NewLength. procedure ShowMessage(const Msg: string);Exibe uma mensagem ao usuárioprocedure TForm1.Button1Click(Sender: TObject);begin

Page 267: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

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 sensitivityReturn 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 ChS := StringOfChar('A', 10);{sets S to the string 'AAAAAAAAAA'} function StrToDate(const S: string): TDateTime;Converte uma string em dataprocedure TForm1.Button1Click(Sender: TObject);varADate: TDateTime;beginADate := StrToDate(Edit1.Text);Label1.Caption := DateToStr(ADate);end; function StrToDateTime(const S: string): TDateTime;Converte uma string para o formato DateTimeprocedure TForm1.Button1Click(Sender: TObject);varADateAndTime: TDateTime;beginADateAndTime := 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 inteiroprocedure TForm1.Button1Click(Sender: TObject);varS: string;I: Integer;beginS := '22467';I := StrToInt(S);Inc(I);Edit1.Text := IntToStr(I);end; function StrToTime(const S: string): TDateTime;Converte uma string em hora

Page 268: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 268 de 272

procedure TForm1.Button1Click(Sender: TObject);varATime: TDateTime;beginATime := StrToTime(Edit1.Text);Label1.Caption := TimeToStr(ATime);end; function Succ(X);Retorna o sucessor de um ordinaluses Dialogs;typeColors = (RED,BLUE,GREEN);varS: string;beginS := '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 thenS := 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 correnteprocedure TForm1.Button1Click(Sender: TObject);beginLabel1.Caption := 'The time is ' + TimeToStr(Time);end; function TimeToStr(Time: TDateTime): string;Converte hora para stringprocedure TForm1.Button1Click(Sender: TObject);beginLabel1.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úsculauses Dialogs;var

Page 269: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 269 de 272

s : string;i : Integer;begin{ Get string from TEdit control }s := Edit1.Text;for i := 1 to Length(s) dos[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úsculasprocedure TForm1.Button1Click(Sender: TObject);varI: Integer;beginfor I := 0 to ListBox1.Items.Count -1 doListBox1.Items[I] := UpperCase(ListBox1.Items[I]);end;

Consulte outras dicas no CD ou pesquise na internet.

Page 270: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 270 de 272

ÍNDICE

Assunto Pág.Capitulo I – Definições 1

Sistema Operacional 1Linguagem 1Linguagem estruturada 1Linguagem orientada a objeto 1Constantes 1Variáveis 1Operadores 2Dados 3Banco de Dados 3Rotina 4Procedimento 4Comandos 4Estruturas 4

Capitulo II – Componentes básicos da orientação a objetos 5Classe 5Objeto 5Instância 5Propriedade 5Método 5Mensagem 6Interface 6Evento 6Procedimento 6Tempo de Projeto 6Tempo de Execução 6

Capitulo III – Apresentação do Delphi 2005 6Tela de Abertura 6VCL Form Application for WIN 32 7Object Inspector 8Caixa de estruturas (Structure) 8A Paleta de Componentes 8Gerente do projeto (Project Manager) 9O Formulário 10A Unit 10Estrutura de uma Unit 11

Capitulo IV – Os primeiros contatos 12Prática 01: O primeiro projeto 12Prática 02: Alterando algumas propriedades do formulário 13Prática 03 - Exercício 01 13

Capitulo V – Estruturas 14Estrutura de bloco 14

Prática 04 15Pratica 05 – Exercício 02 16

Estruturas de decisão 17Pratica 06: Acendendo uma lâmpada 18Prática 07 19Pratica 08 – Exercício 03 20Pratica 09: Controlando o trânsito 21Projeto 10: Promovendo descontos 22Pratica 11 – Exercício 04 24

Estruturas de loop ou laço 24Pratica 12: Demonstração do Repeat ... Until 25Pratica 13 – Exercício 05 26

Estruturas consecutivas 27

Page 271: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 271 de 272

Pratica 14: Demonstração do With...do 27Estruturas de exceção 28

Capitulo VI – Bancos de dados 28O BDEAdministrator 29O MSSQL Server 32

Capitulo VII – O DataBase Desktop (DBD) 32Capitulo VIII – Trabalhando com o DataBase Desktop 34

Exercício 06 37Incrementando registros de uma tabela 37Navegando pelos registros de uma tabela 37Excluindo registros de uma tabela 38Organizando os registros de uma tabela 38Criando índices secundários 38

Exercício 07 39Capitulo IX – Incluindo tabelas em um formulário 39

O Data-Module 39Pratica 15: Incluindo uma senha 40

Criando um alias paradox 40Criando o data module 41

Capitulo X – Incluindo menus em um formulário 44Prática 16 – Montando um formulário de controle 45

Capitulo XI – Trabalhando com mais de um formulário 46Prática 17 – Anexando formulários 46

Capitulo XII – Estruturando um projeto 48Capitulo XIII – Incluindo, localizando e excluindo dados de uma tabela em tempo de execução 50

Prática 18 – Cadastro de clientes 52Exercício 08 – Crie um cadastro de produtos e um cadastro de

fornecedores62

Capitulo XIV – Respondendo a mensagens 62Prática 19 – Utilizando o comando messagedlg 63Prática 20 – Utilizando o comando messagedlg 64Prática 21 – Utilizando o comando messagedlgpos 65Exercício 09 65

Capitulo XV – Rotinas especiais (Procedures e Funções) 65Capitulo 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º) 73Prática 24 – Localizando registros (métodos Locate) 75Prática 25 – Localizando registros (métodos Filter) 78

Exercício 10 – Crie consultas para o seu projeto 79Capitulo XVII – Relacionando tabelas 80

Prática 26 – Relacionamento I 82Prática 27 – Relacionamento II 84

Capitulo XVIII – O SQL 86Criando uma query pelo DataBase Desktop 86Criando uma relação entre duas tabelas através do query de modo interativo 87Criando 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, itens e materias em tempo de execução 90

Prática 29 – Selecionando todas as compras de um cliente 91Operadores WHERE 92Exemplos de consultas 93

Capitulo XIX – Trabalhando com mídias 95Prática 30 – Lendo mídias com uso de objetos 95Prática 31 – Tocando sons wave via função 97

Capitulo XX – Trabalhando com diálogos 98

Page 272: Delphi 2005 - Básico

[email protected]

Delphi 2005 for win32Fábio José de Gondra Ramos

Página 272 de 272

Prática 32 – Trabalhando com diálogos 98Capitulo XXI – Trabalhando unidades, pastas e arquivos 101

Prática 33 – Localizando e executando arquivos via objetos 101Prática 34 – Um gerenciador de arquivos 104Prática 35 – Outro gerenciador de arquivos 105

Capitulo XXII – Trabalhando com gráficos 112Prática 36 – Criando gráficos 115Prática 37 – Criando gráficos com tabelas 121

Capitulo XXIII – Literatura complementar 124Literatura 01 – Criando o arquivo de ajuda 124Literatura 02 – O Rave Report 130

Capitulo XXIV – Dicas da internet 140