Programação Orientada A Eventos FreePascal + Lazarus

Fazer download em pdf ou txt
Fazer download em pdf ou txt
Você está na página 1de 121

Programação Orientada a Eventos

FreePascal + Lazarus

Armando Jorge Sousa ([email protected])

Professor Auxiliar
Depart. de Engenharia Electrotécnica e de Computadores
FEUP

Versão 9, 30 Março 2008

[email protected] --- 1 ---


Índice

● Introdução POE
● Solução FPC/Lazarus
● Resenha Histórica
● Básicos de FreePascal (Object Pascal)
● Lazarus IDE (e primeiro programa)
● Lazarus IDE avançado
(incluindo debugger e navegação em programas longos)
● FPC avançado (e algumas configurações do IDE)
● Controlos visuais (padrão) mais frequentes
● Componentes adicionais

[email protected] --- 2 ---


Introdução

[email protected] --- 3 ---


Paradigma «Programação Orientada a Eventos» (POE)

● O SO fornece um sistema de processamento de eventos em ciclo


▪ Eventos podem ser clicks do rato, mensagens de rede, etc.
▪ A linguagem colabora mapeando callbacks
▪ Adicionando eventos à fila
● Os programas do utilizador são chamados pelo SO
▪ Processam o evento comunicado pelo SO e retornam
▪ O sistema operativo com interface gráfica distribui eventos
(pelos diversos programas) - Multi Janela !
▪ As “forms” janelas pertencem a diferentes programas !
● Estes conceitos integram bem com Multi-Processo / Multi-User

[email protected] --- 4 ---


Benefícios da Programação Orientada a Eventos (POE)

● SO e linguagem colaboram no sentido de:


▪ Optimizar o desempenho / eliminar polling
▪ Identificar Idle Time
▪ Atender eventos na lista de forma adequada
▪ Diminuir mudanças de contexto (forçadas)
▪ Tornar transparentes os acessos remotos ou ao hardware
▪ Facilitar a programação gráfica / interactiva

[email protected] --- 5 ---


Conceitos a abandonar quando se faz POE

● Abordagem procedimental pura


● A noção dos microcontroladores de “tempo para «queimar»”
● Loops de espera
● Operações de polling

Abandonar em definitivo a noção de que o


programa tem um ciclo principal,
começa aí e aí acaba

[email protected] --- 6 ---


Linguagens de programação modernas

● Funcionalidades acrescidas
▪ Independência de SO e ao hardware
● Abordagem JAVA: Máquina Virtual
▪ Byte Code a interpretar(/JIT Compile) é portável
▪ Lento (...)
● Outra abordagem (FPC/Lazarus):
▪ O ambiente de desenvolvimento e a linguagem asseguram a
correcta implementação das mesmas funcionalidades em
ambientes diferentes
▪ Portar para outro ambiente SO/HW implica recompilar
▪ Código executável convencional (rápido)

[email protected] --- 7 ---


Estrutura de camadas

Lazarus / Delphi / Kylix


Maiores
FCL + LCL / VCL / CLX Funcionali-
S.O. Windows / S.O. Linux dades
Hardware
● Funcionalidades
● VCL – Delphi
Cross-Platform à custa de
diversas camadas de software
● CLX – Delphi>=6 e Kylix ● “Footprint” grande
● Não mais lentos por causa
● FCL e LCL - Lazarus disso...

[email protected] --- 8 ---


FPC/Lazarus

[email protected] --- 9 ---


Uma Solução Possível: Lazarus + FreePascal

• “Freeware” with source


• Sem royalties / GPL !
• Bibliotecas LGPL* (pode linkar estaticamente)
• RAD (Rapid Application Development)
• GUI altera código fonte após edição (2 way tool)
• Cross Platform
• Fácil ligação a diversos SGBD
• Facilmente Extensível: pacotes e componentes
• Permite POE ou não + facilidade de instalar servidores
• Linguagem OO, moderna, simples mas poderosa
• Inclui excepções, variantes e operator overloading

[email protected] --- 10 ---


Lazarus cross-platform


FPC+Lazarus portado para:

Processadores:

Intel x86, Amd64/x86 64, PowerPC, Sparc, ...
● Sistemas Operativos:
● Windows 32, Linux, FreeBSD, Mac OS X/Darwin,

Mac OS classic, DOS, OS/2, Netware (libc and


classic), MorphOS, ...

[email protected] --- 11 ---


Histórico

[email protected] --- 12 ---


História do Lázarus

• Borland:
• Turbo Pascal / B. Pascal + Delphi + Kylix

• Internet:
• Free Pascal + Lazarus

• Lazarus feito em Lazarus + FPC,


“autocompilável” !

[email protected] --- 13 ---


História do Lázarus

• Pascal (1971):
• Simplificação do Algol (1960)
• Genérica
• Educativa (ponteiros, “:= vs ==”,... )
• Strong Typed
• Case Insensitive
• Statically Linked
• Rápida
• Inicializações/Finalizações

[email protected] --- 14 ---


Desenvolvimento Integrado - IDEs

• Borland Turbo Pascal


