Hi, I want write a command for attribute editing. The command check if the block name is equal to a string and if yes make some operation, if no continue with DDEDIT standard command.
The program work well if the block name is not the some of the string. When the name is the some the program make the correct operation but then run also the ddedit command.
there is a way for break the command?
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Colors
Imports System
Imports System.Windows.Forms
Imports System.Math
'Imports System.Web.Mail
Imports Microsoft.Office.Core
Imports Microsoft.Office.Interop
'Imports Microsoft.Office.Interop.Outlook
Imports System.Runtime.InteropServices
Imports Autodesk.AutoCAD.Interop
Public ClassreactorDim bEditCommand AsBooleanDim bDoRepositioning AsBoolean
<CommandMethod("AddEvents")> _
PublicSubplantDbEvents()
Dim doc AsDocument = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
Dim db AsDatabase = HostApplicationServices.WorkingDatabase()
'AddHandler db.ObjectOpenedForModify, New ObjectEventHandler(AddressOf objOpenedForMod)AddHandler doc.CommandWillStart, NewCommandEventHandler(AddressOfcmdWillStart)
'AddHandler doc.CommandEnded, New CommandEventHandler(AddressOf cmdEnded)
bEditCommand =
False
bDoRepositioning =
FalseEndSubPublicSub cmdWillStart(ByVal o AsObject, ByVal e AsCommandEventArgs)
Dim ed AsEditor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor
TryIf e.GlobalCommandName = "DDEDIT"Or e.GlobalCommandName = "EATTEDIT"Then
Dim fr2 AsNewFerriDim strNomeBlocco AsStringDim myDwg AsDocument'Dim myBT As BlockTable'Dim myBTR As BlockTableRecordDim myDB As DatabaseServices.DatabaseDim myTransMan As DatabaseServices.TransactionManagerDim myTrans As DatabaseServices.TransactionDim myEd As EditorInput.EditorDim myPSR As EditorInput.PromptSelectionResult
Dim TargetBlockRef As DatabaseServices.BlockReference
myDB = ApplicationServices.
Application.DocumentManager.MdiActiveDocument.Database
myDwg = Autodesk.AutoCAD.ApplicationServices.
Application.DocumentManager.MdiActiveDocument
strNomeBlocco =
"FERRI-P"
myTransMan = myDB.TransactionManager
myTrans = myTransMan.StartTransaction
myEd = myDwg.Editor
a2: myPSR = myEd.SelectImplied
SelectCasemyPSR.Status
Case EditorInput.PromptStatus.OK
SelectCasemyPSR.Value.Count
Case1
Dim mySelobj As EditorInput.SelectedObjectDim myAcadEnt As DatabaseServices.Entity
For I = 1 TomyPSR.Value.Count
mySelobj = myPSR.Value.Item(I - 1)
myAcadEnt = mySelobj.ObjectId.GetObject(DatabaseServices.
OpenMode.ForRead)
TargetBlockRef = myAcadEnt
If Microsoft.VisualBasic.Left$(UCase(TargetBlockRef.Name), 5) = "FERRI"Then
fr2.Show()
GoToA15
EndIf
NextI
CaseIs> 1
MsgBox(
"Seleziona un solo blocco delle Posizioni")
myPSR =
NothingGoToa2
Case ElseEndSelectCase EditorInput.PromptStatus.Error
' GoTo a3
' Case EditorInput.PromptStatus.Cancel
EndSelectEndIfCatch ex As System.Exception
ed.WriteMessage(
"Error in cmdWillStart: "+ ex.Message)
EndTry
A15:
EndSub
End
Class
Handling CommandWillStart event will not meet your need, as you have already found out, because no matter what you do in the event handler, it is just something you can do before the command starts, after your code runs, the command will still run.
To your need, you can handle DocumentCollection.DocumentLockModeChanged event and DocumentCollection.DocumentLockModeChangeVetoed event. That is, in the DocumentLockModeChanged event handler, if a certain condition is met, you can then veto the command, which will result in the DocumentLockModeChangeVetoed event being fired. Then in DocumentLockModeChangeVetoed event handler, you can start your own process/custom command.
Some psuedo code:
private static bool runAlternativeCmd=false;
public void Initialize()
{
DocumentCollection docs=Application.DocumentManager;
docs.DocumentLockModeChanged+=new DocumentLockModeChangedEventHandler(DocLockChanged);
docs.DocumentLockModeChangeVetoed+=new DocumentLockModeChangeVetoedEventHandler(DocLockChangeVetoed);
}
void DocLockChanged(object sender, DocumentLockModeChangedEventArgs e)
{
if (e.GlobalCommandName.ToUpper()=="XXXXXXX")
{
//Test if the entity in the implied selectionset is the targeting block. If it is, veto the command
runAlternativeCmd=true;
}
else
{
runAlternativeCmd=false;
}
}
void DocLockChaneVetoed(object sender, DocumentLockChangeVetoedEventArgs e)
{
If (runAlternativeCmd)
{
Document doc=Application.DocumentManager/MdiDocument;
doc.SendStringToExcute("MyAttrEdit ",true, false, false);
}
}
[CoommandMethod["MyAttrEdit")]
public static void EditMyAttribute()
{
Do my own editing process
}
HTH
Norman Yuan
Here are two ADN DevBlog entries:
Get the real name of a block if it is anonymous (necessary for dynamic blocks):
http://adndevblog.typepad.com/autocad/2012/05/identifying-block-name-from-the-block-reference.html
Veto a command as described above:
http://adndevblog.typepad.com/autocad/2012/05/veto-a-particular-command-in-autocad.html
Thamks
I must use the DLL with AutoCAD 2013 but there is an error
I have convert C code in Vb.net code, this is the result:
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Colors
Imports System
Imports System.Windows.Forms
Imports System.Math
'Imports System.Web.Mail
Imports System.Runtime.InteropServices
Imports Autodesk.AutoCAD.Interop
Imports System.Collections.Specialized
Public ClassClass2
<CommandMethod("AddVetoToQuit")> _
PublicSharedSubAddVetoToQuit()
Dim doc AsDocumentCollection = ApplicationServices.Application.DocumentManager
doc.DocumentLockModeChanged +=NewDocumentLockModeChangedEventHandlerdoc_DocumentLockModeChanged)
EndSub
<CommandMethod("RemoveVetoToQuit")> _
PublicSharedSubRemoveVetoToQuit()
Dim doc AsDocumentCollection = ApplicationServices.Application.DocumentManager
doc.DocumentLockModeChanged -=NewDocumentLockModeChangedEventHandler(doc_DocumentLockModeChanged)
EndSub
PrivateSharedSub doc_DocumentLockModeChanged(sender AsObject, e AsDocumentLockModeChangedEventArgs)
IfString.Compare(e.GlobalCommandName, "QUIT", True) = 0 Then
e.Veto()
EndIf
EndSub
End Class
I do not think you can use
Object.Event +=EventHandler(...) in VB.NET.
You should look into AddHandler/RemoveHandler statement in VB.NET, like:
AddHandler Object.Event, Address Of EventHandlerName
RemoveHandler Object.Event, Address Of EventHandlerName
Norman Yuan
Like this? But I receive an error on "Autodesk.AutoCAD.ApplicationServices.DocumentCollection.DocumentLockModeChanged"
Public
Classveto
<
CommandMethod("AddDocColEvent")> _
PublicSubAddDocColEvent()
AddHandler Autodesk.AutoCAD.ApplicationServices.DocumentCollection.DocumentLockModeChanged, AddressOfdocColDocAct
EndSub
<
CommandMethod("RemoveDocColEvent")> _
PublicSubRemoveDocColEvent()
RemoveHandler ApplicationServices.Application.DocumentManager.DocumentActivated, _
AddressOfdocColDocAct
EndSubPublicSub docColDocAct(ByVal senderObj AsObject, _
ByVal docColDocActEvtArgs AsDocumentCollectionEventArgs)
ApplicationServices.
Application.ShowAlertDialog(docColDocActEvtArgs.Document.Name & _
" was activated.")
EndSub
End
Class
Well, carefully looking into the compiling error would reveal something obviously.
1. You added event handler to handle DocumentLockModeChanged event, but you remove a handler on DocumentActivated event, which is never been added in the first place.
2. The event handler docColDocAct() cannot be used to handle DocumentLockModeChanged event, because the handler's signature is wrong. Event handler for DocumentLockModeChanged requires the second argumnet of the handler to be type of DocumentLockModeChangedEventArgs, not DocumentCollectionEventArgs.
Norman Yuan
I try this but don't work...
<
CommandMethod("AddDocColEvent")> _
PublicSubAddDocColEvent()
Dim doc As Autodesk.AutoCAD.ApplicationServices.Document
doc = Autodesk.AutoCAD.ApplicationServices.
Application.DocumentManager.MdiActiveDocument
AddHandler doc.DocumentLockModeChanged, NewObjectEventHandler(AddressOfdocColDocAct)
EndSubPublicSub docColDocAct(ByVal sender AsObject, docColDocActEvtArgs AsDocumentLockModeChangedEventArgs)
ApplicationServices.
Application.ShowAlertDialog(docColDocActEvtArgs.Document.Name & _
" was activated.")
EndSub
End
Class
Did you try to compile your code (or did get intellisense prompt when writing the code in VB editor)? Document class DOES NOT have event DocumentLockModeChanged event. So, I am wondering how you write your code without intellisense prompt and how you compile your code without error. It is DocumentCollection class that has event DocumentLockModeChanged/DocumentLockModeChangeVetoed event.
I put together some quick code, assuming that under certain codition, you do not want SAVE/QSAVE command run, instead, you run your own custom command. Here is the code:
Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.Runtime Imports Autodesk.AutoCAD.EditorInput <Assembly: CommandClass(GetType(AlternativeCommandVB.AlternativeCmd))> <Assembly: ExtensionApplication(GetType(AlternativeCommandVB.AlternativeCmd))> Public Class AlternativeCmd Implements IExtensionApplication Private Shared docs As DocumentCollection = Nothing Private Shared _dwgName As String = "" Private Shared _runAltCmd As Boolean = False Private Const TARGET_CMD = "SAVE" Public Sub Initialize() _ Implements Autodesk.AutoCAD.Runtime.IExtensionApplication.Initialize docs = Application.DocumentManager AddHandler docs.DocumentLockModeChanged, _ AddressOf Docs_DocumentLockModeChanged AddHandler docs.DocumentLockModeChangeVetoed, _ AddressOf Docs_DocumentLockModeChangeVetoed End Sub Public Sub Terminate() _ Implements Autodesk.AutoCAD.Runtime.IExtensionApplication.Terminate End Sub Private Sub Docs_DocumentLockModeChanged( _ sender As Object, e As DocumentLockModeChangedEventArgs) _dwgName = e.Document.Name _runAltCmd = False If e.GlobalCommandName.ToUpper().Contains(TARGET_CMD) Then If CheckVetoCondition(e.Document) Then _runAltCmd = True e.Veto() End If End If End Sub Private Sub Docs_DocumentLockModeChangeVetoed( _ sender As Object, e As DocumentLockModeChangeVetoedEventArgs) If _runAltCmd AndAlso _dwgName.ToUpper() = e.Document.Name.ToUpper() Then e.Document.Editor.WriteMessage(vbCr & "Command """ & _ TARGET_CMD & """ has been vetoed") e.Document.SendStringToExecute("MyAltCmd ", True, False, True) End If End Sub <CommandMethod("MyAltCmd")> _ Public Shared Sub RunMyCustomCmd() Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor ed.WriteMessage(vbCr & _ "Execute my coomand, instead of ""Save"" command....Done" & vbCr) End Sub Private Function CheckVetoCondition(dwg As Document) As Boolean ''Do needed condition test Return True End Function End Class
Start AutoCAD and load this project. Then enter command SAVE or QSAVE, you would see from command line that the SAVE/QSAVE command is vetoed and the custom command "MyAltCmd" runs.
HTH
Norman Yuan
Can't find what you're looking for? Ask the community or share your knowledge.