Глава 4. Взаимодействие приложений
Создание динамически подключаемых библиотек (DLL) Библиотеки DLL являются хранилищем различных компонентов (обычно процедур, функций и ресурсов). Вызов компонентов из библиотеки производится динамически при выполнении приложения по мере обращения к компонентам и не зависит от языка программирования. Это позволяет изменять компонент отдельно от приложения, не перетранслируя его, и использовать его в приложениях, написанных на других языках программирования (C++, Visual Basic). Приведем пример создания библиотеки из двух функций Sum и Mult. Выполним команду File/New/Dll. Сформируется заготовка, которую далее отредактируем, после строки {$R *.RES} вставим строки: function Mult(x,y:double):double; begin Result:=x*y; end; // произведение x*y function Sum(x,y:double):double; begin Result:=x+y; end; // сумма x+y exports Sum, Mult; //список имен экспортируемых функций Sum, Mult Сохраним проект под именем BSP и откомпилируем его (^F9), сформируется файл Bsp.Dll. Внимание! Регистры букв в имени функции (в команде объявления функции в проекте) и в заголовке функции (в библиотеке) должны соответствовать. В библиотеке можно хранить не только программы, но и ресурсы, например формы. Для примера создадим в проекте BSP форму (Form1) с надписью «Форма из BSP.DLL» и процедуру ShowFormDll (для создания и вывода формы Form1) вида: procedure ShowFormDll(AOwner:TComponent); //заголовок процедуры var F:TForm1; //переменная типа TForm1 begin F:=TForm1.Create(AOwner); //создание формы F.ShowModal; {вывод формы} F.Free; {удаление формы} end; Дополним строку exports: exports Sum, Mult, ShowFormDll; //список имен экспортируемых функций Откомпилируем проект (^F9) и получим новый вариант Bsp.DLL с дополненный формой и процедурой ее создания ShowFormDll. Создайте новый проект для проверки Bsp.DLL (например, форма с двумя полями ввода чисел и кнопками (суммировать, перемножить, вывести форму) для проверки подпрограмм Sum, Mult, ShowFormDll).
В новом проекте объявите процедуры: function Mult(x,y:double):double; //объявление функции Mult external 'bsp.dll' //имя библиотеки DLL с функцией Mult function Sum(x,y:double):double; //объявление функции Sum external 'bsp.dll' //имя библиотеки DLL с функцией Sum procedure ShowFormDll (AOwner:TComponent); //объявление процедуры external 'bsp.dll' //имя библиотеки DLL с процедурой ShowFormDll. Вывод формы можно реализовать командой ShowFormDll(Self). Создание новых компонентов Компоненты компилируются и хранятся в специальных, динамически вызываемых библиотеках ‑ пакетных файлах (BPL). Пакетные файлы (Packages) служат для передачи и использования компонентов в различных приложениях, разрабатываемых на различных языках программирования, поддерживающих стандартный интерфейс компонентов. Для примера создадим новый компонент Divide, который делит два числа, задаваемых его свойствами Val1 (делимое) и Val2 (делитель), а результат помешается в свойство Res. Событие OnZero возникает при делении на ноль. Компонент разместим на панели Samples. Создадим новый проект командой File/New/Component. В появившемся окне заполним первые четыре поля Ancestor Type (тип родителя), ClassName (имя создаваемого класса), Palette Page (панель для размещения), Unit file name (имя файла) (рис. 4.2.1). Нажмем кнопку Ok, сформируется текст оболочки компонента. Далее введем дополнительный код. Приведем весь текст компонента с комментариями (для наглядности выделим строки с кодами оболочки компонента жирным шрифтом). Рис. 4.2.1. Настройка компонента Divide Текст компонента Divide unit Divide; //имя модуля interface //интерфейсная часть uses //подключаемые модули Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; Type //раздел типов //Можно формировать потомка на основе класса, например, TLabel, исполь//зуя свойства родителя и добавляя новые свойства и события.
//MyLabel = class(TLabel) //формирование потомка из класса TLabel //Если имя родительского класса начинается с текста TCustom, то потомок //существенно отличается от родителя и не все свойства и события //переносятся потомку, например: //MyLabel = class(TCustomLabel) //формирование потомка из TCustomLabel //Если имя родительского класса TComponent, то компонент практически //наследует самые общие свойства компонентов. TDivide = class(TComponent) //формирование нового класса TDivide Private //поля, методы, свойства и события, доступные только в классе { Private declarations } //объявление переменных и методов Fzero: TNotifyEvent; //переменная типа события (имена начинаются с F) FVal1: Double; //переменная для хранения значения свойства Val1 FVal2: Double; //переменная для хранения значения свойства Val2 FRes: Double; //переменная для хранения значения свойства Res procedure SetVal1(InVal:Double); //метод установки делимого (Val1) procedure SetVal2(InVal:Double); //метод установки делителя (Val2) protected //аналогичен Private и дополнительно доступен потомкам { Protected declarations } public //поля, методы, свойства и события, доступные всем вне класса { Public declarations } //Конструктор создает представителя класса при размещении или при //выполнении. Он имеет один параметр - компонент‑владелец. Слово //Override означает, что заменяется наследуемый конструктор TComponent. constructor Create (AOwner:TComponent); override; //основной конструктор procedure DoDivide;//объявление процедуры выполнения деления Property Res: Double read FRes;//значение свойства Res в переменной FRes Published //аналогичен Public и изменяемый в Инспекторе Объектов { Published declarations } //Объявления свойств. Значения свойств (read) читаются из переменных //Fval1, Fval2, а устанавливаются (write) процедурами SetVal1, SetVal2. Property Val1: Double read FVal1 write SetVal1; //свойство Val1 Property Val2: Double read FVal2 write SetVal2; //свойство Val2 //Объявления свойства-события OnZero. Значения свойств (read) читаются //и устанавливаются переменной‑событием FZero. Property OnZero: TNotifyEvent read FZero write FZero; //событие OnZero end; procedure Register; //объявление процедуры регистрации компонента implementation //исполнимая часть procedure Register; //заголовок процедуры регистрации компонента begin //процедура регистрации компонента TDivide на панели Samples RegisterComponents('Samples', [TDivide]); end; //конец процедуры регистрации constructor TDivide.Create(AOwner:Tcomponent); //заголовок конструктора begin inherited Create(AOwner);//вызов конcтруктора родительского класса
FVal1:=1; //установка значения FVal (свойства Val1) по умолчанию =1 FVal2:=1; //установка значения Fva2 (свойства Val2) по умолчанию =1 end; //конец конструктора procedure TDivide.SetVal1(InVal:Double);//метод установки значения Val1 begin FVal1:=InVal; DoDivide; end;//переменной Fval1 (свойства Val1) procedure TDivide.SetVal2(InVal:Double); //метод установки значения Val2 begin FVal2:=InVal; DoDivide; end; //переменной Fval2 (свойства Val2) procedure TDivide.DoDivide; //метод деления двух чисел begin if Val2<>0 then FRes:=FVal1/FVal2//формирование значения свойства Res //Функция Assigned возвращает истину, если имеется процедура обработки //события и процедура OnZero данного компонента (Self) выполняется else if assigned(FZero) then OnZero(Self);//выполнение обработчика OnZero end; //конец метода деления end. //конец компонента Для отладки компонента создадим новый проект и включим в него модуль компонента Divide командой Project/Add to Project/Divide. Дополним команду Uses модуля Unit1 именем Divide (подключим этот модуль). В разделе переменных (Var) модуля Unit1 объявим переменную D типа TDivide (D:TDivide;) и составим обработчик события OnCreate для формы: procedure TForm1.FormCreate(Sender: TObject); //заголовок begin D:=TDivide.Create(Self); //создание экземпляра компонента TDivide D.Val1:=3; D.Val2:=4; //задание свойств для созданного компонента //для проверки обработчика события OnZero нужно задать D.Val2=0 D.DoDivide; //выполнение деления методом DoDivide Form1.Caption:=FloatToStr(D.Res);//вывод результата (свойство Res) end; Установим компонент на палитру после отладки командой Component/Install Component/Into new package. В появившемся окне заполним его поля (рис. 4.2.2). Далее компонент можно размещать как обычно. Для удаления компонента выполняется команда Components/Install Packages. В списке компонентов помечается удаляемый; нажимаем кнопку Remove. Рис. 4.2.2. Окно установки компонента 4.3. Создание и установка ActiveX‑элементов Можно визуально создать компонент (OCX‑файл) на основе уже имеющегося командой File/New/ActiveX/ActiveX Control. В поле VCL Class Name выберите базовый класс (например, TButton) и нажмите кнопку OK. Получим исходный текст потомка TButtonX наследника TButton. После компиляции проекта (^F9) появится компонент ActiveX под именем ButtonXControl1.OCX, который можно использовать в других проектах.
Активная форма является одним из видов ActiveX‑элементов и создается командой File/New/ActiveX/ActiveForm. Далее можно размещать на этой форме нужные компоненты, и после трансляции (^F9) формируется OCX‑файл (со всеми компонентами и процедурами), который можно использовать в проектах после размещения на форме проекта. Для размещения нового компонента ActiveX (в том числе и активной формы) на панели компонентов (например, ActiveX) выполните команду Component/Import ActiveX Control/Add и выберите имя нужного OCX‑файла (например, ButtonXControl1.OCX или ActiveFormProj1.OCX) и нажмите кнопку Install.
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|