• DOS - IDE - 1983
• Borland Delphi
• Windows – RAD - 1993
• Borland Kylix
• Linux - RAD - 2001
• Actualmente “clássico” da Borland
• Lazarus: RAD Cross Platform

• Outro RAD muito diferente: MS .NET studio

[email protected] --- 15 ---


Lazarus TimeLine

• Free Pascal - 1993


• FCP 1.0 – 2000
• FPC 2.0 – 2005
• Lazarus começa em 1999
(renascido depois do projecto “Megido”)
• Lazarus 0.9.20 - 2007
• Lazarus 1.0 – brevemente !

[email protected] --- 16 ---


FreePascal / Object Pascal

• Object Reference Model


• Herança, instanciação, propriedades, métodos,
overloading, polimorfismo
(só em run time se vai saber o método)
• Private / Protected / Public
• Cascata de criações/libertações
• Excepções

[email protected] --- 17 ---


• Programação para os S.O. actuais:

Programação Visual !!!


Orientada aos Eventos !!!

• Para cada acção na GUI ou cada evento, o S.O.


chama determinada rotina do programa

[email protected] --- 18 ---


Robustez Multi-Thread -- Synchronize

• Evitar conflitos entre threads (Thread Safe), ver:


http://wiki.lazarus.freepascal.org/index.php/Multithreaded_Application_Tutorial

• Programa deve libertar processador para o SO sempre que


espera, ie., não deve haver ciclos de espera

• Para programação gráfica a eventos não é necessário


recorrer a mutex'es

[email protected] --- 19 ---


Introdução ao Pascal

• EBooks gratuitos
“Essential Pascal” e “Essential Delphi”
No URL:
http://www.marcocantu.com

• Ver na biblioteca qualquer livro do mesmo autor!

• Tutorial de Pascal_FPC
http://www.taoyue.com/tutorials/pascal/

[email protected] --- 20 ---


FreePascal
FPC

[email protected] --- 21 ---


Documentação FreePascal + Lazarus

•Documentação de referência do FreePascal (FPC)


ftp://ftp.freepascal.org/pub/fpc/docs-pdf/ref.pdf

• Documentação do Lazarus:
http://lazarus-ccr.sourceforge.net/docs/

• Tutoriais do Lazarus
http://wiki.lazarus.freepascal.org/Special:Allpages

• Lazarus DB FAQ
http://wiki.lazarus.freepascal.org/index.php/Lazarus_DB_Faq

quase tudo o que disser respeito a kylix ou delphi !!!

[email protected] --- 22 ---


Estrutura do Código

Program Elementar;

begin

// ...

end. // termina com ponto final

[email protected] --- 23 ---


Dicas para pascal

• Atribuições :=
• Comparações =
• Strong Typed (casts automáticos limitados)
• Case Insensitive
• Inicializações/Finalizações
• Blocos com begin/end
• Programas e unidades terminam com end.

[email protected] --- 24 ---


Estrutura do Código

Program Elementar;

const
csAVOG : real = 6.02; // constante global

var
UmInteiro : integer; // var global

begin

// ...

UmInteiro:=Trunc(csAVOG);

// ...

end.

[email protected] --- 25 ---


Estrutura do Código

• O nome do program será o


Program elementar; nome do ficheiro de disco
(elementar.pas) e
Uses Forms {sistema}, MyUnit; possivelmente dará o nome
do executável
begin
• Um programa utiliza units do
// ... sistema e do utilizador, que
são linkadas para produzir o
Application.Run; executável

end. • As units permitem dividir o


código em blocos
• Tipicamente 1 form implica
uma unit para encapsular
todo o código associado

[email protected] --- 26 ---


Estrutura do Código

• O nome da unit será o nome


unit MyUnit; do ficheiro de disco
(MyUnit.pas)
interface • A porção de código
// definições e declarações
// a exportar “Interface” é conhecida
pelos módulos exteriores à
implementation unit
// código local à unit • A porção “implementation” é
local e inacessível do
end. exterior

[email protected] --- 27 ---


Estrutura do Código

unit MyUnit;
• MyUnit utiliza e importa a
interface
interface das unidades A,B,C
uses A, B, C; • MyUnit exporta as declarações de
const AlmostZero = 0.001; AlmostZero e TotalSum
• O programa unidades podem
var TotalSum: Real;
utilizar MyUnit
// ...

Program elementar;
• Programa utiliza MyUnit
Uses
Forms, MyUnit; • Passa a conhecer as variáveis
globais da unidade MyUnit
/// ... (AlmostZero e Total)

[email protected] --- 28 ---


Estrutura do Código

// ...

implementation

uses // outras units a importar/utilizar


D, E;

var // variável local (não será exportada)


UmInteiro : Integer;

procedure MyProcedure;
begin
// ...
end;

initialization
// Inicialização da unidade (opcional)

finalization
// Finalização da unidade (opcional)
end.

[email protected] --- 29 ---


IDE Lazarus

[email protected] --- 30 ---


File,
New Application

 Gere um Projecto
que inclui:
 Programa
 Unit (Forms)
 Unit

 2 Way !!!
 Editor gráfico
encontra código
adequado (...)
 Mudar nome de
componente muda
código todo (...)

[email protected] --- 31 ---


[email protected] --- 32 ---
[email protected] --- 33 ---
 File, Save ALL: unit_ola, project_ola

 Mudar “Name” da Form para “Form_Ola”


“Caption” vem mudada (ver no editor)

 Colocar TButton na Form


 Mudar “Name” para BProximo
 Botões devem começar com letra “B”
 Mudar “Caption” para “Próximo”

[email protected] --- 34 ---


• Fazendo Double Click no botão da form que estamos a
desenhar, o IDE leva-nos até ao código que será executado
quando (em run-time) o utilizador premir o botão uma vez
(evento “OnClick”)

procedure Tform_Ola.BProximoClick (Sender: TObject);


begin
|
end;

[email protected] --- 35 ---


Código do Projecto Elementar de Teste

procedure Tform_Ola.BProximoClick(Sender: TObject);


begin
BProximo.Caption:='Olá Mundo';
end;

• Após introduzir o código mostrado acima, premir F9 ou


seleccionar Menu Run, Opção Run para compilar o código
e executá-lo de seguida
• Depois de compilar sem problemas, o programa gerado é
executado e aparece a janela que desenhamos
• Depois de carregar no botão, o texto inscrito no botão
caption é alterado e passa mostrar “Olá Mundo”
• Saia da aplicação carregando no x do canto da form

[email protected] --- 36 ---


Código do Projecto de teste 2

[email protected] --- 37 ---


SnapShots do projecto de teste 2 (windows e linux)

[email protected] --- 38 ---


Notas para iniciados

● Para facilidade de localização dos ficheiros importantes,


criar uma directoria para cada projecto novo
● Criar o projecto e logo depois gravar todos os ficheiros
(Save All); gravar todos os ficheiros da aplicação na mesma
directoria
● Não alterar código que não foi feito por nós !!!
● Ligar logo as opções de verificação: Project,
Compiler_Options, Code:

[email protected] --- 39 ---


IDE Avançado

[email protected] --- 40 ---


Ajudas à codificação: Code Templates

for (premir CTRL+J)

for | := to do
begin
forb (premir CTRL+J)
end;

[email protected] --- 41 ---


Ajudas à codificação: Code Templates

If, CTRL+J => menu de templates


ifb,CTRL+J=>if| then/begin/end

[email protected] --- 42 ---


Ajuda à codificação: Completion

CTRL+SPACE: Context sensitive Completion

[email protected] --- 43 ---


Ajuda à codificação: Navegação em código extenso

● Bookmarks (máximo de 10 pontos de interesse no código):


▪ Para definir um ponto de interesse no código:
CTRL+Shift+.. (teclas de 1 a 0)
▪ Para levar o cursor até um ponto de interesse no
código: CTRL+.. (teclas de 1 a 0)
● Saltar entre Declaração e Código de procedimento ou
função: CTRL+ e CTRL+
● Saltar para a declaração de variável: CTRL+MouseClick
● Saltar (de volta) para ponto anterior de edição: CTRL H

[email protected] --- 44 ---


Ajuda à codificação: Navegação entre janelas

● F12: troca entre form e código

● F11: Object Inspector


● CTRL+F12: View Units
● Shift+F12: View Forms

[email protected] --- 45 ---


Debugging

[email protected] --- 46 ---


Debugging

Breakpoint

[email protected] --- 47 ---


Debugging

● Premir Ctrl+Alt+L para listar todas as variáveis locais


● Para o cursor do rato em cima de uma variável para ver o
seu valor (funcionalidade em melhoramento)
● Premir F7/F8 para single stepping
● Premir F4 para ir até ao cursor

[email protected] --- 48 ---


Help de contexto

● Premir F1 leva a activar o browser para levar a uma página


de context sensitive help, ie, leva a um help associado ao
texto onde o cursor está

procedure Tform_Ola.BProximoClick(Sender: TObject);


begin
BProximo.Caption|:='Olá Mundo';
end;

● Com o cursor no texto caption do botão, o help de


TControl.Caption é mostrado no browser

[email protected] --- 49 ---


Dúvidas Frequentes

• Procedure não devolve dados


• Function devolve dados

• If (x=y) then begin


x:=x+1;
end else begin // cuidado não pode ter “;” !!!
x:=x+2;y:=x+2;
end;

• Format( ' Total %d ' , [ N ] );

[email protected] --- 50 ---


Funções

• Function devolve um dado de determinado tipo

function InverteString ( S : string ) : string;

var
TempStr : string;
i : integer;
Siz : integer;

begin
TempStr:='';
Siz:=length(S);
if Siz>0 then
for I:=Siz downto 1 do
TempStr:=TempStr+S[I]; !
InverteString:=TempStr;
end;

[email protected] --- 51 ---


Funções e tipos de parâmetros

// Func1 passa param de entrada na função por cópia


// Mudar S dentro da função não altera S fora da função !
function func1 ( S : string ) : string;
// ...

// Func2 passa param por endereço (param. de entrada e saída)


function func2 ( var S : string ) : string;
// ...

// Func3 passa param const -> compilador não deixa alterar


