Programação Orientada a Eventos FreePascal + Lazarus Armando Jorge Sousa () Professor Auxiliar Depart. de Engenharia Electrotécnica e de Computadores FEUP Versão 9, 30 Março 2008 --- 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 --- 2 ---
Introdução --- 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 --- 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 --- 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 --- 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) --- 7 ---
Estrutura de camadas Lazarus / Delphi / Kylix FCL + LCL / VCL / CLX S.O. Windows / S.O. Linux Maiores Funcionalidades VCL Delphi CLX Delphi>=6 e Kylix Hardware Funcionalidades Cross-Platform à custa de diversas camadas de software Footprint grande Não mais lentos por causa FCL e LCL - Lazarus disso... --- 8 ---
FPC/Lazarus --- 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! --- 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,... --- 11 ---
Histórico --- 12 ---
História do Lázarus Borland: Turbo Pascal / B. Pascal + Delphi + Kylix Internet: Free Pascal + Lazarus Lazarus feito em Lazarus + FPC, autocompilável! --- 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 --- 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 --- 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! --- 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 --- 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 --- 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 --- 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/ --- 20 ---
FreePascal FPC --- 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!!! --- 22 ---
Estrutura do Código Program Elementar; begin //... end. // termina com ponto final --- 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. --- 24 ---
Estrutura do Código Program Elementar; const csavog : real = 6.02; // constante global var UmInteiro : integer; // var global begin //... UmInteiro:=Trunc(csAVOG); //... end. --- 25 ---
Estrutura do Código Program elementar; Uses Forms {sistema}, MyUnit; begin //... Application.Run; end. O nome do program será o nome do ficheiro de disco (elementar.pas) e possivelmente dará o nome do executável Um programa utiliza units do sistema e do utilizador, que são linkadas para produzir o executável As units permitem dividir o código em blocos Tipicamente 1 form implica uma unit para encapsular todo o código associado --- 26 ---
Estrutura do Código unit MyUnit; interface // definições e declarações // a exportar implementation // código local à unit end. O nome da unit será o nome do ficheiro de disco (MyUnit.pas) A porção de código Interface é conhecida pelos módulos exteriores à unit A porção implementation é local e inacessível do exterior --- 27 ---
Estrutura do Código unit MyUnit; interface uses A, B, C; const AlmostZero = 0.001; var TotalSum: Real; //... MyUnit utiliza e importa a interface das unidades A,B,C MyUnit exporta as declarações de AlmostZero e TotalSum O programa unidades podem utilizar MyUnit Program elementar; Uses Forms, MyUnit; ///... Programa utiliza MyUnit Passa a conhecer as variáveis globais da unidade MyUnit (AlmostZero e Total) --- 28 ---
Estrutura do Código //... implementation uses D, E; // outras units a importar/utilizar 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. --- 29 ---
IDE Lazarus --- 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 (...) --- 31 ---
--- 32 ---
--- 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 --- 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; --- 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 --- 36 ---
Código do Projecto de teste 2 --- 37 ---
SnapShots do projecto de teste 2 (windows e linux) --- 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: --- 39 ---
IDE Avançado --- 40 ---
Ajudas à codificação: Code Templates for (premir CTRL+J) forb (premir CTRL+J) for := to do begin end; --- 41 ---
Ajudas à codificação: Code Templates If, CTRL+J => menu de templates ifb,ctrl+j=>if then/begin/end --- 42 ---
Ajuda à codificação: Completion CTRL+SPACE: Context sensitive Completion --- 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 --- 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 --- 45 ---
Debugging --- 46 ---
Debugging Breakpoint --- 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 --- 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 --- 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 ] ); --- 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;! --- 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 ); //... --- 52 ---
Funções multi parâmetros procedure func4 (const S1,S2 : string; out S3 : string) ; function func5 ( i,j,k : integer ; s : string ) : string ; --- 53 ---
ShowMessage ShowMessage('Olá, isto é um teste'); --- 54 ---
Pascal Avançado --- 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(...) --- 56 ---
Projecto, Unidade e Form program Project1; ( ) uses ( ) Unit1; begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end. Project, New Project, Application cria uma nova aplicação vazia É criado um projecto vazio e uma unidade vazia associada a uma form vazia Programa é Project1 Utiliza a Unit1 Para ver este ficheiro fazer Menu Project, View Source Este código é gerado e gerido automaticamente, não é necessário alterar nada! --- 57 ---
Unidade e Form unit Unit1; interface ( ) type { TForm1 } TForm1 = class(tform) Button1: TButton; procedure Button1Click(( )); ( ) end; var Form1: TForm1; Obs: A classe não descreve na totalmente a form! Na interface da Unit1 é definida a TForm1 e a variável Form1 Neste caso a Form1 tem um botão e um procedimento Button1Click(...) É o programa (não a unidade) que dá instruções ao S.O. para efectivamente abrir a janela e executá-la Adicionando componentes à form, o código da definição do tipo da form é alterado automaticamente --- 58 ---
Unidade e Form object Form1: TForm1 Left = 412 Height = 320 Top = 121 Width = 400 ( ) object Button1: TButton Left = 86 Height = 25 Top = 70 Width = 75 OnClick = Button1Click ( ) end end A descrição completa da form estará no ficheiro.lfm Não alterar nada! --- 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; --- 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; --- 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; --- 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; --- 63 ---
type TBiDimVector = array [1..12, 1..12] of Integer; var ABiDimVector : TBiDimVector; --- 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; --- 65 ---
Apontadores var P: ^Integer; begin New (P); P^ := 20; // criar / iniciar // atribuir end; ShowMessage (IntToStr (P^)); Dispose (P); // terminar --- 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; --- 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; --- 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; --- 69 ---
Ciclo for... Soma := 0; for i := 1 to 10 do Soma := Soma + i;...... Soma := 0; for i := 10 downto 1 do begin Soma := Soma + i; end;... A variável do ciclo pode ser qualquer ordinal, incluindo tipos enumerados Ciclos for são muito mais restritivos em Pascal que em C Tal como em qualquer outro ciclo for, o corpo do ciclo pode ser não executado nunca --- 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); --- 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; --- 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; --- 73 ---
Formatação de Strings string:=format ('%-8d,%f', [var_i,var_f]); TYPE SPECIFIER d (decimal) x (hexadecimal) p (pointer) s (string) e (exponential) DESCRIPTION The corresponding integer value is converted to a string of decimal digits. The corresponding integer value is converted to a string of hexadecimal digits. The corresponding pointer value is converted to a string expressed with hexadecimal digits. The corresponding string, character, or PChar value is copied to the output string. The corresponding floating-point value is converted to a string based on exponential notation. --- 74 ---
Formatação de Strings f (floating point) g (general) n (number) m (money) The corresponding floating-point value is converted to a string based on floating point notation. The corresponding floating-point value is converted to the shortest possible decimal string using either floating-point or exponential notation. The corresponding floating-point value is converted to a floatingpoint 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 regional settings-see the Delphi Help file under Currency and date/time formatting variables. --- 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; --- 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; --- 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; --- 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; --- 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');... --- 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 --- 81 ---
Código Condicional (cross platform, etc) {$IFDEF LINUX} // Código para Linux {$ELSE} // Código para outras plataformas {$ENDIF} --- 82 ---
Componentes & Pacotes Para acrescentar funcionalidades, qualquer programador pode criar componentes Components, Open Package Package graph --- 83 ---
Mais Controlos Visuais Padrão --- 84 ---
Botões TButton TBitButton TSpeedButton --- 85 ---
Texto numa linha TLabel TEdit TStatusBar --- 86 ---
Caixa de texto (memo box) TMemo Baseado na classe TStrings que permite muitas operações interessantes! --- 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 --- 88 ---
CheckBox / Group TCheckBox TCheckGroup --- 89 ---
RadioGroup TRadioGroup --- 90 ---
ListBox e ComboBox --- 91 ---
Image, PaintBox, Shape TImage (.Picture) TPaintBox (.Canvas) TShape (.Canvas) --- 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 --- 93 ---
Temporizador TTimer (separador system) Tempo em milisegundos Dificuldades em cumprir restrições de tempos curtos --- 94 ---
Gráficos TBarChart --- 95 ---
Menus TMainMenu Fazendo double click abre-se o editor de menus É possível acrescentar diversas opções: check box Ícone Tecla atalho... --- 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 --- 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; --- 98 ---
Componentes Externos Úteis --- 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) --- 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 --- 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] --- 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. --- 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 --- 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 --- 105 ---
Data Aware Objects (i) SGBD Query/ /Dataset DataSource DBGrid DBEdit DBLabel... --- 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 --- 107 ---
Data Aware Objects (ii) - DBGrid --- 108 ---
Data Aware Objects (iii) - DBEdit... dbgrid.readonly:=... (sempre!!!)... SQLQuery.Post;... --- 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; --- 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 --- 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 --- 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; --- 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; --- 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; --- 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; --- 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; --- 117 ---
Operator Overloading type complex = record re : real; im : real; end; //... Z2:=Z1; //... // Atribuição de // record's do // mesmo tipo // Z2:=Z1 // é a atribuição de // todos os campos type complex = record re : real; im : real; end; var R1 : real; Z1,Z2 : complex; // Operator Overloading operator := (r : real) z : complex; begin z.re:=r; z.im:=0.0; end; --- 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 --- 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 --- 120 ---
Programação Orientada a Eventos + FPC/Lazarus - Fim - --- 121 ---