Apostila de
Transcrição
Apostila de
Universidade Federal do Ceará Centro de Tecnologia Departamento de Engenharia Química Programa de Educação Tutorial – MEC / SESu PET Engenharia Química UFC Realização: Apostila de Apoio: V: 1.0 SUMÁRIO 1. PROGRAMAÇÃO ORIENTADA A OBJETOS 1.1 Programação Orientada a Objeto (POO) x Programação Orientada a Evento (POE)...............3 1.2 Liguagem para POO..................................................................................................................4 1.3 Estrutura do código no Code Editor..........................................................................................5 2. ELEMENTOS DO DELPHI 2.1 Elementos Visíveis....................................................................................................................6 2.2 Elementos Não Visíveis.............................................................................................................8 3. FUNDAMENTOS DA LINGUAGEM OBJECT PASCAL 3.1 Seções de uma Unit1 .............................................................................................................10 3.2 Declaração de Variáveis..........................................................................................................11 3.3 Tipos de Dados Predefinidos..................................................................................................11 3.4 Operadores Aritméticos.........................................................................................................12 3.5 Operadores Relacionais..........................................................................................................13 3.6 Operadores Lógicos................................................................................................................13 3.7 Bloco de Comandos................................................................................................................14 3.8 Estruturas Condicionais..........................................................................................................14 3.9 Estruturas de Repetição..........................................................................................................15 3.10 Funções e Procedimentos.....................................................................................................16 4. UTILIZANDO O AMBIENTE DO DELPHI 7 PARA A PROGRAMAÇÃO PROCEDURAL 4.1 Criando uma aplicação...........................................................................................................17 4.2 Implementando uma aplicação..............................................................................................18 5. EVENTOS, MÉTODOS E PROPRIEDADES 5.1 Eventos...................................................................................................................................20 5.2 Propriedades..........................................................................................................................21 5.3 Métodos.................................................................................................................................21 6. ALGUNS EVENTOS E COMPONENTES DO DELPHI 6.1 Principais teclas de atalho da IDE do Delphi...........................................................................23 Página |1 6.2 Eventos mais utilizados no Delphi..........................................................................................23 6.3 Formulário..............................................................................................................................25 6.4 Palheta Standard....................................................................................................................26 7. PLANEJANDO A SUA APLICAÇÃO 7.1 Planejando o nosso Aplicativo-Exemplo.................................................................................28 7.2 Padronizando a Nomenclatura dos Componentes.................................................................29 8. CRIANDO A APLICAÇÃO 8.1 Criando o Formulário da Aplicação.........................................................................................30 8.2 Inserindo um Panel no Formulário Principal..........................................................................31 8.3 Incluindo um Menu no Formulário Principal..........................................................................33 8.4 Criando uma Caixa de Diálogo de Direitos Autorais...............................................................34 8.5 Criando um GroupBox para exibir as equações do problema................................................35 8.6 Criando Botões para a manipulação do Formulário...............................................................36 8.7 Criando Caixas de Texto para receber os dados do problema...............................................37 8.8 Gerando os Resultados do problema.....................................................................................40 8.9 Compatilhando Eventos..........................................................................................................41 8.10 Exibindo as Iterações do problema.......................................................................................42 8.11 Criando um Arquivo com os Resultados do problema.........................................................43 Página |2 1. PROGRAMAÇÃO ORIENTADA A OBJETOS 1.1 Programação Orientada a Objeto (POO) x Programação Orientada a Evento (POE) O primeiro passo para entender a Programação Orientada a Objeto (no resto do material iremos chamá-la apenas POO) é saber fazer a diferenciação com a Programação Orientada a Evento (POE). Para isso, devemos entender o significado das expressões orientação a objeto e orientação a evento. Quando um programa é escrito em POE, o fluxo do programa é determinado pelos eventos, os quais o programa está preparado para responder. Por exemplo, ao digitar um valor no teclado, o usuário oferece uma nova informação ao software, que irá gerar uma ação do programa, levando para determinado ponto do código. A Programação Orientada a Evento é muito antiga, se comparada à POO, e é possível encontrar muitos exemplos de linguagens de programação orientadas a evento, como a linguagem C e Pascal. A Programação Orientada a Objeto é, pelo contrário, bastante recente. Seu conceito foi desenvolvido para facilitar a criação de programas utilizando interface gráfica. As vantagens mais visíveis da POO são a facilidade de manipular os programas e o pouco uso de código no projeto, que facilita a manutenção do programa. Na POO, os objetos são utilizados conforme os interesses do programador. O papel do adepto da Programação Orientada a Objeto é determinar quais objetos irão interagir entre si, e maneira como ocorrerá a interação. Mas o que são esses objetos que a POO pode manipular? Página |3 Basta lembrar que qualquer programa de computador que você já usou, como a calculadora, por exemplo: Na calculadora acima, todos os botões, o menu e o próprio espaço onde eles estão são objetos. Aprendendo a POO, será possível utilizar os objetos para criar programas parecidos com esse. 1.2 Liguagem para POO A linguagem Pascal surgiu como um linguagem de POE como tantas outras.Entretanto, ao longo dos anos, passou a receber cada vez mais funções e procedimentos característicos da POO, originando, gradualmente, uma nova linguagem de programação orientada a objeto. Dessa forma surgiu o Object Pascal, a variante orientada a objeto da linguagem Pascal. O Object Pascal é, no entanto, uma linguagem híbrida, fornecendo suporte para programação visual como também para programação orientada a objeto. Essa característica torna a transição de linguagens como C ou Pascal para o Delphi menos traumática, já que muitas técnicas usadas na POE ainda são válidas. Começaremos nosso estudo da Linguagem Object Pascal apresentando alguns conceitos novos, exclusivos da Programação Orientada a Objeto, que serão muito importantes para a compreensão da programação em Delphi. - Objetos: Os objetos são as ferramentas básicas da POO. Consistem de modelos de objetos reais, com seus estados e comportamentos. O estado de um objeto, em programação, é representado pelas variáveis, e os comportamentos, através de métodos ou funções. Apenas um método pode alterar um estado do objeto. A funcionalidade dos objetos só é real quando eles interagem entre si. Sozinho, cada objeto é inútil. - Classes: Todos os objetos usados em um programa pertencem a uma categoria, a qual agrupa diversos objetos. Por exemplo, ao criar um botão (você aprenderá como nos capítulos Página |4 seguintes), você está criando um objeto que pertence ao grupo que armazena todos os botões. Esse grupo define todos os estados e comportamentos possíveis para os objetos que lhe pertencem. Os grupos de objetos são chamados classes, e os objetos são instancias dessas classes. - Herança: Uma consideração importante é que quando tratamos de uma classe, esta, provavelmente, trata-se de uma subclasse de uma classe maior. Sempre que uma classe fizer parte de uma classe superior, haverá a transmissão de métodos e variáveis do grupo maior para o menor. No entanto, a classe inferior não está limitada as características da classe superior, podendo ter seus próprios métodos e variáveis. Chamamos de herança essa relação entre uma classe e suas subclasses. 1.3 Estrutura do código no Code Editor O código do programa com o qual você irá trabalhar é composto por diversos blocos com diferentes funções. São esses blocos: 1. Cabeçalho: Fica no início do código, e consta da palavra reservada unit seguida do nome da unit. Ex: unit Calculadora. 2. Uses: Nessa seção são listadas todas as units que serão utilizadas no programa ou na unit que está sendo trabalhada. Dessa forma, é possível usar variáveis declaradas em outras units, e fazer referencia a objetos de outras units, por exemplo. Existem algumas units que aparecem automaticamente na seção de uses. Essas units são essências para o programa, e não podem ser retiradas. 3. Type: Nessa seção pode-se encontrar a lista de todos os objetos usados, e suas respectivas classes. Também encontramos na seção types o cabeçalho de todos os eventos associados aos objetos existentes naquela unit. 4. Var: Aqui é a área de declarações do código. Toda variável que for usada precisa ser declarada nessa seção, com exceção daquelas já declaradas em outras units que constem na seção de uses. 5. Implementation: É aqui que, finalmente, podemos escrever os métodos e procedimentos que irão determinar o funcionamento do programa. Na verdade, boa parte do código nessa região não será escrito pelo programador, mas isso é algo que será visto no momento em que, de fato, começarmos a programar. Obs: Para o nosso objetivo atual, não é preciso entender a função das seções Private e Public, dessa forma não iremos discutí-las nesse material. Página |5 2. ELEMENTOS DO DELPHI Agora é o momento de conhecer o Ambiente de Desenvolvimento Integrado (IDE, do inglês Integrated Development Environment) com o qual você trabalhará. O Delphi possui diversos elementos na sua interface, dos quais parte podem ser vistos ao abrir o IDE, enquanto outros permanecem escondidos até que o usuário os abra. 2.1 Elementos Visíveis Os principais elementos visíveis do Delphi são: - Form: O Form (formulário) é o principal objeto a ser usado no desenvolvimento de um programa. É no formulário que todos os outros objetos são dispostos, sendo então essa a interface pela qual o programa irá interagir com o usuário. Um programa não fica limitado a apenas um formulário, podendo ter um formulário principal, que interage com vários outros. Para criar um novo formulário existem duas maneiras: 1. Seguindo a seqüencia: File – New – Form; 2. Através do repositório de objetos, que será mostrado mais à frente. - Editor de Código: O Editor de Código, como o nome indica, permite que o programador faça alterações no código fonte do projeto. Todas as informações relevantes ao programador, como objetos (que aparecem descritos de suas propriedades) e seus respectivos eventos, podem ser acessadas no Editor de Código. Quando um novo projeto é aberto, é gerado, automaticamente, um arquivo de código (.pas). Esse arquivo surge com o nome Unit1, que pode ser visualizado na tabulação do Editor de Código. Você deve notar que o Form e o Editor de Código ocupam o mesmo espaço, alternando em destaque na tela. Uma forma rápida de alternar a visualização entre um e outro é através da tecla F12. Página |6 - Object Inspector: É composto pela Página de Propriedades, Página de Eventos e Seletor de Objetos. Seu papel é providenciar a conexão entre o código e a interface do programa. Na página de propriedades é possível alterar as características dos objetos presentes no formulário, inclusive do próprio formulário, para melhor se ajustarem às suas necessidades. A página de eventos, que fica ao lado, por sua vez, é responsável por manipular os eventos associados aos objetos, permitindo também uma rápida navegação pelo código. O Seletor de objetos é uma ferramenta que lista todos os objetos existentes no projeto e seus respectivos tipos. Com ele é possível encontrar rapidamente qualquer objeto em um formulário. Página |7 - Palhetas: As palhetas são, basicamente, o local onde os objetos ficam listados para que possam ser selecionados e usados pelo programador. As palhetas foram separadas por grupos de funcionalidade, como se pode ver abaixo: Existem três formas de selecionar um objeto e transportá-lo para o formulário: 1. Clicando duplamente no ícone do objeto (isso o transportará direto para o centro do formulário); 2. Clicando no ícone e clicando dentro do formulário, no local onde você quer colocar o objeto; 3. Clicando no ícone enquanto a tecla Shift estiver pressionada (dessa forma você pode clicar várias vezes no formulário adicionando o objeto várias vezes). É importante lembrar que existem componentes que não serão visíveis durante a execução do programa (componentes não-visuais). Esses objetos são chamados DDE (Dynamic Data Exchange). - Speed Bar: É a barra que contém os botões mais utilizados quando no processo de criação do programa, fornecendo rápido acesso aos mesmos. 2.2 Elementos Não Visíveis Os principais elementos não visíveis do Delphi são: - Project Manager: O Project Manager é uma ferramenta que contém a lista de todas as units e formulários, onde os mesmo podem ser adicionados, eliminados e organizados. Existem três maneiras de acessar o Project Manager. São elas: 1. Acessando Project Manager no menu View; 2. Clicando no botão da Speed Bar correspondente ao Project Manager; 3. Usando o atalho Ctrl+Alt+F11. Página |8 - Repositório de Objetos: No Repositório de Objetos constam vários objetos, alguns dos quais não aparecem nas palhetas. Para acessá-lo basta seguir a seqüência File-New-Other... - Object TreeView: Logo acima do Object Inspector, aparece o Object TreeView, onde é apresentada uma lista de todos os objetos que estão sendo utilizados no programa. A princípio, pode parece que não há utilidade alguma para esse componente do Delphi, mas ao trabalhar com programas complexos que envolvam vários forms, o Object TreeView facilita muito o trabalho de ter que encontrar um objeto. Página |9 3. FUNDAMENTOS DA LINGUAGEM OBJECT PASCAL 3.1 Seções de uma Unit No código gerado por uma unit, temos: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} end. Como já comentamos anteriormente, inicialmente, observa-se a palavra reservada unit seguida do nome do arquivo em que a unit está armazenada. Na linha seguinte à que define o nome da unit, tem-se a palavra-chave interface, onde são declarados os tipos de dados, classes, variáveis, funções e procedimentos que podem ser acessados por outras units. Na seção implementation são declarados os tipos de dados, classes, variáveis, funções e procedimentos que não podem ser acessados por outras units. Nessa seção também são implementados as funções e procedimentos cujo cabeçalho é declarado na seção Interface. A palavra uses é outra palavra reservada da Linguagem Object Pascal e define as units que serão utilizadas pela unit corrente. Comentários - Comentários de uma linha: É definido por duas barras inclinadas. A partir destas duas barras, tudo o que for escrito na mesma linha será tratado como um comentário, e durante a execução do programa será desprezado. Exemplo: // Método de Runge Kutta P á g i n a | 10 - Comentários de múltiplas linhas: Para comentários de múltiplas linhas, colocamos o texto requerido entre chaves. Exemplo: { isto é um comentário de múltiplas linhas} 3.2 Declaração de Variáveis A declaração de uma variável de um determinado tipo é feita na seção var de uma unit ou, no caso de se desejar criar uma variável local, na seção var de uma função ou um procedure. A declaração de variáveis e vetores segue a seguinte sintaxe: Var Nome_da_variavel1, Nome_da_variavel2,...: Tipo_da_variavel; Nome_do_vetor: array[i1..i2] of tipo_da_variavel; Onde i1 e i2 determinam os valores mínimo e máximo do índice, respectivamente. Atribuindo um Valor a uma Variável Na Linguagem Object Pascal, o operador de atribuição é “:=”, logo, para atribuirmos um valor a uma dada variável, seguimos a seguinte sintaxe: Nome_da_variavel:= valor; 3.3 Tipos de Dados Predefinidos - Variáveis Inteiras: P á g i n a | 11 - Variáveis Reais: - Variáveis Booleanas: 3.4 Operadores Aritméticos Na Linguagem Object Pascal, realizamos operações aritméticas sobre variáveis utilizando os operadores aritméticos apresentados na tabela abaixo. Para realizarmos uma operação aritmética entre duas variáveis e atribuirmos o resultado a uma terceira variável, usamos a seguinte sintaxe: variavel3:= variavel1 op variavel2; (op é um dos operadores aritméticos) A precedência dos operadores segue uma ordem, essa ordem pode ser alterada pelo uso de parênteses. P á g i n a | 12 Operadores com maior precedência são executados antes dos de menor precedência. Operadores com mesma ordem de precedência em uma expressão são executados da esquerda para a direita. Exemplo: x:= 8 + 5 * 4; Atribui o valor 28 para a variável x. Para que a soma seja executada antes da multiplicação, incluímos os parênteses: x:= (8 + 5) * 4; Nesse caso, a variável x armazenará o valor 52. 3.5 Operadores Relacionais Para relacionarmos dois operandos, por meio de uma condição, utilizamos os operadores relacionais apresentados na tabela abaixo: 3.6 Operadores Lógicos Existem situações em que uma condição a ser testada é, na realidade, uma combinação de duas ou mais condições. Para testarmos uma condição composta, utilizamos os operados lógicos apresentados na tabela abaixo: P á g i n a | 13 A tabela abaixo mostra o resultado de expressões em que são usados operadores lógicos. 3.7 Bloco de Comandos Um bloco de comandos é constituído por um conjunto de linhas de código, que começa com a palavra reservada begin e termina com a palavra reservada end, seguida de um ponto-evírgula (;). Para o bloco de comando, temos a seguinte sintaxe: begin {Instruções do bloco de comandos} end; A palavra reservada end deve sempre ser seguida por um ponto-e-vírgula, exceto quando vier após a palavra reservada else, em uma estrutura condicional do tipo If-then-else, ou quando encerrar uma unit (o end que encerra uma unit é seguido por um ponto). 3.8 Estruturas Condicionais As estruturas condicionais encontradas na Linguagem Object Pascal são a if-then-else e a case of, com sintaxes descritas a seguir. - Estrutura condicional If-then-else: if (condição) then begin {Bloco de comandos executados se a codição for verdadeira} end else begin {Bloco de comandos executados se a codição for falsa} end; Caso não seja necessária a execução de qualquer comando se a condição for falsa, basta suprimir o trecho de código correspondente ao else, como mostrado a seguir. if (condição) then begin {Bloco de comandos executados se a codição for verdadeira} end; P á g i n a | 14 Nos casos em que um bloco de comandos é formado por uma única linha de código, podem-se suprimir as palavras Begin e end, como mostrado a seguir. if (condição) then {Bloco de comandos executados se a codição for verdadeira} else {Bloco de comandos executados se a codição for falsa}; Ou if (condição) then {Bloco de comandos executados se a codição for verdadeira}; - Estrutura condicional case of: case <expressão> of Valor_1: <Bloco de comandos> Valor_2: <Bloco de comandos> .......................... Valor_n: <Bloco de comandos> else: <Bloco de comandos> end; Nesse caso, se a expressão testada for igual a um dos valores especificados, será executado o bloco de comandos a ele correspondente. Caso nenhum desses valores seja igual ao definido pela expressão testada, o bloco de comandos else será executado. 3.9 Estruturas de Repetição As estruturas de repetição encontradas na Linguagem Object Pascal são os Laços For, Laços While e Laços Repeat, com sintaxes apresentadas a seguir. - Laços For: for var_contador:= valor_inicial to valor_final do <bloco de comandos> Caso se queira que o contador assuma valores decrescentes, deve-se usar a seguinte sintaxe: for var_contador:= valor_inicial downto valor_final do <bloco de comandos> P á g i n a | 15 - Laços While: while <condição> do bloco de comandos> - Laços Repeat: repeat <bloco de comandos> until condição; 3.10 Funções e Procedimentos O conceito de procedimentos e funções advém da necessidade de se subdividir um sistema complexo em unidades menores, denominadas sub-rotinas. - Procedimentos: Normalmente, procedimentos são usados para dividir um programa em blocos menores de códigos e para armazenar trechos de códigos utilizados diversas vezes no programa. A definição de um procedimento na Linguagem Object Pascal segue a seguinte sintaxe: procedure nome_do_procedimento (parâmetro_1: tipo_1, ..., parâmetro_n: tipo_n) var {declaração de variáveis locais ao procedimento} begin {corpo do procedimento} end; - Funções: Uma função é muito semelhante a um procedimento, com a diferença de que a chamada a uma função deve retornar um valor como resultado. Além disso, o resultado de uma chamada a uma função pode ser diretamente incorporado a uma expressão aritmética. A definição de uma função na Linguagem Object Pascal segue a seguinte sintaxe: function nome_da_função (par_1: tipo_1, ..., par_n: tipo_n): tipo_de_retorno; var {declaração de variáveis locais à função} begin {corpo da função} result:= valor; end; P á g i n a | 16 4. UTILIZANDO O AMBIENTE DO DELPHI 7 PARA A PROGRAMAÇÃO PROCEDURAL O ambiente de desenvolvimento do Delphi 7 é capaz de desenvolver aplicações utilizando o Pascal como linguagem de programação procedural. Esses tipos de aplicações não terão formulários (janelas), botões de comando ou qualquer outro tipo de componente da interface padrão do ambiente Windows, sendo definidas pelo Delphi 7 como aplicações do tipo console (serão executadas em uma janela padrão do DOS). 4.1 Criando uma aplicação Para criar uma aplicação do tipo console, proceda da seguinte forma: 1. Selecione New/Other do menu File do Delphi 7, para exibir a caixa de diálogo New Items. 2. Selecione o item Console Application na página New desta caixa de diálogo, conforme indicado na figura a seguir. 3. Selecione o botão Ok, para fechar a caixa de diálogo. A aplicação do tipo console será criada com um único arquivo (arquivo de projeto, com extensão dpr), e cujo código gerado é reproduzido a seguir. program Project1; {$APPTYPE CONSOLE} uses SysUtils; begin { TODO -oUser -cConsole Main : Insert code here } end. P á g i n a | 17 4. Salve o seu projeto com o nome MEuler, usando o item Save Project As do menu File. 4.2 Implementando uma aplicação Como exemplo, vamos implementar uma aplicação para a resolução de EDO’s utilizando o Método de Euler. O algoritmo do método está apresentado abaixo: Dados: y' = f(x,y); y(0); x(0); h = passo; n =nº de iterações Para i = 1 até n faça Início y ¬ y + h*f(x,y) x¬x+h Fim. O algoritmo deve ser implementado no bloco de comandos destinado ao código, exceto a declaração de variáveis, classes, funções e procedimentos, que deve ser feita conforme descrito anteriormente. Um exemplo de como o algoritmo pode ser implementado na Linguagem Object Pascal, é mostrado abaixo: program MEuler; {$APPTYPE CONSOLE} uses SysUtils,Math,Windows; var y,x,h:real; i,n:integer; function f(x,y:real):real; begin f := power(x,2); end; begin { TODO -oUser -cConsole Main : Insert code here } writeln('Resolucao de EDOs utilizando o Metodo de Euler'); writeln(''); writeln('Entrada de Dados'); write('y[0] = '); readln(y); write('x[0] = '); readln(x); write('h = '); readln(h); write('n = '); readln(n); for i:=1 to n do begin y := y + h*f(x,y); x := x + h; end; Writeln; writeln('Solucao = ',y:0:3); P á g i n a | 18 Readln; end. Execute esta aplicação, e verá a janela mostrada na figura a seguir. Posteriormente criaremos um programa com a mesma finalidade, porém em POO (Programação Orientada a Objetos), ou seja, criando assim formulários (janelas), botões de comando outros tipos de componentes de interface gráfica. P á g i n a | 19 5. EVENTOS, MÉTODOS E PROPRIEDADES 5.1 Eventos Os programas feitos em Delphi são orientados a eventos. Eventos são as ações normalmente geradas pelo usuário e que podem ser reconhecidas e tradadas pelo programa. Por exemplo, Clicar o mouse sobre um componente, focar um componente, mover o mouse sobre um componente, entre outros. Os eventos podem ser também gerados pelo windows. Existem eventos associados ao formulário e cada componente inserido neste. Por exemplos, o OnShow é o evento que ocorre quando mostramos o formulário na tela, ao componente botão está ligado o evento OnClick, que ocorre quando damos um click com o mouse sobre o botão. - Eventos comuns ao formulário e aos componentes: OnClick: ocorre quando o usuário clica o objeto. OndblClick: ocorre quando o usuário da um duplo clique. OnKeyDown: ocorre quando uma tecla é pressionado e o objeto tem o foco. OnKeyUp: ocorre quando o usuário solta uma tecla enquanto o objeto tem o foco. OnKeyPress: ocorre quando usuário da um clique numa tecla ANSI. OnMouseDown: ocorre quando o usuário pressiona o botão do mouse. OnMouseUp: ocorre quando o usuário solta o botão do mouse. OnMouseMove: ocorre quando o usuário move o ponteiro do mouse. - Rotinas que Respondem a Eventos: Cada evento gera uma procedure, aonde você deve inserir as linhas de código que envolvem este evento. Por exemplo, o evento OnClick, que é gerado ao clicarmos em um botão chamado BTNSair, cria a procedure: Procedure TForm1.BTNSairClick(Sender: Tobject); onde TForm1 é o objeto TForm que contém o botão BTNSair, e Sender é um objeto Tobject que representa o componente que deu origem ao evento. Se você quiser inserir uma rotina que trate um determinado evento de um componente, faça o seguinte: 1. Clique sobre o componente; 2. No Object Inspector, seleciona a página Events; 3. Dê um duplo clique sobre o evento para o qual quer inserir o código; 4. Entre no editor de código e escreva as linhas de código. P á g i n a | 20 Exemplo: Procedure TForm1.BTNSairClick(Sender: Tobject); begin Form1.Close; end; Obs.: Escreva seu código entre o begin e o end, se por acaso você quiser retirar o evento e o componente, retire primeiro os eventos do componente removendo somente o código que você colocou e depois o componente; os resto dos procedimentos o DELPHI tira para você. 5.2 Propriedades Uma propriedade representa um atributo de um objeto. No Delphi todas as coisas que aparecem no Object Inspector são propriedades, inclusive os eventos, porém sua referência é a um método. Como vimos, eventos podem estar associados a modificações em propriedade de componente e formulário, ou seja, você pode modificar propriedades de formulários e componentes durante a execução do sistema. Para isso, você deverá usar a sintaxe: <componente>.<propriedade>; Por exemplo, para modificar a propriedade text de uma caixa de edição Edit1 para “Bom Dia” faça: Edit1.Text := ‘Bom Dia’; Se a propriedade do componente tiver subpropriedades, para acessa-lás, utilize a seguinte sintaxe: <componente>.<propriedade>.<subpropriedade> Por exemplo, para modificar a subpropriedade Name, referente à propriedade fonte de uma caixa de edição Edit1, para ‘Script’, faça: Edit1.Font.name := ‘Script’; Obs.: Verifique o tipo da propriedade para antes de mandar o valor, consultando no Objetc Inspector. 5.3 Métodos São procedures ou funções embutidas nos componentes e formulários, previamente definidas pelo Delphi. P á g i n a | 21 - Exemplos de métodos: Show : Mostra um formulário; Hide : Esconde um formulário mais não o descarrega; Print : Imprime um formulário na impressora; SetFocus : Estabelece o foco para um formulário ou componente; - Chamado de métodos como resposta a eventos: Um evento pode gerar a chamada para um método, ou seja, uma subrotina previamente definida para um componente. No código, para utilizar um método, use a seguinte sintaxe: <nome do objeto>.<método> Por exemplo, clicar em um botão pode dar origem ao evento Show de outro formulário, mostrando este novo formulário na tela: Form2.show; P á g i n a | 22 6. ALGUNS EVENTOS E COMPONENTES DO DELPHI 6.1 Principais teclas de atalho da IDE do Delphi - F9: Executar; - F8: Executa passo a passo sem entrar em sub-rotinas; - F7: Executa passo a passo entrando em sub-rotinas; - CTRL+F9: Compila; - CTRL + SHIFT + (um número de 0 a 9 ): marca uma posição no texto; - CTRL + (um número de 0 a 9 ): vai para uma posição previamente marcada; - F11: Painel de propriedades; - F12: Comuta entre o formulário e a tela de codificação; - CTRL+F2: pára a execução de um programa; - CTRL+F1: Executa o HELP a respeito do texto onde o cursor estava posicionado. 6.2 Eventos mais utilizados no Delphi - OnKeyPress: Use este evento para capturar as teclas pressionadas sobre o objeto. Este evento captura apenas teclas da tabela ASC II, utilizando para isso uma variável KEY do tipo char. Teclas como shift ou F1 não são possíveis de serem capturadas neste evento. Não é possível também capturar seqüências de teclas, como Shift+A. Para estes casos utilize o evento OnKeyDown ou OnKeyUp. A variável KEY representa o caractere ASC II da tecla pressionada. Para anularmos a tecla pressionada atribuímos #0 ao parâmetro KEY. Exemplo: // neste exemplo capturamos a tecla ENTER através de seu caractere ASC II procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); // evento de um TEdit begin if key = #13 then begin showmessage('Você pressionou ENTER.'); Edit2.setfocus; // manda o foco para o componente edit2 end; end; // neste exemplo capturamos teclas através de seu valor e não se seu nº na tabela ASC II P á g i n a | 23 procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); begin if key in ['a' .. 'z', 'A'..'Z'] then begin // permite apenas as letras de ‘a’ à ‘Z’ maiúsculas e minúsculas showmessage('Você pressionou a tecla: [' + key + ']' ); // exibe a tecla pressionada end; end; - OnKeyDown: Este evento faz tudo o que o evento onKeyPress faz porém é capaz de processar sequências de teclas, como CTRL+Z por exemplo. Também é capaz de capturar teclas como TAB, F1, CAPS LOCK, NUM LOCK, INSERT, etc... A variável KEY é do tipo word (um inteiro que não aceita negativo). Para anularmos a tecla pressionada atribuímos 0 ao parâmetro KEY. Exemplo: // neste exemplo exibimos o nº da tecla pressionada. Ideal para se descobrir o nº de uma tecla. procedure TForm1.Edit2KeyDown(Sender: TShiftState); TObject; var Key: Word; Shift: begin showmessage( 'Você pressionou a tecla nº: ' + intToStr(key) ); end; - OnClick: Este evento é disparado sempre que clicamos sobre o objeto. Exemplo: procedure TForm1.FormClick(Sender: TObject); begin showmessage('Você clicou no formulario!'); end; - OnDblClick: Este evento é disparado sempre que executamos um duplo clique sobre o objeto em questão. Este evento não ocorrerá se o evento OnClick também foi programado. Exemplo: procedure TForm1.FormDblClick(Sender: TObject); begin showwmessage('Você deu um duplo clique no formulario!'); end; P á g i n a | 24 - OnMouseMove: Este é um evento pouco utilizado em aplicações normais (cadastros p.ex.). Ele é disparado sempre que o mouse é movimentado sobre o objeto. É possível ainda saber o status de teclas como CTRL, ALT, SHIFT e etc. além das posições X e Y do mouse. Exemplo: procedure TForm1.Edit1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin showMessage('Tira esse mouse daqui!'); end; - OnEnter: Este evento é disparado quando o objeto recebe o foco. Exemplo: procedure TForm1.Edit1Enter(Sender: TObject); begin (sender as TEdit).color := clYellow; // altera a cor do objeto passado no parâmetro SENDER end; - OnExit: Este evento é disparado quando o objeto perde o foco. Exemplo: procedure TForm1.Edit1Exit(Sender: TObject); begin (sender as TEdit).color := clWhite; // altera a cor do objeto passado no parâmetro SENDER end; 6.3 Formulário - Principais eventos do formulário: Os formulários (objeto Form) são os pontos centrais para o desenvolvimento Delphi. Você se utilizará deles para desenhar sua comunicação com o usuário, colocando e organizando outros objetos. Ele tem diversos eventos, porém os principais são: P á g i n a | 25 OnClose: Este evento ocorre sempre ocorre uma tentativa de se fechar o formulário, por exemplo, ao executar-se o método close. Podemos neste evento, por exemplo, fechar as tabelas utilizadas. OnShow: Este evento ocorre sempre que o formulário é exibido. Por exemplo, ao executar-se o método show. Podemos neste evento, por exemplo, limpar os componentes da tela, inicializar variáveis, abrir tabelas e etc. Exemplo: procedure TForm1.FormShow(Sender: TObject); begin showmessage('Exibindo o formulário.'); end; 6.4 Palheta Standard - TMainMenu: Este componente é utilizado para criar menus. Sua utilização é bem simples. Coloque um na tela e execute um duplo-clique para começar a criar o menu. Todos os itens do menu são objetos do tipo TmenuItem e possuem o evento onClick. - TPopupMenu: Este componente permite a exibição de um menu popUp de forma simples. Coloque um na tela e associe-o à propriedade popupMenu dos objetos (nem todos a possuem). Para criar o menu dê um duplo-clique sobre o objeto popupMenu e monte-o da mesma forma que no objeto TMainMenu. - TLabel: Utilizado para exibir uma mensagem no formulário. - TEdit: Este componente permite que o usuário entre com um texto. Sua principal propriedade é a text que armazena o que foi digitado. - TMemo: Utilizado para digitação de texto onde é necessário mais que uma linha. Sua principal propriedade é a lines, onde é possível acessar o texto digitado através da propriedade text ou então linha por linha através de lines[linha]. Para adicionar um texto podemos utilizar o método lines.add() ou mesmo através de text. - TButton: Este botão não permite a utilização de imagens. - TCheckbox: Este objeto armazena o valor de ligado ou não em sua propriedade boolean denominada checked. - TRadiobutton: Este objeto é utilizado quando possuímos várias opções, porém apenas uma deve ser selecionada. Sua principal propriedade é a checked que indica se objeto foi selecionado ou não. - TListbox: Este objeto permite a seleção de uma ou mais opções. P á g i n a | 26 - TCombobox: Este objeto é utilizado quando possuímos várias opções, porém apenas uma deve ser selecionada. Utilize a propriedade ItemIndex para saber se alguma opção foi selecionada. Esta propriedade inicia do “0” e “-1” indica que nada foi selecionado. - TRadioGroup: Este componente é similar ao TRadioButton, porém seus itens são criados através da propriedade itens, onde cada linha indica uma nova opção. - TGroupbox: Utilizado para agrupar componentes. - TPanel: Utilizado para agrupar componentes. P á g i n a | 27 7. PLANEJANDO A SUA APLICAÇÃO Um bom planejamento é indispensável ao sucesso de um empreendimento. Antes de iniciar a codificação e o desenho da interface da sua aplicação, é importante que você reserve um tempo para o seu planejamento. Graças a facilidade e rapidez com que se pode construir a interface de uma aplicação com o Delphi 7, muitos programadores começam a desenhar a interface sem se preocupar com um planejamento prévio da sua aplicação e, no meio do processo de desenvolvimento, descobrem que muita coisa poderia ser modificada. A fim de evitar esse tipo de problema, é recomendável que se reserve algum tempo para discutir aspectos importantes da aplicação. 7.1 Planejando o nosso Aplicativo-Exemplo O aplicativo-exemplo que será desenvolvido nessa apostila será destinado a resolver o problema da concentração, em um dado instante t, em um tanque de misturas que possui uma corrente de entrada e uma de saída. - Equacionando o problema: Para resolver este problema, iremos supor que a quantidade de soluto (q) não é criada nem é destruída dentro do tanque. Portanto, as variações na quantidade de soluto devem-se apenas, aos fluxos de entrada e saída no tanque. Matematicamente, a taxa de variação de q no tanque (dq/dt) é igual diferença entre a taxa de entrada e a taxa de saída, ou seja: dq/dt = taxa de entrada – taxa de saída Sendo C¹ e C² as concentrações das correntes de entrada e saída, respectivamente, e Q¹ e Q² as vazões das corretes de entrada e saída, respectivamente, temos: dq/dt = taxa de entrada – taxa de saída = Q¹.C¹ - Q².C² Para C², temos que: Logo: P á g i n a | 28 Ou seja, temos que a equação que rege o problema é uma equação diferencial. Para resolvermos numericamente tal equação diferencial, precisamos escolher um método matemático. O Método de Euler será o método utilizado para a resolução da equação, para que possamos aproveitar parte do código já desenvolvido anteriormente. Resumidamente, podemos listar os parâmetros que serão recebidos pelo aplicativo-exemplo e os parâmetros que serão retornados pelo mesmo. Nossa aplicação deverá receber: 1. Os parâmetros da equação (Q¹, C¹, Q² e V) 2. Os parâmetros do método (x(0), y(0), h, n) Nossa aplicação deverá fornecer: A Concentração (C²) e o Volume (V’) do tanque no instante t. Com base nos parâmetros que deverão ser utilizados e nos resultados que serão gerados, iremos escolher componentes onde o usuário nos fornecerá os dados requeridos, para que possam ser feitos os cálculos necessários, e componentes que retornem, para o usuário, os dados gerados. 7.2 Padronizando a Nomenclatura dos Componentes Ao criar a interface da sua aplicação, você incluirá diversos componentes nos vários formulários que a compõem. Cada formulário, controle ou componente terá um nome pelo qual será referenciado no código da aplicação. Quando você inicia uma nova aplicação, o Delphi 7 cria automaticamente um formulário denominado Form1. Se você criar um segundo formulário, ele será denominado Form2 e assim por diante. Quando se insere componentes em um formulário, ocorre a mesma coisa. Para facilitar as suas tarefas como um desenvolvedor de aplicações, você deve estabelecer uma convenção para os nomes dos seus formulários e componentes. Pode ser qualquer uma, desde que seja de fácil entendimento. P á g i n a | 29 8. CRIANDO A APLICAÇÃO 8.1 Criando o Formulário da Aplicação Sempre que iniciamos uma nova aplicação, o Delphi 7 cria um formulário vazio, que pode ser usado como formulário principal da aplicação. Como todo objeto, um formulário possui propriedades, métodos e eventos. Dentre as propriedades de um formulário, podem-se destacar: BorderStyle: Determina o estilo de borda do formulário. BorderIcons: Determina os ícones a serem exibidos na extremidade superior direita da barra de títulos do formulário. Caption: Armazena o texto exibido na barra de títulos do formulário. Color: Define a cor do formulário. Font: Define a fonte do texto exibido no formulário. Height: Define a dimensão vertical (altura) de um formulário. Icon: Define o ícone a ser exibido quando o formulário for minimizado. Left: Define a posição de um formulário, em relação à extremidade esquerda da tela. Menu: Define o menu associado ao formulário. Name: Define o nome pelo qual o objeto é referenciado no código da aplicação. PopupMenu: Define o menu flutuante associado ao formulário. Position: Define o posicionamento do formulário na tela. Windowstate: Determina o estado de exibição do formulário (maximizado, minimizado ou normal). Top: Define a posição de um formulário, em relação à extremidade superior da tela. Vamos iniciar a criação da interface visual da nossa aplicação. Para isso, vamos criar o nosso projeto: 1. No menu File selecione Save as... e salve a unit com o nome UnitPrincipal e o projeto com o nome Project_TM. 2. Selecione o formulário principal, inicialmente denominado Form1, e atribua os seguintes valores para as principais propriedades do formulário principal, diretamente no Object Inspector: P á g i n a | 30 BorderStyle: bsSingle (esse estilo impede que o formulário seja redimensionado). BorderIcons: [biSystemMenu, biMinimize]. Caption: Tanque de Mistura. Color: clMenu. Height: 500. Name: FormPrincipal. Position: poScreenCenter. Width: 600. 8.2 Inserindo um Panel no Formulário Principal O Componente Panel é usado para criar um painel no formulário. Para adicioná-lo, execute os seguintes procedimentos: 1. 2. 3. 4. Selecione o componente Panel na página Standard da paleta de componentes. Clique com botão esquerdo do mouse sobre o formulário. O componente será exibido no formulário. Posicione e redimensione o componente conforme a figura a seguir. 5. Atribua os seguintes valores para as propriedades do Panel: BevelInner: bvRaised. BevelWidth: 2. BorderWidth: 1. Caption: Deixar em branco. Color: clMenuBar. Height: 300. Width: 280. P á g i n a | 31 6. Selecione o componente Image na paleta Additional e coloque-o no Panel. 7. Para definir a imagem a ser exibida, selecione as reticências da propriedade Picture. Será exibida a caixa de diálogo Picture Editor. 8. Selecione o botão Load desta caixa de diálogo e procure pela imagem tanquemistura.jpg, clique em Abrir e, na Picture Editor, em Ok. 9. Atribua os seguintes valores para as propriedades do Image: Autosize: true. Left: 16. Top: 16. 10. Insira seis componentes Label no Panel, altere a propriedade Name e disponha-os conforme a figura abaixo. Seu formulário deve ficar com o aspecto mostrado na figura a seguir. 11. Com a tecla shift pressionada, selecione os seis componentes Label e, na propriedade Font, clique nas reticências. Na caixa de diálogo Fonte, escolha a fonte arial, estilo negrito e clique em Ok. P á g i n a | 32 8.3 Incluindo um Menu no Formulário Principal A inclusão de um menu é feita por meio da inserção de um componente MainMenu no formulário principal. O componente MainMenu está situado na página Standard da paleta de componentes e fornece acesso a um editor de menus. Para inserir um componente MainMenu no formulário principal da aplicação, execute os seguintes procedimentos: 1. Selecione o componente MainMenu, na página Standard da paleta de componentes e clique sobre o formulário, para que o componente seja inserido. O componente MainMenu é um componente não-visual, isto é, não estará visível na execução do programa; nesse caso, portanto, a sua posição no formulário não é de grande importância. 2. Usando o Object Inspector, altere a propriedade Name do componente para MenuPrincipal. 3. Dê um duplo clique sobre o componente MainMenu. O editor de menus é exibido, com o primeiro menu selecionado, pronto para ser editado. 4. Selecione o Object Inspector e altere os valores das propriedades Name e Caption do objeto que está em destaque para MenuInicio e &Início, respectivamente. 5. Clique no espaço criado do lado do Menu Início e defina os valores das propriedades Name e Caption como MenuSobre e &Sobre, respectivamente. 6. Para criar itens de menu, selecione o espaço em branco sob o menu Início. 7. Selecione o Object Inspector e altere os valores das propriedades Name e Caption para InicioLimparTudo e &Limpar Tudo. 8. No espaço sob o item de menu criado anteriormente, altere os valores das propriedades Name e Caption para InicioFinalizar e &Finalizar. 9. Para adicionar teclas aceleradoreas para os itens de menu, basta definir sua propriedade ShortCut no Object Inspector. Defina para o itens de menu Limpar Tudo e Finalizar os valores das propriedades ShortCut como Ctrl+L e Ctrl+F, respectivamente. 10. Para associar o evento OnClose (fechar o formulário) ao item de menu finalizar, devemos, na página Events do Object Inspector, dar um duplo clique no evento a ser definido (no caso, o evento onClick) e incluir a seguinte linha de código: procedure TFormPrincipal.InicioFinalizarClick(Sender: TObject); begin FormPrincipal.Close; end; P á g i n a | 33 11. Podemos, também, criar uma rotina para confirmar o encerramento da aplicação. Para isso, podemos usar o comando MessageDlg. Temos o seguinte código: procedure TFormPrincipal.Finalizar1Click(Sender: TObject); begin if MessageDlg('Deseja encerrar a aplicação?',mtConfirmation,[mbYes,mbNo],0) = mrYes then FormPrincipal.Close; end; O evento associado ao item de menu Limpar Tudo será definido posteriormente. 8.4 Criando uma Caixa de Diálogo de Direitos Autorais Para Criar uma caixa de diálogo de direitos autorais, vocês pode usar um dos formulários predefinidos do Delphi 7, executando os seguintes procedimentos: 1. Selecione o item New/Other do Delphi 7. Será exibida a caixa de diálogo New Items, também denominada “Repositórios de Objetos”. 2. Selecione a opção About Box na página Forms da caixa de diálogo New Items. 3. Clique no botão OK, para fechar essa caixa de diálogo e criar o novo formulário. Será criada a caixa de diálogo About, mostrada abaixo. Altere as propriedades Name e Caption desse formulário para FormSobre e Sobre o Sistema, respectivamente. Para personalizar a nossa caixa de diálogo, execute os seguintes procedimentos: 1. Altere o valor da propriedade Caption de ProductName para Problema de Misturas. 2. Altere o valor da propriedade Caption do label Version para Versão 1.0. 3. Altere o valor da propriedade Caption do label Copyright para Direitos Autorais. P á g i n a | 34 4. Altere o valor da propriedade Caption do label Comments para o nome do autor do programa. 5. Altere o valor da propriedade WordWrap do label Comments para False. 6. Se desejar, carregue uma imagem através da propriedade Picture do componente ProgramIcon. 7. Salve o arquivo de código associado a este formulário com o nome UnitSobre.pas, usando o item Save As do menu File. 8.5 Criando um GroupBox para exibir as equações do problema Para criarmos o componente GroupBox desejado, vamos seguir os seguintes passos: 1. Selecione o componente GroupBox, na página Standard da paleta de componentes e clique sobre o formulário, para que o componente seja inserido. 2. Atribua os seguintes valores para as propriedades do GroupBox: Caption: Equações. Height: 95. Hint: Equações do Problema. Name: GroupBoxEquacoes. ShowHint: true. Width: 300. 3. Posicione o GroupBox abaixo do Panel. 4. Insira dois componentes Label no GroupBoxEquacoes. Altere o valor da propriedade Caption e posicione-os de modo a ficaremos como na figura a seguir. 5. Insira dois componentes Image no GroupBoxEquacoes. Conforme descrito anteriormente, através da propriedade Picture, defina para o primeiro Image, a figura EqPM1.jpg e para o segundo Image a figura EqPM2.jpg. Para ambas, altere o valor da propriedade Autosize para true, posicione-as conforme a figura abaixo. P á g i n a | 35 8.6 Criando Botões para a manipulação do Formulário Criaremos, de início, dois botões com as mesmas funções do Menu Iniciar. Teremos um botão para limpar todo o conteúdo das caixas de texto do formulário (botão limpar tudo) e outro para sair da aplicação (botão finalizar). Para inserir os componentes Button no formulário principal da aplicação, execute os seguintes procedimentos: 1. Selecione o componente Button, na página Standard da paleta de componentes e clique sobre o formulário, para que o componente seja inserido. Faça isso para os três componentes Button, alinhando-os horizontalmente. 2. Da esquerda para a direita, altere a propriedade Name dos componentes Button para BtLimpar e BtFinalizar. Faça a mesma coisa para a propriedade Caption, não esquecendo de colocar o símbolo “&” que também é válido para botões. 3. Para melhor organizar a aplicação, coloque todos os botões dentro de um mesmo GroupBox e limpe o texto. Para fazer isso, selecione os três botões simultaneamente (com a tecla shift pressionada) e, com o botão direito do mouse, selecione a opção Edit/Cut. Insira o GroupBox no formulário e, clicando com o botão direito do mouse dentro do GroupBox, selecione a opção Paste. P á g i n a | 36 Seu formulário deve ficar com o aspecto mostrado na figura a seguir. 8.7 Criando Caixas de Texto para receber os dados do problema Para recebermos os valores dos parâmetros da equação do problema e do método que será utilizado, devemos oferecer ao usuário um meio para que ele possa inserir os dados do problema. Para tal fim, usaremos caixas de texto, o componente Edit. Para organizar melhor o aplicativo, vamos inserir os componentes Edit dentro de componentes GroupBox. Criaremos três GroupBox, uma para os parâmetros da equação, uma para os parâmetros do método e a última para os resultados. Os valores das propriedades dos componentes GroupBox estão listados a seguir. - GroupBoxes Name: GroupBoxPE Caption: Parâmetros da Equação Hint: Parâmetros da Equação ShowHint: True Height: 137 Width: 185 Name: GroupBoxPM Caption: Parâmetros do Método P á g i n a | 37 Hint: Parâmetros do Método ShowHint: True Height: 121 Width: 185 Name: GroupBoxResultados Caption: Resultados Hint: Resultados ShowHint: True Height: 135 Width: 185 Objetos a serem inseridos dentro do GroupBoxPE - Labels Name: LabelQ1 Caption: Q¹ (L/min) = Name: LabelQ2 Caption: Q² (L/min) = Name: LabelC1 Caption: C¹ (Kg/L) = Name: LabelV Caption: V (L) = - Caixas de Texto Name: EditQ1 Text: Limpar Texto Width: 75 Name: EditQ2 Text: Limpar Texto Width: 75 Name: EditC1 Text: Limpar Texto Width: 75 Name: EditV Text: Limpar Texto Width: 75 P á g i n a | 38 Objetos a serem inseridos dentro do GroupBoxPM - Labels Name: LabelC Caption: C (Kg/L) = Name: Labelh Caption: h (passo) = Name: Labeln Caption: n (n° ite) = - Caixas de Texto Name: EditC Text: Limpar Texto Width: 75 Name: Edith Text: Limpar Texto Width: 75 Name: Editn Text: Limpar Texto Width: 75 Objetos a serem inseridos dentro do GroupBoxResultados - Labels Name: LabelResultt Caption: Em t = Name: LabelResultq Caption: q(t) = Name: LabelResultV Caption: V(t) = Name: LabelResultC Caption: C(t) = Reposicione e redimensione estes componentes para que o formulário fique com o aspecto mostrado na figura a seguir. P á g i n a | 39 8.8 Gerando os Resultados do problema Com os dados fornecidos pelo usuário nas caixas de texto, podemos, através da resolução da equação diferencial, calcular os resultados do problema. Para isso, precisamos implementar o método escolhido para a resolução da EDO dentro do formulário. Para que a aplicação possa fazer os cálculos requeridos, todos os dados devem estar inseridos nas suas respectivas caixas de diálogos. Uma vez inseridos os dados, precisamos dar o comando para que os cálculos sejam realizados, esse comando será dado clicando sobre um botão, o botão calcular, ou seja, usaremos o evento OnClick do botão calcular para implementar os cálculos para a resolução do problema. Inicialmente, vamos criar o botão calcular (BtCalcular). Como fizemos anteriormente, vamos criar uma GroupBox para colocarmos o botão calcular. Crie também um botão Iterações (BtIte), cuja utilidade será explicada mais adiante. No evento OnClick implementaremos o Método de Euler e aproveitaremos parte do código utilizado no exemplo do Console Application, com algumas alterações. Por exemplo, na entrada de dados usaremos não mais o comando Read e sim a propriedade Text dos componentes Edit da aplicação, porém a propriedade Text é uma string, então precisaremos usar uma função de conversão, essa função é a StrtoFloat. Se quisermos converter a string P á g i n a | 40 dada em um inteiro, usaremos a função StrtoFloat, existem também as funções FloattoStr e InttoStr que desempenham a operação inversa. Um exemplo de como o código pode ser implementado, é apresentado abaixo: function f(t,q,Q1,Q2,C1,V: real): real; begin f:= Q1*C1 - Q2*q/(V + (Q1-Q2)*t); end; procedure TFormPrincipal.BtCalcularClick(Sender: TObject); var q,t,Q1,Q2,C1,C,V,h: real; n,i: integer; begin //Entrada de Dados - Parâmetros da Equação Q1:= StrtoFloat(EditQ1.Text); Q2:= StrtoFloat(EditQ2.Text); C1:= StrtoFloat(EditC1.Text); V := StrtoFloat(EditV.Text); //Entrada de Dados - Parâmetros do Método C:= StrtoFloat(EditC.Text); h:= StrtoFloat(Edith.Text); n:= StrtoInt(Editn.Text); //Implementação do Método t:= 0; q:= C*V; for i:=1 to n do begin q := q + h*f(t,q,Q1,Q2,C1,V); t := t + h; end; //Resultados Labelt.Caption:= Labelq.Caption:= LabelV.Caption:= LabelC.Caption:= Kg/L'; end; 'Em t 'q(t) 'V(t) 'C(t) = = = = ' ' ' ' + + + + FloattoStr(SimpleRoundTo(t,-2)) + ' min'; FloattoStr(SimpleRoundTo(q,-2)) + ' Kg'; FormatFloat('0.00',V + (Q1-Q2)*t) + ' L'; FormatFloat('0.00',q/(V + (Q1-Q2)*t)) + ' Obs. : As funções FormatFloat e SimpleRoundto foram usadas para mostrar os valores calculados com apenas duas casas decimais. 8.9 Compartilhando eventos Agora que o modelos para o cálculo das soluções já está funcionando, podemos dar funcionalidade ao botão Limpar Tudo do formulário. A função desse botão será limpar todos os edits do formulário. Esse mesmo procedimento também é utilizado no menu da aplicação, para aplicarmos a mesma a rotina a ambos os eventos onClick (do menu e do botão), podemos, simplesmente, compartilhar o evento. Para isso, é necessário, inicialmente, implementarmos, em um dos componentes, o seguinte procedimento: procedure TFormPrincipal.BtLimparClick(Sender: TObject); begin //Limpando os componentes Edit EditQ1.Clear; P á g i n a | 41 EditQ2.Clear; EditV.Clear; EditC1.Clear; EditC.Clear; Edith.Clear; Editn.Clear; //Retornando os componentes ao estado inicial Labelt.Caption:= 'Em t = '; Labelq.Caption:= 'q(t) = '; LabelV.Caption:= 'V(t) = '; LabelC.Caption:= 'C(t) = '; end; Repare que o procedimento foi associado ao evento onclick do botão limpar. Agora, para compartilharmos o evento, é necessário selecionarmos, através do componente Menu, a opção limpar tudo e, na palheta de eventos, através da combo do evento onclick selecionarmos a opção BtLimparClick. 8.10 Exibindo as Iterações do problema Para exibir as iterações, criaremos um novo formulário. Selecione as opções New/Form e o novo formulário será criado e salve a Unit (utilizando o Save As...) com o nome de UnitIte. Altere as propriedades Name e Caption para FormIte e Iterações do problema, respectivamente. No formulário, teremos um componente Memo, para exibir as iterações, os botões salvar e fechar e uma GroupBox para agrupar os botões. Insira, no formulário, inicialmente os componente Memo e GroupBox e defina a propriedade align de ambos como alClient e alBotton. Defina também, para o componente Memo as propriedades ReadOnly e ScrollBars para true e ssVertical, respectivamente. Insira os botões no GroupBox e redimensione o formulário de forma semelhante ao mostrado a seguir: P á g i n a | 42 Repare que, ao executar o programa, o formulário Ite não é exibindo clicando o botão Iterações. Para que o formulário seja exibido é necessário associar o método Show ao evento onClick do botão iterações. Faça isso para que o formulário seja exibido. Agora, é necessário fazer com que as iterações sejam adicionadas ao componente Memo. Para isso, devemos fazer uma pequena alteração no código-fonte da aplicação, adicionando à estrutura de repetição for e antes dela, os comandos a seguir: FormIte.MemoIte.Clear; FormIte.MemoIte.Lines.Add('t (min)'+#9+'q (Kg)'+#9+'V (L)'+#9+'C (Kg/L)'); for i:=1 to n do begin q := q + h*f(t,q,Q1,Q2,C1,V); t := t + h; FormIte.MemoIte.Lines.Add(FormatFloat('0.00',t)+#9+FormatFloat('0.00',q)+#9+Fo rmatFloat('0.00',V + (Q1-Q2)*t)+#9+FormatFloat('0.00',q/(V + (Q1-Q2)*t))); end; Repare que dessa forma não serão exibidas as soluções do problema para o instante t=0. Para que a solução em t=0 seja exibida, podemos repetir o mesmo comando que foi acrescentado ao for, adicionando-o antes da execução do for. 8.11 Criando um Arquivo com os Resultados do problema O próximo passo do aplicativo será a geração de um arquivo com as iterações do problema. Utilizaremos duas formas para criar o formulário “Salvar”. Na primeira desenharemos o todo o formulário com o objetivo de receber o local onde o arquivo será salvo. Na segunda maneira, utilizaremos a função SelectDirectory com o mesmo objetivo. O botão salvar terá a função de salvar o arquivo. Para isso criaremos novo formulário com a função de receber o local onde o arquivo será salvo, o nome do arquivo e o tipo de arquivo. Então, em File/New selecione a opção Form, para criar o novo formulário. Para o novo formulário, defina os valores para as propriedades a seguir: BorderStyle: bsSingle BorderIcons: [biSystemMenu, biMinimize] Caption: Salvar uma Cópia… Color: clMenuBar Height: 195 Name: FormSalvar Position: poScreenCenter. Width: 465 Objetos a serem inseridos no FormSalvar: - Labels Caption: Salvar em: Name: LabelSalvarem P á g i n a | 43 Caption: Nome do Arquivo: Name: LabelNomeArq Caption: Salvar como Tipo: Name: LabelSalvarcomo - Caixas de Texto Name: EditEndArq Text: C:\Documents and Settings\Elvis Trabalhos\Desktop\PExem\ TabOrder: 4 Width: 290 Name: EditNomeArq Text: Dados_PM TabOrder: 0 Width: 200 - ComboBox ItemIndex: 0 Items: (TStrings)… Name: ComboBoxTipoArq Style: csDropDownList TabOrder: 1 Width: 200 - Botões Caption: &Salvar Name: BotãoSalvar TabOrder: 2 Caption: &Cancelar P á g i n a | 44 Name: BotãoCancelar TabOrder: 3 Reposicione e redimensione estes componentes para que o formulário fique com o aspecto mostrado na figura a seguir. Para associarmos a aparição do FormSalvar ao evento onClick, precisamos definir o seguinte código: procedure TFormPrincipal.ButtonSalvarClick(Sender: TObject); begin FormSalvar.ShowModal; end; Para a criação do arquivo utilizaremos um processo um pouco diferente. As iterações são geradas no evento onClick do botão calcular, por meio da estrutura de repetição for. Então, para inserir os dados gerados no arquivo, temos duas opções: refazer todos os cálculos no evento onClick do botão salvar ou podemos gerar um “arquivo temporário” quando o botão calcular é pressionado e, caso o usuário queira salvar o arquivo, copiamos o arquivo para um outro diretório e com um nome definido pelo usuário. Lembrando que o “arquivo temporário” deve ser excluído ao fim da aplicação. Para gerarmos o arquivo temporário devemos utilizar algumas funções e procedimentos para manipulação de arquivos. As principais são apresentadas a seguir. A relação a seguir apresenta as principais funções para a manipulação de arquivos representados por uma variável: - Append (var F): Abre o arquivo representado pela variável F, apenas para escrita no final do arquivo. - AssignFile (var F; FileName: string): Associa à variável F o arquivo cujo nome é passado como segundo parâmetro. - CloseFile (var F): Fecha o arquivo representado pela variável F. - EOF (var F): Retorna True, se o arquivo representa pela variável F está posicionado no seu final, e False, em caso contrário. - Erase (var F): Apaga o arquivo representado pela variável F. P á g i n a | 45 - FileSize (var F): Retorna o tamanho, em bytes, do arquivos representado pela variável F. - Read (F, V1 [, V2, ..., Vn]): Lê elementos de dados em um arquivo representado pela variável F e os armazena nas variáveis v1, v2, ..., vn. - Readln ([var F: Text;] V1 [,V2, ..., Vn]): Lê elementos de dados em uma linha de um arquivo de texto representado pela variável F e os armazena nas variáveis v1, v2, ..., vn. Caso não sejam fornecidos parâmetros, o arquivo passa para a linha seguinte. - Rename (var F; NewName): Renomeia como NewName o arquivo representado por F. - Reset (var F [:File; RecSize: Word]): Esse procedimento abre o arquivo representado pela variável F. o parâmetro RecSize é opcional e especifica o tamanho do registro usado na transferência de dados. Se for omitido, o valor default 128 é usado. Se o arquivo não existir, ocorrerá um erro no processamento. Se o arquivo já estiver aberto, ele é fechado e reaberto, sendo posicionado no seu inicio. Se F representar um arquivo de texto, ele é aberto apenas para leitura. - Rewrite (var F [:File; RecSize: Word]): Esse procedimento cria o arquivo representado pela variável. Se o arquivo já existir, seu conteúdo será apagado, mesmo que já esteja aberto. - Write (F, V1 [, V2, ..., Vn]): Escreve, em um arquivo representado pela variável F, elementos de dados armazenados nas variáveis v1, v2, ..., vn. - Writeln (F, V1 [, V2, ..., Vn]): Escreve, em uma linha de um arquivo de texto representado pela variável F, elementos de dados armazenados nas variáveis v1, v2, ..., vn. A relação a seguir apresenta as principais funções para manipulação direta de arquivos (não associados a uma variável): - ChangeFileExt (const FileName, Extension: string): Muda para Extension a extensão do arquivo cujo nome e/ou path complete são definidos pela string FileName. - DeleteFile (const FileName: string): Apaga o arquivo cujo nome e/ou path completo são definidos pela string FileName. Retorna False, se o arquivo não existe, e True, em caso contrário. - ExpandFileName (const FileName: string): Retorna em uma string o path completo e o nome do arquivo definido pela string FileName. - ExtractFileDir (const FileName: string): Retorna em uma string o diretório do arquivo cujo nome e/ou path completo são definidos pela string FileName. - ExtractFileDrive (const FileName: string): Retorna em uma string o drive do arquivo cujo nome e/ou path completo são definidos pela string FileName. - ExtractFileExt (const FileName: string): Retorna em uma string a extensão do arquivo cujo nome e/ou path completo são definidos pela string FileName. P á g i n a | 46 - ExtractFileName (const FileName: string): Retorna em uma string apenas o nome do arquivo cujo nome e/ou path completo são definidos pela string FileName. - ExtractFilePath (const FileName: string): Retorna em uma string apenas o path completo do arquivo cujo nome e/ou path completo são definidos pela string FileName. - FileExists (const FileName: string): Retorna True, se o arquivo cujo nome e/ou path completo são definidos pela string FileName existe, e False, em caso contrário. - FileSearch (const Name, DirList: string): Pesquisa, pelos diretórios definidos no parâmetro DirList, um arquivo cujo nome é definido pela string Name. O parâmetro DirList é uma string em que os diretórios de pesquisa devem ser separados por vírgulas. Se o arquivo for encontrado, a função retorna o path completo do arquivo. - RenameFile (const OldName, NewName: string): Renomeia para NewName o arquivo cujo nome é definido pela string OldName, retornando True, se a operação é realizada com sucesso, e False, em caso contrário. Para criação do arquivo temporário, devemos declarar uma variável do tipo TextFile, junto as variáveis já declaradas no procedimento. Antes de “entrarmos” na estrutura de repetição for, demos associar o arquivo a variável criada, por meio do procedimento AssignFile, e criar o arquivo, por meio do método Rewrite. De forma semelhante ao Memo, os resultados para t = 0 não são exibidos, logo adicionaremos, antes do for, o procedimento write para que, no arquivo, sejam exibidos os valores iniciais do problema e, por último, devemos inserir um procedimento write dentro da estrutura for. Lembrando que, ao encerrar o programa, o “arquivo temporário” deve ser excluído, utilizando, assim, o evento onClose do formulário. As mudanças feitas no código estão mostradas abaixo. procedure TFormPrincipal.BtCalcularClick(Sender: TObject); var q,t,Q1,Q2,C1,C,V,h: real; n,i: integer; Arq: TextFile; begin AssignFile(Arq,'C:\Arq_temp'); Rewrite(Arq); Write(Arq,'t =',t:5:3,'s ','q =',q:5:3,'Kg ',(V + (Q1-Q2)*t):5:3,'L ',(q/(V + (Q1-Q2)*t)):5:3,'Kg/L'); MemoIteracoes.Lines.Add(FloattoStr(SimpleRoundTo(t,-2))+' '+FloattoStr(SimpleRoundTo(q,-2)) +' '+FloattoStr(SimpleRoundTo(V + (Q1-Q2)*t,-2))+' '+FloattoStr(SimpleRoundTo(q/(V + (Q1-Q2)*t),-2))); for i:=1 to n do begin q := q + h*f(t,q,Q1,Q2,C1,V);; t := t + h; Writeln(Arq); Write(Arq,'t =',t:5:3,'s ','q =',q:5:3,'Kg ',(V + (Q1-Q2)*t):5:3,'L ',(q/(V + (Q1-Q2)*t)):5:3,'Kg/L'); MemoIteracoes.Lines.Add(FloattoStr(SimpleRoundTo(t,-3))+' P á g i n a | 47 '+FloattoStr(SimpleRoundTo(q,-3)) +' '+FloattoStr(SimpleRoundTo(V + (Q1-Q2)*t,-3))+' '+FloattoStr(SimpleRoundTo(q/(V + (Q1-Q2)*t),-3))); end; CloseFile(Arq); end; procedure TFormPrincipal.FormClose(Sender: TObject; var Action: TCloseAction); begin DeleteFile('C:\Arq_temp'); end; Agora, para que o formulário salvar possa gerar o arquivo requerido, devemos fazer com que ele copie o “arquivo temporário” (que ainda não foi excluído) para um diretório especificado na caixa de texto EditEndArq. Utilizaremos o evento OnClick do botão salvar para fazer a copia do “arquivo temporário” e salva-lo no diretório desejado. Um exemplo de código que faça a cópia do arquivo para o local descrito no EditEndArq e com a extensão escolhida no ComboBoxTipoArq, é mostrado abaixo: procedure TFormSalvar.ButtonSalvarClick(Sender: TObject); var F_Name: string; F: TextFile; begin if EditNomeArq.Text <> '' then begin case ComboBoxTipoArq.ItemIndex of 0: F_Name:= EditEndArq.Text + EditNomeArq.Text + '.txt'; 1: F_Name:= EditEndArq.Text + EditNomeArq.Text + '.doc'; 2: F_Name:= EditEndArq.Text + EditNomeArq.Text + '.xls'; end; AssignFile(F,F_Name); if CopyFileTo('C:\Arq_temp',F_Name) then; FormSalvar.Close; end else Application.MessageBox('Digite o nome do Arquivo','Erro',16); end; Para o botão Cancelar, definimos o seguinte evento OnClick: procedure TFormSalvar.ButtonCancelarClick(Sender: TObject); begin FormSalvar.Close; end; Agora, mostraremos de uma forma bem mais simplificada como gerar o arquivo com as iterações. Ao botão salvar do FormIte, podemos definir o seguinte procedimento: procedure TFormIte.BtSalvarClick(Sender: TObject); const SELDIRHELP = 1000; var dir: string; begin dir := 'C:'; if SelectDirectory(dir, [sdAllowCreate, sdPerformCreate,sdPrompt], P á g i n a | 48 SELDIRHELP) then MemoIte.Lines.SaveToFile(dir+'\ite.txt'); end; Utilizando poucas linhas, conseguimos produzir o mesmo resultado. No Delphi temos, quase sempre, várias maneiras de chegar no mesmo propósito e muitas vezes o tempo que nós passamos planejando e pensando na nossa aplicação pode se multiplicar e transforma-se em economia de tempo. Pensem nisso! Com isso concluímos nossa breve introdução sobre o Ambiente de Desenvolvimento do Delphi. P á g i n a | 49