// E S_out é parâmetro de saída
procedure func3 ( const S_in : string ; out S_out : string );
// ...

[email protected] --- 52 ---


Funções multi parâmetros

procedure func4 (const S1,S2 : string; out S3 : string) ;

function func5 ( i,j,k : integer ; s : string ) : string ;

[email protected] --- 53 ---


ShowMessage

ShowMessage('Olá, isto é um teste');

[email protected] --- 54 ---


Pascal Avançado

[email protected] --- 55 ---


Referência

• Prioridades:
• unários[@,not,-]
• *,/,div,mod,and,shl,shr
• +,-,or,xor,=,<>,<,>,<=,>=, in/is
• Tipos básicos
• string / Pchar, integer, boolean, char,
TDateTime, Set, Pointer, variant...
• high(vector)/low(vector)/sizeof(variável)
• Ord(...)+Chr(...)

[email protected] --- 56 ---


Projecto, Unidade e Form

• Project, New Project,


program Project1; Application cria uma nova
(●●●) aplicação vazia
• É criado um projecto vazio
uses
(●●●) Unit1;
e uma unidade vazia
associada a uma form vazia
begin • Programa é Project1
Application.Initialize;
Application.CreateForm(TForm1, Form1); • Utiliza a Unit1
Application.Run; • Para ver este ficheiro fazer
end.
Menu Project, View Source
• Este código é gerado e
gerido automaticamente,
não é necessário
alterar nada !

[email protected] --- 57 ---


Unidade e Form

unit Unit1;
• Na interface da Unit1 é
interface
definida a TForm1 e a
(●●●) variável Form1
• Neste caso a Form1 tem um
type
{ TForm1 } botão e um procedimento
Button1Click(...)
TForm1 = class(TForm) • É o programa (não a
Button1: TButton;
procedure Button1Click((●●●)); unidade) que dá instruções
(●●●) ao S.O. para efectivamente
end; abrir a janela e executá-la
var • Adicionando componentes à
Form1: TForm1; form, o código da definição
do tipo da form é alterado
Obs: A classe não descreve na automaticamente
totalmente a form !

[email protected] --- 58 ---


Unidade e Form

object Form1: TForm1


Left = 412
Height = 320
Top = 121
Width = 400
(●●●)
object Button1: TButton • A descrição completa da
Left = 86 form estará no ficheiro .lfm
Height = 25
Top = 70
Width = 75 • Não alterar nada !
OnClick = Button1Click
(●●●)
end
end

[email protected] --- 59 ---


Tipos

Type

// Começar os tipos por 'T'

TUpCaseLetters = 'A'..'Z'; // subrange

TDaysOfMonth = array [1..31] of Integer;

TMyDate = record
Month : Byte;
Day : Byte;
Year : Integer;
end;

[email protected] --- 60 ---


Tipos

type
// tipo enumerado
TColors = ( ColorRed, ColorGreen, ColorBlue ); // RGB

// set, isto é, conjunto !!!


TSetOfLetters = set of Char;

var
AnArray: array [10..24] of Byte;
ColorCode: array [ColorRed .. ColorGreen] of Word;
Palette: set of TColors;

[email protected] --- 61 ---


Operações com Conjuntos (sets)

type
TSetOfLetters = set of Char;
var
Letters1, Letters2 : TConjLetras;
begin
Letters1 := ['A', 'B', 'C'];
Letters2 := [];
if ('A' in Letters1) then ShowMessage('A');
if (['A','B'] <= Letters1) then ShowMessage('A,B');
if (['E'] <= Letters1) then ShowMessage('Falso');
if (Letters2 = []) then ShowMessage('Vazio');
end;

[email protected] --- 62 ---


Range Check

type
TDozen = array [1..12] of Integer;
var
UmMes : TDozen;

procedure WorkSomethingOnADozen;
begin
UmMes[1] := 10;
UmMes[2] := 12;
UmMes[0] := 18; // erro compile-time
UmMes[25] := 18; // erro compile-time
end;

[email protected] --- 63 ---


type

TBiDimVector = array [1..12, 1..12] of Integer;

var

ABiDimVector : TBiDimVector;

[email protected] --- 64 ---


Apontadores

type
PointerToInt = ^Integer;

var
P: ^Integer;
X : Integer;

begin
P := @X;
// Muda variável de duas formas diferentes
X := 10;
P^ := 20;
end;

[email protected] --- 65 ---


Apontadores

var
P: ^Integer;

begin

New (P); // criar / iniciar

P^ := 20; // atribuir

ShowMessage (IntToStr (P^));

Dispose (P); // terminar

end;

[email protected] --- 66 ---


Apontadores – com detecção de limites (range check)

procedure TForm_Ola.Button1Click(Sender: Tobject);


var
x : integer;
DayTemp : array [ 1 .. 31 ] of Integer;
begin
x:=123456;
DayTemp [x] := 18; // GPF – Segmentation Fault
end;

[email protected] --- 67 ---


IFs

if N>0 then begin


ShowMessage('Positivo');
if N>1 then begin
ShowMessage(' >1');
end;
end else begin // relativo ao N>0 (ie N<=0)
ShowMessage('Negativo');
if N<-1 then begin
ShowMessage(' <-1');
end;
end;

