12/11/2018
Как определить, что lisp-функцию можно вызвать из arx-приложения?
Основное документированное средство для вызова lisp-функций из arx-приложения – это функция acedInvoke. Для того, чтобы ею воспользоваться необходимо одно из двух условий:
- Функция имеет имя вида C:XXX, т.е. имя аналогичное тому, как используется в AutoLisp для определения команды AutoCAD.
- Функция зарегистрирована при помощи lisp-функции (vl-acad-defun ‘имя_функции)
Как можно определить, что хотя бы одно из этих условий выполняется? Ниже приведён подробно документированный код:
Код - C++: [Выделить]
- //////////////////////////////////////////////////////////////////////////
- // Функция проверяет можно ли вызвать lisp-функцию с заданным именем при
- // помощи acedInvoke. Такая функция должна или иметь имя в виде C:XXX,
- // или быть зарегистрированной при помощи (vl-acad-defun 'имя_функции)
- //////////////////////////////////////////////////////////////////////////
- static bool IsLispFuncRegisteredInDocument
- (
- AcString funcName, // Имя проверяемой функции
- AcApDocument *ap = curDoc() // Документ, в котором эта
- // функция должна использоваться (по умолчанию текущий документ)
- )
- {
- bool findFunc = false;
- __int64 ptrCurDoc = __int64(ap);
- AcEdCommandIterator* pCmdItr = NULL;
- AcString cmdName, grpName;
- if (NULL != (pCmdItr = acedRegCmds->iterator()))
- {
- for (;!pCmdItr->done() && !findFunc; pCmdItr->next())
- {
- grpName = pCmdItr->commandGroup();
- cmdName = pCmdItr->command()->localName();
- //////////////////////////////////////////////////////////////////////////
- // Если имя группы имеет формат "*DOC(0xNNNNNNNNNNNNNNN)", то эта группа
- // относится к документу. Чтобы определить к какому именно документу она
- // относится достаточно вычленить шестнадцатеричную строку, преобразовать
- // её в длинное целое и сравнить с адресом документа AcApDocument.
- // В случае совпадения все команды и функции работают
- // в пространстве именно этого документа.
- //////////////////////////////////////////////////////////////////////////
- if (grpName.left(7) == ACRX_T("*DOC(0x"))
- {
- __int64 ptrCmdDoc;
- ACHAR *docStart = const_cast<ACHAR *>(grpName.kACharPtr() + 8), *docEnd = NULL;
- // Преобразуем имя группы в длинное целое
- ptrCmdDoc = _wcstoi64(docStart, &docEnd, 16);
- // Сравниваем адрес переданного документа и адрес документа из имени группы
- if (ptrCmdDoc == ptrCurDoc)
- {
- // Если это lisp-функция, то у неё флаг ACRX_CMD_DEFUN
- Adesk::Int32 flag = pCmdItr->command()->commandFlags();
- if ((flag & ACRX_CMD_DEFUN) && !funcName.compareNoCase(cmdName))
- {
- findFunc = true;
- break;
- }
- }
- }
- }
- delete pCmdItr;
- }
- return findFunc;
- }
- // Для проверки функции IsLispFuncRegisteredInDocument
- static void RivilisCheckRegLispFunc()
- {
- AcString sName;
- if (acedGetString(FALSE, ACRX_T("\nУкажите имя функции для проверки: "), sName) != RTNORM)
- return;
- if (sName.isEmpty())
- return;
- acutPrintf(ACRX_T("\n%s %sзарегистрирована для acedInvoke"),
- sName.kACharPtr(), IsLispFuncRegisteredInDocument(sName, curDoc()) ? ACRX_T("") : ACRX_T("не "));
- }
Автор: Александр Ривилис
Отредактировано 12.11.2018 в 02:26:35
Обсуждение: http://adn-cis.org/forum/index.php?topic=
Опубликовано 12.11.2018Отредактировано 12.11.2018 в 02:26:35