Fenner
Começando

Projetos e arquivos

As extensões de arquivo, as três formas de projeto e como dividir um programa em módulos.

As extensões#

ExtensãoO que é
.fxpProjeto: um program (gera .exe), uma library (gera .dll) ou um package (.dll mais .fxd)
.fxmMódulo (a unit do Pascal): um module, ou a forma clássica unit
.fxiArquivo de inclusão, trazido por {$include}
.fxfDescrição do formulário, em texto estilo DFM (o RAD escreve e lê)
.configConfiguração de build do projeto; veja Configuração
.config.localAjustes do desenvolvedor (não vai para o controle de versão)
.fxdInterface compilada de um package (o equivalente ao .dcp do Delphi)
.fxnamesMapa de nomes de um package
.fxdepsLista de tudo o que a compilação leu; o RAD o usa para saber se o executável está desatualizado
.rtti.jsonA forma dos tipos e os atributos, gravada com a opção Rtti

Três formas de projeto#

FormaSaiExportaQuem a usa vê
program.exe——
library.dllsó o que está na cláusula exportsnada: escreve-se external ... name ... à mão
package.dll + .fxdtudo o que é publico .fxd; o compilador resolve o resto sozinho

A library é a DLL clássica, com uma lista explícita de símbolos:

lib-greeter.fxp
library Greeter;

// Uma biblioteca vira uma DLL; a cláusula exports publica os símbolos.

function Add(A, B: Int32): Int32; stdcall;
begin
  Exit(A + B);
end function;

function Square(A: Int32): Int32; stdcall;
begin
  Exit(A * A);
end function;

exports
  Add,
  Square name 'SquareRenamed';

begin
  // roda quando a DLL é carregada (aqui, nada a fazer)
end.

Um package é a forma pensada para código compartilhado entre aplicativos (a própria RTL BedRock é distribuída assim). Veja Packages e o .fxd.

Dividindo em módulos#

Um módulo é um arquivo .fxm. O programa o traz com uses, e o compilador o procura ao lado do projeto (ou nas pastas da chave SourcePath da configuração).

Main.fxp
program Main;

uses Geometry;

begin
  WriteLn('lados: ', Geometry.Sides);
  WriteLn('área: ', SquareArea(5));
  WriteLn('id: ', NextId);
  WriteLn('id: ', NextId);
  // Square(3) aqui seria erro: é private no módulo
end.
Geometry.fxm
module Geometry;

// Um module não tem interface nem implementation: cada declaração diz se é
// public ou private, e a omissão é private.

public const
  Sides = 4;

private function Square(const X: Int32): Int32;
begin
  Exit(X * X);
end function;

public function SquareArea(const ASide: Int32): Int32;
begin
  Exit(Square(ASide));
end function;

// region agrupa e pode trocar a omissão de dentro dela
public region 'Counters';

  var
    Calls: Int32;

  function NextId: Int32;
  begin
    Inc(Calls);
    Exit(Calls);
  end function;

end region;

initialization
  Calls := 100;

end.
Saída
lados: 4
área: 25
id: 101
id: 102

Dois arquivos: Main.fxp usa o módulo Geometry.fxm.

Três coisas para notar no módulo:

  • Não há interface/implementation. Cada declaração diz se é public ou private, e a omissão é private.
  • region agrupa declarações e pode trocar a omissão de dentro dela. O rótulo é para a IDE.
  • initialization roda quando o módulo é carregado; finalization roda no encerramento, na ordem inversa. Depois de uses, o módulo System entra sozinho em todo programa.

Mais sobre visibilidade, namespace e using em Módulos.

A estrutura típica de um aplicativo de janelas#

Um projeto criado pelo RAD tem esta forma:

texto
MeuApp\
  MeuApp.fxp                 o programa: uses, Application.CreateForm, Application.Run
  MeuApp.config              plataformas, modos e ajustes do compilador
  MeuApp.manifest            liga o Common Controls 6 (aparência atual do Windows)
  res\                       ícone e recursos
  src\
    Unit1.fxm                o módulo do formulário (o código é seu)
    Unit1.fxf                o desenho do formulário (o RAD o mantém)
    Unit1.designer.fxi       o código que monta os componentes (gerado)
    AppGuard.fxm             rede de segurança contra queda muda (gerado)
  bin\                       a saída, uma pasta por plataforma e modo