[email protected] --- 68 ---


Case

case MyChar of
'+' : Text := 'Soma';
'-' : Text := 'Subtracção';
'*', '/' : Text := 'Multiplicação ou divisão';
'0'..'9' : Text := 'Algarismo';
'a'..'z' : Text := 'Minúscula';
'A'..'Z' : Text := 'Maiúscula';
else
Text := 'Outro Caracter';
end;

[email protected] --- 69 ---


Ciclo for

... • A variável do ciclo


Soma := 0; pode ser qualquer
for i := 1 to 10 do ordinal, incluindo
Soma := Soma + i; tipos enumerados
...
• Ciclos for são muito
mais restritivos em
Pascal que em C

... • Tal como em qualquer


Soma := 0; outro ciclo for, o corpo
for i := 10 downto 1 do do ciclo pode ser não
begin executado nunca
Soma := Soma + i;
end;
...

[email protected] --- 70 ---


Ciclos While e Repeat Until

While ( (I <= 100) and (J <= 100) ) do


begin
...
I := I + 1;
J := J + 1;
end;

repeat
...
I := I + 1;
J := J + 1;
until (I > 100) or (J > 100);

[email protected] --- 71 ---


Procedimentos e funções

function DoubleVersion1 (Value: Integer) : Integer;


begin
DoubleVersion1 := Value * 2;
end;

function DoubleVersion2 (Value: Integer) : Integer;


begin
Result := Value * 2;
end;

procedure DoubleProc (var Value : Integer);


begin
Value := Value * 2;
end;

[email protected] --- 72 ---


Vectores Dinâmicos

Var DynArray : Array of Integer; // Vector Dinâmico

procedure TForm1.FormCreate(Sender: TObject);


begin
SetLength (DynArray, 100); // alocar
end;

procedure TForm1.BFillClick(Sender: TObject);


var I: Integer;
begin
for I := Low (DynArray) to High (DynArray) do
Array1 [I] := I;
end;

procedure TForm1.BGrowClick(Sender: TObject);


begin
SetLength (DynArray, 200); // mantém + cresce lim sup
end;

[email protected] --- 73 ---


Formatação de Strings

string:=format ('%-8d,%f', [var_i,var_f]);

TYPE SPECIFIER DESCRIPTION


The corresponding integer value is converted to a string of
d (decimal)
decimal digits.
The corresponding integer value is converted to a string of
x (hexadecimal)
hexadecimal digits.
The corresponding pointer value is converted to a string expressed
p (pointer)
with hexadecimal digits.
The corresponding string, character, or PChar value is copied to
s (string)
the output string.
The corresponding floating-point value is converted to a string
e (exponential)
based on exponential notation.

[email protected] --- 74 ---


Formatação de Strings

The corresponding floating-point value is converted to a string


f (floating point)
based on floating point notation.
The corresponding floating-point value is converted to the
g (general) shortest possible decimal string using either floating-point or
exponential notation.
The corresponding floating-point value is converted to a floating-
n (number)
point string but also uses thousands separators.
The corresponding floating-point value is converted to a string
representing a currency amount. The conversion is based on
m (money)
regional settings-see the Delphi Help file under Currency and
date/time formatting variables.

[email protected] --- 75 ---


Ciclos Prolongados

for i := 1 to VeryLargeNumber do begin


Application.ProcessMessages;
Total := Total + i;
end;

for i := 1 to VeryLargeNumber do begin


Application.HandleMessage; // Permite IdleTime
Total := Total + i;
end;

[email protected] --- 76 ---


Excepções (i)

var
n2, n1, n0 : integer;
begin
try
n0 := 0;
n1 := 1;
n2 := n1 div n0;
ShowMessage('1 / 0 = '+IntToStr(n2));
except
on E : Exception do
begin
ShowMessage('Nome da classe = '+E.ClassName);
ShowMessage('Mensagem da excepção = '+E.Message);
end;
end;
end;

[email protected] --- 77 ---


Excepções (ii)

...
except
// IO error
on E : EInOutError do
ShowMessage('IO error : '+E.Message);
// Dibision by zero
on E : EDivByZero do
ShowMessage('Div by zero error : '+E.Message);
// Catch other errors
else
ShowMessage('Unknown error');
end;

[email protected] --- 78 ---


Excepções (iii)

var
number, zero : Integer;
begin
// Try to divide an integer by zero - to raise an exception
number := -1;
Try
zero := 0;
number := 1 div zero;
ShowMessage('number / zero = '+IntToStr(number));
finally
if number = -1 then
begin
ShowMessage('Not assigned - using default');
number := 0;
end;
end;
end;

[email protected] --- 79 ---


Excepções (iv)

...
int2:=2;int1:=1;int0:=0;
vf2:=2.0;vf1:=1.0;vf0:=0.0;
try
case RadioGroup.ItemIndex of
0 : int2 := int1 div int0;
1 : vf2 := vf1 / vf0;
2 : assert(False,'Just Testing');
end;
Memo.Append('Sem erro:='+FloatToStr(vf2)+';'+ IntToStr(int2));
except
on E : EDivByZero do
Memo.Append('Div int por 0:'+e.ClassName+': '+e.Message);
on E : EZeroDivide do
Memo.Append('Div Virg Flt 0:'+e.ClassName+':'+e.Message);
on E : Exception do Memo.Append('outro erro -- '+
e.ClassName+': '+e.Message);
end;
Memo.Append('Continua, Normal');
...

