Cópia da wikiespelho

Este é um espelho da wiki em pascal.chat. A edição, o histórico e a entrada ficam lá.

Howdy World (Hello World on steroids)/pt

English · Português · Suomi

Este capítulo é um tutorial para Lazarus. Ele explica os primeiros passos para obter um software funcional e também algumas das melhores práticas. O resultado final (esperado) é duplo: o leitor entende os conceitos básicos para construir um software com Lazarus e obtém um verdadeiro programa funcional. Uma calculadora é algo razoavelmente fácil de implementar e todo mundo entende seus conceitos, sem necessidade de explicações de antemão. Esta calculadora é limitada a cálculos com números inteiros, mas pode facilmente ser estendida.

Este tutorial não descreve o processo de instalação do Lazarus. Ele assume que o Lazarus está instalado e pronto para uso (preferivelmente a última versão estável, que no momento é a 0.9.30 com FreePascal 2.4.2). Este tutorial é mais ou menos independente de plataforma. Todos os screenshots foram feitos em Windows XP, portanto com o esquema de cores azul/vermelho/cinza.

Leitura recomendada antes de começar: uma introdução abrangente da Lazarus IDE.

Vamos começar

É melhor criar um diretório separado para cada projeto. Portanto, vamos criar um diretório para salvar o projeto da nossa Calculadora. Este diretório será a raiz de todos os arquivos criados para o projeto.

(Texto que descreve ações que precisam ser executadas é marcado, como a linha anterior)

Com isto resolvido, é hora de iniciar um novo projeto Lazarus.

Para ter certeza de que todos os arquivos do nosso novo projeto estarão no diretório certo, o projeto precisa ser salvo primeiro.

Em teoria, o programa que é assim criado é um software válido que pode ser executado. Antes de compilá-lo pela primeira vez, duas modificações são recomendadas: atribuição de novos locais (diretórios) para as unidades de destino e nome do arquivo compilado.

A imagem abaixo mostra como isto ficaria em uma máquina Windows.

Fazendo isto, a pasta do projeto não será desordenada com a saída gerada pelo compilador. Os arquivos da pasta do projeto são necessárias para construir o programa. Tudo nos diretórios ’’lib’’ e ’’bin’’ podem ser eliminados quando do arquivamento do projeto.

Agora, como um primeiro teste, o projeto pode ser compilado e executado.

O primeiro componente

O Lazarus tem uma assim chamada 'paleta de componentes':

Todos os componentes que estão disponíveis para construir uma interface do usuário estão logicamente agrupados nas abas de componentes. O número real de abas depende dos pacotes instalados, mas a paleta básica se parece com a imagem acima. A primeira aba é a Standard, seguida pela Aditional, Common controls, etc.

Para retornar o nome do tipo de um componente, passe o mouse sobre o ícone do componente e um aviso será mostrado (mais precisamente, o nome de classe do componente). Para uma explanação sobre todos os controles, veja esta Lazarus introduction

A primeira coisa que é preciso ser feita para o programa de Calculadora é criar uma área de display, onde estão os números. Para isto, um controle TEdit é usado.

text
# Nota: os componentes visuais são referidos como Controles. 
  Para o nosso propósito, a diferença entre um "componente" e um "controle" não é relevante.

Para colocar um controle no formulário, este precisa ter o foco. Pressionar F12 no teclado muda o foco do editor de formulários para o editor de código e vice-versa.

Agora que o controle está colocado no formulário, ele pode ser personalizado como você precisar. Esta personalização tem lugar no Inspetor de Objetos. Esta é a janela à esquerda da tela, com a lista de propriedades para o controle TEdit que são personalizáveis.

As propriedades determinam a aparência e o comportamento do controle. É fácil modificá-las: apenas clique em uma delas, insira um novo valor e pressione Enter. O efeito no controle é imediatamente visível. As propriedades no Inspetor de Objetos são todas propriedades para um único controle, particularmente o controle que tem o foco ou está selecionado. Portanto, a maneira de modificar propriedades de um controle é primeiramente selecioná-lo e então fazer as modificações no Inspetor de Objetos. Se nenhum controle for selecionado, as propriedades do formulário serão mostradas.

Faça as seguintes modificações nas propriedades de Edit1:

Estas propriedades são bastante autoexplicativas, especialmente quando as modificações acima são feitas e o efeito é monitorado no formulário.

