- •6. Управление внутренними коммуникациями в ос
- •6.1. Общая характеристика коммуникаций
- •6.2. Концепции технологии «Клиент-Сервер»
- •6.3. Внутренние коммуникации между процессами
- •6.3.1. Неименованные каналы
- •6.3.2. Обмен сообщениями
- •6.3.3. Обмен данными через Clipboard
- •1. Подготовка данных для передачи в Clipboard;
- •1. Открытие Clipboard
- •2. Проверка наличия требуемого формата данных в Clipboard
- •3. Чтение данных из Clipboard
- •4. Закрытие Clipboard
- •6.3.4. Обмен данными по технологии dde
- •6.3.5. Обмен данными по технологии ole
- •Insert object
- •Раздел 6
Объект
Собственные данные
Визуальное
представление
Служебная информация
CopyInsert object
Сервер
Объект
Клиент
Объект
Вариант 2. Связывание объекта. В этом случае вторая копия объекта не создается. Документ-клиент содержит только данные для визуального представления и ссылку на документ-сервер, содержащий объект. Ссылка - полный путь к объекту.
Визуальное
представление
(1)
Ссылка на объект
(2)
Сервер
Клиент
(1) (2)
Copy
Paste Link
Объект
Достоинство внедрения состоит в законченности файла составного документа. Все, что нужно, есть в нем самом. Это важно в случае возможного перенесения документа на другую физическую машину.
Недостаток состоит в том, что велик размер файла составного документа. Если есть несколько составных документов с данным объектом, то они скопированы в каждом из составных документов.
Связывание экономит место на диске, особенно, когда один объект является источником для многих клиентов, но при переносе на другую машину документа-клиента необходимо отследить, чтобы все документы-серверы тоже были перенесены.
Первая версия OLE была полностью реализована средствами DDE и обладает следующим неудобством.
При активизации объекта в документе-клиенте, загружается приложение-сервер и ему передается объект для редактирования. Это хорошо, но плохо то, что приложение-сервер загружается в отдельном окне и при редактировании объекта не видно окружения, содержащегося в документе-клиенте.
Недостатки, связанные с этим устранены в последующих версиях OLE.
Характеристика технологии OLE
OLE реализует концепцию визуального редактирования - редактирования на месте
Приложение-сервер запускается при активизации объекта, но оно как бы запускается в окне приложения-клиента. Приложение-клиент как бы превращается в приложение-сервер. Было приложение-клиент, а стало приложение-сервер.
В строку меню приложения-клиента встраиваются позиции меню приложения-сервера, необходимые для редактирования, аналогично согласованно корректируются и панели инструментов.
А поле документа-клиента с визуальным представлением различных объектов не исчезает.
OLE-приложения предоставляют своих функции другим приложениям - OLE-автоматизация
Автоматизация OLE предоставляет возможности по управлению объектами, которые размещаются в других приложениях или в DLL (динамических библиотеках).
Автоматизация включает в себя СЕРВЕРЫ автоматизации и КЛИЕНТОВ автоматизации.
Сервер обеспечивает возможности, а клиент получает к ним доступ.
Написание программ, как серверов, так и клиентов автоматизации, достаточно сложно. Современные средства разработки ПО иногда позволяют упростить этот процесс, хотя и скрывают механизмы реализации.
Достаточно часто требуется построить приложение-клиент автоматизации, использующее возможности уже существующих серверов автоматизации, предоставляемых средствами Microsoft Office.
Например, вам требуется создать неинтерактивное (работающее без участия пользователя) приложение, создающее документ Word и записывающее в него некоторый текст.
Такой пример будет выглядеть следующим образом:
Простой клиент автоматизации OLE
Следующий пример обеспечивает доступ из приложения Delphi к функциям Word.
Var
V : Variant;
Begin
V := CreateOleObject('Word.Basic');
V.FileNew('Normal');
V.Insert('Hello from Delphi!');
V.FileSaveAs('C:\SAMPLE.DOC');
End;
Этот код создает документ Word, вставляет в него строку и сохраняет его. Внешне все очень просто, но за внешней простотой скрыто множество сложнейших действий.
Следует обратить внимание на методы FileNew, Insert, FileSaveAs, которые являются не процедурами Delphi, а методами Word.
Как осуществляется запуск Word. Для этого опять требуется реестр.
По словам 'Word Basic' в реестре находится значение специального идентификатора CLSID. По нему в этом же реестре находится строка примерно следующего вида: С:\WINWORD\WINWORD.EXE /Automation. По ключу /Automation Word возвращает ссылку на объект автоматизации, после чего оказываются доступными его методы.
Создание клиента автоматизации средствами Microsoft
Создание клиента автоматизации с использованием средств Microsoft существенно сложнее, чем с использованием Delphi, однако это позволяет более детально увидеть механизмы работы клиента.
Во-первых, каждое приложение MS Office содержит файл, содержащий библиотеку классов. Например, классы Word, доступные клиенту, содержатся в файле MSWORD.OLB.
Эти классы можно импортировать в собственное приложение.
Например, класс _Application описывает приложение Word. Если вы сделаете объявление вида:
_Application m_app;
то это является основой использования возможностей Word в своем приложении.
Затем надо найти уникальный зарегистрированный в реестре идентификатор приложения Word. Это делается функцией:
CLSIDFromProgID("Word.Application", &clsid);
Т.е. вы по текстовой строке ProgId - "Word.Application" находите число CLSID в реестре.
Затем необходимо проверить, загружено ли приложение сервер. Это делается вызовом:
GetActiveObject(clsid, NULL,&pUnk);
Данный вызов возвращает указатель на переменную типа IUnknown. Этот тип является базовым в СОМ-технологии, на которой основана OLE.
Через этот интерфейс клиент получает доступ к объектам автоматизации, предоставляемым сервером.
Как он это делает? Он это делает путем запроса следующего вида:
pUnk->QueryInterface(IID_Idispatch, (void**)&pDisp);
Этот вызов возвращает указатель на специальный диспетчер, через который будут активизироваться доступные клиенту методы сервера автоматизации.
Если приложение-сервер активно (GetActiveObject вернула TRUE), то диспетчер присоединяется к экземпляру m_app приложения-сервер методом:
m_app.AttachDispatch(pDisp);
Если приложение-сервер загружено не было, то диспетчер создается методом
m_app.CreateDispatch("Word.Application");
в этом методе он же и присоединяется к экземпляру m_app.
После выполнения указанных действий становятся доступными методы приложения-сервер.
Например, создать экземпляр класса документов приложения:
Documents Docs(m_app.GetDocuments());
Класс Documents так же, как и класс _Application, описан в файле MSWORD.OLB.
Далее можно создать экземпляр класса отдельного документа:
_Document adoc(Docs.Open(docfilename);
Класс _Document так же описан в файле MSWORD.OLB.
Теперь с документом можно работать. Например, требуется сохранить его в определенном формате:
adoc.SaveAs(filename, FormatNum);
После завершения работы с документом его надо закрыть:
adoc.Close();
надо отсоединить диспетчер:
m_app.DetachDispatch();
и завершить приложение
m_app.Quit();
Если посмотреть на то, как выглядят методы в файле MSWORD.ODB, то можно увидеть, что все они вызываются через один интерфейс:
InvokeHelper(Id, ...);
которому передается уникальный идентификатор метода.
Например:
GetDocuments() - InvokeHelper(0x6, ...);
Quit() - InvokeHelper(0x451, ...);
SaveAs() - InvokeHelper(0x178, ...)
Подобные средства приходится использовать, если необходимо создать приложение, работающее с документами Word без участия оператора.
Традиционные способы работы с файлами в случае docx-файлов, xlsx-файлов и им подобными, практически невозможны.
В чем причина этого? Дело в том, что подобные файлы представляют собой структурированные хранилища – особый тип файлов.
Ядром OLE стал способ хранения данных в составном документе
Составной документ представляется в виде набора хранилищ, в каждом из которых может содержаться объект, созданный приложением-сервером. Само приложение-клиент не знает способа хранения объекта, созданного другим приложением. Поэтому при сохранении документа клиент как бы «просит» сервер сохранить свои объекты, а сам предоставляет хранилища для этого. При этом общая структура объекта едина для всех приложений, поддерживающих протокол ОLE, и выглядит так, как было показано ранее.
Структурированные хранилища (структурированная память) - это технология записи объектов или данных на диск. Эта техника обеспечивает все услуги, которые существуют в стандартном файловом вводе/выводе. Можно записывать файлы на диск, можно создавать каталоги и подкаталоги.
Отличие структурированной памяти от стандартного файлового ввода/вывода заключается в том, что каждый набор каталогов и файлов структурированной памяти размещается внутри большого единого файла.
Файл структурированной памяти называется составным файлом.
Каталоги внутри этих составных файлов называются потоками.
Например, все DOC-файлы в действительности являются файлами структурированной памяти.
Возможно, структурированная память будет стандартной формой файлового ввода/вывода в будущих ОС.
Элементы работы со структурированной памятью
Составной файл – хранилище - создается вызовом функции StgCreateDocFile(), которая возвращает ссылку на интерфейсный объект IStorage.
Этот вызов как бы создает новый чистый жесткий диск.
Основные методы работы с объектом IStorage:
CreateStream();
OpenStream();
CreateStorage();
OpenStorage().
Для создания потока вызывается метод CreateStream()этого объекта-хранилища, который возвращает ссылку на поток типа IStream. Этот вызов как бы создает новый файл на диске.
В поток можно писать данные методом Write(). Читать данные из потока можно методом Read().
Основные методы работы с объектом IStream:
Read();
Write();
Seek();
В конце работы с потоком и памятью их надо освободить методами Release().
Существует множество режимов работы со структурированной памятью, определяемых константами, передаваемыми в вызовы StgCreateDocFile() и CreateStream(). В частности возможен режим с транзакциями, при котором можно отменить результаты.
Кроме того, возможно создание вложенных хранилищ, т.е. хранилищ внутри других хранилищ. Это напоминает наличие подкаталогов внутри каталогов.
Структурированная память - это очень заманчивая система, когда требуется хранить очень много файлов. Эта система позволяет все их спрятать внутри одного файла.