Главная » Delphi » Отображение модальных форм из DLL

0

В настоящем разделе рассматривается разработка модальной формы, доступной в библиотеке DLL. Одна из причин, по которым имеет  смысл размещать используемые формы в библиотеке DLL, заключается в возможности применения таких  форм  в дру гих приложениях Windows  и даже в другой  среде  разработки (например в C++ или  в Visual Basic).

Для этого, прежде всего, необходимо удалить будущую форму DLL из списка авто

матически создаваемых форм.

Ранее  уже была  создана  подходящая форма, в главном  окне  которой содержится компонент TCalendar. Вызывающее приложение будет обращаться к функции DLL, вызывающей данную  форму.  Когда  пользователь выберет в календаре день,  в вызы вающее приложение возвращается соответствующая дата.

В листинге 6.3 приведен исходный код файла  проекта DLL CalendarLib.dpr, а в листинге 6.4 —  исходный код модуля самой  формы DLL DllFrm.pas. Оба  эти  файла служат иллюстрацией метода инкапсуляции формы в библиотеке DLL.

Листинг 6.3. Исходный код проекта CalendarLib.dpr

unit DLLFrm; interface uses

SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics,

Controls, Forms, Dialogs, Grids, Calendar;

type

TDLLForm = class(TForm)

calDllCalendar: TCalendar;

procedure calDllCalendarDblClick(Sender: TObject);

end;

{ Объявление экспортируемой функции }

ACaption: String): TDateTime; StdCall;

implementation

{$R *.DFM}

function ShowCalendar(AHandle: THandle;

ACaption: String): TDateTime;

var

DLLForm: TDllForm;

begin

// Копирование дескриптора приложения в объект Tapplication

// библиотеки DLL

Application.Handle := AHandle;

DLLForm := TDLLForm.Create(Application);

try

DLLForm.Caption := ACaption;

DLLForm.ShowModal;

// Передача даты обратно в Result

Result := DLLForm.calDLLCalendar.CalendarDate;

finally

DLLForm.Free;

end;

end;

procedure TDLLForm.calDllCalendarDblClick(Sender: TObject);

begin

Close;

end;

end.Главная  форма в этой  библиотеке DLL входит  в состав  экспортируемой функции. Обратите внимание, что объявление DLLForm было удалено из раздела  interface и перенесено в код самой функции.

В рассматриваемой функции  DLL свойству  Application.Handle был  присвоен параметр AHandle. Напомним, что  все проекты Delphi, в том числе  и проекты DLL, содержат глобальный объект Application. В функции библиотеки DLL этот  объект отличается от  объекта Application, который существует  в вызывающем приложе нии.  Чтобы форма DLL правильно работала в качестве модальной формы вызываю щего  приложения,  необходимо присвоить дескриптор такого  вызывающего прило жения свойству  Application.Handle функции библиотеки DLL, что  и было  проде монстрировано. Без этого поведение формы DLL было бы некорректным, особенно в случае ее минимизации. Кроме того, следует удостовериться, что в качестве владельца формы DLL не было передано значение nil.

После  создания формы DLL ее свойству Caption присваивается строка ACaption.

Затем форма отображается в модальном режиме. Когда форма закрывается, дата, вы

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

CОВЕТ

Если создаваемая библиотека DLL экспортирует какие либо процедуры или функции, которые получают в качестве параметров или возвращают в виде результатов выпол- нения строки или динамические массивы, то первым элементом раздела uses этой библиотеки и проекта должен быть модуль ShareMem (меню View пункт Project Source). Это относится ко всем строкам, передаваемым или получаемым от библиотек DLL, даже если они входят в состав записей или классов. Модуль ShareMem представляет собой модуль интерфейса для библиотеки Borlndmm.dll (диспетчера распределяе- мой памяти), который необходимо использовать вместе с этой библиотекой. Чтобы обойтись без модуля Borlndmn.dll, передавайте строковую информацию с помощью параметра типа PChar или ShortString.

Использование модуля ShareMem является единственным обязательным условием

для организации передачи размещаемых в динамической памяти строк и динамиче-

ских массивов из одного приложения в другое. При этом также передается и право собственности на память, занимаемую строками. После приведения внутренних строк к типу Pchar и последующей их передачи в другой модуль как параметра типа PChar право собственности на строковую память вызываемому модулю не передается, по- этому модуль интерфейса ShareMem не требуется.

Следует  учесть,  что  модуль  ShareMem применяется  только  к  библиотекам  DLL

Delphi/C++Builder, которые передают строки или динамические массивы другим биб-

лиотекам Delphi/C++Builder или файлам EXE. Никогда не передавайте строки или ди- намические массивы Delphi (в качестве параметров или результатов выполнения экс- портируемых функций библиотек DLL) в функции библиотек DLL или приложения, на- писанные на языке, отличном от Delphi, поскольку чужеродные приложения не смогут правильно освободить память после использования элементов среды Delphi.

Кроме  того,  модуль  ShareMem не   нужен  приложениям,  встроенными   в   пакеты.

В этом случае диспетчер памяти распределяет память между членами пакета неявно.

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

Источник: Тейксейра, Стив, Пачеко, Ксавье.   Borland Delphi 6. Руководство разработчика. : Пер.  с англ. — М. : Издательский дом “Вильямс”, 2002. —  1120 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии