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

Palette Set Crashes AutoCAD at Close

5 REPLIES 5
Reply
Message 1 of 6
JamieVJohnson2
1629 Views, 5 Replies

Palette Set Crashes AutoCAD at Close

I haven't been in programming for AutoCAD in a while, and I have created a new Palette Set and have set it up to work around AutoCAD's intricacies, but I can't seem to stop the crash when closing Autocad error. (harmless to the user at that time, but very annoying).  Here is my Palette Set activation and maintenance code:

Imports System.Windows.Forms
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.Windows
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.DatabaseServices.Filters
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports System.Drawing
Imports System.Windows.Forms.Integration
Imports AApplication = Autodesk.AutoCAD.ApplicationServices.Application

Public Class TTSPaletteSet
    Implements Autodesk.AutoCAD.Runtime.IExtensionApplication

    Public Sub Initialize() Implements Autodesk.AutoCAD.Runtime.IExtensionApplication.Initialize
        AddHandler AApplication.DocumentManager.DocumentToBeDeactivated, AddressOf DocToBeDeactivated
        AddHandler AApplication.DocumentManager.DocumentToBeActivated, AddressOf DocToBeActivated
        AddHandler AApplication.DocumentManager.DocumentDestroyed, AddressOf DocDestroyed
        AddHandler AApplication.DocumentManager.DocumentCreated, AddressOf DocCreated
    End Sub

    Public Sub Terminate() Implements Autodesk.AutoCAD.Runtime.IExtensionApplication.Terminate
        palSet.Dispose()
    End Sub

    Friend Shared WithEvents palSet As PaletteSet = Nothing
    Friend Shared WithEvents palCG As Palette = Nothing
    Friend Shared WithEvents ucCG As uctlCG = Nothing
    Friend Shared WithEvents mDoc As Autodesk.AutoCAD.ApplicationServices.Document
    Private Shared booActive As Boolean = False
    Private Shared booProcessStateChange As Boolean = True

    Public Shared Function doc() As Autodesk.AutoCAD.ApplicationServices.Document
        If mDoc Is Nothing Then
            mDoc = AApplication.DocumentManager.MdiActiveDocument
        End If
        Return mDoc
    End Function

    <CommandMethod("TTS")> _
    Public Shared Sub BuildPalette()
        Try
            booActive = True
            If palSet Is Nothing Then
                ' Create the palette set
                Dim guid As New Guid(TTSPaletteGUID)
                palSet = New PaletteSet("TTS Tools", guid)
                palSet.Size = New Size(300, 600)
                palSet.DockEnabled = DirectCast(CInt(DockSides.Left) + CInt(DockSides.Right), DockSides)
            End If
            ShowCGPalette()
        Catch ex As System.Exception
            MsgBox(ex.ToString)
        End Try
    End Sub

    Public Shared Sub ShowCGPalette()
        If palSet IsNot Nothing Then
            If palCG Is Nothing Then
                ucCG = New uctlCG
                Dim host As New ElementHost
                host.AutoSize = True
                host.Dock = DockStyle.Fill
                host.Child = ucCG
                palCG = palSet.Add("CG Calculator", host)
            End If
        End If
        palSet.KeepFocus = True
        palSet.Visible = True
    End Sub

    Private Shared Sub palSet_PaletteActivated(sender As Object, e As Autodesk.AutoCAD.Windows.PaletteActivatedEventArgs) Handles palSet.PaletteActivated
        'MsgBox("PaletteSetActivated")
    End Sub

    Private Shared Sub palSet_PaletteSetDestroy(sender As Object, e As System.EventArgs) Handles palSet.PaletteSetDestroy
        ' MsgBox("PaletteSetDestroyed")
        If Not palSet Is Nothing Then
            booProcessStateChange = False
            palSet.Visible = False
            booProcessStateChange = True
            mDoc = Nothing
        End If
    End Sub

    Public Sub DocToBeDeactivated(sender As Object, e As DocumentCollectionEventArgs)
        'get current count of documents
        If AApplication.DocumentManager.Count = 1 Then
            'last document open, going to go to 0 document state
            If Not palSet Is Nothing Then
                mDoc = Nothing
                booActive = False
                booProcessStateChange = False
                palSet.Visible = False
                booProcessStateChange = True
            End If
        End If
    End Sub

    Public Sub DocToBeActivated(sender As Object, e As DocumentCollectionEventArgs)
        mDoc = e.Document
    End Sub

    Public Sub DocDestroyed(sender As Object, e As DocumentDestroyedEventArgs)
        If AApplication.DocumentManager.Count = 1 Then
            'last document open, going to go to 0 document state
            If Not palSet Is Nothing Then
                mDoc = Nothing
                booProcessStateChange = False
                palSet.Visible = False
                booProcessStateChange = True
            End If
        End If
    End Sub

    Public Sub DocCreated(sender As Object, e As DocumentCollectionEventArgs)
        mDoc = e.Document
        If palSet IsNot Nothing AndAlso palSet.IsDisposed = False Then
            If booActive = True Then
                booProcessStateChange = False
                palSet.Visible = True
                booProcessStateChange = True
            End If
        End If
    End Sub

    Private Shared Sub palSet_StateChanged(sender As Object, e As Autodesk.AutoCAD.Windows.PaletteSetStateEventArgs) Handles palSet.StateChanged
        If booProcessStateChange = True Then
            If e.NewState = StateEventIndex.Hide Then
                booActive = False
            End If
        End If
    End Sub
