1.创建ObjectArx应用程序
ObjectARX 应用程序是一个 DLL,它共享 AutoCAD 的地址空间并对 AutoCAD 进行直接函数调用。ObjectARX 应用程序通常实现可从 AutoCAD 内部访问的命令。这些命令通常使用自定义类实现。创建 ObjectARX 应用程序涉及以下常规步骤。
1.1创建对象 ARX 应用程序
- 创建自定义类以实现新命令。
您可以从大多数 ObjectARX 层次结构和符号表类派生自定义类。
- 确定 ObjectARX 应用程序将处理哪些 AutoCAD 消息。
AutoCAD 向 ObjectARX 应用程序发送各种消息,指示 AutoCAD 中发生了特定事件。您可以决定应用程序将响应哪些消息,以及将触发哪些操作。
- 实现 AutoCAD 的入口点。
AutoCAD 通过函数调用 ObjectARX 应用程序,该函数取代了C++程序的功能。您负责在应用程序中实现该函数。该函数调用已与特定 AutoCAD 消息关联的函数。acrxEntryPoint()main()acrxEntryPoint()acrxEntryPoint()
- 实现初始化。
在 ObjectARX 应用程序中,需要初始化已创建的任何自定义类,并重新生成 ObjectARX 运行时类树。此外,如果要添加命令,则必须向 AutoCAD 注册这些命令。
- 准备卸货。
要创建运行良好的 ObjectARX 应用程序,必须在卸载应用程序时删除所有自定义类和命令。
1.2响应 AutoCAD 消息
AutoCAD 向 ObjectARX 应用程序发送的消息有四类:
- 发送到所有应用程序的消息
- 仅当应用程序已向 AutoLISP ® 函数注册时才发送的消息acedDefun()
- 发送到已向 ObjectARX 注册服务的应用程序的消息
- 仅由使用 ActiveX 自动化的应用程序响应的消息(仅限 Windows)
1.2.1ObjectARX 应用程序对 AutoCAD 消息的反应
消息 |
建议的操作 |
---|---|
kInitAppMsg |
注册服务、类、AcEd 命令和反应器以及 AcRxDynamicLinker 反应器。初始化应用程序的系统资源,例如设备和窗口。执行所有一次性早期初始化。AcRx,AcEd和AcGe都是活跃的。如果要解锁和重新锁定应用程序,请存储 pkt 参数的值。 不要期望初始化设备驱动程序、激活任何用户界面资源、按特定顺序加载应用程序、存在 AutoLISP 或打开任何数据库。涉及任何这些假设的调用都将导致错误情况,有时甚至是致命的。AcDb 和 AcGi 文库通常尚未激活,尽管相关的 AcRx 和其他结构已经到位。 |
kUnloadAppMsg |
执行最终的系统资源清理。在 kInitAppMsg 中启动或创建的任何内容现在都应该停止或销毁。 不要指望事情与kInitAppMsg的描述有任何不同。在进行此调用时,AutoCAD 大部分可以拆除,除了在 kInitAppMsg Do 描述中列为活动的库。 |
kOleUnloadAppMsg |
此消息应仅由在 Windows 上使用 ActiveX 自动化的应用程序响应。 如果应用程序可以卸载,请使用 AcRx::kRetOK 进行响应(其他应用程序未引用其任何 ActiveX 对象或接口)。如果无法卸载,请使用 AcRx::kRetError 进行响应。 |
kLoadDwgMsg |
执行与当前图形编辑会话相关的初始化。AcDb、AcGi 和用户界面 API 现在都处于活动状态。未指定是否对图形执行了任何操作。所有 AutoCAD 提供的 API 现在都处于活动状态。此时可以执行 AutoLISP 函数注册,并初始化用户界面。现在要执行的其他操作包括轮询 AutoCAD 驱动程序和查询 AcEditorReactor 事件(如果您希望尽早访问 )。acdbHostApplicationServices()->workingDatabase() 不要对每个图形编辑会话执行不希望发生的任何操作。假设每次程序执行多次发送此消息。 |
kUnloadDwgMsg |
发布或清理为响应 kLoadDwgMsg 代码而启动或注册的所有内容。释放所有AcDb反应器,不包括持久性反应器。 不要释放未绑定到编辑会话的系统资源,也不要清理 AcRx 类、AcEd 反应器或命令;它们在编辑会话中保持有效。 |
kDependencyMsg |
当其他应用程序依赖于应用程序时,请执行应用程序所需的任何操作,例如锁定应用程序,使其无法卸载。 |
kNoDependencyMsg |
当不再有任何其他应用程序依赖于您的应用程序时,请执行应用程序所需的任何操作,例如解锁应用程序,以便用户可以根据需要卸载它。 |
kInvkSubrMsg |
调用在 中注册的函数。通过调用 来确定函数。使用 aceedRetxxx() 返回值。acedDefun()acedGetFuncode() 除了函数调用之外,这里不做太多事情。 |
kPreQuitMsg |
卸载应用程序控制的任何依赖项(应用程序、DLL 等),以确保在应用程序之前卸载这些依赖项。 |
kEndMsg kCfgMsg kQuitMsg kSaveMsg |
请考虑使用 AcEditorReactor 事件回调作为响应这些消息的替代方法。 如果要响应通过 AcEditorReactor 进行的等效事件回调,请不要响应这些消息。 |
1.3ObjectARX 应用程序中的事件序列
在 AutoCAD 和 ObjectARX 应用程序之间传递消息的过程几乎完全是在一个方向上流动的 — 从 AutoCAD 到 ObjectARX 应用程序。下图显示了传递消息的典型顺序。
![](https://help.autodesk.com/cloudhelp/2022/ENU/OARX-DevGuide/images/GUID-E4E7402C-1C5C-4AF1-9487-E56E336F3007.png)
如果在图形已打开时加载应用程序,则会连续发送 和 消息。如果在编辑会话正在进行时卸载 ObjectARX 应用程序,则会连续发送 和 消息。kInitAppMsgkLoadDwgMsgkUnloadDwgkUnloadApp
1.4实现 AutoCAD 的入口点
AutoCAD 通过 调用 ObjectARX 模块,该模块取代了C++程序的功能。您负责实现该函数,如本节所述。acrxEntryPoint()main()acrxEntryPoint()
该函数充当 AutoCAD(或其他主机程序)与 ObjectARX 应用程序通信的入口点。ObjectARX 程序可以通过返回状态代码与 AutoCAD 进行通信。调用 定义 的函数的所有请求都由函数发出。如果使用 ObjectARX 或函数定义新命令,AutoCAD 将立即执行与该命令关联的函数(请参见加载 ObjectARX 应用程序)。acrxEntryPoint()acedDefun()acrxEntryPoint()acedRegFunc()
该函数具有以下签名: acrxEntryPoint()
extern "C"
AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt);
.msg
表示从 ObjectARX 内核发送到应用程序的消息。
PKT
保存数据包数据值。
应用代码
包含返回到 AutoCAD 的状态代码。
在函数的定义中,您可以编写 switch 语句或类似代码来解密来自 AutoCAD 的消息,执行与每条消息相关的相应操作,并返回整数状态值。acrxEntryPoint()
危险:用于函数的最终返回值将导致应用程序被卸载,但消息和 .在这些情况下,如果返回,则不会卸载应用程序。kRetErroracrxEntryPoint()kOleUnloadAppMsgkUnloadAppMsgkRetError
以下代码显示了有效 switch 语句的框架:
extern "C"
AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
switch(msg) {
case AcRx::kInitAppMsg:
break;
case AcRx::kUnloadAppMsg:
break;
...
default:
break;
}
return AcRx::kRetOK;
}
1.5初始化对象ARX 应用程序
必须初始化应用程序定义的任何自定义类和命令。此初始化可以在函数的情况下进行,也可以在从该函数调用的函数中进行。AcRx::kInitAppMsgacrxEntryPoint()
初始化对象ARX 应用程序
- 如果已定义自定义类,请调用其函数。rxInit()
定义自定义类在“派生自定义 ObjectARX 类”中进行了详细讨论。
- 如果已定义自定义类,请调用以重新生成 ObjectARX 运行时类树。acrxBuildClassHierarchy()
为了提高效率,请在为每个自定义类调用函数后调用一次。acrxBuildClassHierarchy()rxinit()
- 执行所需的任何其他初始化。
- 注册服务名称。
如果其他应用程序将依赖于您的应用程序,则建议注册服务名称。注册服务名称允许其他应用程序根据服务进行注册,并允许应用程序在卸载之前检查它是否有任何依赖项。如果要使用 ObjectARX 机制从应用程序导出符号函数,则还需要为应用程序注册服务名称。您可以使用函数 ,也可以使用类。有关注册服务的更多信息,请参阅 ObjectARX 参考中的“AcRxService”。acrxRegisterService()AcRxService
- 使用 AutoCAD 命令机制注册命令。
用于使 AutoCAD 知道应用程序定义的命令。更多信息请参阅“注册新命令”。acedRegCmds->addCommand()
1.6准备卸载
卸载应用程序时,必须清理应用程序创建的任何自定义类或命令。这应该发生在您的函数的情况下,或者在从该情况下调用的函数中发生。AcRx::kUnloadAppMsgacrxEntryPoint()
卸载对象 ARX 应用程序
- 如果已使用宏 或 创建了命令,请将其删除。acedRegCmdsacedDefun()通常,使用 .acedRegCmds->removeGroup()
- 如果已创建自定义类,请将其删除。使用该函数从 AcRx 运行时树中删除自定义类。必须首先从派生类的叶子开始删除类,然后从类树到父类。deleteAcRxClass()
- 删除应用程序添加的任何对象。无法告诉 AutoCAD 忘记当前驻留在数据库中的实例。但是,卸载应用程序时,AutoCAD 会自动将此类对象转换为 或 的实例。AcDbObjectAcDbProxyObjectAcDbProxyEntity
- 移除已连接到任何 、、 或对象的所有反应器。(持久反应器是一个例外;当应用程序卸载时,它们将成为代理对象。AcDbObjectAcDbDatabaseAcRxDynamicLinkerAcEditorAcDbObjects
- 如果已创建服务名称,请将其删除。可以使用该函数删除应用程序已注册的任何服务。请参阅 ObjectARX 参考中的列表。acrxServiceDictionary->remove()acrxServiceDictionary
1.7示例应用程序
下面的示例应用程序实现在加载和卸载应用程序时调用的函数。它的初始化功能向AutoCAD添加了两个新命令:CREATE和ITERATE。
它还初始化新类,并使用函数将其添加到 ObjectARX 层次结构中。
// The initialization function called from the acrxEntryPoint()
// function during the kInitAppMsg case is used to add commands
// to the command stack and to add classes to the ACRX class
// hierarchy.
//
void
initApp()
{
acedRegCmds->addCommand("ASDK_DICTIONARY_COMMANDS",
"ASDK_CREATE", "CREATE", ACRX_CMD_MODAL,
createDictionary);
acedRegCmds->addCommand("ASDK_DICTIONARY_COMMANDS",
"ASDK_ITERATE", "ITERATE", ACRX_CMD_MODAL,
iterateDictionary);
AsdkMyClass::rxInit();
acrxBuildClassHierarchy();
}
// The cleanup function called from the acrxEntryPoint()
// function during the kUnloadAppMsg case removes this application's
// command set from the command stack and removes this application's
// custom classes from the ACRX runtime class hierarchy.
//
void
unloadApp()
{
acedRegCmds->removeGroup("ASDK_DICTIONARY_COMMANDS");
// Remove the AsdkMyClass class from the ACRX runtime
// class hierarchy. If this is done while the database is
// still active, it should cause all objects of class
// AsdkMyClass to be turned into proxies.
//
deleteAcRxClass(AsdkMyClass::desc());
}
2.注册新命令
2.1命令堆栈
AutoCAD 命令存储在命令堆栈中的组中,该命令堆栈由类定义。每个 AutoCAD 会话将创建一个命令堆栈实例。此堆栈由您定义的自定义命令组成。该宏允许您访问命令堆栈。AcEdCommandStackacedRegCmds()
添加命令时,还会为其分配组名。一个好的策略是使用已注册的开发人员前缀作为组名称,以避免与其他命令发生名称冲突。给定组中的命令名称必须是唯一的,并且组名称必须是唯一的。但是,多个应用程序可以添加同名的命令,因为组名使命令明确。
通常使用该函数一次添加一个命令,并按函数组删除命令。您还可以使用该函数一次删除一个命令。作为退出前清理的一部分,应用程序需要删除它注册的任何命令。AcEdCommandStack::addCommand()removeGroup()removeCmd()
函数的签名为addCommand()
Acad::ErrorStatus
addCommand(
const char* cmdGroupName,
const char* cmdGlobalName,
const char* cmdLocalName,
Adesk::Int32 commandFlags,
AcRxFunctionPtr functionAddr,
AcEdUIContext *UIContext = NULL,
int fcode=-1,
HINSTANCE hResourceHandle = NULL,
AcEdCommand** cmdPtrRet = NULL);
- cmd组名称
-
要向其添加命令的组的 ASCII 表示形式。如果该组不存在,则会在添加命令之前创建该组。
- cmd全局名称
-
要添加的命令名称的 ASCII 表示形式。此名称表示全局或未翻译的名称(请参阅“全局与本地命令名称”)。
- cmd本地名称
-
要添加的命令名称的 ASCII 表示形式。此名称表示本地名称或翻译名称。
- 命令标志
-
与命令关联的标志。可能的值包括ACRX_CMD_TRANSPARENT、ACRX_CMD_MODAL、ACRX_CMD_USEPICKSET和ACRX_CMD_REDRAW(请参阅“透明命令与模式命令”)。
- 函数地址
-
AutoCAD 调用此命令时要执行的函数的地址。
- UiContext
-
指向回调类的输入指针。AcEdUIContext
- fcode
-
输入分配给命令的整数代码。
- hResourceHandle
-
执行命令时要设为当前状态的输入资源句柄
- cmdPtrRet
-
输入指针指向要填充的 AcEdCommand 对象的地址的指针,用于添加命令
2.2查找顺序
调用命令时,将按组名称搜索命令堆栈,然后按组中的命令名称搜索。通常,注册的第一个组将是第一个搜索的组,但您无法始终预测此顺序。使用该函数指定应首先搜索特定组。在用户级别,ARX 命令的“组”选项允许用户指定首先搜索哪个组。AcEdCommandStack::popGroupToTop()
2.3全局命令名称与本地命令名称
将命令添加到 AutoCAD 时,需要指定可用于任何语言的全局名称,以及本地化名称(即要在外语版本的 AutoCAD 中使用的命令名称的翻译版本)。如果不需要将命令名称转换为本地语言,则可以对全局名称和本地名称使用相同的名称。
2.4透明命令与模式命令
命令可以是透明的,也可以是模式的。当提示用户输入时,可以调用透明命令。仅当 AutoCAD 正在发布命令提示符且当前没有其他命令或程序处于活动状态时,才能调用模式命令。函数的参数指定新命令是模式 (ACRX_CMD_MODAL) 还是透明 (ACRX_CMD_TRANSPARENT)。该参数还指定命令的其他选项。请参阅对象ARX参考。透明命令只能嵌套一个级别(即调用主命令,主命令调用一个透明命令)。commandFlagsAcEdCommandStack::addCommand()commandFlagsAcEdCommandStack
如果创建多个对一组通用全局对象进行操作的命令,请考虑是否应使它们成为模式,以便它们不会相互干扰。如果此类冲突不是问题,则使新命令透明化会导致更大的使用灵活性。
3加载ObjectArx应用程序
您可以使用以下任一方法加载 ObjectARX 应用程序:
- 为应用程序提供允许其由 AutoCAD 按需加载的功能。这些功能包括 Windows 系统注册表中特定于应用程序的条目。请参阅需求加载。
- 在初始模块文件 acad.rx 中指定应用程序。此文件包含 ASCII 文本,其中包含 AutoCAD 在启动时应加载的所有程序的名称。文件中的每一行都包含一个程序名称(如果文件不在 AutoCAD 库搜索路径的目录中,则包含路径)。acad.rx 文件还必须位于 AutoCAD 搜索路径上的目录中。
- 使用 从另一个 ObjectARX 应用程序发出应用程序加载请求。AcRxDynamicLinker::loadModule()
- 使用 APPLOAD 命令。
- 创建一个捆绑包并将其部署到应用程序插件文件夹。请参阅应用程序自动加载。
- 使用 AutoLISP 中的函数。arxload()
- 使用 ObjectARX 中的函数。acedArxLoad()
- 在 AutoCAD 命令行上输入 ARX 命令,然后使用“加载”选项。
- 从 DOS 命令行启动 AutoCAD,使用 或 开关,后跟 ObjectARX 应用程序或对象启用程序的路径和文件名。例如:/ld-ld
4卸载ObjectArx应用程序
您可以使用以下任一方法卸载 ObjectARX 应用程序(如果它已解锁):
- 使用 从另一个 ObjectARX 应用程序发出应用程序卸载请求。AcRxDynamicLinker::unloadModule()
- 使用 APPLOAD 命令。这将打开一个对话框,允许您加载和卸载应用程序。
- 从应用程序插件文件夹中删除捆绑包。请参阅应用程序自动加载。
- 使用 AutoLISP 中的函数。arxunload
- 使用 ObjectARX 中的函数。acedArxUnload()
- 在 AutoCAD 命令行上输入 ARX 命令,然后使用“卸载”选项。
4.1解锁应用程序
默认情况下,应用程序处于锁定状态,无法卸载。要归类为“不可加载”应用程序,应用程序必须确保 AutoCAD 和其他应用程序不再引用应用程序已定义的任何对象或结构。在使应用程序不可加载之前,请非常小心,不要让客户端应用程序包含指向地址空间中任何对象的活动指针。有关应用程序必须执行才能卸载的清理操作的列表,请参阅准备卸载。
如果要使应用程序不可加载,则需要存储与 .该参数将由函数使用。默认情况下,应用程序处于锁定状态。如果解锁应用程序,则可以将其卸载。pktAcRx::kInitAppMsgpktunlockApplication()
使用以下两个函数锁定和解锁应用程序:
virtual bool
AcRxDynamicLinker::lockApplication(void* pkt) const = 0;
virtual bool
AcRxDynamicLinker::unlockApplication(void* pkt) const = 0;
以下函数检查应用程序是否已锁定:
virtual bool
AcRxDynamicLinker::isApplicationLocked(const char* name) const = 0;
还提供了类似的全局函数:
bool
acrxLockApplication(void* pkt);
bool
acrxUnlockApplication(void* pkt);
bool
acrxApplicationIsLocked(const char* modulename);
5.应用程序自动加载
ObjectARX 应用程序可以使用包格式作为插件的一部分加载,包格式是扩展名为 .bundle 的常见文件夹结构。每个包都可以包含部署应用程序和注册应用程序中包含的命令所需的文件。通过将包放置在本地驱动器上的某个应用程序插件文件夹中,将包加载到 AutoCAD 中。
APPAUTOLOAD 系统变量控制 AutoCAD 何时从“应用程序插件”文件夹中查找和加载插件。如果 APPAUTOLOAD 设置为 0,则可以使用 APPAUTOLOADER 命令加载插件。
有关使用软件包格式部署应用程序的信息,请参阅《定制指南》中的“安装和卸载插件应用程序”。
6.按需加载
按需加载是 AutoCAD 的一项功能,它会自动尝试加载不驻留在 AutoCAD 中的 ObjectARX 应用程序。可以将 ObjectARX 应用程序设计为在以下一种或多种情况下由 AutoCAD 加载:
- 读取包含由不存在的应用程序创建的自定义对象的图形文件时
- 当用户或其他应用程序发出缺少的应用程序的命令之一时
- 启动AutoCAD时
注意:在 AutoCAD 启动时实现需求加载的应用程序将在 acad.rx 中列出的应用程序之前加载。
Autodesk 建议开发利用 AutoCAD 按需加载功能的 ObjectARX 应用程序,因为需求加载具有以下优点:
- 限制代理对象的创建(请参阅代理对象)
- 为加载 ObjectARX 应用程序提供了更大的灵活性
- 通过仅在需要应用程序功能时才加载应用程序来节省内存
要使应用程序可供按需加载访问,Windows 系统注册表中必须存在特定于应用程序的信息。此外,具有多个 DLL 的 ObjectARX 应用程序可能需要一个“控制器”模块,该模块负责加载应用程序的所有其他组件。最后,必须将 DEMANDLOAD 系统变量设置为需求加载的适当值。
注意:可以从本地计算机上的路径或使用因特网地址按需加载 ObjectARX 应用程序。
6.1AutoCAD、Windows System Registry 和 ObjectARX 应用程序
AutoCAD 使用 Windows 系统注册表来维护各种应用程序信息,包括唯一标识可能安装在任何给定计算机上的不同 AutoCAD 版本、语言版本和产品(如 AutoCAD 地图)的信息。标识不同版本的 AutoCAD 的注册表信息对于 ObjectARX 开发人员具有特别重要的意义。ObjectARX 应用程序的安装程序必须将有关该应用程序的信息与有关应运行该应用程序的 AutoCAD 版本的信息相关联。
AutoCAD 安装程序在系统注册表中创建一个唯一的时间戳键,紧靠版本号键的下方(以及将相同的安装 ID 添加到可执行文件本身)。此项可确保同一版本中不同版本的 AutoCAD 能够填充其自己的系统注册表部分。在此键中,存储属性的值,例如 AutoCAD 文件的位置和语言版本,如以下示例所示:
\\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R24.1\
ACAD-5101:409\
...
Language:REG_SZ:English
Location:REG_SZ:C:\Program Files\Autodesk\AutoCAD <release_name>
...
ObjectARX 应用程序的安装程序必须能够找到相应的 AutoCAD 版本密钥,以及相应的语言和产品值。
时间戳键还用于标识当前加载的 AutoCAD 版本(或最近加载的版本)。此标识是必需的,因为 AutoCAD 的“当前”版本会在加载注册表时重置注册表全局部分中的信息以供自己使用。HKEY_CLASSES_ROOT
注册表的发布密钥部分中的值用于标识当前版本,例如:CurVer
\\HKEY_CURRENT_USER\Software\Autodesk\AutoCAD\R24.1\
CurVer:REG_SZ:ACAD-5101:409
6.2在安装 ObjectARX 应用程序时修改注册表
AutoCAD 使用 Windows 系统注册表来查找 ObjectARX 应用程序以进行按需加载。注册表的 AutoCAD 部分的一部分用于提供有关 ObjectARX 应用程序的注册表信息位置的信息。
ObjectARX 应用程序的安装程序必须在系统注册表中创建需求加载所需的特定键和值。某些必需的项和值必须在注册表的 AutoCAD 部分中创建,而其他项和值必须在注册表的 ObjectARX 应用程序的部分中创建。
如果 ObjectARX 应用程序设计为与多个版本的 AutoCAD(即不同的语言版本或相关产品,如 AutoCAD 地图)一起运行,则安装程序必须将相应的信息添加到每个版本的 AutoCAD 的注册表部分。
因此,ObjectARX 应用程序的安装过程必须包括:
- 验证相应版本的 AutoCAD 的系统注册表部分是否存在。(如果注册表的 AutoCAD 部分不存在,则应警告用户尚未安装兼容版本的 AutoCAD,并且应中止安装。
- 在相应版本的 AutoCAD 的系统注册表部分中为应用程序创建一组特定的键和值。
- 为应用程序本身创建一个主键,并使用另一组特定键和值填充该键。
请参阅 ObjectARX SDK 的 samples\entity\polysamp\demandload 目录,了解有关如何修改系统注册表以按需加载示例程序 polysamp 的信息。
6.2.1适应 Windows 权限级别
如果当前 Windows 用户不是高级用户,则 AutoCAD 及其下运行的应用程序都无法写入注册表区域。为了处理这种情况,AutoCAD 支持在“和”注册表“部分中输入需求荷载条目。HKEY_LOCAL_MACHINEHKEY_LOCAL_MACHINEHKEY_CURRENT_USER
对于需求加载,AutoCAD 首先在 下查找条目。如果在那里找到必要的条目,则使用它们。如果在 下找不到这些条目,AutoCAD 将在 下查找。HKEY_CURRENT_USERHKEY_CURRENT_USERHKEY_LOCAL_MACHINE
ObjectDBX 还遵循本节中介绍的 AutoCAD 注册表搜索规则。
ObjectARX 提供的 API 可简化写入注册表正确区域的过程。有关这些 API 的更多信息,请参阅使用 ObjectARX API 简化注册表设置。
6.2.2创建 AutoCAD 子项和值
创建 AutoCAD 子项和值
必须将 ObjectARX 应用程序的安装程序设计为在要运行该应用程序的每个版本的 AutoCAD 的系统注册表部分中管理该应用程序的一组键和值。注册表的此部分必须包括标识应用程序主模块和应用程序的命令集的键和值。
下面的示例演示必须为应用程序创建和维护的注册表部分中的项和值的布局:
\\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\releaseNum\
ACAD-ProductID:LocaleID\
Applications\
ApplicationName\
DESCRIPTION:REG_SZ:User Friendly App Name
LOADCTRLS:REG_DWORD:acrxAppLoadReason
LOADER:REG_SZ:DirPathFileName
Commands\
GlobalCommandName1:REG_SZ:LocalCommandName1
GlobalCommandName2:REG_SZ:LocalCommandName2
GlobalCommandName3:REG_SZ:LocalCommandName3
GlobalCommandName4:REG_SZ:LocalCommandName4
GlobalCommandName5:REG_SZ:LocalCommandName5
Groups\
GroupName:REG_SZ:GroupName
...
和 键由 AutoCAD 安装程序创建。releaseNumACAD-ProductID:LocaleID
密钥必须是应用程序的逻辑名称,AutoCAD 在内部使用该名称来标识程序。ApplicationName
键中的值必须包括 AutoCAD 应首先加载的模块的完整路径和文件名。加载程序模块随后负责加载组成应用程序的任何其他模块。LOADER
该值使用下列十六进制值的一个或多个逻辑 OR 及其关联含义来定义加载应用程序的条件:acrxAppLoadReason
- 0x01
-
检测到代理对象时加载应用程序。
- 0x02
-
在 AutoCAD 启动时加载应用程序。
- 0x04
-
在调用命令时加载应用程序。
- 0x08
-
根据用户或其他应用程序的请求加载应用程序。
- 0x10
-
不要加载应用程序。
- 0x20
-
透明地加载应用程序。
键中的值可用于唯一标识 ObjectARX 应用程序的命令组,从而也用于标识命令。Groups
全局函数可以在 ObjectARX 应用程序中用于将有关应用程序的信息输入到系统注册表的 AutoCAD 部分中。通常, 会在首次加载应用程序时输入此信息,并在后续加载中确认该信息是否存在。acrxRegisterApp()acrxRegisterApp()
7.需求负载系统变量
AutoCAD DEMANDLOAD 系统变量控制 ObjectARX 应用程序的需求加载选项。
默认情况下,设置 DEMANDLOAD 系统变量(安装 AutoCAD 时)以在命令调用或代理检测时启用应用程序的需求加载,前提是在应用程序的系统注册表项中指定了任一选项。当系统注册表中指定了这些选项中的任何一个时,DEMANDLOAD 的设置不会影响 AutoCAD 启动时的需求加载,也不会影响用户或应用程序的请求。(请参见创建 AutoCAD 子项和值)。
系统变量的合法值可以组合使用。它们定义如下:
- 0
-
禁用所有 ObjectARX 应用程序的需求加载。
- 1
-
允许在检测到代理对象时按需加载 ObjectARX 应用程序。
- 2
-
允许在命令调用时按需加载 ObjectARX 应用程序。
- 3
-
为代理对象和命令调用启用需求加载(默认值)。
DEMANDLOAD 系统变量允许用户禁用所有 ObjectARX 应用程序的需求加载,这些应用程序具有指定命令调用和代理检测时需求加载的系统注册表设置。如果相应的系统注册表设置不存在,则它不会导致应用程序被需求加载。
8.检测自定义对象时的需求加载
加载包含自定义对象的 DWG 或 DXF 文件时,AutoCAD 将确定是否加载关联的应用程序。如果未加载应用程序,并且设置了系统变量 DEMANDLOAD 的第一个位,AutoCAD 将在 Windows 系统注册表中搜索有关应用程序及其加载程序模块的信息。如果 AutoCAD 在系统注册表中找到相应的信息,则会加载应用程序。
注意:检测自定义类时的需求加载仅适用于直接或间接派生自 的类。AcDbObject作为一个假设的例子,假设AutoCAD读取由ObjectARX应用程序polysamp(PolySamp Inc.的产品)创建的文件。
- 读取图形文件时,AutoCAD 会遇到使用应用程序多边形创建的自定义对象,并确定应用程序未加载。
- AutoCAD 发现 DEMANDLOAD 系统变量设置为在代理检测时启用应用程序的需求加载,因此它会在系统注册表的“AutoCAD 应用程序”部分中搜索密钥。在此键中,它查找值,该值定义应加载应用程序的条件。注册表的此部分如下所示:polysampLOADCTRLS
\\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\ObjectDBX\<VERSION>\Applications\<Application>
DESCRIPTION:REG_SZ:PolyCad
LOADCTRLS:REG_DWORD:0xd
LOADER:REG_SZ:C:\Program Files\polysampinc\polyui.dbx
AutoCAD reads the polysamp\LOADER key to determine the directory, path, and file name of the module to be loaded.
然后,AutoCAD 尝试加载 ObjectARX 模块。如果模块成功加载,AutoCAD 会将应用程序的句柄添加到要发送 kLoadDwgMsg 消息的应用程序句柄列表中。然后,AutoCAD 验证应用程序是否已正确加载,并验证自定义类是否已注册。如果应用程序已成功加载,AutoCAD 将继续加载图形文件。如果无法加载 ObjectARX 模块,或者仍然没有可用的类实现,则自定义对象将被视为代理并继续加载。
9.根据命令按需加载
如果用户调用的命令未注册到 AutoCAD,AutoCAD 将尝试加载相应的 ObjectARX 应用程序。
为了支持命令调用时的需求加载,ObjectARX 应用程序的安装程序必须在系统注册表中为应用程序的命令创建适当的键和值。系统注册表的应用程序部分应包含如下命令信息:Commands
\\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R24.1\
ACAD-5101:409\
Applications\polysamp\
DESCRIPTION:REG_SZ:PolyCad
LOADCTRLS:REG_DWORD:0xd
LOADER:REG_SZ:C:\Program Files\polysampinc\polyui.arx
Commands\
ASDKPOLY:REG_SZ:ASDKPOLY
ASDKDRAGPOLY:REG_SZ:ASDKDRAGPOLY
ASDKPOLYEDIT:REG_SZ:ASDKPOLYEDIT
Groups\
ASDK:REG_SZ:ASDK
...
注意:使用组前缀调用命令也会消除命令的歧义。换句话说,GROUP_NAME。COMMAND_NAME将要求加载与指定命令组关联的命令。
ObjectARX 应用程序还必须包括对宏的相应调用,以便命令时按需加载才能正常工作。acedRegCmds
10.AutoCAD 启动时的需求加载
可以通过对系统注册表中的值使用(也可以使用另一个合法值执行 OR)来指定 AutoCAD 启动时 ObjectARX 应用程序的需求加载,如下所示。0x020x02LOADCTRLS
\\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R24.1\
ACAD-5101:409\
Applications\PolyCAD\
LOADCTRLS:REG_DWORD:0x02
11.上下文菜单调用时的需求加载
如果应用程序定义了自定义对象上下文菜单,则可以提供注册表设置,以确保在用户右键单击其中一个对象时加载所需的模块。为此,请向注册表部分添加一个项。在高级用户的计算机上,配置单元显示在以下注册表位置:ContextHandlersContextHandlers
\\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R24.1\
ACAD-5101:409\
ContextHandlers
键的名称应为自定义对象类名。键的值应该是需要加载的应用程序的逻辑名称的逗号分隔列表。这些逻辑名称必须与注册表配置单元中存在的项匹配,如创建 AutoCAD 子项和值中所述。ApplicationNameApplications
以下示例说明了对象的键:ContextHandlerAcDbTable
\\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R24.1\
ACAD-5101:409\
ContextHandlers\
AcDbTable:REG_SZ:AcadTable,AcSmSheetList
当用户右键单击对象时,此键可保证与逻辑名称关联的模块被加载。AcDbTableAcadTableAcSmSheetList
12.使用 ObjectARX API 简化注册表设置
ObjectARX 提供的 API 简化了将需求加载条目写入注册表的任务。尽管安装时更适合编写初始注册表项,但如果您需要在运行时更改需求负载信息,这些 API 可能很有用。例如,应用程序可以在安装时写入默认设置,然后使用这些 API 在运行时将用户特定的值写入。HKEY_LOCAL_MACHINEHKEY_CURRENT_USER
类函数和全局函数将注册表项写入当前用户权限指示的位置。如果用户具有高级用户权限,则条目将写入 下。否则,它们将写在 下。AcadAppInfoacrxRegisterApp()HKEY_LOCAL_MACHINEHKEY_CURRENT_USER
该函数写入需求加载所需的所有注册表项。它提供了一个参数,该参数强制将条目写入配置单元,即使用户在 中具有写入权限也是如此。有关详细信息,请参阅对象ARX参考。AcadAppInfo::writeToRegistry()HKEY_CURRENT_USERHKEY_LOCAL_MACHINEwriteToRegistry
以下方法提供了将组和命令需求负载信息写入注册表的功能:
- writeGroupNameToRegistry
- writeCommandNameToRegistry
全局函数是执行部分注册表设置的单调用包装器。您可以将此函数与您自己的对象结合使用。有关详细文档和重要注意事项,请参阅对象ARX 参考。acrxRegisterApp()AcadAppInfoAcadAppInfoacrxRegisterApp
12.1删除系统注册表信息
如果升级或删除了应用程序,则从系统注册表中删除 ObjectARX 应用程序信息可能会很有用。ObjectARX API 包含函数,它是 的对应函数。它会从系统注册表的“AutoCAD”部分中删除有关应用程序的信息。acrxUnregisterApp()acrxRegisterApp()
13.代码示例:编写需求加载键
以下示例(来自 ObjectARX SDK polysamp 示例程序)说明了如何为注册组和命令的 ObjectARX 应用程序编写需求加载键:
void updateRegistry()
{
// Fill the AppInfo structure with our demand loading details.
AcadAppInfo appInfo;
appInfo.setAppName("AsdkPolyCAD"); // Application name
appInfo.setModuleName(acedGetAppName());// Module path
appInfo.setAppDesc("AsdkPolyCAD"); // Description
appInfo.setLoadReason(// Specify when we want these to load
AcadApp::LoadReasons(
AcadApp::kOnCommandInvocation |
AcadApp::kOnLoadRequest));
// Write the appInfo to the registry.
appInfo.writeToRegistry();
// Write the group name.
appInfo.writeGroupNameToRegistry("ASDK_POLYGON");
// Write out all our commands (Global,Local).
appInfo.writeCommandNameToRegistry("ASDK_POLY","POLY");
appInfo.writeCommandNameToRegistry("ASDK_DRAGPOLY","DRAGPOLY");
appInfo.writeCommandNameToRegistry("ASDK_POLYEDIT","POLYEDIT");
appInfo.writeCommandNameToRegistry("ASDK_TRANSACT","TRANSACT");
appInfo.writeCommandNameToRegistry("ASDK_HILITPOLY","HILITPOLY");
appInfo.writeCommandNameToRegistry("ASDK_HILITSOLID","HILITSOLID");
appInfo.writeCommandNameToRegistry("ASDK_CREATEINSERT","CREATEINSERT");
appInfo.writeCommandNameToRegistry("ASDK_HILITINSERT","HILITINSERT");
}
注意:对象启用程序使用 ObjectARX 注册表格式的缩写版本。有关更多详细信息,请参阅“对象启用程序”中的“为需求加载注册对象启用程序”部分。
14.使用系统注册表管理应用程序
为需求加载创建了系统注册表信息后,一组 ObjectARX 函数可以使用相同的信息来加载、卸载和监视独立于按需加载功能的 ObjectARX 应用程序是否存在。其中前两个函数使用的参数是逻辑应用程序名称。AppName
以下 ObjectARX 函数可用于已注册的应用程序名称:
bool acrxLoadApp ("AppName")
此函数采用单个参数,该参数表示要加载的应用程序的不区分大小写的逻辑名称。如果加载失败,该函数返回 0,如果加载成功,则返回 1。
bool acrxUnloadApp ("AppName")
此函数采用单个参数,该参数表示以前加载的应用程序的不区分大小写的逻辑名称。如果卸载失败,该函数返回 0,如果卸载成功,则返回 1。
void *acrxLoadedApps ()
此函数以 的形式返回一个字符串数组,其中包含当前加载的每个应用程序的逻辑应用程序名称。如果未加载任何应用程序,则该函数返回 NULL。调用方负责释放为返回的字符串分配的空间。void *
标签:命令,AutoCAD,ObjectArx,应用程序,基础知识,ObjectARX,注册表,加载 From: https://www.cnblogs.com/HRDK-CADeveloper/p/16851042.html