Escolar Documentos
Profissional Documentos
Cultura Documentos
Biblia Delphi 7 PTBR
Biblia Delphi 7 PTBR
Fernando Anselmo
Borland
Todos os nomes dos produtos citados so marcas registradas da Borland International, Inc. Outros produtos citados so marcas registradas no respectivo cabealho As vrias Marcas Registradas que aparecem no decorrer deste livro. Mais do que simplesmente listar esses nomes e informar quem possui seus direitos de explorao, ou ainda imprimir o logotipo das mesmas, o autor declara estar utilizando tais nomes apenas para fins editoriais, em benefcio exclusivo do dono da marca registrada, sem inteno de infringir as regras de sua utilizao.
ii
SUMRIO
Desvendando o Caminho das Pedras i
INTRODUO
Delphi, como Soluo para Desenvolvedores
7
7
CAPTULO I
Conceito de Programao Orientada a Objeto Orientao a Objeto Object Pascal Smbolos Especiais Palavras Reservadas Nmeros Constantes Expresses Identificadores Declaraes Blocos de Procedimentos ou Funes Caractersticas de Objetos Programando com objetos Delphi Renomeando os objetos e os componentes
9
9 9 10 10 11 12 12 12 13 14 16 17 18 20
CAPTULO II
Conhecendo o Delphi Elementos Visveis Form Code Editor Component Palette Object Inspector SpeedBar Elementos no Visveis Project Manager Menu Designer Fields Editor Repositrio de Objetos Estrutura de Aplicaes com o Delphi 2.0 Implementao efetiva Objetos Data Module Dicionrio de Dados Escalvel Herdando os Formulrios Ferramentas Auxiliares de SQL Monitor SQL SQL Explorer InterBase NT - Banco de Dados Relacional
21
21 21 22 23 23 24 24 24 25 25 26 27 28 29 29 30 31 32 32 33 34
CAPTULO III
Projeto Piloto iii
35
35
Borland
Criando o Modelo Relacional Trabalhando com DataBase Engine Configuration Criando o Alias Trabalhando com DataBase DeskTop Criando o Banco de Dados via Estrutura Criando os Relacionamentos via Estrutura Criando o Banco de Dados via SQL Observaes da utilizao do SQL com o dBase
CAPTULO IV
Trabalhando com o Menu Metendo a Mo na Massa Criando a janela do menu Inserindo os Cdigos Iniciais Iniciando os comandos do Menu Colocando os comandos para o Auxlio Criando a janela Sobre o Sistema Criando e alterando os objetos Associando o form Sobre o Sistema ao menu Criando a janela Splash Criando o acesso a Base de Dados
43
43 43 43 46 47 48 50 50 51 52 54
CAPTULO V
Janela para as Tabelas Reabrindo o seu Projeto Alterando as Janelas Criadas DataModules ? Modificando as Tabelas e as Ligaes Alterando os campos da tabela Codificando o DataModule Controlando a duplicao dos Campos-Chave Finalizando o DataModule Alterando o Formulrio Modificando os Labels e Campos Objeto DBNavigator Modificando os Paineis Modificando a Janela Criando o terceiro Painel Programando no formulrio Preservando as reas de Memria Criando Funes Globais Alterando o Menu para receber o formulrio
57
57 57 58 58 58 59 60 61 62 63 64 65 65 66 66 68 68 71 74
CAPTULO VI
Trabalhando com janela Pai X Filha Criando a janela automaticamente Sobre os DataModules Trabalhando com as Tabelas Trabalhando com os Campos Controlando o DataModule Contadores Validando os Campos Alterando a Janela Criada iv
77
77 77 79 79 81 82 83 84 87
Borland
Organizando os Panels Modificando os campos e Labels Organizando os Panels Modificando a Janela Trabalhando com Grids Finalmente, a programao Consulta Trabalhando com a rea de Transferncia Utilizando o objeto OpenDialog Criando o formulrio para o cadastro das msicas Criando novos Procedimentos Globais Alterando o Menu para receber o formulrio
CAPTULO VII
Trabalhando com consultas Criando consultas para tabelas Trabalhando com Grids Programando no formulrio Enviando e recebendo variveis Alterando o formulrio fCateg Alterando o formulrio fBasico Criando consultas para o cadastro Consultas SQL Realizando Consultas com Filtros Programando o formulrio Criando o formulrio Gerente do Filtro Programando o formulrio Editando os registros
106
106 106 106 109 110 110 111 114 114 114 118 125 128 129
CAPTULO VIII
Relatrios Trabalhando com o ReportSmith Criando relatrio com o ReportSmith Organizando os campos do relatrio Associando o relatrio ao aplicativo Programando o formulrio Imprimindo atravs do Formulrio Criando o Cdigo Trabalhando com o QuickReport
132
132 132 133 135 135 137 138 140 141
CAPTULO IX
Multimdia O que multimdia ? Delphi and Multimedia Objeto TMediaPlayer Colocando as propriedade em modo Runtime Pesquisando variveis em modo RunTime Inserindo o multimdia para o Sistema Desenvolvimento do CD Player
146
146 146 147 147 148 149 152 152
CAPTULO X
v
158
Borland
Desvendando o Caminho das Pedras 158 158 159 159 160 161 161 162 163 163 167
Novos Componentes Criando Componentes A Classe TComponent Um Componente Simples Adicionando o Componente a Palheta Criando Propriedades Mtodos de Acesso Criando novos tipos Pensando em Objetos Construindo um Objeto Finalmente
APNDICE A
Documentao Hardware/Software requeridos
168
168 168
APNDICE B
Converso de Campos Tipos de Dados para o InterBase
169
169 170
APNDICE C
Aplicao rpida com o Objeto Query
171
171
APNDICE D
Imprimindo um Formulrio
173
173
APNDICE E
Trabalhando com Mscaras
175
175
APNDICE F
Trabalhando com Importao e Exportao
177
177
APNDICE G
Doze melhores dicas para o Delphi
180
180
vi
Introduo
Bem-vindo ao Delphi, o mais novo produto de alta performance da Borland. Delphi um produto nico em sua categoria combinando cdigos totalmente compilveis, ferramentas visuais e tecnologia para a composio de bases de dados escalveis, possui facilidades para um rpido desenvolvimento em plataforma Windows e aplicaes Client/Server. Este trabalho ser seu guia para uma rpida aprendizagem no desenvolvimento de sistemas que gerencie bancos de dados. O Delphi encontrado em dois produtos: Delphi Client/Server, de alta performance e facilidade para o desenvolvimento de aplicaes e suporte a bancos de dados do tipo Cliente/Servidor. Delphi Desktop, de alta performance e facilidade para o desenvolvimento de aplicaes e suporte a bancos de dados locais, permitindo total portabilidade verso Client/Server.
Apresento-lhes a seguir algumas informaes detalhadas para um perfeito desenvolvimento visual, sendo que ao final de cada captulo prtico exibido o cdigo fonte completo seguido de um resumo dos principais comandos mostrados. Ao final deste estudo voc encontrar apndices que lhe ajudaro a resolver pequenos problemas do dia-a-dia.
Mas o que possvel fazer com ele ? possvel criar, dentre outros, os seguintes tipos de aplicaes em Delphi : Us-lo como a linguagem de desenvolvimento para bancos do tipo Cliente/Servidor; Ambiente heterogneo para captura e envio de informaes em diversos tipos de arquivos de dados;
Borland
Um pacote corporativo de aplicaes inteligentes e interpretadores de dados. Incorporando DLLs e EXEs externos; Pacotes multimdia com desenho e animao; Genricos utilitrios do Windows ; Criao de bibliotecas (DLL) para leitura por outras aplicaes.
Mas porque arriscar em um ambiente novo quando existe no mercado linguagens mais difundidas ? No mundo inteiro Delphi foi testado, e em 15 meses de vida produziu os seguintes resultados: Delphi est sendo utilizado no momento por mais de 1.500 lugares incluindo as maiores corporaes, consultores e organizaes de treinamento; Eleito pela Byte Magazines como Best of Comdex Award; Vrios livros escritos; Grupos de discusso e peridicos com dicas de desenvolvimento na WorldWibe (Consulte s listas da InterNet atravs da palavra DELPHI); Dezenas de bibliotecas e ferramentas para o suporte em Delphi; Dezenas de artigos em publicaes do mundo inteiro, tais como PC Week, InfoWorld, Computer Reseller News, PC Magazine, Windows Sources e muitas outras.
Por tudo aqui exposto fica claro que este no produto demonstra uma inovao para uma criao em alta performance de aplicaes. Todos os recursos que voc precisar para o desenvolvimento de seus produtos esto agora disponveis. Feliz desenvolvimento. Fernando Antonio F. Anselmo Sempre que voc localizar este smbolo significa que existe uma nota que lhe ajudar em caso de dvida.
Borland
Captulo I
Conceito de Programao Orientada a Objeto
Para compreendermos melhor a novo ambiente de desenvolvimento da Borland o Delphi necessrio que voc, aprenda e, tenha em mente os conceitos de POO (Programao Orientada a Objetos), no confunda os conceitos com POE (Programao Orientada a Eventos) muito difundido com o Access 2.0 (um ambiente baseado em Objetos), mas ao longo deste captulo voc vai notar as sensveis diferenas que existem entre esses dois conceitos. A POO e a POE so facilmente confundidas, mas lembre-se a POO contm a POE mas a POE no contm a POO, um objeto pode existir mesmo que no exista nenhum evento associado a ele, mas um evento no pode existir se no houver um objeto a ele associado. Outra caracterstica que pode causar confuso so ambientes Orientados a Objetos e ambientes Baseados em Objetos. Em ambiente Orientado a Objetos consegue-se criar e manipular objetos enquanto que o Baseado em Objetos no possivel a criao de objetos apenas a sua manipulao. A POO um conceito desenvolvido para facilitar o uso de cdigos de desenvolvimento em interfaces grficas. Sendo a Borland, uma das primeiras a entrar neste novo conceito, possui suas principais linguagens de programao (tais como Object Pascal e C++), totalmente voltadas para este tipo de programao. A POO atraiu muitos adeptos principalmente pelo pouco uso de cdigo que o projeto (diferente de sistema) carrega no programa fonte, ao contrrio das linguagens mais antigas como o Clipper87 muito utilizado no final da dcada de 90 e incio da dcada de 90. O resultado desta limpeza no cdigo resulta que a manuteno do projeto tornase muito mais simples.
Orientao a Objeto
Antes de comearmos a falar realmente de linguagem orientada a objetos e necessrio que voc possua os conceitos bsicos da orientao a objetos, so eles: Objeto - qualquer estrutura modular que faz parte de um produto. Uma janela por exemplo, um objeto de uma casa, de um carro ou de um software com interface grfica para o usurio. Atributos - So as caractersticas do objeto, como cor e tamanho, a janela, por exemplo, tem atributos como o modelo, tamanho, abertura simples ou dupla, entre outros. Encapsulao - um mecanismo interno do objeto escondido do usurio. Uma pessoa pode abrir uma janela girando a tranca sem precisar saber o que h dentro dela.
Borland
Ao - a operao efetuada pelo objeto. Todas as janelas, por exemplo, controlam a iluminao e temperatura ambiente, dependendo do seu design. Herana - um objeto novo nem sempre criado do zero. Ele pode herdar atributos e aes de outros j existentes. Um basculante herda atributos das janelas e das persianas. Polimorfismo - a capacidade de objetos diferentes reagirem segundo a sua funo a uma ordem padro. O comando abre, por exemplo, faz um objeto entrar em ao, seja ele uma janela, uma porta ou uma tampa de garrafa. Ligao - quando um objeto conecta a sua ao a outro. Um sensor de claridade, por exemplo, ativa o acendimento automtico da iluminao de rua. Embutimento - Permite a um objeto incorporar funes de outros, como um liqidificador que mi carne com a mudana do tipo da lmina.
Object Pascal
Object Pascal uma linguagem Orientada a Objetos no pura mas hbrida por possuir caractersticas de programao no s visual mas tambm escrita, para os programadores que j conhecem tcnicas de estruturas de programao, com o C, Basic, Pascal ou xBASE entre outras linguagens a Object Pascal providncia uma migrao de forma natural oferecendo um produto de maior complexibilidade. Object Pascal fora a voc executar passos lgicos isto torna mais fcil o desenvolvimento no ambiente Windows de aplicaes livres ou que utilizam banco de dados do tipo Cliente/Servidor, trabalha com o uso de ponteiros para a alocao de memria e todo o poder de um cdigo totalmente compilvel. Alm disso possibilita a criao e reutilizao (vantagem de re-uso to sonhado com a Orientao a Objetos) de objetos e bibliotecas dinmicas (Dynamic Link Libraries - DLL). Object Pascal contm todo o conceito da orientao a objetos incluindo encapsulamento, herana e polimorfismo. Algumas extenses foram includas para facilitar o uso tais como conceitos de propriedades, particulares e pblicas, e tipos de informaes em modo run-time, manuseamento de excees, e referncias de classes. O resultado de toda esta juno faz com que Object Pascal consiga suportar as facilidades de um baixo nvel de programao, tais como: Controle e acesso das subclasses do Windows (API); Passar por cima das mensagens de loop do Windows ; Mensagens semelhantes as do Windows ; Cdigo puro da linguagem Assembler.
[AL1] Comentrio:
Como deu para perceber a base de toda a programao Delphi a linguagem Object Pascal, ento neste captulo trataremos exclusivamente deste tipo de programao.
Smbolos Especiais
A Object Pascal aceita os seguintes caracteres ASCII:
10
Borland
9 9 9 9 9
Letras - do Alfabeto Ingls: A at Z e a at z. Dgitos - Decimal: 0 at 9 e HexaDecimal: 0 at 9 e A at F (ou a at f) Brancos - Espao (ASCII 32) e todos os caracteres de controle ASCII (ASCII 0 at ASCII 31), incluindo final de linha e Enter (ASCII 13). Especiais - Caracteres: + - * / = < > [ ] . , ( ) : ; ^ @ { } $ # Smbolos - Caracteres: <= >= := .. (* *) (. .) //
O colchetes esquerdo ( [ ) e equivalente ao (. e o colchetes direito ( ] ) e equivalente a .). A chave esquerda ( { ) e equivalente ao (* e a chave direita ( } ) e equivalente a *).
Palavras Reservadas
A Object Pascal se utiliza das seguintes palavras reservadas, no podendo as mesmas serem utilizadas ou redefinidas:
And Array As Asm Begin Case Class Const Constructor Destructor Div Do Downto Else End Except Exports File Finnaly For Function Goto If Implementation In Inherited Initialization Inline Interface Is Label Library Mod Nil Not Object Of On Or Packed Procedure Program Property Raise Record Repeat Set Shl Shr String Then To Try Type Unit Until Uses Var While With Xor
Uma outra lista a seguir, apresenta as diretivas que so utilizadas em contextos de identificao de objetos:
Absolute Abstract Assembler At Cdecl Default Dynamic Export External Far Forward Index Interrupt Message Name Near Nodefault Override Private Protected Public Published Read Resident Stored Virtual Write
11
Borland
Nmeros
possvel definir variveis e constantes de tipos de Inteiro ou Real atravs de qualquer decimal ordinrio ( 0 a 9 ), mas a Object Pascal tambm aceita a notao Hexadecimal utilizados com o prefixo dollar ( $ ) ou a notao cientfica ( E ).
Constantes
Uma constante um identificador com valor(es) fixo(s). Um bloco de declaraes constante possui a seguinte expresso: [Declarao Constante] [Identificador] (=) [constante] (;) A lista abaixo apresenta um conjunto de funes que podem ser utilizadas para a declarao das constantes:
Ab Chr Hi High Length Lo Low Odd Ord Pred Ptr Round SizeOf Succ Swap Trunc
Expresses
As expresses em Object Pascal (como em qualquer linguagem) formada por operadores e operandos; os operadores so divididos em quatro categorias bsicas:
nicos Multiplicativos Adicionais Relacionais @, Not >, /, div, mod, and, shl, shr, as +, -, or, xor =, < >, <, >, < =, > =, in, is
As expresses obdecem as regras bsicas de lgica para a precedncia da execuo das operaes.
12
Borland
Identificadores
Identificadores podem ser constantes, tipos, variveis, procedures, funes, unidades, programas e campos de registros. No existe limite de caracteres para o nome de um identificador mas apenas os 63 primeiros caracteres so significantes (no podendo ser idntico ao nome das palavras reservadas). O nome de um identificador deve ser iniciado por Letras ou o carcter underscore ( _ ). O resto formado por Letras, Dgitos, carcter underscore (ASCII $5F). No permitido a utilizao de espaos para a formao do nome.
Ex: const t: array [1..50] of Char { Declara 50 elementos para o tipo Char } var s : array[1..100] of Real { Declara 100 elementos para o tipo real } ind: Integer; begin for Ind := Low(s) to High(s) do s[Ind] := 0; { Zera os elementos do array S } if SizeOf(t) = C then exit; { Se o ltimo elemento do array T for C sai do bloco } { ... outros comandos... } end;
13
Borland
Declaraes
Declaraes descrevem aes de um algortmo a serem executadas.
begin... end;
Prende um conjunto de declaraes em um bloco de comandos determinado. A sintaxe do comando : BEGIN {comandos} END;. Ex: begin { ... comandos iniciais ... } begin { ... bloco 1 ... } end; begin { ... bloco 2 ... } end; { ... comandos finais ... } end;
goto... ;
Transfere a execuo de um programa para o ponto determinado pelo Label. A sintaxe do comando : GOTO {Label};. Ex: label primeiro; begin { ... comandos iniciais ... } if x = 2 then goto primeiro; { ... outros comandos ... } Primeiro: { ... comandos do Primeiro ... } end;
14
Borland
repeat... until;
Repete um determinado bloco de declaraes at a condio booleana do subcomando until ser satisfeita. A sintaxe do comando : REPEAT {comandos}; until {condio};. Ex: begin { ... comandos iniciais ... } x := 0; repeat x := x + 1 until (x = 2); end;
while... do...;
Repete um bloco de comandos enquanto que determinada condio booleana seja satisfeita. A sintaxe do comando : WHILE {condio} DO {bloco de comandos};. Ex: begin { ... comandos iniciais ... } while i := 1 do
15
Borland
end;
break; ou continue...;
O comando break interrompe um bloco de repetio for, while ou repeat saindo do bloco. A sintaxe do comando : BREAK; enquanto que o comando continue retorna a primeira instruo do bloco de repetio for, while ou repeat. A sintaxe do comando : CONTINUE;. Ex: begin { ... comandos iniciais ... } for i := 1 to 10 do begin if i = 8 then break; {... comandos A...} if i = 5 then continue; {... comandos B ...} end; {... comandos C ...} end;
Procedure
procedure {cabealho}; var {declarao das variveis}; {bloco de comandos};
O cabealho da procedure composto pelo nome do procedimento e variveis que sero recebidas (ou modificadas atravs da declarao var, ex: procedure teste(var x:string);).
procedure soma(a,b: integer); var c: integer; begin c := a + b; end;
Incio enviando as variveis A e B do tipo inteiro. Declarao de variveis locais. Corpo do procedimento.
Function
function {cabealho} : {resultado}; var {declarao das variveis}; {bloco de comandos};
As funes se diferem dos procedimentos pela obrigatoriedade do retorno de um resultado, podendo este resultado ser retornado pela declao: {nome da funo} := valor ou result := valor.
function soma(a,b: integer) : integer;
16
Borland
begin soma := a + b; end;
Junto com o Delphi 2.0 vem o manual de Object Pascal em formato .HLP, caso a linguagem seja novidade para voc aconselho que voc d uma boa olhada (o Delphi 1.0 traz o mesmo manual, mas em formato .PDF), mas no se preocupe com o que foi explicado acima j est mais do que suficiente para uma boa inicializao com o Delphi. Tudo o que vimos a cima o que normalmente temos em outras linguagens comuns, mas o caracteriza realmente a linguagem Orientada em Objetos o trabalho e a manipulao com os mesmos.
Caractersticas de Objetos
Mas afinal de contas, o que um objeto ? Como foi dito anteriormente, um objeto qualquer tipo de elemento, ou componente, que envolva dados e cdigo dentro de um nico pacote. Uma vantagem de programar na POO e quanto a Herana dos objetos, este mtodo faz com que seja possvel um objeto Filho poder herdar todas as caractersticas e contedos de um objeto Pai. Tirando um pouco do Pascal da geladeira (a partir do Pascal verso 7.0 a Borland tornou possvel a utilizao simplificada de todo o conceito de POO) aqui vai um cdigo completo de declarao de dois objetos, o primeiro chamado de TPai e o segundo de Tfilho:
TPai = object Nome: PChar; constructor Init (P: PChar); destructor Done; procedure MudaNome(P: PChar); procedure ShowName; end; TFilho = object(TPai) procedure MudaNome(P: PChar); end;
O segundo objeto TFilho herda do objeto TPai o ponteiro varivel Nome, a constructor Init, o destructor Done e a procedure ShowName, apenas a procedure MudaNome ter o funcionamento como uma caracterstica nica para cada objeto. O Delphi possui inmeros pais (classes de objetos) prontos para serem usados por voc, tais como:
TForm: Centro das aplicaes Delphi, utilizados na criao de janelas, caixas de dilogo entre outros. TMenu: Responsvel pela concepo de menus e menu popup. TButtonControl: Simplifica o refinamento do controle da janela serve de base para os componentes como: Botes, Check Box e Radio Box.
17
Borland
uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} end.
Um novo tipo de objeto TForm1, declarado derivado da classe TForm, que tambm um outro objeto. Relembre um objeto um tipo de elemento capaz de guardar dados e cdigo dentro de um nico pacote. At agora, o tipo TForm1 no contm campos ou mtodos, isso acontecer com a adio de alguns componentes neste objeto. Observando o cdigo, notamos que existe uma varivel declarada com o nome Form1 para o novo tipo de objeto TForm1:
var Form1: TForm1;
Form1 a chamada de instncia ao tipo TForm1. Esta varivel refere-se ao formulrio em si, aonde ser adicionado componentes e desenhado a interface entre o computador e o usurio que for operar o sistema. sempre notado declaraes de uma ou mais instncias referidas ao tipo de objeto. Futuramente ser mostrado o poder deste tipo de declaraes quando falarmos sobre janela MDI (Multiple Document Interface - Interface de documento mltiplos) gerenciando vrias janelas filhas, no permitindo que estas janelas filhas saiam do espao criado pela janela pai.
18
Borland
Adicionando alguns componentes ao formulrio, veremos como o Delphi completar a aplicao escrevendo automaticamente o cdigo, e permitindo que ao final tornar-se- possvel a compilao (lembra-se do Clipper , com .EXE), execuo e distribuio da aplicao. Em nosso formulrio, colocaremos um boto que, em tempo de execuo, ao ser dado um clique com o mouse sobre este objeto, o formulrio mude sua cor. Aperte a tecla F12 para retornar a viso do formulrio e na palheta de objetos (Componnent Pallete) clique no objeto (button localizado na pgina Standard) e clique no formulrio. Na janela da Object Inspector clique na pgina Events e clique duas vezes sobre a ao OnClick e insira o seguinte cdigo:
procedure TForm1.Button1Click(Sender: TObject); begin Form1.Color := clGreen; end;
O novo objeto TForm1 agora apresenta um campo Button1 - o boto que voc adicionou ao formulrio. TButton e o tipo do objeto, e Button1 o objeto boto propriamente dito. Com o tempo voc colocar novos componentes ao formulrio.
19
Borland
Rode o projeto, clicando no boto (Run), d um clique no boto e veja o que acontece. Pare a aplicao fechando a janela com Alt+F4. S por curiosidade, salve este arquivo, feche-o e abra o arquivo UNIT1.DFM (com a opo File | Open File...) notaremos que o Delphi criou um arquivo com todas as propriedades dos objetos criados e que a declarao do objeto Form1 engloba todos os outros, noes de Encapsulamento.
O Delphi modificar apenas os cdigos gerados automaticamente pr ele. Os cdigos para a ao OnClick foram gerados por voc e o Delphi no os modificar. Cabe a voc a manuteno neste caso. Isto foi idealizado para preservar o contedo original do seu cdigo.
20
Borland
Captulo II
Conhecendo o Delphi
Se voc teve algumas dvidas no captulo anterior sobre a rea de trabalho do Delphi no se preocupe, neste captulo voc poder san-las completamente, tambm ser mostrado o mtodo de estrutura de aplicaes Client/Server. Caso voc seja usurio do Delphi 1.0 na barra de menu selecione a opo Help e Interactive Tutors, voc receber uma aula On-Line sobre a nova rea de trabalho. Os elementos da interface Delphi foram divididos do seguinte modo:
Elementos Visveis
O ambiente de trabalho do Delphi formado por objetos que esto visveis to logo que o aplicativo seja iniciado formando a rea de trabalho.
21
Borland
Form
Os formulrios (objeto Form) so os pontos centrais para o desenvolvimento Delphi. Voc se utilizar deles para desenhar sua comunicao com o usurio, colocando e organizando outros objetos. Estes objetos so arrastados da Component Palette, mostrada na janela localizada acima. Voc pode imaginar que o formulrio um objeto que contm outros objetos. Sua aplicao ficar localizada em um formulrio principal e este interagir com outros formulrios criados. possvel aumentar, mover ou ocupar completamente a tela do monitor, ou at mesmo ultrapass-la. Um formulrio bsico inclui os seguintes componentes:
9 9 9 9
O cdigo gerado, na rea conhecida como Code Editor, fica exatamente atrs do objeto formulrio, clique na barra de notas, em Unit1, se alguma coisa for desconhecida para voc, leia maiores explicaes no Captulo I.
+ possvel enviar um formulrio para a impressora, para isto existem duas maneiras:
1. Tipo um PrintScreen de Tela, coloque o seguinte comando [Nome do formulrio].Print; no evento onShow do formulrio; ou
22
Borland
2. Para imprimir um formulrio no tamanho de um papel A4, atravs do uso de comandos da biblioteca Printer, veja o Apndice D para maiores detalhes.
Code Editor
O editor de cdigos providncia total acesso ao cdigo gerado pelo projeto, incluindo alguns dos mais poderosos recursos para a edio. Pode ser selecionado tipos de cores para os elementos do programa (como por exemplo comentrios, palavras reservadas, cdigos assembler, ...) para tanto a partir do menu principal entre em Tools | Options..., localize a pgina Colors. Para outras informaes adicionais sobre o modo de usar este editor, procure referncias no Help OnLine no tpico Code Editor. Ao ser aberto um novo projeto, o Delphi gera automaticamente na pgina do Code Editor uma Unit com o arquivo cdigo (.PAS). Para ver o cdigo de uma Unit em particular, simplesmente Click na tabulao de pgina. O Code Editor mostrar sempre o nome do arquivo corrente ativo na tabulao de pgina.
Component Palette
Componentes (ou objetos) so os elementos que voc usar para trabalhar com a aplicao. Foram includos objetos em vrias pginas, tais como caixas de dilogos e botes, a palheta inclui tambm alguns espaos em branco para ser permitida a adio de novos objetos. Alguns objetos no sero visveis enquanto a aplicao estiver executando, eles fazem parte do servio da DDE (Dynamic Data Exchange). Os objetos da palheta foram divididos em grupos de funcionalidade em diferentes pginas. Por exemplo, os objetos que representam as janelas tradicionais do Windows (tais como fontes, palheta de cores, ...) foram colocados na pgina Dialogs da palheta. Voc poder criar seus prprios objetos como tambm instalar outros j prontos, para isso foi colocado os espaos vazios. Por exemplo poder ser instalado novos controles e objetos do Visual Basic 4.0 (Objetos OCX - ou para os portadores do Delphi 1.0 o do Visual Basic 3.0 os objetos VBX). Uma das principais vantagens da POO que muito em breve dever ser colocado no mercado pacotes de objetos prontos para serem integrados aos sistemas o que facilitar ainda mais o desenvolvimento e a manuteno dos mesmos.
23
Borland
Object Inspector
Providncia a conexo entre a interface visual e o cdigo. Composto por duas pginas Properties (propriedades) e Events (Eventos) que mostrar as propriedades e eventos do objeto selecionado. Disponibiliza um fcil caminho para a personalizao dos objetos. Voc usar a pgina de Propriedades para personalizar os objetos colocados no formulrio (inclusive o prprio formulrio), e a pgina de Eventos para gerenciar a navegao entre certas partes do cdigo do programa. O seletor de objetos (Object Selector - localizado em um objeto do tipo ComboBox no topo do Object Inspector) mostra o nome e o tipo de todos os componentes do formulrio corrente (inclusive o prprio). Voc pode usar o seletor de objetos para localizar facilmente qualquer objeto no formulrio.
SpeedBar
Contm os botes mais freqentemente utilizados. Fornecendo deste modo um atalho de navegao ao menu principal do Delphi. possvel a personalizao da SpeedBar colocando nela os caminhos do menu principal que voc mais utiliza, bastando para isso: 1. Redimensione a SpeedBar. Para tanto posicione o cursor do mouse sobre o ponto de encontro da SpeedBar com a Component Palette conforme o desenho abaixo:
2. Quando o cursor do mouse mudar de formato, clique o boto esquerdo do mouse e arraste abrindo a rea da SpeedBar. 3. Clique com o boto direito do mouse na rea aberta, aparea um menu PullDown contendo entre outras opes a opo Properties, selecione-a. 4. As categorias e os comando so divididos de acordo com o menu, clique em cima dos comandos disponveis e arraste-os para a rea aberta de acordo com a sua necessidade, para retirar os botes da SpeedBar faa o processo inverso.
Elementos no Visveis
Alguns elementos no esto prontamente visveis quando o Delphi iniciado mas voc poder ter acesso a eles bastando para isso selecionar a opo na barra de menu.
24
Borland
Project Manager
O Gerenciador de Projetos contm uma lista de formulrios ou unidades utilizados pela aplicao, e serve para controlar estes formulrios ou unidades, adicionando-os ou removendo-os do projeto, organizando as opes do projeto, entre outros.
+ Voc tambm poder colocar um boto para iniciar o Gerenciador de Projetos atravs
da SpeedBar ,
Menu Designer
O Menu Designer permite a criao de menus para os seus formulrios. Voc pode criar menus ou menus do tipo pulldown atravs dos objetos MainMenu ou PopupMenu (localizado na pgina Standard na Component palette). A criao completa de Menus ser colocada de forma mais abrangente no Captulo IV.
25
Borland
Fields Editor
Para o Delphi possvel editar e modificar as propriedades de quaisquer campos dos objetos de tabelas associadas ao banco de dados, a Fields Editor em conjunto com a Object Inspector controlam o modo de mostrar determinados campos de arquivos, importante lembrar que esta modificao no afetar os campos da tabela, apenas para o formulrio ativo em questo. Sua utilizao efetiva ser mostrada a partir do Captulo V.
Add fields... responsvel pela adio de definies de campos da tabela, possvel inserir um ou mais campos, dependendo de sua utilizao para o formulrio. New field... permite a criao de um novo campo, este pode ser a derivao de um ou mais campos da tabela. Cut envia para rea de transferncia e elimina todas as definies do campo selecionado. Copy copia para a rea de transferncia todas as definies do campo selecionado. Paste recebe da rea de transferncia todas as definies do campo selecionado criando-o. Delete exclui quaisquer definio para os campos. Select all seleciona todas as definies dos campos. Retrieve Attributes atualiza os atributos do campo selecionado com os campos do dicionrio de dados. Save attributes salva os atributos do campo selecionado para o dicionrio de dados. Save attributes as... salva os atributos do campo selecionado para o dicionrio de dados permitindo a renomeao do campo. Associate attributes... faz a associao dos atributos do campo selecionado com determinado campo do dicionrio de dados. Unassociate attributes remove a associao dos atributos do campo selecionado com determinado campo do dicionrio de dados.
26
Borland
Repositrio de Objetos
O Repositrio de Objetos do Delphi 2.0 armazena e gerencia os objetos da aplicao: Formulrios, Data Modules, geradores experts, e DLL (Dinamic Linked Library - Bibliotecas de acesso dinmico). Na essncia, ele centraliza as localizaes dos objetos envolvidos agrupado-os. A proliferao dos objetos no repositrio incrementa as seguintes vantagens: Suporte a equipe de desenvolvimento para referncia aos objetos da rede. Uma customizao de todo o desenvolvimento em grupos lgicos de objetos, facilitando o re-uso dos mesmos.
O Delphi possui diversas caractersticas quanto a sua utilizao. Tem os Tutors e Experts que so as ferramentas responsveis para guiar-nos atravs de tcnicas, tais como, manipulao de componentes e criao de simples aplicaes. Alm disso o Delphi oferece uma coleo de modelos para formulrios, janelas de dilogo e at mesmo aplicaes completas na ferramenta New Items. A janela do New Items sempre chamada automaticamente quando a opo File | New... do menu principal executada.
possvel para voc criar novas janelas, ou projetos, automticos no Delphi. Para a nossa sorte a Borland no esconde o jogo e mostra como se cria uma template visite o diretrio \BORLAND\DELPHI 2.0\OBJREPOS, o equivalente no Delphi 1.0 encontrado no diretrio \DELPHI\GALLERY, todos os exemplos so auto-explicativos. Para definir o projeto padro que o New Items executar no incio de cada projeto, clique com o boto direito acima da janela e escolha a opo Properties aparecer as listas Pages e Objects, defina quaisquer dos objetos como New Form ou Main Form. Observe que a segunda folha da janela New Items (ter o nome do seu arquivo com a extenso .DPR) o seu projeto corrente, ou seja, uma nova janela poder ser derivada, por caracterstica de herana, de uma outra janela j existente.
+ +
27
Borland
Benefcios:
1. A separao do desenho da GUI (atravs dos objetos Forms) com a rea de ligao lgica de dados (atravs dos objetos Data Modules) permite que se cause um menor impacto sobre ambas as reas. As mudanas podem ser executadas nas telas de entrada ou nas ligaes, independentemente, de acordo com os requerimentos do usurio. 2. A separao do desenho da GUI com a rea de ligao lgica de dados realizada com uma certa habilidade aos eventos envolvidos, poder no necessariamente dever ser controlada por um habilidoso DBA (Database Administrator - Administrador de Banco de Dados), com suas fantsticas regras de negcio, podendo inclusive ser mantida por um analista de informaes.
28
Borland
3. O desenho do banco de dados, a construo das metodologias de negcio e o desenho e a criao das janelas de entrada so efetivados dentro da aplicao. O desenvolvimento, ento paralelamente, resultar em uma maior rapidez. 4. Herdando as janelas de entrada, em nveis de utilizao, reduz-se drasticamente o processo de codificao, e em conseqncia, o processo futuro de manuteno. As mudanas lgicas das regras de negcio ou a incorporao de novos padres, so feitas automaticamente para todos os objetos herdados. 5. O repositrio de objetos, os formulrios reusveis e a utilizao dos objetos Data Modules, envolve em eliminao da duplicao de cdigos e de trabalhos com desenhos de janelas, e em conseqncia na reduo da equipe de desenvolvimento.
Implementao efetiva
Objetos Data Module
A partir do Delphi 2.0 foi incorporado o uso de objetos conhecidos por Data Module, que servem para que suas aplicaes providenciem um desenho centralizado da definio de acesso aos dados e das regras de negcio. Os objetos Data Modules, tambm podem ser separados por negcios lgicos (como exemplo por reas: compras, vendas, estoque, etc.) formando caminhos de conexes simples.
Os objetos Data Modules podem ser aplicados a objetos tais como Tables, Stored Procedures, ou Queries permitindo a centralizao dos eventos envolvidos em antes e
29
Borland
depois da gravao, excluso, insero ou edio dos dados. E at mesmo na colocao de novos objetos de controle para maior facilidade. As relaes de dados Master / Detail so definidas em menor quantidade. Possibilita ento ao desenvolvedor criar aplicaes do tipo Client / Server de forma mais fcil, rpida, e segura se utilizando das propriedades dos objetos Datasources ou utilizando o Database Form Expert. Os formulrios das aplicaes, podem ser ligados diretamente a um ou mais objetos Data Module para a propagao das regras de negcio sem a necessidade de execuo de um cdigo extra. Os objetos Data Modules so classes de objetos que pertencem a interao dos dados do database server. Isolando totalmente o acesso ao banco de dados com a aplicao Client, simplificando deste modo toda a manuteno realizada. O Acesso ao Delphi aos bancos de dados se processa da seguinte maneira:
30
Borland
1. Consistncia: Campos idnticos so armazenados centralmente no dicionrio isto reduz o tempo de definio das duplicidades. Um desenvolvedor poder criar os campos complementares com domnios e aplicaes apropriadas. 2. Reduo do Trfico da Rede: O Delphi permite que a validao dos dados seja feita nas mquinas client ou no servidor. O Dicionrio de dados permite que a manuteno dos atributos dos campos do lado client seja validado de forma eficiente reduzindo a necessidade do trfego da rede.
Herdando os Formulrios
O desenvolvimento de aplicaes corporativas de uma forma padronizada um fato de suma importncia para as empresas envolvidas. Mas conseguir e manter este padro uma tarefa considerada praticamente impossvel, j que as aplicaes devem se modernizar na velocidade que o mercado de informtica exige. Os formulrios herdados do Delphi so simples extenses da programao orientada a objetos, conseguindo manter, de forma automtica, os padres e as modificaes realizadas nos projetos. E em conjunto com o Repositrio de Objetos, padroniza, organiza e centraliza os formulrios resultando em modificaes de curtssimo tempo.
31
Borland
Monitor SQL
Um monitor SQL um ferramenta para testes, depurao e execuo de consultas SQL em aplicaes Client / Server. Isto resulta em um aumento da produtividade de desenvolvimento e melhor performance da aplicao. O monitor SQL, intercepta as chamadas entre as mquinas client e o servidor. Esta informao auxilia ao desenvolvedor em problemas relacionados as declaraes SQL e otimiza este tipo de transao. Uma srie de caminhos de interceptaes podem ser traados, dependendo da necessidade do desenvolvedor, para que as informaes a serem colocadas em um relatrio online sejam as mais imprescindveis o possvel. possvel inclusive salvar e imprimir o relatrio gerado para consultas ou testes posteriores.
32
Borland
SQL Explorer
A ferramenta SQL Explorer providencia uma informao centralizada do gerenciamento das demandas da base de dados; tais como, suporte a modificao e criao de tabelas, sinnimos, procedimentos de gravao, triggers (gatilhos disparados pelo banco) e execuo das regras de negcio interativas do SQL. Uma ferramenta grfica que proporciona um esquema de integridade da base da dados e contm as ferramentas essenciais para os administradores de bancos de dados. O SQL Explorer, unicamente para o Delphi, administra de forma intuitiva e fcil o banco de dados. A simplicidade de uso da interface grfica um perfeito caminho para representar o complexo relacionamento que existe no banco de dados do servidor. Apresenta um esquema para informaes em bancos como Oracle, Sybase, InterBase, Informix, DB2 e outros. O desenvolvedor poder trilhar campos, tabelas e procedimentos do banco dentro da construo da aplicao Delphi rapidamente, podendo ser direcionado para mltiplos servidores e mltiplos bancos.
33
Borland
O SQL Explorer, tambm administra o Dicionrio de Dados. Sua interface de uso simplicado permite facilmente definir novos domnios para os atributos dos campos e associao entre tabelas.
34
Borland
alerta. Imagine o desenvolvimento de um grande sistema sendo realizado em um Laptop dentro de um trem, avio ou at mesmo na frente do cliente, apenas o acesso ao banco de dados final que ser modificado. Utilizando o Delphi Client/Server Suite 2.0, desenvolvedores podero conceber e desenhar prottipos e testar a aplicao final em uma nica mquina. O InterBase oferece um excepcional acesso a interface grfica do Windows, incluindo a configurao das propriedades, um perfeito gerenciador de bancos nativo 32 bits, total interatividade com ferramentas SQL, e uma completa documentao em formato de Help do Windows (arquivos .HLP).
Captulo III
Projeto Piloto
bvio que fica mais simples o aprendizado de uma nova ferramenta quando se faz algum tipo de aplicativo, principalmente um que seja til, ento ao longo deste estudo, iremos desenvolver um aplicativo destinado ao Cadastro de Compact Disc (CDs). Todas as pessoas hoje em dia tem montes de CDs, virou uma espcie de febre, ento, porque no fazer um sistema para cadastr-los e control-los, quanto tempo voc j perdeu pensando em qual deles est aquela msica que voc quer ouvir? Ou uma capa que seu filho rasgou, que tal imprimi-la novamente? E no captulo multimdia aprenderemos um mtodo para tocar o CD. Para darmos partida ao nosso primeiro aplicativo (Projeto Piloto), definiremos inicialmente as nossas necessidades: 1. Permitir o cadastro completo e a consulta aos CDs; 2. Ser possvel separar os CDs em categorias, facilitando deste modo a busca e o armazenamento; 3. Quanto as msicas deve ser permitido o cadastro do autor e o tempo de durao; 4. Permitir a incluso da foto da capa do CD; e 5. Comportar relatrios de conferncia e reimpresso da capa. O acesso Delphi a arquivos pode ser feito atravs de duas maneiras local ou remoto, sendo a segunda apenas possvel pela cpia CLIENT-SERVER voltadas a bases de dados mais complexas como ORACLE ou SYBASE , inicialmente, restringiremos o nosso estudo a base de dados locais conseguida atravs da verso Desktop. Lembre-se que verso Desktop contm acesso a criao e a definio de bases dBase e Paradox, alm de outras conseguidas atravs de ODBC. Com base no que foi sugerido acima, vamos definir as tabelas:
CATEGORIA Objetivo: Dados das categorias do CD. Campos: SIGLA DA CATEGORIA - Abreviao da descrio da categoria. DESCRIO DA CATEGORIA - Descrio da Categoria.
35
Borland
BSICO Objetivo: Dados iniciais do CD. Campos: CDIGO DO DISCO - Cdigo do CD, encontrado na prpia capa. NOME DO DISCO - Nome do CD. TIPO DO DISCO - Tipo de Gravao do CD: AAA, AAD, ADD ou DDD. FOTO DA CAPA - Armazenar a foto da capa do CD. SIGLA DA CATEGORIA - Ligao para o cdigo da Categoria. MSICAS Objetivo: Dados das msicas do CD. Campos: CDIGO DO DISCO - Ligao com o CD. NUMERO DA FAIXA - Nmero da faixa. NOME DA MSICA - Ttulo da msica. NOME DO AUTOR - Nome do autor da msica. TEMPO DA MSICA - Tempo de durao da msica MMSS.
36
Borland
1 registro da entidade Bsico se relaciona com 1 registro da entidade Categoria enquanto que 1 registro da entidade Categoria se relaciona com n registros da entidade Bsico, 1 registro da entidade Msicas se relaciona com 1 registro da entidade Bsico enquanto que 1 registro da entidade Bsico se relaciona com n registros da entidade Msica.
Com o MER nas mos j se tem a idia de como deve ficar as estruturas das tabelas, ento, vamos queimar um pouco de neurnios.
Configuration, no arquivo de programas do Delphi d um duplo clique sobre o cone a configurao do banco de dados se divide em vrias pginas:
9 9 9 9 9 9
Drivers - Controla os arquivos de acesso locais e ODBC dos bancos de dados utilizados; Aliases - Controle dos sinnimos dos sistemas; System - Define os recursos do Windows que sero alocados pela aplicao; Date - Especifica os fo rmatos utilizados para campos tipo data; Time - Especifica os formatos utilizados para campos tipo hora; e Number - Especifica os formatos utilizados para campos tipo numrico.
Se atualmente voc estiver utilizando a verso de desenvolvimento, os drivers que aparecero sero: dBase, InterBase e Paradox, na verso Client/Server alm desses sero colocados: Oracle, Informix, SyBase entre outros. Mude para a pgina Aliases e click no boto New Alias, informe:
New alias name: AliasDisco Alias type: STANDARD Boto OK
37
Borland
Neste momento o seu ALIAS AliasDisco foi criado para a banco de dados Paradox, no formato Padro localizado no diretrio C:\SISTEMA\CADDISCO, no menu principal escolha a opo File e Save, o BDE salvou o seu arquivo de configurao chamado IDAPI.CFG. Crie com o Gerenciador de Arquivos o diretrio C:\SISTEMA\CADDISCO, aonde ser localizado o sistema.
+ Para a base dBase a nica diferena seria o comando Default Driver: DBASE.
Encerre o Database Engine Configuration.
38
Borland
No menu principal, opo File, opo New, e opo Table..., ser mostrada uma janela com os tipos de possveis repositrios de tabelas no Table Type escolha a opo Paradox 7 e clique no boto OK. Insira os seguintes campos:
Field Name COD_DISCO NOM_DISCO TIP_DISCO FOT_CAPA SIG_CATEG Type N A A B A 60 3 3 2 Size Key *
Dos campos, o nico que merece uma explicao e FOT_CAPA ele foi escolhido neste formato (Binary) pois guardar uma imagem BitMap (extenso .BMP) da Capa do CD, todos os outros campos so caracteres alfanumricos, com a exceo do COD_DISCO que um campo Numrico e chave. Para esta tabela precisamos ainda criar um ndice secundrio, para tanto na opo Table properties: chame a opo Secondary Indexes e clique no boto Define..., marque no campo o campo passou para a lista Indexed Fields, Nom_Disco (na lista Fields) e clique no boto clique no boto OK e digite SI_NomDisco para o nome do indice e clique no boto OK. Para salvar sua tabela clique no boto Save as... na opo Nome do Arquivo: insira o nome da tabela - Basico. Crie agora as seguintes tabelas: 1. Categor
Field Name SIG_CATEG DES_CATEG Type A A Size 2 40 Key *
2. Musica
Field Name COD_DISCO NUM_FAIXA NOM_MUSICA Type N N A 60 Size Key * *
39
Borland
NOM_AUTOR TMP_MUSICA
A A
40 4
Tambm possvel acessar o Database Desktop atravs do cone grupo de trabalho DELPHI. Encerre o Database Desktop e retorne ao Delphi, ou apague as tabelas e...
localizado no
40
Borland
Clique no boto Run SQL, ou no menu SQL/Run SQL, ou ainda pressione F8, aps executado o comando a tabela ser criada. Salve o SQL com a opo File/Save (digite BASICO .SQL) Abra novas janelas e crie o resto das tabelas:
Create Index SI_NomDisco on Basico (NOM_DISCO); Create Table CATEGOR ( SIG_CATEG Char(2), DES_CATEG VarChar(40), Primary Key(SIG_CATEG) ); Create Table MUSICA ( COD_DISCO Numeric(4,0), NUM_FAIXA Numeric(2,0), NOM_MUSICA VarChar(60), NOM_AUTOR VarChar(40), TMP_MUSICA Char(4), Primary Key(COD_DISCO, NUM_FAIXA) );
O SQL para o Paradox no consegue executar a criao de indices referenciais (ou Constraints) ento para criar este tipo de ndice crie-o atravs da janela de estrutura conforme mostrado anteriormente.
41
Borland
O comando correto para este ndice deveria ser Create Unique Index PK_Unica on Basico (COD_DISCO); mas isto provoca um erro colocando que no possvel esta declarao, ento coloque a clusula UNIQUE atravs da janela de estrutura. Se voc esqueceu de ativar o Select Alias coloque Create Index Cod_Disco on Basico.dbf (COD_DISCO); As outras declaraes so:
Create Index SI_NomDisco on Basico (NOM_DISCO); Create Index FK_SigCateg_Basico on Basico (SIG_CATEG); Create Index PK_Unica on Categor (SIG_CATEG); Create Index FK_CodDisco_Musica on Musica (COD_DISCO);
+ +
Criando o indice secundrio Criando a chave estrangeira Criando a chave primria Criando a chave estrangeira
O comando correto para a criao da chave dupla da tabela MUSICA seria Create Index Chv_Unica on Musica (COD_DISCO, NUM_FAIXA); mas novamente provocado um erro mostrando a impossibilidade de execuo do comando, ento crie este ndice atravs da janela de estrutura. facilmente percebido que o DataBase DeskTop at que tenta colocar todas as bases de dados compatveis com a linguagem SQL, mas infelizmente ainda no foi nesta verso. Para as tabelas do tipo ORACLE, INTERBASE, SYBASE e MS SQL Server a criao das tabelas podem ser feitas tanto pelo modo de estrutura quanto pelas declaraes SQL mas lembre-se que a alterao das mesmas s poder realizar-se atravs do modo de declaraes SQL. Aqui vo alguns exemplos destas declaraes: Create Table MUSICA Criando a tabela MUSICA
( COD_DISCO Numeric(4,0), NUM_FAIXA Numeric(2,0), NOM_MUSICA VarChar(60), TMP_MUSICA Char(4), Constraint PK_Unica Primary Key(COD_DISCO, NUM_FAIXA), Constraint FK_CodDisco_Musica Foreign Key (Cod_Disco) References USUARIO_AGENDA (Cod_ Disco) ); ALTER TABLE MUSICA ADD NOM_AUTOR VarChar(40) DROP TABLE MUSICA;
+ +
42
Borland
Captulo IV
Trabalhando com o Menu
Qualquer projeto precisa de um menu, fica mais prtico para o nosso usurio navegar dentro de um projeto quando este limitado por um menu principal, iniciaremos o nosso projeto no Delphi com a criao do Menu Principal do Sistema.
Metendo a Mo na Massa
A partir deste ponto, nossa aula se transforma em receita de bolo, a nica coisa que voc precisa fazer e seguir as orientaes passo a passo, no princpio pode parecer meio idiota, mas afinal o computador uma mquina idiota. Bom, vamos ento metendo a mo na massa. Ao iniciar o Delphi, foi criado automaticamente um novo projeto, vamos descart-lo e iniciar um novo. Para tanto: 1. Lembre-se: no captulo anterior criamos o diretrio que abrigar o sistema a ser desenvolvido - C:\SISTEMA\CADDISCO - aprendemos o que o Alias e estruturamos as nossas tabelas, se algum destes conceitos ficaram dispersos eu lhe aconselho que retorne ao captulo anterior 2. Crie um novo projeto digitando File e New Application. (Responda negativamente quaisquer mensagem para gravar o projeto atual).
9 9 9
F_Menu - Menu principal propriamente dito; F_Sobre - A janela Sobre o sistema...; e F_Inicio - Janela Splash que iniciar o nosso aplicativo.
Vamos criar inicialmente o nosso menu principal: 1. Clique no boto (Main Menu), localizado na Component Palette na pgina Standard, e clique dentro do objeto Form1 (no se preocupe com a posio, pois este objeto ficar invisvel quando o aplicativo for executado).
Foi criado neste momento o objeto MainMenu1 derivado da classe de objeto TMainMenu, a partir deste objeto vamos criar nosso menu:
43
Borland
2. D um duplo clique em cima do objeto, ou clique na propriedade Items da Object Inspector aparecer o boto . Clique neste boto. Observe a tela de propriedades do Object Inspector, neste momento vou me conter em falar das mais significativas, mas futuramente retomaremos o assunto: Caption - Define o nome do item de menu, quaisquer nomes so vlidos, incluindo acentos, o caractere especial & deve ser colocado uma nica vez, ele causa o sublinhado da letra, tornando-a uma letra (em conjunto com a tecla Alt) de acesso a opo. Enabled - Define se o item est disponvel ou no para o usurio. Name - Nome interno do item (colocado automaticamente na escolha do Caption). ShortCut - Combinao de teclas, para um rpido acesso ao item (alm da letra escolhida com &). Inserindo os itens iniciais: 1. Digite &Arquivo na propriedade Caption, em seguida pressione a tecla Enter. 2. Clique no novo espao aberto, criado lateralmente, e digite &Consulta na propriedade Caption, em seguida pressione a tecla Enter. 3. Proceda da mesma forma criando as opes: &Relatrio e Au&xlio. 4. Clique na opo Arquivo, aparecer um espao vazio abaixo, clique neste espao e digite &Tabela na propriedade Caption. Ao ser dado Enter o Delphi criar mais um espao abaixo, digite &Cadastro na propriedade Caption. 5. Abaixo do Cadastro, digite - (sinal de menos) na propriedade Caption (o Delphi criar uma barra de separao) e altere a propriedade Enabled para False. 6. No novo espao criado, aps a barra, digite &Sair na propriedade Caption e altere a propriedade ShortCut para Ctrl+X. 7. Clique na opo Tabela, clique com o boto direito do mouse, aparecer um menu pulldown, clique na opo Create Submenu. 8. Digite &Categoria na propriedade Caption.
Tabela Cadastro Sair Ctrl+X
Arquivo
Saia da janela Menu Designer digitando Alt+F4, o menu j existe no objeto form1. Altere as seguinte propriedades para o objeto form1:
Valor Single Compact Disc Digital Audio Descrio Estilo da borda da janela; modo simples. Label escrito na tarja superior da janela.
44
Borland
Color Name WindowsState
Cor da janela, clMenu uma constante que guarda a cor padro da janela definido pelo usurio no Windows. Nome do objeto interno. Modo de abertura da janela, modo Maximizado.
Salvando o formulrio e o projeto: 1. Salve o Formulrio nas opes de menu File e Save (ou pressione Ctrl+S), o Delphi questionar o nome e o diretrio, o diretrio (conforme criado no captulo anterior) o C:\SISTEMA\CADDISCO e para o nome digite fMenu (note que o nome externo e o mesmo do nome interno diferenciado por _, isto facilitar a identificao do formulrio e da sua unidade). 2. Salve o Projeto digitando File e Save Project, salve o projeto no diretrio C:\SISTEMA\CADDISCO com o nome CDDA.
Criando no menu uma linha de status: (StatusBar) na pgina Win95 da Component Pallete e clique 3. Clique no boto em qualquer posio do objeto F_Menu. 4. Clique no objeto criado StatusBar1 em seguida clique na propriedade Panels, para alterar esta propriedade clique no boto , aparecer a janela da Status Bar Panels Editor, clique sobre o boto New e para a propriedade Text coloque Bem vindo ao sistema... e clique no boto OK.
+ Caso voc esteje usando o Delphi 1.0 crie a barra de status do seguinte modo:
(Panel) na Component Pallete na pgina Standard e clique em 1. Clique no boto qualquer posio do objeto F_Menu. 2. Clique no objeto criado StatusBar1 e altere as seguintes propriedades:
Propriedade Align Alignment Valor alBottom taLeftJustify Descrio Alinhamento dentro do form, todo no rodap Alinhamento da Caption, justificado esquerda
45
Borland
BevelInner BevelOuter BorderWidth Caption Name Font
bvLowered bvLowered 1 Bem vindo ao sistema... LinhaStatus MS Sans Serif, Estilo da fonte: Normal, Tamanho: 8, Cor: Azul Marinho 22
Borda 3D interna, tipo pressionado Borda 3D externa, tipo pressionado Tamanho da borda Label do objeto Nome do objeto Tipo de letra a ser mostrada no objeto, para alterar esta propriedade clique no boto Altura do objeto
Height
private { Private declarations } procedure ShowHint (Sender: TObject); public { Public declarations } end;
Abaixo da declarao: Private insira os cdigos: Procedures ou Funes Locais. Cabealho de uma procedure Local. Procedures ou Funes Pblicas. Final da seo de declarao.
{$R *.DFM}
Abaixo da diretiva de compilao: {$R *.DFM} Diretiva de compilao associando o nome do recurso externo ao mesmo nome do objeto Form. procedure TF_Menu.ShowHint (Sender: TObject); Cabealho da Procedure associado ao nome do
begin objeto principal (TF_Menu). LinhaStatus.Panels.Items[0].Text := Application.hint; Atribui o valor do hint da aplicaco ao end; Item criado do objeto LinhaStatus.
Clique no boto (Toggle Form/Unit) da SpeedBar, at voc alternar para o Form clique no objeto F_Menu e na pgina Events da Object Inspector, d um duplo clique no evento OnCreate. 1. O Delphi criou a procedure FormCreate a ser iniciada quando o objeto F_Menu for criado. 2. Digite o seguinte comando abaixo do comando begin:
procedure TF_Menu.FormCreate (Sender: TObject); begin Atribui o valor da procedure ShowHint ao OnHint da Application.OnHint := ShowHint; end; aplicao.
46
Borland
Clique no boto (Toggle Form/Unit) da SpeedBar, at voc alternar para o Form clique no objeto MainMenu1 e entre no Menu Designer, e para cada opo de Menu altere as propriedades hint e name do seguinte modo:
Hint Cadastro e sada do sistema. Informaes bsicas do sistema. Tipos de categoria para os CDs. Incluso e manuteno dos CDs. Sada do sistema e retorno ao Windows. Verificao e pesquisa dos CDs cadastrados. Localizao dos CDs atravs de um filtro estabelecido. Localiza o CD atravs de um ttulo de uma msica. Emisses em papel dos CDs cadastrados. Impresso dos CDs por um intervalo de cdigo. Impresso de capas para os CDs. Verifica a impressora a qual ser destinado os relatrios. Formas de ajuda direta ao sistema. Ajuda direta com o responsvel pelo desenvolvimento. Manual On-Line direto. Exibe os tpicos de ajuda do Manual On-Line. Mostra como utilizar o Auxlio On-Line. Name Arquivo1 Tabela1 ItemTabela1 Cadastro1 Sair1 Consulta1 ItemConsulta1 ItemConsulta2 Relatorio1 ItemRelatorio1 ItemRelatorio2 ConfImpressora1 Auxilio1 ItemAuxilio1 ItemAuxilio2 ItemAuxilio3 ItemAuxilio4
Opo do Menu Arquivo Tabela Categoria Cadastro Sair Consulta CDs CDs por msica Relatrio Geral Capa do CD Configura Impressora Auxlio Sobre o sistema Contedo Tpicos de Ajuda Como usar a Ajuda
Saia do Menu Designer, salve o formulrio e o projeto. Rode o projeto, clicando no boto Run, ou ainda, digite F9. da SpeedBar, ou no menu principal a opo Run e
Teste as opes do menu, veja na linha de Status os hints informados, saia com Alt+F4.
+ Caso voc esteje usando o Delphi 1.0 troque a procedure ShowHint para:
procedure TF_Menu.ShowHint (Sender: TObject); begin Atribui o valor do hint da aplicaco a Propriedade LinhaStatus.Caption := Application.hint; end; Caption do objeto LinhaStatus.
procedure TF_Menu.Sair1Click (Sender: TObject); begin Close; proporciona o fechamento do formulrio ativo end;
47
Borland
Automatizando o Comando CONTEDO: No objeto F_Menu, clique na opo Auxlio e clique na opo Contedo. Digite:
procedure TF_Menu. ItemAuxilio2Click(Sender: TObject); begin Chama o arquivo de Ajuda Application.HelpCommand(HELP_CONTENTS, 0); end;
Automatizando o Comando TPICOS DE AJUDA: No objeto F_Menu, clique na opo Auxlio e clique na opo Tpicos de Ajuda. Digite:
procedure TF_Menu. ItemAuxilio3Click(Sender: TObject); const Cria uma constante EmptyString: pChar = ''; begin Application.HelpCommand(HELP_PARTIALKEY, LongInt(EmptyString)); Tpicos do Ajuda end;
Automatizando o Comando COMO USAR A AJUDA: No objeto F_Menu, clique na opo Auxlio e clique na opo Como usar a Ajuda. Digite:
procedure TF_Menu. ItemAuxilio4Click(Sender: TObject); begin Chama o auxlio do Windows Application.HelpCommand(HELP_HELPONHELP, 0); end;
Quando fecharmos a nossa aplicao e necessrio que tambm desativemos o auxlio, no objeto F_Menu, clique na pgina de Events e clique no evento Destroy. Digite:
Desabilita o auxlio
48
Borland
end;
Saia do Menu Designer, salve o formulrio e o projeto. Rode o projeto e teste as opes do menu, saia com Ctrl+X ou utilize o comando Sair.
Caso o F1 no ative o auxlio On-Line, provavelmente o seu menu est com a propriedade FormStyle em modo fsMDIForm, coloque-a no modo fsNormal. Se mesmo assim ainda no funcionou, mude a propriedade HelpContext do formulrio para 1.
HELP_CONTENTS HELP_SETCONTENTS
HELP_CONTEXTPOPUP
HELP_KEY
HELP_PARTIALKEY
HELP_MULTIKEY
Ponteiro longo para uma estrutura de TMULTIKEYHELP. Esta estrutura especfica de caracteres e palavras chaves. Ponteiro longo, contendo a macro para a execuo Ponteiro longo para uma estrutura de TMULTIKEYHELP. Esta estrutura especfica contm o tamanho e a posio da janela do help primrio ou a janela secundria para ser mostrado. Ignorado. Normalmente passado 0. Ignorado. Normalmente passado 0. Ignorado. Normalmente passado 0.
HELP_COMMAND HELP_SETWINPOS
Executa um macro help. Mostra um help do windows com um mnimo de memria, variando o tamanho e a posio de acordo com o dado passado.
Executa o WinHelp mostrando o arquivo de auxlio corrijido. Mostra o auxlio de como usar o auxlio. Solicita o fechamento do auxlio ativo.
49
Borland
50
Borland
Font
Elimine o objeto OKButton (boto de OK), clique sobre ele e pressione Delete, clique no objeto F_Sobre e click no objeto BitBtn , encontrado na Component Palette na pgina Additional, e click novamente no F_Sobre Altere as seguintes propriedades:
Descrio Determina a classe a ser utilizada pelo boto, automaticamente ser alterado as propriedades: Caption, Glyph e ModalResult Ajuda on-line para o objeto especfico Mostrar o contedo da propriedade hint sob a forma de uma caixa de ajuda on-line Nome do Objeto Largura do objeto
D uma organizada geral quanto a posio dos objetos para voc poder ter uma idia compare o desenho do seu formulrio para ver se no ficou faltando nada:
Salve o formulrio nas opes de menu File e Save (ou pressione Ctrl+S), o Delphi questionar o nome e o diretrio, o diretrio o C:\SISTEMA\CADDISCO e para o nome digite fSobre (note que novamente o nome externo e o mesmo do nome interno diferenciado por _).
51
Borland
procedure TF_Menu.ItemAuxilio1Click(Sender: TObject); begin Abre o Objeto F_Sobre em modo Modal. F_Sobre.ShowModal; end;
Saia do Code Editor e salve o formulrio e o projeto. Rode o projeto e teste o formulrio Sobre o Sistema, o modo Modal no permitir que voc clique em nenhum outro lugar at a finalizao desta janela, volte para o menu com o boto OK.
Note que no foi preciso colocar nenhum cdigo para que ao pressionar o boto OK o formulrio fosse fechado, isto foi realizado graas a opo Kind, no Delphi voc encontrar outros modelos de boto padro do tipo: Cancela, Sim, No entre outros.
52
Borland
3. Salve o formulrio nas opes de menu File e Save As..., o Delphi questionar o nome e o diretrio, o diretrio o C:\SISTEMA\CADDISCO e para o nome digite fSplash.
Cria o form como parte da aplicao. Chama o form de modo no modal. Mostra o form e devolve o controle para a
aplicao.
Saia do Code Editor e salve o formulrio e o projeto. Rode o projeto, qualquer problema compare com o cdigo abaixo:
program CDDA; uses Fmenu in 'FMENU.PAS' {F_Menu}, FSobre in 'FSOBRE.PAS' {F_Sobre}; {$R *.RES} begin F_Splash := TF_Splash.Create(Application); F_Splash.Show; F_Splash.Refresh;
53
Borland
Application.Initialize; Application.HelpFile := 'C:\Sistema\CadDisco\Guia.hlp'; Application.CreateForm(TF_Menu, F_Menu); Application.CreateForm(TF_Sobre, F_Sobre); F_Splash.Free; Application.Run; end.
Voc pode mover o comando SplashScreen.Free; para o evento OnShow do form F_Menu. Isto far com que a janela Splash s desaparea quando o menu for ativado. Infelizmente para os usurios do Delphi 1.0 esta caracterstica de herana no havia sido implementada ento, faz-se necessrio a construo da tela fSplash atravs de uma cpia da tela fSobre com a utilizao do comando Save As....
+ +
Insira agora os cdigos que permitir a abertura e o fechamento da base de dados: (Toggle Form/Unit) da SpeedBar, at voc alternar para a Code Clique no boto Editor e localize o procedimento FormCreate associado ao evento OnCreate:
procedure TF_Menu.FormCreate(Sender: TObject); begin Application.OnHint := ShowHint; Inicia o Banco de Dados DBDisco.Connected := True; end;
A partir do prximo captulo entraremos realmente no que o Delphi capaz com tabelas, mas antes, necessrio que os conceitos ensinados anteriormente estejam bem fixados, se alguma coisa deu errada, releia o captulo, ou ento confira o cdigo do F_Menu:
54
Borland
unit fMenu; interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Menus, ComCtrls, DBTables, DB; type TF_Menu = class(TForm) MainMenu1: TMainMenu; Arquivo1: TMenuItem; Consulta1: TMenuItem; Relatorio1: TMenuItem; Auxilio1: TMenuItem; Tabela1: TMenuItem; Cadastro1: TMenuItem; N6: TMenuItem; Sair1: TMenuItem; ItemTabela1: TMenuItem; ItemConsulta1: TMenuItem; ItemConsulta2: TMenuItem; ItemRelatorio1: TMenuItem; ItemRelatorio2: TMenuItem; N12: TMenuItem; ConfImpressora1: TMenuItem; ItemAuxilio2: TMenuItem; ItemAuxilio3: TMenuItem; ItemAuxilio4: TMenuItem; N14: TMenuItem; ItemAuxilio1: TMenuItem; LinhaStatus: TStatusBar; DBDisco: TDatabase; procedure FormCreate(Sender: TObject); procedure Sair1Click(Sender: TObject); procedure ItemAuxilio2Click(Sender: TObject); procedure ItemAuxilio3Click(Sender: TObject); procedure ItemAuxilio4Click(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure ItemAuxilio1Click(Sender: TObject); private procedure ShowHint (Sender: TObject); public { Public declarations } end; var F_Menu: TF_Menu; implementation {$R *.DFM} uses fSobre; procedure TF_Menu.ShowHint (Sender: TObject);
55
Borland
begin LinhaStatus.Panels.Items[0].Text := Application.hint; end; procedure TF_Menu.FormCreate(Sender: TObject); begin Application.OnHint := ShowHint; DBDisco.Connected := True; end; procedure TF_Menu.Sair1Click(Sender: TObject); begin DBDisco.Connected := False; Close; end; procedure TF_Menu.ItemAuxilio2Click(Sender: TObject); begin Application.HelpCommand(HELP_CONTENTS, 0); end; procedure TF_Menu.ItemAuxilio3Click(Sender: TObject); const EmptyString: pChar = ''; begin Application.HelpCommand(HELP_PARTIALKEY, LongInt(EmptyString)); end; procedure TF_Menu.ItemAuxilio4Click(Sender: TObject); begin Application.HelpCommand(HELP_HELPONHELP, 0); end; procedure TF_Menu.FormDestroy(Sender: TObject); begin Application.HelpCommand(HELP_QUIT, 0); end; procedure TF_Menu.ItemAuxilio1Click(Sender: TObject); begin F_Sobre.ShowModal; end; end.
Caso o seu sistema no seja migrado para nenhum banco de dados no padro SQL (do tipo ORACLE , SYBASE ,...) no existe nenhuma necessidade em se utilizar o objeto DataBase, mas a utilizao ou no do objeto no afeta o tempo de acesso ao sistema, ento porque no prepar-lo para uma eventual mudana?
56
Borland
Captulo V
Janela para as Tabelas
Tabelas primrias de informao requerem entradas de dados simples, no nosso caso temos a tabela de categoria, a criao de janelas para a sua manipulao de seus dados no um bicho de sete cabeas como voc ver a seguir.
1. O tipo a ser criada. Form Options: Create a simple form Uma janela simples DataSet Options: Create a form using TTables objects Usando o objeto tabela Boto Next.
2. A tabela a ser usada para a janela. Drive or Alias name: AliasDisco Table Name: categor.db Boto Next
57
Borland
Boto >> Boto Next
6. Completo Gera a tela como form principal - No O Que gerar: Form e DataModule Boto Finish
DataModules ?
Uma das principais novidades que acompanham o Delphi 2.0 a possibilidade de criao de DataModules, estas janelas especiais funcionam como uma espcie de repositrio de dados, no so visualizveis em tempo de execuo. possvel colocar em um nico DataModule todo o modelo relacional e todos os outros formulrios do sistema acessando-o. Acesse inicialmente o objeto DataModule1 para as alteraes que se seguem.
58
Borland
voc poder usar duplicaes da mesma tabela, sem que isso afete a integridade de seu banco de dados. Alterando as propriedades da Table: 1. Altere na propriedade DataBaseName, nome do banco de dados BaseDisco, caso voc no encontre na lista o BaseDisco, abra o objeto F_Menu e tente novamente. 2. Verifique se a propriedade TableName est apontada para a tabela: CATEGOR.DB, retire o .DB (visando a compatibilidade com outras bases) 3. Coloque a propriedade IndexFieldNames no nome do ndice primrio da tabela. SIG_CATEG. 4. Altere a propriedade Name para TabCategor, ou seja, Tab + Nome da tabela externo (sem a sua extenso), isto facilitar a identificao da Table e a qual DataSource que ela pertence.. 5. Outra propriedade interessante da Table Active, ela define se a tabela est ou no ativada para o uso. Alteraremos esta propriedade via cdigo, portanto no se preocupe muito com ela neste instante, o ideal e deix-la false, i. inativa. (DataSource), As Ligaes da Tabela no Delphi realizada atravs do objeto encontrado na Component Palette na pgina Data Access, este objeto faz a ligao de sua tabela externa com os campos do formulrio. Alterando as propriedades do DataSource: 1. Note que a propriedade DataSet est com o nome alterado (TabCategor), est propriedade define a table ou query (falemos nelas mais tarde) que ser ligada. 2. Altere a propriedade Name para DsCategor, ou seja, Ds + Nome da tabela externo (sem a sua extenso), como dito antes, isto facilitar a identificao do DataSource e a qual Table ele pertence.
59
Borland
9 9 9 9 9 9
DisplayWidth: Tamanho do campo disponvel para insero de dados; FieldName: Nome do campo na tabela, externo; Name: Nome do campo dentro do formulrio, interno; ReadOnly: Se um campo s de leitura; Size: Tamanho do campo na tabela; e Visible: Campo ou no visvel.
Codificando o DataModule
Voc j deve ter notado que para o Delphi a escrita de cdigos bastante reduzida e bem dividida entre os eventos e com a criao dos DataModules o cdigo ainda fica mais reduzido, diferentemente para os usurios de Delphi 1.0. Todas as crticas e controles para as tabelas ficaro no DataModule enquanto que o formulrio se preocupar com o manuseamento dos campos. Cdigo para efetivar as modificaes na tabela para as bases SQL, clique no boto (Toggle Form/Unit) da SpeedBar, at ter a viso novamente para o DM_Modelo, d um clique simples no objeto TabCategor (marcando-o) e na Object Inspector, na pgina Events, d um duplo click sobre o evento AfterPost:
procedure TDM_Modelo.TabCategorAfterPost(DataSet: TDataSet); begin if F_Menu.DBDisco.IsSQLbased then Se a base de dados padro SQL begin Gravando as alteraes da tabela F_Menu.DBDisco.Commit; Reinicia o modo de transaes F_Menu.DBDisco.StartTransaction; end; end;
60
Borland
O objeto que controla o banco de dados faz parte da Unit fMenu ento necessrio fazer uso desta Unit, para tanto insira o seguinte cdigo (abaixo da diretiva de compilao):
{$R *.DFM} uses fMenu;
Note que existe uma referncia para o objeto F_Categ (Ser o formulrio de Categoria) precisamos ento fazer uso de sua Unit, para tanto coloque-a abaixo da diretiva de compilao:
{$R *.DFM} uses fMenu, { Menu Principal do Sistema } fCateg; { Cadastro de Categorias }
A declarao #10, funciona como um Enter dentro da mensagem, isto far com que esta mensagem tenha duas linhas. O segundo objeto Table foi criado pois a primeira tabela estar em modo de edio ou insero de registros e no poder ser desposicionada para a verificao, ento a verificao se o registro existe ser feita neste segundo objeto.
+ +
61
Borland
O comando raise impede que o registro duplicado seja adicionado na tabela, no modo run-time este comando provocar um erro de classe exception que travar o projeto, no se preocupe, digite F9 e prossiga com os testes, quando o projeto for compilado e rodado atravs do .EXE o erro no travar o projeto mostrando somente a mensagem definida. Um ltimo detalhe para o DataModule que temos que prever que a cada novo registro o cursor deve se posicionar no primeiro campo do registro, para o incio da digitao: 1. Marque o objeto TabCategor, e d um duplo click sobre o evento OnNewRecord:
procedure TDM_Modelo.TabCategorNewRecord(DataSet: TDataSet); begin Altera a posio do cursor para o objeto EditSig_Categ F_Categ.EditSig_Categ.SetFocus; end;
Finalizando o DataModule
Salve o DataModule com o nome de DMModelo. Confira o cdigo completo para o DataModule:
unit DMModelo; interface uses SysUtils, Windows, Classes, Graphics, Controls, Forms, Dialogs, DB, DBTables; type TDM_Modelo = class(TDataModule) TabCategorSig_Categ: TStringField; TabCategorDes_Categ: TStringField; DSCategor: TDataSource; TabCategor: TTable; TabCategorConf: TTable; StringField1: TStringField; StringField2: TStringField; procedure TabCategorAfterPost(DataSet: TDataSet); procedure TabCategorSig_CategValidate(Sender: TField); procedure TabCategorNewRecord(DataSet: TDataSet); private { private declarations } public { public declarations } end; var DM_Modelo: TDM_Modelo; implementation {$R *.DFM} uses fMenu, { Menu Principal do Sistema } fCateg; { Cadastro de Categorias }
62
Borland
procedure TDM_Modelo.TabCategorAfterPost(DataSet: TDataSet); begin if F_Menu.DBDisco.IsSQLbased then begin F_Menu.DBDisco.Commit; F_Menu.DBDisco.StartTransaction; end; end; procedure TDM_Modelo.TabCategorSig_CategValidate(Sender: TField); begin if DSCategor.State in [dsEdit, dsInsert] then if TabCategorConf.FindKey([TabCategorSIG_CATEG]) then begin F_Categ.EditSIG_CATEG.SetFocus; raise Exception.Create('Sigla da categoria duplicado'#10+ 'Click no boto "Localiza" em caso de dvida'); end; end; procedure TDM_Modelo.TabCategorNewRecord(DataSet: TDataSet); begin F_Categ.EditSig_Categ.SetFocus; end; end.
Comandos e suas funes, por ordem de apario: Uses - Faz o uso de determinada unidade de procedimentos e biblioteca de funes. [DataSource].State - Define o estado em que se encontra determinado objeto DataSource. [Objeto].SetFocus - Posiciona o cursor no objeto definido. raise - Cria um erro de classe exception que no permitir que qualquer outra ao prossiga at a mesma ser resolvida.
Alterando o Formulrio
Com o DataModule concludo vamos atacar a janela que ser mostrada para o nosso usurio, chame objeto Form2 (chame-o atravs da Project Manager - opo do menu View | Project Manager). Antes de fazermos quaisquer modificao vamos inicialmente alterar o nome da janela, para tanto pressione a tecla F11 (aparecer a Object Inspector para o objeto Form2) altere a propriedade Name para F_Categ. Outra modificao importante e trocar a referncia do comando Uses abaixo da diretiva de compilao que estava referenciado ao antigo nome do objeto DataModule (Unit1), troque-o para:
{$R *.DFM} uses
63
Borland
+ Qualquer problema para dimensionar o tamanho de objetos use a tecla SHIFT + Setas. + Qualquer problema para acertar a posio de objetos use a tecla CTRL + Setas.
Uma propriedade interessante a FocusControl ela indicar um controle para a posio do cursor. Ex.: Caso seja digitado ALT+S o cursor se posicionar no objeto EditSig_Categ ou Caso seja digitado ALT+D o cursor se posicionar no objeto EditDes_Categ. Os Campos de Edio, representados pelo objeto (DBEdit), encontrado na Component Palette na pgina Data Controls, so os que recebero o contedo dos campos da tabela. Alterando as propriedades do campo Cdigo: 1. Modifique a propriedade Fonte (de ambos os campos) para MS Sans Serif, Normal, 8 e azul marinho. 2. Verifique as propriedades DataSource e DataField, nome da ligao com DM_ Modelo.DSCategor e o nome do campo Sig_Categ, respectivamente. 3. A propriedade Name, nome do campo, montada com Edit + Nome externo do campo. EditSig_Categ. Alterando as propriedades do campo Descrio: 4. Verifique as propriedades DataSource e DataField, nome da ligao com DM_Modelo.DSCategor e o nome do campo Des_Categ, respectivamente. 5. A propriedade Name, nome do campo, montada com Edit + Nome externo do campo. EditDes_Categ.
64
Borland
Objeto DBNavigator
O objeto para o controle da tabela, representada pelo objeto (DBNavigator), encontrado na Component Palette na pgina Data Controls, e apresentada pr uma barra de funes que ligada ao DataSource controla a navegao dos campos, adio de novos registros, edio e excluso de registros, o cancelamento ou a confirmao de uma modificao e a atualizao do banco de dados (quando em rede):
Apresentada pelos botes: nbFirst (primeiro), nbPrior (anterior), nbNext (prximo), nbLast (ltimo), ndInsert (inserir), ndDelete (excluir), nbEdit (editar), nbPost (confirmar), nbCancel (cancelar) e nbRefresh (atualizar dados). Alterando as propriedades da barra de navegao: 1. Confira a propriedade DataSource verificando para o nome da ligao com DM_Modelo.DSCategor 2. A propriedade ConfirmDelete far com seja exibida uma mensagem, confirmando ou no a excluso. 3. Altere a propriedade Hints, clicando em modo:
Primeiro Anterior Prximo ltimo Inserir Excluir Editar Confirmar Cancelar Atualizar dados
4. Clique no boto OK e altere a propriedade ShowHint para true, isto far com que embaixo de cada boto da barra, sobreposto pelo cursor, seja mostrado uma caixa como uma tarja amarela com a contedo da propriedade Hint. 5. Voc poder definir quais botes devero aparecer na barra utilizando a propriedade VisibleButtons, para tanto clique no sinal de + que aparece a esquerda da opo e defina true ou false para os botes que sero ou no mostrados.
Modificando os Paineis
Existem dois objetos Panel criados automaticamente: o primeiro superior, abriga o objeto DBNavigator, o segundo ocupando o restante da janela, abriga um objeto do tipo ScrollBox, labels e campos. Alterando as propriedades do primeiro painel:
65
Borland
1. Altere a propriedade Alignment, alinhamento da propriedade Caption do painel, para taLeftJustify. 2. Coloque na propriedade Caption o nome Categoria. 3. Modifique a propriedade Fonte para MS Sans Serif, Itlico, 14 e azul marinho. Arrume a barra de navegao de modo que no cubra a descrio, se for o caso aumente o tamanho da janela. Alterando as propriedades do segundo painel: 1. Aumente ou diminua o tamanho da janela e note que este painel diminue e aumenta com ela, isto se deve a propriedade Align estar no modo alClient, altere esta propriedade (temporariamente) para alNone.
Para conseguir ver a tela de propriedades deste painel, clique em quaisquer das bordas, pois sobre este painel existe um outro objeto denominado ScrollBox tambm no modo alClient.
Modificando a Janela
A janela est um pouco escondida atrs dos objetos painis criados, aps alterar a propriedade Align do segundo painel, estique um pouco a janela para baixo e clique nela. Alterando as propriedades da janela: 1. Retire as opes biMinimize e biMaximize da propriedade BorderIcons. 2. Altere na propriedade BorderStyle para bsSingle. 3. Mude a propriedade Caption para Tabela. 4. Se voc no o fez, mude a propriedade Name para F_Categ, ou seja F_ + Nome da tabela externo (sem a sua extenso), isto facilitar a identificao entre o form e sua unit. 5. Verifique a propriedade Position (posio da janela) ela deve estar com o valor ScreenCenter (centralizado). 6. Salve o formulrio com o nome fCateg e salve o projeto.
66
Borland
Align Caption Height
alBottom 41
Os botes que criaremos faro duas funes: 1.Sair da janela e 2.Localizao rpida de um determinado registro.
, encontrado na
Caption Font
[DiretrioDelphi]\IMAGES\BUTTONS\ Imagem a ser mostrada no objeto FIND.BMP 25 Localiza determinado registro na tabela 24 ButLocalizar True MS Sans Serif, Normal, 8, Preto 89 Altura do objeto Ajuda on-line para o objeto especfico Alinhamento a esquerda Nome do objeto Mostrar o contedo da propriedade hint sob a forma de uma caixa de ajuda on-line Tipo de letra a ser mostrada no objeto Tamanho do objeto
Alterando novamente as propriedades do segundo painel: 1. Recoloque a propriedade Align do objeto Panel2 para alClient e Salve o form e o projeto.
67
Borland
Programando no formulrio
Agora vem a parte de cdigo. Ao final deste tpico voc observar que o trabalho maior ficou pr conta de organizar e arrumar os objetos do que com o cdigo em si, i.e., orientao a objetos.
Este tempo com base em uma mquina 486 DX2 com 8 Mb de memria.
68
Borland
Altere agora a instruo do formulrio F_Menu, evento OnClick para o objeto ItemAuxilio1, para criarmos o objeto F_Sobre e aps a sua chamada destru-lo da rea de memria:
procedure TF_Menu.ItemAuxilio1Click(Sender: TObject); begin Cria o formulrio em memria with TF_Sobre.Create(Self) do begin Chama o formulrio atravs da rea aberta ShowModal; Free; Libera a rea aberta end; end;
Cdigo para ativar a Base de dados e as tabelas quando no DataModule, retorne ao formulrio F_Categ: 1. Clique no boto Editor. (Toggle Form/Unit) da SpeedBar, at voc alternar para o Code
procedure FormCreate(Sender: TObject); private { private declarations } public { public declarations } procedure inicio; Criando a chamada para um procedimento pblico. end; var F_Categ: TF_Categ;
69
Borland
implementation {$R *.DFM} uses FMenu, DMModelo;
procedure TF_ Categ.Inicio; begin if F_Menu.DBDisco.IsSQLbased then F_Menu.DBDisco.StartTransaction; DM_Modelo.TabCategor.Open; Screen.Cursor := crDefault; ShowModal; end;
Inicio do procedimento Se a base de dados padro SQL Inicia o modo de transaes Ativa a Tabela Faz o cursor ficar no formato de Seta Mostra o formulrio F_Categ
A propriedade cursor no exemplo foi atribuda a unidade Screen que atribui ao sistema o modelo do cursor, mas possvel tambm atribuir um determinado cursor a um objeto especfico, a propriedade pode ser alterada para os diversos tipos de cursores default do windows com as figuras que se seguem:
No necessrio colocar o comando Close para o objeto butFechar pois a propriedade Kind far isto automtico. Cdigo para encerrar as tabelas do DataModule quando for dada sada no formulrio, observe que o usurio no deve poder estar inserindo ou editando registros: 1. No objeto F_Categ, localize-o atravs da Object Inspector, d um duplo click sobre o evento OnClose:
procedure TF_Categ.FormClose(Sender: TObject; var Action: TCloseAction); begin if DM_Modelo.DSCategor.State in [dsEdit, dsInsert] then Verifica se o estado do objeto begin DataSource Edio ou insero MessageDlg('Cancele a edio (ou insero) da Categoria antes de fechar!', mostra mensagem mtInformation, [mbOK], 0); de informao Cancela a sada da janela Action := caNone; Exit; Sai da procedure end; Faz o cursor virar uma ampulheta Screen.Cursor := crHourGlass;
70
Borland
Fecha a tabela Se a base de dados padro SQL Encerra o modo de transaes gravando
as alteraes no banco de dados
A funo MessageDlg faz parte da Unit Dialogs ento necessrio fazer uso desta Unit, para tanto insira o seguinte cdigo (abaixo da diretiva de compilao):
{$R *.DFM} uses FMenu, DMModelo, Dialogs;
{ Menu Principal do Sistema } { Referencia ao DataModule } { Utilizado para o controle da funo MessageDlg }
Cdigo para localizar determinado registro, observe que se o usurio no deve estar inserindo ou editando registros: 1. D um duplo Click sob o objeto ButLocalizar:
procedure TF_Categ.ButLocalizarClick(Sender: TObject); Declarao de variveis var Cria a varivel ObjPesquisa do tipo String ObjPesquisa: String; begin if DM_Modelo.DSCategor.State in [dsEdit, dsInsert] then begin MessageDlg('Cancele a edio (ou insero) da Categoria antes de localizar!', mtInformation, [mbOK], 0); Exit; end; ObjPesquisa := DM_Modelo.TabCategorSig_Categ.Value; Atribui a ObjPesquisa o valor do campo de tabela Sig_Categ if InputQuery('Entre com a sigla da categoria', Solicita a digitao do cdigo a ser procurado 'Sigla',ObjPesquisa) then if not DM_Modelo.TabCategor.FindKey([ObjPesquisa]) then Pesquisa o campo digitado na tabela Caso no seja encontrado informa MessageDlg('Sigla da Categoria no encontrada.', mtInformation, [mbOK], 0); end;
+ A funo InputQuery tambm faz parte da Unit Dialogs. + O mtodo FindKey faz parte do Objeto TTable.
Criando Funes Globais
Uma funo ou um procedimento global e uma srie de comandos comuns a um sistema como um todo, em linguagem Pascal quase que proibido (no proibido pois a linguagem permite) a utilizao de um mesmo conjunto de comandos repetidas vezes, note que para o nosso formulrio temos os mesmos comandos em chamadas diferentes:
procedure TF_Categ.FormClose(Sender: TObject; var Action: TCloseAction); begin if DM_Modelo.DSCategor.State in [dsEdit, dsInsert] then begin MessageDlg('Cancele a edio (ou insero) da Categoria antes de fechar!',
Aqui Aqui
71
Borland
mtInformation, [mbOK], 0); Action := caNone; Exit; end; ... end; procedure TF_Categ.ButLocalizarClick(Sender: TObject); var ObjPesquisa: String; begin if DM_Modelo.DSCategor.State in [dsEdit, dsInsert] then begin MessageDlg('Cancele a edio (ou insero) da Categoria antes de localizar!', mtInformation, [mbOK], 0); Exit; end; ... end;
Aqui
Podemos ento retirar o trecho e criarmos uma funo isolada que criticar o estado da edio devolvendo a mensagem, modificando o trecho diferente, ficando desta maneira (no esquea de declarar a funo na rea PRIVATE):
private function CriticaEdicao(AntesDe: String) : boolean; public procedure inicio; end;
var ... ... ... function TF_Categ.CriticaEdicao(AntesDe: String) : boolean; Recebe o tipo da mensagem begin if DM_Modelo.DSCategor.State in [dsEdit, dsInsert] then Verifica o estado begin MessageDlg('Cancele a edio (ou incluso) da categoria antes de ' + AntesDe, mtError, [mbOK], 0); Monta e envia a mensagem Result := True; Devolve que enviou a mens. end else Devolve que no enviou a mens. Result := False; end; procedure TF_Categ.FormClose(Sender: TObject; var Action: TCloseAction); begin Substitui pela chamada a funo if CriticaEdicao('fechar' ) then begin Action := caNone; Exit; end; ... end; procedure TF_Categ.ButLocalizarClick(Sender: TObject);
72
Borland
Note que j ganhamos uma certa vantagem, ao invs de termos que alterar em dois lugares diferentes s teremos que alterar em um nico lugar, mas ainda no est perfeito pois devemos lembrar que um sistema normalmente no composto por apenas uma tabela, sem contar a parte do cadastro, ento se seguirmos o mesmo padro de construo de formulrios para outras tabelas continuaremos a repetir vrios comandos, ento vamos fazer que a nossa funo sirva para a critica de edio de qualquer tabela, para isto precisamos enviar tambm o DataSource que pesquisar o estado e uma outra varivel do tipo String para dizermos de qual tabela estamos falando para cancelar a edio, v para o objeto F_Menu e crie a seguinte funo (no esquea de declarar na rea PUBLIC):
private procedure ShowHint (Sender: TObject); public function CriticaEdicao(DSOrigem: TDataSource; DoQue, AntesDe: String) : boolean; end; var ... ... { Funo Critica Edio Recebe: DSOrigem: DataSouce para investigar o estado DoQue: Nome real da Tabela AntesDe: Funo a executar do tipo Fechar, Localizar... Devolve: True - Se o DataSource est em estado de edio ou insero False - Se o DataSource est em estado de navegao } function TF_Menu.CriticaEdicao(DSOrigem: TDataSource; DoQue, AntesDe: String) : boolean; begin if DSOrigem.State in [dsEdit, dsInsert] then begin MessageDlg('Cancele a edio (ou incluso) ' + DoQue + ' antes de ' + AntesDe, mtError, [mbOK], 0); Result := True; end else Result := False; end;
Aqui
Elimine
73
Borland
... ... Elimine as linhas da funo ... ... procedure TF_Categ.FormClose(Sender: TObject; var Action: TCloseAction); begin if F_Menu.CriticaEdicao(DM_Modelo.DSCategor, 'Categoria', 'fechar' ) then Substitua aqui begin Action := caNone; Exit; end; ... end; procedure TF_Categ.ButLocalizarClick(Sender: TObject); var ObjPesquisa: String; begin if F_Menu.CriticaEdicao(DM_Modelo.DSCategor, 'Categoria', localizar' ) then Exit; ... end;
Substitua aqui
3. O objeto F_Categ faz parte da Unit fCateg ento necessrio fazer o uso desta Unit, para tanto insira o seguinte cdigo (abaixo da diretiva de compilao):
{$R *.DFM} uses fSobre, { Janela do Sobre o Sistema } fCateg; { Cadastro da Tabela de Categoria }
4. Saia do Code Editor e salve o formulrio e o projeto. 5. Rode o projeto e teste o formulrio de categoria, insira algumas categorias, tente provocar o erro de duplicao, tente inserir um registro com o cdigo vazio e localizar um registro.
74
Borland
6. Se alguma coisa deu errada, releia o captulo, ou ento confira todo o cdigo:
unit fcateg; interface uses SysUtils, Windows, Messages, Classes, Graphics, Controls, StdCtrls, Forms, DBCtrls, DB, Mask, ExtCtrls, Buttons; type TF_Categ = class(TForm) ScrollBox: TScrollBox; Label1: TLabel; EditSig_Categ: TDBEdit; Label2: TLabel; EditDes_Categ: TDBEdit; DBNavigator: TDBNavigator; Panel1: TPanel; Panel2: TPanel; Panel3: TPanel; ButFechar: TBitBtn; ButLocalizar: TBitBtn; procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure ButLocalizarClick(Sender: TObject); private { private declarations } public procedure inicio; end; var F_Categ: TF_Categ; implementation {$R *.DFM} uses fMenu, DMModelo, Dialogs;
{ Menu Principal do Sistema } { Referencia ao DataModule } { Utilizado para o controle da funo MessageDlg }
procedure TF_Categ.Inicio; begin if F_Menu.DBDisco.IsSQLbased then F_Menu.DBDisco.StartTransaction; DM_Modelo.TabCategor.Open; Screen.Cursor := crDefault; ShowModal; end; procedure TF_Categ.FormClose(Sender: TObject; var Action: TCloseAction); begin if F_Menu.CriticaEdicao(DM_Modelo.DSCategor, 'Categoria', 'Fechar' ) then begin
75
Borland
Action := caNone; Exit; end; Screen.Cursor := crHourGlass; DM_Modelo.TabCategor.Close; if F_Menu.DBDisco.IsSQLbased then F_Menu.DBDisco.Commit; end; procedure TF_Categ.ButLocalizarClick(Sender: TObject); var ObjPesquisa: String; begin if F_Menu.CriticaEdicao(DM_Modelo.DSCategor, 'Categoria', 'Localizar' ) then Exit; ObjPesquisa := DM_Modelo.TabCategorSig_Categ.Value; if InputQuery('Entre com a Sigla da categoria','Sigla',ObjPesquisa) then if not DM_Modelo.TabCategor.FindKey([ObjPesquisa]) then MessageDlg('Sigla da Categoria no encontrada.',mtInformation,[mbOK],0); end; end.
Comandos e suas funes, por ordem de apario: [Tabela].Open - Ativa um objeto Table equivalente a Active := True. [Form].ShowModal - Ativa o objeto Form, no permitindo que nenhum outro objeto Form anterior seja ativado, at que o mesmo seja desativado. Exit - Sai da funo ou procedimento. [Tabela].Close - Desativa um objeto Table equivalente a Active := False. Var - Define uma cadeia de variveis locais. InputQuery - Mostra uma caixa de dilogo para leitura e entrada de variveis do tipo String. [Tabela].FindKey - Funo que realiza uma pesquisa indexada no objeto Table, atravs do ndice definido, retorna True se encontrou ou False se fim de arquivo
76
Captulo VI
Trabalhando com janela Pai X Filha
Se voc at agora no sentiu dificuldade em criar e entender o trabalho com tabelas livres, no sentir tambm dificuldade em criar o formulrio para receber este caso, ao contrrio, aconselho que voc releia e refaa o captulo anterior. Em nosso projeto, cada registro na tabela de msica s existir se houver um correspondente na tabela bsico, ento a tabela bsico pai (mestre) da tabela msica que sua filha (detalhe). Esta teoria acima explicada no conceito de modelo relacional de dados (MER). O Delphi incorpora este modelo mesmo para banco de dados no-relacionais, caso estivssemos utilizando o dBase em nosso projeto.
1. O tipo a ser criada. Form Options: Create a master/detail form Uma janela mestre e detalhes DataSet Options: Create a form using TTables objects Usando o objeto tabela Boto Next.
2. A tabela mestre a ser usada para a janela. Drive or Alias name: AliasDisco Table Name: basico.dbf Boto Next
77
Borland
6. A tabela detalhe a ser usada para a janela. Drive or Alias name: AliasDisco Table Name: musica.dbf Boto Next
9.
10.
78
Borland
Montagem da chave de ligao Available Indexes : Primary Detail Fields : COD_DISCO Master Fields : COD_DISCO Boto Add Joined Fields COD_DISCO -> COD_DISCO Boto Next
Completo Gera a tela como form principal - No O Que gerar: Form e DataModule Boto Finish
Sobre os DataModules
Como eu disse no captulo anterior possvel criar um nico DataModule abrangendo o modelo relacional completo, basta para isto voc fazer o formulrio que est chamando o DataModule controlar o comando Open e Close das tabelas. No farei desta maneira pois isto ao mesmo tempo que simplificaria o meu trabalho dificultaria o seu entendimento, que o de uma pessoa que estivesse aprendendo o Delphi neste momento, ento para este trabalho adotarei um DataModule para cada cadastro.
, encontrado na Component Palette pgina Data Access, e altere objeto DataSource as seguintes propriedades: Para o objeto Table1 (J existente):
Propriedade DatabaseName TableName Name Valor BaseDisco (se este valor no estiver disponvel chame o objeto F_Menu) BASICO TabBasico Descrio Nome do Banco de Dados ou a localizao do diretrio das tabelas Nome externo da tabela Nome do objeto Nome do campo indexado
IndexFieldNames NOM_DISCO
79
Borland
TableName Name MasterSource MasterFields
Nome externo da tabela Nome do objeto Nome do campo indexado Nome do DataSource Mestre Campo de ligao da tabela Mestre
IndexFieldNames COD_DISCO
IndexFieldNames NOM_DISCO
IndexFieldNames SIG_CATEG
IndexFieldNames SIG_CATEG
Os objetos na hora da execuo do formulrio ficaro invisveis, mas bom coloc-los em cantos estratgicos, isto evita a confuso.
80
Borland
9 9 9 9 9
Crie o objeto Query , encontrado na Component Palette pgina Data Access, que servir para calcular o cdigo automtico, calculando sempre o cdigo de maior valor, e altere as seguintes propriedades:
Valor BaseDisco QryContador Select Max(COD_DISCO) from BASICO Descrio Nome do Banco de Dados ou a localizao do diretrio das tabelas Nome do Objeto Clusula SQL, selecione o maior valor do campo COD_DISCO da tabela BASICO
O campo COD_DISCO criado, servir apenas como uma chave de ligao entre a tabela Basico e Musica, ser uma chave interna do nosso sistema e sua alimentao se far atravs deste objeto SQL criado pegando o maior valor e adicionando 1.
9 9 9 9 9 9 9 9 9 9 9
COD_DISCO, Propriedade DisplayLabel: Cdigo; NOM_DISCO, Propriedade DisplayLabel: Nome; TIP_DISCO, Propriedade DisplayLabel: Tipo e EditMask: >AAA;0;_ FOT_CAPA, Propriedade DisplayLabel: Foto; e SIG_CATEG, Propriedade DisplayLabel: Categoria e EditMask: >AA;0;_
81
Borland
Antes de iniciarmos a programao do DataModule compare como ficou o DataModule e salve-o com o nome de DMBasico:
Controlando o DataModule
Agora falta o cdigo, note que a maior parte uma repetio daquilo que j vimos anteriormente: Ativando as tabelas ao ser chamado DataModule: 1. Clique no objeto DMBasico e na Object Inspector na pgina Events d um duplo clique sobre o evento OnCreate e altere-o do seguinte modo:
procedure TDM_Basico.DM_BasicoCreate(Sender: TObject); begin if F_Menu.DBDisco.IsSQLbased then Se a base de dados padro SQL Inicia o modo de transaes F_Menu.DBDisco.StartTransaction; TabCategor.Open; Ativa as tabelas TabCategorConf.Open; TabMusica.Open; TabBasico.Open; TabBasicoConf.Open; end;
Cdigo para encerrar as transaes com a Base de Dados e fechar as tabelas quando for encerrado o DataModule. 1. Digite F11 e localize o objeto DM_Categ, na Object Inspector, na pgina Events, d um duplo click sobre o evento OnDestroy:
procedure TDM_Basico.DM_BasicoDestroy(Sender: TObject); begin Fecha as tabelas TabBasico.Close; TabBasicoConf.Close; TabMusica.Close; TabCategor.Close; TabCategorConf.Close; if F_Menu.DBDisco.IsSQLbased then Se a base de dados padro SQL Encerra o modo de transaes gravando as F_Menu.DBDisco.Commit; end; alteraes no banco de dados
82
Borland
Lembre-se da utilizao do objeto F_Menu, ento preciso declarar a unidade a qual ele pertence com o comando USES (abaixo da diretiva de compilao):
{$R *.DFM} uses fMenu; { Menu Principal }
Repare que no incio desta Unit tambm existe uma outra declarao Uses, aps a sesso interface, ento por que no colocar todas essas declaraes em um lugar s? 1o) O Delphi controlar (colocando ou removendo) as Units ali colocadas (dependendo dos objetos utilizados) e 2o) Todos os comandos declarados antes da declarao implementation (com exceo de eventos de criao do tipo onCreate), sero executados e objetos e units ficaro em memria esperando serem chamados, ento impraticvel colocar units que s sero utilizadas em tempo de execuo.
Contadores
O objeto query realiza consultas em modo SQL, no prximo captulo o utilizaremos para criarmos nossas consultas mas, neste momento ele ser utilizado para verificar qual o maior valor armazenado no campo cdigo. A cada novo registro devemos criar tambm um novo COD_DISCO (lembra do objeto QryContador). Alm disso, precisamos nos posicionar no primeiro campo do cadastro, isto ser realizado em dois eventos distintos: 1. Marque o objeto TabBasico, e d um duplo clique sobre o evento onNewRecord:
Observe que foi utilizado o objeto F_Basico, ento preciso declarar a unidade a qual ele pertence com o comando USES (abaixo da diretiva de compilao):
{$R *.DFM} uses fBasico; { Cadastro do Bsico } fMenu; { Menu Principal }
83
Borland
end; end;
O comando with utilizado como mtodo de taquigrafia, para no escrevermos vrias vezes o mesmo nome de um determinado objeto. Porque no colocarmos todo o cdigo no evento onNewRecord ? Por causa do controle multi-usurio, imagine, um indivduo A inicia a incluso de um CD, e um indivduo B tambm inicia outra incluso, como o cdigo do indivduo A ainda no foi gravado no banco, ser dado o mesmo cdigo para o indivduo B, isto no acontecer se o cdigo for calculado momentos antes de ser gravado o registro, com o caso do evento BeforePost. Para confirmarmos as alteraes para a base SQL, pressione novamente a tecla F11 e na pgina Events, d um duplo click sobre o evento AfterPost:
procedure TDM_Basico.TabBasicoAfterPost(DataSet: TDataSet); begin Se a base de dados padro SQL if F_Menu.DBDisco.IsSQLbased then begin Gravando as alteraes da tabela F_Menu.DBDisco.Commit; F_Menu.DBDisco.StartTransaction; Reinicia o modo de transaes end; end;
Validando os Campos
Para no acontecer um duplicao dos nomes dos CDs, utilizaremos para a crtica a mesma idia do que aconteceu com o formulrio de Categoria: 1. Marque o objeto TabBasicoNOM_DISCO, e d um duplo clique sobre o evento OnValidate:
procedure TDM_Basico.TabBasicoNom_DiscoValidate(Sender: TField); begin if DSBasico.State in [dsEdit, dsInsert] then Se o modo de insero ou edio if TabBasicoConf.FindKey([TabBasicoNOM_DISCO]) then Pesquisa o campo digitado begin F_Basico.EditNOM_DISCO.SetFocus; Altera a posio do cursor Caso j exista mostra mensagem raise Exception.Create('Nome do CD duplicado'#10+ 'Click no boto "Localiza" em caso de dvida'); de erro e impede o cadastro end; end;
Para que o nosso usurio escolha somente as categorias existentes: 1. Marque o objeto TabBasicoSIG_CATEG, e d um duplo clique sobre o evento OnValidate:
procedure TDM_Basico.TabBasicoSig_CategValidate(Sender: TField); begin if DSBasico.State in [dsEdit, dsInsert] then if not (TabCategorConf.FindKey([TabBasicoSIG_CATEG])) then Observe o comando NOT begin F_Basico.EditSIG_CATEG.SetFocus; raise Exception.Create('Sigla da categoria no existe'#10+
84
Borland
end; end;
Com o DataModule o nosso trabalho j est concludo, salve o objeto e confirme o cdigo:
unit DMBasico; interface uses SysUtils, Windows, Classes, Graphics, Controls, Forms, Dialogs, DB, DBTables; type TDM_Basico = class(TDataModule) TabMusicaCod_Disco: TFloatField; TabMusicaNum_Faixa: TFloatField; TabMusicaNom_Musica: TStringField; DSBasico: TDataSource; TabBasico: TTable; TabMusica: TTable; DSMusica: TDataSource; TabBasicoConf: TTable; TabCategor: TTable; TabCategorConf: TTable; DSCategor: TDataSource; TabBasicoCod_Disco: TFloatField; TabBasicoNom_Disco: TStringField; TabBasicoTip_Disco: TStringField; TabBasicoFot_Capa: TBlobField; TabBasicoSig_Categ: TStringField; QryContador: TQuery; QryContadorMAXOFCOD_DISCO: TFloatField; procedure DM_BasicoCreate(Sender: TObject); procedure DM_BasicoDestroy(Sender: TObject); procedure TabBasicoNewRecord(DataSet: TDataSet); procedure TabBasicoBeforePost(DataSet: TDataSet); procedure TabBasicoAfterPost(DataSet: TDataSet); procedure TabBasicoNom_DiscoValidate(Sender: TField); procedure TabBasicoSig_CategValidate(Sender: TField); private { private declarations } public { public declarations } end; var DM_Basico: TDM_Basico; implementation {$R *.DFM} uses fBasico, { Cadastro do Bsico }
85
Borland
fMenu; { Menu Principal } procedure TDM_Basico.DM_BasicoCreate(Sender: TObject); begin if F_Menu.DBDisco.IsSQLbased then F_Menu.DBDisco.StartTransaction; TabCategor.Open; TabCategorConf.Open; TabMusica.Open; TabBasico.Open; TabBasicoConf.Open; end; procedure TDM_Basico.DM_BasicoDestroy(Sender: TObject); begin TabBasico.Close; TabBasicoConf.Close; TabMusica.Close; TabCategor.Close; TabCategorConf.Close; if F_Menu.DBDisco.IsSQLbased then F_Menu.DBDisco.Commit; end; procedure TDM_Basico.TabBasicoNewRecord(DataSet: TDataSet); begin F_Basico.EditNOM_DISCO.SetFocus; end; procedure TDM_Basico.TabBasicoBeforePost(DataSet: TDataSet); begin if DSBasico.State = dsInsert then begin QryContador.Active := False; QryContador.Active := True; with QryContador.Fields[0] do if IsNull then TabBasicoCOD_DISCO.Value := 1 else TabBasicoCOD_DISCO.Value := AsInteger + 1; end; end; procedure TDM_Basico.TabBasicoAfterPost(DataSet: TDataSet); begin if F_Menu.DBDisco.IsSQLbased then begin F_Menu.DBDisco.Commit; F_Menu.DBDisco.StartTransaction; end; end; procedure TDM_Basico.TabBasicoNom_DiscoValidate(Sender: TField); begin if DSBasico.State in [dsEdit, dsInsert] then if TabBasicoConf.FindKey([TabBasicoNOM_DISCO]) then
86
Borland
begin F_Basico.EditNOM_DISCO.SetFocus; raise Exception.Create('Nome do CD duplicado'#10+ 'Click no boto "Localiza" em caso de dvida'); end; end; procedure TDM_Basico.TabBasicoSig_CategValidate(Sender: TField); begin if DSBasico.State in [dsEdit, dsInsert] then if not (TabCategorConf.FindKey([TabBasicoSIG_CATEG])) then begin F_Basico.EditSIG_CATEG.SetFocus; raise Exception.Create('Sigla da categoria no existe'#10+ 'Click no boto "Localiza Categoria" em caso de dvida'); end; end; end.
Organizando os Panels
Vamos passar para as alteraes com objeto F_Basico. Os objetos da janela se encontram distribudos em trs objetos Panel, o primeiro (Panel1) guarda o objeto DBNavigator, o segundo (Panel2) guarda os labels e os campos do arquivo BASICO e o terceiro (Panel3) guarda o objeto DBGrid1 que controlar o arquivo MUSICA. Altere a propriedade Align do objeto Panel3, para alNone. Aumente a janela do modo que todos os campos do objeto mestre apaream.
87
Borland
Organizando os Panels
Vamos organizar cada objeto Panel por partes: Objeto Panel1 Modifique o objeto DBNavigator conforme descrito no captulo anterior.
88
Borland
Para a propriedade Hints, escreva novamente o auxlio para cada boto ou, chame o formulrio F_Categ e copie as descries da propriedade Hints com Ctrl+C e chame novamente o objeto DBNavigator e digite Ctrl+V dentro da propriedade. Modifique tambm o objeto Panel1 conforme descrito no captulo anterior e altere a propriedade Caption para CDs. Objeto Panel2
Altere as propriedades Height e Width para 216 do objeto ImageFOT_CAPA. Crie um novo objeto Label e altere as seguintes propriedades:
Valor &Msicas: MS Sans Serif, Negrito, 8, Castanho DBGrid1 Descrio Label do objeto Tipo de letra a ser mostrada no objeto Controle do foco
Aumente o objeto Panel2 de forma a caber os outros objetos, organize os objetos da seguinte forma: Nome, Tipo, Categoria e Msicas, ao lado coloque a foto. Deixe o espao de um campo entre Categoria e Msicas. , Remova o objeto EditTIP_DISCO e em seu lugar crie o objeto DBComboBox encontrado na Component Palette pgina Data Controls, e altere as seguintes propriedades:
Valor DM_Basico.DSBasico TIP_DISCO MS Sans Serif, Normal, 8, Azul Marinho Selecione o tipo AAA; AAD; ADD; e DDD ComboTIP_DISCO True Descrio DataSource vinculado Campo de tabela Tipo de letra a ser mostrada no objeto Ajuda on-line para o objeto especfico Itens que aparecero como opes do COMBO BOX, coloque um em cada linha. Nome do objeto Mostrar o contedo da propriedade hint sob a forma de uma caixa de ajuda on-line
No objeto Label3 recoloque a propriedade FocusControl apontando para o objeto ComboTIP_DISCO. Objeto Panel3
Marque o objeto DBGrid1 e altere as propriedades Align para alNone e BorderStyle para bsSingle, pressione Ctrl+X marque o objeto ScrollBox e pressione Ctrl+V, acerte o objeto de forma que este caiba abaixo do objeto Label1 (Msicas:). Elimine o objeto Panel3, clique sobre ele e pressione Del.
Modificando a Janela
Altere as propriedades BorderIcons, BorderStyle e Position conforme descrito no captulo anterior.
89
Borland
Mude a propriedade Caption para Cadastro. Altere a propriedade Align do objeto Panel2 para alClient e acerte as posies no formulrio. Salve o formulrio e salve o projeto. No espao deixado entre os labels de Categoria e Msica, crie o objeto DBText , encontrado na Component Palette pgina Data Controls, que servir para mostrar o nome da categoria selecionada, altere as seguintes propriedades:
Valor DM_Basico.DSCategor DES_CATEG MS Sans Serif, Normal, 8, Castanho Descrio DataSource vinculado Campo de tabela Tipo de letra a ser mostrada no objeto
90
Borland
Name ShowHint Width
categoria ButInsCateg True 25 Nome do objeto Mostrar o contedo da propriedade hint sob a forma de uma caixa de ajuda on-line Tamanho do objeto
A funo de cada boto est explicada na propriedade hint, para os objetos ButLocCateg e ButInsCateg iremos nos aproveitar dos formulrios j construdos anteriormente. Provavelmente voc no ir encontrar o arquivo LANTERNA.BMP solicitado para o segundo boto, teremos de cri-lo: 1. Salve o formulrio e feche o projeto, localize (no diretrio demos do Delphi) e abra o projeto [DiretrioDelphi]\DEMOS\DB\MASTAPP\MASTAPP.DPR 2. Atravs do Project Manager abra o formulrio SearchDlg. 3. Localize o objeto SearchButton e clique na propriedade Glyph. e nome proposto
+ +
9 9
DataSource: Nome do objeto DataSource vinculado; Font: Tipo da letra a ser mostrada no contedo do objeto;
91
Borland
9
Options: srie de opes de controle (se a opo True for selecionada): dgEditing: permite a edio e adio dos dados; dgAlwaysShowEditor: O grid entra automaticamente em modo de edio, no havendo a necessidade de pressionar Enter ou F2 (depende que a propriedade dgEditing = True); dgTitles: Viabiliza o uso do ttulo de cada campo; dgIndicator: Habilita o ponteiro de indicao da coluna; dgColumnResize: A coluna pode ser redimensionada; dgColLines: Habilita a separao das colunas; dgRowLines: Habilita a separao das linhas; dgTabs: Use o pressionamento das teclas Tab e Shif+Tab para se mover dentro das colunas; dgRowSelect: Seleciona, com uma tarja azul, todas as colunas de uma linha; dgAlwawsShowSelection: As clulas do grid so mostradas constantemente selecionadas, mesmo que este no detenha o foco. dgConfirmDelete: Use as teclas Ctrl+Del, para excluir dados; dgCancelOnExit: Se qualquer incluso estiver pendente e for dado sada no grid sem a validao dos dados, a incluso cancelada. Previne a incluso de registros invlidos ou em branco. TitleFont: Tipo da letra a ser mostrada nos ttulos do objeto.
ShowHint
Mostrar o contedo da propriedade hint sob a forma de uma caixa de ajuda on-line
No lhe aconselho usar este objeto para realizar alteraes em bases de dados (apesar de isto ser possvel) mais prtico utilizar uma janela separada para realizar este trabalho, as idias ficaro mais bem ordenadas, se cada formulrio controlar uma nica entrada em tabela de cada vez. Se voc est meio perdido com isto tudo, no se desespere, simplesmente compare os formulrios para ver se no falta nada:
92
Borland
Finalmente, a programao
Agora falta apenas o cdigo, pelo tamanho do formulrio e pelo nmero de controles j d para pensarmos que precisamos programar linhas e linhas de cdigo, engano ! o maior trabalho j foi feito, observe: Criando o DataModule ao ser chamado formulrio: 1. Clique no boto Editor.
public procedure inicio; end; var F_Basico: TF_Basico; implementation {$R *.DFM} procedure TF_Basico.Inicio; begin DM_Basico := TDM_Basico.Create(Application); Screen.Cursor := crDefault; ShowModal; end;
Crie o incio do procedimento Cria o DataModule Faz o cursor ficar no formato de Seta Mostra o formulrio F_Basico
Cdigo para eliminar o DataModule, basicamente o mesmo trabalho realizado com o objeto F_Basico:
93
Borland
Lembre-se que a funo CriticaEdicao faz parte da Unit fMenu, ento preciso declarar esta unidade com o comando USES (abaixo da diretiva de compilao):
{$R *.DFM} uses DMBasico, { Referncia ao DataModule } fMenu; { Menu Principal do Sistema }
Repare que no incio desta Unit existe uma declarao Uses, aps o comando interface. Ento por que no colocar todas essas declaraes em um lugar s? 1.O Delphi controlar (colocando ou removendo) estas Units ali colocadas (dependendo dos objetos utilizados) e 2.Todos os comandos declarados antes da declarao implementation (com exceo de eventos de criao. Ex.: onCreate), sero executados e objetos e units ficaro em memria esperando serem chamados, ento impraticvel colocar units que s sero utilizadas em tempo de execuo.
Consulta
Cdigo para pesquisar os registros das tabelas, basicamente utilizaremos o mesmo trabalho realizado com o objeto F_Categ: 1. D um duplo click sob o objeto ButLocalizar:
procedure TF_Basico.ButLocalizarClick(Sender: TObject); var ObjPesquisa: String; begin if F_Menu.CriticaEdicao(DM_Basico.DSBasico, 'CD', 'Localizar') then Exit; ObjPesquisa := TabBasicoNOM_DISCO.Value;
Lembra da Funo
Lembre-se que a funo InputQuery faz parte da Unit Dialogs, ento preciso declarar esta unidade com o comando USES (abaixo da diretiva de compilao):
{$R *.DFM}
94
Borland
uses DMBasico, { Referncia ao DataModule } fMenu, { Menu Principal do Sistema } Dialogs; { Gerente de Mensagens }
Desta vez foi utilizado o comando FindNearest, este comando consulta por parte inicial do cdigo encontrado um cdigo igual ou maior que o pesquisado, no preciso ao usurio lembrar o nome completo como no comando FindKey. Ateno: o comando FindNearest no retornar uma varivel boolean (True ou False como resultado da pesquisa) ento no se faz a necessidade de crticas sobre o mesmo. Salvo exceo se o campo for tipo numrico ou tipo data ento utilize este comando em conjunto com o comando Try. Veja no prximo captulo como. O cdigo para o boto que localizar um registro na tabela de categoria ser tratado no prximo captulo. Para inserir novos registros na tabela de categoria utilizaremos o formulrio construdo anteriormente, a nica diferena que desta vez devemos estar em modo de edio: 1. D um duplo click sobre o objeto ButInsCateg:
procedure TF_Basico.ButInsCategClick(Sender: TObject); begin if not (DSBasico.State in [dsEdit, dsInsert]) then Se no estiver em estado de ediao ou begin incluso MessageDlg('Voc no est no modo de edio!', Envia mensagem de erro mtInformation, [mbOK], 0); exit; end Screen.Cursor := crHourGlass; if F_Menu.DBDisco.IsSQLbased then F_Menu.DBDisco.Commit; with TF_Categ.Create(Self) do begin Inicio; Free; end; if F_Menu.DBDisco.IsSQLbased then F_Menu.DBDisco.StartTransaction; Screen.Cursor := crDefault; end;
Faz o cursor virar uma ampulheta Gravamos as alteraes no banco de dados Cria o formulrio na rea de memria Chama o formulrio Elimina o formulrio da memria Se a base de dados padro SQL Inicia o modo de transaes Faz o cursor ficar no formato de Seta
95
Borland
9 9 9
Objeto.CutToClipboard, envia o contedo do objeto para rea de transferncia; e Objeto.CopyToClipboard, faz uma cpia do contedo do objeto na rea de transferncia. Objeto.PasteFromClipboard, traz para o contedo do objeto da rea de transferncia;
Prximo passo, o cdigo para o boto que permitir trazer uma imagem armazenada na rea de transferncia do Windows (Salva com o utilitrio PaintBrush, por exemplo) para o campo da Foto: 1. D um duplo click sobre o objeto ButPaste:
Prximo passo, o cdigo para o boto que permitir trazer uma imagem em arquivo .BMP para o campo da Foto: 1. D um duplo click sobre o objeto ButPaste:
procedure TF_Basico.ButPasteClick(Sender: TObject); begin If AbreBmp.Execute then Verifica se foi clicado em OK ImageFot_Amostra.Picture.LoadFromFile( AbreBmp.FileName ); Carrega o arquivo end;
96
Borland
9 9
Propriedade DatabaseName TableName Name ReadOnly
Altere a propriedade name do formulrio para F_MUSICA. Chame o DataModule DMBasico e crie mais um objeto TTable, para fazermos as crticas das msicas duplicadas e altere as seguintes propriedades:
Valor BaseDisco MUSICA TabMusicaConf True Descrio Nome do Banco de Dados ou a localizao do diretrio das tabelas Nome externo da tabela Nome do objeto Nome do campo indexado Somente leitura
IndexFieldNames Cod_Disco;Num_Faixa
No esquea de alterar o programa do DataModule para abrir e fechar a nova tabela e coloque a crtica para a tabela de msica, evento OnValidate do objeto TabMusicaNum_Faixa:
procedure TDM_Basico.TabMusicaNum_FaixaValidate(Sender: TField); begin if DSMusica.State in [dsEdit, dsInsert] then begin TabMusicaConf.EditKey; TabMusicaConf.FieldByName('COD_DISCO').AsFloat := TabMusicaCod_Disco.Value; TabMusicaConf.FieldByName('NUM_FAIXA').AsFloat := TabMusicaNum_Faixa.Value; if TabMusicaConf.GotoKey then begin F_Musica.EditNum_Faixa.SetFocus; raise Exception.Create('Faixa do CD duplicada'); end; end; end;
Repare no uso do comando GotoKey ao invs do comando FindKey, ele foi utilizado por se tratar de uma chave composta. Coloque tambm a crtica para a tabela de msica, evento OnNewRecord do objeto TabMusica:
procedure TDM_Basico.TabMusicaNewRecord(DataSet: TDataSet); begin F_Musica.EditNUM_FAIXA.SetFocus; end;
+ +
Uma ltima crtica ser para confirmarmos as alteraes para a base SQL, pressione novamente a tecla F11 e na pgina Events, d um duplo click sobre o evento AfterPost:
procedure TDM_Basico.TabMusicaAfterPost(DataSet: TDataSet); begin if F_Menu.DBDisco.IsSQLbased then Se a base de dados padro SQL begin
97
Borland
9 9
Remova o Label e o DBEdit do campo COD_DISCO; e Mude a propriedade do BorderStyle para bsDialog.
Altere inicialmente, a clusula uses para o DMBasico, em seguida a propriedade de todos os campos e do DBNavigator para DM_Basico.DSMusica. A programao do formulrio basicamente a mesma para as tabelas, ento ao invs de perder tempo e espao falando tudo de novo, observe o cdigo completo e note que a nica mudana est em prevenir para que o formulrio no seja fechado em tempo de edio ou insero e com o estado do cursor:
unit fMusica; interface uses SysUtils, Windows, Messages, Classes, Graphics, Controls, StdCtrls, Forms, DBCtrls, DB, Buttons, Mask, ExtCtrls; type TF_Musica = class(TForm) ScrollBox: TScrollBox; Label2: TLabel; EditNum_Faixa: TDBEdit; Label3: TLabel; EditNom_Musica: TDBEdit; Label4: TLabel; EditNom_Autor: TDBEdit; Label5: TLabel; EditTmp_Musica: TDBEdit; DBNavigator: TDBNavigator; Panel1: TPanel; Panel2: TPanel; Panel3: TPanel;
98
Borland
ButFechar: TBitBtn; procedure FormShow(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { private declarations } public { public declarations } end; var F_Musica: TF_Musica; implementation {$R *.DFM} uses DMBasico; { Referncia ao DataModule } procedure TF_Musica.FormShow(Sender: TObject); begin Screen.Cursor := crDefault; end;
procedure TF_Musica.FormClose(Sender: TObject; var Action: TCloseAction); begin Evento OnClose do objeto F_Musica if F_Menu.CriticaEdicao(DM_Basico.DSMusica, 'Msica', 'fechar' ) then begin Action := caNone; exit; end; Screen.Cursor := crHourGlass; end; end.
No preciso se preocupar com a gravao para o campo COD_DISCO, isto ser feito automaticamente pelo Delphi, mantendo a integridade referencial. Salve o formulrio com o nome fMusica.
Vamos agora alterar o boto do formulrio principal, objeto butMusica, que ser usado para chamar este segundo.
procedure TF_Basico.ButMusicaClick(Sender: TObject); begin if DM_Basico.DSBasico.State in [dsEdit, dsInsert] then begin MessageDlg('Salve a edio do CD antes de Editar as msicas!',mtInformation, [mbOk], 0); Exit; end; Screen.Cursor := crHourGlass; if F_Menu.DBDisco.IsSQLbased then F_Menu.DBDisco.Commit; with TF_Musica.Create(Self) do Criamos o formulrio em memria begin
99
Borland
No esquea tambm de retirar os objetos F_Musica e F_Basico da criao automtica, opo do menu principal clique em Options | Project..., qualquer dvida consulte o captulo anterior.
Os comandos listados se repetem tanto para o procedimento ButInsCategClick e para o procedimento ButMusicaClick, chame o formulrio F_Menu e crie o seguinte procedimento:
public procedure Prepara(Tipo: boolean); Aqui function CriticaEdicao(DSOrigem: TDataSource; DoQue, AntesDe: String) : boolean; end; var ... ... procedure TF_Menu.Prepara(Tipo: boolean); begin Se o valor da varivel tipo recebida for verdadeiro if tipo then begin Faz a primeira parte Screen.Cursor := crHourGlass; if DBDisco.IsSQLbased then DBDisco.Commit;
100
Borland
end else begin if DBDisco.IsSQLbased then DBDisco.StartTransaction; Screen.Cursor := crDefault; end; end;
Um segundo procedimento global pode ser criado verificando os eventos AfterPost dos DataModules Dm_Categ e DM_Basico (este segundo em dois lugares); observamos o mesmo procedimento:
if F_Menu.DBDisco.IsSQLbased then begin F_Menu.DBDisco.Commit; F_Menu.DBDisco.StartTransaction; end;
101
Borland
... procedure TF_Menu.GravaBanco; begin if DBDisco.IsSQLbased then Embutiremos os comandos puros aqui begin DBDisco.Commit; DBDisco.StartTransaction; end; end;
Agora substitua os eventos nos dos DataModules Dm_Categ e DM_Basico; pela seguinte chamada ao procedimento
begin F_Menu.GravaBanco; end;
Repare tambm que foi retirado das funes que ficaram no formulrio F_Menu as referncias da base de dados ao formulrio (eram F_Menu.DBDisco e ficou simplesmente DBDisco).
3. O objeto F_Basico faz parte da Unit fBasico ento necessrio fazer o uso desta Unit, para tanto insira o seguinte cdigo (abaixo da diretiva de compilao):
{$R *.DFM} uses fSobre, { Janela do Sobre o Sistema ... } fCateg, { Utilizada para o cadastro de Categorias } fBasico; { Utilizada para o cadastro de CDs }
No esquea de retirar o formulrio F_Basico da lista de formulrios criados automaticamente. 4. Saia do Code Editor e salve o formulrio e o projeto.
102
Borland
5. Podemos agora salvar e testar o formulrio completo, para incluir algumas imagens utilize o PaintBrush do Windows, ou outro utilitrio qualquer. 6. Se alguma coisa deu errada, releia o captulo, ou ento confira todo o cdigo:
unit fBasico; interface uses SysUtils, Windows, Messages, Classes, Graphics, Controls, StdCtrls, Forms, DBCtrls, DB, DBGrids, Buttons, Grids, Mask, ExtCtrls; type TF_Basico = class(TForm) ScrollBox: TScrollBox; Label2: TLabel; EditNom_Disco: TDBEdit; Label3: TLabel; Label4: TLabel; ImageFot_Capa: TDBImage; Label5: TLabel; EditSig_Categ: TDBEdit; DBNavigator: TDBNavigator; Panel1: TPanel; Panel2: TPanel; Panel4: TPanel; ButFechar: TBitBtn; ButLocalizar: TBitBtn; ButMusica: TBitBtn; Label1: TLabel; ComboTIP_DISCO: TDBComboBox; DBGrid1: TDBGrid; DBText1: TDBText; ButLocCateg: TSpeedButton; ButInsCateg: TSpeedButton; ButPaste: TSpeedButton; { AbreBmp: TOpenDialog; Se voc utilizou o objeto OpenDialog } procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure ButLocalizarClick(Sender: TObject); procedure ButInsCategClick(Sender: TObject); procedure ButPasteClick(Sender: TObject); procedure ButMusicaClick(Sender: TObject); private { private declarations } public procedure inicio; end; var F_Basico: TF_Basico; implementation {$R *.DFM} uses
103
Borland
DMBasico, fMenu, Dialogs, fCateg, fMusica;
{ Referncia ao DataModule } { Menu Principal do Sistema } { Gerente de Mensagens } { Cadastro de Categorias } { Cadastro de Msicas }
procedure TF_Basico.Inicio; begin DM_Basico := TDM_Basico.Create(Application); Screen.Cursor := crDefault; ShowModal; end; procedure TF_Basico.FormClose(Sender: TObject; var Action: TCloseAction); begin if F_Menu.CriticaEdicao(DM_Basico.DSBasico, 'CD', 'Fechar') then begin Action := caNone; Exit; end; Screen.Cursor := crHourGlass; DM_Basico.Free; end; procedure TF_Basico.ButLocalizarClick(Sender: TObject); var ObjPesquisa: String; begin if F_Menu.CriticaEdicao(DM_Basico.DSBasico, 'CD', 'Localizar') then Exit; ObjPesquisa := DM_Basico.TabBasicoNom_Disco.Value; if InputQuery('Pesquisa','Entre com o nome do CD (ou parte).', ObjPesquisa) then DM_Basico.TabBasico.FindNearest([ObjPesquisa]); end; procedure TF_Basico.ButInsCategClick(Sender: TObject); begin if not (DM_Basico.DSBasico.State in [dsEdit, dsInsert]) then begin MessageDlg('Voc no est no modo de edio!',mtInformation,[mbOK],0); exit; end; F_Menu.Prepara(True); with TF_Categ.Create(Self) do begin Inicio; Free; end; F_Menu.Prepara(False); end; procedure TF_Basico.ButPasteClick(Sender: TObject); begin
104
Borland
ImageFOT_CAPA.PasteFromClipboard; end; { Ou se voc utilizou o objeto OpenDialog procedure TF_Basico.ButPasteClick(Sender: TObject); begin If AbreBmp.Execute then ImageFot_Amostra.Picture.LoadFromFile( AbreBmp.FileName ); end; } procedure TF_Basico.ButMusicaClick(Sender: TObject); begin if DM_Basico.DSBasico.State in [dsEdit, dsInsert] then begin MessageDlg('Salve a edio do CD antes de Editar as msicas!',mtInformation, [mbOk], 0); Exit; end; F_Menu.Prepara(True); with TF_Musica.Create(Self) do begin Inicio; Free; end; F_Menu.Prepara(False); end; end.
Comandos e suas funes, por ordem de apario: with [registro ou objeto] do [comandos] - Cria um mtodo de referncia para o registro ou objeto. [tabela].FindNearest - realiza uma pesquisa aproximada na tabela.
105
Captulo VII
Trabalhando com consultas
Todo um projeto pode ir por ralo abaixo caso o usurio no consiga uma maneira eficaz e eficiente para localizar seus registros perdidos, as consultas as tabelas devem auxiliar o usurio na tarefa de lembr-lo qual o cdigo correto para determinada categoria, e as consultas aos CDs devem ser rpidas e prticas, seno, ficaria muito mais prtico e fcil pesquisar manualmente cada CD tentando encontrar determinada msica do que acessar o computador para realizar tal tarefa.
Crie para esta nova janela uma relao com o DataModule DM_Modelo colocando-o na clusula Uses, abaixo da diretiva de compilao:
106
Borland
Crie para esta nova janela os seguintes objetos: DBNavigator (encontrado na pgina Data Controls), altere as seguintes propriedades:
Valor DM_Modelo.DSCategor Um em cada linha: Primeiro, Anterior, Prximo e ltimo 8 True [nbFirst, nbPrior, nbNext, nbLast] 8 113
Descrio DataSource vinculado (caso esta opo no esteja disponvel abra o DataModule DM_Modelo) Tpicos para ajuda on-line do objeto especfico Posio a esquerda Mostrar o contedo da propriedade hint sob a forma de uma caixa de ajuda on-line Botes visveis Distncia do topo Largura do objeto
Tipo de letra a ser mostrada no ttulo do dbGrid Distncia do topo Largura do objeto
107
Borland
Caption Font Height Hint Left Name ShowHint Spacing Top Width
&OK MS Sans Serif, normal, 8, preto 25 Confirma a pesquisa 16 ButOk True 30 248 89
Caption Font, Height, ShowHint, Top e Width Hint Left Name Spacing Width
108
Borland
Programando no formulrio
O cdigo para este objeto no chega a ser um troo estranho, medonho e esquisito, na verdade at bem simples, basta apenas compreendermos o seu funcionamento, o objeto DBGrid far todo o trabalho, mostrando ao usurio os registros cadastrados em uma tabela, a parte que nos resta e programar o objeto butPesquisa de maneira quase idntica ao nosso antigo boto de pesquisa: Cdigo para o boto butPesquisa, responsvel pela ativao da pesquisa: 1. D um duplo clique no objeto:
procedure TF_SelCate.ButPesquisaClick(Sender: TObject); Inicia o procedimento begin if (EdtTrecho.Text = '') then Verifica se foi digitado algo begin MessageDlg('No foi especificado uma sigla!', mtError, [mbOK], 0); Exit; Abandona o procedimento end; try Ativa o comando Try DM_Modelo.TabCategor.FindNearest([EdtTrecho.Text]); Faz a pesquisa na tabela except Caso acontea alguma falha on exception do MessageDlg('Sigla especificada est invlida!',mtError, [mbOK], 0); end; end; Termina o procedimento
+ O comando Try foi utilizado para prevermos qualquer possibilidade de erro durante a
execuo da pesquisa.
109
Borland
private Parte de procedimentos privados Funo para enviar a varivel function GetTrecho: String; procedure SetTrecho(NewTrecho: String); Procedimento para receber o trecho Parte de procedimentos pblicos public Cria uma varivel pblica vCria: Boolean; property CampTrecho: String read GetTrecho write SetTrecho; Inicializa um varivel end;
O comando Property declara uma varivel da seguinte maneira, a sub-opo Read envia um string atravs da funo GetTrecho, e a sub-opo Write recebe o valor enviado atravs da varivel para o procedimento SetTrecho. 2. Declarando o procedimento e a funo:
function TF_SelCate.GetTrecho: String; Incio da funo begin if vCria then Verifica se o DataModule no existia begin Result := DM_Modelo.TabCategorSIG_CATEG.Value; Atribui ao resultado da funo o valor do campo SIG_CATEG DM_Modelo.Free; end; end; procedure TF_SelCate.SetTrecho(NewTrecho: String); begin if vCria then begin DM_Modelo := TDM_Modelo.Create(Application); DM_Modelo.TabCategor.FindKey([NewTrecho]); end; end; Incio do procedimento Se o DataModule no estiver criado Cria o DataModule Localiza o valor da string enviada
110
Borland
Chame o formulrio F_Categ atravs do objeto Project Manager, clique no objeto butLocalizar: 1. D um duplo clique no objeto:
procedure TF_Categ.ButLocalizarClick(Sender: TObject); Aqui permanece o mesmo var MarcaReg: TBookmark; Cria uma varivel de marca begin if F_Menu.CriticaEdicao(DM_Modelo.DSCategor, 'Categoria', 'localizar' ) then Exit; with DM_Modelo.TabCateg do begin MarcaReg := GetBookMark; F_SelCate := TF_SelCate.Create(Application); F_SelCate.vCria := False; if not F_SelCate.ShowModal = mrOk then GotoBookMark(MarcaReg); F_SelCate.Free; FreeBookmark(MarcaReg); end; end;
Salva a posio do registro Cria o formulrio de consulta Seta a varivel pblica Caso a sada do formulrio no seja o boto OK Retorna ao registro marcado Elimina o formulrio de consulta Libera a varivel de marca
Os comandos de BookMark so todos aplicados a tabela por isso foi utilizado em conjunto com um comando with para a simplificao do cdigo.
+ +
{ Menu Principal do Sistema } { Referencia ao DataModule } { Utilizado para o controle da funo MessageDlg } { Seleciona Categoria }
procedure TF_Basico.ButLocCategClick(Sender: TObject); begin if not (DM_Basico.DSBasico.State in [dsEdit, dsInsert]) then begin MessageDlg('Voc no est no modo de edio!', mtInformation, [mbOK], 0); Exit;
111
Borland
end;
F_SelCate := TF_SelCate.Create(Application); F_SelCate.vCria := True; F_SelCate.CampTrecho := EditSIG_CATEG.Text; if F_SelCate.ShowModal = mrOk then EditSIG_CATEG.Text := F_SelCate.CampTrecho; F_SelCate.Free; end;
Cria o formulrio de consulta Seta a varivel pblica Atribui a vriavel declarado o valor do
campo da tela (dispara a funo SetTrecho)
Note que para esse caso no queremos localizar uma categoria, mas sim atribuir ao objeto EditCOD_CATEG ao valor do F_SelCate.CampTrecho localizado No esquea que o objeto F_SelCate faz parte da Unit fSelCate ento necessrio fazer o uso desta Unit, para tanto altere o seguinte cdigo (abaixo da diretiva de compilao):
{$R *.DFM} uses DMBasico, fMenu, Dialogs, fCateg, fMusica, fSelCate;
+ +
{ Referncia ao DataModule } { Menu Principal do Sistema } { Gerente de Mensagens } { Cadastro de Categorias } { Cadastro de Msicas } { Seleciona Categoria }
Salve o formulrio, retire-o da rea de formulrios auto-create, execute e teste o projeto. Se alguma coisa deu errada, releia o captulo, ou ento confira o cdigo para a F_SelCate:
unit fSelCate; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, DBCtrls, Buttons, StdCtrls, Grids, DBGrids; type TF_SelCate = class(TForm) DBNavigator1: TDBNavigator; DBGrid1: TDBGrid; EdtTrecho: TMaskEdit; Label1: TLabel; ButOK: TBitBtn; ButCancela: TBitBtn; ButPesquisa: TSpeedButton; procedure ButPesquisaClick(Sender: TObject); private VeCria : boolean; function GetTrecho: String; procedure SetTrecho(NewTrecho: String); public property CampTrecho: String read GetTrecho write SetTrecho;
112
Borland
end;
var F_SelCate: TF_SelCate; implementation {$R *.DFM} uses DMCateg; { Referncia ao DataModule } function TF_SelCate.GetTrecho: String; begin if vCria then begin Result := DM_Modelo.TabCategorSIG_CATEG.Value; DM_Modelo.Free; end; end; procedure TF_SelCate.SetTrecho(NewTrecho: String); begin if vCria then begin DM_Modelo := TDM_Modelo.Create(Application); DM_Modelo.TabCategor.FindKey([NewTrecho]); end; end; procedure TF_SelCate.ButPesquisaClick(Sender: TObject); begin if (EdtTrecho.Text = '') then begin MessageDlg('No foi especificado uma sigla!', mtError, [mbOK], 0); Exit; end; try DM_Modelo.TabCategor.FindNearest([EdtTrecho.Text]); except on exception do MessageDlg('Sigla especificada est invlida!',mtError, [mbOK], 0); end; end; end.
Comandos e suas funes, por ordem de apario: Property [varivel]: [Tipo] read [funo] write [procedimento] - Declara as propriedades para uma varivel do tipo leitura (read) e do tipo escrita (write). Result - constante utilizada para o retorno de uma funo. Try [declaraes] - palavra reservada para marcar a primeira parte de um bloco de exceo. Except [bloco de exceo] - caso alguma declarao dentro de um bloco de proteo try acontea erro este bloco executado.
113
Borland
On [tipo de exceo] do [declarao] - em conjunto com o bloco try...except define o cdigo para executar um bloco de exceo.
Consultas SQL
O objeto Query , utilizado anteriormente para trabalhar como um contador, mais poderoso do que se imagina, utilizando-o bem nos podemos dar poderes ao nosso usurio que ele jamais imaginou que fosse possvel, e voc ver que trabalhar com filtros pode-se transformar em uma agradvel surpresa.
Vamos criar um formulrio idntico a este que servir para a montagem dos filtros: (New Form) na Speed Bar, ou no menu principal a Inicialmente Clique no boto Clique no menu principal a opo File e New..., em New Items, na pgina New e clique no objeto entitulado Form e altere as seguintes propriedades:
Valor bsDialog Define Filtros Descrio Estilo da borda do objeto Label do objeto
114
Borland
Name Position
F_Filtro poScreenCenter
ComboBox (encontrado na pgina Standard) - que armazenar o nome dos campos do arquivo, altere as seguintes propriedades:
Propriedade Name Font Items Style Text Valor CBCampo MS Sans Serif, Normal, 8, Azul Marinho Nome; Tipo e Categoria (um em cada linha) csDropDown Descrio Nome do objeto Tipo de letra a ser mostrada no objeto Contedo do objeto Estilo do objeto Texto a ser mostrado para o Combo quando nada for selecionado
ComboBox (encontrado na pgina Standard) - que armazenar os critrios de pesquisa, altere as seguintes propriedades:
Propriedade Name Font Items Style Text Valor CBCriterio MS Sans Serif, Normal, 8, Azul Marinho =; >; <; >=; <=; <> e Dentro de csDropDown Descrio Nome do objeto Tipo de letra a ser mostrada no objeto Contedo do objeto (coloque um em cada linha) Estilo do objeto Texto a ser mostrado para o Combo quando nada for selecionado
Edit (encontrado na pgina Standard) - que armazenar o contedo a ser comparado, altere as seguintes propriedades:
Propriedade Name Font Text Valor EditCompara MS Sans Serif, Normal, 8, Azul Marinho Descrio Nome do objeto Tipo de letra a ser mostrada no objeto Texto a ser mostrado para o campo
SpeedButton (encontrado na pgina Additional) - boto que confirmar a condio para o filtro escolhida, altere as seguintes propriedades:
115
Borland
Propriedade Glyph Hint ShowHint Name
Valor
Descrio
[DiretrioDelphi]\IMAGES\BUTT Imagem a ser mostrada no objeto ONS\COPY.BMP Confirma os dados digitados True ButEnvia Ajuda on-line para o objeto especfico Mostrar o contedo da propriedade hint sob a forma de uma caixa de ajuda on-line Nome do objeto
SpeedButton (encontrado na pgina Additional) - este boto servir para chamar a tela de consulta a tabela, ficando originalmente invisvel, sendo ativado caso o campo escolhido seja a sigla da categoria, altere as seguintes propriedades:
Propriedade Glyph Hint ShowHint Name Visible Valor Descrio [DiretrioDelphi]\IMAGES\BUTT Imagem a ser mostrada no objeto (consulte o cap.6, ONS\LANTERNA.BMP criao do objeto ButLocCateg sobre a imagem) Pesquisa Categoria True ButConsulta False Ajuda on-line para o objeto especfico Mostrar o contedo da propriedade hint sob a forma de uma caixa de ajuda on-line Nome do objeto Objeto deve ser mostrado
2 Parte - servir para guardar o filtro montado e esconder o filtro em linguagem pura SQL, ajuste seu tamanho para caber os outros objetos
GroupBox (encontrado na pgina Standard) - servir para guardar os blocos montados do filtro, ajuste seu tamanho para caber os outros objetos, altere as seguintes propriedades:
Propriedade Caption Font Valor Filtro Completo MS Sans Serif, Negrito, 8, Castanho Descrio Label do objeto Tipo de letra a ser mostrada no objeto
Edit (encontrado na pgina Standard) - que mostrar ao usurio o filtro por ele criado, ele ocupar toda a rea interna do objeto GroupBox, altere as seguintes propriedades:
Propriedade BorderStyle Color Ctl3D Font Name ReadOnly Valor bsNone clBtnFalse (mesma cor do objeto GroupBox) False MS Sans Serif, Normal, 8, Castanho FiltroVe True Descrio Estilo da borda Cor do objeto Possui desenho em 3D Tipo de letra a ser mostrada no objeto Nome do objeto Objeto apenas para leitura, no permitida alterao do seu contedo.
Edit (encontrado na pgina Standard)- que montar o nosso filtro em linguagem pura SQL, ele ficar invisvel em modo de execuo, altere as seguintes propriedades:
Propriedade Name Visible Valor FiltroSQL False Descrio Nome do objeto Se o objeto ficar visvel
116
Borland
[DiretrioDelphi]\IMAGES\BUTT Imagem a ser mostrada no objeto ONS\FOLDRDOC.BMP MS Sans Serif, Normal, 8, Preto Um e Outro True &E False Tipo de letra a ser mostrada no objeto Ajuda on-line para o objeto especfico Mostrar o contedo da propriedade hint sob a forma de uma caixa de ajuda on-line Label do Objeto Habilitao para o uso
BitBtn (encontrado na pgina Additional)- boto que servir de Ou - Tipo: Um ou Outro, ficar inicialmente desabilitado em modo de execuo, altere as seguintes propriedades:
Propriedade Name Glyph Font Hint ShowHint Caption Enabled Valor ButOu Descrio Nome do objeto
[DiretrioDelphi]\IMAGES\BUTT Imagem a ser mostrada no objeto ONS\FONTBOLD.BMP MS Sans Serif, Normal, 8, Preto Um ou Outro True O&u False Tipo de letra a ser mostrada no objeto Ajuda on-line para o objeto especfico Mostrar o contedo da propriedade hint sob a forma de uma caixa de ajuda on-line Label do Objeto Habilitao para o uso
BitBtn (encontrado na pgina Additional) - boto que servir para limpar o filtro, ficar inicialmente desabilitado em modo de execuo, altere as seguintes propriedades:
Propriedade Name Glyph Font Hint ShowHint Caption Enabled Valor ButLimpar Descrio Nome do objeto
[DiretrioDelphi]\IMAGES\BUTT Imagem a ser mostrada no objeto ONS\CLEAR.BMP MS Sans Serif, Normal, 8, Preto Apaga o filtro existente True &Limpar False Tipo de letra a ser mostrada no objeto Ajuda on-line para o objeto especfico Mostrar o contedo da propriedade hint sob a forma de uma caixa de ajuda on-line Label do Objeto Habilitao para o uso
BitBtn (encontrado na pgina Additional) - boto que servir para confirmar o filtro, ele ficar inicialmente desabilitado em modo de execuo, altere as seguintes propriedades:
Propriedade Valor Descrio
117
Borland
Kind
bkOK
Determina a classe a ser utilizada pelo objeto, automaticamente sero alteradas as propriedades: Caption, Glyph e ModalResult Nome do objeto Tipo de letra a ser mostrada no objeto Ajuda on-line para o objeto especfico Mostrar o contedo da propriedade hint sob a forma de uma caixa de ajuda on-line Label do Objeto Habilitao para o uso
ButOK MS Sans Serif, Normal, 8, Preto Confirma o filtro editado True &OK False
BitBtn (encontrado na pgina Additional) - boto que servir para abandonar o filtro, altere as seguintes propriedades:
Propriedade Kind Valor bkCANCEL Descrio Determina a classe a ser utilizada pelo objeto, automaticamente sero alteradas as propriedades: Caption, Glyph e ModalResult Nome do objeto Tipo de letra a ser mostrada no objeto Ajuda on-line para o objeto especfico Mostrar o contedo da propriedade hint sob a forma de uma caixa de ajuda on-line Label do Objeto
ButCancela MS Sans Serif, Normal, 8, Preto Cancela o filtro editado True &Cancelar
Programando o formulrio
Antes de prosseguirmos salve o formulrio com o nome de fFiltro. O cdigo para este objeto simples requer apenas que voc compreenda que o formulrio deve fazer. Este formulrio servir de base para a montagem de um filtro que ser mostrado por um dbGrid construdo no segundo formulrio, devemos devolver o cdigo que completar a execuo de um objeto Query colocado no segundo. Ex.: SELECT * FROM BASICO WHERE [condio criada no formulrio] : Cdigo para o boto butEnvia, quando for confirmado os dados digitados: 1. D um duplo clique no objeto:
procedure TF_Filtro.ButEnviaClick(Sender: TObject); var NomeCampo : String; begin case cbCampo.ItemIndex of 0 { Nome } : NomeCampo:= 'NOM_DISCO'; 1 { Tipo } : NomeCampo:= 'TIP_DISCO'; 2 { Categoria } : NomeCampo:= 'SIG_CATEG'; end; if (cbCriterio.ItemIndex = 6) then FiltroSQL.Text := FiltroSQL.Text + '(' + NomeCampo + ' ' + 'Like ''%' + EditCompara.Text + '%'')'
118
Borland
else FiltroSQL.Text := FiltroSQL.Text + '(' + NomeCampo + ' ' + cbCriterio.Text + '''' + EditCompara.Text + ''')'; FiltroVe.Text := FiltroVe.Text + cbCampo.Text + ' ' + cbCriterio.Text + ' ' + EditCompara.Text; cbCampo.ItemIndex := -1; cbCriterio.ItemIndex := -1; EditCompara.Text := ''; cbCampo.Enabled := False; cbCriterio.Enabled := False; EditCompara.Enabled := False; ButConsulta.Visible := False; ButE.Enabled := True; ButOu.Enabled := True; ButOk.Enabled := True; ButLimpa.Enabled := True; end;
Habilita os botes
caso o sistema que voc desenvolver tenha campos do tipo Data altere a linha do critrio para o seguinte: if (cbCriterio.ItemIndex = 6) then Critrio "Dentro de" V os campos Data if cbCampo.ItemIndex in [nmero do campos data] then Condio para este tipo de cmp FiltroSQL.Text := FiltroSQL.Text + '(' + NomeCampo + ' ' +
'Like ''%' + FormatDateTime('MM/DD/YY',StrToDate(EditCompara.Text)) + '%'')' else FiltroSQL.Text := FiltroSQL.Text + '(' + NomeCampo + ' ' + Condio comum para o LIKE 'Like ''%' + EditCompara.Text + '%'')' else As outras condies V os campos Data if cbCampo.ItemIndex = in [nmero do campos data] then FiltroSQL.Text := FiltroSQL.Text + '(' + NomeCampo + ' ' + cbCriterio.Text + '''' + FormatDateTime('MM/DD/YY',StrToDate(EditCompara.Text)) + ''')' else Condies para outros campos FiltroSQL.Text := FiltroSQL.Text + '(' + NomeCampo + ' ' + cbCriterio.Text + '''' + EditCompara.Text + ''')';
...o resto ficar idntico. No esquea no comando USES colocar a biblioteca SysUtils para a funo FormatDateTime Cdigo para o boto butE, quando ser escolhida e uma outra condio: 1. D um duplo clique no objeto:
procedure TF_Filtro.ButEClick(Sender: TObject); begin FiltroVe.Text := FiltroVe.Text + ' E '; FiltroSQL.Text := FiltroSQL.Text + ' And '; cbCampo.Enabled := True; cbCriterio.Enabled := True;
119
Borland
EditCompara.Enabled := True; ButLimpa.Enabled := True; ButE.Enabled := False; ButOu.Enabled := False; ButOk.Enabled := False; end;
Desabilita os botes
Cdigo para o boto butOu, quando ser escolhida ou uma outra condio: 1. D um duplo clique no objeto:
procedure TF_Filtro.ButOuClick(Sender: TObject); begin FiltroVe.Text := FiltroVe.Text + ' Ou '; FiltroSQL.Text := FiltroSQL.Text + ' Or '; cbCampo.Enabled := True; cbCriterio.Enabled := True; EditCompara.Enabled := True; ButLimpa.Enabled := True; ButE.Enabled := False; ButOu.Enabled := False; ButOk.Enabled := False; end;
Desabilita os botes
Cdigo para o boto butLimpa, quando for limpo os filtros: 1. D um duplo clique no objeto:
procedure TF_Filtro.ButLimpaClick(Sender: TObject); begin cbCampo.ItemIndex := -1; cbCriterio.ItemIndex := -1; EditCompara.Text := ''; FiltroVe.Text := ''; FiltroSQL.Text := 'Select * from Basico where '; cbCampo.Enabled := True; cbCriterio.Enabled := True; EditCompara.Enabled := True; ButE.Enabled := False; ButOu.Enabled := False; ButOk.Enabled := False; ButLimpa.Enabled := False; end;
Desabilita os botes
Quando o formulrio for criado iniciado o filtro: 1. Selecione o objeto F_Filtro na tela de eventos d um duplo click sobre a opo OnCreate:
procedure TF_Filtro.FormCreate(Sender: TObject); begin FiltroVe.Text := ''; FiltroSQL.Text := 'Select * from BASICO where '; end;
120
Borland
Caso o campo escolhido seja Sigla da Categoria necessrio habilitar o boto de consulta: 1. Selecione o objeto CBCampo na tela de eventos d um duplo clique na opo OnChange:
procedure TF_Filtro.CBCampoChange(Sender: TObject); begin CBCriterio.SetFocus; if cbCampo.ItemIndex = 2 then ButConsulta.Visible := True else ButConsulta.Visible := False; end;
Desvia o foco para o prximo campo Se o campo seleciona for SIG_CATEG Torna visvel o objeto ButConsulta
Seno Torna invisvel o objeto ButConsulta
Cdigo para o objeto ButConsulta que far a consulta de categoria: 1. D um duplo clique no objeto:
procedure TF_Filtro.ButConsultaClick(Sender: TObject); begin if cbCampo.ItemIndex = 2 then Se o campo for SIG_CATEG begin F_SelCate.CampTrecho := EditCompara.Text; Envia o campo if F_SelCate.Inicio = mrOk then Verifica se foi retornado OK EditCompara.Text := F_SelCate.CampTrecho; Transfere o campo end; end;
Perfumaria para o objeto CBCriterio quando selecionado um critrio ser o controle transferido para o campo seguinte: 1. Selecione o objeto na tela de eventos e d um duplo clique na opo OnChange:
procedure TF_Filtro.CBCriterioChange(Sender: TObject); begin EditCompara.SetFocus; Desvia o foco para o prximo campo end;
Necessitamos agora criar uma varivel comum que devolver o cdigo SQL para a tela secundria: Transfira para a janela do Code Editor: 1. Aps o comando PRIVATE digite: Inicia uma funo Particular Inicia uma varivel pblica s de leitura
private function GetSQL: TEdit; public property SQLString : TEdit read GetSQL; end; var F_Filtro: TF_Filtro; implementation {$R *.DFM} uses fSelCate;
121
Borland
Salve o formulrio, teste o projeto. Se alguma coisa deu errada, releia o captulo, ou ento confira o cdigo para a F_Filtro:
unit Ffiltro; interface uses WinTypes, WinProcs, Classes, Graphics, Forms, Controls, Buttons, StdCtrls, ExtCtrls; type TF_Filtro = class(TForm) Panel1: TPanel; CBCampo: TComboBox; CBCriterio: TComboBox; EditCompara: TEdit; ButEnvia: TSpeedButton; GroupBox1: TGroupBox; Label1: TLabel; Label2: TLabel; Label3: TLabel; ButCancela: TBitBtn; ButE: TBitBtn; ButOu: TBitBtn; Label4: TLabel; FiltroVe: TEdit; FiltroSQL: TEdit; ButOk: TBitBtn; ButLimpa: TBitBtn; ButConsulta: TSpeedButton; procedure ButEnviaClick(Sender: TObject); procedure ButEClick(Sender: TObject); procedure ButOuClick(Sender: TObject); procedure ButLimpaClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure CBCampoChange(Sender: TObject); procedure ButConsultaClick(Sender: TObject); procedure CBCriterioChange(Sender: TObject); private function GetSQL: TEdit; public property SQLString : TEdit read GetSQL; end; var F_Filtro: TF_Filtro; implementation
122
Borland
{$R *.DFM} uses fSelCate;
function TF_Filtro.GetSQL: TEdit; begin Result := FiltroSQL; end; procedure TF_Filtro.ButEnviaClick(Sender: TObject); var NomeCampo : String; begin case cbCampo.ItemIndex of 0 { Nome } : NomeCampo:= 'NOM_DISCO'; 1 { Tipo } : NomeCampo:= 'TIP_DISCO'; 2 { Categoria } : NomeCampo:= 'SIG_CATEG'; end; if (cbCriterio.ItemIndex = 6) then FiltroSQL.Text := FiltroSQL.Text + '(' + NomeCampo + ' ' + 'Like ''%' + EditCompara.Text + '%'')' else FiltroSQL.Text := FiltroSQL.Text + '(' + NomeCampo + ' ' + cbCriterio.Text + '''' + EditCompara.Text + ''')'; FiltroVe.Text := FiltroVe.Text + cbCampo.Text + ' ' + cbCriterio.Text + ' ' + EditCompara.Text; cbCampo.ItemIndex := -1; cbCriterio.ItemIndex := -1; EditCompara.Text := ''; cbCampo.Enabled := False; cbCriterio.Enabled := False; EditCompara.Enabled := False; ButConsulta.Visible := False; ButE.Enabled := True; ButOu.Enabled := True; ButOk.Enabled := True; ButLimpa.Enabled := True; end; procedure TF_Filtro.ButEClick(Sender: TObject); begin FiltroVe.Text := FiltroVe.Text + ' E '; FiltroSQL.Text := FiltroSQL.Text + ' And '; cbCampo.Enabled := True; cbCriterio.Enabled := True; EditCompara.Enabled := True; ButLimpa.Enabled := True; ButE.Enabled := False;
123
Borland
ButOu.Enabled := False; ButOk.Enabled := False; end; procedure TF_Filtro.ButOuClick(Sender: TObject); begin FiltroVe.Text := FiltroVe.Text + ' Ou '; FiltroSQL.Text := FiltroSQL.Text + ' Or '; cbCampo.Enabled := True; cbCriterio.Enabled := True; EditCompara.Enabled := True; ButLimpa.Enabled := True; ButE.Enabled := False; ButOu.Enabled := False; ButOk.Enabled := False; end; procedure TF_Filtro.ButLimpaClick(Sender: TObject); begin cbCampo.ItemIndex := -1; cbCriterio.ItemIndex := -1; EditCompara.Text := ''; FiltroVe.Text := ''; FiltroSQL.Text := 'Select * from BASICO where '; cbCampo.Enabled := True; cbCriterio.Enabled := True; EditCompara.Enabled := True; ButE.Enabled := False; ButOu.Enabled := False; ButOk.Enabled := False; ButLimpa.Enabled := False; end; procedure TF_Filtro.FormCreate(Sender: TObject); begin FiltroVe.Text := ''; FiltroSQL.Text := 'Select * from Basico where '; end; procedure TF_Filtro.CBCampoChange(Sender: TObject); begin CBCriterio.SetFocus; if cbCampo.ItemIndex = 2 then ButConsulta.Visible := True else ButConsulta.Visible := False; end; procedure TF_Filtro.ButConsultaClick(Sender: TObject); begin if cbCampo.ItemIndex = 2 then begin
124
Borland
F_SelCate.CampTrecho := EditCompara.Text; if F_SelCate.Inicio = mrOk then EditCompara.Text := F_SelCate.CampTrecho; end; end; procedure TF_Filtro.CBCriterioChange(Sender: TObject); begin EditCompara.SetFocus; end; end.
Vamos criar um formulrio idntico a este que servir para o gerenciamento do filtro: Inicialmente Clique no boto (New Form) na Speed Bar, ou no menu principal a Clique no menu principal a opo File e New..., em New Items, na pgina New e clique no objeto entitulado Form e altere as seguintes propriedades:
Valor bsDialog Consulta aos Discos F_ConDisc Descrio Estilo da borda do objeto Label do objeto Nome do objeto
125
Borland
Position
poScreenCenter
Posio do objeto
Crie para esta nova janela os seguintes objetos: Table (encontrado na pgina Data Access) - Tabela que se alternar com a query, altere as seguintes propriedades:
Descrio Nome do Alias ou a localizao do diretrio das tabelas Nome externo da tabela Nome do objeto Nome do campo indexado
IndexFieldNames NOM_DISCO
DataSource (encontrado na pgina Data Access) - Posicione-o ao lado do objeto TabBasico. , altere as seguintes propriedades:
Propriedade DataSet Name Valor TabBasico DSBasico Descrio Nome da tabela vinculada Nome do objeto
Query (encontrado na pgina Data Access) - Query que se alternar com a tabela, altere as seguintes propriedades:
Propriedade DatabaseName SQL Name Valor AliasDisco SELECT * FROM BASICO QryBasico Descrio Nome do Alias ou a localizao do diretrio das tabelas Comando SQL para consulta Nome do objeto
DBNavigator (encontrado na pgina Data Controls) - Barra de navegao que servir para andar sobre os registro, lembre-se no deve ser permitida manuteno nos mesmos:
Propriedade DataSource VisibleButtons Hints ShowHint Valor DSBasico [nbFirst, nbPrior, nbNext, nbLast] Primeiro; Anterior; Prximo; ltimo True Descrio DataSource associado Botes visveis Ajuda on-line que ser mostrado sobre cada boto (coloque um em cada linha) Mostrar o contedo da propriedade hint sob a forma de uma caixa de ajuda on-line
SpeedButton (encontrado na pgina Additional) - boto que servir para ativar ou desativar o filtro, altere as seguintes propriedades:
Propriedade Name Glyph Hint ShowHint GroupIndex Valor ButAtivaDesativa Descrio Nome do objeto
[DiretrioDelphi]\IMAGES\BUTT Imagem a ser mostrada no objeto ONS\LOCKOPEN.BMP Ativa/Desativa o filtro True 1 Ajuda on-line para o objeto especfico Mostrar o contedo da propriedade hint sob a forma de uma caixa de ajuda on-line Pertence a um grupo de botes, esta propriedade faz com que o boto permanea em estado de pressionamento.
126
Borland
AllowAllUp
True
BitBtn (encontrado na pgina Additional) - boto que servir para montagem do filtro, altere as seguintes propriedades:
Propriedade Caption Font Glyph Hint Name ShowHint Valor Fil&trar MS Sans Serif, Normal, 8, Preto Descrio Label do objeto Tipo de letra a ser mostrada no objeto
[DiretrioDelphi]\IMAGES\BUTT Imagem a ser mostrada no objeto ONS\FIND.BMP Montagem do Filtro ButFiltrar True Ajuda on-line para o objeto especfico Nome do objeto Mostrar o contedo da propriedade hint sob a forma de uma caixa de ajuda on-line
BitBtn (encontrado na pgina Additional) - boto que servir para editar o campo selecionado no grid, altere as seguintes propriedades:
Propriedade Caption Font Glyph Hint Name ShowHint Valor &Editar MS Sans Serif, Normal, 8, Preto Descrio Label do objeto Tipo de letra a ser mostrada no objeto
[DiretrioDelphi]\IMAGES\BUTT Imagem a ser mostrada no objeto ONS\FOLDRDOC.BMP Edita campo selecionado ButEditar True Ajuda on-line para o objeto especfico Nome do objeto Mostrar o contedo da propriedade hint sob a forma de uma caixa de ajuda on-line
BitBtn (encontrado na pgina Additional) - boto que servir para editar o filtro, altere as seguintes propriedades:
Propriedade Kind Valor bkClose Descrio Determina a classe a ser utilizada pelo objeto, automaticamente sero alteradas as propriedades: Caption, Glyph e ModalResult Nome do objeto Tipo de letra a ser mostrada no objeto Label do Objeto
dbGrid (encontrado na pgina Data Controls) - Objeto Grid que mostrar os campos, altere as seguintes propriedades:
Propriedade DataSource Valor DSDocum Descrio Determina a classe a ser utilizada pelo objeto, automaticamente sero alteradas as propriedades: Caption, Glyph e ModalResult Nome do objeto Tipo de letra a ser mostrada para os campos Opes do Grid Tipo de letra a ser mostrada para o ttulo dos campos
dbGridBasico MS Sans Serif, Normal, 8, Azul Marinho dgTitles, dgIndicator, dgColLines, dgRowLines, dgRowSelect MS Sans Serif, Negrito, 8, Castanho
127
Borland
Programando o formulrio
Antes de prosseguirmos salve o formulrio com o nome de fConDisc. Este formulrio mostrar os dados filtrados no objeto dbGrid, para filtrar os dados utilizaremos o objeto Query, tudo o que temos a fazer controlar quando o filtro est ativo (objeto DataSource aponta para o objeto Query) ou quando o filtro no est ativo (objeto DataSource aponta para o objeto tTable) Cdigo para quando o formulrio iniciado, abertura das tabelas: 1. Vire para o CodeEditor e insira o seguinte cdigo abaixo:
private { Private declarations } public procedure Inicio; end; var F_ConDisc: TF_ConDisc; implementation {$R *.DFM} uses fFiltro, fEdtDisc; procedure TF_ConDisc.Inicio; begin TabBasico.Open; ShowModal; end;
Utiliza a Unit para a montagem do filtro Utiliza a Unit para a edio do registro
Cdigo para o boto Filtrar, quando for solicitada a edio do filtro. 1. D um duplo clique no objeto butFiltrar:
procedure TF_ConDisc.ButFiltrarClick(Sender: TObject); begin Verifica se o boto de prender o filtro if ButAtivaDesativa.Down then begin est pressionado. MessageDlg('Desative a filtragem antes de editar os filtros...', mtInformation, [mbOK], 0); exit; end; if F_Filtro.ShowModal = mrOk then begin QryBasico.SQL.Clear; QryBasico.SQL.Add(F_Filtro.SQLString.Text); end; end;
Chama o filtro e se for retornado OK Limpa a Query Adiciona o novo filtro na Query
Cdigo para o boto Editar, quando for marcado um registro para visualizao geral.
128
Borland
Verifica se existe filtro preso Chama a edio atravs da Query Chama a edio atravs da tTable
Cdigo para o boto Ativa ou Desativa o filtro, para prender ou liberar o filtro. 1. D um duplo clique no objeto butAtivaDesativa:
procedure TF_ConDisc.ButAtivaDesativaClick(Sender: TObject); begin if not ButAtivaDesativa.Down then Se o filtro no estiver ativo Coloca o DataSource apontado para o tTable DSBasico.Dataset := TabBasico else try Clusula para um bloco de exceo Desativa a Query QryBasico.Close; QryBasico.Open; Ativa a Query Coloca o DataSource apontado para a Query DSBasico.Dataset := QryBasico; Caso de alguma coisa errada com o filtro except DSBasico.Dataset := TabBasico; Coloca o DataSource apontado para o tTable Complemento do comando Try...except...raise raise; end; end;
Salve o formulrio. Com certeza ser mostrado um erro para a chamada da unit F_EdtDisc.
Editando os registros
O formulrio que editar os registro no ser montado passo a passo, pois muito simples de ser construdo, ao invs disto darei apenas algumas dicas a respeito da criao do mesmo: 1. Copie o formulrio F_Basico, renomeando-o para F_EdtDisc; 2. Remova os objetos dbNavigator, Query e as tabelas tabCategConf e tabBasicoConf, das tabelas restante, entre no FieldsEditor de cada uma e remova os campos; 3. Retire todo o cdigo e proteja as tabelas com a opo ReadOnly = True; 4. Retire todos os botes, deixando apenas o boto para Fechar o formulrio; 5. Insira os seguintes procedimentos:
a. Procedure INICIO, nas declaraes public ( procedure Inicio(var CodDisco: Integer); ) procedure TF_EdtDisc.Inicio(var CodDisco: Integer); begin Abre as tabelas TabBasico.Open; TabMusica.Open; TabCateg.Open; Posiciona a tabela Basico no CodDisco enviado TabBasico.FindKey(CodDisco);
129
Borland
ShowModal; end;
b. Procedure FormClose, no evento OnClose do objeto F_EdtDisc procedure TF_EdtDisc.FormClose(Sender: TObject; var Action: TCloseAction); begin Fecha as tabelas TabBasico.Close; TabMusica.Close; TabCateg.Close; end;
6. Salve e compile o formulrio com o nome fEdtDisc. Agora sim, voc pode compilar o projeto e rodar o projeto, para uma conferncia final a vai o cdigo completo do formulrio F_ConDisc.
unit Fcondisc; interface uses WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, DB, DBTables, Grids, DBGrids, StdCtrls, Buttons, ExtCtrls, DBCtrls; type TF_ConDisc = class(TForm) DBGrid1: TDBGrid; DSBasico: TDataSource; ButFiltrar: TBitBtn; ButFechar: TBitBtn; QryBasico: TQuery; DBNavigator1: TDBNavigator; TabBasico: TTable; ButEditar: TBitBtn; ButAtivaDesativa: TSpeedButton; TabBasicoCOD_DISCO: TSmallintField; TabBasicoNOM_DISCO: TStringField; TabBasicoTIP_DISCO: TStringField; TabBasicoCOD_CATEG: TStringField; QryBasicoCOD_DISCO: TSmallintField; QryBasicoNOM_DISCO: TStringField; QryBasicoTIP_DISCO: TStringField; QryBasicoCOD_CATEG: TStringField; procedure ButFiltrarClick(Sender: TObject); procedure ButEditarClick(Sender: TObject); procedure ButAtivaDesativaClick(Sender: TObject); private { Private declarations } public procedure Inicio; end; var
130
Borland
F_ConDisc: TF_ConDisc; implementation {$R *.DFM} uses fFiltro, { Chama a montagem do Filtro } fEdtDisc; { Edita o Disco } procedure TF_ConDisc.Inicio; begin TabBasico.Open; ShowModal; end; procedure TF_ConDisc.ButFiltrarClick(Sender: TObject); begin if ButAtivaDesativa.Down then begin MessageDlg('Desative a filtragem antes de editar os filtros...', mtInformation, [mbOK], 0); exit; end; if F_Filtro.ShowModal = mrOk then begin QryBasico.SQL.Clear; QryBasico.SQL.Add(F_Filtro.SQLString.Text); end; end; procedure TF_ConDisc.ButEditarClick(Sender: TObject); begin if ButAtivaDesativa.Down then F_EdtDisc.Inicio(QryBasicoCOD_DISCO.Value) else F_EdtDisc.Inicio(TabBasicoCOD_DISCO.Value); end; procedure TF_ConDisc.ButAtivaDesativaClick(Sender: TObject); begin if not ButAtivaDesativa.Down then DSBasico.Dataset := TabBasico else try QryBasico.Close; QryBasico.Open; DSBasico.Dataset := QryBasico; except DSBasico.Dataset := TabBasico; raise; end; end; end.
131
Borland
Captulo VIII
Relatrios
A parte impressa do Delphi fica a critrio de trs mtodos: utilizar a ferramenta ReportSmith, com a unit Printer ou com a utilizao da ferramenta QuickReport (disponvel no Delphi 1.0 a partir de compra de terceiro, mas disponvel gratuitamente com o Delphi 2.0). O Delphi oferece um gerador de relatrios bastante poderoso, chamado ReportSmith. Com este utilitrio, voc pode criar relatrios associados aos diversos bancos que o Delphi se comunica.
Bases de Dados que o ReportSmith permite acesso Access Btrieve DB2 dBase Excel FoxPro INGRES Informix InterBase ORACLE Paradox Raima AS/400 SQL Server SQLBase Sybase Teradata Arquivo .TXT Unify Watcom SQL qualquer base com driver ODBC
132
Borland
O ReportSmith um produto separado do Delphi, mas ao comprar o Delphi, voc adquiriu automaticamente a licena para usar o ReportSmith bem como a distribuio livre do seu Run-Time.
Tables - Adiciona, remove ou altera tabelas ou cria links entre elas. Selections - Cria, edita e exclui critrios de seleo. Sorting - Adiciona, remove ou reordena dados a serem organizados.
133
Borland
Derived fields - Cria e organiza dados calculados para outras colunas do relatrio, baseado em comandos SQL ou na linguagem de macro ReportBasic. Report variables - Cria, edita ou exclui variveis do relatrio. Estas variveis podem ser criadas para atender a critrios da clusula Selections servindo de comunio entre o ReportSmith e o Delphi. Database grouping - Grupos de dados e critrios de seleo. SQL - Permite a edio de declarao SQL para o relatrio corrente.
1. Pressione o boto Tables. 2. Na caixa de dilogo Tables, pressione o boto Add table... 3. No combo Connections: selecione a conexo DiscoAPP e selecione a tabela Basico.DB e pressione o boto OK, repita a operao para tabela Categor.DB, confirme e retorne a tela anterior. 4. Pressione o boto Add new link... 5. O relacionamento entre Basico e Categor atravs do campo SIG_CATEG, marque a opo Include unmatched records (inclua os registros no correspondentes) do lado de BASICOxDB, confirme e retorne a tela anterior. 6. Selecione a tabela BASICOxDB e pressione o boto Table columns... 7. Selecione o campo FOT_CAPA e marque a opo Exclude from report (retire do relatrio), confirme e retorne a tela anterior. 8. Pressione o boto Report variables e crie as variveis: CodInicial e CodFinal ambas com a opo Type igual a Number e a opo Entry igual a Type-in. 9. Pressione o boto Selections e clique no boto amarelo marcado com 1. e escolha a opo Add selection criteria e marque o seguinte critrio: data field BASICOxDB.COD_DISCO is between report variable CodInicial and report variable CodFinal. 10. Clique no boto Sorting, marque o campo COD_DISCO e clique no boto Insert into sort list (insira para a lista de ordenao). 11. Clique no boto SQL e compare a declarao criada:
SELECT 'BASICOxDB'.'COD_DISCO', 'BASICOxDB'.'NOM_DISCO', 'BASICOxDB'.'TIP_DISCO', 'BASICOxDB'.SIG_CATEG', 'CATEGORxDB'.'SIG_CATEG', 'CATEGORxDB'.'DES_CATEG' FROM 'C:\SISTEMA\CADDISCO\BASICO.DB' BASICOxDB LEFT JOIN 'C:\SISTEMA\CADDISCO\CATEGOR.DB' CATEGORxDB ON ('BASICOxDB'.'SIG_CATEG' = 'CATEGORxDB'.'SIG_CATEG' ) WHERE ((('BASICOxDB'.'COD_DISCO' BETWEEN <<CodInicial>> AND <<CodFinal>>))) ORDER BY 'BASICOxDB'.'COD_DISCO'
12. Confirme o relatrio pressionando o boto Done. Informe os dados iniciais e finais e aguarde a gerao do relatrio.
134
Borland
135
Borland
Criaremos agora uma janela simples de dilogo, onde selecionaremos um cdigo inicial e final para os cdigos do CD. (New Form) na Speed Bar, ou no menu principal a Inicialmente Clique no boto Clique no menu principal a opo File e New..., em New Items, na pgina New e clique no objeto entitulado Form e altere as seguintes propriedades:
Valor bsDialog Imprime Cadastro Geral F_DgGeral poScreenCenter Descrio Estilo da borda do objeto Label do objeto Nome do objeto Posio do objeto
Crie para esta nova janela os seguintes objetos: Label (Localizado na pgina Standard) - crie trs objetos labels:
Valor [1]. Informe o Cdigo dos CDs a imprimir; [2]. Inicial: e [3]. Final: [1]. MS Sans Serif, Negrito, 8, Azul Marinho e [2,3]. MS Sans Serif, Negrito, 8, Castanho
BitBtn (Localizado na pgina Additional) - crie dois botes para confirmar ou cancelar a emisso do relatrio:
Propriedade Kind Valor bkOk e bkCancel Descrio Determina a classe a ser utilizada pelo objeto, automaticamente sero alteradas as propriedades: Caption, Glyph e ModalResult Label do objeto
Caption
&OK e &Cancelar
Edit (Localizado na pgina Standard) - dois objetos de edio para insero do cdigo inicial e final:
Propriedade Text Font MS Sans Serif, Normal, 8, Azul Marinho Valor Descrio Texto a ser apresentado inicialmente para o objeto Tipo de letra a ser mostrada no objeto
136
Borland
Programando o formulrio
Antes de prosseguirmos salve o formulrio com o nome de fDgGeral. Para selecionarmos os cdigos inicial e final, precisamos fazer uma pequena programao no formulrio: Cdigo para criar os dois campos que enviaro os cdigos (lembra-se do captulo VII Referente a Consultas): 1. Alterne para o CodeEditor e insira o seguinte cdigo abaixo: Inicializa as funes Cria tipo caractere as variveis,
apenas como sada
private function GetCodInicial: String; function GetCodFinal: String; public property CampInicial: String read GetCodInicial; property CampFinal: String read GetCodFinal; end; var F_DgGeral: TF_DgGeral; implementation {$R *.DFM} function TF_ DgGeral.GetCodInicial: String; begin Result := Edit1.Text; end; function TF_ DgGeral.GetCodFinal: String; begin Result := Edit2.Text; end;
Por incrvel que parea isto tudo, agora chame o objeto fMenu, insira o objeto Report , encontrado na Component Palette pgina Data Access, este objeto realiza o trabalho de configurao da impresso. 1. Clique na opo Relatrio | Geral chamando o evento onClick;
137
Borland
2. Insira o comando
procedure TF_Menu.Geral1Click(Sender: TObject); begin if F_DgGeral.ShowModal = mrOK then Chama e verifica se a DgGeral retornou OK Para o objeto Report1... with Report1 do begin ReportName := 'RCADAST.RPT'; Altera a propriedade Nome do Relatrio Elimina os valores iniciais InitialValues.Clear; InitialValues.Add('@CodInicial=<'+F_DgGeral.CampInicial+'>'); Seta o valor CodInicial do relatrio com o valor do CampInicial do formulrio fDgGeral InitialValues.Add('@CodFinal=<'+F_DgGeral.CampFinal+'>'); Seta o valor CodFinal do relatrio com o valor do CampFinal do formulrio fDgGeral Inicia o relatrio Run; end; end;
Salve e execute o sistema, informe trechos diferentes para o relatrio. Caso voc queira que o ReportSmith no execute imediatamente o relatrio mostrando antes uma prvia na tela modifique a propriedade do objeto Report1 - Preview para True. Voc descobrir que o ReportSmith uma poderosa e simples ferramenta para a concepo de relatrios, o nico problema seria com relatrios que se precise imprimir uma nica ou poucas folhas, como um recibo ou um formulrio pr-impresso, voc descobrir que ele lento para estas tarefas, existem duas solues para este caso usar a biblioteca Printers ou usar a impresso livre do formulrio como veremos a seguir.
+ +
138
Borland
(New Form) na Speed Bar, ou no menu principal a Inicialmente Clique no boto Clique no menu principal a opo File e New..., em New Items, na pgina New e clique no objeto entitulado Form e altere as seguintes propriedades:
Valor bsNone F_Capa poScreenCenter [] clWhite Descrio Estilo da borda do formulrio Label do objeto (Tarja azul do formulrio) Nome do objeto Posio da janela (centralizado) Elimine todos os botes da janela Cor de fundo
Crie para esta nova janela os seguintes objetos: Table (Localizado na pgina Data Access) , altere as seguintes propriedades:
Descrio Nome do Alias ou a localizao do diretrio das tabelas Nome externo da tabela Nome do campo indexado Nome do objeto Somente para leitura
139
Borland
Strech Width
True 481
O tamanho da imagem foi colocada em 457 x 481 pois em impressoras padro Epson este, aps impresso, o tamanho da capa do CD. necessrio que voc faa os ajustes necessrios para se adaptar ao padro de sua impressora.
Criando o Cdigo
O cdigo para este formulrio e sua chamada a partir do menu principal bem mais simples que o realizado anteriormente, verifique: Para o menu principal Cdigo para criar a chamada: 1. Chame o formulrio fMenu, e clique na opo Capa do CD :
procedure TF_Menu.CapadoCD1Click(Sender: TObject); var NumCD: String; begin NumCD := InputBox('Informe', 'Entre com o cdigo do CD para imprimir:', ''); if NumCD = '' then begin MessageDlg('No foi informado um cdigo para a impresso', mtInformation, [mbOk], 0); exit; end; F_Capa.Inicio(NumCD); end;
O cdigo para este evento bem simples: cria uma varivel caracter e solicita a entrada de seu valor atravs da funo InputBox, caso no seja retornado nenhum valor cancela a impresso ao contrrio chama o procedimento inicio do formulrio F_Capa enviando o valor informado.
procedure TF_Capa.Inicio(Numero: String); begin TabBasico.Open; if not TabBasico.FindKey([StrToFloat(Numero)]) then MessageDlg('Cdigo do CD inexistente !', mtError, [mbOk], 0)
140
Borland
else begin Show; if MessageDlg('Confirma a impresso da Capa ?', mtConfirmation, mbOkCancel, 0) = mrOk then F_Capa.Print; end; TabBasico.Close; Close; end;
O cdigo para este evento novamente bem simples: abre a tabela e pesquisa a existncia do cdigo enviado, caso encontre mostra a capa do CD e solicita a confirmao do relatrio, e imprime ao final fecha a tabela e o formulrio. No se esquea de declarar o procedimento nas declaraes Public. (procedure Inicio(Numero: String);)
+ +
O componente QuickReport e o responsvel pelo controle do relatrio. Seu trabalho transformar o formulrio do Delphi em um relatrio. Para uma prvia do relatrio (em modo de construo) basta simplesmente dar um duplo click sobre o objeto mas lembre-se que os cdigos para os eventos no sero executados. Componente responsvel pelo controle principal do relatrio. Coloque-o em um formulrio que servir de base para o relatrio e utilize os comandos Print ou Preview. QRBand
Uma banda uma simples diviso do relatrio. um relatrio ser dividido em diferentes partes para a impresso, tais como: Detalhe, Cabealho de Pgina, Rodap, Grupos,
141
Borland
etc. Alguns tipos de bandas so impressas automaticamente, enquanto que outros tipos necessitam dos objetos QRGroup ou QRDetailLink para seu controle. possvel tambm utilizar-se de mltiplas bandas de um mesmo tipo. QRGroup
Os grupos podem ser formados com o auxlio deste componente, se utiliza de cabealho e rodap para o controle do grupo. possvel criar no mximo 10 nveis (a proprieade Level varia de 0 a 9) sendo que os nveis mais baixos dominam a impresso dos mais altos. QRDetailLink O componente QRDetailLink usado para criar diferentes tipos de detalhes. QRLabel
Textos esttico no relatrio so formados pelo componente QRLabel bastando para isso modificar a propriedade Caption. possvel tambm modificar a propriedade Caption durante a gerao do relatrio QRMemo O componente QRMemo e usado para imprimir multiplas linhas de um campo. QRDBText Este componente responsvel pela impresso dos campos dos arquivos. QRDBCalc Componente utilizado para realizar clculos bsicos durante a gerao do relatrio QRSysData
Imprime vrias informaes sobre o sistema tais como: nmero da pgina, data, hora ou ttulo do relatrio. QRShape Utilizado para desenhar simples figuras geomtricas. QRPreview Este objeto responsvel pela modificao no Preview padro do relatrio.
142
Borland
Vamos agora realizar um exemplo simples e prtico com o Quick, criando o mesmo relatrio proposto com o Report Smith, deste modo acredito, que voc pode comparar a facilidade de ambos os geradores. (New Form) na Speed Bar, ou no menu principal a 1. Inicialmente Clique no boto Clique no menu principal a opo File e New..., em New Items, na pgina New e clique no objeto entitulado Form e altere a propriedade name para F_Relato e salve o formulrio como fRelato. 2. Coloque os seguintes objetos e faa as seguintes alteraes: Query (Localizado na pgina Data Access) , altere as seguintes propriedades:
Propriedade Valor Descrio Nome do Alias ou a localizao do diretrio das tabelas DatabaseName BaseDisco SQL
Select B.Cod_Disco, B.Nom_Disco, B.Tip_Disco, Clusula de consulta C.Des_Categ from Basico as B left join Categor as C on (B.Sig_Categ = C.Sig_Categ) where B.Cod_Disco Between :Cod01 and :Cod02 order by B.Cod_Disco Acerte ambos os campos para DataType como AsFloat QryBasico Parmetro da consulta Nome do objeto
Params Name
Para o Objeto QrSysData (Localizado na pgina QReport), crie-o clicando dentro do objeto bdCabecalho
Valor True True qrsReportTitle Arial, 14, Negrito, Branco taCenter Descrio Alinha considerando a banda Dimensiona automaticamente o tamanho Tipo do dado a ser mostrado Fonte do objeto Alinhamento do objeto
143
Borland
Para o Objeto QrSysData (Localizado na pgina QReport), crie-o clicando dentro do objeto bdCabecalho
Valor True True qrsDateTime Arial, 8, Normal, Branco taRightJustify Descrio Alinha considerando a banda Dimensiona automaticamente o tamanho Tipo do dado a ser mostrado Fonte do objeto Alinhamento do objeto
Para o Objeto QrLabel (Localizado na pgina QReport), crie-o clicando dentro do objeto bdCabColuna
Valor Cdigo Arial, 12, Negrito, Branco Descrio Label do objeto Fonte do objeto
Para o Objeto QrLabel (Localizado na pgina QReport), crie-o clicando dentro do objeto bdCabColuna
Valor Nome Arial, 12, Negrito, Branco Descrio Label do objeto Fonte do objeto
Para o Objeto QrLabel (Localizado na pgina QReport), crie-o clicando dentro do objeto bdCabColuna
Valor Tipo Arial, 12, Negrito, Branco Descrio Label do objeto Fonte do objeto
Para o Objeto QrLabel (Localizado na pgina QReport), crie-o clicando dentro do objeto bdCabColuna
Valor Categoria Arial, 12, Negrito, Branco Descrio Label do objeto Fonte do objeto
Para o Objeto QrDbText (Localizado na pgina QReport), crie-o clicando dentro do objeto bdDetalhe
144
Borland
Propriedade AutoSize DataSource DataField
Para o Objeto QrDbText (Localizado na pgina QReport), crie-o clicando dentro do objeto bdDetalhe
Valor True DsBasico Nom_Disco Descrio Dimensiona automaticamente o tamanho DataSource vinculado Campo vinculado
Para o Objeto QrDbText (Localizado na pgina QReport), crie-o clicando dentro do objeto bdDetalhe
Valor True DsBasico Tip_Disco Descrio Dimensiona automaticamente o tamanho DataSource vinculado Campo vinculado
Para o Objeto QrDbText (Localizado na pgina QReport), crie-o clicando dentro do objeto bdDetalhe
Valor True DsBasico Des_Categ Descrio Dimensiona automaticamente o tamanho DataSource vinculado Campo vinculado
Criaremos um relatrio simples com cabealho (BdCabecalho), Impresso das linhas detalhe (bdDetalhe) e rodap (bdRodape), a ordem de disposio das bandas no importa, o objeto QuickReport responsvel por este controle. Ao final acerte a tela de modo que fique semelhante a esta:
3. Por mais incrvel que isto possa parecer nosso relatrio est pronto, precisamos somente mudar a chamada a partir do objeto F_Menu (aproveitaremos o objeto F_DgGeral criado para o uso com o Report Smith) chame novamente o objeto F_Menu e clique na opo Relatrio | Geral chamando o evento onClick;
145
Borland
4. Insira o comando
procedure TF_Menu.Geral1Click(Sender: TObject); begin if F_DgGeral.ShowModal = mrOK then Chama e verifica se a DgGeral retornou OK Para o objeto F_Relato with F_Relato do begin QryBasico.Params[0].AsFloat := StrToFloat(F_DgGeral.CampInicial); Envia os parmetros QryBasico.Params[0].AsFloat := StrToFloat(F_DgGeral.CampFinal); QryBasico.Open; Abre a Query Chama o relatrio em tela QrConfere.Preview; Fecha a Query QryBasico.Close; end; end;
Poderiamos ficar criando n tipos de relatrios diferentes mas o melhor mtodo que voc d uma olhada no diretrio [Diretrio de Instalao do Delphi]\Demos\QuickRpt e execute o projeto Qrdemo.dpr. Qualquer outra referncia pode ser encontrada no documento Word que acompanha o produto, o arquivo QrManual.doc. O usurio do Delphi 1.0 pode ficar se perguntando porque adquirir ou aprender a utilizar um outro gerador de relatrio quando o Delphi j traz gratuitamente o ReportSmith? O problema que acontece se restringe a distribuio de um sistema em Delphi que utilize relatrios gerados com o ReportSmith este exige um run-time para executar (distribudo gratuitamente tanto na verso 1.0 quanto na verso 2.0) ocupando mais espao na mquina cliente. Necessariamente, no ser preciso enquanto voc estiver na fase de desenhando o formulrio executar o sistema para ver como ficou, simplesmente d um duplo clique no objeto e o relatrio ser automaticamente gerado. Obs. Cuidado que os eventos criados do formulrio no sero executados.
Captulo IX
Multimdia
Este captulo foi inserido apenas para sanar quaisquer dvidas existentes quanto ao desenvolvimento de aplicaes que envolvam multimdia com o Delphi, a primeira parte no faz parte do desenvolvimento do projeto piloto iniciado.
O que multimdia ?
Multimdia e uma associao que decorre com o uso de imagens, sons e movimentos, os trs tipos de arquivos que se utilizam deste formato de aplicao so: 1. tipo AVI - inclui as produes de vdeo.
146
Borland
2. tipo MID - arquivos para a produo de msica utilizando a interface de Instrumentos Musicais Digitalizados, ou formato MIDI. 3. tipo WAV - mais comuns, inclui o registro de sons utilizando a tecnologia Microsoft's WAVE.. O problema principal que ocorre quanto a aplicaes multimdia o espao fsico ocupado, por exemplo, arquivos do tipo AVI, comparando um filme de apenas um minuto ou menos pode ocupar cerca de 5Mb ou at mesmo 10Mb de espao em disco.
Objeto TMediaPlayer
Para criar uma simples aplicao multimdia crie um novo projeto, e arraste o objeto para o formulrio, automaticamente criado uma barra de tarefas multimdia, conforme a figura abaixo:
Clique no objeto e altere a propriedade FileName para C:\WINDOWS\CHIMES.WAV esta propriedade associa a arquivos tipo AVI, MIDI ou WAVE altere tambm a propriedade AutoOpen para True, esta propriedade inicia automaticamente o arquivo. Depois de completos estes simples passos voc j pode rodar o programa. Pressione o boto verde para ouvir o som do arquivo selecionado. Mas de repente voc no ouviu nada, no se desespere a causa pode ser um destes problemas 1. Voc entrou com o nome do arquivo invlido. 2. Seu sistema de multimdia no est correto. 3. A propriedade AutoOpen no est true.
147
Borland
Podemos tambm alterar o arquivo a qual queremos ouvir, para isto insira o objeto , encontrado na Component Palette na pgina Dialogs, e um objeto BitBtn OpenDialog conforme a figura abaixo:
Um ajuste pode ser feito para permitir que o objeto seleo tenha acesso apenas as extenses AVI , WAV, or MID. Podendo ser colocado de duas maneiras diferentes, na propriedade Filter do objeto OpenDialog1:
148
Borland
Antes de iniciarmos vamos fazer uma pequena observao, principalmente relativo a dois pontos: Para alguns programadores que procuram coisas teis, as informaes aqui presentes contm o essencial para transform-los em programadores multimdia. Outra observao seria a respeito de alguns controles a arquivos multimdia. D uma olhada no arquivo [DiretrioDelphi]\SOURCE\RTL\WIN\MMSYSTEM.PAS, uma biblioteca de funes que contm todas as chamada de acesso a baixo nvel de comandos Windows para aplicaes multimdia. As tcnicas de acessos esto contidas no prprio documento. Com estes dois pontos frescos em nossa mente, podemos iniciar o nosso estudo sobre os aspectos do objeto TMediaPlayer. D uma olhada na Objeto Inspector na pgina de Eventos do objeto TMediaPlayer voc encontrar dois mtodos: O evento OnClick que ocorre quando pressionado qualquer boto do controle. Por instncia, atravs do parmetro enviado Button possvel saber se o boto pressionado foi o OnPlay. Um segundo evento consiste no OnNotify por conter a mensagem mm_MciNotify que so as chamadas do Windows para o inicio ou o termino de uma execuo, com seus eventuais erros. Ambos os eventos sero discutidos nos prximos pargrafos. possvel identificar o boto pressionado atravs do evento OnClick, aqui esto todos os tipos gerados pelo TMPBtnType:
9 9
btPlay: Quando pressionado o boto verde, Iniciar. btPause: Quando pressionado o boto amarelo, Pausa.
149
Borland
9 9 9 9 9 9 9
btStop: Quando pressionado o boto vermelho, Parar. btBack: Quando pressionado o boto azul, Avana a imagem. btStep: Quando pressionado o boto azul, Retorna a imagem. btNext: Quando pressionado o boto azul, Avano rpido. btPrev: Quando pressionado o boto azul, Retorno rpido. btRecord: Quando pressionado o boto vermelho, Gravao. btEject: Quando pressionado o boto azul, Retirar.
Inicialmente vamos determinar qual foi o tipo de boto pressionado, para tanto, crie para o evento OnClick o seguinte cdigo:
procedure TForm1.MediaPlayer1Click(Sender: TObject; Button: TMPBtnType; var DoDefault: Boolean); begin case Button of btPlay: Edit1.Text := 'Tocando'; btPause: Edit1.Text := 'Pausado'; btStop: Edit1.Text := 'Parado'; btNext: Edit1.Text := 'Prximo'; btPrev: Edit1.Text := 'Anterior'; btStep: Edit1.Text := 'Avanando'; btBack: Edit1.Text := 'Retornando'; btRecord: Edit1.Text := 'Gravando'; btEject: Edit1.Text := 'Retirando'; end; end;
Para encontrar o que aconteceu com o processo, necessitamos do evento OnNotify. Aqui esto as mensagens enviadas pelo sistema operacional:
9 9 9 9
do tipo:
mci_Notify_Successful: Comando completado com xito mci_Notify_Superseded: Comando suspenso por outra funo mci_Notify_Aborted: Funo corrente foi interrompida mci_Notify_Failure: Algum erro ocorreu.
O Delphi no reconhece estas diretivas de mensagem, mas ele converte para constantes
9 9 9
nvSuccessful indicando o xito. nvSuperseded indicando que est suspenso, provavelmente por causa de uma pausa. nvAborted messages indicando que foi pressionado o boto parar, ou causa devido ao fechamento do arquivo.
150
Borland
nvSuperseded: S := 'mci_Notify_Superseded'; nvAborted: S := 'mci_Notify_Aborted'; nvFailure: S := 'mci_Notify_Failure'; else S := 'No consigo identificar a mensagem'; end; Edit2.Text := S; if (MediaPlayer1.NotifyValue = nvSuccessful) and (MediaPlayer1.Mode = mpStopped) then Edit1.Text := 'Arquivo finalizado'; end;
Estes eventos verificam os acontecimentos mais significativos que ocorreram com o dispositivo MCI. O modo corrente com que o dispositivo MCI especificado tambm pode ser utilizado pelo objeto TMediaPlayer. Aqui uma listagem dos valores mais comuns designados:
9 9 9 9 9 9 9
Estes valores so auto-explicativos. Por exemplo, o modo do campo fixado em mci_Mode_Stop, o dispositivo est parado. Se fixado em mci_Mode_Play, o dispositivo est tocando. Crie uma nova procedure Private chamada SetMode, e insira o seguinte cdigo:
procedure TForm1.SetMode; begin Edit4.Text := MediaPlayer1.FileName; case MediaPlayer1.Mode of mpNotReady: Edit3.Text := 'mci_Mode_Not_Ready'; mpStopped: Edit3.Text := 'mci_Mode_Stop'; mpPlaying: Edit3.Text := 'mci_Mode_Play'; mpRecording: Edit3.Text := 'mci_Mode_Record'; mpSeeking: Edit3.Text := 'mci_Mode_Seek'; mpPaused: Edit3.Text := 'mci_Mode_Pause'; mpOpen: Edit3.Text := 'mci_Mode_Open'; else begin Edit1.Text := 'Dispositivo Inativo'; Edit2.Text := 'Sem messagens'; Edit3.Text := 'No identificado'; Edit4.Text := 'No h arquivo selecionado'; end; end; end;
Para a chamada desta rotina click no objeto Ttimer e chame o evento OnTimer e insira o seguinte cdigo:
procedure TForm1.Timer1Timer(Sender: TObject); begin
151
Borland
SetMode; end;
Com a propriedade Interval deste objeto fixada em 1000, significa que a cada 1000 milisegundos ser disparada a rotina de verificao que informar o estado para o objeto TMediaPlayer. Execute o projeto e atente para os seguintes detalhes: Toda a vez que for usado um boto da barra multimdia, ser disparado o evento onClick marcando deste modo o tipo de boto pressionado; As mensagens da mm_MciNotify ocorrem durante toda a execuo da aplicao, tente utilizar os botes Pausa e Parar no meio de uma execuo. Quando for selecionar um novo arquivo, afaste um pouco a janela de dilogo e observe como esto os campos edit.
Observe e estude tambm o arquivo [DiretrioDelphi]\SOURCE\VCL\MPLAYER .PAS ele a unidade principal de criao do objeto TMediaPlayer.
Desenvolvimento do CD Player
Inicialmente, crie um novo objeto Form baseado na template Blank form e altere as seguintes propriedades:
Valor bsDialog CD Player F_Player poScreenCenter Descrio Estilo da borda do formulrio Label do objeto (Tarja azul do formulrio) Nome do objeto Posio da janela (centralizado)
Crie para esta nova janela os seguintes objetos: , encontrado na Component Pallety na pgina System, e altere as
Descrio
152
Borland
TTimer , encontrado na Component Pallety na pgina System, servir para controlar o tempo das msicas. Panel propriedades:
Propriedade Align Alignment BevelInner BevelOuter BorderWidth Caption Name Font
Height
Panel propriedades:
Propriedade Align BevelInner BevelOuter BorderWidth Height Caption
Crie quatro objetos Label dentro do objeto Panel2, para os dois primeiros altere a propriedade Caption para Trilha: e Posio: respectivamente para os outros dois altere a propriedade Name para LblTrack e LblTime, altere a propriedade Font de todos para MS Sans Serif, Estilo da fonte: Normal, Tamanho: 8, Cor: Castanho. Compare o desenho do formulrio a seguir:
153
Borland
Quanto ao programa vou explic-lo na integra, acompanhe a listagem colocando os procedimentos nos locais indicados:
unit Fplayer; interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, MPlayer, MMSystem; type TF_Player = class(TForm) CD: TMediaPlayer; Timer1: TTimer; LinhaStatus: TPanel; Panel2: TPanel; Label1: TLabel; Label2: TLabel; LblTrack: TLabel; LblTime: TLabel; procedure Timer1Timer(Sender: TObject); procedure CDPostClick(Sender: TObject; Button: TMPBtnType); procedure CDNotify(Sender: TObject); procedure FormCreate(Sender: TObject); private TrilhaCorrente: byte; FinalTrilhaCorrente: Longint; TrilhaLidas: boolean; CDPlaying, CDPaused: boolean; TamTrilha: array[1..100] of LongInt; function CDPos(Sender:TObject; Trilha, Min, Sec: byte): Longint; procedure InitCD(Sender:TObject); procedure ResetCD(Sender:TObject); public { Public declarations } end; var F_Player: TF_Player; implementation {$R *.DFM}
154
Borland
const ModeStr: array[TmpModes] of string[10] = ('No Lido', 'Parado', 'Tocando', 'Gravando', 'Pesquisando', 'Pausado', 'Aberto');
{ Criado - Calcula a posio } function TF_Player.CDPos(Sender:TObject; Trilha, Min, Sec: byte): Longint; var i: integer; begin result := 0; for i := 1 to (Trilha - 1) do begin Inc(Result, mci_MSF_Second(TamTrilha[i])); Inc(Result, mci_MSF_Minute(TamTrilha[i]) * 60); end; Inc(Result, Sec); Inc(Result, Min * 60); end; { Criado - Inicializa os drivers de CD } procedure TF_Player.InitCD(Sender:TObject); var i : integer; begin if not TrilhaLidas then begin LinhaStatus.Caption := 'Lendo as trilhas'; LinhaStatus.Update; for i := 1 to CD.Tracks do TamTrilha[i] := CD.TrackLength[i]; TrilhaLidas := True; end; end; { Criado - Reseta o formulrio } procedure TF_Player.ResetCD(Sender:TObject); begin { Limpa para trilha 0 } TrilhaCorrente := 1; LblTrack.Caption := '0'; LblTime.Caption := '00:00'; { Modifica a cor para vermelho } LblTrack.Font.Color := clRed; LblTime.Font.Color := clRed; { Para o CD Player } CD.Stop; { Coloca a posicao da trilha para a inicial } CD.StartPos := mci_Make_TMSF(1, 0, 0, 0); CDPlaying := False; CDPaused := False; end;
155
Borland
{ Evento Timer do Objeto Timer1 } procedure TF_Player.Timer1Timer(Sender: TObject); var Trilha, Minutes, Seconds : byte; strMinuto, strSegundo: String; Pos: LongInt; begin { Acerta o estado da linha } if CDPaused then LinhaStatus.Caption := 'Pausado' else LinhaStatus.Caption := ModeStr[CD.Mode]; case CD.Mode of mpStopped: begin { Inicializa o CD para ser lido } if not TrilhaLidas then InitCD(CD); { No caso de ser Continuous Play } if CDPlaying and (not CDPaused) then begin CD.StartPos := mci_Make_TMSF(1, 0, 0, 0); CD.Play; CD.EnabledButtons := [btPause, btStop, btNext, btPrev, btEject]; end; end; mpOpen: begin TrilhaLidas := False; ResetCD(CD); end; mpPlaying: begin Pos := CD.Position; Trilha := mci_TMSF_Track(Pos); Minutes := mci_TMSF_Minute(Pos); Seconds := mci_TMSF_Second(Pos); TrilhaCorrente := Trilha; { Constri os minutos e segundos para mostrar } strMinuto := IntToStr(Minutes); strSegundo := IntToStr(Seconds); if Length(strMinuto) < 2 then strMinuto := '0' + strMinuto; if Length(strSegundo) < 2 then strSegundo := '0' + strSegundo; { Mostra os Labels } LblTrack.Caption := IntToStr(Trilha); LblTime.Caption := strMinuto + ':' + strSegundo; end; end; end;
156
Borland
{ Evento PostClick do Objeto CD } procedure TF_Player.CDPostClick(Sender: TObject; Button: TMPBtnType); begin case Button of btPlay: begin { Modifica a cor para Azul Marinho } LblTrack.Font.Color := clNavy; LblTime.Font.Color := clNavy; CDPlaying := True; CDPaused := False; Update; end; btPause: begin { Modifica a cor para Roxo } LblTrack.Font.Color := clPurple; LblTime.Font.Color := clPurple; CDPlaying := False; CDPaused := True; Update; end; btStop: ResetCD(CD); btEject: begin TrilhaLidas := False; ResetCD(CD); end; end; Timer1Timer(Timer1); end; { Evento OnNotify do Objeto CD } procedure TF_Player.CDNotify(Sender: TObject); begin Timer1Timer(Timer1); end; { Evento OnCreate do Objeto F_Player } procedure TF_Player.FormCreate(Sender: TObject); begin CDPlaying := False; CDPaused := False; TrilhaLidas := False; end; end.
157
Borland
Salve o formulrio com o nome de FPlayer e faa a chamada a partir do menu principal do seu sistema, bom divertimento.
Captulo X
Novos Componentes
Uma das maiores vantagens do Delphi sobre os demais concorrentes o fato da gerao de novos componentes (de novos objetos). O exemplo a seguir pretende colocar uma luz sobre o assunto mostrando os passos bsicos para o desenvolvimento de componentes, estes passos so: Criando propriedades e mtodos; Controle ao acesso as propriedades; Propriedades de leitura e escrita; Enviando e recebendo mensagens atravs dos componentes.
Criando Componentes
Componentes so como blocos de construo para as aplicaes Delphi. Voc poder construir uma aplicao simplesmente adicionando estes blocos e modificando os eventos, propriedades ou mtodos. Todos os componentes possuem duas propriedades em comum: Name e Tag. Alguns componentes esto distribudos na Component Pallete. Mas alguns componentes (TApplication, TMenu, TMenuItem, e TScreen) so disponveis apenas atravs de seu cdigo. Voc pode criar novos componentes utilizando os seguintes passos: 1. Derivando os novos componentes de um componente j existente. 2. Modificando um componente. 3. Registrando um componente. O componente criado como uma unit separada de um projeto, podendo ser formado por uma ou mais units. Aps voc criao do componente, compilao e instalao dentro da paleta de componentes. Para usar o componente, selecione-o da Component Pallete e adicione-o ao formulrio.
158
Borland
A Classe TComponent
Voc criar um novo componente utilizando diretamente o Code Editor, para isso voc usar a Component Expert. Na verdade todos os componentes criados sero derivados de componentes j existentes, mesmo que voc deseje criar um componente sem eventos ou propriedades ele ser herdado de uma classe j existente a TComponent. A TComponent uma classe inicial de componentes, sob ela que foi feita a rvore de componentes Delphi, por exemplo, a classe TControl, possuem mais de 70 componentes descendentes, tais como: TBitBtn, TButton, TCheckBox, TColorDialog, TComboBox, TForm, TFontDialog, TGroupBox, THeader, TImage, TLabel, TListBox, TMainMenu e TMediaPlayer. E voc ainda pode derivar mais alguns descendentes daqui.
Um Componente Simples
Vamos criar agora um novo componente, para tanto abra um novo projeto e selecione
File | New... selecione a pgina New e o item . Ser mostrada a janela da Component Expert. Informe os seguintes parmetros conforme o desenho abaixo:
Clique no boto OK para aceitar a entrada. A Component Expert criar automaticamente o seguinte cdigo para a chamada da Unit1:
unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; type CustComp1 = class(TComponent) private { Private declarations } protected { Protected declarations } public
159
Borland
{ Public declarations } published { Published declarations } end; procedure Register; implementation procedure Register; begin RegisterComponents('Custom', [CustComp1]); end; end.
Clique no boto Add... e ser mostrada a janela dilogo Add Module. Use o boto Browse para localizar o arquivo Cust.PAS, note que ele ser remetido a ListBox Installed units: e caminho do componente (se voc salvou-o em outro diretrio) ser colocado no Search Path.
160
Borland
Para novos componentes crie um diretrio embaixo do Delphi entitulado Lib2, pois se voc sempre colocar cada novo componente no diretrio Lib, caso voc precise copiar apenas os seus componentes, dificilmente os distinguir dos componentes padres do Delphi. Lembre-se que o Search Path um campo texto limitado em 255 posies ento tambm no adianta para cada componente novo colocar um diretrio separado, pois facilmente voc estourar o tamanho do campo Search Path. Finalmente clique no boto OK e a COMPLIB.DCL (Biblioteca padro de componentes) ser recompilada. Ao trmino da compilao, note que foi criada uma nova pgina na Component Pallete (Custom) e adicionado o novo componente (CustomComp1). Para testar seu novo componente crie um novo formulrio insira o componente CustomComp1. Observe atravs da Object Inspector as propriedades do seu novo componente: Name e Tag.
+ +
Criando Propriedades
Para o nosso componente vamos adicionar uma propriedade que armazenar um valor inteiro, para isto chame novamente a unit do componente e insira os cdigos abaixo da declarao private:
type CustComp1 = class(TComponent) private fDemoProp:Integer;
Agora criaremos uma propriedade aonde o valor ser lido e escrito atravs desta varivel para tanto insira os cdigos abaixo da declarao published:
published property DemoProp: Integer read fDemoProp write fDemoProp; end;
A seo Public (pblica) abriga as variveis, procedimentos ou funes que podem ser lidos e executados por quaisquer outras units que utilizem (atravs clusula Uses) a unit em questo j a seo Published (Publicado) utilizada para inserir propriedades ou eventos aos componentes. Salve o componente e recompile a biblioteca atravs das opes Component | Rebuild Library..., ao trmino da recompilao, note que para o componente foi criada uma nova propriedade definida como DemoProp que armazena o valores inteiros.
Mtodos de Acesso
A propriedade criada pode disparar um procedimento ou uma funo para executar determinadas aes (por exemplo, colocando um intervalo vlido para a varivel criada). Primeiro, escreva a seguinte funo para a funo read do comando property:
function Cust.GetDemoProp: integer;
161
Borland
Declare a funo GetDemoProp e o procedimento SetDemoProp na seo private, conforme o exemplo abaixo:
private fDemoProp:Integer; function GetDemoProp: integer; procedure SetDemoProp(val: integer);
Salve o componente e recompile a biblioteca atravs das opes Component | Rebuild Library..., note que a propriedade no mais permitir valores superiores a 99.
Na seo private crie uma nova varivel com base no tipo definido:
private fDemoProp:Integer; fNovaProp:TDirecao;
Salve o componente e recompile a biblioteca atravs das opes Component | Rebuild Library..., teste a nova propriedade.
162
Borland
Pensando em Objetos
Mas para que devemos criar novos componentes? Para aliviarmos os futuros trabalhos. Lembra-se quando voc copiava aqueles pequenos pedaos de rotinas (do tipo: clculo de CPF/CGC, clculo de fatorial, um cabealho de relatrio...) os objetos servem exatamente para guardamos estes pequenos pedaos de blocos de programao, ou se voc preferir o termo serve para encapsularmos estes cdigos.
Construindo um Objeto
Quando for construir objetos lembre-se que ele deve servir vrios aplicativos, nunca construa um objeto que servir apenas a um nico aplicativo ( perda de tempo). Todo o sistema (pelo menos for Windows) necessita de uma janela Sobre o Sistema ento vamos transformar a janela sobre criada no Captulo IV em um objeto prtico que sirva a qualquer sistema, inicie um novo projeto e crie um novo componente, para tanto abra um novo projeto e selecione File | New... selecione a pgina New e o item Component. Ser mostrada a janela da Component Expert. Informe os seguintes parmetros: Class Name: SobreDlg Ancestor type: TComponent Palette Page: Dialogs Clique no boto OK para aceitar a entrada. As alteraes propropostas no objeto esto documentadas com o fonte:
unit SobreDlg; { Este objeto permite a criao de uma "caixa sobre" padro para diversos aplicativos. } interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, fSobre; type TSobreDlg = class(TComponent) private FProductName, FVersion, FCopyright, FComments: string; public function Execute: Boolean; published property NomeProduto: string read FProductName write FProductName; property Versao: string read FVersion write FVersion; property Direitos: string read FCopyright write FCopyright; property Comentario: string read FComments write FComments; end;
163
Borland
const PROCESSOR_INTEL_386 = 386; PROCESSOR_INTEL_486 = 486; PROCESSOR_INTEL_PENTIUM = 586; PROCESSOR_INTEL_860 = 860; PROCESSOR_MIPS_R1000 = 1000; PROCESSOR_MIPS_R2000 = 2000; PROCESSOR_MIPS_R3000 = 3000; PROCESSOR_MIPS_R4000 = 4000; PROCESSOR_ALPHA_21064 = 21064; PROCESSOR_PPC_601 = 601; PROCESSOR_PPC_603 = 603; PROCESSOR_PPC_604 = 604; PROCESSOR_PPC_620 = 620; var SobreDlg: TSobreDlg; procedure Register; implementation procedure Register; begin RegisterComponents('Dialogs', [TSobreDlg]); end; function TSobreDlg.Execute: Boolean; var OsInfo: TOSVERSIONINFO; SysInfo: TSYSTEMINFO; MemStat: TMEMORYSTATUS; DiskNo: Integer; begin // Cria a janela em memria F_Sobre := TF_Sobre.Create(Application); try with F_Sobre do begin // Coloca as propriedades nas variaveis do formulario ProductName.Caption := NomeProduto; Version.Caption := Versao; Copyright.Caption := Direitos; Comments.Caption := Comentario; Caption := 'Sobre ' + NomeProduto; OsInfo.dwOSVersionInfoSize := sizeof(TOSVERSIONINFO); GetVersionEx(OsInfo); // Verso do Windows case OsInfo.dwPlatformId of VER_PLATFORM_WIN32s : WinVersion.Caption := 'Windows 3.1'; VER_PLATFORM_WIN32_WINDOWS : WinVersion.Caption := 'Windows 95'; VER_PLATFORM_WIN32_NT : WinVersion.Caption := 'Windows NT';
164
Borland
end; DosVersion.Caption := format('%d.%d Ver : %d', [OsInfo.dwMajorVersion,OsInfo.dwMinorVersion,LOWORD(OsInfo.dwBuildNumber)]); // Pega o processador GetSystemInfo(SysInfo); case SysInfo.dwProcessorType of PROCESSOR_INTEL_386 : CPU.Caption := format('%d %s',[SysInfo.dwNumberOfProcessors, 'Intel 80386']); PROCESSOR_INTEL_486 : CPU.Caption := format('%d %s',[SysInfo.dwNumberOfProcessors, 'Intel 80486']); PROCESSOR_INTEL_PENTIUM : CPU.Caption := format('%d %s',[SysInfo.dwNumberOfProcessors, 'Intel Pentium']); PROCESSOR_MIPS_R1000 : CPU.Caption := format('%d %s',[SysInfo.dwNumberOfProcessors, 'MIPS R1000']); PROCESSOR_MIPS_R2000 : CPU.Caption := format('%d %s',[SysInfo.dwNumberOfProcessors, 'MIPS R2000']); PROCESSOR_MIPS_R3000 : CPU.Caption := format('%d %s',[SysInfo.dwNumberOfProcessors, 'MIPS R3000']); PROCESSOR_MIPS_R4000 : CPU.Caption := format('%d %s',[SysInfo.dwNumberOfProcessors, 'MIPS R4000']); PROCESSOR_ALPHA_21064 : CPU.Caption := format('%d %s',[SysInfo.dwNumberOfProcessors, 'ALPHA 21064']); PROCESSOR_PPC_601 : CPU.Caption := format('%d %s',[SysInfo.dwNumberOfProcessors, 'Power PC 601']); PROCESSOR_PPC_603 : CPU.Caption := format('%d %s',[SysInfo.dwNumberOfProcessors, 'Power PC 603']); PROCESSOR_PPC_604 : CPU.Caption := format('%d %s',[SysInfo.dwNumberOfProcessors, 'Power PC 604']); PROCESSOR_PPC_620 : CPU.Caption := format('%d %s',[SysInfo.dwNumberOfProcessors, 'Power PC 620']); end; MemStat.dwLength := sizeof(TMEMORYSTATUS); GlobalMemoryStatus(MemStat); FreeMemory.Caption := format('Tot: %d KB Disp: %d KB', [Trunc(MemStat.dwTotalPhys/1024),Trunc(MemStat.dwAvailPhys/1024)]); DiskNo := 3; FreeDisk.Caption := ''; FreeResources.Caption := ''; repeat if DiskNo < 7 then FreeDisk.Caption := FreeDisk.Caption + format('%s: %d MB ', [Chr(DiskNo + Ord('A')- 1),Trunc(DiskFree(DiskNo)/1024/1024)]) else FreeResources.Caption := FreeResources.Caption + format('%s: %d MB ', [Chr(DiskNo + Ord('A')- 1),Trunc(DiskFree(DiskNo)/1024/1024)]); inc(DiskNo); until DiskFree(DiskNo) = -1; ProgramIcon.Picture.Graphic := Application.Icon; Result := (ShowModal = IDOK); end; finally
165
Borland
Para esta primeira etapa do nosso objeto note que tudo gira em torno do procedimento Execute (o nome se deve apenas a uma questo de padronizao com os outros objetos da palheta Dialogs), atravs deste procedimento todos as outras variveis so iniciadas, resta-nos agora a criao do formulrio, crie um novo formulrio, ATENO: No aproveite o formulrio F_Sobre j criado pois este uma herana do formulrio F_Splash, crie-o conforme o desenho abaixo:
Para os objetos dentro do painel: altere a propriedade Caption: Nome do Produto, Verso, Direitos Resevados e Comentrio e a propriedade Name: ProductName, Version, Copyright, Comments. Para os objetos fora do painel: altere os objetos Labels da esquerda a propriedade Caption (Ex: Usurio, Companhia) e os da direita a propriedade Name (Ex: UserName, CompanyName)
+ +
+ A propriedade Name para todos os componentes, na ordem que eles aparecem so:
Objeto ProgramIcon Comments CompanyName DosVersion FreeMemory F_Sobre Tipo TImage TLabel TLabel TLabel TLabel TForm Objeto ProductName Label1 Label3 Label5 Label7 Panel1 Tipo TLabel TLabel TLabel TLabel TLabel TPanel Objeto Version UserName WinVersion CPU FreeDisk Tipo TLabel TLabel TLabel TLabel TLabel Objeto Copyright Label2 Label4 Label6 FreeResources Tipo TLabel TLabel TLabel TLabel TLabel
166
Borland
Salve a janela com o nome de FSobre e o componente como SobreDlg e compile a biblioteca e instale o componente: SobreDlg.PAS, teste o componente da seguinte forma: 1. Remova do projeto o formulrio F_Sobre e retire sua chamada da clusula Uses; 2. Coloque o componente no formulrio F_Menu e acerte as suas propriedades; 3. Insira a chamada ao componente na opo de Sobre o Sistema:
procedure TF_Menu.ItemAuxilio1Click(Sender: TObject); begin SobreDlg.Execute; end;
Finalmente
facilmente reconhecido que este novo ambiente da Borland possui um poder um tanto ilimitado, tanto na criao de sistemas como no desenvolvimento de aplicaes de multimdia resta-nos (a ns desenvolvedores) deixarmos a imaginao fluir e iniciar tudo aquilo que sempre desejamos, espero que lhe tenha ajudado ao menos a trilhar o caminho das pedras.
167
Apndice A
Documentao
A documentao includa com o Delphi Client/Server:
Delphi Users Guide Delphi Component Writers Guide Delphi Database Aplication Developers Guide SQL Links Users Guide InterBase Users Guide InterBase Language Reference InterBase Data Definition ReportSmith Creating Reports
Toda a documentao encontrada em forma de livros e modo on-line (para o segundo caso faz-se necessria a instalao do ACROBAT Reader 2.0 que acompanha o produto).
Hardware/Software requeridos
O Delphi Client/Server requer:
40 megabytes de espao livre para a instalao mnima 90 megabytes de espao livre para a instalao completa
um processador 80386 ou maior (486 recomendado) 8 megabytes de RAM
Para instalar, rode o programa INSTALL.EXE direto do CD ROM ou do disquete e prossiga com as instrues. Sero includas informaes adicionais no arquivo README.TXT normalmente instalado no diretrio \DELPHI. Alguns exemplos de aplicaes esto contidas no diretrio \DELPHI\DEMOS.
168
Apndice B
Converso de Campos
possvel, com o DELPHI, criarmos um mesmo sistema que rode em diferentes tipos de bases, atravs de um nico ALIAS. Para isto precisamos que a definio, tamanho e nome dos campos e tabelas sejam necessariamente os mesmos. Abaixo est a converso para quatro bases lgicas de dados:
Sintaxe SQL - para InterBase, ORACLE , Informix entre outras. BDE Lgico - A chamada do campo interna ao DELPHI. Paradox - Bases do tipo Paradox. dBASE - Bases do Tipo .DBF.
Sintaxe SQL SMALLINT INTEGER DECIMAL(x,y) NUMERIC(x,y) FLOAT(x,y) CHARACTER(n) VARCHAR(n) DATE BOOLEAN BLOB(n,1) BLOB(n,2) BLOB(n,3) BLOB(n,4) BLOB(n,5) TIME TIMESTAMP MONEY AUTOINC BYTES(n) BDE Lgico fldINT16 fldINT32 fldBCD fldFLOAT fldFLOAT fldZSTRING fldZSTRING fldDATE fldBOOL fldstMEMO fldstBINARY fldstFMTMEMO fldstOLEOBJ fldstGRAPHIC fldTIME fldTIMESTAMP fldFLOAT, fldstMONEY fldINT32, fldstAUTOINC fldBYTES(n) Paradox Short Long Integer BCD Number Number Alpha Alpha Date Logical Memo Binary Formatted memo OLE Graphic Time Timestamp Money Autoincrement Bytes dBASE Number (6,10) Number (20,4) N/A Number (x,y) Float (x,y) Character Character Date Logical Memo Binary No Apresenta OLE No Apresenta No Apresenta No Apresenta Float (20,4) No Apresenta No Apresenta
x = preciso (default: especfico para o driver) y = escala (default: 0) n = tamanho em bytes (default: 0) 1-5 = BLOB subtipo (default: 1)
169
Borland
1 at 32767 1 jan 100 at 11 jan 5941 Preciso: 1 at 15 e escala de 1 at 15 1,7 x 10-308 at 1,7 x 10308 3,4 x 10-38 at 3,4 x 1038 -2.147.483.648 at 2.147.483.648 Preciso: 1 at 15 e escala de 1 at 15 -32.768 at 32.767 1 at 32767
varivel
Especifica-se por preciso o nmero de dgitos a serem gravados e por escala o nmero de casas decimais, exemplo NUMERIC(10,3) igual ao formato: ppppppp.eee. Campo mdio. Tamanho varivel de caracteres ou tipo de string. O nome tambm pode apresentar : VARYING CHAR ou VARYING CHARACTER.
SMALLINT VARCHAR(n)
16 bits n Caracteres
170
Apndice C
Para comear, coloque em um novo formulrio um objeto tTable e um objeto tQuery. O objeto tTable efetuar a ligao com a tabela de Clientes (Tabela Customer), enquanto que o tQuery ir extrair os detalhes da encomenda (Tabelas Orders, Parts e Items) apropriados a cada cliente. Os dados esto em uma tabela Paradox, pelo que na propriedade DataBaseName colocado o nome do diretrio que contm os dados (ou defina o nome do Alias: DBDemos). A ligao completada atravs da definio das propriedades TableName e IndexName, e se alternarmos a propriedade Active para true vemos os dados reais, mesmo durante a fase de construo do formulrio. Se os registros contendo os detalhes dos pedidos estivessem todos em uma nica tabela, a juno poderia ser facilmente realizada pela definio das propriedades MasterSource e
171
Borland
MasterField de um segundo objeto tabela, mas, uma vez que necessitamos de dados de mais de uma tabela (Orders e Products), esta tcnica simples no funciona. O controle de consulta recupera um conjunto diferente de registros para cada cliente, extraindo dados das duas tabelas ligadas. O Delphi oferece duas tcnicas para fazer isto: Uma delas envolve o uso de variveis Calculadas para uma das trs tabelas em questo; uma outra (mais simples) envolve atribuio de um valor propriedade SQL do objeto tQuery, ou seja, uma instruo SQL apropriada. Neste exemplo, vamos fazer colocando algum cdigo no evento OnDataChange do objeto DataSource. Lembre-se que este evento chamado sempre que o registro corrente alterado. Insira a seguinte instruo na propriedade SQL do objeto tQuery:
SELECT Orders.OrderNo, Items.Qty, Parts.Description, Parts.ListPrice FROM Orders, Items, Parts WHERE Orders.OrderNo = Items.OrderNo AND Items.PartNo = Parts.PartNo AND Orders.CustNo = :CustNo;
Repare no cdigo SQL na varivel :CustNo, v para a propriedade Params do objeto tQuery e coloque para a varivel CustNo criada o Data type como Float, est varivel ser passada para o SQL atravs do evento OnDataChange do objeto DataSource, insira o seguinte cdigo:
procedure TForm1.DataSource2DataChange(Sender: TObject; Field: TField); begin Query1.Close; Query1.Params[0].AsFloat := Table1CustNo.Value; Query1.Open; end;
Relembrando no Delphi os dados fluem da base de dados para o formulrio na seguinte seqncia:
Base de Dados objeto DataSet (tTable ou tQuery) objeto DataSource objeto Campo
O objeto DataSource necessrio, pois os objetos de campo no podem ligar-se diretamente aos objetos do DataSet, mas apenas atravs de um objeto DataSource. Por conseguinte, para cada objeto DataSet tambm colocado no formulrio um objeto DataSource. Finalmente, so adicionados objetos de caixa de edio de texto, um objeto Grid para as linhas da encomenda e um objeto dbNavigator ligado a tabela de Customer, rode o projeto. objeto Grid est ligado ao objeto tQuery (atravs do objeto DataSource), ento este se atualiza automaticamente com os novos resultados das consultas.
172
Apndice D
Imprimindo um Formulrio
Para imprimir um formulrio no tem nenhum segredo, existe o comando PRINT relacionado a formulrios, o problema se inicia quando o formulrio ultrapassa as dimenses da tela do seu monitor, ou seja, a largura e altura dele maior que a tela. Digamos um formulrio qualquer que tenha a propriedade HorzScrollBar.Range = 768 e VertScrollBar.Range = 1008 (isto corresponde a uma folha de papel tamanho A4). O programa abaixo resolve exatamente este problema, imprimindo somente objetos: Tlabel, TEdit, TMemo, TDBText, TDBEdit e TDBMemo, utiliza a biblioteca Printers para fazer o servio, coloque um boto qualquer no formulrio que deseje imprimir e para o evento onClick, digite os seguintes comandos:
procedure Tform1.SpeedButton1Click(Sender: TObject); var C : array[0..255] of char; CLen, ScaleX, ScaleY, Ind : Integer; Format : Word; DC : HDC; MComp : Tmemo; R : TRect; begin Printer.BeginDoc; DC := Printer.Canvas.Handle; ScaleX := GetDeviceCaps(DC, LOGPIXELSX) div PixelsPerInch; ScaleY := GetDeviceCaps(DC, LOGPIXELSY) div PixelsPerInch; for Ind := 0 to ComponentCount -1 do if (Components[Ind] is TCustomLabel) or (Components[Ind] is TCustomEdit) then begin MComp := TMemo(Components[Ind]); if (MComp.visible) then begin Printer.Canvas.Font := MComp.Font; DC := Printer.Canvas.Handle; R := MComp.BoundsRect; R.Top := (R.Top + VertScrollBar.Position) * ScaleY; R.Left := (R.Left + HorzScrollBar.Position) * ScaleX; R.Bottom := (R.Bottom + VertScrollBar.Position) * ScaleY; R.Right := (R.Right + HorzScrollBar.Position) * ScaleY; if (not (Components[Ind] is TCustomLabel)) and (MComp.BorderStyle = bsSingle) then Printer.Canvas.Rectangle(R.Left, R.Top, R.Right, R.Bottom); Format := DT_LEFT; if (Components[Ind] is TEdit) or (Components[Ind] is TCustomMaskEdit) then Format := Format or DT_SINGLELINE or DT_VCENTER else
173
Borland
begin if MComp.WordWrap then Format := DT_WORDBREAK; if MComp.Alignment = taCenter then Format := Format or DT_CENTER; if MComp.Alignment = taRightJustify then Format := Format or DT_RIGHT; R.Bottom := R.Bottom + Printer.Canvas.Font.Height + 1; end; CLen := MComp.GetTextBuf(C,255); R.Left := R.Left + ScaleX + ScaleX; DrawText(DC, C, CLen, R, Format); end; end; Printer.EndDoc; Close; end;
Se voc conhece um pouco de Pascal 7.0 no acredito que voc teve dificuldades em interpretar o programa, se voc no conhece aqui vo algumas dicas: Inicialmente foi declarado uma srie de variveis que sero utilizadas posteriormente. E ento iniciado o objeto de impresso Printer atravs do comando:
Printer.BeginDoc;
O objeto imprime atravs de uma subclasse conhecida por Canvas. Esta classe e que torna possvel a criao de toda a interface grfica do Delphi (Este objeto parte de um encapsulamento da Windows HDC). Uma forma simples de se imprimir seria utilizar os seguintes comandos:
Printer.BeginDoc; Printer.Canvas.TextOut(0, 0, Est imprimindo...); Printer.EndDoc;
Mas, para se obter uma cpia fiel do formulrio preciso fazer mais do que isto, inicialmente e chamada a propriedade handle (esta faz uma chamada a Windows GDI chamando funes da API para requerer o modo de desenho dos objetos envolvidos), prximo passo verificar o tipo de escala (em pixels) da largura e altura da janela a ser impressa. Agora resta verificar objeto a objeto (do tipo Label ou do tipo Edit) e enviar suas caractersticas para os dados da classe Canvas e imprim-los. Lembre-se o padro de impresso do Windows emitir a listagem somente quando a mesma estiver completa e isto s acontecer no comando :
Printer.EndDoc;
Uma outra sada para a impresso de seus relatrios pode ser conseguida atravs da utilizao de inmeras bibliotecas prontas que fazem o acesso ao objeto TPrinter. Entre elas existem a ReportPrint (da Nevrona Designs) que pode ser adquirido uma verso de demonstrao atravs da internet atravs do seguinte endereo:
ftp.primenet.com/users/j/jgunkel /delphi/rprinter.zip
174
Apndice E
175
Borland
Exemplos de Mscaras:
Tipo Telefone CEP Hora Mscara !\(999\)000-0000;1;_ 00000\-9999;0;_ !90:00:00 >LL;0;_ Entrada 0613873350 73015020 100043PM Formatao (061)3873350 73015-020 10:00:43 PM Sada (061)387-3350 73015020 22:00:43
176
Apndice F
Caption Name
Propriedades
Caption Name
Propriedades
O maior trabalho da codificao ficaria por conta de criar janelas de Salvar e Abrir mas todo esse trabalho realizado pelos objetos OpenDialog e SaveDialog. O resto do cdigo bem simples vejamos: Para o evento OnClick do objeto ButExporta
177
Borland
procedure TForm1.ButExportaClick(Sender: TObject); var Arq: TextFile; begin if SaveDialog1.Execute then begin Screen.Cursor := crHourGlass; with Table1 do begin Open; First; if not EOF then begin AssignFile(Arq, SaveDialog1.FileName); ReWrite(Arq); repeat WriteLn(Arq,FieldByName('EmpNo').AsString + '|' + FieldByName('LastName').AsString + '|' + FieldByName('FirstName').AsString + '|' + FieldByName('PhoneExt').AsString + '|' + FieldByName('HireDate').AsString + '|' + FieldByName('Salary').AsString + '*'); next; until EOF; CloseFile(Arq); end; close; end; Screen.Cursor := crDefault; end; end;
Inicialmente vamos exportar o arquivo (no caso Employee), o funo do comando AssignFile e iniciar um objeto de arquivo texto (determinada pelo tipo de varivel TextFile) e o comando ReWrite prepara o objeto iniciado para a gravao. Lembre-se que um arquivo texto s pode receber logicamente texto definido pelos comandos Write (insere um texto em determinado arquivo e o cursor de gravao permanece na posio) e WriteLn (insere um texto em determinado arquivo e o cursor de gravao inicia uma nova linha) ento o nico trabalho ser de percorrer o nosso arquivo com o comando Repeat. Para o evento OnClick do objeto ButImporta
procedure TForm1.ButImportaClick(Sender: TObject); var Arq: TextFile; Texto: String; I: Integer; function MontaVariavel: String; var monta: String; begin monta := ''; inc(I);
178
Borland
while Texto[I] <> '*' do begin if Texto[I] = '|' then break; monta := monta + Texto[I]; inc(I); end; result := monta; end; begin if OpenDialog1.Execute then begin Screen.Cursor := crHourGlass; Table1.Open; AssignFile(Arq, OpenDialog1.FileName); Reset(Arq); if not EOF(Arq) then repeat ReadLn(Arq,Texto); with Table1 do begin Insert; i := 0; FieldByName('EmpNo').AsString := MontaVariavel; FieldByName('LastName').AsString := MontaVariavel; FieldByName('FirstName').AsString := MontaVariavel; FieldByName('PhoneExt').AsString := MontaVariavel; FieldByName('HireDate').AsString := MontaVariavel; FieldByName('Salary').AsString := MontaVariavel; Post; end; until EOF(Arq); CloseFile(Arq); Table1.Close; Screen.Cursor := crDefault; end; end;
Vamos agora importar o arquivo (no caso Employee), o funo do comando AssignFile e inicar um objeto de arquivo texto (determinada pelo tipo de varivel TextFile) e o comando Reset prepara o objeto iniciado para a gravao. Os comandos de leitura so Read (L um caractere de determinado arquivo) e ReadLn (L uma linha de determinado arquivo) ento o trabalho agora ser de separar em pedaos a linha lida isto realizado na funo MontaVariavel que ler pedaos demarcados do arquivo exportado.
179
Borland
Apndice G
180
Borland
6. Como chamar um outro programa (tipo o notepad do Windows ) a partir de um aplicativo (de trs maneiras diferentes: normal, maximizado e minimizado):
WinExec(C:\windows\notepad.exe, SW_SHOWNORMAL); WinExec(C:\windows\notepad.exe, SW_SHOWMAXIMIZED); WinExec(C:\windows\notepad.exe, SW_SHOWMINIMIZED);
181
Borland
182