Разработка интегрированных прикладных программ (Меньшикова К. Г.). Разработка интегрированных прикладных программ (Меньшикова К. Г.. Методическое пособие по курсу Проектирование программного обеспечения автоматизированных систем для студентов, обучающихся по направлению Прикладная математика и информатика
Скачать 313.5 Kb.
|
1.1.Интерфейсы в DelphiДля объявления интерфейса в Delphi используется ключевое слово interface. Для создания нового GUID применяется сочетание клавиш Ctrl-Shift- G [3]. Родительским интерфейсом является IUnknown. Например, так может быть объявлен следующий интерфейс: ITint=interface ['{4457B5CC-2082-46B3-92F1-BC7CB3CF44C4}'] procedure My_Msg; end; Реализовать интерфейс можно только в классе: TTint=class(TInterfacedObject,ITint) procedure MyMsg; procedure ITint.My_Msg=MyMsg; destructor Destroy; override; end; Объявления переменных, код процедуры и деструктора: Var Form1: TForm1; Tint:ITint; T:TTint; procedure TTint.MyMsg; begin MessageBox(0,'Test','Сообщение',0); end; destructor TTint.Destroy; begin inherited; MessageBox(0,'Free',nil,0); end; Для создания интерфейса сначала нужно получить объект соответствующего класса, применив, например, следующий код: T:=TTint.Create; Tint:=T; Или более коротко: Tint:=TTint.Create as ITint; после этого можно вызывать методы интерфейса: Tint.My_Msg; При выходе переменной за область видимости ссылка на интерфейс будет уничтожена, поскольку Delphi вызывает методы интерфейса IUnknown неявно и автоматически. Если надо освободить интерфейс, не дожидаясь выхода за область видимости, можно применить Tint:=nil; при этом Delphi вызовет IUnknown._Release. Использование T.Free вызовет ошибку, поскольку класс будет освобожден тогда, когда отпадет необходимость в его интерфейсах. 1.2.Присоединение интерфейсов к формамС помощью механизма интерфейсов от различных программных компонент можно добиться одинаковой функциональности. Для этого достаточно реализовать интерфейс в компоненте, а в вызывающем модуле проверить его наличие. В следующем примере интерфейс описан в отдельном модуле, а разрабатываемый класс формы наследует и реализует его: unit Unit2; interface type IMessageInterface=interface ['{C6DB380C-41CB-49C7-AAE8-FAA5C0E00469}'] procedure Msg_Name; end; В модуле формы класс TForm3 наследует интерфейс: unit Unit3; interface type TForm3 = class(TForm, IMessageInterface) private procedure Msg_Name; end; var Form3: TForm3; implementation procedure TForm3.Msg_Name; begin ShowMessage('Form3'); end; Теперь возможен вызов методов интерфейса из других модулей, в которых видна форма Form3. Например, по щелчку на кнопке в модуле Unit1 ( Form1 ): procedure TForm1.Button2Click(Sender: TObject); var IMI: IMessageInterface; begin if Assigned(Form3) and Form3.GetInterface(IMessageInterface,IMI) then IMI.Msg_Name; end; Добавив этот интерфейс к другим компонентам приложения, можно единообразно вызывать их методы. В приведенном примере можно было присоединить к форме не один, а несколько интерфейсов и вызывать еще и их методы. Кроме этого по-прежнему остаются доступными свойства и методы формы, унаследованные от класса TForm. Но, к сожалению, доступ к разработанному нами объекту-форме возможен только из того же самого приложения, где этот объект создан. 1.3.Объекты COMВ отличие от случая, рассмотренного в предыдущем примере, COM-объект предоставляет свою функциональность только посредством механизма интерфейсов. Этим достигается универсальность в общении приложений-клиентов с любыми COM-объектами. Каждый объект реализован внутри некоторого сервера: в динамической библиотеке; в отдельном выполнимом приложении на том же компьютере; в удаленном коде, выполняющемся на компьютере, отличном от компьютера клиента. Сервер содержит код методов интерфейсов объекта, а также данные объекта пока он активен. С точки зрения клиента объект любого сервера выглядит совершенно одинаково и доступ к его методам осуществляется через указатели на интерфейсы. Объект обязан (иначе это не COM-объект) иметь интерфейс IUnknown, в протокол которого входят три метода: QueryInterface – запрос указателя требуемого интерфейса, AddRef – увеличение счетчика ссылок, Release – уменьшение счетчика. Объекты поддерживают счетчики ссылок, чтобы знать, когда можно завершить свою работу (счетчик = 0 – объект не имеет клиентов). Все остальные интерфейсы являются наследниками IUnknown, а значит, имея указатель на любой интерфейс объекта, клиент может получить точку входа в другой необходимый ему интерфейс. Каждый COM-объект является экземпляром некоторого класса, и каждый класс может иметь GUID – идентификатор класса (CLSID). Он нужен в основном для того, чтобы библиотека COM могла найти необходимый сервер в базе объектов (реестре) и создать экземпляр класса (объект). Под классом, в данном случае, понимается конкретная реализация некоторого набора интерфейсов. Понятно, что разные классы могут иметь совершенно одинаковые интерфейсы. Большинство фирм не разрабатывают собственные интерфейсы, а используют существующие. Например, интерфейс IDispatch предназначен для автоматизации приложений. |