Получить свойства объекта, отображаемые в палитре свойств

Автор Тема: Получить свойства объекта, отображаемые в палитре свойств  (Прочитано 5932 раз)

0 Пользователей и 3 Гостей просматривают эту тему.

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Я пытаюсь сделать свой вариант команды _QSelect. Есть ли какой-нибудь способ получить все свойства для любого наследника Entity? Reflection выдает вовсе не те свойства, что видит пользователь в палитре свойств (OPM). Кроме того через Reflection никак не получить локализованные имена свойств. И хотелось бы значения свойств тоже получить так, как их видит пользователь. Единственный полезный атрибут свойств, который я нашел - UnitTypeAttribute. Он позволяет правильно отформатировать значения double, но со значениями остальных свойств тоже полная катавасия - какие-то выдают локализованные значения через ToString() (например, Entity.Color.ToString() выдаст "ПоСлою" или "красный" в русской версии), другие пишут по английски, многие вообще имя класса вместо значения выдают. Есть ли что-то в API на эту тему?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Есть ли что-то в API на эту тему?
В AutoCAD .NET API нет. В ObjectARX можно.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Ох, нет, моя нервная система не выдерживает контактов с С++ :) Но все равно, спасибо! Отрицательный результат - это тоже результат.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Еще вот такое:



Это "компиляция" отсюда: http://adndevblog.typepad.com/manufacturing/2013/02/get-activexcom-class-properties-and-methods-from-net.html

