.NET

Reply
Contributor
karea
Posts: 25
Registered: ‎01-27-2011
Message 1 of 10 (607 Views)
Accepted Solution

Export to WMF without using Interop

607 Views, 9 Replies
07-01-2013 01:24 AM

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,

 


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

 

*Expert Elite*
_gile
Posts: 2,090
Registered: ‎04-29-2006
Message 2 of 10 (600 Views)

Re : Export to WMF without using Interop

07-01-2013 02:06 AM 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
Contributor
karea
Posts: 25
Registered: ‎01-27-2011
Message 3 of 10 (588 Views)

Re : Export to WMF without using Interop

07-01-2013 02:54 AM 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,..

 

 

*Expert Elite*
_gile
Posts: 2,090
Registered: ‎04-29-2006
Message 4 of 10 (582 Views)

Re : Export to WMF without using Interop

07-01-2013 03:06 AM 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
*Expert Elite*
_gile
Posts: 2,090
Registered: ‎04-29-2006
Message 5 of 10 (579 Views)

Re : Export to WMF without using Interop

07-01-2013 03:23 AM 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
Contributor
karea
Posts: 25
Registered: ‎01-27-2011
Message 6 of 10 (557 Views)

Re: Export to WMF without using Interop

07-01-2013 07:27 AM 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!,

 

*Expert Elite*
_gile
Posts: 2,090
Registered: ‎04-29-2006
Message 7 of 10 (541 Views)

Re: Export to WMF without using Interop

07-01-2013 10:42 AM 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
Contributor
karea
Posts: 25
Registered: ‎01-27-2011
Message 8 of 10 (500 Views)

Re: Export to WMF without using Interop

07-02-2013 02:05 AM 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.

 

 

*Expert Elite*
_gile
Posts: 2,090
Registered: ‎04-29-2006
Message 9 of 10 (475 Views)

Re: Export to WMF without using Interop

07-02-2013 07:41 AM 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
Contributor
karea
Posts: 25
Registered: ‎01-27-2011
Message 10 of 10 (468 Views)

Re: Export to WMF without using Interop

07-02-2013 08:55 AM 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,

 

Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.