Message 1 of 7
noob question on custom classes
Not applicable
10-27-2004
01:57 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
When creating a custom class in Arx is it mandatory to have it derive from
some intrinsic Arx class (perhaps AcRxObject for "generic" classes)?
For example, I have put into my Arx project a class for reading and writing
INI files. I did not use the Arx wizard, I simply included the .cpp and .h
files and began calling methods from within my app. This seemed to work
fine, I got no errors or warnings and when running the app it operated
on the ini files as expected.
However, I subsequently added another class, again without the Arx wizard,
which was to read/manipulate attribute values of a particular block
insertion. Again I got no complaints from the compiler but after running the
app and attempting to close the drawing Autocad said it couldnt save
because "something" was open for read access. I stepped through the code and
for every occurance of opening a table or record there was
a statement to close it (which seemed to execute), but obviously "something"
did not close.
Im sure the chunk of code (posted below) in question is good, as I stole it
right out of one of the Arxlab samples and we all know that the folks at
AutoDesk write flawless code ;)
So Im wondering if it failed because the class involved was not an
"official" Arx (derived) class?
Also, if ALL my classes MUST be derived from intrinsic ones do I have to use
the Arx wizard to do so? When clicking on that option it complains that my
app is not a Dbx app and tells me to create a Dbx project to use it. My app
does not create any custom entities so it is not a Dbx app
or would any custom class constitute a custom "object" and therefore mean I
have a Dbx app??
On the other hand, if I can create custom classes without deriving, must I
still add the class to the Arx hierarchy and call ::rxinit? I would think
not.
Thanks for any help.
--
Perry Leets
Inovec Optimization and Control Systems
Eugene, Oregon
Here is the code that fails, I have shown the area where if I comment it
out, it will succeed even though it still opens tables and entities...
// titleblock.cpp: implementation of the titleblock class.
//
#include "stdafx.h"
#include "StdArx.h"
#include "resource.h"
#include "titleblock.h"
#include "dbmain.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
titleblock::titleblock()
{
AcDbEntity *pEnt ;
AcDbObjectId blockId ;
AcDbBlockTable *pBlkTable;
AcDbBlockTableRecord *pBlkTableRec;
AcDbBlockTableRecordIterator *pBlkRecIter ;
char *pBlkName;
acutPrintf("\nIn titleblock constructor");
// Get the block table
if ( (es = acdbHostApplicationServices ()->workingDatabase
()->getBlockTable (pBlkTable, AcDb::kForRead)) != Acad::eOk )
{
acutPrintf ("\nCouldn't open the block table!") ;
return ;
}
// Get the Model Space record and open it for read.
if ( (es = pBlkTable->getAt (ACDB_PAPER_SPACE, pBlkTableRec,
AcDb::kForWrite)) != Acad::eOk )
{
acutPrintf ("\nCouldn't get Paper Space! Drawing corrupt.\n") ;
pBlkTable->close () ;
return ;
}
pBlkTable->close () ;
// In this case, the Model Space block table record will provide the
iterator
// start at the beginning of the record and skip deleted entities
if ( (es = pBlkTableRec->newIterator (pBlkRecIter) ) != Acad::eOk )
{
acutPrintf ("\nCouldn't create Model Space iterator.") ;
pBlkTableRec->close () ;
return ;
}
for ( pBlkRecIter->start (); !pBlkRecIter->done () ; pBlkRecIter->step () )
{
// First open each entity for read, just to check its class
// if it's what we want, we can upgrade open later
// Don't bother with erased entities
if ( (es = pBlkRecIter->getEntity (pEnt, AcDb::kForRead)) != Acad::eOk )
{
acutPrintf ("\nCouldn't open entity.");
continue ;
}
if ( pEnt->isA() != AcDbBlockReference::desc () )
{
pEnt->close () ;
continue ;
}
// At this point there should be no entity open unless its a blockref
// Get the insert's block table record and compare its name
// to make sure we've got the right block. If so, set the layer
blockId = (AcDbBlockReference::cast (pEnt))->blockTableRecord () ;
// <--- COMMENT OUT start here
if ( acdbOpenObject ((AcDbObject *&)pBlkTableRec, blockId, AcDb::kForRead)
== Acad::eOk )
{
pBlkTableRec->getName(pBlkName);
acutPrintf("\n %s", pBlkName);
if ( strcmp (pBlkName, "title-b2") == 0 )
{
if ( pEnt->upgradeOpen () == Acad::eOk )
// setLayer also has an overload that takes a layer ID
// but to avoid global variables we specify the layer name
pEnt->setLayer ("0") ;
}
pBlkTableRec->close () ;
acdbFree (pBlkName) ;
}
// <--- COMMENT OUT end here
pEnt->close () ;
}
// delete, rather than close, the iterator object
delete pBlkRecIter ;
pBlkTableRec->close () ;
acutPrintf("\nDone with titleblock constructor");
}
titleblock::~titleblock()
{
acutPrintf("\nIn titleblock destructor");
}