Tony,
Seems like NOD solution will not work once it is read at last and I need to
access it when filling in the custom objects...
Maybe using the BlockTable extension dictionary could solve this...
I can't believe that there is no easy solution to this...oh my!!!
Regards.
"fpgs" wrote in message
news:C6B1BAC428116C18AD563CFC1BE08027@in.WebX.maYIadrTaRb...
> Tony,
>
> Ok, I suspect that it does not work...I have made a test like you with
> tell() / seek() functions.
>
> As I only need to know if the drawing is a new one I will create an entry
on
> NOD and check if it exists. As the name of entry remains intact I can
check
> it when reading the DWG.
>
> Thank you!
>
> "Tony Tanzillo" wrote in message
> news:42B0FDF529733CB114919D7C5B42779F@in.WebX.maYIadrTaRb...
> > Fernando. It looks like I may have been wrong about
> > seek() and tell(). They appeared to work, but a simple
> > test revealed that seek() does not move the filer
> > position, even though tell() says it does.
> >
> > In a simple test, I tried to read the same data twice
> > by calling seek() to rewind the filer, and the data
> > wasn't the same.
> >
> > Oh Well....
> >
> >
> > "fpgs" wrote in message
> > news:C81449BF669D362C6B68D3C571B2A52B@in.WebX.maYIadrTaRb...
> > > Hello Tony,
> > >
> > > I have thought something like this but a found a document on pointA:
> > >
> > > There is a DEVNOTE (ID 13487) that tells:
> > > -----------------------
> > > (Note: Using AcDbDwgFiler::seek, AcDbDwgFiler::tell methods cannot be
> used
> > > to
> > > solve this problem. These methods are not implemented for the filer
used
> > > during
> > > save an load.)
> > > -----------------------
> > >
> > > As I need to do this exactly on save/load operations this will not
> solve.
> > > So you think your approach will work?
> > >
> > > By the way, thank you for your complete tutorial! 🙂
> > >
> > > Regards.
> > >
> > > "Tony Tanzillo" wrote in message
> > > news:7FCB7ABC9AAE76FD61A04B53E62E27B4@in.WebX.maYIadrTaRb...
> > > > I can't guarantee this will work, but here is how
> > > > I might approach the problem:
> > > >
> > > > All of this should be in your CComponent::dwgInFields(),
> > > > and should be supermessaged from CPanel::dwgInFields():
> > > >
> > > > Prior to the initial call to AcDbObject::dwgInFields(),
> > > > call AcDbDwgFiler::tell() to get the filer position,
> > > > and save it to a variable:
> > > >
> > > > long nAcDbObjectStart = pFiler->tell();
> > > >
> > > > Call AcDbObject::dwgInFields() the first time:
> > > >
> > > > AcDbObject::dwgInFields();
> > > >
> > > > Next get the filer position again, and calculate the
> > > > the number of bytes that AcDdObject::dwgInFields()
> > > > read from the filer:
> > > >
> > > > long nSizeAcDbObject = pFiler->tell() - nAcDbObjectStart;
> > > >
> > > > Call seek() to rewind to filer back to the start of
> > > > the first copy of AcDbObject's member data:
> > > >
> > > > pFiler->seek(nStartAcDbObject, 0);
> > > >
> > > > Allocate a memory buffer that holds nSize bytes
> > > >
> > > > void* pBuf1 = (void*) malloc(nSizeOfAcDbObject);
> > > >
> > > > Re-read the first copy of the AcDbObject member data in
> > > > binary form:
> > > >
> > > > pFiler->readBytes(pBuf1, nSizeOfAcDbObject);
> > > >
> > > > If your derived CComponent class wrote something to the
> > > > filer after the first call to AcDbObject::dwgOutFields(),
> > > > then read it now, so that the stream is positioned at the
> > > > first byte of the second erroneous copy of the AcDbObject
> > > > member data (if this instance contains it).
> > > >
> > > > Now save the filer position again:
> > > >
> > > > long nCPanelStart = pfiler->tell();
> > > >
> > > > Allocate a second buffer of the same size as pBuf1:
> > > >
> > > > void* pBuf2 = (void*) malloc(nSizeOfAcDbObject);
> > > >
> > > > Try to read the second copy the AcDbObject's member
> > > > data into the second buffer:
> > > >
> > > > pFiler->readBytes(pBuf2, nSizeOfAcDbObject);
> > > >
> > > > If you get an error from readBytes() or filerStatus()
> > > > returns something other than Acad::eOk, it probably means
> > > > you are reading an instance of your object that was
> > > > written by the newer version of your class, which does not
> > > > contain the second copy of AcDbObject's member data.
> > > >
> > > > In that case, you need to reset the filer position back
> > > > to nCPanelStart and just let CPanel::dwgInFields() read
> > > > from there.
> > > >
> > > > Otherwise, you have to compare the contents of pBuf1
> > > > and pBuf2 to see if they're identical. If they are, then
> > > > the filer contains the second erroneous copy of AcDbObject's
> > > > member data, and you just leave the filer at the current
> > > > position, for CPanel::dwgInFields() to start reading from
> > > >
> > > > memcmp(pBuf1, pBuf2, (size_t) nSizeOfAcDbObject);
> > > >
> > > > If the contents of the two buffers are not identical (that
> > > > is, memcmp() returned 0), this instance has no second copy
> > > > of AcDbObject's member data, and all that you should need to
> > > > do is reposition the filer back to where it was prior to the
> > > > second call to readBytes(), and CPanel::dwgInFields can take
> > > > it from there:
> > > >
> > > > pFiler->seek(nCPanelStart, 0);
> > > >
> > > > delete pBuf1;
> > > > delete pBuf2;
> > > >
> > > > Good luck.
> > > >
> > > >
> > > > "fpgs" wrote in message
> > > > news:00E6C3A919FC14CF196BA87821796442@in.WebX.maYIadrTaRb...
> > > > > Dear David,
> > > > >
> > > > > I have already read this but the problem is that I can't get back
on
> > DWG
> > > > file after read this info.
> > > > >
> > > > > Today, my files is looking like:
> > > > >
> > > > > ... AcDbObject | CComponent | AcDbObject | CPanel ...
> > > > >
> > > > > The second AcDbObject portion is wrong and causes my application
to
> > > crash
> > > > if I save the DWG file without my ARX loaded.
> > > > > The correct sequence must be:
> > > > >
> > > > > ... AcDbObject | CComponent | CPanel ...
> > > > >
> > > > > But, if I try to read a old drawing with the new version of ARX
when
> > it
> > > > tries to read the CPanel portion there will be the second AcDbObject
> > which
> > > > will crash AutoCAD with a fatal error.
> > > > >
> > > > > The perfect solution would be a way to know if a byte package on
the
> > DWG
> > > > file is relate to AcDbObject or CPanel so I can use appropriate
> process
> > to
> > > > read them.
> > > > >
> > > > > By the way, if nothing works, at the last solution I can create a
> new
> > > > version of this object and read the old drawing converting all old
> > objects
> > > > to the new ones. Obviously I will need to mantain this "garbage" on
my
> > App
> > > > suposing the on sometime in the future someone will open an old
> drawing.
> > > > >
> > > > > I'm planning to derive a class from CPanel and override only both
> dwg
> > > > In/Out Fields. Update all existing objects when the drawing is
opened.
> > > > >
> > > > > Regards,
> > > > > Fernando.
> > > > >
> > > > > "David Bartliff" wrote in message
> > > > news:533F4E3879960F640931E264B83C8763@in.WebX.maYIadrTaRb...
> > > > > Look in the ObjectARX help Chapter 12 -- Deriving from
> AcDbObject -
> > > > Object Version Support
> > > > > to see if it is possible to put in code to read in the existing
or
> > the
> > > > corrected version
> > > > > "fpgs" wrote in message
> > > > news:f0fa4ef.0@WebX.maYIadrTaRb...
> > > > > (The previous message was unreadable)
> > > > > Hello,
> > > > >
> > > > > I'm facing an AcDbObject derived class update issue.
> > > > > There is a base class called CComponent derived from
AcDbObject.
> > > > > There is a class called CPanel, derived from CComponent.
> > > > > Both implement their own dwgInFields / dwgOutFields members:
> > > > >
> > > > > CComponent::dwgInFields(AcDbDwgFiler* pFiler)
> > > > > {
> > > > > assertWriteEnabled();
> > > > > AcDbObject::dwgInFileds(pFiler);
> > > > > ....
> > > > > }
> > > > >
> > > > > CPanel::dwgInFields(AcDbDwgFiler* pFiler)
> > > > > {
> > > > > assertWriteEnabled();
> > > > > // The following line is wrong
> > > > > // CComponent will call AcDbObject's
> > > > > AcDbObject::dwgInFileds(pFiler);
> > > > >
> > > > > CComponent::dwgInFileds(pFiler);
> > > > > ...
> > > > > }
> > > > >
> > > > > CComponent::dwgOutFields(AcDbDwgFiler* pFiler)
> > > > > {
> > > > > assertReadEnabled();
> > > > > AcDbObject::dwgOutFileds(pFiler);
> > > > > ....
> > > > > }
> > > > >
> > > > > CPanel::dwgOutFields(AcDbDwgFiler* pFiler)
> > > > > {
> > > > > assertReadEnabled();
> > > > > // The following line is wrong
> > > > > // CComponent will call AcDbObject's
> > > > > AcDbObject::dwgOutFileds(pFiler);
> > > > >
> > > > > CComponent::dwgOutFileds(pFiler);
> > > > > ...
> > > > > }
> > > > >
> > > > > Several drawings are made with those classes but, as you may
> > already
> > > > noted, the guy who implemented these put an AcDbObject call on
CPanel
> > > class
> > > > which is not needed once it derives from CComponent that calls
> > AcDbObject
> > > > member on its dwgInFields/OutFields call.
> > > > >
> > > > > Due that, when serializing the DWG file, the portion of
> AcDbObject
> > > is
> > > > saved 2 times and there is no reason to do that. CComponent save it
> once
> > > and
> > > > CPanel save it again.
> > > > >
> > > > > The solution is to remove the AcDbObject calls but if I do
that
> > the
> > > > CPanel::dwgInFields() will fail because when it try to read its
> members
> > > they
> > > > are not there and will try to read bytes related to the wrong
> AcDbObject
> > > > save process.
> > > > >
> > > > > How can solve this?
> > > > >
> > > > > I can't loose all DWG generated by this buggy version.
> > > > >
> > > > > Regards,
> > > > > F.
> > > > >
> > > > >
> > > >
> > > >
> > > >
> > > >
> > >
> > >
> >
> >
> >
> >
>
>