Скачиваний:
90
Добавлен:
28.06.2014
Размер:
318.46 Кб
Скачать

OLE -технология

OLE – технология (Object Linking and Embedding – объектное связывание и встраивание) позволяет создавать сложные составные документы, в которых содержатся разнотипные объекты, созданные различными приложениями. Так в текстовый документ редактора Word можно вставить таблицу Excel, диаграмму, поясняющую текст, или математическую формулу, для пользователя это останется единым документом. Приложение, отвечающее за составной документ, принято называть контейнером. Оно имеет сложную структуру, так как умеет работать с “чужими” объектами. Приложение, создавшее объект, называется сервером.

Контейнеры и серверы могут поддерживать два режима взаимодействия:

  • встраивание (внедрение) объектов. Этот режим означает, что данные объекта будут храниться вместе с основным документом (например, внедренная таблица Excel будет сохранена в .doc – файле редактора Word).

  • связывание объектов. В составном документе хранится только ссылка на объект, данные которого находятся в другом документе.

При внедрении увеличивается объем хранимых документов, однако, их легче перемещать, тогда как при связывании, необходимо помнить, что изменение места расположения файлов может привести к ошибочным ссылкам.

Для редактирования связанных данных открывается отдельное окно, того приложения, в котором эти данные были созданы, т.е. сервера. При внедрении объектов можно также запустить сервер в отдельном окне, но можно и редактировать данные «на месте» («in Place»), т.е. в окне контейнера, если он это позволяет. В этом случае контейнер обязан иметь меню, а загрузившийся «in Place»сервер дополнит его своими командами.

Компонент oleContainer

На странице System палитры компонент в Borland Builder С++ есть специальный компонент , предназначенный для внедрения и связывания объектов из других приложений - OLEContainer.

Основные свойства

Свойство State позволяет определить состояние объекта и его сервера. Его значения:

  • osEmpty –контейнер не содержит объекта;

  • osLoaded – объект в контейнере, сервер не выполняется;

  • osRunning – сервер запущен;

  • osOpen – OLE –объект открыт в отдельном окне сервера;

  • osInPlaceActive – объект активизирован «на месте», но меню еще не изменено. Это промежуточное состояние объекта перед полной загрузкой сервера.

  • osUIActive объект активизирован «на месте», меню изменено.

Следующий код позволяет определить имя объекта, загруженного в контейнер (свойство AnsiString OleClassName), способ работы с объектом (Linked = true – связывание, иначе – внедрение), а также получить имя связанного документа:

if (OleContainer1 -> State != osEmpty)

{

Label2 -> Caption = OleContainer1 -> OleClassName;

// Состояние контейнера – целое число, начиная с 0 (osEmpty)

Label6 -> Caption = OleContainer1 -> State;

if ( OleContainer1 -> Linked)

Label4 -> Caption = OleContainer1 -> SourceDoc;

}

Свойство bool AllowInPlace определяет возможность редактировать внедренный объект «на месте». Если AllowInPlace = true и Iconic = false (свойство Iconic определяет должен ли объект быть представлен в виде пиктограммы), то «InPlace» – редактирование разрешено. При AllowInPlace = false сервер будет открываться в отдельном окне.

Свойство AutoActivate имеет три возможных значения: aaManual, aaGetFocus, aaDoubleClick и определяет способы активизации загруженного в контейнер объекта.

По умолчанию AutoActivate = aaDoubleClick, то есть объект становится активным при двойном щелчке. Значение aaGetFocus определяет активизацию при получении фокуса ввода. При AutoActivate = aaManual за активизацию объекта отвечает программист. В этом случае можно использовать метод компонента-контейнера DoVerb, который отвечает за передачу команд от контейнера серверу. Например, можно воспользоваться следующим оператором:

OleContainer1->DoVerb (ovShow); // Показать объект

Кроме посылки команд серверу, методы контейнера обеспечивают создание, загрузку и разрушение объектов. Перейдем к их рассмотрению.

Создание и сохранение нового объекта (внедрение)

Создание нового объекта можно обеспечить использованием специального диалогового окна Insert Object (вставка объекта) или вызовом метода CreateObject. В первом случае класс объекта выбирает пользователь из системного списка возможных объектов, а во втором программно создается конкретный объект.

Для использования диалогового окна можно воспользоваться следующим кодом, расположенным, например, в команде меню «новый»:

AnsiString File_Name; // переменная объявлена глобально или в классе формы

if (OleContainer1->InsertObjectDialog() )

{ File_Name = "";

OleContainer1->DoVerb(ovShow);

}

В появившемся диалоговом окне необходимо установить значение RadioButton - кнопки «Создать новый», в списке выбрать необходимый тип объекта и щелкнуть «OK».

Программно объект можно создать так (операторы можно вставить, например, в соответствующие пункты меню):

  • таблица Excel

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

  • документ Word

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

Если создать нужно объект, имя типа которого неизвестно, то нужно обратиться либо к соответствующей документации по серверу, либо написать тестовую программу с загрузкой объекта методом OleContainer->InsertObjectDialog() и воспользоваться свойством OleContainer -> OleClassName для определения его имени.

При создании нового объекта используется внедрение (так как для связывания необходим файл). В этом случае за хранение данных объекта отвечает программа - контейнер. Сохранить данные в файле можно с помощью метода SaveToFile (<имя файла>), например, в пункте меню «Файл - Сохранить…» можно использовать следующий код:

void __fastcall TForm1::FSaveClick(TObject *Sender)

{ if (File_Name=="")

if ( SaveDialog1->Execute() )

File_Name = SaveDialog1->FileName;

else return;

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

}

В данном примере расширение файла .ole указывает на то, что объект будет сохранен в специальном формате отличном от формата сервера. Приложение - сервер отдельно от контейнера прочесть эти данные не сможет.

Функция ChangeFileExt была использована в примере для замены расширения файла. При выполнении команд сохранения и извлечения данных из файла могут понадобиться и другие функции обработки имен файлов:

  • ChangeFileExt(const AnsiString FileName, const AnsiString Extension) – принудительно изменяет имя файла FileName, заменяя расширение на Extension;

  • функция AnsiString ExtractFileExt(AnsiString FileName) возвращает расширение файла и, следовательно, позволяет проверить его тип;

  • AnsiString ExtractFileName(AnsiString FileName) возвращает имя файла, извлеченное из строки FileName, т.е. после последнего обратного слэша или двоеточия;

  • AnsiString ExtractFilePath(AnsiString FileName) извлекает путь к файлу, включая последний слэш или двоеточие;

  • AnsiString ExtractFileDrive(AnsiString FileName) извлекает диск файла с двоеточием (например, «D:»).

Метод контейнера LoadFromFile(<имя файла>) позволяет загрузить запомненный объект в контейнер:

void __fastcall TForm1::FOpenClick(TObject *Sender)

{

if ( OpenDialog1->Execute() )

{

if (ExtractFileExt(OpenDialog1->FileName)!= ".ole")

return;

File_Name = OpenDialog1->FileName;

OleContainer1->LoadFromFile(File_Name);

OleContainer1->DoVerb(ovShow);

}

}