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

Set MDIACTIVEDOCUMENT not working

10 REPLIES 10
SOLVED
Reply
Message 1 of 11
andred
2111 Views, 10 Replies

Set MDIACTIVEDOCUMENT not working

Hi,

 

I have difficulties to set MDIActiveDocument. I read many post  but any is working. I create a sample program. That program open a drawing try to set it current and set a layout current. The drawing open but the MDIACTIVEDOCUMENT is always the drawing I run the program. I'm working with VS2010 and AutoCAD 2012.


Here's my class:

 

Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports System.Windows.Forms
Imports System.IO

Public Class TestDocSwitch
    <CommandMethod("TestDocSwitch", CommandFlags.Session)> _
    Public Sub TestDocSwitch()
        Dim DWGNameToOpen As String = "D:\LOGESDES\3177\H90930\3177-90930-001-01-E-LR-1.DWG"
        Dim LayoutName As String = "Model"
        OpenDrawing(DWGNameToOpen, LayoutName)


    End Sub

    Public Sub OpenDrawing(DrawingName As String, Optional LayoutName As String = "")


        Dim acDocMgr As DocumentCollection = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager
        Dim acDoc As Autodesk.AutoCAD.ApplicationServices.Document = Nothing

        If (File.Exists(DrawingName)) Then
            acDoc = acDocMgr.Open(DrawingName, False)
        Else
            acDocMgr.MdiActiveDocument.Editor.WriteMessage("File " & DrawingName & " does not exist.")
        End If

        acDocMgr.MdiActiveDocument = acDoc

        If LayoutName <> "" Then
            SetCurrentLayoutTab(LayoutName)
        End If

    End Sub
    Public Sub SetCurrentLayoutTab(ByVal LayoutName As String)
        Dim acDoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
        MessageBox.Show(acDoc.Name)
        Dim acCurDb As Database = acDoc.Database
        Using doclock As DocumentLock = acDoc.LockDocument
            Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
                Try
                    Dim acLayoutMgr As LayoutManager
                    acLayoutMgr = LayoutManager.Current
                    acLayoutMgr.CurrentLayout = LayoutName
                    acTrans.Commit()
                Catch ex As Autodesk.AutoCAD.Runtime.Exception
                    Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(ex.Message & vbCr & ex.StackTrace)
                    acTrans.Abort()
                End Try
            End Using
        End Using

    End Sub
End Class

 

In my complete program I need to obtain information about the current layout but it doesn't work because the active drawing is not the drawing I open.

 

Need help!

 

Regards,

 

André

 

10 REPLIES 10
Message 2 of 11
mleslie00
in reply to: andred

My goodness! We are beating our heads on the same wall simultaneously! (Posted one minute apart)

http://forums.autodesk.com/t5/NET/Cannot-set-MdiActiveDocument/td-p/4377495
Message 3 of 11
andred
in reply to: andred

Thank you,

 

I read your post and it is not a problem only with 2013.

 

Regards,

 

André

Message 4 of 11
Hallex
in reply to: andred

Tested yor code in 2014

Solution (on my end):

to avoid this error

//Error 1 ... 'TestDocSwitch': member names cannot be the same as their enclosing type //

Rename

Public Sub TestDocSwitch  on

Public Sub TestDocSwitchCommand

Also I've added refrerence to accoremgd.dll (copy local=false)

Let us know if this work on your release

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 5 of 11
andred
in reply to: andred

Thank you for your reply Hallex,

 

It is not necessary to rename the command. The name can be the same (I use it all the time). The command is running, the only problem is Mdiactivedocument is not change. You can notice the MessageBox in the SetCurrentLayoutTab sub, it display the name of the first drawing, not the last drawing open.

 

Also the reference to accoremgd.dll is required only from 2013 release, not 2012.

 

Regards,

 

André

 

Message 6 of 11
Hallex
in reply to: andred

Then take a look at your code
In the code snip the class and sub have identical name
TestDocSwitch, try rename frist or second one no matters
_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 7 of 11
andred
in reply to: andred

Thank you Hallex,

 

It doesn't change anything but I found my problem. When you debug with VS2010 and AutoCAD 2012 sometimes you have to set NEXTFIBERWORLD variable to 0. I don't know why exactly but it works. Usually I debug my app with this variable set to 0. I changed it to 1 (normal mode) and you have to restart AutoCAD to apply the changes. Voilà! my messagebox show the last open document name (not the first one). I will try it in my main application to be sure it is working well.

 

Maybe with AutoCAD 2013/2014 you don't have to set this variable. It was not necessary when I develop application for AutoCAD 2010 (VS2008).

 

Best regards,

 

André

 

Message 8 of 11
andred
in reply to: andred

I confirm, set NEXTFIBERWORLD to 1 (default value) solve my problem in my main application.

 

Regards,

 

André

 

Message 9 of 11
Hallex
in reply to: andred

Or without nextfiberword, try this code, tested from A2010 to 2014

it works everywhere:

    Public Class TestDocSwitch

       
        Public is_template As Boolean = True

        <CommandMethod("ts", CommandFlags.Session)> _
        Public Sub testNewDocOpen()
            Dim docs As DocumentCollection = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager
            Dim doc As Document = docs.MdiActiveDocument
            Dim ed As Editor = Nothing
            ''System.Windows.Forms.MessageBox.Show(Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Name)

            ' possible using examples:
            ' is_template = true;
            ' OpenDocCallback("acad.dwt");// <-- or acadiso.dwt

            ' Or
            is_template = False

            OpenDocCallback("C:\Test\WorkingDrawing.dwg") ' <-- your file name here

            docs.MdiActiveDocument = docs.MdiActiveDocument

            Dim newdoc As Document = docs.MdiActiveDocument

            ed = newdoc.Editor

            Using doclock As DocumentLock = newdoc.LockDocument()

                docs.MdiActiveDocument = newdoc

                Dim newdb As Database = HostApplicationServices.WorkingDatabase

                Using tr As Transaction = newdb.TransactionManager.StartTransaction()

                    Dim lmr As LayoutManager = LayoutManager.Current

                    Try
                        Dim layout As Layout = Nothing
                        Try
                            layout = DirectCast(tr.GetObject(lmr.GetLayoutId("Blocks"), OpenMode.ForRead), Layout) ' <-- your layout name here

                        Catch exl As Autodesk.AutoCAD.Runtime.Exception

                            ed.WriteMessage("Error on swith to Layout: {0}" & vbLf & "{1}" & vbLf, "Blocks", exl.Message)

                        End Try

                        LayoutManager.Current.CurrentLayout = layout.LayoutName

                        tr.Commit()

                    Catch ex As Autodesk.AutoCAD.Runtime.Exception

                        ed.WriteMessage((vbLf + ex.Message & vbLf) + ex.StackTrace & vbLf)

                    Finally
                        ed.WriteMessage(vbLf + "I hope you're satisfied with the result." + vbLf)
                    End Try
                End Using
            End Using
        End Sub
        Public Sub OpenDocCallback(Data As Object)
            ' Open the document here, whose name was passed in
            ' the Data parameter
            Dim docs As DocumentCollection = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager
            If is_template Then
                docs.Add(Data.ToString())
            Else
                docs.Open(Data.ToString(), False, "")
                ' documents is already open and activated, pass your utility here:
                'Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.RunCommand("my cool command, etc");//2014

            End If
        End Sub
End Class

Change a drawing name and layout name in the code,

Cheers

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 10 of 11
andred
in reply to: andred

Thank you Hallex for your code.

 

It is working well but it does work differently depending of NEXTFIBERWORLD setting. When set to 0, the MIDACTIVEDOCUMENT is not set to the new open document. In your code, you use "newdb" pointing to the database of the just open drawing to get information about layouts.

 

...

            MessageBox.Show(docs.MdiActiveDocument.Name)
            Dim newdb As Database = HostApplicationServices.WorkingDatabase
            MessageBox.Show(newdb.Filename)
...


NEXTFIBERWORLD=1: The message boxes displays the same drawing name

NEXTFIBERWORLD=0: The first message box displays "Drawing1" (or the name of the current drawing).

 

So each time I have to get information about this drawing I have to set a database variable, not use the current one. This is a litte bit annoying because I have to pay attention at this each time I want to access current document information. But it is a good workaround.

 

Thanks a lot!

 

André

 

Message 11 of 11
dimitrie.vatra
in reply to: andred

This workaround is going to solve it:

void SetActiveDocumentAndDoSomethingWithItWhenUpdated()
{
    Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.DocumentActivated += DrawingActivated;
    Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument = myDocument;
}

private void DrawingActivated(object sender, EventArgs e)
{
    //here Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument == myDocument. Do anything you want with it here
    Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.DocumentActivated -= DrawingActivated;
}

You basically subscribe to the event of document changes, and only when the event comes later on (before Application.Idle it will come), only then you MdiActiveDocument has been changed 

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