[email protected] --- 80 ---


Variants

procedure TFormMain.Button1Click(Sender: TObject);


var
V : Variant;
I : Integer;

begin
V:='100';
I:=V;
Button1.Caption:='I = ' + IntToStr(I); // OK
V:='Something else';
I:=V;
Button1.Caption:='I = ' + IntToStr(I); // NOK
end;

• Something else não é um inteiro válido

•Na 2ª atribuição é gerada uma excepção

[email protected] --- 81 ---


Código Condicional (cross platform, etc)

{$IFDEF LINUX}

// Código para Linux

{$ELSE}

// Código para outras plataformas

{$ENDIF}

[email protected] --- 82 ---


Componentes & Pacotes

• Para acrescentar
funcionalidades, qualquer
programador pode criar
componentes

• Components, Open Package

• Package graph

[email protected] --- 83 ---


Mais Controlos
Visuais Padrão

[email protected] --- 84 ---


Botões

● TButton
● TBitButton
● TSpeedButton

[email protected] --- 85 ---


Texto numa linha

● TLabel

● TEdit

● TStatusBar

[email protected] --- 86 ---


Caixa de texto (memo box)

● TMemo

● Baseado na classe TStrings


que permite muitas operações
interessantes !

[email protected] --- 87 ---


TMemo

... with FormMain.Memo do begin ...

• Append('Mais Uma Linha');

• Lines.SaveToFile('c:\memo.txt'); // windows

• Lines.Delete(0); // apaga primeira linha

• Lines[0]:='... substitui a 1a linha ...';

• UmaStringGrande:=text; // toda a memo

• Memo.Lines.LoadFromFile('~/memo.txt'); // linux

... end; ...

Obs1: Ver Scroll Bars, Wrap, ReadOnly, ...


Obs2: Ver variável global DirectorySeparator

[email protected] --- 88 ---


CheckBox / Group

● TCheckBox
● TCheckGroup

[email protected] --- 89 ---


RadioGroup

● TRadioGroup

[email protected] --- 90 ---


ListBox e ComboBox

[email protected] --- 91 ---


Image, PaintBox, Shape

● TImage (.Picture)
● TPaintBox (.Canvas)
● TShape (.Canvas)

[email protected] --- 92 ---


Caixas de diálogo Standard (Gravar, Abrir, ...)

● Componentes que desaparecem


durante a execução do código
● Chamam as caixas standard do S.O.
● OpenDialog1, SaveDialog, SelectDirectoryDialog
● Chamar método execute

[email protected] --- 93 ---


Temporizador

● TTimer (separador system)


● Tempo em milisegundos
● Dificuldades em cumprir
restrições de tempos curtos

[email protected] --- 94 ---


Gráficos

● TBarChart

[email protected] --- 95 ---


Menus

● TMainMenu
▪ Fazendo double click abre-se o editor de menus
▪ É possível acrescentar diversas opções:
◦ check box
◦ Ícone
◦ Tecla atalho
◦ ...

[email protected] --- 96 ---


Componente de persistência

● TXMLPropStorage
(Separdor Misc)
(depois utilizar a propriedade da form.SessionProperties)
● À saída do programa grava-se estado actual dos elementos
listados em SessionProperties que serão carregados de volta
à entrada, eliminando necessidade de gravar
explicitamente configurações
● Grava um ficheiro em formato XML

● Existe um outro componente TIniPropStorage


que faz o mesmo com ficheiros INI

[email protected] --- 97 ---


Aplicções Multi Form

● Para acrescentar ao projecto File, New Form (acrescenta


uma unidade para esta form)
● Para mostrar uma form:
▪ A form nova é criada automaticamente
▪ É necessário utilizar a unit correspondente:
uses UnitWhereFormSecondaryIs
▪ FormSecondary.Show;
● Para fechar fechar a form
▪ FormMain.Close;
● Para obrigar a ter apenas uma janela da aplicação activa:
▪ FormSecondary.ShowModal;

[email protected] --- 98 ---


Componentes
Externos Úteis

[email protected] --- 99 ---


Componentes a utilizar

• ZeosLib - http://sourceforge.net/projects/zeoslib/

• A ligação ao PostGreSQL é nativa a partir da


versão Lazarus 0.9.12

• Sdpo_Serial – 5dpo component pack

• lNnet - LightWeight Networking Library


http://wiki.lazarus.freepascal.org/lNet

• Todos estes pacotes são (win32 + linux)

[email protected] --- 100 ---


Sdpo Serial

• Para utilizar SDPO_Serial sob Linux


• uses cthreads em 1º em todas as units e no *.LPR

•{$DEFINE UseCThreads} no *.LPR


(abrir o *.LPR através do Project Inspector)
[automático no lazarus 0.9.20]
• Recompilar o Lazarus e o LCL com a opção
-dUseCThreads
(Tools, Configure Build Lazarus e depois Build Lazarus)
• Obs1: executar o programa na command line para obter
mensagens de erro adicionais
• Obs2: a sincronização (-dUSE_SYNCHRONIZE)
é desnecessária a partir da versão 0.9.12 do Lazarus

[email protected] --- 101 ---


Lazarus FAQs

After I installed a component, Lazarus crashes with the following message:


Threading has been used before cthreads was initialized. Make cthreads one of the first units in
your uses clause. Runtime error 211
How can I fix this?
Your freshly installed component is using threads. Fpc on *nix doesn't automatically include threading
support, but it must be intialized. This initialization is done in the cthreads unit. Every application
using the component needs to add this unit to the uses clause of the main program. Lazarus itself is
no exception. This can be done in two ways:
1) Change the source of ide/lazarus.pp: add the cthreads as first unit to the uses clause, so that is looks
like this:
uses
cthreads,
{$IFDEF IDE_MEM_CHECK}
...
and rebuild lazarus. [su, cd laz_dir, make clean bigide ou make clean all]

[email protected] --- 102 ---


Lazarus FAQs

2) In order to avoid modifying lazarus.pp file, a fpc compiler option could be used. Once package that
uses threads has been compiled, open menu Tools->Configure "build Lazarus". Configure "build
Lazarus" dialog will be shown, in field "Options:" type -Facthreads and then press "OK" button. The
next step is to install the package. Lazarus will be built with option -Facthreads which means that it
will treat main program as if unit cthreads where first in uses clause.

Hint:
Maybe your old (non-crashing) lazarus executable is stored as lazarus.old in the same directory as
the crashing lazarus executable.

[email protected] --- 103 ---


Mais detalhes funcionamento Porta Série

• Comando exemplo envio:


SdpoSerial.WriteData(EditSend.text);
• Receber:
• Evento OnRxData tem cadência imprevisível -
algumas vezes pode-se receber byte a byte, outras não,
é obrigatório o programa lidar com este facto !!!
• Exemplo de recepção:
SdpoSerial.SynSer.RecvPacket(0);
• Cuidado com as permissões e os portos (tty0, ttyUSB0):
chmod a+rw /dev/tty*
chmod a+rwx /var/lock

[email protected] --- 104 ---


RADs & acesso Bases de Dados

● Cursor – aponta para um tuplo (linha de tabela de BD)


● Dataset – colecção de tuplos (tabela de BD)
● BD: Local ou Remota (Cliente / Servidor)
▪ CLI - Call Level Interface
▪ ODBC JDBC BDE
● Propriedades ACID:
Atomicity-Consistency-Isolation-Durability
● Middleware: CORBA, DCOM, DataSnap (=MIDAS)
● D6 & Kylix dBExpress – SQL Thin DB access Layer

[email protected] --- 105 ---


Data Aware Objects (i)

SGBD

DBGrid
Query/ DBEdit
DataSource
/Dataset DBLabel
...

[email protected] --- 106 ---


Sequência para ligar à BD PGSQL em Lazarus 0.9.12

•Colocar na form os componentes das respectivas tabs:


• PQConnection - SQLdb
• SQLQuery - SQLdb
• SQLTransaction - SQLdb
• DataSource - DataAccess
• DBGrid - DataControls
•PQConnection preencher:
• Transaction + Database + HostName + UserName + password
•Verificar que SQLTransaction aponta para PQConnection
•Na SQLQuery preencher:
• Transacção + Database
• SQL (exemplo: 'select * from anytable')
•Na DataSource preencher DataSet como SQLQuery
•Na DBGrid preencher DataSource

[email protected] --- 107 ---


Data Aware Objects (ii) - DBGrid

[email protected] --- 108 ---


Data Aware Objects (iii) - DBEdit

...
dbGrid.ReadOnly:= ... (sempre!!!)
...
SQLQuery.Post;
...

[email protected] --- 109 ---


Alterações directas à Base de Dados

...
begin
enter:=chr(13)+chr(10);
s:='update copias set nalugueres=nalugueres+1 where'+
'codcopia='+IntToStr(EstaCopia); // string de código SQL
try
PQConChange.Connected:=True;
PQConChange.ExecuteDirect('Begin Work;');
PQConChange.ExecuteDirect(s);
PQConChange.ExecuteDirect('Commit Work;');
PQConChange.Connected:=False;
except
on E : EDatabaseError do
MemoLog.Append('ERROBD:'+enter+
E.ClassName+enter+E.Message);
on E : Exception do
MemoLog.Append('ERRO:'+enter+
E.ClassName+enter+E.Message);
end;
end;

[email protected] --- 110 ---


Observações acerca de Lazarus e PGSQL

• Não utilizar dados tipo “text” mas sim “varchar”


• Não utilizar “numeric” mas antes inteiros ou “float8”
• As tabelas devem ter uma chave primária
• Utilizar nomes sempre e só com minúsculas e sem caracteres
portugueses
• É obrigatório proteger todas as operações directas sobre a base de
dados com transacções
• É obrigatório o ficheiro libpq.dll e as outras DLLs binárias do
PostGreSQL estarem no path do sistema operativo