Como um toque final, a fonte que é usada para mostrar textos em todos os controles será mudada. A fonte pode ser mudada de duas maneiras: na propriedade Font de edDisplay ou na mesma propriedade do formulário. Mudando a fonte do formulário tem o benefício de que todos os componentes anteriormente criados 'herdarão' a nova fonte, e é aí que nós faremos a nossa modificação.

O título do formulário não é muito significativo. O padrão é 'Form1'.

O resultado de todas estas ações será um formulário que se parece com este:

Agora é uma boa hora para salvar o formulário.

Lembre-se de salvá-lo e o salve com frequência!

Botões

Para que serve uma calculadora se não puderem ser inseridos números? Portanto o próximo passo será adicionar botões para os dígitos 0..9. Antes de posicionar os botões para os dígitos, um assim chamado "contêiner" é colocado no formulário. Um TPanel é outro contêiner que podem ser colocados no formulário. Contêineres podem ser colocados dentro de outros, mas isto é para outro tutorial.

(Aumentando o tamanho do formulário nos dará algum espaço para mover os controles.)

Agora os botões dos dígitos serão adicionados.

Isto precisa ser repetido para os dígitos 1..9. A forma mais rápida de fazê-lo é copiando e colando o botão já criado.

Os próximos são os quatro botões para operações matemáticas (soma, subtração, etc).

E os botões especiais:

Redimensione o formulário para que se ajuste aos botões.

Isto deve resultar em algo assim:

Lembre-se de salvar e salve com frequência!

Respondendo a eventos

Uma aplicação GUI muitas vezes é uma aplicação baseada em eventos. Isto significa que a aplicação não faz nada até que digamos a ela o que fazer. Por exemplo, inserindo dados através do teclado, pressionando botões, etc. Uma das coisas que a calculadora precisa fazer é responder a cliques do mouse nos botões 0..9. É nisto que a IDE nos ajuda. Acrescentar um manipulador de eventos para um botão é fácil.

pascal
edDisplay.Text := edDisplay.Text + '0'

edtDisplay é uma caixa de edição. A forma de modificar o conteúdo de uma caixa de edição é modificando a propriedade Text. A declaração acima acrescenta o número '0' ao texto e isto é visível na tela imediatamente.

pascal
edDisplay.Text := edDisplay.Text + '1'

É uma boa ideia compilar o código a intervalos para verificar erros de sintaxe.

É claro que agora é fácil acrescentar manipuladores de eventos para os dígitos 2..9, mas isto vai resultar em muito código redundante. Cada manipulador de eventos faz exatamente a mesma coisa, apenas os dígitos são diferentes. A forma de eliminar esta redundãncia é criar um procedimento que faça o processamento e acrescentar uma variável (os dígitos 0..9) como parâmetro.

pascal
  { TForm1 }

  TForm1 = class(TForm)
    btnDigit0: TButton;
    btnDigit1: TButton;
    btnDigit2: TButton;
    btnDigit3: TButton;
    btnDigit4: TButton;
    btnDigit5: TButton;
    btnDigit6: TButton;
    btnDigit7: TButton;
    btnDigit8: TButton;
    btnDigit9: TButton;
    btnFunction: TButton;
    btnFunction1: TButton;
    btnFunction2: TButton;
    btnFunction3: TButton;
    btnCalculate: TButton;
    btnPlusMinus: TButton;
    btnClear: TButton;
    edDisplay: TEdit;
    Panel1: TPanel;
    procedure btnDigit0Click(Sender: TObject);
    procedure btnDigit1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

Note que, na definição de classe acima, todos os controles e procedimentos declarados foram adicionados ao formulário automaticamente. Não faça qualquer modificação manual aí!! A IDE vai ficar nervosa que você o fizer. O lugar para acrescentar variáveis, procedientos e funções personalizadas são as seções private e public. Como regra geral, variáveis personalizadas são adicionadas à seção private. Procedimentos e funções são acrescentadas à seção private também, exceto quando outros formulários precisam chamar estes procedimentos ou funções (o que deve acontecer com frequência).

De volta para o nosso problema de dígitos: precisamos de um procedimento que acrescente dígitos ao display em que os dígitos possam variar.

pascal
  private
    { private declarations }
    procedure AddDigit(const pDigit: byte);
  public
    { public declarations }
  end;

Em seguida, o código efetivo para o procedimento AddDigit precisa ser inserido. Novamente a IDE vem em nosso auxílio:

A IDE gerará a definição deste novo método e posicionará o cursor de texto dentro do procedimento vazio. Podemos imediatamente começar a digitar.

