Logo Gladiston Santana

Pascal: Delphi & Free Pascal

Desenvolvimento robusto, compilado e de alta performance.

Usando resources no FPC/Lazarus

Há muita diferença entre os arquivos resources no Delphi e no Lazarus.

Resources é qualquer arquivo que você deseje embutir junto com o executável. A prática comum é ter imagens, efeitos sonoros, arquivos html/dll/etc espalhados ou distribuídos no disco durante a instalação. Usar resources significa que você pode embuti-lo no executável e, ao executá-lo, usufruir desses recursos da forma que desejar.

Por exemplo, a utilização do CEF4 (Navegador Chromium) embutido em nossa aplicação irá requerer algumas DLLs no mesmo diretório do executável. Eu posso criar um instalador que distribua essas DLLs ou usar o resources para transferir essas DLLs de dentro do executável para a pasta de instalação e garantir que o programa funcione com as DLLs planejadas. Mas seu uso não é restrito para extrairmos arquivos para o disco; a forma mais comum é carregar imagens ou tocar efeitos sonoros sem precisar extrair nada.

Diferenças Técnicas

No Delphi:

Usa arquivos binários .res gerados a partir de .rc.

{$R arquivo.res}
No Lazarus:

Usa arquivos .lrs (não binários). A diretiva é:

{$I arquivo.lrs}

Gerando o arquivo .lrs com lazres

No Lazarus, usamos a ferramenta de linha de comando lazres para agrupar os arquivos diretamente:

C:\Lazarus\Tools\lazres.exe arquivo.lrs image1.jpg image2.jpg minhaDLL.dll

Diferente do Delphi, o arquivo gerado não é binário e pode ser versionado por ferramentas como o Git. Existe também uma GUI chamada LRS Explorer que simplifica essa operação.

Implementação no Código

A documentação recomenda incluir a diretiva na seção initialization da primeira unit carregada no projeto:

uses ..., LResources;

initialization
  {$I arquivo.lrs}

Exemplo: Carregar Imagem Diretamente

procedure TForm1.LoadResources;
var Image: TImage;
begin
  Image := TImage.Create(Self);
  // Note que não precisamos da extensão do arquivo
  Image.Picture.LoadFromLazarusResource('image1');
end;

Extração para o Disco (DLLs e Arquivos Externos)

Abaixo está a função Extract_ResFileTo para extrair recursos quando necessário (ex: dependências de componentes como CEF4):

function Extract_ResFileTo(AResName: String; ASaveFileTo: String): String;
var
  res: TLResource;
  st: TLazarusResourceStream;
begin
  Result := '';
  if not DirectoryExists(ExtractFilePath(ASaveFileTo)) then
    ForceDirectories(ExtractFilePath(ASaveFileTo));

  res := LazarusResources.Find(AResName);
  if res = nil then
    Result := 'RC com nome "' + AResName + '" não encontrada.'
  else
  begin
    try
      st := TLazarusResourceStream.Create(AResName, nil);
      st.SaveToFile(ASaveFileTo);
    finally
      st.Free;
    end;
  end;
end;

Conclusão

O uso de resources no Lazarus é, na minha opinião, muito melhor e mais flexível do que no Delphi. A possibilidade de carregar recursos diretamente sem extração prévia para o disco e o suporte a arquivos versionáveis (.lrs) tornam o desenvolvimento muito mais produtivo e menos sujeito a erros de distribuição.

Créditos e Referência: Wiki oficial - Adding resources to your program.