Loading a form from a package at runtime

2.7k views Asked by At

I am currently working on a few Plugin concepts and came across during my research on the use of dlls or BPls and I have now decided to use bpls.

I would like to know when I have to use UnloadPackage (Package modules); best views because immediately after loading brings me nothing because the shape then immediately disappears

Current program structure

Hostapplication(PackageLoader.exe)
                |_Plugin.bpl
                 |_TPluginForm

enter image description here

PackageLoader.exe

var
  PackageModule : hModule;
  createProc: Procedure;
begin
  // Package laden
  try
  PackageModule := LoadPackage('plugin.bpl');
  If PackageModule <> 0 then
  begin
    @createProc := GetProcAddress( PackageModule, 'CreatePluginForm' ); // Funktion aus den Exports aufrufen
    if Assigned(CreateProc) then
      CreateProc
    else
      ShowMessage('GetProcAddress failed');
  end;
  finally
    //UnloadPackage(PackageModule);
  end;
end;

enter image description here

plugin.bpl - uPlugin.pas

unit uPlugin;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TPluginForm = class(TForm)
    Memo1: TMemo;
    Panel1: TPanel;
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  PluginForm: TPluginForm;
  Status: Boolean;

implementation


uses
  uRandomString;

{$R *.dfm}

procedure TPluginForm.Button1Click(Sender: TObject);
var
  User, pwd, mail: String;
  ul, pl, ml: Integer;
begin
  Status := True;
  ul := StrToInt(Edit1.Text);
  pl := StrToInt(Edit2.Text);
 // ml := StrToInt(Edit3.Text);
  while Status do
  begin
    Application.ProcessMessages;
    User := RandomString(ul);
    pwd := RandomString(pl);
    //mail := RandomString(ml) + '@' + RandomString(5)+'.de';

    Memo1.Lines.Add(User+':'+pwd); //+':'+mail);
  end;
end;

procedure TPluginForm.Button2Click(Sender: TObject);
begin
  Status := False;
end;

function CreatePluginForm(ApplicationHandle, ParentHandle: THandle): boolean;
begin
  Result := False;
  PluginForm := TPluginForm.Create(nil);
  try
    PluginForm.Show;
    //PluginForm.ShowModal;
  finally

  end;
end;


exports
  CreatePluginForm;

initialization
  RegisterClass(TPluginForm);

finalization
  UnRegisterClass(TPluginForm);

end.
1

There are 1 answers

2
David Heffernan On BEST ANSWER

When to unload the package depends on the design of your application. Given that we don't know much about it, it is hard to give specific advice. One option is that you don't unload the package. Why do you feel that you need to do so? If there is a need to unload you must make sure that no code from the package is still running. You show a form from the package. That form must have been destroyed by the time you come to unload the package.

The big problem that I can see is in the way you import that function. It is declared like this in the package:

function CreatePluginForm(ApplicationHandle, ParentHandle: THandle): Boolean;
begin
  ....
end;

exports
  CreatePluginForm;

And then you import it like this:

var
  createProc: Procedure;
....
@createProc := GetProcAddress(PackageModule, 'CreatePluginForm');
if Assigned(CreateProc) then
  CreateProc

You need to declare createProc with a matching signature:

var
  createProc: function(ApplicationHandle, ParentHandle: THandle): Boolean;

And then when you call it you need to pass the two handles, and do something with the return value.

Your code also leaks PluginForm.

Finally, THandle would appear to be the wrong type. I think you meant to use HWND. Although I don't see why you don't pass VCL objects around. After all, you chose to use packages which means that you can pass the parent control directly. And you certainly don't need to pass anything related to the application because the plugin can already see the application.