acedCommand 迁移
acedCommand在运行无光纤时,它本身不起作用,因为需要开发人员干预来确定所需的使用类型。有两种迁移路径可供使用。acedCommand 迁移路径基于两个新函数:和 。“S”和“C”前缀分别代表“子例程”和“协程”。选择替换哪个功能取决于 的预期用途。acedCommandSacedCommandCacedCommandacedCommand acedCmdNF.h Content ////////////////////////////////////////////////////////////////////////////// // // Copyright 2018 Autodesk, Inc. All rights reserved. // // Use of this software is subject to the terms of the Autodesk license // agreement provided at the time of installation or download, or which // otherwise accompanies this software in either electronic or hard copy form. // ////////////////////////////////////////////////////////////////////////////// #pragma once #include "acedinpt.h" #include "acdocman.h" // acedCmdNF.h: // Fiberless variants of acedCommand and acedCmd // plus supporting functions #ifdef __cplusplus extern "C" { #endif #pragma pack (push, 8) // acedFiberWorld: // Returns // true if $FIBERWORLD is 1, and // false if $FIBERWORLD is 0 // On both Windows-based and Mac-based AutoCAD, by default returns "false" // ACAD_PORT bool acedFiberWorld(); // // acedCommandS: syntax-compatible replacement of acedCommand, // use for "full commands", not partial ones. // This command essentially begins with its own // private command line processor, initialized at // the "Command:" prompt. The commands are executed // in the same manner as with acedCommand, except that // when the supplied input has all been executed, // the private command line processor is deleted // and the previous command line processor is unchanged // from when the call is made. modality and // transparent "builtin" commands may not be nested. // // int acedCommandS(int rtype, ...); // acedCmdS // // Does the same thing with the same restructions as acedCommandS, // with a resbuf chain rather than a veriable arguments list. // Two more supplied parameters are intended for future use. // class AcApDocument; int acedCmdS(const resbuf* rb, bool forFutureUse = false, AcApDocument* pForFutureUse = NULL); // acedCommandC, acedCmdC: // "coroutine" relationship with calling command processor. // Queues up the resbuf chain for feeding to the // calling command processor and stores the "returning" // callback function pointer and data pointer. // In the text here, they will be collectively // referred to as "acedCmdC", which in fact is // the common implementation. "acedCmd" will represent // the corresponding legacy command functions. // // After making call, caller must return from its // command (or defun/regfunc) entry // point to allow the command processor to process the // pending command input. Once done with that input, // AutoCAD will call pReturnFcn, with pReturnFcnParams // passed in. // // There are some common rules for the use of both acedCmdC // and acedCmd within a recognized application callback // (specifically, these functions are only operative within // specific AutoCAD contexts: // - a command, registered in ARX via AcEdCommandStack::addCommand // - a LISP invocation of a function registered via acedDefun // (and/or acedRegfunc). // - a coroutine callback passed in from acedCmdC // - Evaluation of LISP (command) statement evaluation. // - builtin commands (plus AcEdCommand commands with the // ACRX_CMD_NONEWSTACK flag set). // - Session Fiber Commands (or Application Execution Context) // - Transparent commands, executed at an input prompt of another // command in progress (Regardless of builtin or ARX-registered) // // 1. acedCmdC may be invoked from non-LISP calling contexts // regardless of the $FIBERWORLD // setting, (the exclusion from transparent commands remains). // // From LISP contexts where acedInvoke() is active (i.e. acedDefun'ed // functions being called from LISP), // acedCmdC may only be invoked when $FIBERWORLD is 0. // // acedCmd, in comparison, cannot be invoked unless $FIBERWORLD // is 1, if done, it will return an error status. It also // cannot be invoked from builtin commands, nor transparent commands. // // Therefore, function logic running in an acedDefun/acedInvoke // context should test acedFiberWorld to determine whether // to run acedCmd or acedCmdC is permissible. Notice that // acedCmdS is safe to run in this context regardless of the // $FIBERWORLD setting. // // 2. While it is not a destination in one's migration, // Command and defun'ed function logic (but not coroutine callbacks, // described next) may invoke acedCmd any number of times, // but after making a call to acedCmdC, the function must // return without making a call to either acedCmdC nor acedCmd. // If such a call is made, the resbuf chain previously supplied // by acedCmdC will be replaced with the subsequent chain. // acedCmd will return an error status and take no action. // 3. Coroutine continuation functions may call acedCmdC, // but use of acedCmd will return an error status // and no action. // 2. acedCmdS may be used in any of these contexts (and many more) // and at any time within these contexts. // It is unobvious to invoke acedCmdS // after calling acedCmdC and before returning to have its // input procssed, since the acedCmdS will be executed // synchronously, but it would work. // 3. Repeated calls to acedCmdC without returning for processing // in between will simply erase the earlier acedCmdC contents. // In other words, only one call will count before returning, // so don't bother making multiple calls. // 4. Commands and LISP expressions which use different mixes of // acedCmd, acedCmdC and acedCmdS may invoke each other // without regard to the makeup of the other command/expression. // Command processor modality restrictions will still apply // such as no nesting of nontransparent commands nor transparent // commands. // // WARNING: support of these functions in logic operated through // invocation of functions registered via acedDefun // is incomplete in ACAD 2011. // typedef int (*AcEdCoroutineCallback)(void* pData); ACAD_PORT int acedCommandC(AcEdCoroutineCallback pCallback, void* pReturnFcnParms, int rtype, ...); ACAD_PORT int acedCmdC(AcEdCoroutineCallback pCallback, void* pReturnFcnParms, const struct resbuf *rb); // acedPendingCmdCTokens // // This predicate should be checked immediately after calling // acedInvoke from a function registered via acedDefun that // has itself been invoked from LISP. If it returns true, then // the calling // function should itself also immediately return RSRSLT, without // necessarily establishing a return value. The tokens will be // processed, and either the calling function will be called back // (see acedResumeInvocation below for determining if this is the // case), or cancel will terminate the rest of the operation. // Note that acedFiberWorld() must return true for acedCmdC // to succeed in an acedInvoke context, and for this function to // return true. // // Returns // true after a function has invoked acedCmdC // from a LISP context, and LISP has yet to return. // See preceding for how to proceed when true is returned. // false when there are no pending comand tokens, in which // case the caller should proceed normally. // ACAD_PORT bool acedPendingCmdCTokens(); // acedResumingInvocation // // Returns // true when in a function registered via acedDefun and/or acedRegFunc // and invoked from LISP that is being called back after a // previous invocation called acedCommandC or acedCmdC, (see // acedPendingCmdCTokens()), either directly or via a nested // invocation. // In this case, the function is responsible for // determining how to resume. If, during its resumption, // acedCommandC or acedCmdC is invoked again, then after // returning to process those tokens, the function will be // "resumed" again, until no call to acedCommandC or acedCmdC // is made. Because acedCommandC/acedCmdC can be invoked // regardless of the $FIBERWORLD state, this function can // also return true, in any case. // false in all other conditions, including whenever acedFiberWorld() // is true. // ACAD_PORT bool acedResumingInvocation(); // acedCallBackOnCancel // // If you have made a call to acedCommandC or acedCmdC and wish to // have your registered callback called when a CANCEL or other error occurs, // call this function before returning. If you don't call this function // and a CANCEL or other error occurs, your callback will not be // called, instead AutoCAD will directly cancel the command state. // ACAD_PORT void acedCallBackOnCancel(); // acedCmdCWasCancelled // // When your registered callback is called in response to a CANCEL or error, // this function will return true, else it will return false. // ACAD_PORT bool acedCmdCWasCancelled(); #pragma pack (pop) #ifdef __cplusplus } #endif /* __cplusplus */ // acedPendingFiberlessDocSwitch: // // pNextActiveDocument: Optional parameter to receive the next active document // if the function returns true. Pass in NULL if the value is not needed. // // Returns // True if: // - $FIBERWORLD is 0 and // - a cancel is in progress and // - a document switch has been requested but // hasn't occurred yet, // // else false is returned. // // If a cancel happens at an input prompt and you // want your command to continue in the new document, // use something like AcApDocumentManager::sendStringToExecute // to the new document to perpetuate control. // ACAD_PORT bool acedPendingFiberlessDocSwitch(AcApDocument** pNextActiveDocument = NULL); acedCommandS在“子例程”中,第一个输入标记被馈送到 Command: 提示符,因此应该启动命令,最后一个输入标记完成命令。“令牌”是命令的一段。在这样的通话中:acedCommandS acedCommand(RTSTR, _T("_Line"), RTSTR, _T("0,0"), RTSTR, _T("111,111"), , RTSTR, _T("") , RTNONE); RTSTR, _T("_Line")是第一个命令令牌,也是最后一个,用于完成 LINE 命令。RTSTR, _T(””) 如果您的调用遵循此协定,则使用 .将上述代码迁移到就像键入额外的“S”一样简单,如下所示:acedCommandacedCommandSacedCommandS acedCommandS(RTSTR, _T("Line"), RTSTR, _T("0,0"), RTSTR, _T("111,111"), RTSTR, _T(""), RTNONE); 但是,如果 acedCommandS 不适合传入足够的令牌来开始命令但不能完成命令。当令牌用完时,任何正在进行的命令都将被取消。部分完成的命令副作用不会回滚。例如,以下语句无法提示用户输入另一个终结点,并且不会向数据库添加新行: acedCommandS(RTSTR, _T("Line"), RTSTR, _T("0,0"), RTNONE); 鉴于此,使用起来比您将看到的要简单得多,您可以通过迁移代码以尽可能使用来节省时间。acedCommandSacedCommandCacedCommandS acedCommandC“协程”可以概括为:在呼叫中,您停下来进行用户交互的任何地方都需要您使用 。acedCommandacedCommandacedCommandC 启用光纤后,在逻辑中负责将控制权返回给AutoCAD进行处理,该逻辑会根据需要切换光纤。禁用光纤后,ARX 命令和 LISP 必须实际返回给调用方。AutoCAD 将调用提供的“回调”函数,以允许 ARX 命令和 LISP 逻辑继续执行。acedCommand 需要协程方法的简单用法示例是 NAMEXXX 中 TYPE2 命令实现的函数:acedCommand static void adskacedCommandTeststype2(void) { acedCommand(RTSTR, _T("Line"), RTSTR, _T("0,0"), RTSTR, _T("111,111"),RTNONE); while(isLineActive()) acedCommand(RTSTR,PAUSE,RTNONE); acutPrintf(_T("\nFinished LINE command - control returned to addin\n")); } 注意:是一个简单的帮助程序功能,用于检查命令是否仍处于活动状态。isLineActive
转换为用法,此代码将如下所示。(为简洁起见,此处删除了注释,但包含的 NAMEYYY 项目已完全注释):acedCommandC static void myCallbackFn1(void * pData) { if (isLineActive()) acedCommandC(&myCallbackFn1, NULL, RTSTR,PAUSE,RTNONE); else acutPrintf(_T("\nFinished LINE command - control returned to addin\n")); } static void adskacedCommandTeststype2(void) { acedCommandC(&myCallbackFn1, NULL, RTSTR, _T("Line"), RTSTR, _T("0,0"), RTSTR, _T("111,111"), RTNONE); } 迁移的 TYPE2 命令的行为存在差异。在示例版本中,即使用户按 ESCAPE 结束 LINE 命令,控制也会返回到函数。在此示例中,按 ESCAPE 键也会取消您自己的命令 – 因此,仅当 LINE 命令通过按 ENTER 或(例如)CLOSE 关键字结束时,才会执行表达式。acedCommandacedCommandCacutPrintf TYPE3 命令实现显示了另一种(不太常见的)协程用法: static void adskacedCommandTeststype3(void) { acedCommand(RTSTR, _T("Line"), RTSTR, _T("0,0"), RTSTR, _T("111,111"),RTNONE); for (int i=0; i<3; ++i) acedCommand(RTSTR, PAUSE, RTNONE); acedCommand(RTSTR, _T(""), RTNONE); acutPrintf(_T("\nFinished LINE command - control returned to addin\n")); } 在这里,我们只是画一条线,并允许用户最多画三条额外的线。 迁移到使用情况后,这将如下所示:acedCommandC static void myCallbackFn2(void * pData) { struct MyData *pCountData = reinterpret_cast<struct MyData *>(pData); if (pCountData->mCount < 3) { acedCommandC(&myCallbackFn2, reinterpret_cast<void *>(pCountData), RTSTR, PAUSE, RTNONE); } else if (pCountData->mCount == 3) { acedCommandC(&myCallbackFn2, reinterpret_cast<void *>(pCountData), RTSTR, _T(""), RTNONE); } pCountData->mCount++; } static void adskacedCommandTeststype3(void) { static struct MyData countData; countData.mCount = 0; acedCommandC(&myCallbackFn2, reinterpret_cast<void *>(&countData), RTSTR, _T("Line"), RTSTR, _T("0,0"), RTSTR, _T("111,111"), RTNONE); } 父主题: |
|Archiver|CAD开发者社区 ( 苏ICP备2022047690号-1 苏公网安备32011402011833)
GMT+8, 2024-12-15 22:29
Powered by Discuz! X3.4
Copyright © 2001-2021, Tencent Cloud.