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

26/10/2020

Как обновить информацию в командной строке AutoCAD?

Вопрос: В процессе длительного выполнения кода необходимо обновлять информацию в командной строке AutoCAD (например, процент выполнения). В старых версиях AutoCAD достаточно было вызвать acedPrompt(L""). Начиная с AutoCAD 2015 это не помогает.

Ответ: По-прежнему в последних версиях AutoCAD lisp-выражение (princ) позволяет обновить содержимое командной строки. В ObjectARX для этой цели приходится использовать недокументированную функцию  adsi_flushcommandline(). При этом следует учитывать, что для обновления интерфейса AutoCAD ему необходимо дать возможность обработать свои сообщения. Для этой цели можно воспользоваться такой функцией:

Код - C++: [Выделить]
  1. int OnIdleAcadInternal(void) {
  2.   CWinApp* app = acedGetAcadWinApp();
  3.   CWnd* wnd = app->GetMainWnd();
  4.   MSG msg;
  5.   while (::PeekMessage(&msg, wnd->m_hWnd, 0, 0, PM_NOREMOVE)) {
  6.     if (!app->PumpMessage()) {
  7.       ::PostQuitMessage(0);
  8.       break;
  9.     }
  10.   }
  11.   LONG lIdle = 0;
  12.   // while (app->OnIdle(lIdle++)&& lIdle < 1000);
  13.   return RSRSLT;
  14. }

Тестовый код может выглядеть вот так:

Код - C++: [Выделить]
  1. //-----------------------------------------------------------------------------
  2. //----- acrxEntryPoint.cpp
  3. //-----------------------------------------------------------------------------
  4. #include "StdAfx.h"
  5. #include "resource.h"
  6.  
  7. //-----------------------------------------------------------------------------
  8. #define szRDS _RXST("")
  9.  
  10. // Эта функция выполняет обновление командной строки
  11. void __cdecl adsi_flushcommandline(void);
  12.  
  13. int OnIdleAcadInternal(void) {
  14.   CWinApp* app = acedGetAcadWinApp();
  15.   CWnd* wnd = app->GetMainWnd();
  16.   MSG msg;
  17.   while (::PeekMessage(&msg, wnd->m_hWnd, 0, 0, PM_NOREMOVE)) {
  18.     if (!app->PumpMessage()) {
  19.       ::PostQuitMessage(0);
  20.       break;
  21.     }
  22.   }
  23.   LONG lIdle = 0;
  24.   // while (app->OnIdle(lIdle++)&& lIdle < 1000);
  25.   return RSRSLT;
  26. }
  27.  
  28. //-----------------------------------------------------------------------------
  29. //----- ObjectARX EntryPoint
  30. class CTestCommandLineApp : public AcRxArxApp {
  31.  
  32. public:
  33.   CTestCommandLineApp() : AcRxArxApp() {}
  34.  
  35.   virtual AcRx::AppRetCode On_kInitAppMsg(void* pkt) {
  36.     AcRx::AppRetCode retCode = AcRxArxApp::On_kInitAppMsg(pkt);
  37.     return (retCode);
  38.   }
  39.  
  40.   virtual AcRx::AppRetCode On_kUnloadAppMsg(void* pkt) {
  41.     AcRx::AppRetCode retCode = AcRxArxApp::On_kUnloadAppMsg(pkt);
  42.     return (retCode);
  43.   }
  44.  
  45.   virtual void RegisterServerComponents() { }
  46.  
  47.   static void RivilisTestCommandLine() {
  48.  
  49.     for (int i = 0; i <= 100; i++)
  50.     {
  51.       acutPrintf(_T("\rПроцент выполнения: %d%%"), i);
  52.       OnIdleAcadInternal();
  53.       adsi_flushcommandline();
  54.       Sleep(100);
  55.     }
  56.  
  57.   }
  58. };
  59.  
  60. //-----------------------------------------------------------------------------
  61. IMPLEMENT_ARX_ENTRYPOINT(CTestCommandLineApp)
  62.  
  63. ACED_ARXCOMMAND_ENTRY_AUTO(CTestCommandLineApp, Rivilis, TestCommandLine, TestCommandLine, ACRX_CMD_MODAL, NULL)
  64.  

 

Результат:

 

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