Включение в библиотеку форм

Несмотря на то, что DLL не имеет собственной формы, с ее помощью можно вызывать формы из связанных с библиотекой модулей. Для этого в библиотеке используется ссылка uses на связанные модули-формы и объявляются экспортируемые из DLL подпрограммы, в которых реализуется вызов соответствующих форм.

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

Текст DLL

library DLLWithForm;


uses
SysUtils,
Classes,
DLLFormU in 'DLLFormU.pas' {DLLForm};


{$R *.RES}


exports


ShowModalForm, ShowForm, FreeForm;
begin


end.

Текст формы в DLL

unit DLLFormU;


interface


uses


Windows, Messages, SysUtils,Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, Buttons;


type


TDLLForm = class (TForm)
BitBtnl: TBitBtn;
BitBtn2: TBitBtn;


procedure FormClose(Sender: TObject;


var Action: TCloseAction);


private
{ Private declarations }
CallForm: THandle; //Дескриптор вызывающей формы


public
{ Public declarations }


end;


// Объявление экспортируемых подпрограмм
function ShowModalForm: Integer;
procedure ShowForm(aHandle: THandle);
procedure FreeForm;


var
DLLForm: TDLLForm;
implementation
{$R *.DFM}
function ShowModalForm: Integer;
// Модальный вызов
begin
DllForm:= TDllForm.Create(Application);
Result:= DLLForm.ShowModal;
DLLForm.Free;
end;


procedure ShowForm(Appl, Form: THandle);
// Немодальный вызов
begin
Application.Handle:= Appl; // Замена объекта
Application DllForm:= TDllForm.Create(Application);
// Запоминаем дескриптор вызывающего окна для посылки
// ему сообщения о закрытии
CallForm:= Form;
DLLForm.Show
end;


procedure FreeForm;
// Уничтожение формы


begin
DLLForm.Free
end;


procedure TDLLForm.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
if CallForm>O then
SendMessage(CallForm, wm_User, 0, 0)
end;
end.


Текст вызывающей программы

unit TestMainU;


interface


uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs, StdCtrls;


type
TTestMain = class (TForm)
Buttoni: TButton; // Открыть в модальном режиме
Button2: TButton; // Открыть в немодальном режиме
Button3: TButton; // Закрыть окно
Label I: TLabel;


procedure ButtonlClick(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure ButtonSClick(Sender: TObject);

private
{ Private declarations }
public
{ Public declarations }
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.ButtonlClick(Sender: TObject);
// Модальный вызов
begin
Button2.Enabled:= False;
label1.Caption:= 'ModalResult = '+IntToStr(ShowModalForm);
label1.Show; // Показываем результат вызова
Button2.Enabled:= True
end;

procedure TTestMain.Button2Click(Sender: TObject);
// Немодальный вызов
begin
Buttoni.Enabled:== False;
Button2.Enabled:= False;
Buttons.Enabled:= True; label 1.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
Buttons.Click
end;


end.

Модуль формы DLLForm, помещенной в DLL, ссылается на стандартный модуль Forms и таким образом получает свой глобальный объект Application, который ничего 'не знает' о глобальном объекте вызывающей программы (см. гл. 21). В режиме модального вызова это не имеет особого значения, т. к. модальное окно блокирует работу вызывающей программы. В режиме немодального вызова следует синхронизовать действия объектов, в противном случае минимизация главного окна, например, не приведет к минимизации окна DLL. Синхронизация достигается тем, что дескриптор объекта Application DLL заменяется на соответствующий дескриптор вызывающей программы.

При показе формы в немодальном режиме она может быть закрыта щелчком по собственной системной кнопке закрыть. В этом случае она должна каким-то образом известить вызывающую программу об этом событии. Для этого используется стандартный механизм посылки вызывающей форме Windows-сообщения. Сообщение должно иметь адрес, в роли которого используется дескриптор окна, получающего это сообщение. Вот почему вторым параметром обращения к функции ShowForm в DLL передается и в поле CallForm: запоминается дескриптор вызывающего окна. Обработчик события enclose формы проверяет это поле и, если оно определено, посылает вызывающему окну сообщение с индексом wm_user. В вызывающей программе предусмотрен обработчик этого сообщения, в котором реализуются необходимые действия.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: