style="PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
"chris" <
href="mailto:christian_marx@justmail.de">christian_marx@justmail.de>
wrote in message
href="news:05F596ABF67EDA566099F47B05F103AB@in.WebX.maYIadrTaRb">news:05F596ABF67EDA566099F47B05F......
i've created a AcDbObjectReactor to change the
attribute text of a block, every time
something is happening to the block.
the problem is, i can't change the attribute
text, bacuse the opning for write returns eWasNotifying
while i close the pointer.
how can i change the text in the
attribute?
regards
chris
color=#008080>
color=#008080>//-----------------------------------------------------------------------------
color=#000080>void MarxCiCADKoteReaktor::modified(
color=#000080>const AcDbObject* dbObj)
{
color=#000080>#ifdef OARXWIZDEBUG
acutPrintf
("\nOARXWIZDEBUG - MarxCiCADKoteReaktor::modified()
called.");
#endif
color=#008080>// OARXWIZDEBUG
color=#008080>// TODO: implement this
function.
color=#000080>if ( DocVars.docData ().m_editCommand == false
)
color=#000080>return;
DocVars.docData
().m_editCommand = false ;
//
disable the object reactor
color=#008080>// (so the object reactor knows that we are changing the
object)
DocVars.docData ().m_doConversion =
true ;
//Bemassung bearbeiten
und aktualisieren
ChangeKoteText(dbObj);
}
color=#000080>void
MarxCiCADKoteReaktor::ChangeKoteText(const
AcDbObject* dbObj)
{
AcDbBlockReference *pInsert =AcDbBlockReference::cast (dbObj)
;
color=#000080>if ( !pInsert
)
return
;
CString
str;
GetAttributeString(pInsert,
str);
SetAttributeString(pInsert, "test" );
color=#008080>// insert text to the
attribute
}
Acad::ErrorStatus
MarxCiCADKoteReaktor::GetAttributeString(AcDbBlockReference* pObj, CString
&str)
{
// Acad::ErrorStatus
es;
AcDbObjectIterator *pIter = NULL;
pIter =
pObj->attributeIterator();
assert(pIter);
color=#000080>for(pIter->start(); !pIter->done();
pIter->step())
{
AcDbAttribute*
pAttrib;
AcDbObjectId attId =
pIter->objectId();
color=#000080>if (pObj->openAttribute(pAttrib, attId,
AcDb::kForRead) ==
Acad::eOk)
{
str =
pAttrib->textString();
pAttrib->close();
}
}
delete
pIter;
return
Acad::eOk;
}
Acad::ErrorStatus
MarxCiCADKoteReaktor::SetAttributeString(AcDbBlockReference* pObj, CString
str)
{
Acad::ErrorStatus es;
AcDbObjectIterator *pIter =
NULL;
pIter =
pObj->attributeIterator();
assert(pIter);
color=#000080>for(pIter->start(); !pIter->done();
pIter->step())
{
AcDbAttribute*
pAttrib;
AcDbObjectId attId =
pIter->objectId();
color=#000080>if (pObj->openAttribute(pAttrib, attId,
AcDb::kForWrite) ==
Acad::eOk)
{
pAttrib->setTextString(str);
pAttrib->close(); //HERE IS THE ERROR
size=2>eWasNotifying
}
}
delete
pIter;
return
Acad::eOk;
}
style="PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
"Stephen Preston" <
href="mailto:discussion@autodesk.com">discussion@autodesk.com> schrieb
im Newsbeitrag
href="news:07521D27263651ADEEF6AB3F2376D58C@in.WebX.maYIadrTaRb">news:07521D27263651ADEEF6AB3F237......
You can store the ObjectId of the object being
modified and then process that object in the commandEnded callback of an
editor reactor. The technique is demonstrated in the final labl of the arxlabs
in the ObjectARX SDK.
--
Cheers,
Stephen Preston
Developer Technical
Services
Autodesk
href="http://adn.autodesk.com">http://adn.autodesk.com
style="PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
"chris" <
href="mailto:christian_marx@justmail.de">christian_marx@justmail.de>
wrote in message
href="news:05F596ABF67EDA566099F47B05F103AB@in.WebX.maYIadrTaRb">news:05F596ABF67EDA566099F47B0......
i've created a AcDbObjectReactor to change the
attribute text of a block, every time
something is happening to the
block.
the problem is, i can't change the attribute
text, bacuse the opning for write returns eWasNotifying
while i close the pointer.
how can i change the text in the
attribute?
regards
chris
color=#008080>
color=#008080>//-----------------------------------------------------------------------------
color=#000080>void MarxCiCADKoteReaktor::modified(
color=#000080>const AcDbObject* dbObj)
{
color=#000080>#ifdef OARXWIZDEBUG
acutPrintf ("\nOARXWIZDEBUG -
MarxCiCADKoteReaktor::modified() called.");
color=#000080>#endif //
OARXWIZDEBUG
//
TODO: implement this function.
color=#000080>if ( DocVars.docData ().m_editCommand == false
)
color=#000080>return;
DocVars.docData
().m_editCommand = false ;
color=#008080>// disable the object reactor
// (so the object reactor knows that we are changing
the object)
DocVars.docData
().m_doConversion = true ;
color=#008080>//Bemassung bearbeiten und
aktualisieren
ChangeKoteText(dbObj);
}
color=#000080>void
MarxCiCADKoteReaktor::ChangeKoteText(const
AcDbObject* dbObj)
{
AcDbBlockReference *pInsert =AcDbBlockReference::cast (dbObj)
;
color=#000080>if ( !pInsert
)
return
;
CString
str;
GetAttributeString(pInsert,
str);
SetAttributeString(pInsert, "test" );
color=#008080>// insert text to the
attribute
}
Acad::ErrorStatus
MarxCiCADKoteReaktor::GetAttributeString(AcDbBlockReference* pObj, CString
&str)
{
// Acad::ErrorStatus
es;
AcDbObjectIterator *pIter = NULL;
pIter =
pObj->attributeIterator();
assert(pIter);
color=#000080>for(pIter->start(); !pIter->done();
pIter->step())
{
AcDbAttribute*
pAttrib;
AcDbObjectId attId =
pIter->objectId();
color=#000080>if (pObj->openAttribute(pAttrib, attId,
AcDb::kForRead) ==
Acad::eOk)
{
str =
pAttrib->textString();
pAttrib->close();
}
}
delete
pIter;
return
Acad::eOk;
}
Acad::ErrorStatus
MarxCiCADKoteReaktor::SetAttributeString(AcDbBlockReference* pObj, CString
str)
{
Acad::ErrorStatus es;
AcDbObjectIterator *pIter =
NULL;
pIter =
pObj->attributeIterator();
assert(pIter);
color=#000080>for(pIter->start(); !pIter->done();
pIter->step())
{
AcDbAttribute*
pAttrib;
AcDbObjectId attId =
pIter->objectId();
color=#000080>if (pObj->openAttribute(pAttrib, attId,
AcDb::kForWrite) ==
Acad::eOk)
{
pAttrib->setTextString(str);
pAttrib->close(); //HERE IS THE ERROR
size=2>eWasNotifying
}
}
delete
pIter;
return
Acad::eOk;
}
Hello Stephen,
I'm facing a similar situation, except I do not run a command I could catch the end of.
I have a blockreference, showing a Height Cote as MText in it (I know, there could be an field-attribute bound to a BlockPoint, this is not an option in my case; for my needs there is a 1:1 relationship between Bref and Bdef).
My goal is, when the user changes the Z-Coordinate of the blockref via the Property-Panel , the heigthcotes shall be updated, and by changing the rotation, the text readability shall be maintained ( cos(rotation)>=0 --> normal, else rotated by 180deg).
I'm looking for an event/overrule to achieve this. Unfortunatelly all events leave the Object in notifying state before enter the handler.
For Stretch_editing there is a command I can catch, I only struggle with changing the props themselves.
I found a DBObjectMonitor (not sure the source anymore) erlaier, which works fine to dump the info to the editor, but cannot be used for editing objects (I know, it's general not a good idea to modify object within an eventhandler - haven't found any better way), since the object is still notifying.
Somehow the ent.UpdgradeFromNotify doesn't seem to work here...
Recently I tried to add a bref.Modified event to my blockrefs when they are selected and used this handler
Friend Sub CallBack_Object_Modified(sender As Object, e As EventArgs) Dim s As BlockReference = TryCast(sender, BlockReference) If s Is Nothing Then Return Try s.UpgradeFromNotify() '<-- throws "ewasnotifying" 'do my BlockUpdate here s.DowngradeToNotify(True) Catch ex As Exception End Try End Sub
Any hints appreciated!
Best Regards,
Daniel
Acad Architecture 2012 x64 / Win7 pro x64/ .net 4.0 / VS2010
Hi,
Another solution is described here which might match your requirements: you can store the modified object oid and wait until AcDbObject::objectClosed(AcDbObjectId) is called.
"
[...stuff about AcDbSmartObjectPointer class...]
eWasNotifying Returned when the specified object is currently closing from kForWrite mode, is sending notification and kForWrite mode is requested again. At that point undo recording has been done, and all reactors get to see the same object state. The workaround for this status is to record that the notification happened then wait until the AcDbObject::objectClosed(AcDbObjectId) callback is made, at which point the object can be opened for write.
"
Since I'm not comfortable with VB, I may let you guess what corresponding code is.
I hope this helps
Hi,
thank you for the quick answer.
In my understanding this would mean to catch the ObjectClosed event.
After trying this it seems, the object is still notifying at the time the event is firing.
The current way is:
selecting the object -> adding the bref.objectClosed Eventhandler
changing the prop -> Event fires, Eventhandler is called
I alter the BlocktableRecord the bref belongs to -> OK
I need the Blockref to recordgraphicsmodified, to avoid a regen of the drawing (in a huge drawing I don't want to regen all entities...), therefore
I start a new transaction and open the Blockreference for write and at this point the "eWasNotifying" error throws.
I must be missing something..... 😞
With all these ObjectEvents I can only dump some info to the editor, or collect objectids????
Again, I have no Command to catch... 😞
I tried an Objectoverrule by overriding the Close method also -> invalid state....
I guess there MUST be a way to catch the very moment, when the object is available again for editing.... even in .net
BR,
Daniel
Hi,
Indeed, the workaround described seems not to work, sorry. As clearly described in the documentation: "[..objectClosed handler documentation...] Reopening the object for write is not supported since it leads to recursive notifications. Doing so will return Acad::eWasNotifying during the open operation."
So, I would try to record oid of modified object in your "CallBack_Object_Modified" and, instead of catching the end of any command (as described in this post), I would catch "DocumentLockModeWillChange" testing when the document is getting unlocked, this should be a good place to update your object.
I hope this helps.