Сохранение и вызов дочерней формы MDI из DLL
Сначала мы создадим приложение типа 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 приложения.
Комментарии