domingo, 25 de novembro de 2007

sábado, 17 de novembro de 2007

Eventos

Os eventos são blocos de comandos que associam a ocorrência de alguma atividade a uma ação a ser tomada. O Delphi possui mais de 130 eventos pré-definidos, que estão associados à ocorrência de ações, nas mais diversas classes.
Uma linguagem de programaçao orientada a eventos não tem necessariamente um início ou final lógico, isto é, de acordo com um sequência de comandos, pois só são realizadas a partir do instante que ocorre um evento.

Um evento pode estar associado a:
  • clique ou movimento do mouse;
  • acionamento do teclado;
  • operações sobre janelas (abrir, fechar, criar, redimensionar, mover, ...);
  • erros de execução; etc.
Eventos comuns:

On Active: ocorre quando o programa ativa o objeto pela primeira vez, ou quando se retorna de um outro aplicativo.

OnClick: ocorre quando o usuário dá um clicque no botão esquerdo do mouse

OnCreate: ocorre quando o objeto é criado.

Tais eventos são encontrados no Object Inspector do ambiente do Delphi como vemos abaixo:




segunda-feira, 5 de novembro de 2007

Procedimentos e Funções Predefinidas usuais do Object Pascal

A linguagem Pascal coloca disponível aos usuários um conjunto de funções e procedimentos distribuídos em UNITS (as units são rotinas compiladas separadamente do programa principal), com a finalidade de facilitar e agilizar a programação.

1.1 Manipulação de strings

1.1.1 CHR

Retorna o carácter correspondente ao código ASCII fornecido.

Ex:

Var

P : TextFile;

Begin

AssignPrn(P);

Rewrite(P);

Writeln(P, chr(12) , ‘Testando a Impressora’);

CloseFile(P);

End;

1.1.2 CONCAT

Concatenar as strings especificadas.

Ex:

var

S: string;

Begin

S := Concat('ABC', 'DEF'); { 'ABCDEF' }

End;

1.1.3 COPY

Retorna uma substring de uma string , isto é, retorna uma parte se S, desde inicio e com o tamanho especificado.

Ex:

var

s, s1 : string;

begin

s := 'ABCDEF';

s1 := Copy(s, 2, 3) { 'BCD' }

End;

1.1.4 DELETE

Elimina parte da string S; começa em inicio com o tamanho especificado.

Ex:

var

s: string;

Begin

s := 'Honest Abe Lincoln';

Delete(s,8,4);

WriteLn(s); { 'Honest Lincoln' }

End.

1.1.5 INSERT

Insere um string origem em s a partir da posição inicio.

Ex:

var

s: string;

Begin

s := 'Honest Lincoln';

Insert('Abe ', s, 8);

WriteLn(s); { 'Honest Abe Lincoln' }

End.

1.1.6 LENGTH

Retorna o número de caracteres da string.

Ex:

var

S : string;

Begin

read(S);

write(length(S));

End.

1.1.7 POS

Retorna a posição do inicio da string s1 dentro do string s2. (retorna 0 se não encontrar)

Ex:

var s: string;

Begin

s := ' 123.50';

{ Converte espaços para zeros }

while Pos(' ', s) > 0 do

s[Pos(' ', s)] := '0';

End.

1.1.8 UPPERCASE - LOWERCASE

Uppercase - Retorna o String com letras maiúsculas.

Lowercase - Retorna o String com letras minúsculas.

Ex:

Uses Sysutils;

var

s : string;

i : Integer;

Begin

Write('Digite um string: ');

ReadLn(s);

WriteLn('Conversão do string para maiúsculo: ',Uppercase(s));

Readln;

End.

1.1.9 STR

Transforma um número em representação string; x pode ser inteiro ou real; S passa a conter representação string de x com a largura e casas decimais especificadas.

Ex:

var

F : string;

N : integer;

begin

N:=1492;

str(N:7,F);

write(F); (* ' 1492' *)

end.

1.1.10 VAL

Converte string S em numero n. A posição de qualquer erro na string S é reportada no parâmetro código. Se código = 0, a conversão foi feita com sucesso.

Ex:

Program conver;

var

X : string;

Y,Z : integer;

begin

X:='9876';

Val(X,Y,Z);

writeln(Y);

writeln(Z);

readln;

end.

1.1.11 TRIM – TRIMLEFT - TRIMRIGHT

Trim - Retira espaços a esquerda e direita da string

TrimLeft - Retira espaços a esquerda da string

TrimRight - Retira espaços a direita da string

Ex:

If Trim(EditNome.Text) = ‘’ then

Begin

ShowMessage(‘Falta Informar o Nome’);

EditText.SetFocus;

Exit;

End;

1.1.12 ORD

Retorna o código ASCII do caractere da variável x.

Ex:

program MINUSCULA;

var I:integer;

(* MINUSC retorna um string com caracteres Minúsculos*)

function MINUSC(C : STRING) : STRING;

var

I : integer;

begin

for I := 1 to length(C) do

if (ord(C[I]) >= 65) and (ord(C[I]) <= 90)

then

C[I] := chr(ord(C[I])+32);

MINUSC := C;

end;

begin

writeln(MINUSC('ABCDEFGHIJKLMNOPQRSTUVWXYZ'));

writeln(MINUSC('FACE FUMEC.'));

readln;

end.

1.2 Manipulação Numérica

1.2.1 ABS

Retorna o valor absoluto de x.

Ex:

var

r: real;

i: Integer;

begin

r := Abs(-2.3); { 2.3 }

i := Abs(-157); { 157 }

end.

1.2.2 EXP

Retorna o valor de e(e=2.7182818285E+00) elevado a potência x.

Exemplo:

begin

WriteLn('e = ',Exp(1.0));

end.

1.2.3 LN

Retorna o logaritmo natural de x (base e=2.7182818285E+00).

Exemplo:

program exponencial;

var

I : integer;

{ função para calcular um exponencial }

