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

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

28 REPLIES 28
SOLVED
Reply
Message 1 of 29
mindofcat
6886 Views, 28 Replies

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

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

28 REPLIES 28
Message 2 of 29
ACADuser
in reply to: mindofcat

See if this might help;

 

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

ACADuser
Civil 3D 2018, Raster Design 2018
Windows 7 Enterprise
Dell Precision 5810 Workstation
Intel Xeon E5-1630 v3 @ 3.70GHz
32GB RAM, NVIDIA Quadro K2200 4 GB GDDR5
DUAL 27" Dell UltraSharp U2713HM
Message 3 of 29
sszabo
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

Message 4 of 29
jeff
in reply to: sszabo

Message 5 of 29
mindofcat
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!

Message 6 of 29
mindofcat
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...

Message 7 of 29
mindofcat
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

Message 8 of 29
sszabo
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

 

 

Message 9 of 29
mindofcat
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...

Message 10 of 29
mindofcat
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...

Message 11 of 29
sszabo
in reply to: mindofcat

On a second thought: I just recreated what you describe by replacing this line:

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

 

with this:

 

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

 

So you probably have the wrong document obj.  Unfortunately I am not familiar with ACAD 2010 and have't worked with ACAD before 2013.  You will have to ask somebody to point you to the correct way to return the ThisDrawing object for your version.  I think your code should work so I am not sure why it doesn't.

 

try this too if you like:

 

First make sure you can see messages from eventDoubleClick().  If you don't the problem is your document object.  Make sure you have this: 

Dim activeDoc As Document = Application.DocumentManager.MdiActiveDocument

 

I am also assuming you loaded a valid drawing before you ran your mst command.  To verify this:

 

        Private Sub callback_DoubleClick(ByVal PickPoint As Object)

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

            Dim msg As String = ""

 

            msg = String.Format("doc: {0} prmtSel:{1}", activeDoc.Name, prmtSel.Value.ToString)

            ed.WriteMessage(vbLf + msg)

 

 

This should give you:

doc: C:\mydrawing.DWG prmtSel:(((8796087866032),PickPoint,114,))

 

 

 

 

Message 12 of 29
jeff
in reply to: sszabo

Confused why you even try using AcadDocument object among other things.

 

I would start over and forget about blockreferences or blocks and focus on showing a blank form for a double-click event.

Thats it.

Will help you along but for now

 

So you need a blank form

A command to register event handler.

 

And showing the form .

 

Once you get a understanding of that then move to next steps and improving approach. 

 

You can also find your answers @ TheSwamp
Message 13 of 29
mindofcat
in reply to: sszabo

Thanks sszabo,

 

I deeply appreciate all the help you've given me. Let me try out the suggestion you just made, and see where it gets me. Yes I totally understand about CAD 2013, unfortunately, my work is based on 2010 (eventually the company will upgrade to 2013) but for now, all the work is on 2010 so I have a lot of research to do on the ThisDrawing and document objects. Seems that's where my problem is originating...

 

 

Thanks for everything

Message 14 of 29
jeff
in reply to: mindofcat


@mindofcat wrote:

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...



Have you tried adding a command myForm?

<Command("myForm")...>

Sub

 Dim formInstance As New frmMassStraight

application.showModalDialog(formInstance)

End Sub

You can also find your answers @ TheSwamp
Message 15 of 29
mindofcat
in reply to: jeff

Yes, I have tried

<Command("myForm")...>

Sub

 Dim formInstance As New frmMassStraight

application.showModalDialog(formInstance)

End Sub

 

That's how I had things set up in the first place. And this calls my form alright, but I still don't know how to tie in the doubleclick override, or how to build a functional doubleclick override in the first place.

 

You've seen my code? Any idea what I'm doing wrong, or what I'm missing? Many have told me that my code seems alright, and works for them. But unfortunately, I still doubleclick on my frmMassStraight block references and the default AutoCAD doubleclick behavior kicks in, instead of my frmMassStraight form popping up...

Message 16 of 29
Balaji_Ram
in reply to: mindofcat

Hello,

 

Maybe this is causing the problem : In the finally block, the system variable "DBLCLKEDIT" is set to 1 again ?

 

I have attached the dropbox link to a sample project that is mostly from your code and a recording of the steps that I tried.

https://www.dropbox.com/sh/xzp9iiq6sc7e1bm/MBhZ6B7evG

 

It works ok on AutoCAD 2011 and on double-clicking a block reference the modal form displays the block name.

 

Hope this provides some hint to resolve the issue with your sample project.

 

 

 

 



Balaji
Developer Technical Services
Autodesk Developer Network

Message 17 of 29
mindofcat
in reply to: Balaji_Ram

Thanks very much, this helped immensely. Truly grateful for the help.

Message 18 of 29
jeff
in reply to: Balaji_Ram

By getting the current selection set would'nt that clear it and no other doubleclick actions would be called?

 

I thought the DBLCLICK variable had to do with DoubleClickActions in CUI and nothing to do with Application.BeginDoubleClick event?

 

What if you wanted it to show for certain blocks but not all?

 

 

You can also find your answers @ TheSwamp
Message 19 of 29
mindofcat
in reply to: jeff

I ended up NOT going down the Application.BeginDoubleClick event route anymore. What I ended up doing was creating a custom doubleclick action to which I attached the macro that calls my edit form.

 

And then, in the myCommands.vb file, I call the moethod that registers this custom doubleclick action in the initialize() method.

 

Which means that, upon AutoCAD load, the AutoCAD cuix file is iterated thru, my custom doubleclick action (which targets attribute blocks) is removed, and then recreated.

 

As well, in order to ensure that I target only specific blocks, in the method that executes the selectImplied() pickset, I cast the picked entity as a block reference, and then check its name. IF the name falls under the category of blocks I need, then I pop up the edit form; else I use acDoc.SendStringToExecute() to execute the eattedit command macro.

 

The only downside I suffered was that it now takes 3 clicks (instead of 2) to pop up the eattedit editor for attribute blocks other than the ones I need to edit. Still, considering how almost impossible it was to get this problem resolved, I am honestly satisfied with the outcome.

Message 20 of 29
Balaji_Ram
in reply to: jeff

Hi Jeff,

 

That is a valid point.

 

I was only looking into getting the originally posted code to work. It does have its limitations such as showing our dialog for all the blocks without being selective.

 

I dont see that the "DBLCLKEDIT" system variable can get reset without our code doing it. This system variable controls the customization of double click that is done using the CUI. So switching it off will ensure that we are allowed to show our dialog without the macro specified in the CUI customization of bloc edit interfering in it.

 

To do double click customization selectively, using the CUI approach is the right way. But I still dont get why 3 clicks are needed for blocks for which the custom dialog need not be shown.

 

Here is a sample code that worked ok. It changes the macro for the block double click to invoke a custom command called "mybedit". Inside the "mybedit" command, we can check if the block is one that we are interested in. If yes, we do our custom action such as showing our dialog. If not we set the pick first selection and then invoke the AutoCAD "bedit".

 

public class Test : IExtensionApplication
{
    static CustomizationSection cs;

	[CommandMethod("mybedit", CommandFlags.UsePickSet)]
	static public void MyBeditCommand()
	{
		Document activeDoc = Application.DocumentManager.MdiActiveDocument;
		Editor ed = activeDoc.Editor;

		PromptSelectionResult result = Application.DocumentManager.MdiActiveDocument.Editor.GetSelection();
		if (result.Status == PromptStatus.OK)
		{
			SelectionSet ss = result.Value;
			foreach (SelectedObject so in ss)
			{
				ed.WriteMessage(so.ObjectId.Handle.ToString());

				// Some check here to identify if we need to show our dialog
				if (so.ObjectId.Handle.ToString().Equals("1BB"))
				{
					// Show our dialog
				}
				else
				{
					// Let AutoCAD do the block edit.

	                ObjectId[] ids = ss.GetObjectIds();

					// Set the implied selection to what it was before our command was called
					ed.SetImpliedSelection(ids);

					// call "bedit" command
					activeDoc.SendStringToExecute("_BEDIT ", false, false, false);
				}
			}
		}
	}
	
    [CommandMethod("MacroCUI")]
    static public void ModifyMacroCUI()
    {
        Document activeDoc = Application.DocumentManager.MdiActiveDocument;
        Editor ed = activeDoc.Editor;

        DoubleClickAction blockDoubleClickAction = null;
        foreach (DoubleClickAction dca in cs.MenuGroup.DoubleClickActions)
        {
            ed.WriteMessage("\n" + dca.Name);
            if (dca.Name.Equals("Block"))
            {
                blockDoubleClickAction = dca;
                break;
            }
        }
        if (blockDoubleClickAction != null)
        {
            blockDoubleClickAction.DoubleClickCmd.MenuMacroReference.macro.Command = "$M=$(if,$(and,$(>,$(getvar,blockeditlock),0)),^C^C_properties,^C^C_mybedit)";

            if (cs.IsModified)
              cs.Save();
        }
    }

    void IExtensionApplication.Initialize()
    {
        Document activeDoc = Application.DocumentManager.MdiActiveDocument;
        Database db = activeDoc.Database;
        Editor ed = activeDoc.Editor;

        // retrieve the location of, and open the ACAD Main CUI File
        string mainCuiFile = (string)Application.GetSystemVariable("MENUNAME");
        mainCuiFile += ".cuix";
        cs = new CustomizationSection(mainCuiFile);
    }

    void IExtensionApplication.Terminate()
    {
    }
}

 

In the code, I have made a check on the block reference handle, which you can change to any other condition to identify your block reference (ex : XData )

 

The "MacroCUI" command changes the macro for block double click action after which you can try the double click.

 

 

 

 



Balaji
Developer Technical Services
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