pascal
edDisplay.Text := edDisplay.Text + IntToStr(pDigit)

Note que a função IntToStr() traduz o valor numérico, o digito, para um valor de sequência de caracteres de modo que possa ser mostrado no display.

E para usar este procedimento para todos os dígitos:

pascal
procedure TForm1.btnDigit0Click(Sender: TObject);
begin
  AddDigit(0)
end;
pascal
procedure TForm1.btnDigit1Click(Sender: TObject);
begin
  AddDigit(1)
end;

Antes de completar esta sequência para todos os outros botões de dígitos, certifique-se de que ele realmente faz o que queremos.

Um bom programador é um programador preguiçoso

Agora podemos acrescentar manipuladores de eventos para os botões 2..9. Mas agora novamente temos o mesmo problema de criar código redundante: AddDigit(2), AddDigit(3), etc. E se houvesse uma maneira de contar os botões separadamente? Felizmente existe.

Todos os componentes têm uma propriedade de valor inteiro chamada Tag (lembre-se: um controle é apenas um tipo especial de componente que herda esta propriedade Tag. É uma propriedade que não tem uma função verdadeira. Está lá para usarmos como acharmos melhor. E se cada botão pudesse ter seu valor de dígito armazenado na propriedade Tag...

Agora todos os botões de dígitos têm um valor de Tag único. Não modificamos o botão do dígito 0 porque o valor padrão de Tag já é 0. Agora, para fazer uso deste valor de Tag:

pascal
procedure TForm1.btnDigit0Click(Sender: TObject);

O parâmetro Sender é na verdade uma referência ao botão que foi pressionado. Através de conversão de tipo, podemos usar o parâmetro como se fosse um TButton.

pascal
procedure TForm1.btnDigit0Click(Sender: TObject);
begin
  AddDigit(TButton(Sender).Tag)
end;

Não parece que tenhamos feito muito, substituindo uma linha de código por outra. No entanto, Se tivéssemos de adicionar código para os outros dígitos (1..9), ele ficaria exatamente igual. Assim, todos os outros dígitos podem reusar este método!

Vamos olhar melhor para o Inspetor de Objetos.

No Inspetor de Objetos, podemos não somente mudar as propriedades do controle, mas também os manipuladores de eventos. No Inspetor de Objetos podemos ver que, tão logo o botão do dígito 0 for clicado, o método btnDigit0Click seá chamado (este é o manipulador de eventos OnClick).

Now all buttons share one common procedure that does exactly what we want except for digit button 1. Remember that for digit button 1 we created an event handler btnDigit1Click that we don't really need anymore.

Now all buttons share the same event handler to add digits to the display box.

For the digit buttons one final thing needs to be done: event handler btnDigit1Click still exists but is not used anymore and should be deleted. The safest way to do this (for now) is to let the IDE handle it. For this to work the option Auto remove empty methods must be enabled.

From now on all empty methods are automatically deleted as soon as the source file is saved.

Tuning

So far so good: the calculator program compiles, runs and responds to clicks on digit buttons 0..9. But it doesn't behave exactly as we want: there's always this annoying zero at the beginning of the number and the number of allowed digits is too large.

Removing leading zeroes

Normally an integer number that's bigger (or smaller) than zero does not start with a leading zero. So our calculator should compensate for this. Luckily this is easy to implement. Remember that we have one and only one method that handles the addition of digits: AddDigit. This is the place to add logic to suppress the leading zero.

pascal
procedure TForm1.AddDigit(const pDigit: byte);
begin
  // Suppress leading zeroes when adding digits
  if edDisplay.Text = '0' then
    edDisplay.Text := IntToStr(pDigit)
  else
    edDisplay.Text := edDisplay.Text + IntToStr(pDigit)
end;

Limit the number of digits

This demo calculator cannot handle numbers that are too large. So we need to limit the number of digits that can be entered. Again the logical place to do this is the AddDigit method:

pascal
procedure TForm1.AddDigit(const pDigit: byte);
begin
  // Limit the number of digits
  if length(edDisplay.Text) < 8 then
  begin
    // Suppress leading zeroes when adding digits
    if edDisplay.Text = '0' then
      edDisplay.Text := IntToStr(pDigit)
    else
      edDisplay.Text := edDisplay.Text + IntToStr(pDigit)
  end;
end;

Operations

Now it's time to look at the actual operations we want to implement: adding, subtracting, multiplying and dividing. The way the user is going to use the calculator goes something like this:

  1. The user enters a number
  2. The user presses a function button (e.g. '+')
  3. The user enters a second number
  4. The user presses '='
  5. The program responds with the addition of the first and second number

As soon as the user presses the '=' button the program has to know three things:

  1. What was the operation?
  2. What was the first number?
  3. What was the second number?

What was the operation?

Somehow we need to register that a certain operation type was selected. And for that we need to know what operation types are available. One way to implement this is to create an enumeration type (or user defined scalar type) that contains all valid operations.

pascal
 type

  { All supported operations for our calculator }
  TOperationType = (otNone, otPlus, otMinus, otMultiply, otDivide);

  { TForm1 }

  TForm1 = class(TForm)
pascal
  private
    { private declarations }
    SelectedOperation: TOperationType;
    procedure AddDigit(const pDigit: byte);

What was the first number?

To temporarily store the first number that was entered we need a variable.

pascal
  private
    { private declarations }
    SelectedOperation: TOperationType;
    FirstNumber: longint;
    procedure AddDigit(const pDigit: byte);

What was the second number?

What's on your mind

Now it's time to implement the actions for the function buttons: add, subtract, multiply and divide. Let's start with the '+' button. As mentioned in one of the previous sections: when the '+' button is pressed, we need to store the first number and the operation type. So that's what we are going to do.

Hold on! Before adding all the code here and doing the same for the three other operation buttons, remember what was said when the digit buttons 0..9 were added: do not add redundant code! It's reasonable to assume that the code for the other three operation buttons will be the same as for the '+' button, except for the operation itself. So let's save ourselves some work.

pascal
  private
    { private declarations }
    SelectedOperation: TOperationType;
    FirstNumber: longint;
    SecondNumber: longint;
    procedure AddDigit(const pDigit: byte);
    procedure StoreOperation(const pOperation: TOperationType);

The StoreOperation procedure must do two things: store the operation and store the number that was entered in the display, so it can be used afterwards.

pascal
procedure TForm1.StoreOperation(const pOperation: TOperationType);
begin
  // Store the operation so it can be used later
  SelectedOperation := pOperation;

  // Store the number that was entered by the user
  FirstNumber := StrToInt(edDisplay.Text);
end;

Ok, now back to the '+' button:

Now test the program and see what happens:

What happens is that after pressing the '+' button, or any other operation button for that matter, the display is not cleared. We must find a way to make sure that the display is cleared, as soon as an operation button is pressed. Because we have used procedures to group similar actions, this again is an easy change.

pascal
  private
    { private declarations }
    SelectedOperation: TOperationType;
    FirstNumber: longint;
    SecondNumber: longint;
    doClearDisplay: boolean;
    procedure AddDigit(const pDigit: byte);
    procedure StoreOperation(const pOperation: TOperationType);
pascal
procedure TForm1.StoreOperation(const pOperation: TOperationType);
begin
  // Store the operation so it can be used later
  SelectedOperation := pOperation;

  // Store the number that was entered by the user
  FirstNumber := StrToInt(edDisplay.Text);

  // The display must start with a new number
  doClearDisplay := true;
end;
pascal
procedure TForm1.AddDigit(const pDigit: byte);
begin
  // Must the display be cleared first?
  if doClearDisplay then
  begin
    edDisplay.Text := '0';   // Reset the display to zero
    doClearDisplay := false; // Once is enough...
  end;

  // Limit the number of digits
  if length(edDisplay.Text) < 8 then
  begin
    // Suppress leading zeroes when adding digits
    if edDisplay.Text = '0' then
      edDisplay.Text := IntToStr(pDigit)
    else
      edDisplay.Text := edDisplay.Text + IntToStr(pDigit)
  end;
end;

Now let's see what happens:

We're almost there: we can enter numbers and select an operation. Now it's time to do the actual calculations.

Doing the math

Now that we have stored a number and an operation, it's time to do the actual calculations. Let's start easy with additions.

pascal
procedure TForm1.btnCalculateClick(Sender: TObject);
var result: longint;
begin
  case SelectedOperation of
    otPlus: begin
              // Retrieve the second number
              SecondNumber := StrToInt(edDisplay.Text);
              // Do the math
              result := FirstNumber + SecondNumber;
              // Display the resulting value
              edDisplay.Text := IntToStr(result);
            end;
  end;
end;

The above code is pretty straightforward: if the user presses the '+' button, the first and second number are added up and the result is stored in the edit control on screen.

We now have a working calculator (that can only add two numbers):

We now could add the 3 missing operations ('-', '*' and '/'). But hold on, there is room for improvement. Let's have a look at the following statement:

pascal
SecondNumber := StrToInt(edDisplay.Text);

We have seen such a statement before: the StoreOperation procedure contains something similar:

pascal
FirstNumber := StrToInt(edDisplay.Text);

Calculating the number the user entered now happens in two different locations. We do not want to repeat ourselves so it's a good idea to create a new function that does the calculation.

pascal
  private
    { private declarations }
    SelectedOperation: TOperationType;
    FirstNumber: longint;
    SecondNumber: longint;
    doClearDisplay: boolean;
    procedure AddDigit(const pDigit: byte);
    procedure StoreOperation(const pOperation: TOperationType);
    function GetDisplayValue: longint;
pascal
function TForm1.GetDisplayValue: longint;
begin
  result := StrToInt(edDisplay.Text);
end;

So much for refactoring, back to the calculations.

Now look at the following statements:

pascal
              // Retrieve the second number
              SecondNumber := GetDisplayValue;
              // Do the math
              result := FirstNumber + SecondNumber;

Variable SecondNumber is used to store the value in the display box. However it is not really necessary. The above code can be simplified:

pascal
              // Do the math
              result := FirstNumber + GetDisplayValue;

Now look at the following statements:

pascal
              // Do the math
              result := FirstNumber + GetDisplayValue;
              // Display the resulting value
              edDisplay.Text := IntToStr(result);

The same now applies to the result variable. The above code can be simplified to:

pascal
              // Display the resulting value
              edDisplay.Text := IntToStr(FirstNumber + GetDisplayValue);

Now we can add the 3 remaining operations.

pascal
procedure TForm1.btnCalculateClick(Sender: TObject);
begin
  case SelectedOperation of
    otPlus     : edDisplay.Text := IntToStr(FirstNumber + GetDisplayValue);
    otMinus    : edDisplay.Text := IntToStr(FirstNumber - GetDisplayValue);
    otMultiply : edDisplay.Text := IntToStr(FirstNumber * GetDisplayValue);
    otDivide   : edDisplay.Text := IntToStr(FirstNumber div GetDisplayValue);
  end;
end;

We now have a working calculator for all 4 operations:

Intermezzo

After all this work we now have a useable calculator. But some things are not quite right. The obvious thing to try is dividing a number by zero. And the buttons 'C' and '+/-' don't work yet. These things will be addressed in the next section.

First let's add another procedure, just for the fun of it (well, there's more to it of course:-)):

