noob question on custom classes

noob question on custom classes

Anonymous
Not applicable
484 Views
6 Replies
Message 1 of 7

noob question on custom classes

Anonymous
Not applicable
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"); }
0 Likes
485 Views
6 Replies
Replies (6)
Message 2 of 7

pkohut-og
Contributor
Contributor
You inadvertently left pBlockTableRec open. Close it right
before the for loop statement. I would stay away from the
ARX lab examples as their pretty ripe, if you get my meaning.

Paul Kohut
www.pkautomation.com
0 Likes
Message 3 of 7

Anonymous
Not applicable
Perry: You only need to derive classes from AcRxObject if you want or need them to participate in the Rx class hierarchy. In the code you posted, you need a call to pBlkTableRec->close() immediately before starting your loop. Then move the pBlkTableRec->close() at the end of the function inside your 'for' loop in order to close the open object each time through the loop. This sort of error would be more obvious if the local pBlkTableRec variable inside the loop had a different name from the function scope variable. :) -- Owen Wengerd President, ManuSoft ==> http://www.manusoft.com VP Americas, CADLock, Inc. ==> http://www.cadlock.com
0 Likes
Message 4 of 7

Anonymous
Not applicable
Right on Paul ! You know, I musta looked at this code for 2 hours and swore that all objects were freed, all tables were closed, all buttons buttoned and all snaps snapped. Although Im new to C/Arx I've been coding for several years and I shoulda learned by now that the longer I stare at a piece of code, the less I see ! Thanks for clearing up my vision :) Perry "pkohut" wrote in message news:7113598.1098919122375.JavaMail.jive@jiveforum2.autodesk.com... > You inadvertently left pBlockTableRec open. Close it right > before the for loop statement. I would stay away from the > ARX lab examples as their pretty ripe, if you get my meaning. > > Paul Kohut > www.pkautomation.com
0 Likes
Message 5 of 7

Anonymous
Not applicable
Thanks Owen, you and Paul both saw what my myopic eyes didnt ! So are you saying that there is no compelling reason to derive from the intrinsic classes, unless of course you are using members of those classes? Why else would I want or need my classes to "partcipate" in the hierarchy? I have been pouring over Charles Mcauley's book (programming Autocad 2000 with Arx) and attempting to digest the Arx documentation, but inevitably there are still unanswered questions. Thanks again for you patience with this fledglings elementary questions, Im sure more will follow! Perry "Owen Wengerd" wrote in message news:41805423$1_2@newsprd01... > Perry: > > You only need to derive classes from AcRxObject if you want or need them > to participate in the Rx class hierarchy. In the code you posted, you > need > a call to pBlkTableRec->close() immediately before starting your loop. > Then > move the pBlkTableRec->close() at the end of the function inside your > 'for' > loop in order to close the open object each time through the loop. This > sort of error would be more obvious if the local pBlkTableRec variable > inside the loop had a different name from the function scope variable. :) > -- > Owen Wengerd > President, ManuSoft ==> http://www.manusoft.com > VP Americas, CADLock, Inc. ==> http://www.cadlock.com > >
0 Likes
Message 6 of 7

Anonymous
Not applicable
Perry: > So are you saying that there is no compelling reason to derive from the > intrinsic classes, unless of course you are using members of those classes? Exactly. Furthermore, even when you do derive from Rx classes, you don't always need to give your class a new Rx class name (that is, you omit the ACRX_DECLARE_MEMBERS and ACRX...DEFINE_MEMBERS macros). > Why else would I want or need my classes to "partcipate" in the hierarchy? Two reasons are that you want it to be possible for your objects to be database resident or you want to utilize the run-time type identification mechanism that ARX provides. :) -- Owen Wengerd President, ManuSoft ==> http://www.manusoft.com VP Americas, CADLock, Inc. ==> http://www.cadlock.com
0 Likes
Message 7 of 7

Anonymous
Not applicable
Thanks a bunch for clearing that up Owen :) -- Perry Leets Inovec Optimization and Control Systems Eugene, Oregon "Owen Wengerd" wrote in message news:4180ce62$1_3@newsprd01... > Perry: > > > So are you saying that there is no compelling reason to derive from the > > intrinsic classes, unless of course you are using members of those > classes? > > Exactly. Furthermore, even when you do derive from Rx classes, you don't > always need to give your class a new Rx class name (that is, you omit the > ACRX_DECLARE_MEMBERS and ACRX...DEFINE_MEMBERS macros). > > > > Why else would I want or need my classes to "partcipate" in the hierarchy? > > Two reasons are that you want it to be possible for your objects to be > database resident or you want to utilize the run-time type identification > mechanism that ARX provides. :) > -- > Owen Wengerd > President, ManuSoft ==> http://www.manusoft.com > VP Americas, CADLock, Inc. ==> http://www.cadlock.com > >
0 Likes