ADN Open CIS
Сообщество программистов Autodesk в СНГ

15/09/2015

Регистрация команды для функции обратного вызова UnknownCommand

Этот пример отвечает на множество вопросов по поводу функции обратного вызова unknownCommand и использования UnknownCommand.

Когда когда-либо пользователь вводит неправильное или незарегистрированное имя команды или опечатывается, мы можем использовать механизм, чтобы перехватить команду с опечаткой и отправить нашу команду или зарегистрировать новую команду и отправить её.

В этом примере пользователь пытается ввести некоторую неизвестную команду, например, в функции обратного вызова, запущенной из реактора события unknownCommand, мы будем загружать наш "TestUknCom".

Некоторые проблемы и вопросы:

Как подавить сообщение о неизвестной команде в командной строке ?

Сейчас команда инженеров работает над этим. В идеале “AcadAppInfo::kNoAction” в функции loaderFunPtr должно решить эту проблему. Но уже сейчас есть обходной путь – прочитать строку неизвестной команды и на ходу зарегистрировать её, а разрегистрировать её при выгрузке приложения.

Как удалить команду, вызванную в функции обратного вызова из истории команд?

Флаг ACRX_CMD_NOHISTORY при регистрации команды поможет исключить её от добавления в историю команд.

Код - C++: [Выделить]
  1. #include "StdAfx.h"
  2. #include "resource.h"
  3.  
  4.  
  5. class adskedReactor : public AcEditorReactor
  6. {
  7. public:
  8.   // Конструктор / Деструктор
  9.   adskedReactor(const bool autoInitAndRelease = true);
  10.   virtual ~adskedReactor();
  11.  
  12.   //{{AFX_ARX_METHODS(adskedReactor)
  13.   virtual void beginQuit();
  14.   virtual void unknownCommand(   const TCHAR* cmdStr,   AcDbVoidPtrArray *al);
  15.   //}}AFX_ARX_METHODS
  16.  
  17. private:
  18.   // Флаг автоинициализации и освобождения
  19.   bool m_autoInitAndRelease;
  20. };
  21.  
  22. adskedReactor::adskedReactor(const bool autoInitAndRelease)
  23. {
  24.   m_autoInitAndRelease = autoInitAndRelease;
  25.   if (m_autoInitAndRelease)
  26.     if (NULL != acedEditor)
  27.       acedEditor->addReactor(this);
  28.     else
  29.       m_autoInitAndRelease = false;
  30. }
  31.  
  32. adskedReactor::~adskedReactor()
  33. {
  34.   if (m_autoInitAndRelease)
  35.     if (NULL != acedEditor)
  36.       acedEditor->removeReactor(this);
  37. }
  38.  
  39. void adskedReactor::beginQuit()
  40. {
  41.   AcApDocumentIterator *pIt;
  42.   pIt=acDocManager->newAcApDocumentIterator();
  43.  
  44.   while(!pIt->done())
  45.   {
  46.     // По всем открытым документам
  47.     AcApDocument* pDoc=pIt->document();
  48.     acDocManager->setCurDocument(pDoc);
  49.     struct resbuf res;
  50.     acedGetVar(_T("DBMOD"),&res);
  51.  
  52.     if(res.resval.rint) // Если чертеж менялся...
  53.     {
  54.       acDocManager->lockDocument(pDoc); // Блокируем
  55.       // Если мы хотим сохранить...
  56.       // SaveDb(pDoc);// Вызываем сохранение...
  57.       // Если хотим игнорировать изменения...
  58.  
  59.       acdbSetDbmod(pDoc->database(),0); // Сбрасываем флаг изменений
  60.       acDocManager->unlockDocument(pDoc); // разблокируем
  61.  
  62.     }
  63.  
  64.     pIt->step();
  65.  
  66.   }
  67.  
  68.   delete pIt;
  69.  
  70. }
  71.  
  72. /* Функция обратного вызова */
  73. CString gsCmd;
  74.  
  75. AcadAppInfo::CmdStatus LoaderFunPtr(void *p)
  76. {  
  77.   acedPostCommand ((LPCTSTR) gsCmd) ;
  78.   return AcadAppInfo::kNoAction;
  79. }
  80.  
  81. /* Чтобы запретить сообщение о неизвестной команде,
  82. регистрируем на лету команду с этим именем */
  83.  
  84. void unknwCommand()
  85. {
  86.   /* Пустая функция */
  87. }
  88.  
  89.  
  90. void adskedReactor::unknownCommand(   const TCHAR* cmdStr,   AcDbVoidPtrArray *al)
  91. {
  92.   /* Не забудем удалить команду после её завершения*/
  93.   acedRegCmds->addCommand(_T("UNKGrp"), cmdStr, cmdStr, ACRX_CMD_MODAL, unknwCommand);
  94.   CString unkCmd;
  95.   unkCmd.Format(cmdStr);
  96.   gsCmd.Format(_T("TestUknCom\n"));
  97.   AcadAppInfo* pAppInfo = new AcadAppInfo();
  98.   pAppInfo->setAppLoader(LoaderFunPtr);
  99.   pAppInfo->setLoadReason(AcadApp::kLoadDisabled);
  100.   pAppInfo->setAppName(_T("TestCBCom"));
  101.   al->append(pAppInfo);
  102. }
  103.  
  104. /* Arx-функция*/
  105. void TestUknCom()
  106. {
  107.   acutPrintf(_T("TestUknCom вызвана \n"));
  108. }
  109.  
  110. // Эта функция регистрирует ARX-команды.
  111. void AddCommand(const TCHAR* cmdGroup, const TCHAR* cmdInt, const TCHAR* cmdLoc,
  112.                 const int cmdFlags, const AcRxFunctionPtr cmdProc, const int idLocal = 0)
  113. {
  114.   acedRegCmds->addCommand(cmdGroup, cmdInt, cmdLoc, cmdFlags, cmdProc);
  115. }
  116.  
  117. // Инициализируем приложение. Регистрируем
  118. // команды, реакторы...
  119.  
  120. void InitApplication()
  121. {
  122.   adskedReactor *pEdReactor = new adskedReactor();
  123.   acedEditor->addReactor(pEdReactor);
  124.   AddCommand(_T("TestCBCom"), _T("TestUknCom"), _T("TestUknCom"),ACRX_CMD_NOHISTORY , TestUknCom);
  125. }
  126.  
  127. // Выгружаем это приложение. Разрегистрируем все объекты,
  128. // зарегистрированные в InitApplication.
  129. void UnloadApplication()
  130. {
  131.   acedRegCmds->removeCmd(_T("TestCBCom"),_T("TestUknCom"));
  132. }
  133.  
  134.  
  135.  
  136. extern "C" AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg, void *pkt)
  137.   //**************************************************************
  138. {
  139.   switch(msg)
  140.   {
  141.   case AcRx::kInitAppMsg:
  142.     acrxDynamicLinker->unlockApplication(pkt);
  143.     acrxDynamicLinker->registerAppMDIAware(pkt);
  144.     /* Загружаем команды */
  145.     acrxBuildClassHierarchy(); /* для регистрации производных классов */
  146.     InitApplication();
  147.     break;
  148.   case AcRx::kUnloadAppMsg:
  149.     UnloadApplication();
  150.     break;
  151.   default:
  152.     break;
  153.   }
  154.   return AcRx::kRetOK;
  155. }

 

Источник: http://adndevblog.typepad.com/autocad/2015/07/registering-command-for-unknowncommand-callback.html

Автор перевода: Александр Ривилис

Обсуждение: http://adn-cis.org/forum/index.php?topic=3016

Опубликовано 15.09.2015