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

16/07/2016

Как позволить пользователю прервать длительную операцию в AutoCAD .NET

Если у вас запущена длительная операция, то вам может понадобится возможность прервать эту операцию (при помощи клавиши ESC). Следующий код работал в AutoCAD 2007…2009, но он продолжает по-прежнему исправно работать и в AutoCAD 2017.

Код - C#: [Выделить]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7.  
  8. [assembly: CommandClass(typeof(EscapeLoop.MyCommands))]
  9.  
  10. namespace EscapeLoop
  11. {
  12.   public class MyCommands
  13.   {
  14.     [CommandMethod("EscapeLoop")]
  15.     static public void Loop()
  16.     {
  17.       Document doc =
  18.         Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  19.      
  20.       if (doc == null) return;
  21.  
  22.       Editor ed = doc.Editor;
  23.  
  24.       // Создаем и добавляем фильтр сообщений
  25.       MyMessageFilter filter = new MyMessageFilter();
  26.       System.Windows.Forms.Application.AddMessageFilter(filter);
  27.       //////////////////////////////////////////////////////////////////////////
  28.       //                    Запускаем цикл
  29.       //////////////////////////////////////////////////////////////////////////
  30.       while (true)
  31.       {
  32.         // Проверяем не было ли пользовательского ввода
  33.         System.Windows.Forms.Application.DoEvents();
  34.         // Проверяем не установил ли наш фильтр флаг ESC
  35.  
  36.         if (filter.bCanceled == true)
  37.         {
  38.           ed.WriteMessage("\nЦикл прерван!");
  39.           break;
  40.         }
  41.         ed.WriteMessage("\nВнутри цикла...");
  42.       }
  43.  
  44.       // Мы закончили - удаляем фильтр
  45.       System.Windows.Forms.Application.RemoveMessageFilter(filter);
  46.     }
  47.   }
  48.  
  49.   //////////////////////////////////////////////////////////////////////////
  50.   //            Наш класс для фильтрации сообщений
  51.   //////////////////////////////////////////////////////////////////////////
  52.  
  53.   public class MyMessageFilter : System.Windows.Forms.IMessageFilter
  54.   {
  55.  
  56.     public const int WM_KEYDOWN = 0x0100;
  57.     public const int WM_KEYUP = 0x0101;
  58.  
  59.     public bool bCanceled = false;
  60.  
  61.     public bool PreFilterMessage(ref System.Windows.Forms.Message m)
  62.     {
  63.       if (m.Msg == WM_KEYDOWN || m.Msg == WM_KEYUP)
  64.       {
  65.         // Проверяем не нажата ли клавиша ESC
  66.         System.Windows.Forms.Keys kc =
  67.           (System.Windows.Forms.Keys)(int)m.WParam & System.Windows.Forms.Keys.KeyCode;
  68.         if (kc == System.Windows.Forms.Keys.Escape)
  69.         {
  70.           bCanceled = true;
  71.           // Возвращаем true, чтобы показать, что мы обработали это сообщение
  72.           return true;
  73.         }
  74.       }
  75.       // Возвращаем false, чтобы сообщить, что мы не обрабатывали это сообщение
  76.       return false;
  77.     }
  78.   }
  79. }

 

Источник: http://adndevblog.typepad.com/autocad/2012/07/allowing-users-to-escape-from-long-operations-in-autocad-net.html

 

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

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

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