Интеграция приложений
Цель лекции: приобрести навыки работы с интеграцией приложений.
Создание документа MS Word
Технология COM
Фирма Microsoft разработала модель COM (Component Object Model - модель компонентных объектов). Модель позволяет связывать самые разнородные приложения. Построенный на спецификации этой модели программный комплекс предоставляет описание своих компонентов и средств доступа к ним другим программам. Это дает возможность проектировать такие системы, в которых одни приложения (приложения-клиенты) обращаются к другим приложениям (приложениям-серверам) для выполнения некоторых операций, специфичных для приложений-серверов. При этом приложение-сервер может запускаться в видимом режиме (для него открывается свое окно) или в невидимом режиме (приложение работает в оперативной памяти, не открывая своего окна).
Приложения, поддерживающие технологию COM, при установке заносят в реестр Windows информацию о себе, о своих компонентах и объектах. Так, например, имя приложения (ProgID), под которым оно может быть вызвано как приложение-сервер, заносится в реестр в раздел HKEY_CLASSES_ROOT.
На рис. 10.1 показано окно редактора реестра (Пуск - Выполнить - Regedit). Установленная версия AutoCAD зарегистрирована как AutoCAD.Application.17.1. Под таким именем нужно создавать (загружать в оперативную память) объект приложения AutoCAD 2008, если вы будете обращаться к нему из приложения-клиента.
В реестре также находится информация о том, как можно обратиться к любому зарегистрированному объекту, и какие методы к нему применимы.
Рассмотрим пример использования технологии COM. Создадим прямо из AutoCAD документ Word. Приложение Microsoft Word 2010 в реестре имеет регистрацию как "Word.Application.14". Для работы с этим приложением необходимо иметь в оперативной памяти экземпляр приложения. Если он загружен и уже находится в памяти, то нужно с ним просто соединиться. Иначе требуется создать в памяти новый объект-приложение. При этом необязательно, чтобы он был виден на экране.
Установления связи с Word возможно с помощью одной из трех функций:
- vlax-create-object - создание нового объекта;
- vlax-get-object - соединение с существующим в памяти объектом;
- vlax-get-or-create-object - проверка существования объекта и соединение с существующим, - при его отсутствии создание нового экземпляра приложения.
Объект Application
Создадим VLA-объект приложения Word с помощью следующего выражения:
(setq g_ow (vlax-get-or-create-object "Word.Application"))
Переменную g_ow рекомендуется делать глобальной. По окончании использования нужно освободить занимаемую ею память с помощью функции vlax-release-object. При неправильном освобождении COM-объекты могут оставаться в памяти (причем они могут быть невидимы), что приведет к проблемам. В данной лекции для удобства отслеживания такие переменные будут сопровождаться префиксом g_.
Для вывода свойств и методов объекта Application можно пользоваться функцией (vlax-dump-object g_ow T)
Наличие второго параметра T в этом выражении означает вывод не только свойств, но и методов объекта g_ow. Функция возвратит свойства объекта приложения Word 2003 и его методы. Для извлечения значений свойств объекта следует пользоваться функцией vlax-get-property, например:
(setq vers (vlax-get-property g_ow "Version")) или (setq vers (vlax-get-property g_ow 'Version)).
Для изменения свойств объекта используется LISP-функция:
(vlax-put-property g_ow 'Visible :vlax-true)
Это выражение делает окно приложения (т.е. объект g_ow) видимым. По умолчанию окно приложения невидимо.
При вызове методов с помощью функции vlax-invoke-method должно быть два основных параметра: первым должен быть объект, а вторым - имя метода. Например:
(vlax-invoke-method g_ow 'ListCommands :vlax-true)
Данное выражение формирует новый документ с таблицей, в которой приведены команды Word 2003 (примерно 25 страниц текста).
Семейство Documents
Все открытые документы являются элементами семейства Documents. Доступ к нему можно получить из объекта Application с помощью свойства Documents:
(setq g_docs (vlax-get-property g_ow 'Documents))
Перечислим свойства семейства Documents Word 2003
;Property values (RO=ReadOnly)): ; Application (RO) = #<VLA-OBJECT _Application 09672214> ; Count (RO) = 0 ; Creator (RO) = 1297307460 ; Parent (RO) = VLA-OBJECT _Application 09672214> ; NewEnum (RO) = #<IUnknown 096e150> ;Method supported: ; Add (4) ; CanCheckOut (1) ; CheckOut (1) ; Close (3) ; Item (1) ; Open (16) ; Save (2)
Объект Document
Каждый из открытых текстовых документов является объектом типа Document. Доступ к активному документу получается путем извлечения значения свойства ActiveDocument объекта Application. Для создания нового документа необходимо к семейству Documents применить метод Add:
(setq g_doc (vlax-invoke-method g_docs 'Add))
В этом выражении использован простейший вариант создания нового документа без дополнительных аргументов. Новый документ создается со свойствами по умолчанию и по стандартному шаблону.
Объект Range
Объект Range используется в качестве рабочего диапазона документа Word. Диапазон может иметь любой размер от нуля символов до всего документа. Ноль символов фактически обозначает ту позицию курсора, перед или после которой будет добавляться текст.
Метод Range, с помощью которого можно создать объект Range, присутствует у разных объектов Word. Нас будет интересовать объект Range в текущем документе:
(setq g_r (vlax-invoke-method g_docs 'Range 0 0))
В этом выражении создан диапазон, начинающийся в позиции 0 (вначале документа). Относительно этой позиции далее будут выполнены какие-то операции.
Пример формирования документа
В приведенном ниже листинге приведен пример создания нового документа Word. В этот документ выводятся несколько заголовков, разделенных символами конца абзаца.
(defun writew11_com ( / _re) (vl-load-com) ; Загружаем Word 2003 без открытых документов (setq g_ow (vlax-get-or-create-object "Word.Application.11")) ; Раскомментировать следующую строку, ; если окно Word должно быть видимым ;;;(vlax-put-property g_ow 'Visible :vlax-true) ; Указатель семейства Documents (setq g_docs (vlax-get-property g_ow 'Documents)) ; Создаем новый документ (setq g_doc (vlax-invoke-method g_docs 'Add)) ; Создаем рабочий диапазон, позиция 0 (setq g_r (vlax-invoke-method g_doc 'Range 0 0)) ; Вставляем текст заголовка в начало диапазона (vlax-invoke-method g_r 'InsertBefore "Пояснительная записка") ; Вставляем конец абзаца дважды (vlax-invoke-method g_r 'InsertParagraphAfter) (vlax-invoke-method g_r 'InsertParagraphAfter) ; Параметры шрифта рабочего диапазона (setq g_f (vlax-get-property g_r 'Font)) (vlax-put-property g_f 'Name "Arial") (vlax-put-property g_f 'Size 14.0) (vlax-put-property g_f 'Bold :vlax-true) (vlax-put-property g_f 'Italic :vlax-false) (vlax-put-property g_f 'Underline :vlax-false) ; Создание нового диапазона в конце документа (setq _re (vlax-get-property g_r 'End)) (setq g_r (vlax-invoke-method g_doc 'Range _re _re)) ; Вставляем текст в конец (vlax-invoke-method g_r 'InsertAfter "Строка один") (vlax-invoke-method g_r 'InsertParagraphAfter) (vlax-invoke-method g_r 'InsertAfter "Строка два") (vlax-invoke-method g_r 'InsertParagraphAfter) (vlax-invoke-method g_r 'InsertAfter "Строка три") (vlax-invoke-method g_r 'InsertParagraphAfter) ; Параметры шрифта рабочего диапазона (setq g_f (vlax-get-property g_r 'Font)) (vlax-put-property g_f 'Name "Times New Roman") (vlax-put-property g_f 'Size 10.0) (vlax-put-property g_f 'Bold :vlax-false) (vlax-put-property g_f 'Italic :vlax-false) (vlax-put-property g_f 'Underline :vlax-false) ; Сохранение документа (vlax-invoke-method g_doc 'SaveAs "d:\\Temp\\WordDoc.doc") ; Выход из Word (vlax-invoke-method g_ow "Quit") ; Освобождение объектов и выгрузка Word (if (and g_f (not (vlax-object-released-p g_f))) (vlax-release-object g_f)) (if (and g_r (not (vlax-object-released-p g_r))) (vlax-release-object g_r)) (if (and g_doc (not (vlax-object-released-p g_doc))) (vlax-release-object g_doc)) (if (and g_docs (not (vlax-object-released-p g_docs))) (vlax-release-object g_docs)) (if (and g_ow (not (vlax-object-released-p g_ow))) (vlax-release-object g_ow)) (setq g_f nil g_r nil g_doc nil g_docs nil g_ow nil) (gc) );defunЛистинг 10.1. Функция writew11_com
Создаваемое приложение имеет следующие особенности. Для хранения всех COM-объектов использованы только глобальные переменные. Это должно обеспечить их аккуратное освобождение и тем самым избежать потери памяти.
Функция writewll_com сначала создает объект приложения Word или соединяется с тем объектом, который был загружен заранее. Затем создается новый документ g_doc. В новом пустом документе формируется рабочий диапазон (объект класса Range).
В начало диапазона с помощью метода InsertBefore текст "Пояснительная записка" вставляется тем шрифтом, который действует в шаблоне по умолчанию. Тут же методом InsertParagraphAfter в конец рабочего диапазона добавляются два символа конца абзаца. Затем с помощью свойства Font создается объект Font, который управляет шрифтом выделенного диапазона текста. Для установления требуемого шрифта используется редактирование значений свойств Name, Size, Bold, Italic, Underline.
После формирования заголовка необходимо добавить три абзаца текста с новым шрифтом. Для этого с помощью свойства End вычисляется позиция в конце документа и создается новый рабочий диапазон Range вначале нулевой длины (вырожденный). Затем в его конец добавляются нужные куски текста (три фразы). С помощью объекта Font задаются нужные свойства шрифта.
Документ сохраняется под именем D:\Temp\WordDoc.doc. Приложение Word закрывается. Вообще говоря, необходимо было бы вначале программы создать признак того, что приложение Word было загружено в память функцией writewll_com. Только в случае, если признак имеет значение T, только тогда закрыть Word. В конце программы освобождаются объекты и очищается память. Созданный документ показан на рис. 10.2.
Если Word загружается только рассмотренной программой, то все выполнение по умолчанию идет в скрытом режиме. Окно MS Word не показывается на экране, но файл сохраняется. Если требуется появление окна, то следует раскомментировать строку с изменением свойства Visible. Тогда на экране появится окно MS Word (рис.10.2).
Загрузка приложений
Часто желательно, чтобы приложение автоматически загружалось при старте системы AutoCAD или открытии чертежа. Для этого необходимо добавить строку на языке AutoLISP в файл acad.lsp или acaddoc.lsp:
(load "exc_com2.vlx")
Файл acad.lsp автоматически читается при начальной загрузке AutoCAD. Файл acaddoc.lsp читается при открытии каждого чертежа-документа. Можно заставить систему читать файл acad.lsp также с каждым открытием нового чертежа. Для этого необходимо изменить значение 0 системной переменной ACADLISPASDOC на 1. Путь к файлам должен быть внесен в пути доступа к файлам поддержки.
Иногда требуется не только загрузить файлы-приложения при открытии чертежа, но и начать их выполнение. Для этого в файлы acad.lsp или acaddoc.lsp нужно добавить строку обращения к главной функции нашего приложения: (exc_com2)
Автоматической загрузкой LISP-функций при загрузке меню управляет файл с расширением .mnl, аналогичный файлу acaddoc.lsp.