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

AcDbObject derived class update

10 REPLIES 10
Reply
Message 1 of 11
fpgs
449 Views, 10 Replies

AcDbObject derived class update

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.
10 REPLIES 10
Message 2 of 11
fpgs
in reply to: fpgs

(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.
Message 3 of 11
Anonymous
in reply to: fpgs

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


style="PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
(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.

Message 4 of 11
Anonymous
in reply to: fpgs

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.

 


style="PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">

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


style="PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
(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.

Message 5 of 11
Anonymous
in reply to: fpgs

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.
>
>
Message 6 of 11
Anonymous
in reply to: fpgs

oops:

>
> pFiler->seek(nStartAcDbObject, 0);

Should be:

pFiler->seek(nAcDbObjectStart, 0);
Message 7 of 11
Anonymous
in reply to: fpgs

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.
> >
> >
>
>
>
>
Message 8 of 11
Anonymous
in reply to: fpgs

"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: blah blah blah

You have to be careful with Autodesk documentation, as
much of it has not been updated since R14.

That DevNote is dated 8/1/2000, and "Applies to R14.01'.
IOW, it's obsolete. I've used seek() and tell() in AutoCAD
2000, and I can attest that they're implemented.

In fact, I just did a little test on one of my own custom
objects, and I was able to rewind the filer and then use
readBytes() to re-read the AcDbObject member data, and it
seemed to work.

You probably should also check the filerType() to see what
type of filing operation is being done (the process should
only be done when your object is being streamed in from a
.dwg read operation).

Another thing you can do to eliminate the overhead of this
is to store a 'cookie' or something in the DWG file (in a
dictionary or extension dictionary that is guaranteed to be
read before any instances of your custom object are), that
tells you that the current drawing has already had all of
your custom objects converted to the new version. If you
did this, you would only have to apply this process once
per drawing with the old object versions (if they're saved).

Here is a more complete example (still not tested):

Acad::ErrorStatus
CComponent::dwgInFields(AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
assert(pFiler);
Acad::ErrorStatus es;
long nStartPos = pFiler->tell();
es = AcDbObject::dwgInFields(pFiler);
if( es != Acad::eOk )
return es;

// theoretically, you should only have to resort
// to this when reading objects from a dwg file.

if( pFiler->filerType() == AcDb::kFileFiler )
{
long nBufSize = pFiler->tell() - nStartPos;
pFiler->seek(nStartPos, AcDb::kSeekFromStart);
void* buf1 = malloc(nBufSize);
void* buf2 = malloc(nBufSize);
if( buf1 == NULL )
return Acad::eOutOfMemory;
if( buf2 == NULL )
{
free(buf1);
return Acad::eOutOfMemory;
}
pFiler->readBytes(buf1, nBufSize); // should not fail
long nEndPos = pfiler->tell();
es = pFiler->readBytes(buf2, nBufSize); // may fail:
if( es != Acad::eOk || memcmp(buf1, buf2, nBufSize) != 0 )
pFiler->seek(nEndPos, AcDb::kSeekFromStart);
else if( pFiler->FilerStatus() != Acad::eOk )
{
pFiler->resetFilerStatus();
pFiler->seek(nEndPos, AcDb::kSeekFromStart);
}
free(buf1);
free(buf2);
}

// read any new members added to CComponent here

return Acad::eOk;
}

And please consider using versioning !!!!
Message 9 of 11
Anonymous
in reply to: fpgs

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.
> > >
> > >
> >
> >
> >
> >
>
>
Message 10 of 11
Anonymous
in reply to: fpgs

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.
> > > >
> > > >
> > >
> > >
> > >
> > >
> >
> >
>
>
>
>
Message 11 of 11
Anonymous
in reply to: fpgs

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

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost