Abrindo Forms MDI de um BPL

Crie um Projeto novo... Em seguida vá até as propriedades do projeto, na aba Packages ,e selecione: Build with runtime packages.
Isto dará uma drastica mudança de tamanho no executável... de 350k ele passa a ter 16k, mas o projeto fica dependente da rtlXX.bpl e VCL.bpl
Tudo bem... certifique-se que o campo abaixo do check contenha apenas isso: "vcl;rtl"


Salve tudo e feche tudo com o Close All.

*Crie um Pacote e coloque um formulário nele... certifique-se de que o formulário está em modo fsMDIChild.



Na ação OnClose do form, coloque isso:

procedure TFormMDIChildBPL.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;

Agora adicione este procedimento:

procedure ExecutarChild;
begin
  TFormMDIChildBPL.Create(Application);
end;

Este procedimento fará com que quando ele for chamado, o mesmo abra o formulário que está guardado no BPL.

Antes do END. adicione isto:

exports
  ExecutarChild; 

Fique atento! Para exportação de procedimentos vale a regra do CaseSensitive!

Pronto... o pacote está ok... compile ele agora. e salve tudo. depois feche tudo e volte para o aplicativo que abre o form do BPL
---

Agora, no fomulário principal do aplicativo onde você vai chamar o form do BPL, escreva estes códigos nos seguintes setores.

type
  TExecutarChild = procedure; //tipo do procedimento de chamada do BPL
...

private
    ModuloDoPacote: HModule;
    ExecutarChild : TExecutarChild;
    procedure CarregarPacote;
end;

Adicione este procedimento para que possa ser chamado o package.

procedure TForm1.CarregarPacote;
begin
  //Tenta carregar o pacote...
  ModuloDoPacote := LoadPackage(`SeuPacote.bpl`);

  //se carregou, tenta localizar o procedure
  if ModuloDoPacote <> 0 then
    try

      @ExecutarChild := GetProcAddress(ModuloDoPacote, `ExecutarChild`);
    except
      ShowMessage (Pacote não Encontrado);
    end;
end;

Pronto, agora está abrindo o pacote.
Insira um botão na tela, e no evento OnClick, coloque o seguinte código:

  //Se o pacote não estiver carregado ele cerrega.
  if ModuloDoPacote = 0 then CarregarPacote;

  //se o procedimento estiver colocado na memória ele executa o procedimento
  if Assigned(ExecutarChild) then ExecutarChild;

E... o produto final: