多文档命令
多文档命令允许用户在选定的用户提示符下切换文档,同时该命令仍处于控制状态。让单个命令在文档中保持活动状态的能力非常复杂。在执行点,当用户选择要切换到的另一个文档时,所有文档都会轮询输入。因此,它们可能建立了复杂的命令处理器状态,包括可能的嵌套命令、AutoLISP 表达式、活动脚本,以及所有以任意嵌套顺序排列的脚本。 如果不付出很大的努力,人们就无法轻易地定义,更不用说将一个国家的相关元素嫁接到另一个国家了。相反,最佳策略是让应用程序在用户指定的文档开关之间保留控制权,即使应用程序必须在不同的窗口中作为不同的命令实现。然后,应用程序所需要的只是一个机制来链接在不同文档中运行的单独命令,并控制在更改文档时启动哪个命令。 要同步多个命令的操作,请实现覆盖以下反应器函数的响应器:AcApDocManager virtual void documentActivated( AcApDocument* pActivatedDoc); virtual void documentToBeDeactivated( AcApDocument* pDeActivatedDoc); 也可以使用反应器功能,但它发生在文档被激活之前。在这种情况下,尚未设置文档上下文。documentToBeActivated() 每当用户单击其他文档以激活该文档时,都会调用这些回调。只有在提示用户输入之前,在初始命令中,在支持文档切换时,才应使用反应器。当完成或取消任何或所有此类提示时,应移除反应器。在回调中,调用:AcApDocManager virtual Acad::ErrorStatus sendStringToExecute( AcApDocument* pAcTargetDocument, const char * pszExecute, bool bActivate = true, bool bWrapUpInactiveDoc = false, bool bEchoString = true) = 0; 此函数将字符串排成一列,以便在下次激活指定文档时进行解释。字符串通常应是命令调用(我们将其称为辅助命令),但也可以是 AutoLISP 表达式、命令片段或菜单标记。字符串限制为 296 字节,因此较长的序列应实现为运行临时脚本的 SCRIPT 命令,或作为 AutoLISP 表达式来加载和执行 AutoLISP 程序。新文档将根据注册期间指定的新命令的锁定级别进行锁定。 如果初始命令中的输入提示符看起来与辅助命令中的第一个提示符相同,则用户无需知道正在发生两个单独的命令。 注意:由于此技术涉及从方法调用,因此应传入参数以避免错误或无限循环。documentActivated()kFalsebActivate
此外,为了管理跨文档的控制流,此回调应保持应用程序所需的任何转换状态。例如,非重入变体可以记住原始文档,并为每个文档设置一个标志,以指示它是否已经处于活动状态,因此不必调用 。sendStringToExecute() 当多文档命令完成时,控制应用程序应确保该命令在以前的文档中没有留下挂起的命令状态。应用程序可以通过使用 bWrapUpInactiveDoc 参数向它遍历的文档发送 ESC 或 ENTER 来执行此操作。如果不这样做,文档可能会处于非静止状态。sendStringToExecute() 初始命令和辅助命令(以及可能的多个调用)之间的协调必须通过静态变量或堆驻留变量进行管理。 初始命令和辅助命令都应通过 或 注册。初始命令应编码为自行成功完成,以防用户决定在不切换文档的情况下执行整个命令。第二个命令不需要是完整的命令,只需调用命令的一部分,即可从不同的打开文档中积累信息(植根于静态结构),并应用结果。第二个命令可能还必须进行编码,以便可以在另一个文档中重新输入,如果这是命令的结构。acedRegCmds()acedDefun() 请记住,在设计这些构造时,UNDO 在每个文档中单独运行。 注意:“正常”是不可行的,因为它可以多次提示,因此不会返回任何正在进行的选择集。相反,因为它要么返回一个实体,要么返回 RTNONE,这意味着用户真的完成了,或者 RTCAN,它可以是真正的取消或“移动到另一个文档”信号。设置本地“完成”标志,执行该操作,然后将 ESC 排队到所有其他活动文档,以便在用户下次单击该文档时在该文档中完成该命令。acedSSGet()acedEntSel()
父主题: |
|Archiver|CAD开发者社区 ( 苏ICP备2022047690号-1 苏公网安备32011402011833)
GMT+8, 2025-1-19 06:48
Powered by Discuz! X3.4
Copyright © 2001-2021, Tencent Cloud.