.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Export to WMF without using Interop

9 REPLIES 9
SOLVED
Reply
Message 1 of 10
karea
1792 Views, 9 Replies

Export to WMF without using Interop

Hi:

I would like to export a DWG file to WMF. I've read in the forum I need to add Autodesk.Autocad.interop.dll and Autodesk.Autocad.interop.common.dll, but with these references the interface displays too many duplicate definitions.

How can I do without using Interop references?

 

thanks,

 

9 REPLIES 9
Message 2 of 10
_gile
in reply to: karea

Hi,

 

You can use the 'dynamic' type (Framwork4 / A2012+) or late binding with reflection with prior versions.

The main inconvenient is that you won't have help from Visual Studio at editing and compiling time (intellisense). If there's an error in the code (i.e. a typo in a method or property or a bad argument type) the exception will raise at runnig time.

 

To avoid writing every time: "GetType().InvokeMember("membername", blah blah blah )" with late binding, you can use some extension methods which make the code more legible, there're many examples, here's one:

 

using BF = System.Reflection.BindingFlags;

namespace LateBindingHelpers
{
    public static class LateBinding
    {
        public static object GetInstance(string appName)
        {
            return System.Runtime.InteropServices.Marshal.GetActiveObject(appName);
        }

        public static object CreateInstance(string appName)
        {
            return System.Activator.CreateInstance(System.Type.GetTypeFromProgID(appName));
        }

        public static object GetOrCreateInstance(string appName)
        {
            try { return GetInstance(appName); }
            catch { return CreateInstance(appName); }
        }

public static void ReleaseInstance(this object obj)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
} public static object Get(this object obj, string propName, params object[] parameter) { return obj.GetType().InvokeMember(propName, BF.GetProperty, null, obj, parameter); } public static void Set(this object obj, string propName, params object[] parameter) { obj.GetType().InvokeMember(propName, BF.SetProperty, null, obj, parameter); } public static object Invoke(this object obj, string methName, params object[] parameter) { return obj.GetType().InvokeMember(methName, BF.InvokeMethod, null, obj, parameter); } } }

 

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 10
karea
in reply to: _gile

than you Gille,

I'm working with VB.NET but I will try to translete the code to VB.NET.

Now, I would like to export the drawing to WMF but I'm not able to use the export command,..

 

 

Message 4 of 10
_gile
in reply to: _gile

Using examples.

 

With late binding extension methods

        [CommandMethod("ExportWmf", CommandFlags.Modal)]
        public void ExportWmf()
        {
            Document doc = AcAp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            PromptSelectionResult psr = ed.GetSelection();
            if (psr.Status != PromptStatus.OK)
                return;

            object acadDoc = doc.AcadDocument; // replace with doc.Getacaddocument() for A2013+
            object selSet = acadDoc.Get("ActiveSelectionSet");
            acadDoc.Invoke(
                "Export",
                System.IO.Path.ChangeExtension(db.Filename, "wmf"),
                "wmf",
                selSet);
            selSet.Invoke("Delete");
        }

 

With dynamic type

        [CommandMethod("ExportWmf", CommandFlags.Modal)]
        public void ExportWmf()
        {
            Document doc = AcAp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            PromptSelectionResult psr = ed.GetSelection();
            if (psr.Status != PromptStatus.OK)
                return;

            dynamic acadDoc = doc.AcadDocument; // replace with doc.Getacaddocument() for A2013+
            dynamic selSet = acadDoc.ActiveSelectionSet;
            acadDoc.Export(
                System.IO.Path.ChangeExtension(db.Filename, "wmf"),
                "wmf",
                selSet);
            selSet.Delete();
        }

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 5 of 10
_gile
in reply to: karea

Sorry,

VB.net doesn't allow  using extension methods with the Object type. But, if you set the Strict option to Off (default), VB.net uses implicitly late binding for the Object type.

So, you can write your code as if you referenced AutoCAD.Interop with replacing interop types with Object.

 

        <CommandMethod("ExportWmf")> _
        Public Sub ExportWmf()
            Dim doc As Document = AcApp.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor

            Dim psr As PromptSelectionResult = ed.GetSelection()
            If psr.Status <> PromptStatus.OK Then
                Return
            End If
' replace with doc.GetAcadDocument() for A2013+ Dim acadDoc As Object = doc.AcadDocument Dim selSet As Object = acadDoc.ActiveSelectionSet acadDoc.Export( _ System.IO.Path.ChangeExtension(db.Filename, "wmf"), _ "wmf", _ selSet) selSet.Delete() End Sub

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 6 of 10
karea
in reply to: karea

hi,

 

The code you send is ok to use like command in a single drawing but I would like to use in batch process and when I execute the code appears "InvalidCastException" and it no runs.

 

thanks for your answer!,

 

Message 7 of 10
_gile
in reply to: karea

For a batch process, as you need to open the drawing in the editor for a selection, you cannot use Database.ReadDwgFile() method.

 

Here's a quick and dirty (no error handling) which shows a way to open each selected dwg into the current session.

 

        <CommandMethod("ExportWmf", CommandFlags.Session)> _
        Public Sub ExportWmf()
            Dim docMan As DocumentCollection = AcApp.DocumentManager
            Dim fileDlg As OpenFileDialog = New OpenFileDialog()
            fileDlg.Filter = "Drawing (*.dwg)|*.dwg"
            fileDlg.Multiselect = True
            If fileDlg.ShowDialog = DialogResult.OK Then
                For Each filename As String In fileDlg.FileNames
                    Dim doc As Document = docMan.Open(filename)
                    ExportDocument(doc, filename)
                    doc.CloseAndDiscard()
                Next
            End If


        End Sub

        Private Sub ExportDocument(ByVal doc As Document, ByRef filename As String)
            Using doc.LockDocument()
                Dim db As Database = doc.Database
                Dim ed As Editor = doc.Editor
                Dim acad As Object = AcApp.AcadApplication
                Dim acadDoc As Object = doc.AcadDocument

                db.TileMode = True
                acad.ZoomExtents()

                Dim psr As PromptSelectionResult = ed.SelectAll()
                If psr.Status <> PromptStatus.OK Then
                    Return
                End If
                Dim selSet As Object = acadDoc.ActiveSelectionSet
                acadDoc.Export( _
                    Path.Combine(Path.GetDirectoryName(filename), Path.GetFileNameWithoutExtension(filename)), _
                    "wmf", _
                    selSet)
                selSet.Delete()
            End Using
        End Sub

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 8 of 10
karea
in reply to: karea

When I was trying the code , two errors have appeared:

 

+ With  Dim acadDoc As Object = doc.AcadDocument :  'AcadDocument' is not a member of 'Autodesk.AutoCAD.ApplicationServices.Document'

 

+ Dim psr As PromptSelectionResult = ed.SelectAll() : Error eNotApplicable.

If I execute Dim psr As PromptSelectionResult = Application.DocumentManager.MdiActiveDocument.editor.SelectAll() the sentece runs.

 

 

Message 9 of 10
_gile
in reply to: karea


karea a écrit :

When I was trying the code , two errors have appeared:

 

+ With  Dim acadDoc As Object = doc.AcadDocument :  'AcadDocument' is not a member of 'Autodesk.AutoCAD.ApplicationServices.Document'

 

+ Dim psr As PromptSelectionResult = ed.SelectAll() : Error eNotApplicable.

If I execute Dim psr As PromptSelectionResult = Application.DocumentManager.MdiActiveDocument.editor.SelectAll() the sentece runs.

 

 


With AutoCAD 2013 (and 2014) the Document.AcadDocument property have been replaced by the DocumentExtension.GetAcadDocument() method.

This code seems to work for me (A2014).

 

        <CommandMethod("ExportWmf", CommandFlags.Session)> _
        Public Sub ExportWmf()
            Dim docMan As DocumentCollection = AcApp.DocumentManager
            Dim fileDlg As OpenFileDialog = New OpenFileDialog()
            fileDlg.Filter = "Drawing (*.dwg)|*.dwg"
            fileDlg.Multiselect = True
            If fileDlg.ShowDialog = DialogResult.OK Then
                For Each filename As String In fileDlg.FileNames
                    Dim doc As Document = docMan.Open(filename, True)
                    Dim name As String = Path.Combine( _
                        Path.GetDirectoryName(filename), _
                        Path.GetFileNameWithoutExtension(filename))
                    Using doc.LockDocument()
                        Dim db As Database = doc.Database
                        Dim ed As Editor = doc.Editor
                        Dim acad As Object = AcApp.AcadApplication
                        Dim acadDoc As Object = doc.GetAcadDocument()

                        db.TileMode = True
                        acad.ZoomExtents()

                        Dim psr As PromptSelectionResult = ed.SelectAll()
                        If psr.Status <> PromptStatus.OK Then
                            Return
                        End If
                        Dim selSet As Object = acadDoc.ActiveSelectionSet
                        acadDoc.Export(name, "wmf", selSet)
                        selSet.Delete()
                    End Using
                    doc.CloseAndDiscard()
                Next
            End If
        End Sub

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 10 of 10
karea
in reply to: _gile

great!  it runs!

 

The code has a little problem with this sentence:

Dim psr As PromptSelectionResult = ed.SelectAll()

Because it appears an error 'eNotApplicable'

 

Instead of this I put:

Dim psr As PromptSelectionResult = Application.DocumentManager.MdiActiveDocument.Editor.SelectAll()

and it's ok,

 

thanks,

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost