Differences .NET API between AutoCAD and BricsCAD

I wrote the list more than 60 differences between API. I use this list to forget nothing. And I found ways to solve some of these problems. I think this article can be interesting, for those who plan to port their .Net plug-ins. While I did not translate into English. I think that the code in C # is understandable without translation. But write to me if there is interest.
https://sites.google.com/site/avcprg/bricscad-net
I propose to leave in this thread a comment about the problems of porting plug-ins and your ways of solving them.

Comments

  • abeltello
    edited June 2018

    You know the way to open and close a drawing in BRICSCAD .NET.

  • @abeltello said:
    You know the way to open and close a drawing in BRICSCAD .NET.

    Is this a question? I have not yet tried to open the document, but I load the drawing database without opening the document. This works perfectly.

  • @avc Thanks, its a question, but i need to open a drawing in BRICSCAD and I have been reading the documentation form .NET API in AUTOCAD and BRICSCAD it can not found the namespace in the same place.

  • You can use COM and a bit of reflection. Here is a sample

        /// <summary>
        /// Gets the specified property name.
        /// </summary>
        /// <param name="obj">The object.</param>
        /// <param name="propName">Name of the property.</param>
        /// <param name="parameter">The parameter.</param>
        /// <returns>System.Object.</returns>
        public static object Get(this object obj, string propName, params object[] parameter)
        {
            return obj.GetType().InvokeMember(propName, BindingFlags.GetProperty, null, obj, parameter);
        }
    
        /// <summary>
        /// Sets the specified property name.
        /// </summary>
        /// <param name="obj">The object.</param>
        /// <param name="propName">Name of the property.</param>
        /// <param name="parameter">The parameter.</param>
        public static void Set(this object obj, string propName, params object[] parameter)
        {
            obj.GetType().InvokeMember(propName, BindingFlags.SetProperty, null, obj, parameter);
        }
    
        /// <summary>
        /// Invokes the specified meth name.
        /// </summary>
        /// <param name="obj">The object.</param>
        /// <param name="methName">Name of the meth.</param>
        /// <param name="parameter">The parameter.</param>
        /// <returns>System.Object.</returns>
        public static object Invoke(this object obj, string methName, params object[] parameter)
        {
            return obj.GetType().InvokeMember(methName, BindingFlags.OptionalParamBinding | BindingFlags.InvokeMethod, null, obj, parameter);
        }
    
    
        /// <summary>
        /// Opens the DWG.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="dwgPath">The DWG path.</param>
        public static void OpenDwg(this Document doc, string dwgPath)
        {
            var acad = Application.AcadApplication;
            var documents = acad.Get("Documents", null);
            if (documents != null)
            {
                var parameters = new List<object> {dwgPath, Type.Missing, Type.Missing};
                documents.Invoke("Open", parameters.ToArray());
            }
        }
    

    and the final call:

    Application.DocumentManager.MdiActiveDocument.OpenDwg(fname);

  • avc
    avc
    edited July 2018

    @Daniele Piazza said:
    public static void OpenDwg(this Document doc, string dwgPath)
    and the final call:
    Application.DocumentManager.MdiActiveDocument.OpenDwg(fname);

    Your method OpenDwg is mistakenly primed to the helper for the document. But an existing document is not needed to open a new file. In AutoCAD there is an Open helper and it is assigned to DocumentCollection. And this is logical.
    public static Document Open(this DocumentCollection docCol, string FileName);
    and the final call:
    Document newdoc = Application.DocumentManager.Open(filename);
    In BricsCAD it is desirable to do the same, so get a new document.

    I will write down this BricsCAD API defect in my list.

    update:
    I tried this:

            #if BRICS
                public static Document Open(this DocumentCollection dc, string dwgPath) // вообще-то параметр dc не нужен, добавлен чисто для совместимости c AutoCAD
                {
                  var acad = Application.AcadApplication;
                  var documents = acad.Get("Documents", null);
                  if (documents != null)
                  {
                    var parameters = new List<object> { dwgPath, Type.Missing, Type.Missing };
                    return documents.Invoke("Open", parameters.ToArray()) as Document;
                  }
                  else return null;
                }
            #endif
    

    Document opened without problem but returned null :(

  • Yes, you are right about the poor design: just provided a code snippet.
    Extending DocumentCollection (DocumentManager) makes sense.

  • @avc said:
    I wrote the list more than 60 differences between API. I use this list to forget nothing. And I found ways to solve some of these problems. I think this article can be interesting, for those who plan to port their .Net plug-ins. While I did not translate into English. I think that the code in C # is understandable without translation. But write to me if there is interest.
    https://sites.google.com/site/avcprg/bricscad-net
    I propose to leave in this thread a comment about the problems of porting plug-ins and your ways of solving them.

    Thanks for putting this together

  • I continue to replenish my collection. There are already 75 problems with the BricsCAD API. In most cases I found and published solutions ... terrible crutches, but better than nothing.

  • Chili
    edited April 2019

    I can't find the Get() method in AcadApplication … Is this done another way now?

  • Bricscad.ApplicationServices.Application and Autodesk.AutoCAD.ApplicationServices.Application does not contain Get() method.

  • gile
    edited April 2019

    Here's an extension method which mimics the V19 DocumentCollection.Open() method.

            public static Document Open(this DocumentCollection docs, string path, bool readOnly = false, string passWord = null)
            {
                if (docs == null)
                    throw new ArgumentNullException("docs");
    
                dynamic acadApp = Application.AcadApplication;
                if (path == null)
                {
                    acadApp.Documents.Add();
                    return docs.MdiActiveDocument;
                }
    
                if (!System.IO.File.Exists(path))
                    throw new Teigha.Runtime.Exception(ErrorStatus.FilerError);
    
                if (!Regex.IsMatch(path, @".dwg$|.dxf$|.dwt$"))
                    throw new Teigha.Runtime.Exception(ErrorStatus.NotApplicable);
    
                acadApp.Documents.Open(path, readOnly, passWord);
                return docs.MdiActiveDocument;
            }
    
  • @gile said:
    Here's an extension method which mimics the V19 DocumentCollection.Open() method.

    The method DocumentCollection.Open() has already been implemented in V19.
    What is acadApp? Bricscad.ApplicationServices.Application does not have the property "Documents"

  • gile
    edited April 2019

    @avc said:
    The method DocumentCollection.Open() has already been implemented in V19.

    The upper extension method is to be used with versions prior to V19. It mimics the V19 DocumentCollection.Open() method behavior.

    @avc said:
    What is acadApp? Bricscad.ApplicationServices.Application does not have the property "Documents"

    acadApp is a dynamic variable which will be evaluate as an AcadApplication instance (COM API) at execution time.
    Using the dynamic type (available since Framework 4.0) allows to avoid all the Reflection stuff to use late binding and simply write:
    acadApp.Documents.Open(path, readOnly, passWord)
    instead of:
    object acadDocs = acadApp.GetType().InvokeMember("Documents", BindingFlags.GetProperty, null, acadApp, null); acadDocs.GetType().InvokeMember("Open", BindingFlags.InvokeMethod, null, acadApp, new object[3] { path, readOnly, passWord });
    or, using the extension methods shown by @Daniele Piazza
    object acadDocs = acadApp.Get("Documents", null); acadDocs.Invoke("Open", path, readOnly, passWord)