Скачиваний:
100
Добавлен:
01.05.2014
Размер:
1.56 Mб
Скачать

Технология ole Внедрение и связывание объектов - ole

Прежде, чем рассматривать реализацию в C++Builder технологии внедрениям связывания объектов OLE (произносится "оле" с ударением на последний слог), остановимся на некоторых базовых понятиях. Эта технология появилась как OLE 1.0 в Windows 3.1 и означала, что пользователь мог создавать сложные составные документы, в которых содержались объекты различного происхождения. Внедренные объекты могли редактироваться простым двойным щелчком мыши на соответствующем элементе данных. Например, можно было дважды щелкнуть на электронной таблице Excel, встроенной в документ редактора Word, и в отдельном окне запускался Excel с загруженным рабочим листом, готовым к редактированию. После завершения редактирования Excel позволял сохранить изменения во внедренном в документ Word объекте Excel.

Другой особенностью было связывание объектов. Это позволяло связать электронную таблицу с документом Word (по сути, внутри документа Word хранился просто указатель на электронную таблицу). Если данные в оригинале электронной таблицы обновлялись, то при следующей загрузке документа Word ссыпка обновляла документ и отражала в нем проведенные изменения.

Дальнейшее развитие внедрение и связывание получило в OLE 2.0. Основой этого усовершенствованного подхода явилась компонентная модель объекта (СОМ), Это модель объекта в системном обеспечении, которая предусматривает полную совместимость во взаимодействии между компонентами, написанными разными компаниями и на разных языках. Ключом к успеху является модульность этих компонентов. Они могут покупаться, модернизироваться или заменяться по одиночке или группами, причем это никак не влияет на работу целого. Новая особенность, появившаяся в OLE 2.0, — это автоматизация OLE, которая обеспечивает доступ к объектам приложения и манипуляцию с ними извне. Такие объекты, предоставленные (экспонированные) для внешнего пользования, называются автоматными объектами OLE. Типы объектов, которые могут быть экспонированы, так же разнообразны, как и сами приложения Windows. Текстовый процессор мог бы экспонировать в качестве автоматного объекта документ, абзац или предложение. Электронная таблица могла бы экспонировать таблицу, диаграмму, ячейку или группу ячеек.

Главное отличие автоматных объектов от обычных объектов OLE состоит в том, что автоматные объекты доступны только программно, они создаются и используются при помощи программного кода и, следовательно, в принципе временны. Они не могут быть внедрены или связаны. Они могут существовать только в течение времени выполнения ваших программ и не видны непосредственно конечному пользователю.

Использование ole-документов в приложениях

Теперь рассмотрим некоторые приемы использования OLE в C++Builder. На странице System библиотеки визуальных компонентов имеется контейнер OLE OleContainer — компонент, обеспечивающий внедрение и связывание. OLE-контейнер инкапсулирует все интерфейсы, необходимые для создания клиента OLE документов. Давайте посмотрим его возможности сначала на очень простом примере. Разместите на форме контейнер OleContainer, компонент главного меню MainMenu, диалоги OpenDialog и SaveDialog. Можно также разместить список изображений ImageList, панель ToolBar и на ней быстрые кнопки, дублирующие основные команды меню. Впрочем, можете этими изысками не заниматься, но меню, как мы увидим ниже, должно быть обязательно.

Панель, если вы ее ввели, выравнивается по верху формы (Align = alTop), a контейнер должен занимать всю оставшуюся площадь формы (Align — alClient).

В MainMenu введите меню "Объект" и в нем разделы "Новый", "Открыть", "Сохранить", "Закрыть". Назовите объекты этих разделов MNew, MOpen, MSave и MClose.

Установите в диалогах в свойстве Filter: «объекты OLE *.ole» и «все файлы *.*». Установите также в диалогах расширение по умолчанию в свойстве DefaultExt равным ole.

Теперь перейдем собственно к программированию. Давайте введем в определении класса формы глобальную переменную FName, в которой будет храниться имя файла объекта OLE:

AnsiString FName;

Процедура, соответствующая разделу меню "Новый", может иметь вид:

void __fastcall TForm1::MNewClick(TObjeot *Sender)

{

if (OleContainer1->InsertObjectDialog ())

{

FName = "";

OleContainer1->DoVerb (ovShow);

}

}

Вызываемый этим оператором метод InsertObjectDialog осуществляет обращение к стандартному окну Windows Insert Object (вставка объекта), в котором пользователь может указать тип вставляемого объекта, инициализирует объект OLE и загружает его в контейнер OleContainer1. Вызываемый далее метод DoVerb обеспечивает немедленное открытие программы, связанной со вставленным документом. Вызов DoVerb можно не вводить в приведенный код. Тогда после вставки документа пользователь должен будет сделать двойной щелчок на контейнере, чтобы открыть соответствующую программу.

Работу с окном "Вставка объекта", которую инициирует приведенный код, мы рассмотрим несколько позднее, а пока продолжим создание приложения. Процедура, соответствующая разделу меню "Закрыть", может иметь вид:

void __fastcall TForm1::MCloseClick(TObject *Sender)

