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

ADN Club => AutoCAD .NET API => Тема начата: xSAKABSx от 09-04-2015, 14:07:59

Название: Получение имени блока редактируемого в данный момент пользователем
Отправлено: xSAKABSx от 09-04-2015, 14:07:59
Вопрос к А.Ривилису: Александр нашел вашу небольшую переписку с Virupaksha Aithal(по русски не осмелился написать) (http://adndevblog.typepad.com/autocad/2015/03/identify-the-block-editing-mode-in-autocad.html)
Удалось как нибудь решить данную задачу ?
Название: Re: Получение имени блока редактируемого в данный момент пользователем
Отправлено: Александр Ривилис от 09-04-2015, 15:20:22
Я дополнительно задал вопрос в ADN DevHelp. После их исследования и переписки с командой инженеров выяснилось, что нет API, которое бы позволяло узнать имя блока внутри команды _BEDIT. Если используется _REFEDIT, то есть системная переменная _REFEDITNAME.
ADN DevHelp подало пожелание о дополнительном API в следующих версиях. Но без бизнес-кейса это пожелание может так и остаться нереализованным. Как минимум нужно уточнить количество пользователей, которых затрагивает эта проблема и возможность/невозможность обойти эту проблему другим способом.
Название: Re: Получение имени блока редактируемого в данный момент пользователем
Отправлено: Александр Ривилис от 25-06-2015, 11:57:16
Обнаружил недокументированную функцию, экспортируемую из acad.exe (начиная с AutoCAD 2013 из accore.dll):
Код - C++ [Выбрать]
  1. class AcString __cdecl acedGetBlockEditBlockName(void);
В ObjectARX ею можно воспользоваться для получения имени редактируемого блока в редакторе блоков. Теоретически можно вызвать и из .NET через P/Invoke, но будет проблема с преобразованием неуправляемого AcString в string.
Название: Re: Получение имени блока редактируемого в данный момент пользователем
Отправлено: Александр Ривилис от 25-06-2015, 20:38:05
Оказывается эти недокументированные функции есть начиная с AutoCAD 2009.

Код - C++ [Выбрать]
  1. //--------------------------------------------------------------
  2. //  Эти функции экспортируются из acad.exe (или accore.dll
  3. //  начиная с AutoCAD 2013) и требуют соотвественно для линковки
  4. //  acad.lib (или accore.lib для версий начиная с 2013)
  5. //--------------------------------------------------------------
  6. class AcString __cdecl acedGetBlockEditBlockName(void);
  7. bool __cdecl acedIsDocumentInBlockEditor(class AcApDocument *);
  8.  
  9. static void TestBEdit () {
  10.   if (acedIsDocumentInBlockEditor(curDoc()))
  11.   {
  12.     acutPrintf(_T("\nМы в редакторе блока %s"),
  13.         acedGetBlockEditBlockName().constPtr());
  14.   } else {
  15.     acutPrintf(_T("\nМы в не в редакторе блоков"));
  16.   }
  17. }
Название: Re: Получение имени блока редактируемого в данный момент пользователем
Отправлено: Александр Ривилис от 25-06-2015, 23:44:50
Еще немного покопался в мозгах в файле acmgd.dll и обнаружил, что от меня "скрыли" решение. Вот как эта задача решается при помощи AutoCAD .NET API начиная с версии 2010 (с 2009 как оказалось):
Код - C# [Выбрать]
  1. using System;
  2. using System.Reflection;
  3. using System.Runtime.InteropServices;
  4. using Autodesk.AutoCAD.Runtime;
  5. using Autodesk.AutoCAD.ApplicationServices;
  6. using Autodesk.AutoCAD.DatabaseServices;
  7. using Autodesk.AutoCAD.Geometry;
  8. using Autodesk.AutoCAD.EditorInput;
  9. using Autodesk.AutoCAD.Internal;
  10.  
  11. [assembly: CommandClass(typeof(Rivilis.BEdit))]
  12.  
  13. namespace Rivilis
  14. {
  15.   public class BEdit
  16.   {
  17.     [CommandMethod("TestBEDIT")]
  18.     public void TestBEdit()
  19.     {
  20.       Document doc = Application.DocumentManager.MdiActiveDocument;
  21.       Editor ed;
  22.       if (doc != null)
  23.       {
  24.         ed = doc.Editor;
  25.         if (AcAeUtilities.IsInBlockEditor())
  26.         {
  27.           ed.WriteMessage("\nМы в редакторе блока \"{0}\"", AcAeUtilities.GetBlockName());
  28.         }
  29.         else
  30.         {
  31.           ed.WriteMessage("\nМы НЕ в редакторе блока");
  32.         }
  33.       }
  34.     }
  35.   }
  36. }

Придётся "разобраться" с ADN DevHelp почему они не предложили этот вариант, если ему уже больше пяти лет.
Название: Re: Получение имени блока редактируемого в данный момент пользователем
Отправлено: Андрей Бушман от 26-06-2015, 08:02:57
почему они не предложили этот вариант, если ему уже больше пяти лет.
К сожалению, это далеко не единичный случай и как-то уж очень слабо верится, что ситуация может измениться. Да, собственно, чего далеко-то ходить: тынц (http://adn-cis.org/forum/index.php?topic=2810.msg10096#msg10096). Вот и вам, в данном случае, ответили точно так же - обозначив свой вариант  аля "я уверен", вместо того, чтобы на самом деле попытаться разобраться. Так что удивляться не приходится - это просто отношение к работе такое.
Название: Re: Получение имени блока редактируемого в данный момент пользователем
Отправлено: Александр Ривилис от 26-06-2015, 12:12:37
В данном случае я не совсем правильно задал им вопрос, проведя параллель с системной переменной REFEDITNAME для команды _REFEDIT. Впрочем я просил дать решение на любом API.
Название: Re: Получение имени блока редактируемого в данный момент пользователем
Отправлено: Александр Ривилис от 26-06-2015, 12:34:50
Андрей Бушман проверил, что этот код работает и в AutoCAD 2009 если подключить acmgdinternal.dll из каталога с acad.exe (в составе ObjectARX SDK этого файла нет).