[email protected] --- 111 ---


Sockets com componente visual

● Descarregar a partir de:


▪ http://ovh.dl.sourceforge.net/sourceforge/lazarus-ccr/lnet-0.4.0.zip

● Instalar o *.lpk run_time e depois *.lpk relativo ao IDE

[email protected] --- 112 ---


lnet/visual/examples/tcpudp

...
FNet: TLNetComponent; // TCP ou UDP
...

procedure TForm1.LTCPComponentReceive(aSocket: TLSocket);


var
s: string;
begin
if aSocket.GetMessage(s) > 0 then begin
MemoText.Append(s);
MemoText.SelStart:=Length(MemoText.Lines.Text);
FNet.IterReset;
if FIsServer then repeat
FNet.SendMessage(s, FNet.Iterator);
until not FNet.IterNext;
end;
end;

[email protected] --- 113 ---


lnet/visual/examples/tcpudp

procedure TForm1.SendButtonClick(Sender: TObject);


var
AllOK: Boolean;
n: Integer;
begin
if Length(EditSend.Text) > 0 then begin
AllOk:=True;
if Assigned(FNet.Iterator) then repeat
n:=FNet.SendMessage(EditSend.Text, FNet.Iterator);
if n < Length(EditSend.Text) then begin
MemoText.Append('Error on send [' + IntToStr(n) + ']');
AllOK:=False;
end;
until not FNet.IterNext;
if FIsServer and AllOK then
MemoText.Append(EditSend.Text);
EditSend.Text:='';
end;
end;

[email protected] --- 114 ---


lnet/visual/examples/tcpudp

procedure TForm1.ListenButtonClick(Sender: TObject);


begin
if FNet.Listen(StrToInt(EditPort.Text)) then begin
MemoText.Append('Accepting connections');
FIsServer:=True;
end;
end;

procedure TForm1.ConnectButtonClick(Sender: TObject);


begin
if FNet.Connect(EditIP.Text, StrToInt(EditPort.Text)) then
FIsServer:=False;
end;

[email protected] --- 115 ---


lnet/visual/examples/tcpudp

procedure TForm1.DiconnectButtonClick(Sender: TObject);


begin
FNet.Disconnect;
MemoText.Append('Disconnected');
end;

procedure TForm1.SendEditKeyPress
(Sender: TObject; var Key: char);
begin
if Key = #13 then
SendButtonClick(Sender);
end;

[email protected] --- 116 ---


TAChart

procedure TForm1.Button1Click(Sender: TObject);


var
Serie:TTASerie;
i:Integer;
begin
Serie:=TTASerie.Create(TAChart1);
TAChart1.AddSerie(Serie);
Serie.ShowLines:=True;
Serie.ShowPoints:=False;
Serie.Title:='Sinus';
for i:=-500 to 499 do
Serie.AddXY(i/10,Sin(i/10)*10,clBlack);
end;

[email protected] --- 117 ---


Operator Overloading

type
complex = record type
re : real; complex = record
im : real; re : real;
end; im : real;
end;

// ... var
Z2:=Z1; R1 : real;
//... Z1,Z2 : complex;

// Atribuição de
// record's do // Operator Overloading
// mesmo tipo
// Z2:=Z1 operator := (r : real) z : complex;
// é a atribuição de begin
// todos os campos z.re:=r;
z.im:=0.0;
end;

[email protected] --- 118 ---


Ligações interessantes

● Mailing List do Lazaros, arquivo e pesquisa:


http://www.lazarus.freepascal.org/mailarchives
http://www.lazarus.freepascal.org/modules.php?op=modload&name=Search
● Todos os Wiki's:
http://wiki.lazarus.freepascal.org/Special:Allpages
● Lazarus & Pascal:
http://wiki.lazarus.freepascal.org/Lazarus_Documentation
● Bases de dados:http://wiki.lazarus.freepascal.org/index.php/Lazarus_Database_Tutorial

http://wiki.lazarus.freepascal.org/TPSQL
● RXLib:
▪ http://wiki.lazarus.freepascal.org/RXfpc
▪ http://www.alexs75.narod.ru/fpc/rxfpc/index.html

[email protected] --- 119 ---


Ligações interessantes

● http://wiki.lazarus.freepascal.org/Lazarus_Faq
● http://wiki.lazarus.freepascal.org/Installing_Lazarus
● http://wiki.lazarus.freepascal.org/LCL_Defines
● http://wiki.lazarus.freepascal.org/Getting_Lazarus
● http://wiki.lazarus.freepascal.org/Icon_Editor
● http://wiki.lazarus.freepascal.org/GLScene
● http://wiki.lazarus.freepascal.org/Multiplatform_Programming_Guide
● http://wiki.lazarus.freepascal.org/Multithreaded_Application_Tutorial
● http://wiki.lazarus.freepascal.org/lNet
● http://wiki.lazarus.freepascal.org/Pascal_Script

[email protected] --- 120 ---


Programação Orientada a Eventos
+ FPC/Lazarus

- Fim -

[email protected] --- 121 ---

Você também pode gostar