Код - C# [Выбрать]
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using Autodesk.AutoCAD.Runtime;
  4. using Autodesk.AutoCAD.ApplicationServices;
  5. using Autodesk.AutoCAD.DatabaseServices;
  6. using Autodesk.AutoCAD.Geometry;
  7. using Autodesk.AutoCAD.EditorInput;
  8.  
  9. #pragma warning disable 0618
  10.  
  11. // This line is not mandatory, but improves loading performances
  12. [assembly: CommandClass(typeof(GetProperties.MyCommands))]
  13.  
  14. namespace GetProperties
  15. {
  16.   #region COMIDispatch
  17.  
  18.   [ComImport()]
  19.   [Guid("00020400-0000-0000-C000-000000000046")]
  20.   [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  21.   public interface IDispatch
  22.   {
  23.     [PreserveSig]
  24.     int GetTypeInfoCount(out int Count);
  25.  
  26.     [PreserveSig]
  27.     int GetTypeInfo
  28.         (
  29.             [MarshalAs(UnmanagedType.U4)] int iTInfo,
  30.             [MarshalAs(UnmanagedType.U4)] int lcid,
  31.             out System.Runtime.InteropServices.ComTypes.ITypeInfo typeInfo
  32.         );
  33.  
  34.     [PreserveSig]
  35.     int GetIDsOfNames
  36.         (
  37.             ref Guid riid,
  38.             [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)]
  39.             string[] rgsNames,
  40.             int cNames,
  41.             int lcid,
  42.             [MarshalAs(UnmanagedType.LPArray)] int[] rgDispId
  43.         );
  44.  
  45.     [PreserveSig]
  46.     int Invoke
  47.         (
  48.             int dispIdMember,
  49.             ref Guid riid,
  50.             uint lcid,
  51.             ushort wFlags,
  52.             ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams,
  53.             out object pVarResult,
  54.             ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo,
  55.             IntPtr[] pArgErr
  56.         );
  57.   }
  58.   public enum MethodType
  59.   {
  60.     Method = 0,
  61.     Property_Getter = 1,
  62.     Property_Putter = 2,
  63.     Property_PutRef = 3
  64.   }
  65.  
  66.   public struct MethodInformation
  67.   {
  68.     public string m_strName;
  69.     public string m_strDocumentation;
  70.     public MethodType m_method_type;
  71.   }
  72.  
  73.   class COMIDispatch
  74.   {
  75.     // This static function returns an array containing
  76.     // information of all public methods of a COM object.
  77.     // Note that the COM object must implement the IDispatch
  78.     // interface in order to be usable in this function.
  79.     public static MethodInformation[] GetMethodInformation(object com_obj)
  80.     {
  81.       IDispatch pDispatch = null;
  82.  
  83.       try {
  84.         // Obtain the COM IDispatch interface from the input com_obj object.
  85.         // Low-level-wise this causes a QueryInterface() to be performed on
  86.         // com_obj to obtain the IDispatch interface from it.
  87.         pDispatch = (IDispatch)com_obj;
  88.       }
  89.       catch (System.InvalidCastException ex) {
  90.         // This means that the input com_obj
  91.         // does not support the IDispatch
  92.         // interface.
  93.         return null;
  94.       }
  95.  
  96.       // Obtain the ITypeInfo interface from the object via its
  97.       // IDispatch.GetTypeInfo() method.
  98.       System.Runtime.InteropServices.ComTypes.ITypeInfo pTypeInfo = null;
  99.       // Call the IDispatch.GetTypeInfo() to obtain an ITypeInfo interface
  100.       // pointer from the com_obj.
  101.       // Note that the first parameter must be 0 in order to
  102.       // obtain the Type Info of the current object.
  103.       pDispatch.GetTypeInfo
  104.       (
  105.           0,
  106.           0,
  107.           out pTypeInfo
  108.       );
  109.  
  110.       // If for some reason we are not able to obtain the
  111.       // ITypeInfo interface from the IDispatch interface
  112.       // of the COM object, we return immediately.
  113.       if (pTypeInfo == null) {
  114.         return null;
  115.       }
  116.  
  117.       // Get the TYPEATTR (type attributes) of the object
  118.       // via its ITypeInfo interface.
  119.       IntPtr pTypeAttr = IntPtr.Zero;
  120.       System.Runtime.InteropServices.ComTypes.TYPEATTR typeattr;
  121.       // The TYPEATTR is returned via an IntPtr.
  122.       pTypeInfo.GetTypeAttr(out pTypeAttr);
  123.       // We must convert the IntPtr into the TYPEATTR structure
  124.       // defined in the System.Runtime.InteropServices.ComTypes
  125.       // namespace.
  126.       typeattr = (System.Runtime.InteropServices.ComTypes.TYPEATTR)Marshal.PtrToStructure
  127.           (
  128.             pTypeAttr,
  129.             typeof(System.Runtime.InteropServices.ComTypes.TYPEATTR)
  130.           );
  131.       // Release the resources related to the obtaining of the
  132.       // COM TYPEATTR structure from an ITypeInfo interface.
  133.       // From now onwards, we will only work with the
  134.       // System.Runtime.InteropServices.ComTypes.TYPEATTR
  135.       // structure.
  136.       pTypeInfo.ReleaseTypeAttr(pTypeAttr);
  137.       pTypeAttr = IntPtr.Zero;
  138.  
  139.       // The TYPEATTR.guid member indicates the default interface implemented
  140.       // by the COM object.
  141.       Guid defaultInterfaceGuid = typeattr.guid;
  142.  
  143.       MethodInformation[] method_information_array = new MethodInformation[typeattr.cFuncs];
  144.       // The TYPEATTR.cFuncs member indicates the total number of methods
  145.       // that the current COM object implements.
  146.       for (int i = 0; i < (typeattr.cFuncs); i++) {
  147.         // We loop through the number of methods.
  148.         System.Runtime.InteropServices.ComTypes.FUNCDESC funcdesc;
  149.         IntPtr pFuncDesc = IntPtr.Zero;
  150.         string strName;
  151.         string strDocumentation;
  152.         int iHelpContext;
  153.         string strHelpFile;
  154.  
  155.         // During each loop, we use the ITypeInfo.GetFuncDesc()
  156.         // method to obtain a FUNCDESC structure which describes
  157.         // the current method indexed by "i".
  158.         pTypeInfo.GetFuncDesc(i, out pFuncDesc);
  159.         // The FUNCDESC structure is returned as an IntPtr.
  160.         // We need to convert it into a FUNCDESC structure
  161.         // defined in the System.Runtime.InteropServices.ComTypes
  162.         // namespace.
  163.         funcdesc = (System.Runtime.InteropServices.ComTypes.FUNCDESC)Marshal.PtrToStructure
  164.             (
  165.               pFuncDesc,
  166.               typeof(System.Runtime.InteropServices.ComTypes.FUNCDESC)
  167.             );
  168.         // The FUNCDESC.memid contains the member id of the current function
  169.         // in the Type Info of the object.
  170.         // Use the ITypeInfo.GetDocumentation() with reference to memid
  171.         // to obtain information for this function.
  172.         pTypeInfo.GetDocumentation
  173.             (
  174.               funcdesc.memid,
  175.               out strName,
  176.               out strDocumentation,
  177.               out iHelpContext,
  178.               out strHelpFile
  179.             );
  180.         // Fill up the appropriate method_information_array element
  181.         // with field information.
  182.         method_information_array[i].m_strName = strName;
  183.         method_information_array[i].m_strDocumentation = strDocumentation;
  184.  
  185.         if (funcdesc.invkind == System.Runtime.InteropServices.ComTypes.INVOKEKIND.INVOKE_FUNC) {
  186.           method_information_array[i].m_method_type = MethodType.Method;
  187.         } else if (funcdesc.invkind == System.Runtime.InteropServices.ComTypes.INVOKEKIND.INVOKE_PROPERTYGET) {
  188.           method_information_array[i].m_method_type = MethodType.Property_Getter;
  189.         } else if (funcdesc.invkind == System.Runtime.InteropServices.ComTypes.INVOKEKIND.INVOKE_PROPERTYPUT) {
  190.           method_information_array[i].m_method_type = MethodType.Property_Putter;
  191.         } else if (funcdesc.invkind == System.Runtime.InteropServices.ComTypes.INVOKEKIND.INVOKE_PROPERTYPUTREF) {
  192.           method_information_array[i].m_method_type = MethodType.Property_PutRef;
  193.         }
  194.  
  195.         // The ITypeInfo.ReleaseFuncDesc() must be called
  196.         // to release the (unmanaged) memory of the FUNCDESC
  197.         // returned in pFuncDesc (an IntPtr).
  198.         pTypeInfo.ReleaseFuncDesc(pFuncDesc);
  199.         pFuncDesc = IntPtr.Zero;
  200.       }
  201.  
  202.       return method_information_array;
  203.     }
  204.   }
  205.  
  206.   #endregion
  207.  
  208.   public class MyCommands
  209.   {
  210.     [CommandMethod("GetProps")]
  211.     public void GetProps()
  212.     {
  213.       Document doc = Application.DocumentManager.MdiActiveDocument;
  214.       if (doc == null) return;
  215.       Editor ed = doc.Editor;
  216.       PromptEntityResult rs = ed.GetEntity("\nВыберите примитив: ");
  217.       if (rs.Status != PromptStatus.OK) return;
  218.       using (Entity ent = rs.ObjectId.Open(OpenMode.ForRead) as Entity) {
  219.         object ob = ent.AcadObject;
  220.         MethodInformation[] mis = COMIDispatch.GetMethodInformation(ob);
  221.         foreach (MethodInformation mi in mis) {
  222.           if (mi.m_method_type == MethodType.Property_Getter) {
  223.             ed.WriteMessage("\n{0} ==> {1}", mi.m_strName, mi.m_strDocumentation);
  224.           }
  225.         }
  226.       }
  227.     }
  228.   }
  229. }

Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение