Текст вызывающей программы
unit TestMainU; interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TTestMain = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Label1: TLabel; procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private { Private declarations }
public { Public declarations }
// Следующая процедура обрабатывает сообщение WM_USER,
// которое посылает форма из DLL в момент своего закрытия
procedure WMUser(var Msg: TMessage);
message WM_USER; end; var TestMain: TTestMain; implementation {$R *.DFM}
function ShowModalForm: Integer; External 'DLLWithForm'; procedure ShowForm(Appl, Form: THandle);
External 'DLLWithForm'; procedure FreeForm; External 'DLLWithForm'; procedure TTestMain.Button1Click(Sender: TObject);
// Модальный вызов
begin Button2.Enabled := False; label1.Caption := 'ModalResult = '+IntToStr(ShowModalForm);
label1.Show; // Показываем результат вызова Button2.Enabled := True end; procedure TTestMain.Button2Click(Sender: TObject);
// Немодальный вызов
begin Button1.Enabled := False; Button2.Enabled := False; Button3.Enabled := True; label1.Hide; ShowForm(Application.Handle, Self.Handle);
end; procedure TTestMain.Button3Click(Sender: TObject);
// Закрыть форму
begin FreeForm; Button1.Enabled := True; Button2.Enabled := True; Button3.Enabled := False; end; procedure TTestMain.WMUser(var Msg: TMessage);
// Сообщение из формы DLL о ее закрытии
begin Button3.Click end; end.
Модуль формы DLLForm, помещенной в DLL, ссылается на стандартный модуль Forms и, таким образом, получает свой глобальный объект Application, который ничего «не знает» о глобальном объекте вызывающей программы. В режиме модального вызова это не имеет особого значения, поскольку модальное окно блокирует работу вызывающей программы. В режиме немодального вызова следует синхронизовать действия объектов, в противном случае минимизация главного окна, например, не приведет к минимизации окна DLL. Синхронизация достигается тем, что дескриптор объекта Application DLL заменяется соответствующим дескриптором вызывающей программы.
При показе формы в немодальном режиме она может быть закрыта либо вызвавшей ее программой, либо щелчком по собственной системной кнопке Закрыть. В последнем случае она должна каким-то образом известить вызывающую программу об этом событии. Для этого используется стандартный механизм посылки Windows-сообщения. Сообщение должно иметь адрес — дескриптор окна, для которого оно предназначено. Вот почему вторым параметром обращения к функции ShowForm в DLL передается и в поле CallForm запоминается дескриптор окна вызывающей программы. Обработчик события OnClose формы проверяет это поле и, если оно определено, посылает вызвавшему окну сообщение с индексом WM_USER. В вызывающей программе предусмотрен обработчик этого сообщения, в котором реализуются необходимые действия.