{

OleContainer1->DestroyObject ();

}

Эта процедура разрушает объект в контейнере OLE.

Процедура, соответствующая разделу меню "Сохранить", может иметь вид:

void __fastcall TForm1::MSaveClick(TObject *Sender)

{

if (FName == "")

if (SaveDialog1->Execute ())

FName = SaveDialog1->FileName;

else return;

OleContainer1->SaveToFile(ChangeFileExt (FName, ".ole"));

}

Если имя файла не задано, то вызывается диалог Сохранить как (SaveDialog1), с помощью которого пользователь задает имя файла. Затем методом SaveToFile объект сохраняется в файле. При этом во избежание ошибок расширение файла принудительно заменяется на .ole с помощью функции ChangeFileExt, изменяющей расширение файла.

Процедура, соответствующая разделу меню "Открыть", может иметь вид:

void __fastcall TForm1::MOpenClick(TObject "Sender)

{

if (OpenDialog1->Execute ())

{

OleContainer1->LoadFromFile(OpenDialog1->FileName);

FName = OpenDialog1->FileName;

OleContainer1->DoVerb(ovShow);

}

}

Она обычным образом вызывает диалоговое окно, в котором пользователь выбирает открываемый файл. Затем объект, соответствующий этому файлу, загружается в контейнер методом LoadFromFile. Имя файла запоминается в переменной FName. Последний оператор методом "DoVerb" открывает программу, связанную с загруженным объектом. Этот оператор записывать не обязательно. Но тогда для открытия программы пользователь должен будет сделать двойной щелчок на контейнере OLE.

Теперь посмотрим, как работает наше приложение. Запустите его на выполнение и выполните команду "Новый". Перед вами откроется окно Вставка объекта (Insert Object). В этом окне вам предоставляются две возможности: создание нового объекта OLE (радиокнопка "Создать новый"), или создать объект из имеющегося файла (радиокнопка "Создать из файла").

Рассмотрим сначала первую возможность. В этом случае в окне "Тип объекта" вы должны указать тип вставляемого в контейнер объекта. Это может быть документ Word, лист Excel, объект звукозаписи, точечный рисунок и т.п. Правда, к сожалению, надо отметить, что не любой тип объекта и не в любой версии Windows может быть вставлен. Так что с переносимостью подобных приложений могут иногда возникать проблемы. Если вставка не получится, вам будет выдано соответствующее сообщение.

После того как вы выбрали тип объекта, щелкните на ОК. Дальнейшее зависит от того, включили ли вы в код процедуры MNewClick вызов метода DoVerb. Если не включали, то в первый момент в контейнере OLE вашего приложения отобразится вид объекта по умолчанию. Этот вид зависит от типа объекта. Возможно, в первый момент вы вообще ничего не увидите. Надо будет сделать двойной щелчок на контейнере, чтобы вызвать программу, обслуживающую объект этого типа. Если же вы включили в код процедуры MNewClick вызов метода DoVerb, программа, обслуживающая объект, откроется без вашего вмешательства.

В обоих случаях вы увидите, что ваше приложение чудесным образом преобразится. В него встроится соответствующая программа вместе со своими инстру ментальными панелями и меню, например, Excel. Вы можете создать какую-то таблицу, построить соответствующие диаграм мы и т.п.

Обратите внимание на то, что ваша инструментальная панель сохранилась на экране и после загрузки объекта и начала работы с ним. И, главное, заметьте, что не все разделы меню программы Microsoft Excel встроились в ваше приложение. Нет первого меню — Файл, в котором содержатся команды открытия и сохранения файлов. Это не случайно, так как далее будет показано, что сохранение объекта OLE отличается от сохранения файла изображения. Вместо меню Файл, имеющегося в Microsoft Excel, встроилось меню Объект вашего приложения, в котором имеются соответствующие команды открытия и закрытия файла. Именно ради этого мы и делали в своем приложении меню.

Выше была продемонстрирована возможность внедрения объекта OLE в результате диалога вставки объекта. Этот диалог позволяет выбрать любой доступный тип документа. Но если тип нового объекта известен, можно внедрять его программно. Например, если требуется внедрить объект страницы Excel, то в обработчик события формы OnCreate или в обработчик щелчка на какой-то кнопке надо вставить операторы:

OleContainer1->CreateObject ("Excel.Sheet", false);

OleContainer1->DoVerb (ovShow);

Для создания объектов иных типов второй оператор остается неизменным, а в вызове метода CreateObject меняется только первый параметр — класс создаваемого объекта OLE. Например, оператор

OleContainer1->CreateObject("Word.Document",false);

создаст документ Word, а оператор

OleContainer1->CreateObject("PowerPoint.Show",false);

создаст слайд PowerPoint.

Мы рассмотрели пока одну из возможностей создания в вашем приложении объекта OLE. Теперь давайте рассмотрим другие возможности. Выполните опять команду "Новый" вашего приложения и выберите радиокнопку "Создать из файла" (Create from File). В этом случае вы можете создать объект OLE на основе имеющегося файла. При этом диалоговое окно изменит свой вид. В нем вы можете с помощью кнопки "Обзор" выбрать какой-нибудь файл документа Word, Excel, графический и т.п. Обратите внимание на очень важный индикатор "Связь" (Link). Пока не устанавливайте этот индикатор, а просто нажмите ОК. Вы создадите в своем приложении внедренный (но не связанный) объект OLE. В контейнер приложения загрузится содержимое файла и откроется обслуживающая его программа, как это было и раньше.

Теперь остановимся на сохранении объекта. Если вы выполните команду вашего приложения "Сохранить", то с помощью обычного диалога сохранения можете записать объект в нужный вам каталог. Тем самым вы создадите файл, содержащий внедренный объект OLE. В дальнейшем вы можете открыть его командой Открыть вашего приложения. Это абсолютно автономный объект, никак не связанный с исходным файлом, из которого он был создан. Но открыть его можно только как объект OLE. Если вы попробуете открыть, например, файл, созданный из объекта Excel, самой программой Excel, вы потерпите неудачу, так как Excel не поймет формата этого файла.

Теперь попробуйте создать внедренный и связанный документ. Выполните опять команду "Новый" вашего приложения, в диалоговом окне "Вставка объекта", опять выберите радиокнопку "Создать из файла" (Create from File), выберите какой-нибудь файл, но на этот раз установите индкатор "Связь" (Link). После щелчка на ОК в окне вашего приложения снова появится выбранный вами объект документа. Вы опять можете сохранить этот объект командой Сохранить. Но теперь документ в вашем объекте не просто внедрен, а и связан с исходным файлом. Это означает, что все изменения в исходном файле отразятся в вашем объекте и наоборот. Кроме того, изменяется и взаимодействие вашего приложения с документом. Раньше программа, обслуживающая документ, открывалась в контейнере OLE. А теперь она открывается в отдельном, полноценном окне программы с загруженным в него документом. Вы можете что-то изменить в документе, напечатать его, сохранить. Как только он будет сохранен, в тексте документа в вашем приложении отразятся введенные изменения.

Вы создали очень простое приложение, использующее OLE. Его можно усовершенствовать, добавив в меню еще несколько разделов. Один из них — "Открыть файл". В отличие от рассмотренного ранее раздела, открывающего объект OLE, в данном разделе можно создавать новый объект на основе какого-то существующего файла документа. Делается это методом GreatcObjectFromFile:

void CreateObjectFromFile(AnsiString FileName, bool Iconic);

Аргумент FileName определяет имя открываемого файла. Второй аргумент Iconic, значение которого обычно задается равным false, показывает, что объект отображается в том виде, в каком он содержится в исходном файле. Если задать этот аргумент, равным true, то объект будет отображаться в виде пиктограммы.

Таким образом, в вашем приложении обработчик команды "Открыть файл" может иметь вид:

void __fastcall TForm1::MOpenFClick (TObject *Sender)

{

if (OpenDialog1->Execute ())

{

OleContainer1->CreateObjectFromFile (OpenDialog1->FileName, false);

FName = OpenDialog1->FileMame;

OleContainer1->Repaint ();

}

}

Выполнение этой команды эквивалентно описанному ранее созданию внедренного объекта OLE из файла, но исключает необходимость пользователю работать с дополнительными окнами.

Имеется также аналогичный метод GreateLinkToFile, позволяющий создавать внедренный и связанный объект:

void CreateLinkToFile (const AnsiString FileName, bool Iconic);

Можете воспользоваться им для включения в ваше меню и такого раздела.

Еще один раздел, который можно добавить в меню вашего приложения — "Сохранить файл". В отличие от рассмотренного ранее раздела, сохраняющего в файле объект OLE, в данном разделе можно сохранять документ, содержащийся в объекте, в его натуральном виде. Это можно сделать оператором, использующим функцию SaveAsDocument:

OleContainer1->SaveAsDocument(FName);

Функции CreateObjectFromFile, CreateLinkToFile и SaveAsDocument позволяют построить фактически универсальный редактор текстовых, графических, музыкальных и других файлов.

Модифицируем приложение, добавив еще две кнопки с надписями "Свойства" и "Вставка".

Создадим соответствующие обработчики событий:

void __fastcall TForm1::Button2Click(TObject *Sender)

{

OleContainer1->ObjectPropertiesDialog ();

}

void __fastcall TForm1::Button3Click(TObject *Sender)

{

OleContainer1->PasteSpecialDialog ();

}

Скомпилируем приложение. Добавим какой-нибудь объект в OleContainer.

Нажав на кнопку "Свойства", получим стандартный диалог с описанием свойств объекта.

Нажав кнопку "Вставить", получим диалог вставки объекта.

Выбрав тип вставки объекта, можем вставить его в OleContainer.

В заключение несколько слов об автоматизации OLE. Рассмотренное выше внедрение и связывание позволяют запустить приложение, обрабатывающее соответствующий документ, как единое целое. Автоматизация OLE позволяет управлять этим приложением (сервером OLE), используя экспонированные им функции и процедуры.