3

I have two drawings, dg1 and dg2. I have defined a block 'b1' in dg1 which I want to copy in dg2. It works well in Early Binding but giving error when I try code in late binding. The code in question is:

private void Form1_Load(object sender, EventArgs e)
        {
            AcadApplication m_oAcadApp = null;
            AcadCircle circle = null;
            AcadAcCmColor color = null;
            AcadDocument oSourceFile = null;
            AcadDocument m_oActiveDoc = null;
            try
            {
                object obj = Marshal.GetActiveObject("AutoCAD.Application.17");
                if (obj != null)
                {
                    m_oAcadApp = obj as AcadApplication;
                    m_oActiveDoc = m_oAcadApp.ActiveDocument;
                    foreach (AcadDocument oTempDoc in m_oAcadApp.Documents)
                    {
                        if((@"c:\d1.dwg").ToUpper() == oTempDoc.FullName.ToUpper())
                        {
                            Console.WriteLine(oTempDoc.FullName);
                            oSourceFile = oTempDoc;
                            break;
                        }

                    }
                    try
                    {
                        object[] objCollection = new object[1];
                        objCollection[0] = null;
                        objCollection[0] = oSourceFile.Blocks.Item("b1");
                        oSourceFile.CopyObjects(objCollection, m_oActiveDoc.Blocks);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Opening Blocks " + ex.Message);
                    }

                    /*double[] cen = new double[] { 0, 0, 0 };
                    circle = m_oAcadApp.ActiveDocument.Database.ModelSpace.AddCircle(cen, 2);
                    color = m_oAcadApp.GetInterfaceObject("Autocad.AcCmColor.17") as AcadAcCmColor;
                    color.SetRGB(150, 150, 250);
                    circle.TrueColor = color;
                    m_oAcadApp.ZoomExtents();
                     * */
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("AutoCAD not opened");
            }
            finally
            {
               // if (color != null) Marshal.FinalReleaseComObject(color);
                //if (circle != null) Marshal.FinalReleaseComObject(circle);
                if (m_oAcadApp != null) Marshal.FinalReleaseComObject(m_oAcadApp);
            }
        }

And I get exception: Invalid object array exception while I try to copy a block in other drawing.

How do I do it in late Binding?

I am using Autocad 2009.

The Objective of implement Late Binding for Autocad and copying Object

Thanks

Volatil3
  • 14,253
  • 38
  • 134
  • 263
  • you're sure oSourceFile.Blocks.Item("b1") is an actual object? – FlavorScape Sep 13 '13 at 17:56
  • it works if oSourceFile is earlyBound – Volatil3 Sep 13 '13 at 17:59
  • So oSourceFile.Blocks.Item("b1") is still null? – FlavorScape Sep 13 '13 at 18:01
  • its not null. It is of type *Object* instead of *ACadBlock* – Volatil3 Sep 13 '13 at 18:20
  • can you cast it to ACadBlock? – FlavorScape Sep 13 '13 at 18:25
  • I saw something you might make it a string? Weird, I know... – FlavorScape Sep 13 '13 at 18:27
  • @FlavorScape it was one of the tasks by my client. He had to run different AutoCad versions so wanted late binding. Every other method worked but *CopyObject* could not as it needed first parameter of type **ACADBlock**. What you are suggesting is actually early binding. – Volatil3 Sep 13 '13 at 18:39
  • so a simple (ACadBlock)dynamic does not work with implicit cast? – FlavorScape Sep 13 '13 at 19:26
  • the goal that I don't need to use any Interop will not work here and my code should be able to run with different versions of AutoCAD – Volatil3 Sep 13 '13 at 19:29
  • You might have to do dynamic tests to determine and cast to all possible autocad types – FlavorScape Sep 13 '13 at 20:53
  • @FlavorScape can you guide some resource in this regard? How do I test if block is of type **ACadBlock** while it tells of type **ComObject**? – Volatil3 Sep 14 '13 at 07:12
  • you would have to know what to test for on a normal ACadBlock, you're sort of sniffing the object by trying to copy into your own definition of ACadBlock.... You might also look into LISP helper app. – FlavorScape Sep 16 '13 at 17:25
  • I don't get you. Sniffing of Object is possible if it expose relevant methods. Since it is of type *Object* so even I assign an ACADBlock it is not going to figure it out. Can you pls explain with exmaple? – Volatil3 Sep 16 '13 at 19:13
  • Try catch on expected properties/methods. http://stackoverflow.com/questions/2985161/duck-type-testing-with-c-sharp-4-for-dynamic-objects but ultimately you need to redefine the type to cast into so that ACad does not raise exception. – FlavorScape Sep 16 '13 at 22:12
  • Will this type casting mean Early Binding? – Volatil3 Sep 17 '13 at 10:54

1 Answers1

0

You can late-bind cast to an object.

http://www.dicks-clicks.com/excel/olBinding.htm

You can use entities: http://msdn.microsoft.com/en-us/library/gg309272.aspx

or the Dynamic and cast to a similar object definition or property bag, if you will.

In Microsoft Dynamics CRM 2011 and Microsoft Dynamics CRM Online, you can use the Entity class when you work with entities. In Microsoft Dynamics CRM 4.0, you used the DynamicEntity class. When initialized, the Entity class contains the logical name of an entity and a property-bag array of the entity’s attributes. This lets you use late binding so that you can work with types such as custom entities and custom attributes that were not available when your application was compiled. Because the entity base class always contains the property bag of attributes and values, the ReturnDynamicsEntities property from Microsoft Dynamics CRM 4.0 is no longer necessary. The key difference between early and late binding involves type conversion. While early binding provides compile-time checking of all types so that no implicit casts occur, late binding checks types only when the object is created or an action is performed on the type. The Entity class requires types to be explicitly specified to prevent implicit casts.

It might look something like this then

blockCollection[0] = (ACadBlock)oSourceFile.Blocks.Item("b1");

FlavorScape
  • 13,301
  • 12
  • 75
  • 117
  • The mere act of casting (ACadBlock) requires a reference to the AutoCAD interops, therefore it's early binding and not late binding as specified in the question. I guess there is no way to call that specific function with late binding. – reckface Sep 21 '13 at 14:04