Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Включение в библиотеку форм

Несмотря на то, что 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;

// Сообщение из формы DLL о ее закрытии
procedure TTestMain.WMUser(var Msg: TMessage);
begin
  Buttons.Click
end;

end.

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

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

Проект Delphi World © Выпуск 2002 - 2004
Автор проекта: ___Nikolay