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

Database.BeginSave Event Only Fires Intially

4 REPLIES 4
SOLVED
Reply
Message 1 of 5
VB_Autocad_guy
2271 Views, 4 Replies

Database.BeginSave Event Only Fires Intially

My Document.Database.beginsave event only fires once. 

After I try saving the file again the .beginsave event doesn't trigger. 

Why isn't the Autocad firing the .BeginSave each time I save or qsave? 

Am I using the correct event? 

 

 

Public Sub AddDocEvents()
        Try


            DocMan = AcApp.DocumentManager
            'Adds Document Created Handler
            AddHandler DocMan.DocumentCreated, AddressOf callback_documentCreated

            'Adds Document BeingSave/SaveComplete Handlers
            Dim doc As Document
            For Each doc In DocMan
                Dim db As Database = doc.Database
                AddHandler db.BeginSave, AddressOf callback_BeginSave
                AddHandler db.SaveComplete, AddressOf callback_SaveComplete

            Next
            ed.WriteMessage("<<[Register]: AddDocEvent>>" & Environment.NewLine)

        Catch ex As Exception
            ed.WriteMessage("<<[Error]: AddDocEvents>>" & Environment.NewLine)
        End Try
    End Sub

 

 Private Sub callback_documentCreated(ByVal sender As Object, ByVal e As DocumentCollectionEventArgs)
        If e.Document = Nothing Then
            Exit Sub
        End If

        'Step 1 -Add Document BeginSave & SaveComplete Handlers
        Dim db As Database = e.Document.Database
        AddHandler db.BeginSave, AddressOf callback_BeginSave
        AddHandler db.SaveComplete, AddressOf callback_SaveComplete

        'Step 2- Check for Pstyles Mode
        modAcadDoc.Fix_DWGs_Without_A_CTB_Style()
    End Sub

 

  Private Sub callback_BeginSave(ByVal sender As Object, ByVal e As DatabaseIOEventArgs)
        Dim myDwg As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
        AcApp.ShowAlertDialog("BeginSave: " + e.FileName)

        'Step 1: Update Drawing Stamp
        Dim Stamp As New clsDwgStamp
        If modRegistry.DWGSTAMP.ToString = eDWGSTAMP.StampOn Then MsgBox("STAMP ON")
        Stamp.UpdateDWGSTAMP()
    End Sub

 

4 REPLIES 4
Message 2 of 5

Hi VB_AutoCad_Guy,

 

If I had to guess, I'd say that an exception is being thrown in one of your events handlers. You don't enclose your event handler code in Try...Catch blocks - this is extremely dangerous. Any managed exception thrown by your code is getting passed back to AutoCAD - and AutoCAD's behavior when handling exceptions thrown by your code are passed across the managed/unmanaged code boundary is not defined. I'm suggesting this as a possible cause because I've seen this exact behavior before - events being disabled by unhandled exceptions.

 

Try setting your debugger to stop when an exception is thrown instead of just when its not handled and see if that's the reason. If its not, then sorry for the incorrect suggestion - but you need to add that exception handing anyway.

 

Cheers,

 

Stephen Preston

Autodesk Developer Network

Cheers,

Stephen Preston
Autodesk Developer Network
Message 3 of 5

Good Morning Stephen,

 

Thank you so much for your response. 

 

We'll I've had problems before when my Intialize Procedure had errors in it and the rest of the Autocad .NET DLL didn't load properly. This is where I learned that it needs to load cleanly. As an exception will prevent the entire dll to stop working properly.

 

Could you please expound upon how to handle some the exceptions I'm possibly dealing with? 

This is a subject I could afford to learn more about. As I'm new to VB.NET.  Or maybe a good web-site to read up more about exception handling and properly dealing with them. 

 

Can you tell me how to set my Debug Preference to Stop when there is an exception? 

 I know where the setting is in VBA... but VB.NET haven't found that setting as of yet. 

 

This is my best guess.

DEBUG OPTIONS.png

Message 4 of 5

Ah Hah!

 

We'll I've discovered the problem. 

 

I commented one line of code out which reads my registry for a startup value. 

So I've isolated the problem. 

 

' If modRegistry.DWGSTAMP.ToString = eDWGSTAMP.StampOn Then MsgBox("STAMP ON")

 

The point in my modregistry.dwgstamp function is to have a Boolean flag for User Mode versus Admin Mode. 

As Admin mode we don't want our Drawing Stamps Updated as our Admin's do batch processing of files for maintenance purposes. 

 

So Yes... I'm getting an error or exception. (What's the difference between an error and an exception?

I'm a self-taught programmer so forgive my ignorance. 

 

#Region "Imports"
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.ApplicationServices
Imports AcApp = Autodesk.AutoCAD.ApplicationServices.Application

#End Region

<Assembly: ExtensionApplication(GetType(clsEvents))> 
Public Class clsEvents
    Implements Autodesk.AutoCAD.Runtime.IExtensionApplication

    'Variables
    Private DocMan As DocumentCollection

    'Initialize sub
    ''' <summary>
    ''' Initializes Trigger -This Code runs when the .NET dll is loaded into Autocad 
    ''' </summary>
    ''' <remarks><para>This Code Intializes All Application And Document Events</para>
    ''' <para>See http://forums.autodesk.com/autodesk/attachments/autodesk/152/15076/1/VB%20-%20Ext%20App%20Monitor%20...</para>
    ''' <para>See http://through-the-interface.typepad.com/through_the_interface/2006/09/initialization_.html</para>
    ''' <para>See http://msdn.microsoft.com/en-us/library/cb6t8dtz(v=vs.80).aspxFor how to flag the Registry to Auto Load the .NET Dll into Autocad </para>
    ''' <para>SEE Autocad 2011 Activate.vbs for the Script to Run And Edit the Registry so the .NET DLL Security Permission And Flag are set properly.</para>
    ''' </remarks>
    Public Sub Initialize() Implements Autodesk.AutoCAD.Runtime.IExtensionApplication.Initialize

        'Step1 -Write Message to Acad Console Window
        ed.WriteMessage("<<[Initializing] - VB.NET:ClassAutocad2011.dll Loaded>>" & Environment.NewLine)

        'Step2 -Check to see if Autocad is Setup Already
        If Not (modRegistry.IsAcadSetup) Then
            MsgBox("Please Run the Command 'RunSetup'" & vbCrLf & _
                   "Your Autocad is NOT Setup Properly." & vbCrLf & vbCrLf & _
                   " Regards, Your Autocad Administrator")
            '    modAcadSetup.RunSetup_AC2K11()
        End If

        'Step3 -Initalize All Application Events
        AddAppEvents()

        'Step4 -Initalize All Document Events
        AddDocEvents()

        'Step5 -Add SFR Tab to the Options Dialog
        ctrlSFROptionsTab1.LoadIt()

        'Step6 -Standard Startup Variables 
        modAcadSetup.TurnFileDialogOn()

        'Step7 -Write to Access DB Signaling that Autocad is being used by this User
        modAcadSetup.UserLoggedOn()

        'Step8 -Setup Support Paths 
        modAcadSetup.SetupAcadSupportPaths()

        'Step9 -Check if SFAR_ISO_UTIL Lisp Routines need to be loaded
        If modRegistry.IsISOUTIL_ON = True Then
            Dim acInterface As New clsInterface
            acInterface.LoadIsoUtilLispRoutines()
            ed.WriteMessage("<<[Loading] Iso Lisp Routines >>" & Environment.NewLine)
        End If

        'Step10 -Write Message to Acad Console Window of Success
        ed.WriteMessage("<<[Finished Initializing] ClassAutocad2011.dll is Successful >>" & Environment.NewLine)

  
    End Sub
    'Terminate sub
    Public Sub Terminate() Implements Autodesk.AutoCAD.Runtime.IExtensionApplication.Terminate




        'RemoveAppEvents()
        'RemoveDocEvents()

    End Sub
    ''' <summary>
    '''  'Register Application Events
    ''' </summary>
    ''' <remarks>This Activates the Application Events -Such as Begin Quit</remarks>
    Public Sub AddAppEvents()

        AddHandler Application.BeginQuit, AddressOf appBeginQuit
        ed.WriteMessage("<<[Register]: AddAppEvent>>" & Environment.NewLine)

    End Sub
    ''' <summary>
    ''' Removes Applications Events Upon Closing of .NET DLL
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub RemoveAppEvents()
        'RemoveHandler Application.BeginQuit, AddressOf appBeginQuit
    End Sub
    ''' <summary>
    ''' App Event Sub Routine to Run Each Time Event is Triggered
    ''' </summary>
    ''' <param name="senderObj"></param>
    ''' <param name="sysAppBeginQuitArgs"></param>
    ''' <remarks></remarks>
    Public Sub appBeginQuit(ByVal senderObj As Object, _
                                ByVal sysAppBeginQuitArgs As System.EventArgs)

        modAcadSetup.UserLoggedOff()

    End Sub

    ''' <summary>
    ''' Add Document Events
    ''' </summary>
    ''' <remarks>This Activates the Autocad Document Events for Autocad</remarks>
    ''' 
    Public Sub AddDocEvents()

        DocMan = AcApp.DocumentManager
        'Adds Document Created Handler
        AddHandler DocMan.DocumentCreated, AddressOf callback_documentCreated

        'Adds Document BeingSave/SaveComplete Handlers
        Dim doc As Document
        For Each doc In DocMan
            Dim db As Database = doc.Database
            AddHandler db.BeginSave, AddressOf callback_BeginSave
            AddHandler db.SaveComplete, AddressOf callback_SaveComplete

        Next
        ed.WriteMessage("<<[Register]: AddDocEvent>>" & Environment.NewLine)

     
    End Sub
    Public Sub RemoveDocEvents()
        'RemoveHandler DocMan.DocumentCreated, AddressOf callback_documentCreated

    End Sub

 
    Private Sub callback_BlockInserted(ByVal Sender As Object, ByVal e As System.EventArgs)
    

    End Sub


    ''' <summary>
    '''  documentCreated handler 
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub callback_documentCreated(ByVal sender As Object, ByVal e As DocumentCollectionEventArgs)
        If e.Document = Nothing Then
            Exit Sub
        End If

        'Step 1 -Add Document BeginSave And SaveComplete Handlers
        Dim db As Database = e.Document.Database
        AddHandler db.BeginSave, AddressOf callback_BeginSave
        AddHandler db.SaveComplete, AddressOf callback_SaveComplete

        'Step 2- Check for Pstyles Mode
        modAcadDoc.Fix_DWGs_Without_A_CTB_Style()
    End Sub

    ''' <summary>
    ''' SaveBegin handler
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks>Place Code here that runs off the BeginSave Event</remarks>
    Private Sub callback_BeginSave(ByVal sender As Object, ByVal e As DatabaseIOEventArgs)
        Dim myDwg As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
        AcApp.ShowAlertDialog("BeginSave: " + e.FileName)

        'Step 1: Update Drawing Stamp
        Dim Stamp As New clsDwgStamp
 ' If modRegistry.DWGSTAMP.ToString = eDWGSTAMP.StampOn Then MsgBox("STAMP ON")
        Stamp.UpdateDWGSTAMP()
    End Sub

    ''' <summary>
    ''' SaveComplete handler
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub callback_SaveComplete(ByVal sender As Object, ByVal e As DatabaseIOEventArgs)
        Dim myDwg As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
        AcApp.ShowAlertDialog("SaveComplete: " + e.FileName)
        'myDwg.Database.Save()
    End Sub
End Class

 

  Friend Enum eDWGSTAMP      
  StampOn = 1     
  StampOff = 0   
End Enum
Public Property DWGSTAMP() As eDWGSTAMP
        Get
            Dim ThisKey As RegistryKey
            Dim sKeyValue As String
            Try
                If Registry.CurrentUser.OpenSubKey(SFRSubKey) Is Nothing Then CreateSFRSubKey()
                ThisKey = Registry.CurrentUser.OpenSubKey(SFRSubKey, True)
                sKeyValue = ThisKey.GetValue(cDWGSTAMP, Nothing)
                DWGSTAMP = sKeyValue
                debug.writeline("<<DWGSTAMP: " & sKeyValue & ">>" & Environment.NewLine)
                ThisKey.Close()
            Catch
                DWGSTAMP = ""
                debug.writeline("Error on Registry: DWGSTAMP")
            End Try
        End Get
        Set(ByVal Value As eDWGSTAMP)
            Dim ThisKey As RegistryKey
            Try
                If Registry.CurrentUser.OpenSubKey(SFRSubKey) Is Nothing Then CreateSFRSubKey()
                ThisKey = Registry.CurrentUser.OpenSubKey(SFRRodeoSubKey, True)

                Dim iInputValue As Integer
                Select Case Value
                    Case eDWGSTAMP.StampOff
                        iInputValue = 0
                        ThisKey.SetValue(cDWGSTAMP, iInputValue)
                    Case eDWGSTAMP.StampOn
                        iInputValue = 1
                        ThisKey.SetValue(cDWGSTAMP, iInputValue)
                End Select



                ThisKey.Close()
                debug.writeline("<<DWGSTAMP: " & Value & ">>" & Environment.NewLine)
            Catch
                debug.writeline("Error on Registry: DWGSTAMP ")
            End Try
        End Set
    End Property

 

Message 5 of 5

Cool. I'm glad you found the problem. Smiley Happy

 

To stop when an exception is thrown, go to the VS Debug menu, select the Exceptions... menu item (CTRL+ALT+E on my setup - I'm using a professional VS version - not sure if its there for Express). You'll see a list of exception types there with a checkbox next to each under the heading 'Thrown'. Set the checkbox for each Exception type you want to stop for as its thrown. Hint - Don't set these options until you're close to executing the piece of code you think the exception is coming from. An Exception isn't necessarily an error - its just an unusual (exceptional) event. When you start up AutoCAD, you'll probably see lots of Exceptions thrown if you look for them, but AutoCAD handles them, and moves on. Same for any significant application.

 

And always bear in mind that the AutoCAD .NET API is a thin wrapper on top of the unmanaged C++ ObjectARX API. Not catching exceptions in your event handlers is something of a special case. You'll normally get away with it if an exception isn't handled in a CommandMethod - AutoCAD will usually display an unhandled exception dialog and then allow you to continue. (Although your users probably won't be very happy if they start seeing those dialogs appearing all over the place Smiley Wink

 

I don't have any specific recommendation for an article on exception handling, but it should be covered in any good (.NET) programming book, and googling for 'exception handling' will return some useful online articles.

 

Hope this helps.

 

Cheers,

 

Stephen

 

 

 

Cheers,

Stephen Preston
Autodesk Developer Network

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