0

I have CAD library & wpf contains some combo boxes for getting the input from user.if user clicks any of the item in combo box then the Auto CAD should open ,the selected block will be get from library and inserted in Auto CAD.How can i do that?

For Example, I have a CAD Block library ,the block contains Model 1,Model 2,Model 3,Model 4. if any of the model selected in combo box then the Auto CAD should open and respected model should be selected from block library and inserted in newly opened Auto CAD file. How can i do that?

Dinesh
  • 3
  • 3

1 Answers1

0

You basically have to open AutoCAD from external C# process, which is discused here and here. I suggest you to make a singleton, that handles opening and closing of the AutoCAD process and takes care for open/insert/save/close of the documents (blocks). Hook to selectionChanged drop-down event and spawn Autocad if it is not. Further you have to call Insert() or WblockCloneObjects() methods in order to insert a block into current document.

private object SpawnCadApplication(string appProgId)
{
    var acadType = Type.GetTypeFromProgID(appProgId);
    return Activator.CreateInstance(acadType);
}

private bool ApplicationIsInstalled(string appProgId)
{
    return Type.GetTypeFromProgID(appProgId) != null;
}

private bool GetRunninApplication(string appProgId, out object cadApp)
{
    cadApp = null;
    try
    {
        cadApp = Marshal.GetActiveObject(appProgId);
    }
    catch (Exception e)
    {

    }
    return cadApp != null;
}

private void ReleaseObject(object obj)
{
    try
    {
        Marshal.FinalReleaseComObject(obj);
        obj = null;
    }
    catch (Exception ex)
    {
        obj = null;
    }
}

Once you have controll over AutoCAD, then you could make everything you want

public void OpenSaveCloseFile(string filePath)
{
    object cadApp;
    if (!GetRunninApplication(AutoCadProgId, out cadApp))
        {
            cadApp = SpawnCadApplication(AutoCadProgId);
        }
    var cadDocuments = cadApp.GetType().InvokeMember("Documents", BindingFlags.GetProperty, null, cadApp, null);

// open a file
        var openArgs = new object[2];
        openArgs[0] = filePath; // Name
        openArgs[1] = false; // ReadOnly
        var acDoc = cadDocuments.GetType().InvokeMember("Open", BindingFlags.InvokeMethod, null, cadDocuments, openArgs, null);

// save the file
        acDoc.GetType().InvokeMember("Save", BindingFlags.InvokeMethod, null, acDoc, null);

// close the file
        var closeArgs = new object[2];
        closeArgs[0] = true; //Save changes
        closeArgs[1] = filePath; // Document Name
        acDoc.GetType().InvokeMember("Close", BindingFlags.InvokeMethod, null, acDoc, closeArgs);

        ReleaseObject(acDoc);
    }

Insert block into current document should be somehting like:

var activeDocument = cadApp.GetType().InvokeMember("ActiveDocument", BindingFlags.GetProperty, null, cadApp, null);
var database = activeDocument.GetType().InvokeMember("Database", BindingFlags.GetProperty, null, activeDocument, null);
var insertArgs = new object[3];
insertArgs[0]=*Objects*;
insertArgs[1]=*Owner*;
insertArgs[2]=*IdPairs*;
database.GetType().InvokeMember("CopyObjects", BindingFlags.InvokeMethod, null, database, insertArgs, null);

However you have to figure it out how to fill the arguments array. Look at the attached puctures.

CopyObjects CloneObjects from Interop interface has to correspond to WBlockCloneObjects. WBlockCloneObjets

The cool thing is that you don't have to add any Acad libs as a reference.

Community
  • 1
  • 1
A.Kostadinov
  • 383
  • 1
  • 6
  • 18