Карта сайтаСсылкиКонтакты

Сохранение и вызов дочерней формы MDI из DLL

PDF Печать
Статьи

Давайте создадим одно простое приложение MDI и простой пакет, который будет содержать одну дочернюю форму.

Обратите внимание: оба проекта содержатся в одной группе проектов.

Сначала мы создадим приложение типа MDI:

  1. Создайте MDI приложение. Вы можете использовать MDI Application Wizard (File -> New -> Other ->Projects -> MDI Application).
  2. Удостоверьтесь, что свойство FormStyle главной формы установлено в fsMDIForm.
  3. Добавьте главное меню в приложение. Создайте в нем один элемент меню, который будет загражать дочернюю форму MDI из пакета.
  4. Меню на Главной форме для вызова MDI
  5. Удостоверьтесь, что Вы создаете приложение, используя пакеты времени выполнения. Перейдите в Project -> Options, выберите вкладку Packages и отметьте флажок Build with run-time packages. Вы должны, по крайней мере, использовать пакеты rtl и vcl.
Окно настройки пакетов

Перед написанием кода давайте сначала построим пакет и добавим в него одну дочернюю форму MDI.

  • Сначала создайте пакет времени выполнения.
  • Добавьте объект TForm в пакет. Удостоверьтесь, что свойство FormStyle установлено в fsMDIChild.

  • Добавьте одну экспортируемую процедуру, чтобы создавать экземпляр дочерней формы.

procedure TPackageMDIChildForm.FormClose
  (Sender: TObject;
   var Action: TCloseAction);
begin
  //  так как это MDI ребенок, удостоверьтесь, 
  //  что оно закрывается, когда пользователь
  //  щелкает кнопку закрытия окна.
  Action := caFree;
end;

procedure ExecuteChild;
begin
  TPackageMDIChildForm.Create(Application);
end;

exports
  //  ВАЖНО!! Экспортируемое имя
  //  является чувствительным к РЕГИСТРУ
  ExecuteChild;
  
end.

Перейдем к MDI приложению...

Вот полный код главной MDI формы:


type
  //  сигнатура процедуры "ExecuteChild" 
  //  из Package
  TExecuteChild = procedure;

  TMainForm = class(TForm)
   ...
  private
    PackageModule : HModule;
    ExecuteChild : TExecuteChild;
    procedure PackageLoad;
  end;

var
  MainForm: TMainForm;

implementation
{$R *.dfm}

procedure TMainForm.PackageLoad;
begin
  //  пробуем загрузить пакет
  //  (полагаем, что он находится в той же самой
  //  папке, что и главное приложение .exe)
  PackageModule := LoadPackage('MDIPackage.bpl');

  //  если загружено, пытаемся найти процедуру
  //  ExecuteChild
  if PackageModule <> 0 then
  try
    @ExecuteChild := GetProcAddress(PackageModule,
                                    'ExecuteChild');
  except
    //  показать сообщение об ошибке, если неудачно
    ShowMessage ('Package not found');
  end;
end;

//  щелчок меню
procedure TMainForm.mnuCallFromDLLClick
  (Sender: TObject);
begin
  //  загружаем пакет
  if PackageModule = 0 then PackageLoad;

  //  если процедура ExecuteChild
  //была найдена в пакете, вызываем ее
  if Assigned(ExecuteChild) then ExecuteChild;
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  //  если пакет был загружен,
  //  убедитесь, что освободили ресурсы
  if PackageModule <> 0 then
    UnloadPackage(PackageModule);
end;

Вышеупомянутый код динамически загружает (процедура PackageLoad) пакет, как необходимо, когда выбран пункт меню и выгружает пакет, когда приложение завершается.

Наконец, во время выполнения, мы имеем дочернюю MDI форму, загруженную из пакета и прекрасно работающую внутри родительской MDI формы:

Программа MDI в действии

Одно важное примечание: когда мы используем пакеты времени выполнения, мы должны поставлять пакеты вместе с главным файлом .exe приложения.


 

Добавить комментарий


Защитный код
Обновить