function pot (X,Y : real) : real; {X**Y}

begin

pot:=exp(Y*ln(X));

end;

{ Programa Principal }

begin

for I:=1 to 10 do

begin

writeln (I:2 , '**' , 3 ,' = ',pot(I,3):0:2);

end;

readln;

end.

1.2.4 FRAC

Retorna a parte fracionaria de x.

Exemplo:

var

S : string;

begin

str(Frac(123.456):7:3,S); { 0.456 }

Writeln(S);

str(Frac(-123.456):7:3,S); { -0.456 }

Writeln(S);

readln;

end.

1.2.5 INT

Retorna a parte inteira de x.

Exemplo:

var

r: real;

begin

r := Int(123.456); { 123.0 }

r := Int(-123.456); { -123.0 }

end.

1.2.6 ROUND

Retorna o valor de x arredondado para um inteiro.

Exemplo:

begin

WriteLn(1.4, ' arredonda para ', Round(1.4));

WriteLn(1.5, ' arredonda para ', Round(1.5));

WriteLn(-1.4, ' arredonda para ', Round(-1.4));

WriteLn(-1.5, ' arredonda para ', Round(-1.5));

Readln;

end.

1.2.7 TRUNC

Retorna a parte inteira de x descartando a parte decimal.

Exemplo:

begin

WriteLn(1.4, ' truncar para ', Trunc(1.4));

WriteLn(1.5, ' truncar para ', Trunc(1.5));

WriteLn(-1.4, ' truncar para ', Trunc(-1.4));

WriteLn(-1.5, ' truncar para ', Trunc(-1.5));

Readln;

end.

1.2.8 SQR

Retorna o quadrado de x.

Exemplo:

writeln (‘O quadrado de x = ‘ , SRQ(X));

1.2.9 SQRT

Retorna a raiz quadrada de x

Exemplo:

begin

WriteLn('5 ao quadrado = ', Sqr(5));

WriteLn('A raiz quadrada de 2 = ', Sqrt(2.0));

end.

1.2.10 ODD

Retorna true se o valor de X e um número impar.

Exemplo:

If ODD(X) then Write(‘X é um número Impar’);

1.3 MANIPULAÇÃO DE TIPOS ESCALARES

1.3.1 PRED

Função encarregada de reconhecer o elemento, que antecede X no conjunto considerado. O resultado e do mesmo tipo do

parâmetro X.

Exemplo:

var

x : char;

begin

x:=‘C’;

write(PRED(x)); { ‘B’ }

end.

1.3.2 SUCC

Função encarregada de reconhecer o elemento, que sucede X no conjunto considerado. O resultado e do mesmo tipo do

parâmetro X.

Exemplo:

var

x : char;

begin

x:=‘C’;

write(SUCC(x)); { ‘D’ }

end.

1.4 Controle de memória

1.4.1 SIZEOF

Retorna o número de bytes ocupados pelo argumento.

Exemplo:

var

s : string[35];

begin

write(sizeof(S)); { 36 }

Readln;

end.

1.5 Interagindo com o sistema operacional

1.5.1 CHDIR

ChDir muda de diretório corrente.

Exemplo:

begin

{$I-}

{ mudar para o diretório especificado em Edit1 }

ChDir(Edit1.Text);

if IOResult <> 0 then

ShowMessage('Diretório não foi encontrado');

end;

1.5.2 GETDIR

Retorna o path do diretório ativo do drive especificado (acionador default=0,A=1,B=2,...). Retorna -1 se o drive não estiverpresente.

Exemplo:

var

s : string;

begin

GetDir(0,s); { 0 = Current drive }

writeln('Drive e diretório corrente: ' + s);

readln;

end.

1.5.3 MKDIR

Cria um subdiretório especificado em PATH.

Exemplo:

Mkdir(‘\tp\fontes\tmp’);

1.5.4 RMDIR

Exemplo:

Rmdir (\ tp\fontes\tmp’);

1.6 Comandos de desvio

Outro recurso que existe na linguagem Object Pascal é a capacidade de desviar no código, isto é a capacidade de pular para outra parte do código, quando necessário.

1.6.1 GOTO

A instrução GOTO permite que você salte de onde está no programa para uma linha rotulada específica.

Exemplo:

Var

Resp: char;

Begin

Inicio:

Writeln(‘Ok’);

Writeln(‘Quer repetir?’);

Readln(Resp);

If Resp = ‘S’ then GOTO Inicio

End.

1.6.2 Comandos Break / Continue ( Desvios dentro da repetição)

Estes comandos, à exceção daqueles demonstrados até agora, não são de repetição condicional, mas possuem importante papel junto á estes. Eles são usados em apenas duas situações: (1) quando se deseja interromper o processamento de um estrutura de repetição - Break; (2) quando for necessário garantir a continuidade do processamento de uma estrutura de repetição - Continue.

Exemplo:

Var

I : Integer;

Begin

For I := 1 to 3 do If (I mod 2) <> 0 then Continue;

For I := 1 to 3 do If (I mod 2) = 0 then Break;

End;

1.6.3 EXIT

Use o comando EXIT para sair do bloco corrente. Se o bloco corrente é o programa principal EXIT faz o programa terminar. Se o bloco corrente está aninhado, EXIT faz com que o bloco mais externo continue na instrução imediatamente após a que passou o controle para o bloco aninhado. Se o bloco corrente é uma procedure ou função, EXIT provoca a saida da função ou procedure para continuar após o ponto em que foi chamado.

Exemplo:

Procedure Teste ( X : Integer) ;

Begin

IF X = 0 then EXIT;

...

...

End;

Comandos

1 - Comando de atribuição

Permite atribuir a uma variável o resultado de uma expressão, valor de uma outra variável ou uma constante.Editar postagens
Sintaxe:

<> := <>;

2 – Comandos de Decisão

2.1 Comando de If...Then...Else

O comando IF é um dos comandos mais importantes e básicos da programação Object Pascal. Ele é utilizado para determinar o fluxo do programa a partir de determinada condição. Caso a situação pela qual o programa estiver passando confirme uma dada

condição, o programa executará os comandos abaixo da cláusula Then; caso contrário, executará as instruções abaixo da cláusula Else. A cláusula Else, em funçaõ das necessidades do programa pode ser omitida. Neste caso, se a situação da execução do

programa não satisfazer a condição estabelecida no IF, prosseguirá no seu funcionamento normal.

Alternativa Simples

IF <> THEN <>;

Alternativa Simples

IF <> THEN

BEGIN

<>;

¦ <>;

¦ <>;

...

END;

Alternativa Composta

IF <> THEN

<>

ELSE

<> ;

Alternativa Composta

IF <> THEN

BEGIN

<>;

END

ELSE

BEGIN

;

...

END;

2.2 Comando Case

O Case é uma estrutura que permite que o programador avalie o valor de uma determinada variável. A avaliação é sempre realizada em relação a constante ou intervalos de valores. Poderíamos dizer que o Case funciona de maneira similar ao IF, embora do ponto de vista prático, seja completamente diferente, pois permite obter o mesmo efeito de vários comandos IF em funcionamento conjunto com apenas um comando Case.

Exemplo:

Case NotaFinal of

100 : Begin

ShowMessage (‘Aprovado – Excelente’);

Contador := Contador + 1;

End;

80..99 : ShowMessage (‘Aprovado’);

0..79 : ShowMessage (‘Reprovado’);

End;

2.3 Estrutura de Repetição

É muito comum para o programador surgir situações em que se faz necessário a repetição de determinado conjunto de comandos. Na verdade estas situações nos levam a utilizar comandos muito interessantes que sem dúvida serão capazes de resolver o problema. Contudo para que seja assim, é muito importante que o programador determine até quando deseja que os comandos sejam repetidos. Existem algumas opções: (1) um número determinado de vezes e (2) até que determinada condição seja atendida.

2.3.1 Comando For

A estrutura FOR permite que um conjunto de comandos sejam executados num determinado número de vezes. O Número de

vezes é armazenado em uma variável inteira de controle da repetição.

Exemplo:

Var

I : Byte;

Begin

For I := 1 to 10 do
Begin

ShowMessage (‘Esta é a mensagem número: ‘ + IntToStr(I));

End;

End;

2.3.2 Comando WHILE

A estrutura do comando while também possibilita a repetição de um conjunto determinado de comandos. No entanto, diferentemente do For, permite a definição de condições para o término da repetição que não estão limitadas necessariamente a

uma contagem. S condições são verificadas no inicio do processamentoe, uma vez satisfeitas, os comandos internos a ela começam a ser repetidos até que alguma situação permita negar as condições iniciais.

Exemplo:

Var

Digitos : Integer ;

Terminas : Boolean ;

Begin

Digitos :=0;

Termina := True;

While Termina do

Begin

Digitos := Digitos + 1;

If Digitos = 100 then Termina := False;

End;

End.

2.3.3 Comando Repeat ... Until

O comando Repeat funciona de maneira análoga ao comando While. Na verdade entre eles existe apenas duas diferenças: (1) ao invés do Repeat verificar se as condições da repetição estão sendo atendidas no ínicio de seu processamento, ele as verifica ao final da repetição; (2) dispensa o uso dos comandos Begin e End.

Exemplo:

Var

Digitos : Integer ;

Terminas : Boolean ;

Begin

Digitos :=0;

Termina := False;

Repeat

Digitos := Digitos + 1;

If Digitos = 100 then Termina := True;

Until Termina;

End.

Amarrações

Declaração de Constantes

Constantes são valores especiais que geralmente são definidos no ínicio do programa e, se destinam a armazenar informações ou valores que não se alteram ao longo da execução do programa. Veja abaixo um exemplo de declaração de constantes no Delphi.

Const

PI = 3.1416;

Linguagem : String = ‘Delphi’;

dia : array [0..6] of String[9] = ('Domingo' , 'Segunda' , 'Terça' , 'Quarta' , 'Quinta' , 'Sexta', 'Sábado');

As declarações de constantes não alocam recursos do sistema. De fato, isto somente ocorre quando elas forem utilizadas na aplicação. Contudo, a constante Linguagem terá um tratamento diferente, uma vez que ela é uma constante tipada, ou seja, seu tipo (string) já foi previamente definido.

A maior diferença entre constantes do C e do Object Pascal é que Object Pascal, assim como Visual Basic, não requer que você declare o tipo constante junto com o valor na declaração. O compilador do Delphi automaticamente aloca espaço apropriado para a constante baseado nos seus valores, ou, no caso de constantes escalares tais como Inteiros, o compilador fiscaliza os valores que ele manipula, e espaços nunca são alocados.

Os valores das constantes são substituídos em tempo de compilação. Ou seja, os valores são definidos estaticamente.

Declaração de Variáveis

Sempre que desenvolvemos nossas aplicações, surge a necessidade de armazenarmos temporariamente certas informações. Para isto utilizamos variáveis. No Delphi podemos Ter diversos tipos de variáveis com características de armazenamento próprias.

Tais variáveis devem ser sempre bem definidas antes de tentarmos utilizá-las. Ao definir ou declarar uma variável, indique seu nome seguido do tipo de informação que deseja que ela armazene.

As variáveis estão dispostas em cinco grupos:

Numéricas: Podem ser números inteiros ou reais, formadas pelos dígitos de 0 a 9, sinais + e - podendo também conter o “.” para determinar a casa decimal.

Alfanuméricas: Podem ser formadas pôr qualquer tipo de caractere da tabela ASCII.

Lógicas: Podem assumir apenas dois valores: TRUE para valores verdadeiros ou FALSE para falsos.

Data/Hora: Podem armazenar data e hora, permitindo um processamento simples de data/hora.

Ponteiros: Podem armazenar apenas endereços de memória.

O nome da variável deve ser único em cada bloco do programa e deve conter até 255 caracteres, podendo ser composto pôr letras, números e sublinhado “_” , porém serve sempre iniciar com uma letra e não pode ser uma palavra reservada pelo Object Pascal.

É aconselhável que defina o nome da variável de forma que esta nós lembre a função que ela terá no contexto do programa. Além disso, o nome de uma variável não deve conter símbolos especiais (p.e. &%#@!), , nem ser igual ao nome de uma palavra reservada do Object Pascal.

O formato de declaração de variáveis deve ter a seguinte sintaxe:

VAR

nome_da_variável [, nome_da_variável ...] : tipo;

Exemplo N_Pessoas : Byte;

:

Var

Nome, SobreNome : String;

Idade : Integer;

O compilador Delphi entende que todos os dados globais são automaticamente inicializados com zero. Quando sua aplicação é iniciada, todo tipo inteiro possui 0, tipos ponto-flutuante possuem 0.0, ponteiros serão nil, strings estarão vazias, e assim em diante.Então, não é necessário inicializar com zero dados globais em seu código fonte.

Procedimentos e Funções

Como um programador, você já deve estar familiarizado com os conceitos de funções e procedimentos. Um procedimento é uma parte discreta do programa que efetua alguma tarefa particular quando ele é chamado e então retorna a parte do seu código que o chamou. Uma função trabalha da mesma forma exceto pelo fato de que ela retorna um valor depois de sua saída para a parte do programa que a chamou.

Se você está familiarizado com C ou C++, considere que um procedimento em Pascal é equivalente a uma função em C ou C++ que retorna void, enquanto que uma função corresponde a uma função do C ou C++ que retorna um valor.


A variável local Result na função merece atenção especial. Toda função em Object Pascal tem uma variável local implícita chamada Result que contém o valor de retorno da função. Note que diferentemente de C e C++, a função não termina assim que um valor é atribuído a Result.
Você também pode retornar um valor de uma função atribuindo ao nome de uma função o valor dentro do código da função. Esta é a sintaxe padrão do Pascal e costume das versões anteriores do Borland Pascal.

Passando Parâmetros

Pascal possibilita que você passe parâmetros por valor ou por referência para funções e procedimentos. Os parâmetros que você passa podem ser de qualquer tipo básico ou definido pelo usuário, ou open array (open arrays serão discutidos nesse tutorial). Parâmetros também podem ser constantes se seus valores não mudarem no procedimento ou função.

Parâmetros Valor

Parâmetros valor são o modo default de passagem de parâmetros. Quando um parâmetro é passado por valor, significa que uma cópia local daquela variável é criada, e a função ou procedimento opera sobre a cópia. Considere o exemplo a seguir:

procedure Foo(s: string);


Quando você chama um procedimento desta forma, uma cópia da string s será criada, e Foo() operará sobre a cópia local de s. Isto significa que você pode escolher o valor de s sem ter qualquer efeito sobre a variável passada para dentro de Foo().

Parâmetros Referência

Pascal permite que você passe variáveis para funções e procedimentos por referência; parâmetros passados por referência são também chamados parâmetros variáveis. Passar por referência significa que a função ou procedimento ao receber a variável pode modificar o valor daquela variável. Para passar uma variável por referência, use a palavra var na lista de parâmetros da função ou procedimento:

procedure ChangeMe(var x: longint);
begin
x := 2; { x agora é alterado na chamada do procedimento }
end;


Em vez de fazer uma cópia de x, a palavra reservada var faz com que o endereço do parâmetro seja copiado de forma que seu valor possa ser diretamente alterado.

Usar parâmetros var é equivalente a passar variáveis por referência em C++ usando o operador &. Assim como o operador & do C++, a palavra var faz com que o endereço da variável seja passado para a função ou procedimento, e não o valor da variável.

Parâmetros Constantes

Se você não quiser que o valor de um parâmetro passado para dentro de uma função seja alterado, você pode declará-lo com a palavra chave const. const não apenas impede que você modifique o valor dos parâmetros, mas ele também gera código mais otimizado para strings e registros passados para dentro de procedimentos ou funções. Aqui está um exemplo de uma declaração de procedimento que receber um parâmetro string constante:

procedure Goon(const s: string);


Parâmetros Open Array

Parâmetros open array permite que você passe um número variável de argumentos para funções e procedimentos. Você pode passar ou open arrays de algum tipo homogêneo ou arrays constantes de tipos diferentes. O código seguinte declarar uma função que aceita um open array de inteiros:

function AddEmUp(A: array of Integer): Integer;

Você pode passar variáveis, constantes ou expressões constantes para funções ou procedimentos de open array. O código a seguir demonstra isto chamando AddEmUp() e passando uma variedade de elementos diferentes.

var
i, Rez: Integer;
const
j = 23;
begin
i := 8;
Rez := AddEmUp([i, 50, j, 89]);


Para funcionar com um open array dentro de um a função ou procedimento, você pode usar as funções High(), Low() e SizeOf() para obter informação sobre o array. Para ilustrar isto, o código seguinte mostra uma implementação da função AddEmUp() que retorna a soma de todos os números passados em A:

function AddEmUp(A: array of Integer): Integer;
var
i: Integer;
begin
Result := 0;
for i := Low(A) to High(A) do
inc(Result, A[i]);
end;



Escopo

Escopo refere-se a alguma parte de seu programa na qual uma dada função ou variável é conhecida pelo compilador. Uma constante global está no escopo em todos os pontos de seu programa, por exemplo, enquanto uma variável local para algum procedimento tem escopo apenas dentro daquele procedimento.
program Foo;


const
AlgumConstant = 100;

var
AlgumGlobal: Integer;
R: Real;

procedure AlgumProc(var R: Real);
var
LocalReal: Real;
begin
LocalReal := 10.0;
R := R - LocalReal;
end;

begin
AlgumGlobal := AlgumConstant;
R := 4.593;
AlgumProc(R);
end.

AlgumConstant, AlgumGlobal e R tem escopo global—seus valores são conhecidos pelo compilador em todos os pontos dentro do programa. O procedimento AlgumProc() tem duas variável na qual o escopo é local para aquele procedimento: R e LocalReal. Se você tentar acessar LocalReal fora de AlgumProc(), o compilador mostrará um erro de identificador desconhecido. Se você acessar R dentro de AlgumProc(), você estará referindo a versão local, mas se você acessar R fora daquele procedimento, você estará referindo à versão global.

Object Pascal permite o uso de funções em tempo de compilação em declarações const e var. Essas rotinas incluem: Ord(), Chr(), Trunc(), Round(), High(), Low(), e SizeOf(). Por exemplo, todos os códigos seguintes são válidos:

type
A = array[1..2] of Integer;

const
w: Word = SizeOf(Byte);

var
i: Integer = 8;
j: SmallInt = Ord(‘a’);
L: Longint = Trunc(3.14159);
x: ShortInt = Round(2.71828);
B1: Byte = High(A);
B2: Byte = Low(A);
C: char = Chr(46
);

Introduzindo o Coletor de lixo - Gerenciamento de Memória em Delphi

Como já explicamos anteriormente, a partir de 2002 (delphi 7), além de manter sua compatibilidade com as versões anteriores, agora permite que o desenvolvedor disponibilize seus aplicativos para serem executados sobre a arquitetura .NET.

Na arquitetura .NET o CLR (Commom Language Runtime), ou tempo de execução compartilhado, é o ambiente de execução de aplicações. Logo o gerenciamento de memória é efetuado pelo runtime, permitindo que o desenvolvedor se concentre na resolução do seu problema específico. O que diz respeito ao sistema operacional, como o gerenciamento da memória, é feito pelo runtime.

Como isso é efetuado? À medida que uma área de memória é necessária para alocar um objeto, o GC ou coletor de lixo (Garbage Collector) realizará essa tarefa, assim como a liberação de espaços de memória que não estiverem mais em uso.

Para os que trabalham com linguagens de programação como C ou C++, que permitem o acesso direto à memória Heap via ponteiros, essa é uma das maiores dores de cabeça que os programadores sofrem, ora por fazer referência a espaços de memória que não foram alocados, ora porque estes espaços já foram liberados anteriormente; é exatamente esse tipo de erro que o coletor de lixo nos ajuda a evitar.

O gerenciamento de memória, quando efetuado diretamente pelo programador, torna os programas mais eficientes em termos de desempenho, mas ao mesmo tempo o penaliza, obrigando-o a alocar e desalocar memória quando assim é requerido. Como a .NET suporta diversas linguagens, como o C++, ela permite que o programador faça esse gerenciamento também, o que é chamado de “unsafe code” (código inseguro); entretanto, por default, O GC é o encarregado dessa tarefa, e o contrário não recomendado.

sexta-feira, 2 de novembro de 2007

A Evolução do Delphi e Curiosidades

1994

Nasce o Delphi 1 , versão 16 bits.
Ferramenta revolucionária que em menos de três meses ganhou uma considerável fatia de mercado.
Foi a primeira ferramenta RAD(*) 100% orientada a objetos.

1995

Com o lançamento do Windows 95, primeira versão 32 bits do Windows, foi lançado o Delphi 2 mantendo total compatibilidade com a versão 16 bits.
A nova versão vinha com melhorias significativas na construção de aplicações Cliente/Servidor.

1997

Acontece o grande "BOOM" da internet. E o Delphi 3 traz suporte à construção de aplicações para internet com CGI e ISAPI/NSAPI. Era a primeira ferramenta com suporte para construção de aplicações multi-camadas (usando DCOM), com ambiente RAD (MIDAS).

1998

A Borland disponibiliza o Delphi 4 com suporte aos mais recentes padrões de mercado, tais como o CORBA e Oracle 8 , trazendo aumento de produtividade do ambiente de desenvolvimento, com a possibilidade de depuração remota de aplicações, e wizards para a construção de controles ActiveX/ActiveForms.

1999

A onda do momento era o XML e, como não poderia deixar de ser, o Delphi 5 massacra qualquer concorrente com suas facilidades na manipulação de arquivos XML. Mantendo sua característica de suportar diversas tecnologias, a Borland disponibiliza um conjunto de componentes para utilização da tecnologia ADO (Microsoft) de acesso a dados. As ferramentas TeamSource e TranslationSuite também são novidades nessa versão.

2001

A estrela do momento é o Linux e a Borland é a primeira a disponibilizar uma ferramenta RAD nativa "Cross-plataform". Os Web Services eram também destaque, e o Delphi 6 é a primeira ferramenta comercial a ter suporte para essa tecnologia. Nasce o Kylix , o Delphi para Linux. BizSnap, DataSnap e WebSnap também são novidades.

2002

Chegou o .NET . O que fazer agora? Jogar o Delphi fora? É certo que a Borland jamais deixaria isto acontecer. O Delphi 7 , além de manter total compatibilidade com as versões anteriores, agora permite que o desenvolvedor disponibilize seus aplicativos para serem executados sobre a arquitetura .NET .



(*) RAD ( Rapid Aplication Development ) - significa "Ambiente Rápido de desenvolvimento" . Um RAD diminui bastante o tempo necessário para o desenvolvimento de aplicações. Mas como isso é possível? Um RAD traz em seu ambiente formas de diminuir o trabalho de um programador. No Delphi, por exemplo, quando criamos um botão, ao invés de digitarmos todo o código fonte para tal criação, simplesmente arrastamos o botão para a tela. O Delphi se encarrega de fazer toda a programação necessária para a criação deste botão. Em geral ferramentas do tipo RAD, economizam “trabalho braçal” do programador.

quinta-feira, 1 de novembro de 2007

Object Pascal a LP do Delphi

Agora que você tem uma idéia da aparência de uma aplicação, Delphi você estará mais a vontade para aprofundar-se no estudo desta nova linguagem de programação do Delphi conhecida como Object Pascal. Assim, além de ter o contato com conceitos fundamentais como constantes, variáveis, estruturas de repetição condicional, também começará a entender como trabalhar com a programação orientada a objetos.

Nunca é demais enfatizar que a chave da programação Delphi consiste em reconhecer que ele geralmente processa um código apenas em resposta a eventos. Pense num programa como um conjunto de elementos independentes que “acordam” apenas em resposta a eventos que forma ensinados a reconhecer. Também vale a pena dizer, que mesmo que você conheça uma linguagem de programação convencional, não tente obrigar seus programas Delphi a se adaptarem às estruturas dela. Caso imponha hábitos antigos de programação enfrentará problemas. Não pense num programa Delphi executando seus comandos de cima para baixo.

Primeiramente vamos mostrar como os principais programas escritos em Object Pascal são divididos para uma melhor compreensão.

O programa se divide em três partes:
- Cabeçalho
- Declarações
- Comandos

PROGRAM ;
USES ,,...;
CONST ...;
LABEL ...;
TYPE ...;
VAR ...;
PROCEDURE ...;
FUNCTION ...;
BEGIN
comandos;
END.
. Cabeçalho do Programa.
PROGRAM
. Área de Declarações:
. Cláusula USES
Identifica as bibliotecas (units) usadas pelo
programa.
. Definição de Constantes ( CONST )
Declara constantes que serão usadas no
programa.
. Identificação de Rótulos ( LABEL )
Identifica os rótulos que serão
referenciados no comando GOTO.
. Definição de tipos ( TYPE )
. Declaração de Variáveis. ( VAR )
. Área de definições de Procedimentos e Funções
PROCEDURE
FUNCTION
. Comandos
BEGIN
comandos;...
......
END.

quarta-feira, 31 de outubro de 2007

AMBIENTE DELPHI

Vamos mostrar agora um pouco do ambiente de programação do delphi. Os seus principais recursos estão listados abaixo:

1 - Barra de Menus

Através da barra de menu o usuário terá acesso a todos os recursos do Delphi. Os menus seguem até certo ponto a padronização do Windows.

2 - SPEEDBAR

A Speedbar contém ícones que foram considerados como de uso comum, justamente para que os programadores Delphi não precisem acessar constantemente à barra de menus. Em caso de dúvida sobre a função de qualquer ícone na tela do Delphi, basta mover o mouse sobre o ícone que surgirá um texto descritivo. Todo item da Speedbar possui uma tecla de atalho correspondente, portanto, se voce já tiver o costume de utilizar de teclas de atalho poderá dispensar o uso do mouse.


3 - PALHETA DE COMPONENTES

Está é a principal barra de ferramentas do Delphi. Através dela você tem acesso a todos os recursos que permitirão construir visualmente a sua aplicação.
Na página Standard, por exemplo, você tem acesso a objetos como: caixas de textos, combos, botões de rádio, caixas de verificação, campos de textos, e muito mais. Para utilizar qualquer um destes objetos
basta selecioná-lo com o mouse e arrastá-lo para o formulário de sua aplicação.



4 - O FORMULÁRIO


O Formulário é o ponto central de qualquer aplicação Delphi e constitui a área de programação e a tela da aplicação em desenvolvimento. O formulário é equivalente às janelas dos programas Windows. A partir de um formulário você constrói a janela da sua aplicação. Nesta janela você deve posicionar os componentes ou objetos desejados (Combos, Caixas de listagem,
etc) e escrever os códigos associados aos eventos selecionados dos componentes.
Tudo o que é colocado e realizado para o formulário, fica gravado num arquivo (.DFM) anexado ao projeto da aplicação. Embora este arquivo esteja em formato binário, é possível abrí-lo no Delphi e ler o seu conteúdo.


5 - CODE EDITOR

A janela Code Editor é propriamente o lugar onde o código do programa, será escrito. O código dos eventos, definidos no formulário através dos mais variados componentes, será necessário para fazer com que o Delphi responda as ações do usuário.Em outras palavras quando o usuário clicar sobre um botão do formulário, os comandos executados serão escritos no Code Editor.
O código escrito em Pascal, ou seja o programa, será gravado num arquivo com extensão (.PAS) que será designado UNIT. Estes arquivos são armazena
dos no padrão ASCII podendo ser acessados através de qualquer editor de textos no Windows.
É bom saber que nem tudo o que estiver escrito na UNIT será por iniciativa própria do usuário. O Delphi nos auxilia escrevendo sozinho a maior parte do código e insere nos lugares certos aqueles comandos que o programador deseja acrescentar.


6 - OBJECT INSPECTOR
Através desta importantíssima janela auxiliar o Delphi permite que você altere certos atributos dos componentes e dos formulários usados na aplicação. Alguns dos atributos ou propriedades poderiam ser: a cor do texto, a cor do fundo, o tipo de letra, etc. (PROPRIEDADES)
Além disso é através do Object Inspector que podemos programar o que deverá acontecer quando o usuário da aplicação clicar sobre um botão , selecionar uma opção no formulário, etc. (EVENTOS)

Tipos de dados Compostos

Tipo Array

Arrays são matrizes, isto é, coleções ordenadas de elementos de um mesmo tipo de dados, que faz uso de um índice para dar acesso aos itens da coleção. Como array já é um tipo, basta declarar uma variável como array, da seguinte forma:

var
Dia_da_semana: array [1..7] of string;
Dia_do_mês: array [1..31] of integer;

Note que separamos os valores mínimo e máximo de um array por dois pontos. Os arrays declarados acima são unidimensionais, isto é, seus elementos podem ser dispostos formando uma única linha. Para atribuir valores a um array proceda da seguinte forma:

begin
Dia_da_semana [1] := ‘Domingo’;
Dia_da_semana [2] := ‘Segunda-feira’;
Dia_da_semana [3] := ‘Terça-feira;
Dia_da_semana [4] := ‘Quarta-feira’;
Dia_da_semana [5] := ‘Quinta-feira’;
Dia_da_semana [6] := ‘Sexta-feira’;
Dia_da_semana [7] := ‘Sábado’;
end;

Para armazenar valores de um array em outra variável, podemos escrever:

var
Dia : string;

begin
Dia := Dia_da_semana [1];
end;

e assim por diante. A declaração de arrays multidimensionais é semelhante à de arrays unidimensionais. Por exemplo, para declarar um array a ser usado como uma tabela 30x30, escrevemos:

var
Bi_array: array [1..30,1..30] of currency;

Note que os elementos de um array podem pertencer a qualquer tipo de dados pré-definido ou definido pelo usuário.

- Arrays Dinâmicos

Uma novidade no Delphi 4 são os arrays dinâmicos. Arrays Dinâmicos são arrays alocados dinamicamente em dimensões que não são conhecidas em tempo de compilação. Para declarar um array dinâmico, apenas declare um array sem incluir as dimensões:

var
// array dinâmico de string:
SA: array of string
;

Antes de poder usar um array dinâmico, você deve usar o procedimento SetLength() para alocar memória para o array:

begin
// aloca lugar para 33 elementos:
SetLength(SA, 33);

Depois que a memória foi alocada, você pode acessar os elementos do array dinâmico como um array normal:

SA[0] := 'O urso parece feliz';
OutraString := SA[0];

Nota: Arrays Dinâmicos sempre iniciam no zero.

Arrays dinâmicos são auto-suficientes, assim não é necessário liberá-los quando você deixar de usá-los; eles serão liberados quando deixarem o escopo. Entretanto, pode haver uma hora que você queira remover o array dinâmico da memória antes que ele saia do escopo (se ele usa muita memória, por exemplo). Para fazer isso, você apenas precisa atribuir ao array dinâmico um nil:

SA := nil; // libera SA

Arrays dinâmicos são manipulados utilizando semanticas de referência similares à AnsiStrings


Tipo Enumerado

Este tipo permite que você crie uma lista organizada de itens. Para usar um tipo você deve antes declará-lo com a palavra reservada type. Por exemplo, um tipo enumerado que descreve os dias da semana pode ser declarado da seguinte maneira:

type
Semana = (Segunda, Terça, Quarta, Quinta, Sexta, Sábado, Domingo);

Espaços em branco não são permitidos dentro de um elemento. Uma vez declarado um tipo, você deve declarar uma variável pertencente a este tipo. Não usamos o tipo diretamente, mas sim uma variável deste tipo. Por exemplo, vamos supor que queiramos construir um programa que forneça o nome da pessoa escalada para um plantão semanal. Poderíamos declarar uma variável Plantao da seguinte forma:

var
Plantao : Semana;

Para atribuir valores à variável Plantao escreva simplesmente:

Plantao := Segunda;
Plantao := Terça;
etc.


Tipos Registro(Record)

O tipo de dados Record provavelmente é o mais versátil à disposição, pois pode conter tipos de dados heterogêneos. Por exemplo, a folha de pagamento de uma empresa conterá dados do tipo string (nome, endereço, etc), dados do tipo currency (salário), dados do tipo TDateTime (data de contratação) e assim por diante. Não poderíamos usar um array, pois este tipo só pode conter dados de um mesmo tipo. O tipo Record resolve o problema e, mais uma vez, devemos declarar o tipo de dados antes de usá-lo:

type
Folha_Pgto = Record
Nome: String;
Data_Cont : TDateTime;
Salario: currency;
end;

var
Folha_Abril: Folha_Pgto;

begin

Folha_Abril.Nome := ‘Ana Paula Magalhães’;
Folha_Abril.Data_Cont := 10/02/1998;
Folha_Abril.Salário := 2200;

end;

Note que você deve usar um ponto para separar o nome do Record do nome do campo a que você está se referindo. O Object Pascal, e várias linguagens modernas fornecem uma maneira mais fácil de executar esta operação, usando a instrução With:

begin

With Folha_Abril do begin

Nome := ‘Ana Paula Magalhães’;
Data_Cont := 10/02/1998;
Salário := 2200;

end;

end;

Aqui, o primeiro "end" é da instrução With. A documentação do Object Pascal sugere que você use With quando for possível, pois isto diminui o tempo de execução.

Os tipos Record também podem conter arrays e são bastante usados quando se requer bancos de dados simples. Veremos que o Delphi permite a implementação de estruturas de dados bastante complexas, usando bancos de dados Dbase, Paradox, Access, etc. Contudo, vez por outra não é necessária toda esta sofisticação e é conveniente optar pelos tipos Record. Além disso, nesses casos simples não será necessário instalar os drivers de bancos de dados.


Tipo Subintervalo

O tipo subintervalo permite que você defina um intervalo válido de respostas que um usuário pode inserir em um programa, tal como o número de horas trabalhadas em um mês, a faixa de idade dos membros de um clube, etc. Um subintervalo pode conter os seguintes tipos: boolean, char, integer e tipos enumerados.

A declaração de um tipo subintervalo é similar àquela de um tipo enumerado:

type
Salario_faixa1 = 500 .. 1000;

Note que usamos dois pontos para separar os limites do subintervalo, e não vírgulas. Isto permite que o compilador identifique o tipo como um subintervalo e não um tipo enumerado. A seguir, devemos declarar uma variável como pertencente ao tipo declarado anteriormente:

var
Salario_Ana : Salario_faixa1;

Quando um programa usando subintervalos é executado, e se um valor atribuído a um tipo subintervalo estiver fora do intervalo, o programa gerará um erro de tempo de execução. Para que o teste de intervalo seja executado, você deve antes incluir a diretiva de compilação {$R+} no programa, da seguinte forma:

procedure Tform1.ButtonClick (Sender : Tobject);
{$R+}

type
Salario_faixa1 = 500 .. 1000;

var
Salario_Ana : Salario_faixa1;


Tipo Conjunto

Os conjuntos são ainda mais interessantes que os subintervalos. Os conjuntos podem usar intervalos em suas definições. Um conjunto é um grupo de elementos que você quer associar a um nome e que pode comparar com outros valores para a inclusão ou exclusão do conjunto. Um exemplo poderia ser um conjunto contendo todas as respostas de um caractere possíveis para uma pergunta do tipo SIM/NÂO. As quatro respostas são y , Y, n e N. você poderia criar um conjunto que abrangesse as quatro: [ ‘y’, ‘Y’, ‘n’, ‘N’]. uma vez definido esse conjunto , você pode então usá-lo para ver se algo está nele ou não.

Você procura inclusão de um conjunto chamando a instrução in. Por exemplo, a instrução :

Myinput in [‘y’, ‘Y’, ‘n’, ‘N’] then

Está dizendo que, se o valor da variável, Myinput é um dos itens do conjunto, então essa expressão é valida como TRUE booleano. Se o valor de Myinput não esta no conjunto, então essa instrução é FALSE. Um conjunto pode conter quase tudo, desde que seus membros sejam do mesmo tipo ordinal ou de tipos ordinais compatíveis.

Constantes Tipadas

Na verdade, constantes tipadas são variáveis inicializadas com valor persistente, que podem ser alteradas normalmente, como qualquer variável. A única diferença de sintaxe entre constantes tipadas e simples é que o tipo da constante é indicado explicitamente na declaração. Se uma constante tipada for declarada localmente, ela não será destruída quando o método for encerrado


Tipo Variant

O tipo Variant pode assumir tipos como SmallInt (inteiro de 16 bits), Integer(inteiro de 32 bits), Strings, Single (ponto flutuante de precisão simples), Double (ponto flutuante de precisão dupla), Boolean(lógico de 16 bits)... Bem como também assumir tipos como Null (para nulo), e Empty (para nunca atribuído, vazio). As conversões de tipos acontecem automaticamente (na medida do possível), e a atribuição de tipos para uma variável do tipo Variant pode mudar em modo de execução, observe o exemplo abaixo:

procedure TForm1.Button1Click(Sender: TObject);
var m_valor1,

m_valor2,

m_valor3 : Variant;

m_Str1 : String;

Begin

m_valor1 := 12; // atribui valor inteiro

m_valor2 := 5.2; // atribui um ponto flutuante

m_valor3 := m_valor1 * m_valor2;

m_Str1 := m_valor3;
// atribui resultado(já convertendo)

End;

Como pode notar, temos em mãos uma flexibilidade ímpar no trabalho com variáveis. Todavia, como nem tudo são rosas, existem desvantagens com o uso de Variant, entre elas, o tamanho mínimo de 16 bits para as variáveis (tornando-as mais lentas), e também o fato de não haver verificações em modo de compilação quando usamos Variant, podendo surgir Bugs que daremos conta somente em modo de execução.


Tipo Ponteiros

Os ponteiros em Object Pascal têm o mesmo poder dos ponteiros em C / C++, porém são muito menos utilizados.

Vejamos algumas comparações de sintaxe de ponteiros em Delphi e C.

Linguagem

C

Delphi (pascal)

Declaração

tipo * apontador;

var apontador: ^tipo;

Exemplos

int * PointerPara_int;
char * string;

var PointerPara_integer: ^integer;
Mensagem: ^String[40];


Para usarmos apontadores é necessário fazê-los apontar para a referência correta. Um apontador nulo ou inválido faz com que o programa aborte. Para usar o valor referenciado por um apontado, utilizamos a seguinte sintaxe:

Linguagem

C

Delphi

Sintaxe

* apontador

apontador^

Exemplos

a = *b;
*a = *a + 1;

a := b^;
a^ := a^ + 1;


Para inicializar apontadores, é necessário "apontá-lo" para o endereço de memória no qual se deseja referenciar. Isso pode ser feito através do operador "cria pointer". Veja os exemplos abaixo:

C

Delphi

int main() {

int dia = 5;

int mes = 1;

int *ap;

ap = &dia;

*ap --;

ap = &mes;

*ap ++;

}

var dia, mes: integer;

ap: ^integer;

begin

dia := 5;

mes := 1;

ap := @dia;

dec(ap^);

ap := @mes;

inc(ap^);

end;

Para usar a memória dinâmicamente, ela precisa ser alocada. A alocação de memória reserva um bloco de memória e armazena o seu endereço em um apontador, para futuras referências. Existem várias formas para se alocar memória. Abaixo estão algumas:

Linguagem

C

Delphi

Declaração

char *buffer;

type tBuffer = array[0..1023] of char;
var Buffer: ^tBuffer;

Alocação

buffer = (char *)malloc(1024);

buffer = (char *)calloc(1024,1);

getmem(Buffer, 1024);

Liberação

free(buffer);

freemem(Buffer, 1024);


Um apontador pode referenciar outro apontador ao invés de uma variável. Esse recurso é em geral utilizado quando um apontador é passado para uma função, por referência. A função abaixo, por exemplo, aloca memória e testa se a alocação foi bem sucedida:

C

Delphi

void aloca(void **apont, int tamanho) {

*apont = (void *) malloc(tamanho);

if (*apont == NULL) {

printf(stderr, "Erro alocando buffer!\n");

exit(-1);

}

}

type tBuffer = array[0..1000] of char;

pBuffer = ^tBuffer;

procedure aloca(var apont: pBuffer; tamanho: integer);

begin

getmem(apont, tamanho);

if (apont = nil) then begin

writeln('Erro alocando buffer!');

halt(-1);

end;

end;

A linguagem pascal usa a palavra reservar "var" para indicar que a passagem de parâmetros foi feita por referência e evita a necessidade de se tratar o apontador para apontador diretamente na linguagem.