Описание функций работы с COM-объектами в HomeLisp

Одним из краеугольных камней операционной системы Windows является компонентная модель объекта (Component Object Model; COM). Эта модель стандартизует правила построения и манипулирования объектами. Подавляющее большинство стандартных элементов оконного интерфейса Windows на самом деле являются COM-объектами (другое название - ActiveX-компонент). Так, командная кнопка, поле ввода, список являются ActiveX-компонентами. Однако понятие COM-объекта существенно шире. COM-объект может не иметь графического визуального интерфейса, а может быть полнофункциональным Windows-приложением. Так большинство офисных продуктов Microsoft (Excel, Word, PowerPoint и др.) могут рассматриваться, как COM-объекты.

COM-объекты "живут" в файлах типа dll, exe или ocx. Чтобы источник COM-объектов мог упешно функционировать, он должен быть зарегистрирован на компьютере. Суть регистрации заключается в том, что информация о COM-объекте заносится в системный реестр. После регистрации источник COM-объектов готов к работе.

С точки зрения HomeLisp-а COM-объект - это атом, у которого установлен определенный список свойств и стандартный индикатор COM. При создании объектов или при возврате объектов из методов и свойств необходимо на месте соответствующих параметров задавать атом без списка своиств и без индикаторов. Будем далее называть такие атомы чистыми.

Все функции манипулирования COM-объектами являются функциями типа SUBR (их аргументы вычисляются).

Имена функций манипулирования COM-объектами в HomeLisp для удобства начинаются префиксом COM. Эти функции доступны во всех режимах работы HomeLisp, кроме WEB-компоненты.

Имя функции К-во аргументов Тип аргументов Выполняемое действие
  COMCREATEOBJECT 2 1-Атом; 2-STRING Создает COM-объект, имя которого представлено значением ВТОРОГО аргумента. Атом-значение первого аргумента становится ссылкой на созданный объект
  COMDESTROYOBJECT 1 Атом Атом-значение аргумента должен иметь стандартный индикатор COM. Функция уничтожает COM-объект, созданный ранее вызовом ComCreateObject
  COMMETHOD 2 и более 1-COM; 2-STRING; 3 и далее FIXED, FLOAT, BITS, STRINGS Вызов метода объекта
  COMMETHODO 2 и более 1-COM; 2-STRING; 3 и далее FIXED, FLOAT, BITS, STRINGS Вызов метода объекта (возвращающего объектную ссылку)
  COMPROPGET 2 и более 1-COM; 2-STRING; 3 и далее FIXED, FLOAT, BITS, STRINGS Вызов PROPERTY GET объекта.
  COMPROPGETO 2 и более 1-COM; 2-STRING; 3 и далее FIXED, FLOAT, BITS, STRINGS Вызов PROPERTY GET объекта (c возвратом объектной ссылки)
  COMPROPLET 2 и более 1-COM; 2-STRING; 3 и далее FIXED, FLOAT, BITS, STRINGS Вызов PROPERTY LET объекта.
COMCREATEOBJECT  

Функция COMCREATEOBJECT служит для создания COM-объекта. Функция принимает два параметра: первым параметром должен быть "чистый" атом (т.е. атом, не содержащий в списке свойств никаких индикаторов). Вторым параметром должна быть строка вида "Имя_Сервера.Имя_Объекта". Если COM-сервер, заданный именем, зарегистрирован на компьютере, будет создан COM-объект, а атом, заданный первым параметром вызова получит в список свойств все необходимые индикаторы. В дальнейшем все действия с COM-объектом выполняются посредством ссылки на этот атом (который далее будем называть идентификатором объекта).

Если COM-объект создан успешно, функция COMCREATEOBJECT возвращает идентификатор объекта.

Вот примеры вызова функции COMCREATEOBJECT:


(comCreateObject 'xlsApp "Excel.Application")

==> xlsApp

(proplist 'xlsApp)

==> (COM Lib "Excel.Application" COMHANDLE 1)

(comPropLet 'xlsApp "Visible" -1)

==> T

(comDestroyObject 'xlsApp)

==> T

(comCreateObject 'o "a.a")

comCreateObject: Ошибка при создании COM-объекта ERRCode=429
==> ERRSTATE

Здесь создается объект-приложение Excel. Запрос списка свойст у идентификатора объекта показыает, что объект создан успешно. Далее, свойству Visible присваивается значение True (-1). После этого на экране возникает главное меню Excel. Далее вызов COMDESTROYOBJECT уничтожает приложение Excel. Последняя команда делает попытку создать незарегистрированный (несуществующий) объект. Возбуждается состояние ошибки с кодом VB, равным 429.

COMDESTROYOBJECT  

Функция COMDESTROYOBJECT уничтожает созданный ранее COM-объект. Единственный аргумент этой функции должен быть идентификатором COM-объекта. При успешном завершении функция возвращает T, COM-объект выгружается из памяти, а идентификатор объекта лишается списка свойств. Если на вход функции COMDESTROYOBJECT подан атом, не имеющий в списке свойств флага COM, то ошибки не возникает, но возвращается Nil.

Все это иллюстрируется следующим примером:


(comCreateObject 'xlsApp "Excel.Application")

==> xlsApp

(proplist 'xlsApp)

==> (COM Lib "Excel.Application" COMHANDLE 1)

(comDestroyObject 'xlsApp)

==> T

(proplist 'xlsApp)

==> NIL

(comDestroyObject 'z)

==> NIL

Видно, что после уничтожения объекта идентификатор объекта лишается всех флагов, специфичных для COM-объекта. Видно, также, что попытка уничтожить несуществующий объект не приводит к ошибке (возвращается Nil).

COMMETHOD  

Функция COMMETHOD принимает два обязательных параметра: идентификатор COM-объекта и имя метода (типа STRING), а также переменное число параметров арифметического или строкового типа. Функция вызывает у объекта заданного идентификатором метод с именем, заданным вторым параметром. При этом методу передается список параметров, составленный из параметров функции COMMETHOD, начиная с третьего.

Функцию COMMETHOD следует вызывать в том случае, когда соответствующий метод не возвращает результата или возвращает результат, не являющийся ссылкой на COM-объект.

Все это иллюстрируется следующим примером:


(comCreateObject 'xlsApp "Excel.Application")

==> xlsApp

(comPropLet 'xlsApp "visible" -1)

==> T

(comMethod 'xlsApp "FindFile")

==> T

(comMethod 'xlsApp "CentimetersToPoints" 5)

==> 141.732283464567

(comMethod 'xlsApp "MethodaNet" 5)

Ошибка COM 438
Object doesn't support this property or method
==> ERRSTATE

(comMethod 'xlsApp "quit")

==> NIL

(comDestroyObject 'xlsApp)

==> T

На врезке видно, как создается приложение Microsoft Excel, делается видимым, и вызывается метод "FindFile" (этот метод не возвращает значения). Возврат T означает, что метод "FindFile" вызван успешно. Далее вызывается метод приложения, который преобразует сантиметры в пойнты. Этот метод возвращает значение. Попытка вызвать заведомо несуществующий метод вызывает ошибку. И, наконец, вызывается метод "quit" - приложение завершается.

COMMETHODO  

Функция COMMETHODO предназначена для вызова метода COM-объекта, возвращающего ссылку на другой COM-объект. Функция COMMETHODO принимает три обязательных параметра: идентификатор исходного COM-объекта, имя метода (типа STRING) и чистый атом, который станет идентификатором объекта, возвращаемого методом. Аргументы метода задаются четвертым и последующими параметрами.

Вот пример вызова функции COMMETHODO:


(comCreateObject 'wdApp "Word.Application")

==> wdApp

(comPropLet 'wdApp "Visible" -1)

==> T

(comPropGetO 'wdApp "Documents" 'docs)

==> docs

(comMethodO 'docs "ADD" 'doc)

==> doc

(proplist 'wdApp)

==> (COM Lib "Word.Application" COMHANDLE 1)

(proplist 'docs)

==> (COM Lib "Word.Application" COMHANDLE 2)

(proplist 'doc)

==> (COM Lib "Word.Application" COMHANDLE 3)

Здесь создается приложение Microsoft Word, делается видимым, а затем создается объект Documents. После чего вызывается метод Add для объекта Documents, а результат (объект Document) присваивается атому doc.

COMPROPGET  

Функция COMPROPGET принимает два параметра: идентификатор COM-объекта и имя свойства (арифметического, логического или строкового типа). При успешном завершении функция возвращает значение свойства. Если запрошенного свойства у объекта нет, то возбужается состояние ошибки.

Все это иллюстрируется следующим примером:


(comCreateObject 'wdApp "Word.Application")

==> wdApp

(comPropGet 'wdApp "Visible")

==> NIL

(comPropLet 'wdApp "Visible" -1)

==> T

(comPropGet 'wdApp "Visible")

==> T

(comPropGet 'wdApp "Name")

==> "Microsoft Word"

Здесь свойство Visible отображается в духе Лиспа: True - T и False - Nil.

COMPROPGETO  

Назначение функции COMPROPGETO заключается в получении объектного свойства какого-либо COM-объекта. Например, у COM-объекта "Word.Application" есть свойство-объект Documents. Функция COMPROPGETO принимает три обязательных параметра: идентификатор COM-объекта, имя свойства и чистый атом, который и станет возвращенным объектом. При успешном завершении функция возвращает значение свойства. Если запрошенного свойства у объекта нет, то возбужается состояние ошибки.

Все это иллюстрируется следующим примером:


(comCreateObject 'wdApp "Word.Application")

==> wdApp

(comPropLet 'wdApp "Visible" -1)

==> T

(comPropGetO 'wdApp "Documents" 'docs)

==> docs

(comPropGet 'docs "count")

==> 0

Атом docs становится идентификатором коллекции документов приложения Word.Application. Для только что созданного приложения коллекция документов пуста (свойство Count у объекта Documents равно нулю).

COMPROPLET  

Функция COMPROPLET обеспечивает присваивание свойству COM-объекта значение (арифметического, логического или строкового типа). Функция COMPROPLET принимает три обязательных параметра: идентификатор COM-объекта, имя свойства и значение, которое будет присвоено свойству, заданному вторым параметром. При успешном завершении функция возвращает T. Если запрошенного свойства у объекта нет, то возбужается состояние ошибки.

Вот пример:


(comCreateObject 'wdApp "Word.Application")

==> wdApp

(comPropLet 'wdApp "Visible" -1)

==> T

Создается приложение Microsoft Word и делается видимым, посредством присваиванию свойству Visible логического значения True (-1).