by Fenton Webb
I wonder how many people have this issue?
A message appears when running the REDO command in AutoCAD straight after running the UNDO command… There’s a relatively simple explanation as to why this is happening.
In short, calling StartTransaction() or opening anything for kForWrite whenever UNDO or REDO is occurring will cause this issue to happen.
A lot of developers want to make special updates to objects while AutoCAD is running commands, perhaps they want to relink interconnecting entities, update parts schedules or move objects in relation to others.
Some examples of places where they might run this type of update code are:
- In a CommandEnded event or reactor notification
- In an ObjectModified, ObjectAppended, etc. event or reactor notification
- In a Overrule or Custom entity callback
- any other event or reactor notification
The problem stems from the fact that when you run the UNDO or REDO commands inside of AutoCAD, those commands also invoke the same callback mechanisms that all of the other normal commands do.
If that happens, and you call StartTransaction() or you open something for kForWrite from within one of those callback mechanisms, the REDO will fail. The reason is that StartTransaction() and kForWrite both initialize the UNDO filing system, and if you do that initialization while UNDO or REDO is happening then you trash the UNDO filer.
Here’s some tips on how to operate on entities from within these events or reactor notifications:
- Don’t use StartTransaction(), simply calling this function while UNDO or REDO is running will blitz the UNDO filer – instead call StartOpenCloseTransaction() or use Open(kForRead).
- Opening something for kForRead is fine, even when UNDOing, so you can safely record any updates that are happening in your own buffers.
- There’s no need to update anything while the UNDO or REDO is happening – why? Because the UNDO and REDO will restore it for you anyway…
So what are our options…
- In a CommandEnded event or reactor notification
- you just need to make sure that UNDO and/or REDO is not happening by testing the command string that is passed to the event callback.
- In an ObjectModified, ObjectAppended, etc event or reactor notification
- you can test the entity that is passed to see if the IsUndoing property is set to true, if it is, do nothing.
- In a Overrule or Custom entity callback
- simply testing the host (this or me) object to see if the callback is occurring with IsUndoing is set to true, if it is, do nothing.