Давайте создадим одно простое приложение MDI и простой пакет, который будет содержать одну дочернюю форму.
Обратите внимание: оба проекта содержатся в одной группе проектов.
Сначала мы создадим приложение типа MDI:
- Создайте MDI приложение. Вы можете использовать MDI Application Wizard (
File -> New -> Other ->Projects -> MDI Application ).
- Удостоверьтесь, что свойство FormStyle главной формы установлено в fsMDIForm.
- Добавьте главное меню в приложение. Создайте в нем один элемент меню, который будет загражать дочернюю форму MDI из пакета.
- Удостоверьтесь, что Вы создаете приложение, используя пакеты времени выполнения. Перейдите в
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 формы:
Одно важное примечание: когда мы используем пакеты времени выполнения, мы должны поставлять пакеты вместе с главным файлом .exe приложения.
|