Baixe o app para aproveitar ainda mais
Prévia do material em texto
Índice Analítico Introdução____________________________________________________________ 9 Agradecimentos ______________________________________________________________9 Objetivos ____________________________________________________________________9 Convenções__________________________________________________________________9 Parte I - Programação Visual e Linguagem ________________________________ 10 O que é o Delphi ? ___________________________________________________________10 Terminologia do Delphi ______________________________________________________11 1 Aplicativos e Projetos_________________________________________________ 12 1.1 Criando um Projeto ______________________________________________________12 1.2 Abrindo um Projeto ______________________________________________________12 1.3 Salvando um Projeto______________________________________________________12 1.4 Modificando um Projeto___________________________________________________12 1.5 Rodando Aplicativos______________________________________________________13 1.5.1 Compilando um Projeto ________________________________________________________13 1.5.2 Depurando um Projeto _________________________________________________________13 2 Formulários ________________________________________________________ 14 2.1 Criando um Formulário ___________________________________________________14 2.2 Adicionando um Formulário ao Projeto______________________________________14 2.3 Removendo um Formulário do Projeto ______________________________________14 2.4 Manipulando Formulários _________________________________________________14 3 Units ______________________________________________________________ 15 3.1 Criando uma Unit ________________________________________________________15 3.2 Adicionando uma Unit ao Projeto ___________________________________________15 3.3 Removendo uma Unit do Projeto____________________________________________15 3.4 Manipulando Units _______________________________________________________16 4 Componentes _______________________________________________________ 17 4.1 Adicionando Componentes a um Formulário _________________________________17 4.2 Removendo Componentes de um Formulário _________________________________17 4.3 Manipulando Componentes de um Formulário ________________________________17 4.4 Manipulando Propriedades e Eventos - Object Inspector _______________________19 5 O Repositório de Objetos e os Experts ___________________________________ 20 5.1 Personalizando o Repositório de Objetos _____________________________________21 5.1.1 Adicionando Modelos ao Repositório _____________________________________________21 5.1.2 Opções do Repositório _________________________________________________________21 6 A Linguagem Object Pascal ___________________________________________ 22 3 6.1 Tipos de Dados Pré-definidos ______________________________________________ 22 6.1.1 Tipos Ordinais _______________________________________________________________22 6.1.2 Tipos Reais__________________________________________________________________22 6.1.3 Tipos String _________________________________________________________________22 6.1.4 Tipo Variant_________________________________________________________________22 6.2 TypeCasting e Conversão de Tipos__________________________________________ 23 6.3 Tipos de Dados Definidos pelo Usuário ______________________________________ 23 6.4 Estilos de Codificação ____________________________________________________ 24 6.4.1 Comentários _________________________________________________________________24 6.4.2 Letras Maiúsculas e Minúsculas _________________________________________________24 6.4.3 Espaços em Branco ___________________________________________________________24 6.4.4 Destaque da Sintaxe___________________________________________________________24 6.5 Instruções Pascal ________________________________________________________ 25 6.5.1 Operadores __________________________________________________________________25 6.5.2 Instruções Simples e Compostas _________________________________________________26 6.5.3 Instruções Condicionais ________________________________________________________26 6.5.4 Loops ______________________________________________________________________26 6.6 Procedimentos e Funções__________________________________________________ 27 6.6.1 Parâmetros __________________________________________________________________28 6.6.2 Convenções de Chamadas ______________________________________________________29 6.6.3 Declarações _________________________________________________________________29 6.6.4 Tipos Procedurais_____________________________________________________________29 6.7 Classes e Objetos ________________________________________________________ 30 6.7.1 Construtores e Destrutores______________________________________________________30 6.7.2 Encapsulamento ______________________________________________________________31 6.7.3 Classes e Units _______________________________________________________________32 6.7.4 Escopo _____________________________________________________________________32 6.7.5 A Palavra-Chave Self__________________________________________________________32 6.7.6 Métodos Classe e Dados Classe__________________________________________________32 6.7.7 Ponteiro de Método ___________________________________________________________33 6.7.8 Referências a Classes__________________________________________________________33 6.7.9 Herdando de Tipos Existentes ___________________________________________________33 6.7.10 Métodos Virtuais e Dinâmicos__________________________________________________34 6.7.11 Manipuladores de Mensagens __________________________________________________35 6.7.12 Métodos Abstratos ___________________________________________________________35 6.7.13 Informações de Tipo em Tempo de Execução (RTTI) _______________________________35 6.7.14 Manipulando Exceções _______________________________________________________36 7 A Biblioteca de Componentes Visuais ____________________________________38 7.1 A Hierarquia da VCL ____________________________________________________ 38 7.1.1 Componentes ________________________________________________________________38 7.1.2 Objetos_____________________________________________________________________39 7.2 Usando Componentes e Objetos ____________________________________________ 39 7.3 Propriedades____________________________________________________________ 39 7.3.1 Propriedades Mais Comuns _____________________________________________________41 7.4 Métodos de Componentes _________________________________________________ 43 7.5 Eventos de Componentes__________________________________________________ 44 7.6 Usando Coleções Delphi___________________________________________________ 46 Parte II - Usando Componentes __________________________________________48 8 Uma Viagem Pelos Componentes Básicos ________________________________48 8.1 Seta do Mouse___________________________________________________________ 48 8.2 Botão (Button) __________________________________________________________ 48 8.3 Rótulo (Label) ___________________________________________________________49 8.4 Caixa de Diálogo Color (DialogColor) _______________________________________49 8.5 Caixa de Edição (Edit) ____________________________________________________50 8.6 Caixa de Edição com Máscara______________________________________________50 8.7 Memo __________________________________________________________________51 8.8 Caixa de Diálogo Font (FontDialog) _________________________________________52 8.9 RichEdit ________________________________________________________________53 8.10 Caixa de Verificação (CheckBox) __________________________________________54 8.11 Botão de Radio (RadioButton)_____________________________________________54 8.12 Caixa de Listagem (ListBox)______________________________________________54 8.13 Caixa Combinada (ComboBox)____________________________________________55 8.14 Barra de Rolagem (ScrollBar) _____________________________________________56 9 Criando e Manipulando Menus ________________________________________ 58 9.1 A Estrutura de um Menu __________________________________________________58 9.1.1 Diferentes Papeis dos Itens do Menu ______________________________________________58 9.2 Menu Principal (MainMenu) _______________________________________________58 9.2.1 Editando um Menu com o Menu Designer__________________________________________58 9.2.2 Observações _________________________________________________________________59 9.2.3 Respondendo a Comando de Menu _______________________________________________59 9.2.4 Mudando Menus em Tempo de Execução __________________________________________59 9.3 Menu Pop-Up (PopupMenu) _______________________________________________60 9.3.1 Criando Menus Pop-Up ________________________________________________________60 9.3.2 Manipulando Menus Pop-Up Automaticamente _____________________________________60 9.3.3 Manipulando Menus Pop-Up Manualmente ________________________________________61 9.4 Alterando o Menu de Sistema ______________________________________________61 10 De Volta ao Formulário _____________________________________________ 63 10.1 Formulários Versus Janelas_______________________________________________63 10.2 Janelas Sobrepostas, Pop-Up e Filhas _______________________________________63 10.3 O Aplicativo é uma Janela ________________________________________________63 10.4 Definindo Estilos e Comportamentos de Formulários__________________________64 10.4.1 O Estilo do Formulário________________________________________________________64 10.4.2 O Estilo da Borda ____________________________________________________________64 10.5 Os Ícones da Borda ______________________________________________________64 10.6 Configurando Mais Estilos de Janelas ______________________________________65 10.7 Formulários em Diferentes Resoluções de Tela _______________________________65 10.7.1 Graduação Manual do Formulário _______________________________________________66 10.7.2 Graduação Automática do Formulário ____________________________________________66 10.8 Definindo a Posição e o Tamanho do Formulário _____________________________66 10.8.1 Propriedade Position _________________________________________________________66 10.8.2 Propriedade WindowState _____________________________________________________66 10.9 O Tamanho de um Formulário e sua Área Cliente ____________________________67 10.10 O Tamanho Máximo e Mínimo de um Formulário ___________________________67 10.11 Criação Automática dos Formulários ______________________________________68 10.12 Fechando um Formulário________________________________________________69 5 10.13 Recebendo Entrada do Mouse ___________________________________________ 69 10.13.1 O Papel dos Botões do Mouse _________________________________________________69 10.13.2 Usando o Windows sem um Mouse_____________________________________________69 10.14 Desenhando no Formulário______________________________________________ 70 10.14.1 As Ferramentas de Desenho___________________________________________________70 10.14.2 Desenhando Formas_________________________________________________________70 10.15 Desenhando e Pintando no Windows ______________________________________ 71 10.15.1 Pintando uma Única Forma ___________________________________________________71 10.15.2 Pintando uma Série de Formas_________________________________________________72 11 Componentes Gráficos _______________________________________________74 11.1 O Botão de Bitmap (BitBtn) ______________________________________________ 74 11.1.1 Muitas Imagens em um Bitmap _________________________________________________74 11.2 O Image_______________________________________________________________ 75 11.3 Desenhando em um Bitmap_______________________________________________ 75 11.4 Outline________________________________________________________________ 75 11.5 ImageList _____________________________________________________________ 76 11.6 TreeView ______________________________________________________________ 77 11.7 ListView ______________________________________________________________ 77 11.8 Construindo Grades (Tabelas) ____________________________________________ 79 11.8.1 StringGrid e DrawGrid _______________________________________________________79 11.8.2 ColorGrid __________________________________________________________________79 12 Uma Barra de Ferramentas e uma Barra de Status ________________________80 12.1 Agrupando Controles com o Painel ________________________________________ 80 12.2 SpeedButton ___________________________________________________________ 80 12.3 Criando uma Barra de Ferramentas _______________________________________ 81 12.3.1 Adicionando Dicas à Barra de Ferramentas (Hint) __________________________________81 12.4 Criando uma Barra de Status _____________________________________________ 81 12.4.1 Adicionando Dicas à Barra de Status_____________________________________________82 13 Formulários Múltiplos e Caixas de Diálogo ______________________________83 13.1 Caixas de Diálogo Versus Formulários _____________________________________ 83 13.2 Adicionando um Segundo Formulário a um Programa ________________________ 83 13.3 Formulários Modais e Não-Modais ________________________________________ 84 13.4 Mesclando Menus de Formulários _________________________________________ 84 13.5 Criando uma Caixa de Diálogo____________________________________________ 85 13.6 Usando Caixas de Diálogo Pré-definidas ____________________________________ 85 13.6.1 Caixas de Diálogo Comuns do Windows _________________________________________85 13.6.2 Caixas de Mensagem e de Entrada_______________________________________________86 13.7 Herança Visual de Formulários ___________________________________________ 86 13.7.1 Herdando de um Formulário-Base_______________________________________________86 14 Rolagem e Formulários Multipáginas___________________________________89 14.1 Rolando um Formulário _________________________________________________ 89 14.2 Criando Fichários_______________________________________________________ 89 14.2.1 TabControl, PageControl e TabSheet ____________________________________________89 14.2.2 Abas sem Páginas e Páginas sem Abas ___________________________________________90 15 Dividindo Janelas __________________________________________________ 91 15.1 Técnicas de Divisão de Formulários ________________________________________91 15.2 Dividindo com um Cabeçalho (HeaderControl)_______________________________91 16 Criando Aplicativos MDI_____________________________________________ 93 16.1 Janelas-Filhas e Janelas de Moldura________________________________________93 16.2 Criando um Menu Janela Completo ________________________________________94 16.3 Montando uma Janela Filha ______________________________________________94 17 Utilizando Controles OLE ____________________________________________ 95 17.1 Controles OLE Versus Componentes Delphi _________________________________95 17.2 Instalando um Novo Controle OLE_________________________________________95 17.3 Utilizando Controles OLE ________________________________________________96 18 Criando Aplicativos de Bancos de Dados ________________________________ 98 18.1 Acesso a Bancos de Dados ________________________________________________98 18.2 Componentes de Bancos de Dados__________________________________________99 18.2.1 DataSource _________________________________________________________________99 18.2.2 Data Sets__________________________________________________________________100 18.2.3 Outros Componentes de Acesso a Dados_________________________________________10018.2.4 Componentes Relativos a Dados _______________________________________________100 18.3 Acessando os Campos de uma Tabela ou Query _____________________________101 18.4 Usando Campos para Manipular uma Tabela _______________________________102 18.4.1 Procurando Registros em uma Tabela ___________________________________________102 18.4.2 Atualizando Registros em uma Tabela___________________________________________102 18.5 Criando um Formulário Mestre-Detalhe com o Form Expert __________________102 18.6 Caixas Combinadas Relativas a Dados _____________________________________103 7 Introdução Agradecimentos Meus agradecimentos são destinados ao meu amigo de graduação Bruno de P. Ribeiro, por meio de quem eu tive conhecimento desta atividade de iniciação científica, à minha orientadora Vera M. B. Werneck por ter me dado a oportunidade de adquirir novos conhecimentos ao participar de atividades de pesquisa, aos outros participantes do grupo pela cooperação e complementação das minhas tarefas e, finalmente, àqueles que de alguma forma apoiaram nosso trabalho, dentre os quais, o professor Gustavo J. M. Hajdu. Objetivos Esta apostila é baseada no Livro Dominando o Delphi 2 para Windows 95 / NT “A Bíblia”, do escritor Marco Cantù e, de um modo geral, segue a mesma ordem de apresentação dos assuntos. O Help on-line do aplicativo foi um dos recursos secundários utilizados para um maior detalhamento de certos tópicos. O objetivo deste material é fornecer o conhecimento necessário a respeito da ferramenta Delphi 2.0 ao grupo de iniciação científica “Engenharia de Software para Sistemas Baseados em Conhecimento” da Universidade do Estado do Rio de Janeiro, orientado pela professora Vera M. B. Werneck e do qual faço parte deste agosto de 1997 na condição de bolsista. São requisitos para um bom aproveitamento da apostila o conhecimento por parte do leitor da linguagem Pascal e de conceitos de Orientação a Objetos, já que o texto se concentra na implementação desse recurso e não na sua teoria. Convenções • Identificadores usados em linguagem de programação e exemplos de programas aparecem em uma fonte diferente da usada no resto do texto. • Ao citar um comando efetuado através de um menu, é utilizada a notação NomeDoMenu / ÍtemDoMenu. Significa que o menu NomeDoMenu deve ser aberto e a opção ÍtemDoMenu escolhida. O mesmo vale para menus com maior número de níveis (NomeDoMenu / ÍtemDoMenu / Sub-ítemDoMenu / ...) . Rio de Janeiro, 4 de fevereiro de 1998 Autor: Luiz Reuter Silva Torro e-mail: luiz_t@hotmail.com 9 Parte I - Programação Visual e Linguagem Nesta parte será apresentado o ambiente, e dada uma visão geral da linguagem Object Pascal e da Biblioteca de Componentes Visuais. O que é o Delphi ? O Delphi é um ambiente de desenvolvimento de softwares com as seguintes características: 1. Visual: A definição da interface e até mesmo de parte da estrutura de um aplicativo Delphi pode ser realizada com o auxílio de ferramentas visuais. Por exemplo, uma tela é criada com um simples clique e um botão, selecionando esta imagem em uma barra de ferramentas e clicando sobre a tela onde ele deve aparecer. 2. Orientada a Objeto: Os conceitos de classe, herança e polimorfismo são abarcados pela linguagem de programação do Delphi, o Object Pascal. Esta não é, no entanto, uma linguagem puramente orientada a objeto como Smalltalk e Eiffel. 3. Orientada a Eventos: Cada elemento de uma interface de aplicativo é capaz de capturar e associar ações a uma série de eventos (caracter teclado, clique do mouse, ...). 4. Compilada: A geração de código em linguagem de máquina acelera a execução dos aplicativos. Terminologia do Delphi Alguns termos utilizados no ambiente Delphi: • Expert: Gerador de código baseado em perguntas feitas ao desenvolvedor. Os ícones que invocam Experts costumam apresentar uma lâmpada para diferenciá-los Figura 1- A Expert . • Hint: Uma dica, que aparece dentro de um retângulo, a respeito do objeto sobre o qual o mouse é posicionado. Figura 1-B: Hint. • SpeedBar (ou barra de ferramentas): Conjunto de ícones posicionados no topo da tela com funções equivalentes às de alguns itens dos menus. Figura 1-C Janela do Delphi 2.0 (barra de título, barra de menus e speedbar). Figura 1-D Speedmenu de um formulário. • SpeedMenu (ou menu de atalho): Menu reduzido que surge quando se clica um objeto com o botão secundário do mouse. 11 1 Aplicativos e Projetos Um aplicativo Delphi é criado a partir de um projeto, que engloba: • um arquivo de projeto (.dpr) responsável pela unidade do projeto - lista todos os elementos de um projeto e possui o código de inicialização; • arquivo(s) de formulário (.dfm) com as informações gráficas do aplicativo. Cada arquivo de formulário possui uma unit (descrita abaixo) associada; • unit(s) - arquivo(s) de código Object Pascal (.pas) com as ações do aplicativo. Podem estar associadas ou não a formulários. Outros tipos de arquivos utilizados no ambiente Delphi têm as extensões: • bmp, ico: arquivos gráficos; • dcu: unit Delphi compilada; • ~df: backup de formulário gráfico; • dof: arquivo de opções do Delphi; • ~dp: backup do projeto; • dsk: configurações de desktop (posicionamento de janelas, ...); • dsm: dados do object browser; • exe: arquivo executável compilado; • ~pa: backup de unit; • res: arquivo de recursos compilados (ícone do projeto, ...). 1.1 Criando um Projeto Ao iniciar o Delphi, é fornecido um projeto em branco. Se outro projeto estiver aberto, um novo poderá ser criado selecionando o menu File / New Application: 1.2 Abrindo um Projeto Selecione o menu File / Open e localize o arquivo do projeto desejado (.dpr). 1.3 Salvando um Projeto Selecione o menu File / Save Project As. Será pedido um nome para cada unit e para o arquivo de projeto. 1.4 Modificando um Projeto Selecione o menu View / Project Manager. Esta janela permite a alteração das propriedades do projeto, como a inclusão e remoção de units, alteração do nome do aplicativo e definição dos formulários exibidos quando o programa é iniciado. A alteração de algumas das opções iniciais gera um arquivo com a extensão dof contendo as novas definições. O código do arquivo de projeto (.dpr), que pode ser visto com o comando View / Project Source, costuma servir apenas para iniciar o programa que executa a janela principal do aplicativo. 1.5 Rodando Aplicativos 1.5.1 Compilando um Projeto Para gerar o executável de um projeto basta selecionar o menu Project / Compile. Após a compilação de cada uma das units em arquivos de código objeto (.dcu), elas são associadas com códigos da biblioteca visual do Delphi (VCL) para formar o aplicativo. 1.5.2 Depurando um Projeto Um projeto será executado no depurador integrado sempre que ele for rodado a partir do Delphi com o comando Run / Run. 13 2 Formulários Dentro do Delphi, as janelas são referenciadas como formulários e contêm objetos de interface com o usuário. Figura 1-A Formulário recém-criado. 2.1 Criando um Formulário Quando um projeto é criado, ele já fornece um formulário em branco. Para criar outros formulários, selecione o menu File / New Form. Cada formulário criado no projeto virá acompanhado de uma unit associada. 2.2 Adicionando um Formulário ao Projeto Pode-se reaproveitar formulários prontos em um projeto sem a necessidade de criá-los novamente. Para adicionar um formulário existente a um projeto, selecione o menu File / Add to Project e localize a unit associada ao formulário desejado. Quando se adiciona um formulário a um projeto, não é feita uma cópia, e sim uma referência ao original. Portanto, quaisquer alterações realizadas se refletirão em todos os projetos que utilizem o formulário.2.3 Removendo um Formulário do Projeto Selecione o menu File / Remove from Project e escolha o formulário (e sua unit associada) a ser removido na lista dos componentes do projeto que é exibida. A remoção do componente de um projeto não acarreta a sua exclusão, os arquivos apenas deixam de ser considerados pelo projeto. 2.4 Manipulando Formulários Use a lista de formulários do menu View / Forms para localizar e visualizar os formulários. Já a unit associada ao formulário pode ser vista com o comando View / Toggle Form/Unit, e vice-versa. 3 Units As units são a base da modularidade da linguagem e servem para definir classes, rotinas e elementos visuais. São compostas pelas seções: 1) Interface: Declara os elementos que são visíveis para outras units: rotinas, variáveis globais, tipos de dados, etc. A cláusula uses no início da seção interface indica quais outras units precisamos acessar dentro desta seção. 2) Implementation: Contém o código real e outras declarações. A cláusula uses no início da seção implementation indica quais outras units precisamos acessar dentro desta seção. 3) Initialization (opcional): Contém o código a ser executado quando o programa que usa a unit é carregado para a memória. 4) Finalization: (opcional): Contém o código a ser executado quando o programa que usa a unit é descarregado da memória. Figura 2-A Código padrão de uma unit. 3.1 Criando uma Unit Cada formulário inserido no projeto virá acompanhado de uma unit; o inverso, porém, não é verdadeiro. Para criar uma unit desvinculada de um formulário, selecione o menu File / New; na página New da caixa de diálogo apresentada, escolha o ícone Unit. 3.2 Adicionando uma Unit ao Projeto Pode-se reaproveitar units prontas em um projeto sem a necessidade de criá-las novamente. Para adicionar uma unit existente a um projeto, selecione o menu File / Add to Project e localize a unit desejada. Quando se adiciona uma unit a um projeto, não é feita uma cópia, e sim uma referência à original. Portanto, quaisquer alterações realizadas se refletirão em todos os projetos que utilizem a unit. 3.3 Removendo uma Unit do Projeto Selecione o menu File / Remove from Project e escolha a unit a ser removida na lista dos componentes do projeto que é exibida. 15 A remoção do componente de um projeto não acarreta a sua exclusão, os arquivos apenas deixam de ser considerados pelo projeto. 3.4 Manipulando Units Use a lista de units do menu View / Units para localizar e visualizar as units. 4 Componentes Os componentes são as classes básicas sobre as quais são construídos aplicativos Delphi. Alguns exemplos de componentes são: • Botões • Barras de Rolagem • Caixas de Listagem • Caixas de Texto • Legendas Um formulário pode conter uma série de componentes de forma a criar uma interface para o usuário com botões, menus, etc. Figura 4-A Formulário com alguns componentes. Os componentes são divididos em categorias como Standard, Data Access, ..., de acordo com suas funções e ficam na palheta de componentes posicionada no alto tela. Para ver os componentes de uma categoria selecione a página correspondente na palheta. Figura 4-B Palheta de componentes com a página Standard selecionada. 4.1 Adicionando Componentes a um Formulário Selecione o componente desejado na palheta de componentes e clique no local do formulário onde o componente deve ser posicionado. 4.2 Removendo Componentes de um Formulário Selecione o componente a ser removido e selecione o menu Edit / Delete. 4.3 Manipulando Componentes de um Formulário Em tempo de projeto um componente pode ser reposicionado arrastando-o para uma nova posição, ou pode ter seu tamanho alterado selecionando-o com um clique e arrastando os controladores de tamanho que surgem ao seu redor. A Paleta de Alinhamento (menu View / Alignment Palette) auxilia no posicionamento relativo dos componentes. A ordem de tabulação1 pode ser alterada através do menu Edit / Tab Order. 1 A ordem em que os componentes são acessados quando o usuário tecla <Tab>. 17 Um formulário pode ser reaproveitado adicionando-o ao repositório com o SpeedMenu Add to Repository. 4.4 Manipulando Propriedades e Eventos - Object Inspector Selecione o menu View / Object Inspector para abrir a janela do Object Inspector. Ele permite a visualização e a alteração das propriedades e das respostas a eventos do componente selecionado. A seleção de um componente é feita clicando-se sobre o mesmo ou selecionando seu nome na caixa de opções do Object Inspector. Figura 4-C Object Inspector exibindo as propriedades do formulário Form1 Para alterar uma propriedade, basta selecioná-la e digitar um novo valor. Em alguns casos o valor deve ser escolhido em uma lista drop-down2 que aparece ao lado da propriedade selecionada. Em outros, aparece um sinal de adição à frente da propriedade, indicando a existência de sub-propriedades. Você pode dar um duplo-clique sobre o sinal para exibi-las e alterá-las. Há, ainda, um outro caso, em que surge um pequeno botão com reticências. Você deve, então, dar um duplo-clique na área branca da propriedade para abrir uma caixa de diálogo. No caso dos eventos, após selecioná-lo, pode-se escolher um procedimento existente na lista drop-down ao lado do evento, ou dar um duplo-clique na área branca para criar o procedimento padrão do evento. 2 Lista de opções que surge quando se clica uma caixa combinada ou um menu. 19 5 O Repositório de Objetos e os Experts Um outro modo de se criar objetos é através do Repositório de Objetos, composto por modelos de objetos pré-definidos ou definidos pelo usuário, e dos Experts, que guiam o processo de criação através de janelas de diálogo. O Repositório de Objetos permite a reutilização de objetos utilizando modelos prontos como ponto de partida. A reutilização compreende 3 possibilidades: 1. Copiar: Duplica o objeto original - alterações na cópia não alteram o original. 2. Herdar: Herda as características do objeto original e mantém um vinculo - alterações no original são refletidas no novo objeto. 3. Usar: Referencia o objeto original - alterações (em tempo de projeto) no objeto inserido são refletidas no objeto original . Para criar um objeto com o Repositório de Objetos, selecione o menu File / New. Surge a caixa de diálogo mostrada abaixo, com as seguintes páginas: Figura 5-A Página New do Repositório de Objetos. 6. New: Cria objetos, em alguns casos com a participação de um Expert. Exemplos: Aplication: Projeto em branco. Automation Object: Cria um objeto OLE através do Automation Object Expert. Component: Cria um componente através do Component Expert. Data Module: Módulo de dados em branco. DLL: DLL em branco Form: Formulário em branco. Text: Arquivo texto ASCII em branco. 7. “Projeto Atual”: Herda um dos formulários ou uma das units do projeto atual. 8. Forms: Insere um tipo pré-definido de formulário no projeto. Exemplos: About Box: “Caixa Sobre ...”. Database Form: Cria um formulário de interface para banco de dados através do Database form Expert. Dual list box: Formulário dotado de duas caixas de listas e de botões que permitem a transferência de elementos de uma caixa para a outra. QuickReport Labels: Formulário de relatório. QuickReport List: Formulário de relatório. QuickReport Master/Detail: Formulário de relatório de estrutura mais complexa. Tabbed pages: Formulário baseado em páginas. 9. Dialogs: Insere caixas de diálogo, que são formulários com alguns atributos especiais, como o tipo da borda. Exemplos: Dialog Expert: Expert gerador de caixas de diálogos com uma ou múltiplas páginas. Dialog with help (1): Caixa de diálogo combotão de ajuda na parte inferior. Dialog with help (2): Caixa de diálogo com botão de ajuda no lado direito. Password dialog: Caixa de diálogo com uma caixa de edição simples para a digitação de senha. Standard dialog (1): Caixa de diálogo com botões na parte inferior. Standard dialog (2): Caixa de diálogo com botões no lado direito. 10. Data Modules: Insere um modulo de dados, que pode ser utilizado para o armazenamento de componentes não visuais. 11. Projects: Inicia um projeto. Exemplos: Application Expert: Expert que permite opções sobre a estrutura do arquivo e alguns outros elementos da aplicação. MDI Application: Define os elementos principais de uma aplicação MDI (Multiple Document Interface) - formulário principal com menu, barra de status e de ferramentas e um componente para a criação de janelas filhas. SDI Aplication: Define os elementos principais de uma aplicação SDI (Single Document Interface). Win95 Logo Application: Basicamente uma aplicação SDI com um componente RichEdit e código para a manipulação de correio eletrônico. 5.1 Personalizando o Repositório de Objetos 5.1.1 Adicionando Modelos ao Repositório As páginas do Repositório podem ser personalizadas adicionando Experts e modelos. Para adicionar um projeto ao Repositório, ative o comando Add to Repository do Menu Project; para adicionar um formulário, ative o comando Add to Repository do seu SpeedMenu. Em ambos os casos, surgirá uma caixa de diálogo com espaços para o título, a descrição, a página do Repositório e o ícone do novo modelo. 5.1.2 Opções do Repositório O comando Tools / Repository dá acesso à tela de opções do Repositório. Nela é possível incluir, excluir, renomear e alterar o posicionamento das páginas onde os modelos e Experts são armazenados com a auxílio dos botões e setas ao redor da lista de páginas. A lista de modelos oferece as opções de edição e exclusão. Também é possível tornar um modelo o padrão de criação marcando a caixa de verificação New Form (ou New Project). No caso de formulários, pode-se tornar um modelo o formulário padrão de novos projetos marcando a caixa de verificação Main Form. 21 6 A Linguagem Object Pascal Como esta apostila pressupõe por parte do leitor uma certa familiaridade com a Linguagem Pascal, que é um subconjunto da Object Pascal, suas características principais serão citadas sucintamente. Uma referência mais minuciosa pode ser obtida no Guia de Referência e no Help on-line da linguagem. 6.1 Tipos de Dados Pré-definidos Há três grupos principais: ordinais, reais e strings. 6.1.1 Tipos Ordinais Tipo Propósito Integer, ShortInt, SmallInt, Longint Inteiros com sinal Byte, Word, Cardinal Inteiros sem sinal Boolean, ByteBool, WordBool, LongBool Booleanos Char ANSIChar WideChar Caractere de 8 bits Caractere de 8 bits Caractere de 16 bits (Unicode) Tabela 6.1-A 6.1.2 Tipos Reais Tipo Propósito Single, Real, Double, Extended Números reais Comp Números inteiros muito longos Currency Números reais com 4 dígitos decimais Tabela 6.1-B 6.1.3 Tipos String Tipo Propósito ShortString Tamanho máximo de 255 caracteres String, ANSIString Tamanho “ilimitado” Tabela 6.1-C 6.1.4 Tipo Variant O tipo de dado variant tem checagem de tipo em tempo de execução, e foi introduzido na linguagem para suportar automação OLE (Object Linking and Embedding). No entanto, uma variável deste tipo pode ser usada para armazenar qualquer tipo de dado. 6.2 TypeCasting e Conversão de Tipos A notação de typecasting se assemelha à chamada de uma função, cujo argumento é o valor original. var n: integer; c: char; b: boolean; ... begin n := integer (‘x’); c: = char (n); b := boolean (0); end; As rotinas de conversão de tipo estão listadas abaixo: Rotina Converte chr Número ordinal em caracter ord Valor ordinal no número que indica sua ordem round Valor real em inteiro, arredondando trunc Valor real em inteiro, truncando inttostr Número em string inttohex Número em string com representação hexadecimal strtoint String em número, suscitando uma exceção se a string não estiver correta strtointdef String em número, usando um valor padrão se a string não estiver correta val String em número str Número em string, usando parâmetros de formatação strpas String terminada em nulo em string estilo Pascal strpcopy String estilo Pascal em string terminada em nulo strplcopy Parte de uma string estilo Pascal em string terminada em nulo 6.3 Tipos de Dados Definidos pelo Usuário Novos tipos de dados são definidos na seção Type do programa empregando os construtores de tipos: Faixas Secundárias: Faixa de valores dentro da faixa de outro tipo. Exemplo: Type Maiúsculas = ‘A’..’Z’; Enumerações: Lista de valores na ordem desejada. Exemplo: Type Cores = (Vermelho, Verde, Azul); Conjuntos: Conjunto de valores do tipo definido. Exemplo: Type Letras = Set Of Maiúsculas; Matrizes: Número fixo de elementos de um tipo específico. Exemplo: Type TemperaturasDia = Array [1..24] of integer; Registros: Coleção fixa de elementos de diferentes tipos, os campos. Exemplo: Type Data = Record Ano: integer; Mês: Byte; 23 Dia: Byte; end; Indicadores ou Ponteiros: Define uma variável que mantém o endereço de memória de outra variável de certo tipo de dados. Exemplo: Type PonteiroInt = ^integer; Arquivos: Relacionados à entrada / saída. Exemplo: Type IntFile = File Of integer; 6.4 Estilos de Codificação 6.4.1 Comentários Tipo Propósito // <comentário> Comentário “até o fim da linha” { <comentário> } Comentário entre as chaves (* <comentário> *) Comentário entre o grupo “parênteses / asterisco” Tabela 6.4-A É possível aninhar comentários de tipos diferentes. Os dois últimos esquemas de comentários também são empregados na construção de diretivas de compilação, tais como {$X+}. 6.4.2 Letras Maiúsculas e Minúsculas O compilador Pascal não distingue entre letras maiúsculas e minúsculas nos identificadores. Desta forma, MeuIdentificador e meuidentificador são equivalentes. 6.4.3 Espaços em Branco Os espaços, tabulações e caracteres de novas linhas, coletivamente conhecidos como espaços em branco, são ignorados pelo compilador, mesmo dentro de um comando já que o separador utilizado pelo compilador é o ponto-e-vírgula. 6.4.4 Destaque da Sintaxe O Destaque em Cores da Sintaxe presente no editor Delphi utiliza formatos e cores diferentes para exibir as palavras digitadas. Por padrão, as palavras chaves estão em negrito, as strings e os comentários estão em cores e assim por diante. Você pode personalizar o destaque da sintaxe usando a página Colors do comando Tools / Options. 6.5 Instruções Pascal 6.5.1 Operadores Estes são os grupos de operadores em ordem decrescente de precedência: Unários Operador Propósito @ Endereço de (retorna um ponteiro) not “Não” booleano ou bit-a-bit Tabela 6.5-A Operadores Multiplicativos e de type casting Operador Propósito * Multiplicação aritmética ou interseção de conjuntos / Divisão real div Divisão inteira mod Resto da divisão de números inteiros as Typecast seguro and “E” booleano e bit-a-bit shl Deslocamento de bits à esquerda shr Deslocamento de bits à direita Tabela 6.5-B Operadores Aditivos Operador Propósito + Adição, união de conjuntos, concatenação de strings, valor positivo, ou adição de compensação (offset) - Subtração, diferença de conjuntos, valor negativo, ou subtração de compensação (offset) or “Ou” booleano ou bit-a-bit xor “Ou exclusivo” booleano ou bit-a-bit Tabela 6.5-C Operadores Relacionais, de Pertinência de Conjunto e de Comparação de tipo Operador Propósito = Testar se é igual <> Testar se é diferente < Testar se é menor que > Testar se é maior que <= Testar se é menor ou igual que, ou se é subconjunto de um conjunto >= Testar seé maior ou igual que, ou se é superconjunto de um conjunto in Testar se é membro de um conjunto is Testar se o tipo é compatível 25 Tabela 6.5-D 6.5.2 Instruções Simples e Compostas As instruções simples são separadas por ponto-e-vírgula. x := y + z; Randomize; As instruções compostas são instruções delimitadas pelo par begin e end. begin x := y + z; Randomize; end; 6.5.3 Instruções Condicionais 1) Instruções If: Podem ser usadas as sintaxes if-then e if-then-else. if (a < b) then a := a + 1; if (a < b) then a := a + 100 else c := a; 2) Instruções Case: Podem ser usadas com e sem o else. case Numero of 1: Texto := ‘Um’; 2: Texto := ‘Dois’; 3: Texto := ‘Três’; end; case Numero of 1..3: Texto := ‘Um’; 4..6: Texto := ‘Dois’; else Texto := ‘Maior que 6’; end; Por padrão, a linguagem Object Pascal realiza a avaliação de curto-circuito de expressões booleanas. Isto significa que assim que o resultado da expressão puder ser determinado, para-se de avaliar a expressão. Este comportamento pode ser alterado com a opção Complete boolean eval na página Compiler do menu Project / Options. 6.5.4 Loops 1) Instruções For: Podem incrementar ou decrementar a variável. for i := 1 To 10 do k := k + 1; for i := 10 DownTo 5 do k := k + 2; 2) Instruções While e Repeat: A instrução Repeat é sempre executada pelo menos uma vez, o que nem sempre ocorre com a instrução While. while i < 100 do i := i * 2; repeat i := i * 2; until i >= 100; Dentro de um loop, o procedimento Break interrompe as iterações e seguem para a próxima instrução do programa; já o procedimento Continue desvia a execução para o início da próxima iteração. 3) Instruções With: Simplifica a referência a subitens de uma estrutura. Ao invés de acessar propriedades desta forma Form1.canvas.pen.width := 2; Form1.canvas.pen.color := clRead; Podemos escrever with Form1.Canvas.Pen do begin width := 2; color := clRead; end; 6.6 Procedimentos e Funções Ao contrário dos procedimentos, as funções retornam um valor, definido através da sua atribuição ao identificador da função ou, alternativamente, à palavra-chave result. Esta atribuição pode aparecer um número qualquer de vezes dentro da rotina (dentro de if e else, etc.). Definição: procedure Alo (s : String); begin ShowMessage (‘Alo ’ + s); end; Chamada: Alo (‘você !’); Resultado: Alo você ! Definição: function Dobro (i : integer) : integer; begin 27 Dobro := i * 2; //ou Result := i * 2; end; Chamada: Result := Dobro (250); Resultado: Result := 500; 6.6.1 Parâmetros O compilador assume que os parâmetros são passados por valor, a menos que seja usada a palavra- chave var. Definição: procedure Dobro (var i : integer); begin i := i * 2; end; Chamada: Dobro (Valor); A palavra-chave Const impede a alteração de um parâmetro dentro de uma rotina gerando um erro caso você tente compilar um código que altere o valor do parâmetro constante. function Dobro (Const i : integer) : integer; begin Dobro := i * 2; end; O recurso da matriz aberta é a forma de passar uma quantidade variável de parâmetros. Basta definir uma matriz sem índices. As funções Low, High e SizeOf fornecem os valores necessários à manipulação da matriz. Definição: procedure Clear (var A: Array of Double); var i: integer; begin for i := 0 to High (A) do A [i] := 0; end; Chamada: var List1 : Array [0..3] of Double; begin Clear (List1); end; 6.6.2 Convenções de Chamadas A convenção padrão na passagem de parâmetros do Delphi 2 é a fastcall, que não é compatível com a API do Windows; as funções da API do Windows devem ser declaradas solicitando-se a utilizando da convenção padrão do Pascal com a palavra-chave stdcall antes da declaração da função. 6.6.3 Declarações 1) Declarações Forward: Disponibiliza o protótipo de uma rotina antes da sua definição completa. procedure Ola; Forward; procedure OlaDuplo; begin Ola; Ola; end; Procedure Ola; begin ShowMessage (‘Ola mundo !’); end; 2) Declarações External: Possibilitam a vinculação de rotinas externas escritas em assembly ou localizadas em DLLs. function GetMode: Word; external; function LineTo; external; ‘gdi32’ name ‘LineTo’; 6.6.4 Tipos Procedurais Você pode declarar variáveis de tipos procedurais e passá-las como argumentos para rotinas. A declaração de um tipo procedural indica a lista dos parâmetros (ou apenas os tipos dos parâmetros). Type IntProc = procedure (var Num: integer); procedure DobraValor (var Valor: integer); begin Valor := Valor * 2; end; var IP: IntProc; X: integer; begin IP := DobraValor; X := 5; IP (X); end; 29 6.7 Classes e Objetos O Delphi, assim como a linguagem Eiffel, trabalha com o modelo de referência de objetos, no qual uma variável objeto é um ponteiro para o objeto real. É preciso chamar um método construtor (create é o construtor padrão) para gerar uma instância real do objeto na memória. A definição de uma classe é feita com a palavra-chave class. Definição da classe Data: type Data = class //isto equivale a Data = class (TObject) Dia, Mes, Ano: integer; //campos procedure DefVal (m, d, a: integer); //métodos function AnoBis: Boolean; end; Para indicar que um método pertence a uma classe, usa-se a notação [Nome da Classe].[Método]: procedure Data.DefVal (m, d, a: integer); begin Mes := m; Dia := d; Ano := a; end; function Data.AnoBis: Boolean; begin if (Ano mod 4 <> 0) then AnoBis := False else if (Ano mod 100 <> 0) then AnoBis := True else if (Ano mod 400 <> 0) then AnoBis := False else AnoBis := True; end; Utilização de um objeto da classe Data: var Dia: Data; Bis: Boolean; begin ... Dia := Data.Create; //cria uma instância de objeto Dia.DefVal (10, 10, 1994); //chama métodos do objeto Bis := Dia.AnoBis; ... Dia.Free //destrói o objeto end; 6.7.1 Construtores e Destrutores Construtores e destrutores são rotinas especiais que alocam e liberam memória para objetos automaticamente. Elas são declaradas com as palavras-chave constructor e destructor respectivamente; Todas as classes que criamos herdam o método construtor create e o destrutor destroy, porém podemos definir versões personalizadas de construtores e destrutores que realizem outras tarefas além de criar e destruir objetos, como inicializar o objeto e liberar recursos. A destruição de um objeto que não teve seu destrutor redefinido deve ser feita indiretamente com o método free e não com o método destroy. Definição da classe Data com o construtor personalizado Init: type Data = class //campos Dia, Mes, Ano: integer; constructor Init (d, m, a, integer); //construtor procedure DefVal (m, d, a: integer); //métodos function AnoBis: Boolean; end; constructor Data.Init (m, d, a: integer); begin Mes := m; Dia := d; Ano := a; end; Com o novo construtor, a criação e inicialização do objeto ocorrem de uma só vez: var Dia: Data; Bis: Boolean; begin ... Dia := Data.Init (10, 10, 1994); //cria e inicializa ... Dia.Free; //destrói o objeto end; 6.7.2 Encapsulamento Há duas construções envolvidas no encapsulamento: classes e units. Os especificadores de acesso associadas às classes são: 1) Private: Denota componentes acessíveis somente dentro da unit onde é definida a classe. 2) Public: Denota componentes acessíveis a todo o programa. 3) Protected: Denota componentes acessíveis somente pela classe que os define e por suas classes descendentes. 4) Published: Denota componentes acessíveis em tempo de projeto inclusive. Esta é a especificaçãopadrão. 5) Automated: Denota componentes públicos para automação OLE. 31 6.7.3 Classes e Units Quando você define uma nova classe em uma unit, escreve na seção interface a declaração da classe, que é composta pela declaração de seus dados e pela declaração (implicitamente) forward de seus métodos. O código dos métodos usualmente é colocado na seção implementation. 6.7.4 Escopo Um identificador declarado na parte de implementação de uma unit só poderá ser usado dentro da própria unit (identificadores locais). Já os identificadores declarados na parte de interface também serão visíveis às units que usarem a unit que os declara (identificadores globais). 6.7.5 A Palavra-Chave Self A palavra-chave self é um parâmetro implícito passado a qualquer método e representa a instância de objeto que o chamou. Na maior parte dos casos é desnecessário utilizar este parâmetro pois ele fica subentendido. procedure Data.DefVal (d, m, a: integer); begin Dia := d; //equivale a Self^.Dia := d; Mês := m; //equivale a Self^.Mês := m; Ano := a; //equivale a Self^.Ano := a; end; 6.7.6 Métodos Classe e Dados Classe Normalmente os dados dos campos de uma classe são independentes para cada instância de objeto desta classe. Existe uma forma de adicionarmos campos compartilhados: se declararmos um campo na parte de implementação da unit, ele se comportará como uma variável de classe - uma única localização na memória compartilhada por todos os objetos de uma classe. type Pessoa = class nome: string //variável independente para cada objeto ... function Quantidade: integer; end; ... implementation var i: integer; //variável compartilhada entre objetos function Pessoa.Quantidade: integer; begin .. Quantidade := i; end; Um método classe, declarado com a palavra-chave class, é um método que não pode acessar os dados de instâncias de objetos, mas que pode ser chamado ao se referir a uma classe (ou a um objeto desta classe). type MinhaClasse = class ... class function Valor: byte; //método de classe end; ... begin i := MinhaClasse.Valor end; 6.7.7 Ponteiro de Método Um tipo ponteiro de método é semelhante a um tipo procedural, a diferença é que a sua declaração é seguida das palavras-chave of object. type IntMethodPointer = procedure (Num: Integer) of object; MinhaClasse = class Value: Integer; Operation: IntMethodPointer; end; 6.7.8 Referências a Classes Este tipo é declarado com a participação das palavras-chave class of. type CRefType = class of TControl; var ClassRef: CRefType; ... begin ClassRef := TRadioButton; end; 6.7.9 Herdando de Tipos Existentes Para herdar de um tipo existente3, você precisa somente colocar esse tipo entre parênteses após a palavra-chave class na declaração da classe descendente. type NovaData = class (Data) ... end; Como regra geral, você pode usar um objeto de uma classe descendente toda vez que um objeto de uma classe ancestral for esperado, porém o inverso não é permitido. type Animal = class ... 3 Um novo tipo pode herdar de uma única classe existente, isto é, não é permitida a herança múltipla. 33 end; type Cao = class (Animal) ... end; var MeuAnimal, MeuAnimal2: Animal; begin MeuAnimal := Animal.Create; MeuAnimal2 := Cao.Create; end; 6.7.10 Métodos Virtuais e Dinâmicos As diretivas virtual (ou dinamic) e override são alguns dos recursos para a aplicação do polimorfismo. Um método de uma classe ancestral declarado como virtual (ou dinamic) pode ser ignorado (redefinido) em suas classes descendentes como override, contanto que tenha os mesmos parâmetros e (tipo de retorno no caso das funções). Sem estas diretivas, se uma classe descendente declarar um método com o mesmo nome de um método da classe ancestral, o novo método substituirá o anterior ao invés de ignorá-lo. Os métodos virtuais são mais utilizados que os dinâmicos pois favorecem a velocidade de execução em detrimento do tamanho do código, enquanto que os métodos dinâmicos fazem o contrário. type Animal = class ... function Verse: string; virtual end; type Cao = class (Animal) ... function Verse: string; override end; function Animal.Verse: string; begin Verse := ‘Ruído do Animal’; end; function Cao.Verse: string; begin Verse := ‘Au Au’; end; Um método redefinido pode substituir o antigo como no caso anterior, ou complementá-lo. Neste caso, a palavra-chave inherited é usada para chamar o método da classe ancestral. function Cao.Verse: string; begin inherited; //chama o método anterior Verse := ‘Au Au’; //complemento end; 6.7.11 Manipuladores de Mensagens A diretiva message serve para definir métodos de manipulação de mensagens. Estes métodos devem ser procedimentos protegidos com um único parâmetro var do tipo TMessage, e a diretiva message deve ser seguida do identificador da mensagem Windows a que o procedimento se refere. Este manipulador de mensagem é chamado quando o tamanho da janela é alterado. type TForm1 = class (TForm) protected procedure WMMinMax(var Message:Tmessage); message WM_GETMINMAXINFO; end; procedure TForm1. WMMinMax (var Message: TMessage); begin ShowMessage (‘Evento capturado.’); inherited; end; 6.7.12 Métodos Abstratos Outro recurso de polimorfismo é a diretiva abstract, usada para declarar métodos (virtuais ou dinâmicos) que serão definidos somente em subclasses da classe atual. type Animal = class ... function Verse: string; virtual; abstract; end; Cao = class (Animal) ... function Verse: string; override end; ... // a função Animal.Verse não é definida function Cao.Verse: string; begin Verse := ‘Au Au’; end; 6.7.13 Informações de Tipo em Tempo de Execução (RTTI) Uma vez que cada objeto conhece seu tipo e sua herança, podemos requisitar estas informações através de certos operadores. O operador is retorna True se um determinado objeto for do tipo de dados especificado ou se for descendente desse tipo de dados. if MeuAnimal is Cao then MeuCao := Cao (MeuAnimal); O operador as realiza a moldagem de um objeto para o tipo de dados especificado, se for possível. Senão uma exceção é gerada. 35 MeuCao := Cao as MeuAnimal; 6.7.14 Manipulando Exceções Podemos substituir a manipulação padrão de exceções realizada pelo Delphi em tempo de execução criando blocos de código protegido com as palavras-chave a seguir: try - delimita o início de um bloco de código protegido. except - delimita o final de um bloco de código protegido e insere as instruções de manipulação de exceções, com a forma: on [tipo de exceção] do [instruções]; este bloco é terminado com a palavra- chave end. finally - indica um bloco executado após a saída do bloco try, seja essa saída pelo fluxo normal do programa ou por exceção; este bloco é terminado com a palavra-chave end. raise - instrução usada para suscitar uma exceção. function Divide (A, B: integer): integer; begin try Divid except e := A div B; on EDivByZero do begin Divide := 0; MessageDlg (‘Divisão por zero’, mtError, [mbOK], 0); end; end; end; O exemplo acima utiliza a classe de exceção pré-definida EDivByZero. No entanto, os programadores podem definir suas próprias exceções simplesmente criando uma nova subclasse das classes de exceções existentes. type EArrayFull = class (Exception); A exceção é gerada criando uma instância da classe de exceção desejada e, então, chamando a instrução raise com o objeto criado como argumento. Este objeto não precisa ser destruído, ele será apagado pelo manipulador de exceções. Certifique-sede desativar a característica de depuração Break on Exception na tela Environment Option (menu Tools / Options); isto impedirá que o depurador interrompa a execução do programa quando um erro for encontrado. var MeuErro: EArrayFull ... if MinhaArray.Full then begin MeuErro := EArrayFull.Create (‘Matriz cheia’); raise MeuErro; end; Quando uma exceção é manipulada, o fluxo de execução inicia-se novamente após o manipulador, e não após o código que suscita a exceção. No exemplo abaixo, quando B for igual a zero a instrução Bmp.Free não será executada. function ComputeBits (A, B: integer): integer; var Bmp: TBitmap; begin Bmp := Tbitmap.create; try ComputeBits := A div B; Bmp.Free; except on EDivByZero do begin ComputeBits := 0; MessageDlg (‘Erro emComputeBits’, mtError, [mbOK], 0); end; end; end A instrução finally resolve o problema citado anteriormente, garantindo a execução da instrução Bmp.Free, quer ocorra uma exceção, quer não; function ComputeBits (A, B: integer): integer; var Bmp: TBitmap; begin Bmp := Tbitmap.create; try Comput finally eBits := A div B; Bmp.Free; end; end; Um bloco try pode ser seguido de um bloco except ou de um bloco finally, mas não de ambos ao mesmo tempo. No entanto, podemos obter o mesmo efeito construindo blocos try aninhados. function ComputeBits (A, B: integer): integer; var Bmp: TBitmap; begin Bmp := Tbitmap.create; try try Comput finally eBits := A div B; Bmp end; .Free; except on EDivByZero do begin ComputeBits := 0; MessageDlg (‘Erro emComputeBits’, mtError, [mbOK], 0); end; end; end; 37 7 A Biblioteca de Componentes Visuais A biblioteca do sistema Delphi é chamada de Biblioteca de Componentes Visuais (VCL), não obstante ela inclua mais do que componentes. No âmago do Delphi encontra-se uma hierarquia de classes. Desde que cada classe do sistema é uma subclasse da classe TObject, toda a hierarquia tem uma única raiz. Isto permite que você use TObject como substituto para qualquer tipo de dados do sistema. As RTTI (informações de tipo em tempo de execução) obtidas com os operadores is e as fornecem o tipo de dados de um objeto quando necessário. 7.1 A Hierarquia da VCL Use o Object Browser (menu View / Browser) para visualizar a hierarquia da VCL; se este comando de menu estiver desabilitado, compile um projeto primeiro. Figura 7-A Object Browser no topo da hierarquia da VCL. 7.1.1 Componentes Componentes são os elementos centrais dos Aplicativos Delphi. Eles podem ser visuais ou não- visuais. Os não-visuais aparecem no formulário como um pequeno ícone, mas em tempo de execução alguns deles gerenciam recursos visuais, como uma caixa de diálogo. Controles podem ser definidos como componentes visuais. Você pode ver como um controle se apresenta num formulário tanto em tempo de projeto como em tempo de execução. Controle ajanelados (windowed control) são controles baseados em janela, ou seja, que possuem um manipulador de janela. Controles desta subclasse podem receber o foco ou conter outros controles. Exemplos: classes TEdit, Tbutton, TForm. Controles gráficos ou controles não ajanelados (nonwindowed control) Ao contrário dos controles ajanelados, estes controles não possuem um manipulador de janela, e não podem receber o foco nem conter outros controles. Exemplos: classes Tlabel, TSpeedButton. 7.1.2 Objetos Embora a VCL seja basicamente uma coleção de componentes, existem outras classes que não se enquadram nesta categoria. Todas as classes não-componentes freqüentemente são indicadas pelo termo objetos, embora esta não seja uma definição precisa. Há dois usos principais para estas classes. Geralmente elas definem os tipos de dados das propriedades dos componentes, por exemplo, a propriedade Picture de um componente de imagem, a qual é da classe Tgraphic. O segundo uso de classes não-componentes é a utilização direta na programação, como armazenar o valor de uma propriedade na memória e modificá-la enquanto ela não se relaciona a nenhum componente. Há diversos grupos de classes de não-componentes na VCL: • Objetos gráficos: TBitmap, TBrush, Tcanvas, TFont, TGraphic, TGraphics-Object, TIcon, TMetaFile, TPen e Tpicture. • Objetos de fluxo / arquivo: TBlobStream, TFileStream, THandleStream, TIniFile, TMemory- Stream, TFiler, TReader e Twriter. • Coleções: TList, TStrings, TStringList e TCollection. 7.2 Usando Componentes e Objetos Existem basicamente duas maneiras de criar um objeto no Delphi. Você pode definir uma nova instância adicionando um componente a um formulário, ou pode criar um objeto dinamicamente. No segundo caso, é preciso declarar um objeto, alocar sua instância (chamando o construtor create) e definir sua propriedade parent. A partir deste ponto, você pode agir sobre o objeto exatamente como se ele fosse definido em tempo de projeto. Código para criar um botão dinamicamente: var MeuBotao: TButton; begin MeuBotao := TButton.create (self); //cria instância MeuBotao.left := 100; //define a posição MeuBotao.top := 50; MeuBotao.parent := self; //exibe o botão no formulário end; 7.3 Propriedades Propriedades são atributos de classes que determinam o status de um objeto, como sua posição e sua aparência, e também seu comportamento. A diferença de uma propriedade para um campo de dados é que, ao ler ou alterar o valor de uma propriedade um método pode ser chamado, embora algumas propriedades mapeiem diretamente a campos de dados, particularmente quando você lê o seu valor. 39 Figura 7-B O Object Inspector acessa as propriedades dos componente em tempo de projeto. Para saber o valor de uma propriedade em tempo de projeto, ou para mudá-la, você pode usar o Object Inspector. Em tempo de execução, você pode acessar uma propriedade lendo-a ou escrevendo-a com algum código. Existem propriedades de tempo de projeto, declaradas na seção published, e propriedades de tempo de execução, declaradas na seção public. O Object Inspector lista somente as primeiras. Usualmente você pode atribuir ou ler um valor de uma propriedade, e até mesmo usá-la em expressões, mas nem sempre pode passar uma propriedade como parâmetro para uma rotina. Isto acontece porque uma propriedade não é uma localização de memória; deste modo, ela não pode ser usada como um parâmetro passado por referência. Nem todas as classes VCL têm propriedades. Elas estão presentes nos componentes e em todas as demais subclasses da classe TPersistent, porque as propriedades usualmente podem se escoadas (streamed) e gravadas num arquivo. A palavra-chave property inicia a declaração de uma propriedade; as diretivas read e write especificam uma rotina ou campo de leitura e escrita, respectivamente. type TAnObject = class(TObject) property Color: TColor //valor do tipo TColor read GetColor; //leitura chama GetColor write SetColor; //escrita chama SetColor end; A omissão da diretiva write torna uma propriedade somente-leitura (comum). De forma equivalente, a omissão da diretiva read a torna somente-escrita (raro). type TAnObject = class(TObject) property AProperty: TypeX //propriedade somente-leitura read GetAnObject; end; 7.3.1 Propriedades Mais Comuns A tabela abaixo lista algumas das propriedades comuns à maioria dos componentes e é seguida de observações sobre algumas propriedades. Propriedade Disponível para Descrição Align Todos os controles Determina como o controle é alinhado dentro do componente-pai. BoundsRect Todos os controles Indica o retângulo demarcador do controle. Caption Todos os controles A legenda do controle. ComponentCount Todos os componentes O número de componentes possuídos pelo atual. ComponentIndex Todosos componentes Indica a posição do componente na lista de componentes do proprietário. Components Todos os componentes Um vetor dos componentes possuídos pelo atual. ControlCount Todos os controles O número de controles que são filhos do atual. Controls Todos os controles Um vetor dos controles que são filhos do atual. Color Muitos Objetos e componentes Indica a cor da superfície, do fundo, ou a cor atual. Ctrl3D A maioria dos Componentes Determina se o controle tem uma aparência tridimensional. Cursor Todos os controles O cursor usado quando o ponteiro do mouse está sobre o controle. DragCursor A maioria dos controles O cursor usado para indicar que o controle aceita ser arrastado. DragMode A maioria dos controles Determina o comportamento “arrastar-e-soltar” do controle como componente inicial para a operação de arrastar. Enabled Todos os controles e alguns outros componentes Determina se o controle está ativo ou inativo. Font Todos os controles Determina a fonte do texto exibido dentro do componente. Handle Todos os controles O manipulador da janela usado pelo sistema. Height Todos os controles e alguns outros componentes O tamanho vertical do controle. HelpContext Todos os controles e os componente de caixa de diálogo Um número contextual usado para chamar a ajuda contextual automaticamente. Hint Todos os controles A string usada para exibir dicas instantâneas sobre o controle. Left Todos os controles A coordenada horizontal do canto superior esquerdo do componente. Name Todos os componentes O Nome único do componente, o qual pode ser usado no código-fonte. Owner Todos os componentes Indica o componente proprietário. Parent Todos os controles Indica o controle de origem (pai). ParentColor Muitos objetos e componentes Determina se o componente deve usar sua própria propriedade Color ou a do componente-pai. Parent3D Maioria dos componentes Determina se o componente deve usar sua própria propriedade Ctrl3D ou a do componente-pai. ParentFont Todos os controles Determina se o componente deve usar sua própria propriedade Font ou a do componente-pai. ParentShowHint Todos os controles Determina se o componente deve usar sua própria propriedade ShowHint ou a do componente-pai. PopupMenu Todos os controles Indica o menu suspenso a ser usado quando o usuário der 41 um clique sobre o controle com o botão esquerdo. ShowHint Todos os controles Determina se as dicas estão ativadas. Showing Todos os controles Determina se o controle está visível quando seu controle- pai está visível. TabOrder Todos os controles (exceto TForm) Determina a ordem de tabulação do controle. TabStop Todos os controles (exceto TForm) Determina se o usuário pode tabular para o controle. Tag Todos os componentes Um long integer disponível para armazenar dados personalizados. Top Todos os controles A coordenada vertical do canto superior esquerdo do componente. Visible Todos os controles e alguns outros componentes Determina se o controle é visível. Width Todos os controles e alguns outros componentes O tamanho horizontal do controle. Tabela 7.3-A A Propriedade Name • O nome deve ser único dentro do componente proprietário, geralmente um formulário. • Se o nome e a legenda de um controle forem idênticos, uma mudança do nome também mudará a legenda. • O Delphi usa o nome do componente para criar os nomes dos métodos relacionados a seus eventos. Se posteriormente você mudar o nome do componente, o Delphi modificará os nomes dos métodos relacionados de acordo. Propriedades Relacionadas ao Tamanho e à Posição • A posição de um componente sempre se relaciona à área cliente de seu componente-pai. Para um formulário, a área cliente é a superfície incluída em suas fronteiras, mas sem as bordas. As Propriedades Enabled, Visible e Showing • Quando a propriedade Enabled de um componente é definida como falsa, o usuário fica impedido de interagir com o componente, embora ele continue visível. • A propriedade Showing de um componente pode ser falsa enquanto sua propriedade Visible é verdadeira. A primeira indica que o componente está atualmente visível e a segunda indica que o componente estará visível quando seu contêiner (componente-pai) também estiver. A Propriedade Tag • Esta propriedade assemelha-se mais a um campo de dados já que não exerce nenhum efeito sobre o componente quando é alterada. • Usando typecasting na propriedade Tag, você pode armazenar um ponteiro, um objeto ou qualquer dado que tenha quatro bytes de largura. Isto permite que se associe virtualmente qualquer coisa a um componente. 7.4 Métodos de Componentes Os métodos de componentes são exatamente iguais a quaisquer outros métodos A tabela abaixo lista alguns métodos disponíveis para a maioria dos componentes. Método Disponível para Descrição BeginDrag Todos os controles Inicia o arrasto manual. BringToFront Todos os controles Coloca o componente na frente de todos os outros. CanFocus Todos os controles Verifica se o controle pode receber o foco. ClientToScreen Todos os controles Traduz coordenadas do cliente para coordenadas globais da tela. ContainsControl Todos os controles ajanelados Verifica se certo controle é contido pelo atual. Create Todos os objetos e componentes Cria uma instância. Destroy Todos os objetos e componentes Destrói uma instância (ver método Free). Dragging Todos os controles Indica se o controle está sendo arrastado. EndDrag Todos os controles Termina manualmente o arrasto. FindComponent Todos os componentes Retorna o componente da propriedade matricial Components que tiver o nome solicitado. Focused Todos os controles ajanelados Verifica se o controle tem o foco. Free Todos os objetos e componentes (não sugerido para formulários) Apaga uma instância se ela for não-nula. GetTextBuf Todos os controles Copia o texto ou a legenda do controle para uma string terminada em nulo. GetTextLen Todos os controles Retorna a extensão do texto ou da legenda do controle. HandleAllocated Todos os controles Retorna True se o manipulador de janela do controle existir. HandleNedded Todos os controles Cria um manipulador de janela para o controle se ele não existir ainda. Hide Todos os controles Torna o controle invisível. InsertComponent Todos os componentes Adiciona um elemento à lista de componentes possuídos pelo atual. InsertControl Todos os controles Adiciona um elemento à lista de controles filhos do atual. Invalidate Todos os controles Força um redesenho do controle. RemoveComponent Todos os componentes Remove um elemento da lista de componentes possuídos pelo atual. ScaleBy Todos os controles Gradua o tamanho controle em determinada percentagem do seu tamanho anterior. ScreenToClient Todos os controles Traduz coordenadas globais da tela para coordenadas do cliente. ScrollBy Todos os controles Rola o conteúdo do controle. SendToBack Todos os controles Coloca o componente atrás de todos os outros. SetBounds Todos os controles Muda a posição e tamanho do controle de uma só vez. SetFocus Todos os controles Coloca o foco de entrada no controle. SetTextBuf Todos os controles Define o texto ou legenda do controle. Show Todos os controles Torne o controle visível. Update Todos os controles Redesenha imediatamente o controle, mas apenas se o redesenho tiver sido solicitado (invalidate). Tabela 7.4-A 43 7.5 Eventos de Componentes Os eventos podem ser gerados tanto pelas ações do usuário, um clique sobre um componente por exemplo, quanto pelo sistema, que pode responder a métodos e a mudanças de propriedades. Figura 7-C Eventos do formulário Form1 na página Events do Object Inspector É possível alterar um manipulador de eventos em tempo de projeto e de execução, desde que o novo método seja compatível com os parâmetro do evento. Para que um método esteja disponível em tempo de projeto no Object Inspector eledeve ser declarado na seção published da classe do formulário. Outro recurso utilizado e o compartilhamento de manipuladores de eventos por componentes. A tabela abaixo lista alguns eventos disponíveis para a maioria dos componentes. Evento Disponível para Descrição OnChange Muitos objetos e componentes Ocorre quando o objeto (ou seu conteúdo) muda. OnClick Muitos Controles Ocorre quando se dá um clique como botão primário do mouse sobre o componente. OnDblClick Muitos Controles Ocorre quando o usuário dá um duplo-clique com o botão primário do mouse sobre o componente. OnDragDrop Muitos Controles Ocorre quando uma operação de arrastar termina sobre um componente. OnDragOver Muitos Controles Ocorre quando um usuário está arrastando sobre um componente. OnEndDrag Muitos Controles Ocorre quando a operação de arrastar é encerrada. OnEnter Todos os controles ajanelados Ocorre quando o componente fica ativo, ou seja, quando ele recebe o foco. OnExit Todos os controles ajanelados Ocorre quando o componente perde o foco. OnKeyDown Muitos Controles Ocorre quando qualquer tecla é pressionada e o componente tem o foco. OnKeyPress Muitos Controles Ocorre quando uma tecla ou seqüência de teclas é pressionada e o componente tem o foco. OnKeyUp Muitos Controles Ocorre quando qualquer tecla é liberada e o componente tem o foco. OnMouseDown Muitos Controles Ocorre quando o usuário pressiona um dos botões do mouse sobre um componente. OnMouseMove Muitos Controles Ocorre quando o usuário move o mouse sobre um componente. Evento Disponível para Descrição OnChange Muitos objetos e componentes Ocorre quando o objeto (ou seu conteúdo) muda. OnClick Muitos Controles Ocorre quando se dá um clique como botão primário do mouse sobre o componente. OnDblClick Muitos Controles Ocorre quando o usuário dá um duplo-clique com o botão primário do mouse sobre o componente. OnDragDrop Muitos Controles Ocorre quando uma operação de arrastar termina sobre um componente. OnDragOver Muitos Controles Ocorre quando um usuário está arrastando sobre um componente. OnEndDrag Muitos Controles Ocorre quando a operação de arrastar é encerrada. OnEnter Todos os controles ajanelados Ocorre quando o componente fica ativo, ou seja, quando ele recebe o foco. OnExit Todos os controles ajanelados Ocorre quando o componente perde o foco. OnKeyDown Muitos Controles Ocorre quando qualquer tecla é pressionada e o componente tem o foco. OnKeyPress Muitos Controles Ocorre quando uma tecla ou seqüência de teclas é pressionada e o componente tem o foco. OnKeyUp Muitos Controles Ocorre quando qualquer tecla é liberada e o componente tem o foco. OnMouseDown Muitos Controles Ocorre quando o usuário pressiona um dos botões do mouse sobre um componente. OnMouseUp Muitos Controles Ocorre quando o usuário solta um dos botões do mouse que havia sido pressionado sobre um componente. OnStartDrag Muitos Controles Ocorre quando um componente inicia uma operação de arrasto. Tabela 7.5-A Conforme o quadro acima, os componente distinguem entre 3 “tipos de cliques”: • O evento OnClick envolve pressionar e soltar o botão primário do mouse sobre um componente. • O evento OnMouseDown é disparado apenas com o pressionar de qualquer botão do mouse sobre um componente. • O evento OnMouseUp é disparado quando qualquer botão do mouse é liberado sobre um componente. Estes dois últimos eventos incluem parâmetro para indicar qual botão foi pressionado, se alguma tecla de shift (Alt, Control e Shift) estava pressionada simultaneamente e a posição (X e Y) em que se deu o clique. O evento OnClick costuma se adequar aos casos mais comuns, em que não são importantes os detalhes fornecidos pelos outros dois eventos. • Os eventos OnDragOver e OnDragDrop são utilizados em conjunto por um componente capaz de receber um outro componente arrastado: o código do primeiro evento verifica se o componente sendo arrastado pode ser solto e ativa ou desativa o parâmetro Accept; o segundo contém a ação a ser tomada quando o componente é solto, e só ocorre se o parâmetro Accept estiver ativo. 45 7.6 Usando Coleções Delphi Entre os vários objetos, ou seja, as classes de não componentes, um grupo importante são as coleções. Basicamente, há quatro diferentes classes de coleções: • TList define uma lista de objetos de alguma classe. • TStrings é uma classe abstrata para representar todas as formas de listas de strings, independente de quais sejam suas implementações de armazenagem. Esta classe define uma lista de strings sem oferecer a adequada armazenagem. Por esta razão, objetos TStrings são usados somente como propriedades de componentes capazes de armazenar as próprias strings, como uma caixa de listagem. • TStringList define uma lista de strings com sua própria armazenagem. Você pode usar esta classe para definir suas próprias listas de strings num programa. • TCollection define uma lista homogênea de objetos, que pertence à classe de coleções. Os objetos devem ser persistentes (derivados de TPersistent), porque a coleção inteira pode ser direcionada (gravada em arquivo). Você pode operar com listas usando a notação de matrizes ( [ e ] ), tanto para ler quanto para mudar elementos. 47 Parte II - Usando Componentes Esta pode ser considerada a parte mais importante para desenvolvedores de aplicações, já que a programação visual usando componentes é a característica fundamental do Delphi. O objetivo agora é mostrar como usar algumas das características oferecidas pelos componentes pré-definidos na criação de aplicações. 8 Uma Viagem Pelos Componentes Básicos Aqui detalharemos algumas propriedades, métodos e eventos já citados anteriormente e sua utilização em situações específicas para cada componente. Mas antes algumas informações sobre os componentes: • Se, quando um componente for selecionado na palheta, a tecla shift estiver pressionada, uma borda surgirá em volta dele. Ela indica que você pode criar vários componentes do tipo selecionado, de uma só vez. Ao terminar, desmarque o componente selecionando a seta do mouse na palheta. • Podemos criar teclas de atalho ao sublinhar uma letra da legenda do componente, precedendo-a com o caracter “&”. Assim, o usuário poderá acionar um controle ou menu através da combinação Alt + Tecla. • A menos que nunca se cogite em referenciar um componente no código da aplicação, ele deve receber um nome. Um modelo que pode ser adotado é juntar o tipo do componente ao seu nome. Por exemplo, um botão que chama a tela de ajuda poderia se chamar AjudaButton. • A ordem com que os componentes são acessados no formulário ao se teclar <Tab> (ordem de tabulação) pode ser alterada através do speedmenu Tab Order do formulário. Além disso, cada componente pode ser excluído da ordem de tabulação desativando a propriedade TabStop. • No Windows 95, os controles de edição possuem por padrão um speedmenu que, no Delphi, podem ser personalizados. • Se a propriedade ShowHint estiver ativada, o texto da propriedade Hint será exibido como dica quando o usuário posicionar o mouse sobre o componente. • A propriedade HelpContext contém o número de uma tela do arquivo de help (.hlp) da aplicação (se houver um arquivo de help), para chamá-la quando o usuário teclar <F1> dentro do componente. Isto permite a criação de um sistema de help sensível ao contexto. Se o valor desta propriedade for zero para o componente, será usado o HelpContext do pai do componente. Figura 8-A 8.1 Seta do Mouse Usada simplesmente para desmarcar a seleção de algum componente na palheta. 8.2 Botão (Button) Os Botões são utilizados para permitir que o usuário dispare determinadas ações ao clicá-los. Propriedades Figura 8-B 1. Defina a legenda (Caption) pois é ela que indica primariamente ao usuário a função do botão. 2. Se o evento OnClick deve ser chamado
Compartilhar