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

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

В следующих примерах (TestDLLForm.dpr) иллюстрируется техника включения в DLL формы и использования ее в вызывающей программе (листинги 8, 9 и 10).

Текст 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)    
    BitBtn1: TBitBtn;    
    BitBtn2: TBitBtn;    
    procedure FormClose(Sender: TObject; var Action: TCloseAction);    
  private    
    { Private declarations }    
  CallForm: THandle; //Дескриптор вызывающей формы    
 public    
    { Public declarations }    
  end;    
     
  // Объявление экспортируемых подпрограмм    
  function ShowModalForm: Integer;    
  procedure ShowForm(Appl, Form: 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<>0 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)   
    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. В вызывающей программе предусмотрен обработчик этого сообщения, в котором реализуются необходимые действия.
Теги:
форма
Добавлено: 08 Апреля 2018 06:45:13 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...