3. OLE - технология (Разработка многомодульных интегрированных SDI-приложений)
Описание файла
Файл "3. OLE - технология" внутри архива находится в папке "Разработка многомодульных интегрированных SDI-приложений". Документ из архива "Разработка многомодульных интегрированных SDI-приложений", который расположен в категории "". Всё это находится в предмете "проектирование программного обеспечения автоматизированных систем" из 9 семестр (1 семестр магистратуры), которые можно найти в файловом архиве НИУ «МЭИ» . Не смотря на прямую связь этого архива с НИУ «МЭИ» , его также можно найти и в других разделах. Архив можно найти в разделе "остальное", в предмете "проектирование по автоматизированных систем" в общих файлах.
Онлайн просмотр документа "3. OLE - технология"
Текст из документа "3. OLE - технология"
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);
}
}
Создание объекта из файла (внедрение)
Для создания объекта из имеющегося файла можно воспользоваться тем же окном Insert Object, как и в случае создания нового объекта. В случае внедрения пользователь устанавливает значение RadioButton-кнопки «Создать из файла», а для поиска файла щелкает на кнопке «Обзор…».
Программный способ создания объекта из файла обеспечивается методом: OleContainer-> CreateObjectFromFile (AnsiString , bool Iconic).
Параметры методы определяют имя исходного файла и режим отображения объекта (Iconic=true – объект в виде пиктограммы). Вот такой код можно вставить в соответствующий пункт меню:
void __fastcall TForm1::FFileClick(TObject *Sender)
{
if ( OpenDialog1->Execute() )
{
OleContainer1->CreateObjectFromFile(OpenDialog1->FileName,false);
OleContainer1->Repaint();
}
}
Метод OleContainer->Repaint() приводит к перерисовке окна контейнера и, следовательно, появлению данных объекта на экране.
Создание связанного объекта
Так же как и при внедрении создать связанный объект может или пользователь или программист.
Пользователю в окне Insert Object следует выполнить действия по выбору файла, перечисленные выше, и дополнительно установить флажок «Связь».
Программист должен воспользоваться методом: OleContainer->CreateLinkToFile (AnsiString , bool Iconic).
Поскольку при связывании редактировать объект можно только в отдельном окне, то для сохранения объекта пользователь может обратиться к меню сервера.
Работа с сервером
Поскольку работать с данными объекта может только программа создавшая объект (сервер), то контейнеру могут потребоваться знания о возможных действиях над объектом. Метод DoVerb (int Verb) требует выполнения одной из команд, а весь список возможных действий содержит свойство ObjectVerbs компонента контейнера. Получить этот список можно только после загрузки объекта в контейнер, и, естественно, что каждый сервер (а, следовательно, и объект) имеет свой список команд.
Константа ovShow – это пример зарезервированной OLE – команды. Использование метода DoVerb с параметром ovShow, которое было уже рассмотрено в одном из предыдущих разделов, приводит к немедленному открытию сервера.
Следующий код проявляет список возможных команд объекта в компоненте ListBox (команды нумеруются с нуля) и просит выполнить вторую команду в списке:
ListBox1->Items = OleContainer1->ObjectVerbs;
OleContainer1->DoVerb(1);
Кроме этого контейнер может попросить сервер сохранить данные объекта в виде документа в формате сервера. Для этого используется метод SaveAsDocument(). Этот документ в дальнейшем может обрабатываться приложением сервером без участия контейнера. Интересно, что этот метод можно использовать как для связанных так и для внедренных объектов.
При завершении работы с объектом программа может освободить OleContainer, вызвав метод OleContainer->DestroyObject() - разрушить загруженный объект. Этот метод можно вызывать перед загрузкой нового объекта или в команде меню «Файл-Выход».
Задание
1. Создать новое приложение. На главной форме расположены следующие компоненты:
-
OleContainer
-
ListBox
-
Несколько элементов Label
-
MainMenu
И два невизуальных компонента:
-
OpenDialog
-
SaveDialog.
Примерный вид главного окна приложения представлен на рисунке. В OleContainer загружен рисунок (файл с расширением .bmp). Состояние сервера: osRunning.
2. Добавить на форму компонент, в котором будет отображаться информация об объекте: «не загружен» / «внедрение» / «связывание».
3. Меню должно содержать следующие команды:
-
«Файл» (Сохранить объект, Сохранить документ, Загрузить объект, Разорвать связь, Выход)
-
«Объект» (InsertDialog, новый объект Excel, новый объект Paint, внедренный из файла, внедренный из «имя презентации PowerPoint», связанный из файла, связанный из «имя документа Word», Выполнить команду);
-
«Свойства» (Свойства объекта, Команды сервера);
-
«Справка» (О программе).
Предусмотреть, чтобы пункты меню были доступны только в тот момент, когда соответствующие им действия могут быть выполнены. Например, пункт «Объект»| «Выполнить команду» может быть доступен только, если объект загружен в OleContainer, а в список ListBox помещен список доступных команд сервера.
4. Для всех команд меню создать соответствующие обработчики событий.
-
«Файл» | «Сохранить объект» - внедренный объект сохраняется в отдельном файле с расширением .ole;
-
«Файл» | «Сохранить документ» - объект сохраняется в документе сервера;
-
«Файл» | «Загрузить объект» - сохраненный объект загружается из ole – файла.
-
«Файл» | «Разорвать связь» - разрыв связи с объектом;
-
«Файл» | «Выход» - корректный выход из программы ( если была связь с объектом разорвать ее);
-
«Объект» | InsertDialog – объект и его способ загрузки в контейнер выбирается в диалоговом окне пользователем;
-
«Объект» | «Объект Excel» – создается новый объект;
-
«Объект» | «Объект Paint» – создается новый объект;
-
«Объект» | «Внедренный из файла» – имя файла определяется пользователем в диалоговом окне OpenDialog;
-
«Объект» | «Внедренный из «имя презентации PowerPoint» - в контейнер вставляется предварительно созданная презентация слайдов;
-
«Объект» | «Связанный из файла» » – имя файла определяется пользователем в диалоговом окне OpenDialog;
-
«Объект» | «Связанный из «имя документа Word» - в контейнер вставляется предварительно созданный документ;
-
«Объект» | «Выполнить команду» - серверу для выполнения передается команда, выбранная пользователем в списке ListBox$
-
«Свойства» | «Свойства объекта» - контейнер запрашивает у сервера имя объекта, состояние сервера и имя связанного документа, на основании полученной информации делается вывод: «объект – не загружен / внедрен / связан». Полученная информация выводится в компоненты Label главного окна приложения.
-
«Свойства» | «Команды сервера» - список команд сервера выводится в компоненте ListBox;
-
«Справка» | «О программе…» - окно с информацией оприложении и его авторе.
5. Провести полное тестирование приложения на различных объектах и серверах.