pascal
  private
    { private declarations }
    SelectedOperation: TOperationType;
    FirstNumber: longint;
    SecondNumber: longint;
    doClearDisplay: boolean;
    procedure AddDigit(const pDigit: byte);
    procedure StoreOperation(const pOperation: TOperationType);
    function GetDisplayValue: longint;
    procedure SetDisplayValue(const pValue: longint);
pascal
procedure TForm1.SetDisplayValue(const pValue: longint);
begin
  edDisplay.Text := IntToStr(pValue);
end;

The above code should look pretty familiar. Have a look at the procedure that does all calculations:

pascal
procedure TForm1.btnCalculateClick(Sender: TObject);
begin
  case SelectedOperation of
    otPlus     : edDisplay.Text := IntToStr(FirstNumber + GetDisplayValue);
    otMinus    : edDisplay.Text := IntToStr(FirstNumber - GetDisplayValue);
    otMultiply : edDisplay.Text := IntToStr(FirstNumber * GetDisplayValue);
    otDivide   : edDisplay.Text := IntToStr(FirstNumber div GetDisplayValue);
  end;
end;

This procedure can now be simplified.

pascal
procedure TForm1.btnCalculateClick(Sender: TObject);
begin
  case SelectedOperation of
    otPlus     : SetDisplayValue(FirstNumber + GetDisplayValue);
    otMinus    : SetDisplayValue(FirstNumber - GetDisplayValue);
    otMultiply : SetDisplayValue(FirstNumber * GetDisplayValue);
    otDivide   : SetDisplayValue(FirstNumber div GetDisplayValue);
  end;
end;

Loose ends

There's a couple of things that need to be done: implement the two loose buttons and make the calculator a bit more robust.

The +/- button

pascal
procedure TForm1.btnPlusMinusClick(Sender: TObject);
begin
  SetDisplayValue(0 - GetDisplayValue);
end;

See here the fruits of our labor. We have reused the procedure SetDisplayValue and GetDisplayValue to implement the negate function.

Try it by running the program and press the '+/-' button.

The Clear button

pascal
procedure TForm1.btnClearClick(Sender: TObject);
begin
  SetDisplayValue(0);          // Start from scratch
  SelectedOperation := otNone; // No operation selected yet
  doClearDisplay := false;     // The display is already cleared
end;

The above code is pretty self-explanatory: the display is cleared (the first line), we 'forget' about any pending operation by clearing the SelectedOperation variable and there is no need to clear the display when adding new digits, because it was already cleared by the first statement.

Divide by zero

Let's go crazy: run the application and try to divide 10 by 0. This will make the application crash horribly. We have to make sure that this will not happen. The place to check this of course is the place where all calculations are performed (TForm1.btnCalculateClick).

pascal
procedure TForm1.btnCalculateClick(Sender: TObject);
begin
  case SelectedOperation of
    otPlus     : SetDisplayValue(FirstNumber + GetDisplayValue);
    otMinus    : SetDisplayValue(FirstNumber - GetDisplayValue);
    otMultiply : SetDisplayValue(FirstNumber * GetDisplayValue);
    otDivide   : if GetDisplayValue <> 0 then
                   SetDisplayValue(FirstNumber div GetDisplayValue)
                 else
                   begin
                     // Display an error message to the user
                     MessageDlg('It is not possible to divide a number by 0!', mtWarning, [mbCancel],0);
                     // Reset the calculator to start with a clean slate
                     btnClearClick(nil);
                   end
  end;
end;

Things noteworthy:

  1. MessageDlg is a function for displaying a short warning/error/informative message to the user. ShowMessage can also be used. It is a bit easier to use but cannot display warning/error icons.
  2. btnClearClick(nil): as soon as an error condition occurs we must reset the calculator. That's basically the same as pressing the 'C' button. We simulate pressing the 'C' button by directly calling the event handler.

Overflows

Now two things could have happened:

  1. The application gives an incorrect result (something like 1674919425).
  2. The application raises an error.

If it's the first option then overflow errors have been disabled for the project. Enable them by ticking the Overflow option box:

Now run the program again and see what happens with overflows.

If it was the second (and expected) option then this means we have to add exception handling to our little calculator. Exception handling is used to prevent an application from crashing when errors occur. In our case we want to handle the arithmetic overflow error that might occur. Because all calculations are done in one place, it's easy to catch any overflow errors.

pascal
procedure TForm1.btnCalculateClick(Sender: TObject);
begin
  // Catch any overflow errors
  try
    case SelectedOperation of
      otPlus     : SetDisplayValue(FirstNumber + GetDisplayValue);
      otMinus    : SetDisplayValue(FirstNumber - GetDisplayValue);
      otMultiply : SetDisplayValue(FirstNumber * GetDisplayValue);
      otDivide   : if GetDisplayValue <> 0 then
                     SetDisplayValue(FirstNumber div GetDisplayValue)
                   else
                     begin
                       // Display an error message to the user
                       MessageDlg('It is not possible to divide a number by 0!', mtWarning, [mbCancel],0);
                       // Reset the calculator to start with a clean slate
                       btnClearClick(nil);
                     end
    end;
  except
    on E: EIntOverflow do
      begin
        // Display an error message
        MessageDlg('The result of the calculation was too big for the calculator to process!', mtWarning, [mbCancel], 0);
        // Reset the calculator
        btnClearClick(nil);
      end
  end
end;

Note that even with the exception handling in place, the application will still halt when run from inside the IDE. However the application is only paused and still active. Press F9 to continue. This will display another pop up window, a debugger notification window. Press Continue. Now our own exception handler will kick in with the expected message. If you were to run the application stand alone (i.e. outside the IDE) then you would only see the message box that we added to the exception handler.

Final tweaks

Remember that at a certain point a variable called SecondNumber was introduced. If you choose Run/Build All from the menu, then after building the application the compiler will display a message in the Messages window that this particular variable is never used. If you click on the message text the IDE opens the exact location in the editor where the variable is declared.

As soon as our demo Calculator is started we see that the number 0 in the display has the focus (see image below).

This is counter intuitive because a user should not be able to enter anything in that box. Even worse as soon as she would type something in there that is not a number, our calculator would crash! So it's better not to give access to the that control at all. We are going to fix that.

Run the program to see the result of these changes.

(Under construction: OO-ify the program)


From the Free Pascal wiki, page "Howdy World (Hello World on steroids)/pt", as it stood on 2020-02-17 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.

Revisão 3, última alteração por WikiArchive .