Часть 1.
Давайте сделаем базовый проект, обеспечивающий динамическую подгрузку пакета. На самом деле это достаточно тривиально, но нам необходимо
- начать с чего-нибудь привычного (а кому это не привычно - он прочувствует, что это не так сложно, как это кажется на первый взгляд)
- просто иметь некоторую стартовую точку
- показать, что и разработанные на текущий момент проекты могут быть легко модернизированы с учетом данной методики (возможно, их придется переписывать заново (или начисто, в зависимости от того, как к этому относиться!), - но это даже иногда полезно ).
Завершив эти "магические пассы", добавляем следующее: в секцию private вносим переменную FPackageHandle типа THandle. Она будет хранить дескриптор пакета. Туда же добавляем процедуру LoadPluginPackage, которая будет непосредственно выполнять загрузку пакета plugin.bpl.
Вот текст этой процедуры procedure TForm1.LoadPluginPackage; var FileName: TFileName; Begin // предполагаем, что пакет хранится в том же каталоге, что и исполняемое приложение FileName := ExtractFilePath(Application.ExeName); FileName := FileName + 'plugin.bpl'; // Загружаем пакет FPackageHandle := LoadPackage(FileName); if FPackageHandle = 0 then RaiseLastWin32Error() // пакет не загружен, выбрасываем исключение else MessageBox(Handle, 'Пакет plugin загружен', 'Информация', MB_APPLMODAL+MB_ICONINFORMATION+MB_OK); end; Теперь сделаем собственно пакет . В него поместим две формы, одну из которых сделаем дочерней (MDIChild), а на другую положим две кнопки (Ok и Cancel).
Далее организуем в главной форме загрузку пакета и вызов из него форм. Для этого на OnShow делаем вызов LoadPluginPackage и добавляем actions в ActionList:
Для дочерней формы procedure TForm1.aOpenExecute(Sender: TObject); var frmClass: TFormClass; frm: TForm; begin frmClass := TFormClass(GetClass('TfrmChild')); // получаем класс дочернего окна if not Assigned(frmClass) then begin MessageBox(Handle, PChar(Format('Не найден класс %s', ['TfrmDialogFrom'])), 'Ошибка', MB_APPLMODAL+MB_ICONERROR+MB_OK); Exit; end; frm := frmClass.Create(Self); // создаем дочернее окно end;
Для диалога procedure TForm1.aOpenDialogExecute(Sender: TObject); var frmClass: TFormClass; begin frmClass := TFormClass(GetClass('TfrmDialogFrom')); // получаем класс диалогового окна if not Assigned(frmClass) then begin MessageBox(Handle, PChar(Format('Не найден класс %s', ['TfrmDialogFrom'])), 'Ошибка', MB_APPLMODAL+MB_ICONERROR+MB_OK); Exit; end; // создаем и показываем окно диалога with frmClass.Create(Self) do try case ShowModal of mrOk: MessageDlg('Выбрано Ok!', mtInformation, [mbOk], 0); mrCancel: MessageDlg('Выбрано Cancel!', mtInformation, [mbOk], 0); else MessageDlg('Выбрано хрен знает что!', mtInformation, [mbOk], 0); end; finally Free(); end; end; Плюс ко всему добавляем обработчик OnUpdate на все action'ы для обеспеченя корректного вызова procedure TForm1.aOpenUpdate(Sender: TObject); begin aOpen.Enabled := FPackageHandle > 0; aOpenDialog.Enabled := FPackageHandle > 0; end; Полный исходный код находится в архиве (каталог Step1)