.NET

Reply
Valued Contributor
mindofcat
Posts: 55
Registered: ‎05-14-2012
Message 1 of 29 (1,406 Views)
Accepted Solution

How to capture double click event in AutoCAD using VB.NET

1406 Views, 28 Replies
11-26-2012 06:16 PM

Hi all,

 

I`m still trying to find a solution to my previous post, displaying a vb.net form when an autocad block reference is double-clicked. Unfortunately, I still don`t know how to capture the double-click event for a block reference from code. I have gone down the IMessageFilter path, still no success.

 

I have tried the addHandler for application using code supplied to me in my previous post, still no luck. I really need to be able to capture the doubleclick event for a block reference in autocad, without overwriting the default autocad double-click behavior.

 

I wish to be able to double-click a block reference, capture its name, and, if the name is same as blocks created by my form, then I`d simply have my dot net form pop up, displaying a few of the block`s properties.

 

Does anyone have any ideas on how this might be accomplishedÉ

 

Below is the code module I am using, which isn`t working ofr me:

 

' System
Imports Microsoft.Win32
Imports System.Reflection

 

' AutoCAD
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.Runtime
Imports acApp = Autodesk.AutoCAD.ApplicationServices.Application
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput

 

' AutoCAD Interop
Imports acOp = Autodesk.AutoCAD.Interop
Imports acOpCom = Autodesk.AutoCAD.Interop.Common

 

Module ModDoubleClick


Private acDoc As acOp.AcadDocument
Private handlerAdded As Boolean = False

 

Public Sub eventDoubleClick()
    Try
        If handlerAdded = False Then
            acApp.SetSystemVariable("DBLCLKEDIT", 0)
            If acDoc Is Nothing Then
                acDoc = CType(acApp.DocumentManager.MdiActiveDocument.AcadDocument, _
                Autodesk.AutoCAD.Interop.AcadDocument)
                AddHandler acDoc.BeginDoubleClick, AddressOf callback_DoubleClick
            End If
            handlerAdded = True
        End If

    Catch ex As Autodesk.AutoCAD.Runtime.Exception
        MsgBox(ex.Message, MsgBoxStyle.Critical)

    Finally
        acApp.SetSystemVariable("DBLCLKEDIT", 1)
    End Try
End Sub

 

Private Sub callback_DoubleClick(ByVal PickPoint As Object)
    Dim activeDoc As Document = acApp.DocumentManager.MdiActiveDocument
    Dim prmtSel As PromptSelectionResult = activeDoc.Editor.GetSelection()

 

    Using docLock As DocumentLock = activeDoc.LockDocument()
        If prmtSel.Status <> PromptStatus.OK Then Return
        If prmtSel.Value.Count <> 1 Then Return

 

        Dim id As Autodesk.AutoCAD.DatabaseServices.ObjectId = _
        prmtSel.Value(0).ObjectId

 

        Using acTrans As Autodesk.AutoCAD.DatabaseServices.Transaction = _
        activeDoc.TransactionManager.StartTransaction()

            Dim dbObj As Autodesk.AutoCAD.DatabaseServices.DBObject = _
            acTrans.GetObject(id, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)

 

            Dim ent As Autodesk.AutoCAD.DatabaseServices.Entity = _
            TryCast(dbObj, Autodesk.AutoCAD.DatabaseServices.Entity)

            If ent Is Nothing Then
                Return
            Else
                Dim blockRef As Autodesk.AutoCAD.DatabaseServices.BlockReference = _
                TryCast(ent, Autodesk.AutoCAD.DatabaseServices.BlockReference)

                If blockRef Is Nothing Then
                    Return
                Else
                    activeDoc.Editor.WriteMessage(blockRef.Name)
                End If
            End If
            acTrans.Commit()

        End Using

    End Using

End Sub

 

End Module

 

 

And the Commands class, from which my vb.net form is generated, as well as where the ModDoubleClick.eventDoubleClick() method is called:

 

 

Public Class Commands


    ' Component for displaying the Mass Straight Conveyor form

    <CommandMethod("mst")> _
    Public Shared Sub massStraight()

        Try
            ' Call this to override default block dblclk event handler
            ModDoubleClick.eventDoubleClick()

 

            ' Display the mass straight form
            Dim cForm As New frmMassStraight
            acApp.ShowModalDialog(cForm)

 

        Catch ex As Autodesk.AutoCAD.Runtime.Exception
            MsgBox(ex.Message, MsgBoxStyle.Critical)
        End Try

    End Sub

 

End Class

 

 

Any help is greatly appreciated!

 

Many thanks...

 

Cat

Distinguished Contributor
ACADuser
Posts: 1,191
Registered: ‎12-22-2003
Message 2 of 29 (1,380 Views)

Re: How to capture double click event in AutoCAD using VB.NET

11-27-2012 06:58 AM in reply to: mindofcat

See if this might help;

 

http://www.theswamp.org/index.php?topic=40021.0

ACADuser
Dell Precision T5500 Workstation
Windows 7 Enterprise
Dual Quad Core Intel Xeon Processors E5540 2.53GHz,8M L3,5.8GT/s,turbo
12GB RAM
1.5GB NVIDIA Quadro FX 4800
DUAL 27" Dell UltraSharp U2713HM
Valued Contributor
sszabo
Posts: 86
Registered: ‎09-05-2012
Message 3 of 29 (1,374 Views)

Re: How to capture double click event in AutoCAD using VB.NET

11-27-2012 07:30 AM in reply to: mindofcat

This code seems to be working OK for me as far as capturing the event.  You are creating and displaying the form at the wrong place however.  I think these 2 lines of code shouldn't be part of your command that's setting up the handler:

 

            Dim cForm As New frmMassStraight
            acApp.ShowModalDialog(cForm)

 

but instead have to be called before your callback returns.  If you try to run this but you double click on something other than a block reference you might Return prematurely.  I would suggest you print out the Type of your entity just to be sure you are double clicking on the right entity before you return:

 

ed.WriteMessage(vbLf & "Type:        " + ent.GetType().ToString())

 

You should see:

 

Type:        Autodesk.AutoCAD.DatabaseServices.BlockReference

 

as opposed to something like this:

 

Type:        Autodesk.AutoCAD.DatabaseServices.Solid3d

 

or something else.  Hope this helps

Valued Mentor
jeff
Posts: 322
Registered: ‎05-12-2009
Message 4 of 29 (1,364 Views)

Re: How to capture double click event in AutoCAD using VB.NET

11-27-2012 08:31 AM in reply to: sszabo
Valued Contributor
mindofcat
Posts: 55
Registered: ‎05-14-2012
Message 5 of 29 (1,348 Views)

Re: How to capture double click event in AutoCAD using VB.NET

11-27-2012 12:14 PM in reply to: ACADuser

Thanks... the article shows me a code structure that is quite similar to the one I already have. My code should work, but it isn't, I am not seeing the desired result, and I'm guessing this is probably as a result of HOW I'm calling its command.

 

This whole thing is so confusing. I even seperated the doubleclick module into its own calling command (complete with usepickset), so that I could draw a block, then execute the doubleclick command, and then double-click on the block to see if anything happens... nothing. Just the same ol' AutoCAD attributes editor.


Really frustrating!

Valued Contributor
mindofcat
Posts: 55
Registered: ‎05-14-2012
Message 6 of 29 (1,345 Views)

Re: How to capture double click event in AutoCAD using VB.NET

11-27-2012 12:20 PM in reply to: jeff

And as well, I have also been to http://adndevblog.typepad.com/autocad/2012/09/displaying-entity-details-on-double-click.html many days ago; I translated the code to dot net, and executed it. When I go to AutoCAD and type cui in the command to pull up the cui editor, I see that my new double click action has been created alright, but I still don't know how to attach it to block references, or how to modify the macro string to open my vb.net form.

 

The macro string in the article runs thus:

 

C^C^myForm

 

How does this get modified to pop up a vb.net form named frmMassStraight which I would normally open using application.showModalDialog(formInstance)

 

Thanks all, for your help, but I'm still floundering in the dark, trying so hard to see the light which I know exists at the end of this dark tunnel...

Valued Contributor
mindofcat
Posts: 55
Registered: ‎05-14-2012
Message 7 of 29 (1,341 Views)

Re: How to capture double click event in AutoCAD using VB.NET

11-27-2012 12:27 PM in reply to: mindofcat

Does anyone know of any professional AutoCAD VB.NET Customization Consultants whom I can pay for their time in order to discuss this doubleclick action problem on the phone or via email, in the hope of finding a feasible solution?

 

Many thanks in advance...

 

Cat

Valued Contributor
sszabo
Posts: 86
Registered: ‎09-05-2012
Message 8 of 29 (1,338 Views)

Re: How to capture double click event in AutoCAD using VB.NET

11-27-2012 12:35 PM in reply to: mindofcat

I am not sure I understand what is the problem.. Your code works perfectly with minor changes. 

 

I replaced your cForm with one that has a textbox1 that displays all the properties of the objects you double click.  It should help you identify/discover any issues.  Alll you should have to do is add a winform to your project and drag a textbox1 on it:

 

 Keep me posted where is your code failing exactly, because this works for me.  Also, I am using AutoCAD 2013, it should be easy to replace document code relevant to 2012 or earlier.

 

 

Imports acOp = Autodesk.AutoCAD.Interop

 

        Public db As Database = HostApplicationServices.WorkingDatabase

        Public ed As Editor = activeDoc.Editor

        Public ReadOnly Property ThisDrawing() As AcadDocument

            Get

                Return DocumentExtension.GetAcadDocument(Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument)

            End Get

        End Property

        Private acDoc As acOp.AcadDocument

        Private handlerAdded As Boolean = False

        Private cForm As New frmMassStraight

 

        Public Sub eventDoubleClick()

            Try

                If handlerAdded = False Then

                    MgdAcApplication.SetSystemVariable("DBLCLKEDIT", 0)

                    If acDoc Is Nothing Then

                        acDoc = CType(ThisDrawing, Autodesk.AutoCAD.Interop.AcadDocument)

                        AddHandler acDoc.BeginDoubleClick, AddressOf callback_DoubleClick

                    End If

                    handlerAdded = True

                End If

            Catch ex As Autodesk.AutoCAD.Runtime.Exception

                MsgBox(ex.Message, MsgBoxStyle.Critical)

            Finally

                MgdAcApplication.SetSystemVariable("DBLCLKEDIT", 1)

            End Try

        End Sub

 

        Private Sub DisplayError(ByVal msg As String)

            ed.WriteMessage(vbLf + msg)

            cForm.TextBox1.Text += msg + vbCrLf

            MgdAcApplication.ShowModalDialog(cForm)

        End Sub

        Private Sub callback_DoubleClick(ByVal PickPoint As Object)

            Dim prmtSel As PromptSelectionResult = activeDoc.Editor.GetSelection()

            Dim msg As String = ""

            Using docLock As DocumentLock = activeDoc.LockDocument()

                If prmtSel.Status <> PromptStatus.OK Then

                    DisplayError(String.Format("ERROR: prmtSel.Status= {0}", prmtSel.Status))

                    Return

                End If

                If prmtSel.Value.Count <> 1 Then

                    DisplayError(String.Format("ERROR: prmtSel.Value.Count={0}", prmtSel.Value.Count))

                    Return

                End If

 

                Dim id As Autodesk.AutoCAD.DatabaseServices.ObjectId = prmtSel.Value(0).ObjectId

                Try

                    Using acTrans As Autodesk.AutoCAD.DatabaseServices.Transaction = _

                    activeDoc.TransactionManager.StartTransaction()

                        Dim dbObj As Autodesk.AutoCAD.DatabaseServices.DBObject = _

                        acTrans.GetObject(id, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)

 

                        Dim ent As Autodesk.AutoCAD.DatabaseServices.Entity = _

                        TryCast(dbObj, Autodesk.AutoCAD.DatabaseServices.Entity)

 

                        cForm.Text = ent.GetType().ToString()

 

                        For Each p As System.Reflection.PropertyInfo In ent.GetType().GetProperties()

                            Try

                                Dim displStr As String = String.Format("  {0}:     '{1}'", p.Name, p.GetValue(ent, Nothing))

                                cForm.TextBox1.Text += displStr + vbCrLf

                            Catch

                                Dim msgStr As String = String.Format("ERR: '{0}' p='{1}'", Err.Description, p.ToString)

                                ed.WriteMessage(vbLf + msgStr)

                                cForm.TextBox1.Text += msgStr + vbCrLf

                            End Try

                        Next

 

                        If ent Is Nothing Then

                            DisplayError(String.Format("ERROR: ent={0}", ent))

                            Return

                        Else

                            Dim blockRef As Autodesk.AutoCAD.DatabaseServices.BlockReference = _

                            TryCast(ent, Autodesk.AutoCAD.DatabaseServices.BlockReference)

                            If blockRef Is Nothing Then

                                DisplayError(String.Format("ERROR: blockRef={0}", blockRef))

                                Return

                            Else

                                activeDoc.Editor.WriteMessage(blockRef.BlockName)

                            End If

                        End If

                        acTrans.Commit()

                    End Using

                Catch ex As Autodesk.AutoCAD.Runtime.Exception

                    Dim msgStr As String = String.Format("EX: '{0}'", ex.ToString)

                    ed.WriteMessage(vbLf + msgStr)

                    cForm.TextBox1.Text += msgStr + vbCrLf

                Catch

                    Dim msgStr As String = String.Format("ERR: '{0}'", Err.Description)

                    ed.WriteMessage(vbLf + msgStr)

                    cForm.TextBox1.Text += msgStr + vbCrLf

                End Try

            End Using

            MgdAcApplication.ShowModalDialog(cForm)

        End Sub

        ' Component for displaying the Mass Straight Conveyor form

        <CommandMethod("mst")> _

        Public Sub massStraight()

            Try

                ' Call this to override default block dblclk event handler

                eventDoubleClick()

            Catch ex As Autodesk.AutoCAD.Runtime.Exception

                MsgBox(ex.Message, MsgBoxStyle.Critical)

            End Try

 

        End Sub

 

 

Valued Contributor
mindofcat
Posts: 55
Registered: ‎05-14-2012
Message 9 of 29 (1,333 Views)

Re: How to capture double click event in AutoCAD using VB.NET

11-27-2012 01:41 PM in reply to: sszabo

Thanks a bunch. Let me try out your suggestion, and see if I can pinpoint where I am making my mistake.

 

I shall keep you posted on the development.

 

Many thanks...

Valued Contributor
mindofcat
Posts: 55
Registered: ‎05-14-2012
Message 10 of 29 (1,311 Views)

Re: How to capture double click event in AutoCAD using VB.NET

11-27-2012 07:21 PM in reply to: sszabo

Hi sszabo,

 

I`ve implemented the code revision you so kindly provided. However, when I run the `mst` command, nothing happens. I doubleclick on a block after running the command, and the attributes editor is what I see still.

 