End Class

Thank you,

 

jvj

jvj
5 REPLIES 5
Message 2 of 6

You are using Aad 2013, aren't you (because there is not PaletteSetDestroy event with my 2012 or older Acad)?

 

Probably you already know: once a Paletteset is instanciated in AutoCAD, it cannot be destroyed by code, it can be only visible or invisible

 

I'd go from firstly trying to remove code from IExtensionApplicayion.Terminate(). Have you tried to start Acad, NETLOAD you DLL, and then WITHOUT RUN YOUR COMMAND (so, the paletteSet is not instanciated), close Acad right away? In this case, the code palSet.Dispose() would be illegal, because palSet has not be set (Nothing) can cannot be called for disposing. OTH, there is really no need to dispose it: AutoCAD is shutting down, everything is AutoCAD is gone anyway.

 

Unless, your override PaletteSet's Dispose() method to properly dispose some other resources used in controls added to the PaletteSet. If it is this case, make sure your overriding Dispose() does not try to dispose some AutoCAD stuff, because at the stage of Terminate(), most AutoCAD stuff has already gone. In this case, you should do

 

If palSet IsNot Nothing Then palSet.Dispose()

 

But from your code, it seems you did not subclass the PaletteSet. But I'd still try to remove code in Terminate() first.

 

Then, you can try to remove code in PaletteSetDestroy event handler. Again, there is no need for the code as yours to set some status flags - by the time the PaletteSet is to be destroyed, AutoCAD has been in its way of shutting down without chance turning back and most Acad stuff is not reachable. Why you need to set status flags then?

 

.

Message 3 of 6

--------------------------- Exception in c:\program files\autodesk\applicationplugins\sbd.bundle\contents\aalsbin\acadaliasapp.arx ARX Command --------------------------- Unhandled Exception F0F312DC (Access Violation Reading 0xffffffff) at address FA10582Fh --------------------------- OK   ---------------------------

 

Perhaps I'm barking up the wrong tree?  this is the crash I'm getting regularly.  This will happen even if I don't activate my palette, just open AutoCAD and Close.

 

jvj

jvj
Message 4 of 6

Infact, that crash happend, then the stop in my code for terminate took place.  They are definitely un-related issues.  But since we are on the topic of Palette Set's, you mentioned that I was not inheriting the Palette Set in my code (wrapping the object).  Now I'm curious as to your best practice on working with a Palette Set in 2013.  I am making a single Palette Set with multiple palettes for each company tool I write.

 

Thanks,

 

jvj

jvj
Message 5 of 6

PaletteSet was sealed class (not inheritable) before Acad 2009. I'd prefer to derive my PaletteSet:

 

public class MyPaletteSet : Autodesk.AutoCAD.Windows.PaletteSet

{

    public/private Windows.Forms.Control[] palettes;

 

    public MyPaletteSet([name]):base([name],[guid])

    {

         //initialize the paletteSet

    }

}

 

Then you can add method to clean up, if necessary. and of course you'd likely override Dispose() method of the raw PaletteSet

 

With derived PaleteeSet, the code is much cleaner. However, deriving it or not, it does not directly solve your issue. Since you use WPF user control as palette and hosted in PaletteSet with ElementHost, I suspect if it is the a possible cause.

 

As I said previously, your PaletteSet.Dispose in terminate() method was problemetic, because the PaletteSet could well be null, if user did not show the PaletteSet during the Acad session, thus the Dispose() call would fail.

 

If you could try to create the equivalent palette(s) with Windows.Form user controls and see if your code still crash Acad the same way?

 

Also, what version of ACAD you use?

 

I also have some .NET code on Acad Map .NET API, which causes seriuos fatal error when AutoCAD closes, harmless but annoying. I also could not find out the reason for many years with acad Map 2006/7/8/9. But is is not PaletteSet. I was so fed up with it and almost decided to rewrite the app in completely different way, just to show user that I can get rid of it. And then when I got acad Map 2012, the Acad closing fatal error is completely gone. I am trying to say is that sometimes, this type of fatal error may not be all our fault.

 

But again, I'd alway derive my custom PaletteSet instead of just instatiate a raw PaletteSet and use it in my command method class.

Message 6 of 6

I'll have to give that derived palette set a try, because I too like that idea.  When I get something up, I.ll let you know what I created.  It may be a while though.  I would also like to try the windows form's difference.  Before this job, my palettes were based on windows forms contols.  BTW I am using AutoCAD 2013 (Mechanical, as part of the Product Design Suite 2013 Premium).  Thank you for your help, I'll reply to this post when I have rewritten it.

 

Later,

 

jvj

jvj

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