Разработка интегрированных прикладных программ (Меньшикова К. Г.) (548342)
Текст из файла
УДК 621.398
М-513
Утверждено учебным управлением МЭИ
Подготовлено на кафедре прикладной математики
Рецензенты: докт. техн. наук, профессор А.Б.Фролов,
канд. техн. наук, доцент М.М. Маран
Меньшикова К.Г.
М-513 Разработка интегрированных прикладных программ: методическое пособие / К.Г. Меньшикова; под ред. А.М. Меньшикова. – М.: Издательство МЭИ, 2006.– 32 с.
Излагаются практические приемы создания сложных приложений на базе COM-технологии. COM предоставляет открытый унифицированный протокол связи программ, который поддерживает стандартный способ управления одной EXE-программы другой, разработку и использование универсальных управляющих элементов, создание сложных составных документов на базе OLE. Рассмотрены вопросы создания серверов и контейнеров OLE-автоматизации, управление офисными приложениями, создание управляющих элементов ActiveX, а также возможности VCL- библиотеки для создания сложных документов. Пособие ориентировано на инструментальные средства разработки программных средств фирмы Borland: С++Builder и Delphi.
Для студентов МЭИ, обучающихся по направлению «Прикладная математика и информатика». Может быть полезно студентам и аспирантам всех специальностей, занимающимся профессиональным созданием сложных Windows-приложений.
_______________________
Учебное издание
Меньшикова Ксения Георгиевна
Разработка интегрированных прикладных программ
Методическое пособие по курсу «Проектирование программного обеспечения автоматизированных систем» для студентов, обучающихся по направлению «Прикладная математика и информатика»
Редактор издательства Г.Ф. Раджабова
Темплан издания МЭИ 2005, метод. Подписано к печати
Формат 60x84/16 Печать офсетная Печ.л. 2,0
Тираж 100 экз. Изд. № 121 Заказ
Издательство МЭИ, 111250, Москва, Красноказарменная, д. 14
Отпечатоно в типографии НИИ «Геодезия», 141292, Московская обл.,
г. Красноармейск, просп. Испытателей, д. 14
© Московский энергетический институт
(технический университет), 2006
Введение
Пособие посвящено разработке сложных приложений на основе COM (Component Object Model – модель многокомпонентных объектов) -одной из базовых технологий Windows. В настоящее время профессиональное программирование требует ее обязательного знания и применения. Основная цель технологии – взаимодействие различных приложений путем экспорта объектов. Можно сказать, что COM обеспечивает новую модульную архитектуру программного обеспечения [2].
Поскольку программные коды пишутся различными разработчиками в разное время, запускаются в разных адресных пространствах и даже на разных компьютерах, то COM – это, прежде всего, система требований к архитектуре программных приложений. Она определяет стандартный механизм, с помощью которого одна часть программного обеспечения предоставляет свои сервисы другой [4]. Чтобы это стало возможно, в любой системе, поддерживающей модель COM, должна иметься библиотека базовых функций, обеспечивающая процесс общения объектов и их клиентов (создание и поиск требуемых объектов, управление памятью, передача данных и т.д). Доступ к функциям библиотеки осуществляется обычным образом.
В настоящее время спецификацией COM охвачены многие аспекты взаимодействия приложений, среди них унифицированный обмен данными, совместное хранение объектов в структурированных хранилищах, создание составных OLE-документов, удаленный доступ к серверам автоматизации, создание ASP-объектов и т.д. Настоящее пособие рассматривает только некоторые аспекты данной технологии и включает следующие разделы:
-
создание приложений-серверов и управляющих ими контроллеров (OLE-автоматизация);
-
управление офисными приложениями MS Word и Excel из других программ;
-
создание и использование управляющих элементов ActiveX;
-
внедрение и связывание OLE-объектов.
Для создания, отладки и тестирования рассматриваемых в пособии примеров использовались С++Builder 6, Delphi 6, MS Office (Word, Excel) 2000.
1.COM-объекты и интерфейсы
“COM – это протокол, который соединяет один программный модуль с другим, а затем покидает сцену. После того, как связь установлена, модули могут взаимодействовать через механизм, называемый интерфейсом (interface)” [2]. Интерфейс – это основное понятие, на котором основана модель COM. Интерфейс включает описание методов и их параметров, но не включает в себя их реализацию. Интерфейсы имеют мнемонические имена, а также уникальные идентификаторы IID в виде GUID (глобальный уникальный идентификатор) – 16-байтное число, сгенерированное специальной утилитой.
Можно говорить о наследовании интерфейса; это подразумевает, что интерфейс-потомок включает в себя все методы предка. Базовым интерфейсом в модели COM является интерфейс IUnknown, все другие являются его потомками и должны реализовать объявленные в нем методы.
Каждый интерфейс однозначно определяется своим IID, имеет определенный список методов со своими параметрами. Применительно к COM разработчики программных продуктов должны строго придерживаться следующего принципа (правила постоянства интерфейсов): если интерфейс где-то опубликован и начал работать, то изменять его нельзя. Любое изменение функциональности требует создания нового интерфейса, естественно, с новым идентификатором.
Для лучшего понимания работы с интерфейсами обратимся к среде Delphi, расширившей синтаксис языка Pascal новыми управляющими словами для использования интерфейсов.
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 предназначен для автоматизации приложений.
2.OLE-автоматизация
Любое приложение, которое хочет сделать доступными для других программ свои внутренние функции, (т.н. программируемое приложение), может осуществить это, предоставив клиентам объекты, реализующие интерфейс IDispatch. Это обычный COM-интерфейс, который реализован с помощью виртуальной таблицы указателей на его методы, но в его состав входит метод Invoke, который используется для вызова других (диспетчерских) методов. Клиент, которого в данном случае принято называть контроллером автоматизации, может посредством Invoke обращаться к необходимому методу и передавать параметры.
Конечно, современные программные инструментарии предоставляют в распоряжение программистов достаточно удобные средства для создания серверов и контроллеров. Рассмотрим примеры их создания.
2.1.Создание сервера автоматизации в Builder C++
Д ля создания сервера можно разработать обычное приложение и затем добавить к нему описание класса COM-объекта, создаваемого этим приложением. Через этот объект будет осуществляться доступ к функциональности, которую нужно автоматизировать.
На рис. 1 представлено главное окно приложения-сервера «День недели».
Рис. 1
Приложение должно выводить на экран текущую дату (в Label2) и день недели (в Label3). В поле ввода (Edit1) можно ввести любую дату, а по щелчку на кнопке (Button1) получить день недели, соответствующий введенной дате.
В класс формы (Form1) главного окна приложения были добавлены следующие функции:
void __fastcall TForm1::day_this(int& n);
void __fastcall TForm1::day_date(AnsiString str,int& n);
void __fastcall TForm1::day_week(int n, AnsiString& str);
В модуль формы следует также добавить строку #include , которая обеспечит обращение к системным функциям.
Функция day_this возвращает номер дня недели (1 – воскресенье):
void __fastcall TForm1::day_this(int& n)
{ n=DayOfWeek(Date()); }
Функция day_date по заданной дате возвращает номер дня недели:
void __fastcall TForm1::day_date(AnsiString str,int& n)
{ TDateTime dtDate = StrToDate(str);
n=dtDate.DayOfWeek(); }
Функция day_week по заданному номеру дня недели возвращает его название:
void __fastcall TForm1::day_week(int n, AnsiString& str)
{ char days[7][12] = {"Воскресенье","Понедельник",
"Вторник","Среда", "Четверг","Пятница","Суббота"};
str=(AnsiString)(days[n-1]); }
Пусть при создании формы Form1 в окне появляется текущая дата:
void __fastcall TForm1::FormCreate(TObject *Sender)
{ int i; AnsiString str;
str = DateToStr(Date()); Label2->Caption=str;
day_this(i); day_week(i,str); Label3->Caption=str; }
При щелчке на кнопке Button1, по дате, введенной в Edit1, определяется день недели:
void __fastcall TForm1::Button1Click(TObject *Sender)
{int i; AnsiString str; str=Edit1->Text;
try
{ day_date(str,i); day_week(i,str);
Label5->Caption=str; }
catch(Exception &e)
{ Application->MessageBoxA (e.Message.c_str(),
"Ошибка",MB_OK); } Label4->Caption=Edit1->Text; }
Сохранив проект, как обычное Windows-приложение, затем можно превратить его в сервер автоматизации. Для этого следует:
-
на странице ActiveX галереи объектов выбрать элемент Automation Object;
-
в появившемся диалоговом окне ввести имя класса (CoClassName); под этим именем данный класс COM-объектов будет зарегистрирован в реестре. В нашем примере введено имя класса: DayWeek;
-
в редакторе библиотеки типов (Type Library Editor) определить свойства и методы созданного класса;
-
на инструментальной панели редактора библиотеки типов нажать кнопку Refresh Implementation для генерации модуля с заготовками методов (в нашем примере сгенерирован модуль DayWeekImpl).
Обычно описания интерфейсов создаются на языке IDL (Interface Definition Language), а затем по ним строится библиотека типов. При работе в среде Builder C++ и Delphi достаточно в окне редактора библиотеки указать свойства и методы создаваемого COM-объекта. Объект (рис. 2) имеет диспетчерский интерфейс IDayWeek, в состав которого входят два метода (Today, Data_Day) и свойство Visible.
Характеристики
Тип файла документ
Документы такого типа открываются такими программами, как Microsoft Office Word на компьютерах Windows, Apple Pages на компьютерах Mac, Open Office - бесплатная альтернатива на различных платформах, в том числе Linux. Наиболее простым и современным решением будут Google документы, так как открываются онлайн без скачивания прямо в браузере на любой платформе. Существуют российские качественные аналоги, например от Яндекса.
Будьте внимательны на мобильных устройствах, так как там используются упрощённый функционал даже в официальном приложении от Microsoft, поэтому для просмотра скачивайте PDF-версию. А если нужно редактировать файл, то используйте оригинальный файл.
Файлы такого типа обычно разбиты на страницы, а текст может быть форматированным (жирный, курсив, выбор шрифта, таблицы и т.п.), а также в него можно добавлять изображения. Формат идеально подходит для рефератов, докладов и РПЗ курсовых проектов, которые необходимо распечатать. Кстати перед печатью также сохраняйте файл в PDF, так как принтер может начудить со шрифтами.