Here is the code I have:

 

' System
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.Linq.Expressions

' AutoCAD
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.Runtime
Imports acApp = Autodesk.AutoCAD.ApplicationServices.Application
Imports Autodesk.AutoCAD.EditorInput

' AutoCAD Interop
Imports acOp = Autodesk.AutoCAD.Interop
Imports acOpCom = Autodesk.AutoCAD.Interop.Common

<Assembly: CommandClass(GetType(Test.Commands))> 


Namespace Test

    Public Class Commands
        Public db As Database = HostApplicationServices.WorkingDatabase
        Public activeDoc As Document = acApp.DocumentManager.MdiActiveDocument
        Public ed As Editor = activeDoc.Editor

        Private acDoc As acOp.AcadDocument
        Private handlerAdded As Boolean = False
        Private cForm As New frmMassStraight ' I already have a form called frmMassStraight, so I simply added a Textbox1 to it
        
        ' I tried using the property call, but was getting an error on type mismatch from document to acadDocument
        Public Function ThisDrawing()
            Return acApp.DocumentManager.MdiActiveDocument.AcadDocument
        End Function

        Public Sub eventDoubleClick()

            Try
                If handlerAdded = False Then
                    acApp.SetSystemVariable("DBLCLKEDIT", 0)
                    If acDoc Is Nothing Then
                        acDoc = CType(ThisDrawing, Autodesk.AutoCAD.Interop.AcadDocument)
                        AddHandler acDoc.BeginDoubleClick, AddressOf callback_DoubleClick
                    End If
                    handlerAdded = True
                End If

            Catch ex As Autodesk.AutoCAD.Runtime.Exception
                MsgBox(ex.Message, MsgBoxStyle.Critical)

            Finally
                acApp.SetSystemVariable("DBLCLKEDIT", 1)
            End Try

        End Sub

        Private Sub displayError(ByVal msg As String)
            ed.WriteMessage(vbLf + msg)
            cForm.TextBox1.Text += msg + vbCrLf
            acApp.ShowModalDialog(cForm)
        End Sub

        Private Sub callback_DoubleClick(ByVal pickPoint As Object)
            Dim prmtSel As PromptSelectionResult = activeDoc.Editor.GetSelection()
            Dim msg As String = ""

            Using docLock As DocumentLock = activeDoc.LockDocument()
                If prmtSel.Status <> PromptStatus.OK Then
                    displayError(String.Format("Error: prmtSel.Status= {0}", prmtSel.Status))
                    Return
                End If

                If prmtSel.Value.Count <> 1 Then
                    displayError(String.Format("Error: prmtSel.Value.Count={0}", _
                                               prmtSel.Value.Count))
                End If

                Dim id As Autodesk.AutoCAD.DatabaseServices.ObjectId = prmtSel.Value(0).ObjectId
                Try
                    Using acTrans As Autodesk.AutoCAD.DatabaseServices.Transaction = _
                        activeDoc.TransactionManager.StartTransaction()

                        Dim dbObj As Autodesk.AutoCAD.DatabaseServices.DBObject = _
                        acTrans.GetObject(id, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)

                        Dim ent As Autodesk.AutoCAD.DatabaseServices.Entity = _
                            TryCast(dbObj, Autodesk.AutoCAD.DatabaseServices.Entity)

                        cForm.Text = ent.GetType().ToString()

                        For Each p As System.Reflection.PropertyInfo In _
                            ent.GetType().GetProperties()
                            Try
                                Dim displStr As String = String.Format(" {0}:      '{1}'", _
                                                        p.Name, p.GetValue(ent, Nothing))
                                cForm.TextBox1.Text += displStr + vbCrLf

                            Catch
                                Dim msgStr As String = String.Format("Error: '{0}' p='{1}'", _
                                                Err.Description, p.ToString)
                                ed.WriteMessage(vbLf + msgStr)
                                cForm.TextBox1.Text += msgStr + vbCrLf
                            End Try
                        Next

                        If ent Is Nothing Then
                            displayError(String.Format("Error: ent={0}", ent))
                            Return
                        Else
                            Dim blockRef As Autodesk.AutoCAD.DatabaseServices.BlockReference = _
                                TryCast(ent, Autodesk.AutoCAD.DatabaseServices.BlockReference)

                            If blockRef Is Nothing Then
                                displayError(String.Format("Error: blockRef={0}", blockRef))
                                Return
                            Else
                                activeDoc.Editor.WriteMessage(blockRef.BlockName)
                            End If
                        End If
                        acTrans.Commit()

                    End Using
                Catch ex As Autodesk.AutoCAD.Runtime.Exception
                    Dim msgStr As String = String.Format("EX: '{0}'", ex.ToString)
                    ed.WriteMessage(vbLf + msgStr)

                Catch
                    Dim msgStr As String = String.Format("ERR: '{0}", Err.Description)
                    ed.WriteMessage(vbLf + msgStr)
                    cForm.TextBox1.Text += msgStr + vbCrLf
                End Try

            End Using
            acApp.ShowModalDialog(cForm)

        End Sub

        ' Component for displaying the Mass Straight Conveyor form
        <CommandMethod("mst")> _
        Public Sub massStraight()
            Try
                ' Call this to override the default block dblclk event handler
                eventDoubleClick()

            Catch ex As Autodesk.AutoCAD.Runtime.Exception
                MsgBox(ex.Message, MsgBoxStyle.Critical)

            End Try
        End Sub

    End Class


End Namespace

 

I wonder if the problem is because I used the wrong document translations here. I am developing in an AutoCAD 2010 environment, and probably used the wrong instances for your equivalent of DocumentExtension.GetAcadDocument() as well as MgdAcApplication.

 

As it is, this code should work, but I am not seeing the desired effect. The form doesn`t pop up at all, so I can`t even tell what`s wrong. However, in an attempt to debug, I am guessing that the showModalDialog code at the end of the doubleclick callback probably isn`t being reached at all, which is why the form does not pop up at all to show me anything.

 

Not even the commandline shows me any of the messages I am supposed to see in the event of an error, or successful call.

 

Any ideas,

 

Thanks in advance...

You are not logged in.

Log into access your profile, ask and answer questions, share ideas and more. Haven't signed up yet? Register

Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.

Need installation help?

Start with some of our most frequented solutions to get help installing your software.

Ask the Community