|
如何判断是否可以从 arx 应用程序调用 lisp 函数?
从 arx 应用程序调用 lisp 函数的主要记录方法是 acedInvoke 函数。为了使用它,需要以下两个条件之一:
该函数的名称形式为 C:XXX,类似于 AutoLisp 用于定义 AutoCAD 命令的名称。
使用 Lisp 函数注册的函数 (vl-acad-defun 'function_name')
如何判断是否至少满足其中一个条件?下面是详细的记录代码
//////////////////////////////////////////////////////////////////////////
// Функция проверяет можно ли вызвать 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("не "));
} |
|