Sunteți pe pagina 1din 75

Noţiuni de programare Object ARX sub AutoCAD2000

1.Mediul de programare ObjectARX 2000……………………………………...3


1.1.Introducere………………………………………………………………….3
1.2.Instalarea si structura mediului ObjectARX………………………………..3
1.3.Ce ofera pachetul ObjectARX……………………………………………...5
1.4.Comparatie intre AutoLISP, ADS si ARX…………………………………7
1.5.Bibliotecile de clase ale ObjectARX 2000…………………………………9
1.6.Functii uzuale ale mediului ObjectARX 2000……………………………..16
1.6.1. Functii AcDb…………………………………………………………16
1.6.2. Functii AcEd…………………………………………………………19
1.6.3.Functii AcUt…………………………………………………………..26
1.6.4.Functii de gestionare a memoriei……………………………………..28
1.7.Bazele aplicatiilor realizate cu pachetul ObjectARX……………………….28
1.7.1.Crearea unei aplicatii ObjectARX…………………………………….28
1.7.1.1.Crearea claselor proprii……………………………………..30
1.7.1.2.Mesajele AutoCAD catre aplicatia ObjectARX……………30
1.7.1.3.Secventa de evenimente intr-o aplicatie ObjectARX………36
1.7.1.4.Implementarea unui punct de intrare in aplicatie
pentru AutoCAD……………………………………………………………………37
1.7.1.5.Initializarea unei aplicatii ObjectARX………………………38
1.7.1.6.Pregatirea descarcarii aplicatiei……………………………..39
1.7.2.Exemplu de aplicatie…………………………………………………..40
1.7.3.Inregistrarea noilor comenzi…………………………………………..42
1.7.3.1.Stiva de comenzi…………………………………………….42
1.7.3.2.Ordinea de cautare…………………………………………..44
1.7.4.Incarcarea unei aplicatii ObjectARX………………………………….44
1.7.5.Descarcarea unei aplicatii ObjectARX………………………………..45
1.8.Construirea unei aplicatii ARX cu Microsoft Visual C++6.0………………47

Object ARX 1
2.Aplicatii de tip laborator…………………………………………….. 57
2.1. Hello.arx……………………………………………………..57
2.2. Fact.arx……………………………………………………….57
2.3. Alee.arx………………………………………………………58
2.4. Fan.arx……………………………………………………….58
2.5. Spirala.arx……………………………………………………58
2.6. Mir.arx……………………………………………………….59
2.7. Instructiuni de exploatare ……………………………………59

BIBLIOGRAFIE……….………………………………………………………..61
ANEXE…………………………………………………………………………..62

Object ARX 2
1. Mediul de programare ObjectARX 2000

1.1. Introducere

Mediul de programare ObjectARX este o extensie a AutoCAD® si contine


biblioteci C++ utilizabile in crearea unor noi aplicatii AutoCAD, extinderea claselor si
protocoalelor AutoCAD si crearea de noi comenzi care se comporta la fel ca si comenzile
interne ale AutoCAD-ului.
O aplicatie ObjectARX este o biblioteca dinamica de functii (DLL) care
partajeaza spatiul de adresare al AutoCAD-ului si face apeluri directe de functii catre
AutoCAD. Este posibila aduagarea de noi clase ObjectARX-ului, clasele implementate
putand fi exportate in scopul utilizarii lor si de catre alte aplicatii. Entitatile ObjectARX
create sunt practic identice cu entitatile de baza AutoCAD. Protocolul ObjectARX poate
fi extins prin adaugarea unor noi functii in interiorul claselor AutoCAD existente.

1.2. Instalarea si structura mediului ObjectARX 2000

Acest paragraf trateaza problema cerintelor de sistem, atat hardware cat si


software, necesare functionarii corecte a mediului ObjectARX. Este descris modul de
instalare al ObjectARX, precum si structura de directoare a mediului.

• Cerinte sistem:
Pentru a putea dezvolta aplicatii in ObjectARX, sunt necesare urmatoarele
componente minimale hardware si software:
- sistem de operare Windows NT® 4.0;
- mediu de dezvoltare Microsoft Visual C++® 32bit versiunea 6.0;
- calculator dotat cu un procesor Pentium® PC rulind la 90MHz sau mai
mult, 32 megaocteti si adaptor grafic cu o rezolutie minimala de 800x600 pixeli.

• Instalarea ObjectARX:
In momentul inceperii instalarii ObjectARX-ului, programul de instalare va
ghideaza pe tot parcursul instalarii.

Object ARX 3
Pentru instalarea ObjectARX se procedeaza in felul urmator:
1. Introduceti CD-ul care contine ObjectARX in unitatea de CDROM.
2. Daca rulati Windows NT 4.0 cu optiunea de AutoPlay activata, lasati-va
condusi de instructiunile afisate pe ecran.
3. Daca ati dezacrtivat optiunea AutoPlay din Windows NT 4.0, alegeti din
meniul Start optiunea Run, apoi alegeti unitatea de CDROM care contine CD-ul de
instalare si selectati programul “setup” aflat pe CD.

• Structura de directoare ObjectARX


Procedure de instalare implicita a mediului de programare ObjectARX va crea
directorul de baza C:\ObjectARX. In acest director vor mai fi create inca noua
subdirectoare al caror continut este descris mai jos.
arxlabs
Directorul arxlabs consta dintr-un set de subdirectoare, fiecare continand aplicatii
de tip laborator care demonstreaza modalitatile de implementare a cite unei functionalitati
ObjectARX. Aceste programe au parti lipsa, lasindu-l pe programator sa le completeze
spre a le face functionale. Bineinteles, fiecare sursa de program contine instructiuni care
explica modul in care programul trebuie completat pentru a functiona. De asemenea, in
fiecare subdirector se gaseste un alt subdirector care contine solutia problemei propuse.
classmap
Directorul classmap contine un desen in format AutoCAD care ilustreaza ierarhia
de clase din ObjectARX.
docs
Directorul docs contine fisiere help cu informatii suplimentare referitoare la toata
aspectele mediului de programare ObjectARX. Aceste fisiere includ explicatii complete
referitoare la clasele utilizate in ObjectARX, precum si a functiilor membre ale acestora,
si un ghid al dezvoltatorului ObjectARX.
docsamps
Directorul docsamps contine subdirectoare pentru fiecare din programele care au
fost folosite ca exemple in ghidul dezvoltatorului ObjectARX. Fiecare subdirector
contine codul sursa complet si un fisier cu explicatii (README).

Object ARX 4
inc
Acest director contine toate fisierele header necesare construirii unei aplicatii
ObjectARX.
lib
Acest director contine toate bibliotecile de functii ObjectARX intr-o forma
precompilata, biblioteci folosite de editorul de legaturi din Microsoft Visual C in
momentul crearii aplicatiei.
redistrib
Acest director contine un set de biblioteci dinamice de functii (DLL) care uneori
sunt necesare pentru a avea o aplicatie functionala. Este recomandabil pentru
dezvoltatorii de aplicatii ca, in cazul in care folosesc biblioteci de functii proprii, sa
copieze aceste fisiere in unul din directoarele prezente in caile de cautare al AutoCAD-
ului si sa foloseasca acest director pentru a salva eventualele biblioteci de functii proprii,
care vor fi distribuite impreuna cu aplicatia creata.
samples
In acest director se gasesc subdirectoare continind exemple de aplicatii complete
ObjectARX, utile in procesul de invatare a programarii in ObjectARX. Polysamp este
subdirectorul cu cea mai semnificativa aplicatie.
utils
Acest director cuprinde un set de utilitare aferente ObjectARX-ului, inclusiv brep
(reprezentarea frontierelor) si istorage (stocarea documentelor compuse). Fiecare
subdirector continind aceste utilitare, include si subdirectorele inc, lib si sample, in acesta
din urma gasindu-se exemple pentru utilitarul in cauza.

1.3. Ce ofera pachetul ObjectARX 2000

ObjectARX este un mediu de programare orientat pe obiecte pentru dezvoltatorii


de aplicatii AutoCAD, care le permite acestora sa foloseasca si sa extinda capacitatile
AutoCAD-ului. Bibliotecile de functii ObjectARX cuprind o serie de mijloace de
dezvoltare foarte puternice si care se pot adapta cu usurinta nevoilor fiecarui dezvoltator
de aplicatii. Astfel, se beneficiaza la maximum de arhitectura deschisa a AutoCAD-ului,

Object ARX 5
oferindu-se acces direct la functiile sale interne, la structurile de date, la sistemul grafic si
comenzile sale native. In acelasi timp, aceste biblioteci de functii sunt concepute sa
lucreze cu Visual LISP sau cu orice (API- application programming interface) alt mediu
de programare permitind oricarui dezvoltator sa isi aleaga platforma de programare care
se potriveste cel mai bine cu nevoile si experienta sa.
Biblioteca ObjectARX asigura satisfacerea urmatoarele cerinte ale unei aplicatii
AutoCAD:
• Accesul la structurile de date ale AutoCAD-ului
Un desen AutoCAD este o colectie de obiecte stocate intr-o baza de date. Aceste
obiecte sunt reprezentate nu numai de entitati grafice, dar si de structuri interne precum
tabelele de simboluri si dictionarele. ObjectARX faciliteaza accesul la aceste structuri de
date si totodata permite definirea de structuri proprii specifice unei anumite aplicatii.
• Interactiunea cu editorul AutoCAD
ObjectARX ofera clase si functii membre pentru comunicarea cu editorul
AutoCAD. Este posibila adaugarea de comenzi noi AutoCAD-ului, comenzi care vor fi
tratate la fel ca orice comanda AutoCAD standard. Aplicatia poate primi si raspunde
unei multitudini de notificari si mesaje care apar pe parcursul unei sesiuni AutoCAD.
• Crearea unei interfete folosind Microsoft® Foundation Classes (MFC)
Aplicatiile ObjectARX pot sa foloseasca librarii dinamice de functii MFC care
sunt partajate cu AutoCAD. Aceste biblioteci permit crearea de interfete grafice standard
Microsoft (GUI).
• Suport pentru interfete multi-document (MDI)
Aplicatiile ObjectARX suporta interfetele multi-document specifice AutoCAD-
ului, si este garantata interactiunea cu orice alta aplicatie din mediul Microsoft Windows.
• Crearea unor clase proprii
Este posibila imbunatatirea ierarhiei de clase ObjectARX prin crearea de noi
clase specifice unei anumite aplicatii. La crearea acestor clase se poate apela la biblioteca
extinsa de functii grafice existenta in ObjectARX.
• Crearea de aplicatii complexe
ObjectARX permite dezvoltarea de aplicatii complexe, furnizind urmatoarele
servicii:

Object ARX 6
- notificarea aplicatiilor;
- gestiunea tranzactiilor;
- multiplicare pe mai multe nivele;
- modificarea referintelor;
- extensibilitatea protocolului;
- suport pentru obiecte “proxy”.
• Interactiunea cu alte medii de dezvoltare
Aplicatiile ObjectARX pot comunica cu alte interfete de dezvoltare cum ar fi
Visual LISP, ActiveX si COM. De asemenea, pot sa interactioneze cu Internet-ul prin
asocierea de URL-uri unor entitati grafice care pot fi incarcate si salvate de pe World
Wide Web (WWW).

1.4. Comparatie intre AutoLISP, ADS si ARX

AutoLISP este un limbaj de interpretare care ofera un mecanism simplu de


adaugare de comenzi in AutoCAD. Desi exista anumite variatii de la o platforma la alta,
AutoLISP este in principiu un proces separat care comunica cu AutoCAD-ul prin
intermediul IPC (interprocess communication), asa cum se arata in figura 1.
Aplicatiile ADS sunt scrise in limbajul de programare C si apoi sunt compilate.
Cu toate acestea, la nivelul AutoCAD-ului, aplicatiile ADS sunt identitice cu aplicatiile
AutoLISP. Aplicatiile ADS sunt compuse dintr-un set de functii externe care sunt apelate
si incarcate de interpretorul AutoLISP. Aplicatiile ADS comunica cu AutoLISP-ul prin
IPC.
Mediul de prgramare ARX este diferit fata de ADS si AutoLISP din mai multe
puncte de vedere. Cea mai importanta diferenta consta in faptul ca o aplicatie ARX este o
biblioteca dinamica (DLL) care imparte spatiul de adrese al AutoCAD-ului si poate face
apel direct la AutoCAD, evitand astfel supraincarcarea IPC. Aplicatiile care comunica in
mod frecvent cu AutoCAD-ul, vor rula mai rapid in ARX decit in ADS sau AutoLISP. In
plus fata de imbunatatirea vitezei de executie, este permisa adaugarea de noi clase in
interiorul mediului de programare ARX, clase care pot fi exportate in scopul utilizarii lor
de catre alte aplicatii. Entitatile ARX create se comporta ca orice enititate de baza

Object ARX 7
AutoCAD, ele integrindu-se perfect in AutoCAD. Protocolul ARX poate fi extins prin
adaugarea de noi functii claselor AutoCAD deja existente, aceasta facindu-se in
momentul rularii aplicatiei ARX.

Aplicatia ADS

IPC

Procese AutoLISP
separate

IPC

AutoCAD

Apeluri directe
de functii
Aplicatia

Figura 1. Comunicatia cu AutoCAD-ul a aplicatiilor AutoLISP, ADS si ARX.

In diagrama din figura 2 se prezinta diferentele dintre AutoLISP, ADS, ADSRX si


ARX, in functie de viteza de executie, expunerea la erori, puterea fiecarui mediu de
programare si nivelul de cunostinte necesare pentru a folosi oricare din aceste interfete de
programare API (Application Programing Interface). Expunerea la erori este un
parametru care indica gravitatea unor posibile erori de programare. Desi ARX este cel
mai puternic dintre cele patru medii de programare, el are de asemenea cel mai ridicat
nivel de expunere la erori, o simpla eroare de programare in aplicatie putand conduce la
distrugerea structurilor de date AutoCAD. Celelalte medii de programare cer cunostinte
de programare de nivel mai redus dar, in acelasi timp, nu au puterea si versatilitatea
ARX-ului.

Object ARX 8
100

80

60 AutoLISP
ADS
40
ADSRX
20 ARX

0
Viteza Expunere Putere Expertiza
la erori

Figura 2. Comparatie intre modurile de functionare ale AutoLISP, ADS, ADSRX si


ARX.

1.5. Bibliotecile de clase ale ObjectARX 2000

Mediul de dezvoltare ObjectARX contine urmatoarele grupe de clase si functii:


• AcRx
- clase pentru crearea, inregistrarea si identificarea unei aplicatii in momentul
executiei.
• AcEd
- clase utilizate la adaugarea de noi comenzi AutoCAD-ului si pentru notificarea
aplicatiilor din AutoCAD.
• AcDb
- clase utilizate pentru accesul la baza de date AutoCAD.
• AcGi
- clase grafice pentru lucrul cu entitati AutoCAD.
• AcGe
- clase utilitare pentru calcule algebrice si geometrice.

Tabelul 1 contine numele bibliotecilor care sunt necesare pentru construirea unei
aplicatii ObjectARX. Toate aplicatiile ObjectARX trebuie sa utilizeze bibliotecile

Object ARX 9
acad.lib si rxapi.lib. In raport de functiile si clasele utilizate in aplicatia ObjectARX,
prezenta altor biblioteci este necesara.

Prefix Biblioteci ce contin clasa/prefixul


AcRx acad.lib, rxapi.lib, acrx15.lib
AcEd acad.lib, rxapi.lib, acedapi.lib, acrx15.lib
AcDb acad.lib, rxapi.lib, acdb15.lib, acrx15.lib
AcGi acad.lib, rxapi.lib, acgiapi.lib, acrx15.lib
AcGe acad.lib, rxapi.lib, acge15.lib, acrx15.lib

Tabelul 1. Biblioteci necesare la construirea unei aplicatii.

In sectiunea urmatoare sunt descrise mai pe larg fiecare din bibliotecile de baza
utilizate in aplicatiile ObjectARX.
• Biblioteca AcRx
Biblioteca AcRx pune la dispozitia dezvoltatorului clase la nivel sistem utilizate
pentru initializarea, legatura, identificarea si inregistrarea bibliotecilor dinamice (DLL).
Clasa de baza a acestei biblioteci este AcRxObject care ofera urmatoarele facilitati:
- identificarea unei clase in momentul rularii aplicatiei si analiza
mostenirii;
- adaugarea unui nou protocol unei clase existente in momentul rularii
aplicatiei;
- functii de comparare si echivalare a obiectelor;
- copierea obiectelor.
Biblioteca AcRx ofera de asemenea un set de macrouri C++ utile in crearea unor
noi clase ObjectARX, derivate din AcRxObject.
AcRxDictionary este o alta clasa importanta in aceasta biblioteca. Un dictionar
reprezinta legatura dintre un identificator de tip sir de caracatere si un obiect. Biblioteca
AcRx isi dispune clasele, obiectele si serviciile intr-un dictionar global, care este o
instanta a clasei AcRxDictionary. Aplicatiile pot adauga obiecte in acest dictionar astfel
incit ele sa fie disponibile altor aplicatii.

Object ARX 10
Ierarhia de clase a bibliotecii AcRx are urmatoarea structura:

AcRxObject

AcRxClass
AcRxDictionary
AcRxDynamicLinker
AcRxEvent
AcEditor
AcRxService
AcRxKernel
AcDbServices
AcEdServices
AcadAppInfo

Figura 3. Ierarhia de clase a bibliotecii AcRx.

Fiecare subclasa a AcRxObject are asociata un descriptor obiect (de tip


AcRxClass) care este utilizat pentru identificarea subclasei respective in momentul rularii
aplicatiei. ObjectARX ofera urmatoarele tipuri de functii:
- functii de testare a obiectelor pentru a vedea daca este vorba de un obiect al
unei clase particulare sau al unei clase derivate;
- functii care determina daca doua obiecte sunt derivate din aceeasi clasa sau
nu;
- functii care returneaza descriptorul pentru o clasa data.

• Biblioteca AcEd
Biblioteca AcEd furnizeaza clase care permit definirea si inregistrarea unor noi
comenzi in AutoCAD, comenzi care se vor comporta ca orice alta comanda interna a
AutoCAD-ului. Noile comenzi definite sunt numite "native" pentru ca ele rezida in
aceeasi structura interna ca si comenzile standard (stiva de comenzi,
AcEdCommandStack). De asemenea, in biblioteca AcEd mai gasim un editor de reactori
si un set global de functii care facilitateaza interactiunea cu AutoCAD-ul.

Object ARX 11
O clasa importanta in aceasta biblioteca este AcEditorReactor. Ea monitorizeaza
starea editorului AutoCAD si notifica aplicatia cind un anumit eveniment apare, cum ar
fi: lansarea, oprirea sau anularea unei comenzi de editare.
Ierarhia de clase a bibliotecii AcEd este prezentata in urmatoarea figura:
AcRxObject

AcEdCommand
AcEdCommandStack
AcEdUIContext
AcEdJig
AcEdInputFilter
AcEdInputPointMonitor
AcEdInputPointManager
AcEdSolidSubentitySelector
AcTransaction
AcDbTransactionManager
AcTransactionManager

Figura 4. Ierarhia de clase a bibliotecii AcEd.

• Biblioteca AcDb
Biblioteca AcDb furnizeaza clasele care compun baza de date AutoCAD. Aceasta
baza de date stocheaza toate informatiile referitoare la obiectele grafice, numite entitati,
care formeaza un desen AutoCAD, precum si informatiile despre toate obiectele non-
grafice (layer-e, tipuri de linii, tipuri de caractere) care fac de asemenea parte dintr-un
desen. Cu ajutorul bibliotecii AcDb pot fi manipulate si interogate instantele existente ale
entitatilor si obiectelor AutoCAD care compun un desen si pot fi definite noi instante ale
obiectelor stocate in baza de date AutoCAD.
Baza de date AutoCAD contine urmatoarele elemente principale:
- un set de noua tabele de simboluri care reprezinta obiecte AcDbDatabase si
datele membre ale acestor obiecte;
- un obiect dictionar (derivat din clasa AcDbDictionary) care ofera un index
referitor la desenul AutoCAD. Initial, aceast index contine identificatorii altor
patru dictionare utilizate de AutoCAD. Aplicatiile nou create au dreptul sa
adauge noi identificatori.

Object ARX 12
- un set de aproximativ 200 de variabile ale caror valori sunt setate de catre
AutoCAD.
Ierarhia de clase a bibliotecii AcDb arata ca in figura urmatoare:

AcRxObject
AcDbDictionary AcDbSymbolTable AcDbSymbolTableRecord
AcDbDictionaryDefault AcDbAbstractViewTablE AcDbAbstractViewTable
AcDbFilter AcDbViewportTable Record
AcDbLayerFilter AcDbViewTable AcDbViewportTable
AcDbSpatialFilter AcDbBlockTable Record
AcDbGroup AcDbDimStyleTable AcDbViewTableRecord
AcDbIDBuffer AcDbFontTable AcDbBlockTableRecord
AcDbIndex AcDbLayerTable AcDbDimStyleTableRecord
AcDbLayerIndex AcDbLinetypeTable AcDbFontTableRecord
AcDbSpatialIndex AcDbRegAppTable AcDbLayerTableRecord
AcDbLongTransaction AcDbTextStyleTable AcDbLinetypeTableRecord
AcDbMlineStyle AcDbUCSTable AcDbRegAppTableRecord
AcDbPlaceholder AcDbTextStyleTableRecord
AcDbPlotSettings AcDbUCSTableRecord
AcDbLayout

AcDbProxyObjects AcDbRasterImageDef
AcDbXrecord AcDbRasterImageDefReaactor
AcDbEntity AcDbRastervariables

Figura 5. Ierarhia de clase a bibliotecii AcDb.

• Biblioteca AcGi
Biblioteca AcGi pune la dispozitie interfetele grafice utilizate la desenarea
entitatilor AutoCAD. Aceasta biblioteca este folosita de catre functiile membre
worldDraw(), viewportDraw() si saveAs() ale clasei AcDbEntity, toate facind parte din
protocolul standard. Functia worldDraw() trebuie sa fie definita de catre toate clasele de
entitati particulare. Obiectul AcGiWorldDraw ofera un API prin care functia
AcDbEntity::worldDraw() poate sa reprezinte grafic desenul vazut din toate directiile, in
acelasi timp. In mod similar, AcGiViewportDraw ofera un API prin care functia
AcDbEntity::viewportDraw() poate sa reprezinte grafic desenul vazut dintr-o directie
data.
Ierarhia de clase a bibliotecii AcGi este prezentata in figura 6.

Object ARX 13
AcRxObject
AcGiCommonDraw
AcGiWorldDraw
AcGiContext
AcGiEdgeData
AcGiFaceData
AcGiGeometry
AcGiViewportGeometry
AcGiWorldGeometry
AcGiLinetypeEngine
AcGiSubentityTraits
AcGiDrawableTraits
AcGiTextStyle
AcGiVertexData
AcGiViewport
AcGiDrawable
AcGiGlyph

Figura 6. Ierarhia de clase a bibiotecii AcGi.

• Biblioteca AcGe
Biblioteca AcGe este folosita de biblioteca AcDb si ofera clase utilitare, precum
clase de vectori si matrici folosite in calculul geometric 2D si 3D. De asemenea, ea ofera
obiecte grafice de baza, cum ar fi: puncte, curbe si suprafete.
Biblioteca AcGe este formata din doua subseturi de baza: clase pentru calcul
geometric 2D si clase pentru calcul geometric 3D. Clasele de baza ale acestei biblioteci
sunt AcGeEntity2d si AcGeEntity3d. Mai sunt incluse si clasele AcGePoint2d,
AcGeVector2d si AcGeMatrix2d. Aceste clase sunt utilizate pentru calcul gemoetric de
baza cum ar fi: adaugarea unei vector la un punct, calcularea rezultatului de intersectie a
doi vectori si calcularea produsului a doua matrici. Clasele de nivel superior ale acestei
biblioteci sunt implementate tinind cont de clasele de baza.
Ierarhia de clase a bibliotecii AcGe este prezentata in figura 7.

Object ARX 14
AcGeEntity2d AcGeEntity3d
AcGeBoundBlock2d AcGeBoundBlock3d
AcGeClipBoundery2d AcGeCurve3d
AcGeCurve2d AcGeCircArc3d
AcGeCircArc2d AcGeCompositeCurve3d
AcGeCompositeCurve2d AcGeEllipArc3d
AcGeEllipArc2d AcGeExternalCurve3d
AcGeExternalCurve2d AcGeLinearEnt3d
AcGeLinearEnt2d AcGeLine3d
AcGeLine2d AcGeLineSeg3d
AcGeLineSeg2d AcGeRay3d
AcGeRay2d AcGeMatrix3d
AcGeOffsetCurve2d AcGeOffsetCurve3d
AcGeSplineEnt2d AcGeSplineEnt3d
AcGeCubicSplineCurve2d AcGeCubicSpline
AcGeNurbCurve2d Curve3d
AcGePolyline2d AcGeNurbCurve3d
AcGeCurveCurveInt2d AcGePolyline3d
AcGePointEnt2d AcGeAug
AcGePointOnCurve2d Polyline3d
AcGePosition2d AcGeCurveCurveInt3d
AcGeCurveSurfInt
AcGeCurveBoundery AcGePointEnt3d
AcGeContext AcGePointOnCurve3d
AcGeDwgIO AcGePointOnSurface
AcGeDxfIO AcGePosition3d
AcGeFileIO AcGeSurfSurfInt
AcGeFiler AcGeSurface
AcGeInterval AcGeCone
AcGeKnotVector AcGeCylinder
AcGeLibVersion AcGeExternalBounded
AcGeMatrix2d Surface
AcGeMatrix3d AcGeExternalSurface
AcGePoint2d AcGeNurbSurface
AcAxPoint2d AcGeOffsetSurface
AcGePoint3d 1 AcGePlanarEnt
AcAxPoint3d AcGeBoundedPlanet
AcGeScale2d AcGePlane
AcGeScale3d AcGeSphere
AcGeTol AcGeTorus
AcGeVector2d
AcGeVector3d

Figura7. Ierarhia de clase a bibliotecii AcGe.

Object ARX 15
1.6. Functii uzuale ale mediului ObjectARX 2000

Prezentarea functiilor se face folosind urmatoarea conventie pentru corpurile de


litera:
*curier – pentru nume simbolice care trebuie scrise ca atare;
*italic – pentru nume de argumente care pot fi alese de utilizator.

1.6.1. Functii AcDb

Functiile din aceasta catogorie sunt precedate de prefixul “acdb”. S-a considerat
oportuna aceasta notatie deoarece toate functiile realizeaza un anumite fel de interactiune
cu baza de date asociata unui desen AutoCAD.

• int acdbAngToF(const char str, int unit, ads_real* v);


Converteste str, care reprezinta un unghi in formatul specificat de unit, intr-un
pointer de tip float, cu dubla precizie.

• int acdbDictAdd(const ads_name dictname, const char* symname, const


ads_name newobj);
Adauga obiectul non-grafic newobj la dictionarul dictname. Argumentul symname
este numele cheie al obiectului care va fi introdus in dictionar si trebuie sa fie un nume
unic, care nu exista deja in dictionar. Daca acdbDictAdd() se executa cu succes,
returneaza RTNORM, iar daca eseueaza, returneaza RTERROR.

• struct resbuf* acdbDictNext(const ads_name dict, int rewind);


Parcurge dictionarul specificat prin dict si returneaza urmatoarea intrare in
dictionar sub forma unui result buffer. Daca executia functiei esueaza, variabila sistem
ERRNO este setata la o valoare care indica motivul esuarii.

• int acdbDictRemove(const ads_name dictname, const char* symname);

Object ARX 16
Elimina din dictionarul dictname intrarea specificata prin cheia symname. Daca
functia se executa cu succes, se returneaza RTNORM. Daca esueaza, se returneaza
RTERROR, iar variabila sistem ERRNO este setata la o valoare care indica motivul
esuarii.

• int acdbDictRename(const ads_name dictname, const char* oldsym, const char*


newsym);
Are ca efect modificarea cheii corespunzatoare intrarii in dictionarul dictname, de
la oldsym la newsym.Daca funtia se executa cu succes, se returneaza RTNORM. In
situatiile in care cheia oldsym nu este prezenta in dictionar, numele dictname sau newsym
sunt invalide, sau newsym este deja prezent in dictionar, se returneaza RTERROR, iar
variabila sistem ERRNO este setata la o valoare care indica motivul esuarii.

• int acdbEntDel(const ads_name ent);


Are ca efect stergerea entitatii specificate prin ent, daca este prezenta in desenul
curent. Daca entitatea ent a fost stearsa in sesiunea curenta de editare, ea este restaurata.

• struct resbuf* acdbEntGet(const ads_name ent);


Entitatea cu numele ent este regasita in baza de data corespunzatoare desenului si
este returnata sub forma unei liste asociate.

• int acdbEntLast(ads_name result);


In urma executie, result va contine numele ultimei entitati principale nesterese din
baza de date corespunzatoare desenului. Nu este obligatoriu ca entitatea sa se afle pe
ecran sau intr-un nivel (layer) dezghetat, dar nu este posibila selectarea unei entitati non-
grafice. Daca functia se executa cu succes, se returneaza RTNORM. Daca esueaza, se
returneaza RTERROR, iar variabila sistem ERRNO este setata la o valoare care indica
motivul esecului.

• int acdbEntMake(const struct resbuf* ent);

Object ARX 17
Creaza o noua entitate prin adaugarea entitatii specificate prin ent la baza de date
corespunzatoare desenului. Argumentul ent este o lista de tip result buffer, avand aceeasi
structura cu lista returnata de acdbEntGet().

• int acdbEntMod(const struct resbuf* ent);


Functia actualizeaza datele corespunzatoare entitatii specificate prin ent.
Argumentul ent trebuie sa aiba acelasi format ca lista returnata de acdbEntGet().

• int acdbEntNext(const ads_name ent, ads_name result);


Daca ent are valoarea null, argumentul result va contine numele primei entitati
neeliminate din baza de date. In caz contrar, result va contine numele entitatii care ii
urmeaza in baza de date entitatii specificate prin ent. Daca functia se executa cu succes,
se returneaza RTNORM. Cand executia functiei esueaza, acest fapt se intampla fie pentru
ca ent nu este un nume de entitate valid in baza de date curenta, fie pentru ca ent este
ultima entitate. In caz de esec, se returneaza RTERROR, iar variabila de sistem ERRNO
este setata la o valoare care indica motivul esecului.

• int acdbEntUpd(const ads_name ent);


Are ca efect regenerarea pe ecran a entitatii specificate prin ent. In cazul
entitatilor complexe, se redeseneaza intreaga entitate, inclusiv vertexurile de polilinie si
atributele de bloc. Argumentul ent poate fi specificat si sub forma de subentitate. In acest
caz, inainte de redesenare, functia gaseste entitatea principala. Daca functia se executa cu
succes, se returneaza RTNORM. In caz de esec, se returneaza RTERROR, iar variabila
de sistem ERRNO este setata la o valoare care indica motivul esecului.

• void acdbFail(const char* str);


Este utilizata atunci cand se intalneste o eroare recuperabila. Are ca efect tiparirea
unui mesaj de eroare, continand numele aplicatiei si argumentul str.

• int acdbHandEnt(const char* handle, ads_name entres);

Object ARX 18
Returneaza in argumentul entres numele entitatii care are asociat numele de
handle specificat prin handle. Daca functia se executa cu succes, se returneaza
RTNORM. Daca esueaza, se returneaza RTERROR, iar variabila de sistem ERRNO este
setata la o valoare care indica motivul esecului.

• int acdbInters(const ads_point from1, const ads_point to1, const ads_point from2,
const ads_point to2, int teston, ads_point result);
Examineaza doua linii si returneaza in argumentul result punctul lor de
intersectie, daca acesta exista. Cele doua linii sunt specificate prin capetele lor, respectiv
from1, to 1 pentru prima linie, si from2, to2 pentru a doua linie. Daca argumentul teston
are valoarea 0, cele doua linii se considera a fi infinite. Daca teston este 1, punctul de
intersectie trebuie sa se incadreze pe lungimea celor doua segmente. Daca functia se
executa cu succes, se returneaza RTNORM. In caz contrar, se returneaza un cod de
eroare.

• int acdbRegApp(const char* appname);


Inregistreaza numele de aplicatie appname in baza de date corespunzatoare
desenului curent. Argumentul appname trebuie sa fie unic pentru aplicatia respectiva.

1.6.2. Functii AcEd

Urmatoarele functii au fost grupate pe considerentul ca toate realizeaza operatii


care implica interactiunea cu utilizatorul si de editare. Acesta este motivul pentru care
toate functiile din aceasta categorie sunt precedate de prefixul “aced”.

• int acedArxLoad(const char* app);


Are ca efect incarcarea unui modul ARX. Corespunde functiei (arxload) din
AutoLISP. Functia returneaza un cod de eroare atunci cand argumentul app nu reprezinta
un nume valid, sau atunci cand fisierul nu poate fi incarcat.

• struct resbuf* acedArxLoaded(void);

Object ARX 19
Returneaza un pointer la o lista continand aplicatiile ARX incarcate la momentul
curent. Numele fiecarei aplicatii este returnat sub forma de string in result-buffer-ul
corespunzator aplicatiei. Daca nici o aplicatie externa nu este incarcata, functia
returneaza NULL.

• int acedArxUnload(const char* app);


Are ca efect descarcarea unui modul ARX. Corespunde functiei (arxunload) din
AutoLISP. Functia returneaza un cod de eroare atunci cand argumentul app nu indica un
program ARX incarcat.

• int acedCommand(int rtype, ...);


Executa una sau mai multe comenzi AutoCAD. Argumentul functiei
acedCommand() este de lungime variabila. Argumentele functiei sunt tratate ca perechi.
Primul element al fiecarei perechi reprezinta tipul argumentului care urmeaza, iar al
doilea corespunde argumentului respectiv. Ultimul argument din lista nu are pereche si
trebuie sa aiba valoarea 0 sau RTNONE. Daca 0 sau RTNONE este singurul argument
din lista, functia va fi echivalenta apasarii combinatiei [CTRL]+[C] de la tastatura, care
are ca efect anularea majoritatii comenzilor AutoCAD.

• int acedDefun(const char* sname, short funcno);


Defineste o functie dintr-o aplicatie ARX ca o functie exerna AutoLISP.
Argumentul sname invoca functia din AutoLISP. Argumentul funcno identifica functia in
blocul care urmeaza mesajului kInvkSubrMsg din AutoLISP. Valoarea acestui argument
trebuie sa fie non-negativa.

• int acedEntSel(const char* str, ads_name entres, ads_point ptres);


Prin aceasta functie se cere utilizatorului sa selecteze o entitate prin specificarea
unui punct. Functia returneaza atat numele entitatii selectate, in argumentul entres, cat si
punctul care a fost introdus pentru selectarea entitatii, in argumentul ptres. Argumentul
str reprezinta mesajul afisat inainte de cererea de selectie. Acest argument este optional;

Object ARX 20
daca este null, prompterul implicit este “select object”. Functia acedEntSel() nu
returneaza numele obiectelor non-grafice.

• int acedGetAngle(const ads_point pt, const char* prompt, ads_real* result);


Prin aceasta functie se cere utilizatorului introducerea unui unghi, tinandu-se cont
de valoarea curenta a variabilei de sistem ANGBASE. Argumentul pt specifica punctul
de baza al unghiului in UCS-ul curent (UCS = sistemul de coordonate al utilizatorului).
Argumentul prompt contine un mesaj care este tiparit inainte de cerere. Atat pt, cat si
prompt sunt optionale; daca nu se doreste utilizarea lor, se introduce un pointer nul.

• struct resbuf* acedGetArgs();


Returneaza argumentele unei functii externe apelate. Rezultatul este sub forma
unui pointer catre lista pe care AutoLISP a transmis-o aplicatiei ARX prin intermediul
unui mesaj kInvkSubrMsg. Daca AutoLISP nu a transmis nici un argument aplicatiei
ARX, acedGetArgs() returneaza un pointer null.

• int acedGetCorner(const ads_point pt, const char* prompt, ads_point result);


Prin aceasta functie se cere utilizatorului introducerea celui de al doilea colt al
unui dreptunghi. Argumentul result este setat la valoarea punctului ales. Argumentul pt
nu este optional si reprezinta punctul de baza al dreptunghiului in UCS-ul curent.
Argumentul prompt este optional si corespunde mesajului afisat inainte de cererea de
selectie. Daca nu se doreste utilizarea lui, se introduce in loc un pointer nul.

• int acedGetDist(const ads_point pt, const char* prompt, ads_real* result);


Prin aceasta functie se cere utilizatorului introducerea unei distante lineare.
Argumentul result este setat la valoarea distantei selectate. Argumentul pt reprezinta
punctul de baza in UCS-ul curent. Prompt corespunde mesajului afisat inainte de cererea
de selectie. Atat pt, cat si prompt sunt optionale. Daca nu se doreste utilizarea lor, ele se
inlocuiesc cu cate un pointer nul.

• int acedGetInput(char* str);

Object ARX 21
Returneaza un cuvant cheie introdus de utilizatorul AutoCAD in timpul apelului
uneia dintre functiile: acedGetXxx(), acedEntSel() sau acedDragGen(). Argumentul str
va contine maxim 132 de caractere.

• int acedGetInt(const char* prompt, int* result);


Se cere utilizatorului introducerea unui intreg si seteaza argumentul result la
valoarea selectata. Prompt reprezinta un mesaj care este afisat inainte de cerere. Daca nu
se doreste utilizarea lui, se inlocuieste cu pointerul NULL. Utilizatorul AutoCAD poate
introduce orice valoare intreaga intre –32 768 si +32 767.

• int acedGetPoint(const ads_point pt, const char* prompt, ads_point result);


Prin aceasta functie se cere utilizatorului introducerea unui punct. Result va
contine valoarea aleasa. Argumentul pt reprezinta un punct de baza in UCS-ul curent.
Prompt este mesajul afisat inainte de cerere. Atat pt, cat si prompt sunt optionale. Daca
nu se doreste utilizarea lor, se inlocuiesc cu pointerul NULL. Argumentul result trebuie
sa pointeze catre o zona de memorie suficient de mare, pentru a contine valoarea unui
punct 3D.

• int acedGetString(int cronly, char* prompt, char* result);


Prin aceasta functie se cere utilizatorului introducerea unui sir de caractere. Prin
argumentul cronly se specifica daca sirul de caractere poate contine spatii. Prompt
reprezinta mesajul afisat inainte de cerere. Functia returneaza maxim 132 de caractere,
deci result nu trebuie sa fie mai mare de 133 de caractere.

• int acedGetVar(const char* sym, struct resbuf* result);


Returneaza valoarea curenta a variabilei de sistem AutoCAD, specificata prin
sym, si depune rezulatul in result. Argumentul sym trebuie sa contine un nume valid de
variabila de sistem (indiferent daca se folosesc sau nu majuscule). Argumentul result
trebuie sa pointeze catre o structura resbuf, deoarece variabilele de sistem constau dintr-o
varietate de tipuri.

Object ARX 22
• int acedGrDraw(const ads_point from, const ads_point to, int color, int hl);
Are ca efect desenarea unui vector intre doua puncte, specificate prin from si to.
Argumentul color corespunde unei culori AutoCAD (poate lua valori intre 0-250). Daca
argumentul hl este diferit de zero, vectorul este desenat in mod accentuat, iar daca
valoarea lui hl este 0, vectorul este desenat in modul de afisare normal.

• int acedHelp(char* filename, char* topic, int command);


Furnizeaza un fisier de help, folosind fisierul Windows Help filename.

• int acedInitGet(int val, const char* kwl);


Stabileste diferite optiuni pentru a fi folosite de urmatoarea functie care necesita
introducerea de date de catre utilizator (de exemplu: acedGetXxx(), acedDragGen(),
acedEntSel()).
Prin argumentul val se specifica valorile acceptate ca intrare. Argumentul kwl
mentioneaza cuvantul cheie acceptat ca raspuns. Daca nu se doreste utilizarea acestui
argument, se inlocuieste cu un sir de caractere nul sau vid.

• int acedInvoke(const struct resbuf* args, struct resbuf** result);


Permite apelul unei functii externe definite intr-o alta aplicatie ARX. Daca
acedInvoke() returneaza RTNORM, inseamna ca functia externa a fost apelata cu succes,
dar aceasta nu garanteaza calitatea rezultatului returnat. Pentru a determina rezultatul
apelului, programul trebuie sa prevada explicit o astfel de analiza. Daca functia externa a
esuat sau nu returneaza nici o valoare, argumentul result va fi NULL; altfel, result va
pointa catre o lista ce contine valorile returnate.
• int acedMenuCmd(const char* str);
Activeaza unul dintre submeniurile meniului AutoCAD curent. Argumentul str
are urmatoarea structura:
“section = submenu”, unde section specifica meniul principal, iar submenu
reprezinta submeniul care se doreste a fi activat in sectiunea respectiva.

• int acedSetVar(const char* sym, const struct resbuf* val);

Object ARX 23
Are ca efect setarea variabile de sistem AutoCAD, specificate prin sym, la
valoarea continuta in result-buffer-ul val. Argumentul sym trebuie sa contina un nume
valid de variabila sistem (indiferent daca este sau nu cu majuscule). Argumentul val
trebuie sa fie initializat si trebuie sa contina o valoare adecvata pentru variabila de sistem
avuta in vedere.

• int acedSSAdd(const ads_name ename, const ads_name sname, ads_name result);


Creaza o noua multime de selectie sau adauga o entitate la o multime de selectie
existenta. Argumentul ename corespunde entitatii, iar sname corespunde multimii de
selectie. Daca atat ename, cat si sname sunt pointeri nuli, acedSSAdd() creaza o multime
de selectie vida. Daca ename este o entitate valida, dar sname este nul, acedSSAdd()
creaza o noua multime de selectie, avand ca singur membru entitatea ename. In toate
situatiile, argumentul result va contine numele multimii de selectie noi sau actualizate.
Daca entitatea ename exista deja in multime, acedSSAdd() ignora cererea, fara a genera
eroare.

• int acedSSDel(const ads_name ename, const ads_name ss);


Se sterge entitatea specificata prin ename din multimea de selectie ss. Atat ename,
cat si ss trebuie sa reprezinte nume valida pentru desenul curent. Daca functia se executa
cu succes, se returneaza RTNORM. In caz contrar, se returneaza un cod de eroare, iar
varabila de sistem ERRNO este setata la o valoare indicand motivul esecului.

• int acedSSGet(const char* str, const void* pt1, const void* pt2, const struct
resbuf* filter, ads_name ss);
Returneaza o multime de selectie obtinuta prin mentionarea unui mod de selectie
AutoCAD. Argumentul str este optional si reprezinta modul de selectie a entitatilor.
Argumentul filter permite selectarea entitatilor in functie de tip, sau in functie de anumite
proprietati. Argumentele pt1 si pt2 sunt optionale si sunt specifice anumitor moduri de
selectie.

• int acedSSLength(const ads_name sname, long* len);

Object ARX 24
Returneaza o valoare intreaga len care contine numarul de entitati cuprinse in
multimea de selectie sname. Multimile de selectie nu contin niciodata entitati identice.

• int acedSSName(const ads_name ss, long i, ads_name entres);


Returneaza numele entitatii aflata in pozitia i din multimea de selectie ss.
Entitatile sunt numarate incepand cu 0, deci i trebuie sa fie nenegativ si sa nu fie mai
mare decat indexul ultimei entitati din multimea de selectie.

• int acedTrans(const ads_point pt, const struct resbuf* from, const struct resbuf*
to, int disp, ads_point result);
Are ca efect translatarea unui punct dintr-un sistem de coordonate in altul.
Argumentul from reprezinta sistemul de coordonate initial, iar to corespunde sistemului
de coordonate in care se face translatarea.

• int acedUndef(const char* sname, short funcno);


Elimina o functie externa, care a fost mai inainte declarata printr-un apel al
functiei acedDefun(). Argumentul sname este numele functiei, iar funcno corespunde
codului intreg, nenegativ al functiei. Ambele argumente trebuie sa coincida cu
argumentele utilizate anterior in apelul acedDefun().

• int acedUsrBrk();
Verifica daca utilizatorul a apasat combinatia de taste [CTRL]+[C] pentru a
intrerupe executia curenta a unei functii externe. Aceasta functie permite aplicatiilor
ARX care efectueaza operatii complexe si de lunga durata, sa verifice daca nu apar
intreruperi de la utilizator.

• void acrx_abort(const char* format, ...);


Are ca efect stoparea unei aplicatii ARX, cerand utilizatorului sa salveze
modificarile facute pana in momentul inceperii comenzii curente. Functia preia ca
argumente un sir de caractere de control si alte cateva argumente optionale, la fel ca
acutPrintf().

Object ARX 25
1.6.3. Functii AcUt

Functiile descrise in acest paragraf realizeaza operatii utilitare, fiind precedate de


prefixul “acut”.

• ads_real acutAngle(const ads_point pt1, const ads_point pt2);


Determina unghiul dintre o linie si axa X a sistemului curent de coordonate a
utilizatorului (UCS). Linia este definita prin cele doua puncte: pt1 si pt2. Functia
calculeaza unghiul in sens anti-orar si returneaza valoarea lui in radiani.

• int acutCvUnit(ads_real value, const char* oldunit, const char* newunit,


ads_real* result);
Transforma o unitate de masura in alta. Converteste valoarea value, exprimata
inunitati specificate prin oldunit, in unitati newunit si seteaza result la valoarea rezultata.
Atat oldunit, cat si newunit trebuie sa fie siruri de caractere care sa respecte specificatiile
din fisierul acad.unt.

• ads_real acutDistance(const ads_point pt1, const ads_point pt2);


Returneaza distanta dintre punctele pt1 si pt2. Argumentele pt1 si pt2 pot fi
puncte tridimensionale.

• int acutIsAlNum(int c);


Returneaza TRUE in cazul in care caracterul c este alfanumeric; altfel, returneaza
FALSE.

• int acutIsCntrl(int c);


Verifica daca argumentul c este sau nu un caracter de control. Returneaza TRUE
sau FALSE.

• int acutIsUpper(int c);

Object ARX 26
Verifica daca argumentul c este sau nu o majuscula. Returneaza TRUE sau
FALSE.

• int acutIsPrint(int c);


Verifica daca argumentul c poate sau nu sa fie tiparit. Returneaza TRUE sau
FALSE.

• int acutIsPunct(int c);


Verifica daca argumentul c este sau nu un semn de punctuatie. Returneaza TRUE
sau FALSE.

• struct resbuf* acutNewRb(int v);


Returneaza un pointer la result-buffer si seteaza campul restype la valoarea v.
Argumentul v trebuie sa corespunda cu unul dintre codurile definite in adscodes.h. Daca
v nu are o valaore valida, acutNewRb() returneaza totusi un pointer, dar apelul ulterior al
functiei acutRelRb() poate elibera memorie de dimensiune necorespunzatoare.

• void acutPolar(const ads_point pt, ads_real angle, ads_real dist, ads_point result)
Determina un punct pe baza coordonatelor polare. In urma executiei functiei,
result va contine punctul aflat la unghiul angle si distanta dist fata de punctul initial pt.
Result si pt sunt puncte tridimensionale. Unghiul angle este exprimat in radiani si este
masurat in sens anti-orar fata de axa X a sistemului de coordonate. Functia nu returneaza
nici o valoare.

• int acutRelRb(struct resbuf* rb);


Are ca efect eliberarea memoriei alocate result-buffer-ului rb.

• int acutToUpper(int c);


Daca argumentul c este o majuscula, functia il returneaza ca atare. In caz contrar,
returneaza majuscula corespunzatoare lui c.

Object ARX 27
1.6.4. Functii de gestionare a memoriei

• void* acad_calloc(int count, int sz);


Aloca o zona de memorie argumentului count, avand dimensiunea sz. Returneaza
un pointer la primul element al zonei alocate.

• void acad_free(void* buff);


Elibereaza o zona de memorie alocata anterior cu functiile acad_malloc(),
acad_realloc() sau acad_calloc().

• void* acad_malloc(size_t sz);


Aloca o zona de memorie suficient de mare pentru a pastra un obiect a carui
dimensiune este returnata de acad_msize(). Daca memoria nu poate fi alocata, functia
returneaza un pointer nul.

• int acad_msize(void* buff);


Returneaza dimensiunea in byti a zonei de memorie catre care pointeaza buff.

1.7. Bazele aplicatiilor realizate cu pachetul ObjectARX

Acest capitol trateaza modalitatatile de scriere si de executie ale unei aplicatii


ObjectARX. De asemenea, listeaza toate mesajele trimise de catre AutoCAD aplicatiei
ObjectARX si arata cum trebuie sa raspunda aplicatia ObjectARX la aceste mesaje. In
acest capitol se mai discuta despre inregistrarea unor noi comenzi in AutoCAD, cum se
incarca si cum se descarca o aplicatie, functia de incarcare la cerere a AutoCAD-ului si
gestionarea erorilor.

1.7.1. Crearea unei aplicatii ObjectARX

O aplicatie ObjectARX este o biblioteca dinamica de functii (DLL) care


partajeaza spatiul de adrese al AutoCAD-ului si face apeluri directe de functii AutoCAD.

Object ARX 28
Aplicatiile ObjectARX implementeaza in general comenzi ce pot fi accesate din
interiorul AutoCAD-ului. Aceste comenzi sunt implementate adeseori utilizind clase
proprii. Crearea unei aplicatii ObjectARX presupune urmatorii pasi generali:
1.Crearea de clase proprii care sa implementeze noile comenzi.
Puteti deriva clasele proprii din majoritatea claselor continute in ierarhia
de clase ObejctARX si din tabelele de simboluri atasate acestora.

2. Stabilirea tipurilor de mesaje AutoCAD carora aplicatia le va raspunde.


AutoCAD-ul trimite o varietate de mesaje unei aplicatii ObjectARX,
indicind aparitia unor evenimente in interiorul AutoCAD-ului. Dezvoltatorul aplicatiei
decide caror tipuri de mesaje le va raspunde aplicatia, precum si felul in care aplicatia va
reactiona la aparitia fiecarui tip de mesaj.

3.Implementarea unui punct de intrare pentru AutoCAD.


AutoCAD face apel la o aplicatie ObjectARX prin intermediul functiei
acrxEntryPoint(), care inlocuieste functia main() a unui program C++. Dezvolatorul este
responsabil de implementarea functiei acrxEntryPoint() in aplicatie. Functia
acrxEntryPoint() va face apel la toate functiile asociate fiecarui tip de mesaj specific
AutoCAD-ului.

4.Implementarea initializarii.
In interiorul aplicatiei ObjectARX trebuie initializate toate clasele proprii
create si este necesara reconstruirea arborelui de clase utilizate de catre ObjectARX in
momentul executiei aplicatiei. In plus, daca se adauga comenzi noi, ele trebuie
inregistrate in AutoCAD.

5.Pregatirea descarcarii aplicatiei.


Pentru a crea o aplicatie ObjectARX care se comporta normal, in
momentul descarcarii acesteia din memorie trebuie eliminate orice clase proprii sau orice
comenzi implementate de aplicatia ObjectARX.

Object ARX 29
In urmatoarele paragrafe se arata mai detaliat care sunt pasii necesari pentru
dezvoltarea unei aplicatii ObjectARX.

1.7.1.1. Crearea claselor proprii

Este permisa derivarea unei clase proprii din oricare clasa continuta in ierarhia
ObjectARX. ObjectARX pune la dispozitie un set de macro-uri, declarate in fisierul
rxboiler.h, care ajuta la crearea unor noi clase derivate din AdRxObject.
Este interzisa derivarea de clase proprii din urmatoarele clase:

AcDb2dPolyline
AcDb3dPolyline
AcDbPolygonMesh
AcDbPolyFaceMesh
AcDbSequenceEnd
AcDbBlockBegin
AcDbBlockEnd
AcDbVertex
AcDbFaceRecord
AcDb2dVertex
AcDb3dPolylineVertex
AcDbPolygonMeshVertex
AcDbPolyFaceMeshVertex
AcDbMInsertBlock
Daca totusi exista clase derivate din clasele mentionate mai sus, AutoCAD-ul se
va bloca in momentul executiei aplicatiei.

1.7.1.2. Mesajele AutoCAD catre aplicatia ObjectARX

Exista patru categorii de mesaje trimise de catre AutoCAD unei aplicatii


ObjectARX:

Object ARX 30
- mesaje trimise tuturor aplicatiilor;
- mesaje care sunt trimise doar daca aplicatia ObjectARX a inregistrat o
functie AutoLISP® prin intermediul functiei acedDefun();
- mesaje care sunt trimise aplicatiilor care au inregistrat un serviciu prin
intermediul ObjectARX;
- mesaje trimise aplicatiilor care folosesc automate ActiveX.

Urmatoarele tabele descriu mesajele pe care AutoCAD-ul le trimite unei aplicatii


ObjectARX. Tabelul 2 listeaza toate mesajele trimise tuturor aplicatiilor.

Mesaj Descriere

kinitAppMsg Trimis cind aplicatia ObjectARX este incarcata si folosita


pentru a initializa si deschide comunicarea dintre AutoCAD
si aplicatie.

kUnloadAppMsg Trimis cind aplicatia ObjectARX e descarcata (fie cind


utilizatorul descarca aplicatia, fie cind AutoCAD-ul isi
incheie executia). Inchide fisierele si executa procedurile de
curatare a zonelor de memorie folosite.

kLoadDwgMsg Trimis cind desenul este deschis. Apoi, daca aplicatia


inregistreaza o functie in AutoLISP, AutoCAD-ul transmite
aceste mesaj pentru fiecare desen incarcat in editor.
AutoCAD-ul este complet initializat in acest moment si
toate functiile globale sunt disponibile. Totusi, nu puteti
folosi o functie acedCommand() din interiorul unei functii
de tratare a mesajului kLoadDwgMsg.

Tabelul 2. Mesaje trimise tuturor aplicatiilor (continuare).

Object ARX 31
Continuare tabelul2.
Mesaj Descriere
kPreQuitMsg Trimis cind AutoCAD-ul isi incheie executia, dar inainte de
a incepe descarcarea aplicatiilor ObjectARX.

Tabelul 2. Mesaje trimise tuturor aplicatiilor.

Tabelul 3 contine mesajele care sunt trimise in cazul in care aplicatia ObjectARX
a inregistrat o functie AutoLISP® prin intermediul functiei acedDefun().
Mesaj Descriere
kUnloadDwgMsg Trimis cind utilizatorul termina o sesiune de desenare.
kInvkSubrMsg Trimis cand se apeleaza functii inregistrate cu
acedDefun().
kEndMsg Trimis doar cind comanda END e introdusa si exista
schimbari care trebuiesc salvate (cind dbmod != 0).
kEndMsg nu este trimis pentru o comanda NEW sau
OPEN, in schimb, sunt transmise mesajele kSaveMsg si
kLoadDwgMsg. Pentru comanda END, daca dbmod = 0,
atunci este trimis mesajul kQuitMsg in loc de kEndMsg.
kQuitMsg Trimis cind AutoCAD-ul intrerupe editarea unui desen
fara salvare, ca urmare a unei comenzi QUIT introdusa de
utilizator. Mesajul kQuitMsg poate fi de asemenea primit la
aparitia unei comenzi END, asa cum s-a explicat mai sus.
Daca comanda trimisa e END si dbmod = 0, atunci este
trimis mesajul kQuitMsg.
kSaveMsg Trimis cind AutoCAD salveaza desenul datorita
introducerii unei comenzi SAVE, SAVEAS, NEW sau
OPEN.
kCfgMsg Trimis de AutoCAD cind modificarea configuratiei sale
necesita schimbari in driver-ul adaptorului grafic.
Tabelul 3. Mesaje transmise doar daca aplicatia a inregistrat o functie AutoLISP.

Object ARX 32
Tabelul 4 contine mesajele primite de catre o aplicatie doar daca aplicatia are un
serviciu ObjectARX inregistrat.
Mesaj Descriere
kDependencyMsg Trimis cind aplicatia ObjectARX a inregistrat un obiect
AcRxService si functiile(dependency count) pentru acel
serviciu s-au schimbat din 0 in 1.
KNoDependencyMsg Trimis cind aplicatia ObjectARX a inregistrat un obiect
AcRxService si functiile(?) pentru acel serviciu s-au
schimbat din 1 in 0.
Tabelul 4. Mesaje primite doar de aplicatiile care au inregistrat un serviciu.

Tabelul 5 contine mesajul caruia o aplicatie trebuie sa ii raspunda doar daca


foloseste automate ActiveX.
Mesaj Descriere
kOleUnloadAppMsg Trimis pentru a determina daca aplicatia poate fi
descarcata, asta insemnind ca niciunul din obiectele sau
interfetele aplicatiei nu sunt utilizate de catre alte aplicatii.
Tabelul 5. Mesaj caruia i se raspunde doar de catre aplicatii care folosesc
controale ActiveX.

Dezvoltatorul aplicatiei decide caror mesaje le va raspunde aplicatia ObjectARX.


Tabelul 6 descrie actiunile recomandate pentru fiecare tip de mesaj primit.

Mesaj Actiuni recomandate


kInitAppMsg Inregistrati serviciile, clasele, comenzile AcEd si reactorii
AcRxDynamicLinker. Initializati resursele sistem ale
aplicatiei, precum dispozitive periferice si ferestre de
afisare. Salvati valoarea parametrului pkt daca doriti sa
protejati aplicatia dumneavoastra. Nu va asteptati ca
dispozitivele sa fie initializate, ca interfetele cu utilizatorul
sa fie active, ca aplicatiile sa fie incarcate intr-o ordine

Object ARX 33
(continuare tabelul 6)
Mesaj Actiuni recomandate
predefinita, ca AutoLISP sa fie incarcat sau o baza de date
sa fie deschisa. Orice actiune in interiorul aplicatiei
dumneavoastra care se bazeaza pe aceste presupuneri duce
la o eroare in aplicatia dumneavoastra, uneori aceste erori
fiind fatale aplicatiei . Bibliotecile de functii AcDb si AcGi
nu sunt in general active desi parti componente, AcRx si
alte structuri, pot sa fie deja incarcate.
kUnloadAppMsg Eliberati resursele sistem utilizate. Orice actiune demarata
in kInitAppMsg trebuie acum distrusa sau oprita. Nu va
asteptati ca lucrurile sa fie diferite fata de descrierea
comportamentala a kInitAppMsg.
KoleUnloadAppMsg Acestui mesaj trebuie sa i se raspunda doar de catre
aplicatiile care utilizeaza automate ActiveX. Raspundeti cu
AcRx::kRetOK, daca aplicatia poate fi descarcata, ceea ce
inseamna ca nici unul din obiectele sau interfetele ActiveX
nu sunt utilizate de catre alte aplicatii. Daca aplicatia nu
poate fi descarcata, raspundeti cu AcRx::kRetError.
kLoadDwgMsg Executati initializari necesare in actuala sesiune de editare a
desenului. AcDb, AcGi si interfata cu utilizatorul a API-
ului (Application Programing Interface) sunt acum active.
Nu se cunoaste nimic despre starea desenului curent. Toate
functiile API ale AutoCAD-ului sunt acum active. Puteti
inregistra functii AutoLISP in acest moment si sa intializati
interfata cu utilizatorul. Efectuati alte operatii de intergoare
a evenimentelor cu AcEditorReactorOther si obtineti
informatii referitoare la dispozitivele AutoCAD, daca doriti
sa aveti acces la aceste resurse in cel mai scurt timp posibil
prin functia acdbHostApplicationServices()-
>workingDatabase(). Luati in calcul faptul ca acest mesaj

Object ARX 34
(continuare tabelul 6)
Mesaj Actiuni recomandate
este transmis de mai multe ori pe perioada de executie a
aplicatiei.
kUnloadDwgMsg Dezactivati sau descarcati orice functie care trateaza
mesajul kLoadDwgMsg. Deactivati toti reactorii AcDb, cu
exceptia celor persistenti. Nu eliberati resursele sistem care
nu au legatura cu o sesiune de editare, nu dezactivati
reactorii AcEd sau comenzile; ele ramin active pe parcursul
sesiunii de editare.
kDependencyMsg Executati orice actiune necesara aplicatiei dumneavoastra
atunci cind alta aplicatie are nevoie de ea, cum ar fi
blocarea ei pentru a nu putea fi descarcata.
kNoDependencyMsg Executati orice actiune necesara aplicatiei dumneavoastra
atunci cind de ea nu mai depind alte aplicatii, cum ar fi
deblocarea ei pentru a putea fi descarcata atunci cand
utilizatorul doreste acest lucru.
kInvkSubrMsg Invocati functiile inregistrate cu acedDefun(). Determinati
functia printr-un apel al functiei acedGetFuncode().
Retrunati valorile obtinute cu ajutorul functiei
acedRetxxx(). NU faceti prea multe lucruri aici, cu exceptia
apelurilor de functii.
kPreQuitMsg Dezactivati orice resurse controlate de catre aplicatia
dumneavoastra (alte aplicatii, biblioteci dinamice (DLL),
etc.) pentru a va asigura ca ele sunt descarcate inaintea
aplicatiei dumneavoastra.
KEndMsg, kCfgMsg, kQuitMsg, kSaveMsg Nu raspundeti acestor mesaje
daca veti utiliza reactorul AcEditorReactor corespunzator
acestor mesaje.
Tabelul 6. Reactia aplicatiilor ObjectARX la mesajele AutoCAD.

Object ARX 35
1.7.1.3. Secventa de evenimente intr-o aplicatie ObjectARX

Procesul de pasare a mesajelor intre AutoCAD si aplicatia ObjectARX se face


aproape intr-o singura directie: dinspre AutoCAD spre aplicatia ObjectARX. Urmatoarea
diagrama arata o secventa tipica de pasare de mesaje.

Timp Eveniment Mesaj

Start AutoCAD kInitAppMsg


acedRegCommand->addCommand(“Test2”,

Open drawing kLoadDwgMsg


ads_defun “C:TEST1”

Apelul comenzii kInvokeSubr


TEST1

Apelul comenzii Controlul este transferat direct


TEST2 rutinei “test2”

Apelul comenzii kSaveMsg


SAVE

Quit kUnloadDwgMsg
kQuit
kUnloadApp

Figura 8. Secventa de evenimente intr-o aplicatie ObjectARX.

Daca o aplicatie e incarcata cind un desen e deja deschis, mesajele kInitAppMsg


si kLoadDwgMsg sunt trimise succesiv. Cind o aplicatie ObjectARX e descarcata in timp
ce exista o sesiune de editare activa, mesajele kUnloadDwg si kUnloadApp sunt trimise
succesiv.

Object ARX 36
1.7.1.4. Implementarea unui punct de intrare in aplicatie pentru AutoCAD

AutoCAD face apelul in interiorul unui modul ObjectARX prin intermediul


functiei acrxEntryPoint(), care inlocuieste functia main() a unui program C++. Este
responsabilitatea dezvoltatorului aplicatiei sa implementeze functia acrxEntryPoint().
Functia acrxEntryPoint() serveste ca punct de intrare pentru AutoCAD (sau alte
programe/aplicatii) pentru a comunica cu aplicatia ObjectARX. Aplicatiile ObjectARX
pot la randul lor sa comunice cu AutoCAD-ul returnind coduri de stare. Toate cererile de
apel de functii definite cu ajutorul functiei acedDefun() sunt facute de catre functia
acrxEntryPoint(). Daca definiti o noua comanda cu ajutorul ObjectARX-ului sau cu
ajutorul functiei acedRegFunc(), AutoCAD-ul va executa imediat functia asociata acestei
comenzi (vezi "Incarcarea unei aplicatii ObjectARX").
Functia acrxEntryPoint() are urmatoarea definitie:

extern "C"
AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt);

msg
Reprezinta mesajul trimis dinspre nucleul (kernel-ul) ObjectARX inspre aplicatie.
pkt
Contine datele referitoare la pachet.
AppRetCode
Contine codul de stare intors AutoCAD-ului.

In interiorul definitiei functiei acrxEntryPoint(), se introduce un bloc switch(), sau


orice alt cod similar, pentru descifrarea mesajelor primite de la AutoCAD, luarea
deciziilor ce se impun pentru fiecare mesaj primit si pentru returnarea unui cod de stare
sub forma unei valori numerice intregi.

Object ARX 37
NOTA: Daca functia acrxEntryPoint() returneaza AutoCAD-ului codul de stare
kRetError ca ultima valoare, acest lucru va determina AutoCAD-ul sa descarce aplicatia.
In schimb, daca kRetError este returnat dintr-o bucla de tratare a mesajelor
kOleUnloadAppMsg si kUnloadAppMsg, aplicatia nu va fi descarcata.

Urmatorul cod arata scheletul de baza al unei aplicatii care foloseste un bloc
conditional switch():

AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
switch(msg) {
case AcRx::kInitAppMsg:
break;
case AcRx::kUnloadAppMsg:
break;
...
default:
break;
}
return AcRx::kRetOK;
}

1.7.1.5. Initializarea unei aplicatii ObjectARX

Dezvoltatorul aplicatiei are sarcina de a initializa orice clase proprii si comezi


care sunt definite in cadrul aplicatiei. Aceste initializari pot sa aiba loc fie in
AcRx::kInitAppMsg din cadrul blocului conditional al functiei acrxEntryPoint() (cu alte
cuvinte, initializarea e facuta pe ramura blocului conditional care trateaza mesajul
kInitAppMsg, mesaj primit de aplicatie de la AutoCAD atunci cind aplicatia trebuie

Object ARX 38
incarcata), sau de catre o functie externa, dar care e apelata de pe acea ramura a buclei
conditionale.
Pentru a initializa o aplicatie ObjectARX se efectueaza urmatoarele:

1. Daca sunt definite clase proprii, se apeleaza la fuctia rxInit(). Pentru a


reconstrui arborele de clase care este utilizat de ObjectARX, apelati functia
acrxBuildClassHierarcy().
Pentru eficienta, apelati acrxBuildClassHierarchy() chiar dupa apelul
functiei rxinit() pentru fiecare din clasele dumneavoastra proprii.

2. Se efectueaza orice alta initializare de care este nevoie.

3. Se inregistreaza un nume de serviciu.


Inregistrarea unui nume de serviciu este recomandata daca alta aplicatii
depind de aplicatia curenta. Inregistrarea unui nume de serviciu permite aplicatiilor sa
foloseasca acest serviciu si in acelasi timp permite aplicatiei curente sa verifice daca este
utilizata sau nu de catre alte aplicatii in momentul in care se incearca descarcarea ei.
Inregistrarea unui nume de serviciu este necesara si in cazul in care se doreste acordarea
accesului altor module la functiile interne ale aplicatiei, folosind mecanismele interne
ObjectARX-ului. In acest scop, se foloseste functia acrxRegisterService() sau clasa
AcRxService.

5. Se inregistreaza comenzi in AutoCAD folosind mecanismul de comenzi al


AutoCAD-ului.
Se foloseste functia acedRegCmds->addCommand() pentru a determina
AutoCAD-ul sa ia in calcul comenzile pe care aplicatia le implementeaza.

1.7.1.6. Pregatirea descarcarii aplicatiei

Cand aplicatia este descarcata, trebuie eliminate toate clasele proprii utilizate si
toate comenzile pe care aplicatia le-a implementat. Toate aceste actiuni trebuie facute in

Object ARX 39
AcRx::kUnloadAppMsg, pe ramura kUnloadAppMsg a blocului conditional definit in
functia acrxEntryPoint(), sau intr-o functie apelata de pe acea ramura conditionala.
Pentru a descarca o aplicatie ObjectARX se efectueaza urmatoarele:

1. Daca au fost create comenzi cu ajutorul macro-urilor acedRegCmds sau


acedDefun(), acestea trebuie eliminate.
In general, comeznile implementate de o aplicatie ObjectARX se elimina pe
grupuri folosind apelul functiei acedRegCmds->removeGroup().
2. Daca au fost create clase proprii, trebuie eliminate.
Se foloseste functia deleteAcRxClass() pentru a sterge orice clasa proprie
definita din ierarhia de clase AcRx. Clasele trebuie eliminate pornind dinspre frunze catre
parinti.
3. Se sterge orice obiect creat de aplicatie.
Nu exista nici o metoda de a informa AutoCAD-ul sa nu ia in calcul
instantele clasei AcDbObject care sunt residente intr-o baza de date. Totusi, cind o
aplicatie e descarcata, AutoCAD va determina automat care din aceste obiecte vor fi
convertite catre instante ale claseor AcDbProxyObject sau AcDbProxyEntity.
4. Se elimina orice reactor care a fost atasat oricarui obiect AcDbObject,
AcDbDatabase, AcRxDynamicLinker sau AcEditor. (Reactorii persistenti in obiectele
AcDbObjects sunt o exceptie; ei vor deveni obiecte de tip "proxy"cind aplicatia va fi
descarcata.)
5. Daca a fost creat un nume de serviciu, acesta trebuie eliminat.
Se foloseste functia acrxServiceDictionary->remove() pentru a elimina
orice nume de serviciu ce a fost inregistrat in cadrul aplicatiei.

1.7.2.Exemplu de aplicatie

Urmatorul exemplu de aplicatie ObjectARX implementeaza functii care sunt


apelate atunci cind aplicatia e incarcata sau descarcata. Functiile sale de initializare
adauga doua noi comenzi AutoCAD-ului CREATE si ITERATE. Initializeaza de

Object ARX 40
asemenea clasa AsdkMyClass si o adauga ierarhiei de clase ObjectARX cu ajutorul
functiei acrxBuildClassHierarchy().

//Aceasta este functia de initializare apelata din acrxEntryPoint() de pe ramura cu


//kInitAppMsg si este utilizata pentru adaugarea comenzilor si claselor la ierarhia
//de clase ACRX.
//
void initApp()
{
acedRegCmds->addCommand("ASDK_DICTIONARY_COMMANDS",
"ASDK_CREATE", "CREATE", ACRX_CMD_MODAL,
createDictionary);

acedRegCmds->addCommand("ASDK_DICTIONARY_COMMANDS",
"ASDK_ITERATE", "ITERATE", ACRX_CMD_MODAL,
iterateDictionary);

AsdkMyClass::rxInit();
acrxBuildClassHierarchy();
}

// Aceasta este functia apelata de pe ramura cu kUnloadAppMsg din cadrul


//functie acrxEntryPoint() si are ca rol eliminarea comenzilor si claselor proprii
//din ierarhia ACRX.
//
void unloadApp()
{
acedRegCmds->removeGroup("ASDK_DICTIONARY_COMMANDS");
delete AcRxClass(AsdkMyClass::desc());

Object ARX 41
1.7.3. Inregistrarea noilor comenzi

Aceasta sectiune descrie modul de adaugarea a comenzilor noi folosind


mecanismul AcEd de inregistrare a comenzilor.

1.7.3.1. Stiva de comenzi

Comezile AutoCAD sunt stocate pe grupuri de comenzi in stiva de comenzi, care


e definita de clasa AcEdCommandStack. De-a lungul unei sesiuni AutoCAD este creata
o singura instanta a acestei clase. Aceasta stiva contine comenzile proprii pe care
dezvoltatorul aplicatiei le-a definit. Macro-ul acedRegCmds() asigura accesul la stiva de
comenzi.
In momentul in care se adauga o comanda, acesteia i se atribuie si un nume de
grup. Numele comenzilor trebuie sa fie unice in interiorul aceluiasi grup, iar numele
grupului trebuie sa fie si el unic in stiva de comenzi. Totusi, mai multe aplicatii pot
adauga comenzi cu acelasi nume atata timp cat numele de group nu este acelasi.
In mod normal, comenzile se adauga una cate una folosind functia
AcEdCommandStack::addCommand() si se elimina pe grupuri de comenzi folosind
functia AcEdCommandStack::removeGroup(). De asemenea, este permisa utilizarea
functiei AcEdCommandStack::removeCmd() pentru a elimina comenzile una cite una. Ca
parte integranta a procesului de eliberare a resurselor , aplicatia trebuie sa stearga toate
comenzile implementate inainte de a fi descarcata din memorie.
Antetul functiei addCommand() este:

Acad::ErrorStatus
addCommand(
const char* cmdGroupName,
const char* cmdGlobalName,
const char* cmdLocalName,
Adesk::Int32 commandFlags,

Object ARX 42
AcRxFunctionPtr functionAddr,
AcEdUIContext *UIContext=NULL,
int fcode=-1,
HINSTANCE hResourceHandle=NULL);

cmdGroupName
Reprezentarea ASCII a grupului caruia ii va fi adaugata comanda. Daca grupul nu
exista, este creat inainte de adaugarea comenzii.
cmdGlobalName
Reprezentarea ASCII a numelui comenzii care urmeaza a fi adaugata. Acest nume
reprezinta numele global al comenzii.
cmdLocalName
Reprezentarea ASCII a numelui comenzii ce urmeaza a fi adaugata. Acest nume
reprezinta numele local al comenzii.

NOTA: Cand se adauga o comanda AutoCAD-ului, trebuie specificat un nume global,


care este valabil pentru orice limba, si un nume local, care reprezinta traducerea numelui
comenzii pentru o versiune intr-o limba straina a AutoCAD-ului.Daca nu este necesara o
versiune straina a numelui comenzii, atunci poate fi folosit acelasi nume global si local.

commandFlags
Valorile posibile sunt:
ACRX_CMD_TRANSPARENT – Comanda poate fi invocata in timp ce o alta
comanda este activa.
ACRX_CMD_MODAL – Comanda nu poate fi invocata atata timp cat o alta
comanda este activa.
ACRX_CMD_USEPICKSET – Cand multimea de selectie este recuperata, ea
este stearsa din AutoCAD.
ACRX_CMD_REDRAW – Cand multimea de selectie este recuperata, ea nu este
stearsa din AutoCAD.
functionAddr

Object ARX 43
Adresa functiei care urmeaza a fi executata in momentul invocarii comenzii de
catre AutoCAD.
UiContext
Pointer catre clasa AcEdUIContext.
fcode
Cod de intrare asignat comenzii.

NOTA: Este recomandat ca numele comenzii sa fie prefixat de patru caractere specifice
pentru a evita conflictul intre comenzi cu acelasi nume dar definite in alte aplicatii. De
exemplu, numele comenzii MOVE pentru un dezvoltator cu prefixul ASDK va fi
ASDKMOVE. Utilizarea prefixului e recomandata si la numirea grupurilor de comenzi.

Antetul functiei removeCmd() este:


virtual Acad::ErrorStatus AcEdCommandStack::removeCmd (const char*
cmdGroupName, const char* cmdGlobalName) = 0;
Antetul functiei removeGroup() este:
virtual Acad::ErrorStatus AcEdCommandStack::removeGroup(const char*
groupName);

1.7.3.2. Ordinea de cautare

Cand o comanda este invocata, stiva de comenzi este parcursa dupa numele de
grup, apoi dupa numele comenzii din grupul respectiv. In general, primul grup de
comenzi inregistrat va fi primul cautat dar nu se poate prevedea care va fi ordinea de
cautare. Folosind functia AcEdCommandStack::popGroupToTop() se poate specifica
care grup de comenzi va fi cautat primul. Optiunea 'Group' a comezii ARX permite
utilizatorului sa specifice numele grupului care va fi cautatmai intai.

Object ARX 44
1.7.4. Incarcarea unei aplicatii ObjectARX

O aplicatie ObjectARX poate fi incarcata in AutoCAD folosind oricare din


metodele urmatoare:
- Se prevede aplicatia cu caracteristici care sa permita sa fie incarcata la cerere de
catre AutoCAD. Acest lucru presupune utilizarea registrilor sistem care pot stoca trasaturi
specifice ale unei aplicatii.
- Se mentioneaza aplicatia in fisierul modul initial, acad.rx. Acesta contine o lista
de fisiere pe care AutoCAD trebuie sa la incarce la fiecare lansare in executie. Fiecare
linie din fisier contine un nume de program (incluzind calea completa pina la fisier daca
fisierul nu se afla in directorul care contine bibliotecile de functii standard). Fisierul
acad.rx trebuie sa fie si el intr-un director care se afla in calea de cautare a AutoCAD-
ului.
- Se face o cerere de incarcare a aplicatiei dintr-o alta aplicatie ObjectARX,
folosind functia AcRxDynamicLinker::loadModule().
- Se utilizeaza cutia de dialog APPLOAD definita in modulul loadapp.arx al
AutoCAD-ului.
- Se utilizeaza functia arxload() din AutoLISP.
- Se utilizeaza functia acedArxLoad() din ObjectARX.
- Se introduce comanda 'ARX' la prompterul AutoCAD si se foloseste optiunea
'Load'.

1.7.5. Descarcarea unei aplicatii ObjectARX

In cazul in care nu este blocata, o aplicatie ObjectARX poate fi descarcata


folosind oricare din urmatoarele metode:
- Se face o cerere de descarcare a aplicatiei dintr-o alta aplicatie ObjectARX
utilizand functia AcRxDynamicLinker::unloadModule().
- Se folositi cutia de dialog APPLOAD definita in modulul loadapp.arx al
AutoCAD-ului. Acest fisier defineste o interfata utilizator pentru functiile AutoLISP
arxload si arxunload.

Object ARX 45
- Se utilizeaza functia arxunload din AutoLISP.
- Se utilizeaza functia acedArxUnload() din ObjectARX.
- Se introduce comanda 'ARX' la prompterul AutoCAD si foloseste optiunea
'Unload'.

• Deblocarea aplicatiilor

Implicit, aplicatiile sunt blocate si nu pot fi descarcate. Pentru a putea fi calificata


ca "descarcabila", aplicatia trebuie sa se asigure ca nici AutoCAD-ul si nici o alta
aplicatie nu foloseste vreun obiect sau structura pe care ea le-a definit. Inainte de a
permite descarcarea, trebuie asigurat faptul ca nici o alta aplicatie client nu are pointeri
activi catre obiecte din spatiul de adresare al aplicatiei.
Daca se doreste ca aplicatia sa nu poata fi descarcata, trebuie salvata valoarea
parametrului pkt trimis o data cu mesajul AcRx::kInitAppMsg. Parametrul pkt va fi
folosit de functia unlockApplication(). Implicit, orice aplicatie e blocata. Daca se
deblocheaza o aplicatie, ea poate fi descarcata.
Se utilizeaza urmatoarele doua functii pentru a bloca sau a debloca o aplicatie:

bool AcRxDynamicLinker::lockApplication(void* pkt) const;


bool AcRxDynamicLinker::unlockApplication(void* pkt) const;

Urmatoarea functie verifica daca o aplicatie este blocata sau nu:


bool AcRxDynamicLinker::isApplicationLocked(const char* name)
const;

Object ARX 46
1.8. Construirea unei aplicatii ARX in Visual C++ 6.0

Pentru construirea unei aplicatii ObjectARX in Visual C++ 6.0 trebuie parcurse
etapele descrise mai jos. Cu scopul de a facilita intelegerea mecanismului prezentat,
fiecare etapa va fi particularizata pentru o aplicatie ObjectARX foarte simpla, avand
numele “Project.arx”. Aceasta aplicatie va realiza afisarea mesajului “Hello World!” in
linia de comanda a AutoCAD-ului.
• Crearea unui nou proiect
1. Din meniul "File" al Visual C++ 6.0, selectati "New".
2. Selectati "Projects" in ferestra de dialog care apare.
3. Selectati "Win32 Dynamic-Link Library" din lista de tipuri de proiecte.
4. Introduceti numele dorit pentru proiectul dumneavoastra, de exemplu "Project".
5. Specificati directorul pe disk unde vor fi pastrate toate fisierele noii aplicatii,
apoi apasati butonul "OK" (vezi figura 8).

Object ARX 47
Figura 8. Crearea unui nou spatiu de lucru.
6. In urmatoarea fereastra de dialog, alegeti "An empty DLL project."
7. Apasati pe butonul "Finish", apoi pe butonul "OK".

• Setarile compilatorului

1. Din meniul "Project", alegeti "Settings...", pentru a afisa fereastra de dialog


"Project Settings" (vezi figura 9).

Object ARX 48
Figura 9. Selectarea optiunii “Project Settings” din meniul “Project”.

NOTA: Initial, lista de optiuni din stinga ferestrei, "Settings For:" are valoarea "Win32
Debug". Daca trebuie sa aduceti schimbari atit versiunii de depanare, cit si
versiunii finale a aplicatiei, alegeti optiunea "All Configurations".

2. Selectati "C/C++ " din partea dreapta a ferestrei de dialog pentru a avea acces
la parametrii compilatorului.
3. Verificati daca numele proiectului dumneavoastra se afla in lista de proiecte si
este selectat.
4. Din lista "Settings For:", alegeti "All Configurations."
5. Din casuta "Category:", alegeti optiunea "Code Generation."
6. In casuta de editare "Use run-time library", alegeti "Multithreaded DLL" (vezi
figura 10) .
7. Din casuta "Category:", alegeti "Preprocessor."
8. In campul "Additional include directories:", adaugati calea completa pina la
fisierele antet ale ObjectARX 2000. In mod normal, aceste fisiere se gasesc in:
C:\ObjectARX2000\inc.

Object ARX 49
Figura 10. Setarile compilatorului.

• Setarile editorului de legaturi

1. In fereastra de dialog "Project settings", alegeti "Link" pentru a avea acces la


parametrii editorului de legaturi.
2. Verificati ca valoarea casutei "Category:" sa fie pozitionata pe "General."
3. In partea stinga a ferestrei de dialog, alegeti optiunea "Win32 Debug" in cadrul
sectiunii "Settings For:"(vezi figura 11).
4. In campul de editare "Output File Name:", veti vedea scris
"Debug/<Project>.dll". Schimbati extensia fisierului din .dll in .arx. Este
recomandat sa folositi extensia .arx pentru ca aceasta este extensia implicita pe
care AutoCAD o cere pentru aplicatii ARX.

NOTA: Aceste setari specifica numele aplicatiei si directorul unde aceasta va fi


salvata dupa editarea de legaturi.

Object ARX 50
5. In partea stanga a ferestrei de dialog, selectati "Win32 Release" din cadrul listei
de optiuni "Settings For:".
6. In casuta de editare "Output File Name:", veti vedea scris
"Release/<Project>.dll." Schmibati extensia fisierului din .dll in .arx.
7. In partea stinga a ferestrei de dialog, selectati optiunea "All Configurations" in
cadrul sectiunii "Settings For:".
8. In casuta de editare "Object/library modules" , adaugati urmatoarele nume de
librarii ObjectARX, la inceputul listei deja existente de librarii: rxapi.lib
acrx15.lib acutil15.lib acedapi.lib.

NOTA: Acestea sunt singurele biblioteci ObjectARX 2000 de care avem nevoie
pentru aceasta aplicatie simpla. Aplicatiile mai sofisticate pot avea nevoie de alte
biblioteci ObjectARX 2000.

Figura 11. Setarile editorului de legaturi.

9. Selectati valoarea "Input" in casuta de dialog "Category:".

Object ARX 51
10. In campul "Additional Library Path:", introduceti calea completa pana la
librariile ObjectARX 2000. In mod normal, aceasta este: C:\ObjectARX 2000\lib.
11.Inchideti fereastra de dialog "Project Settings" apasand pe butonul "OK".

Cu aceasta, setarile pentru noul nostru proiect au luat sfarsit. Se continua cu


adaugarea de cod sursa necesar aplicatiei care va afisa mesajul "Hello World!" in
AutoCAD, atunci cind vom rula aplicatia.

• Adaugarea de cod sursa in aplicatie

1. Din meniul "Project" alegeti "Add to Project" si apoi selectati "New...".


2. Alegeti "C++ Source File" pentru tipul de fisier si introduceti “Hello World” in
casuta de editare "File name:".
3. Apasati pe "OK."

In primul rand, trebuie incluse doua fisier antet ObjectARX: aced.h si rxregsvc.h.
Adaugati-le cum se arata mai jos:

#include <aced.h>
#include <rxregsvc.h>

Apoi, vom declara urmatoarele doua functii:


-initApp() - functie care va fi apelata de catre AutoCAD in momentul incarcarii
aplicatiei;
-unloadApp() - functie care va fi apelata de catre AutoCAD in momentul in care
aplicatia este descarcata.

Cititi documentatia functiei acrxEntryPoint() pentru a intelege cum sunt apelate


aceste functii da catre AutoCAD. Adugati liniile urmatoare:

void initApp();

Object ARX 52
void unloadApp();

In urmatorul pas, vom declara functia proprie, care va afisa mesajul "Hello
World!" in linia de comanda a AutoCAD-ului. Adaugati:

void helloWorld();

Urmeaza sa definim functia initApp(). Aceasta functie adauga o noua comanda


AutoCAD-ului. Noua comanda va fi un punct de intrare aditional in cadrul aplicatiei:

void initApp()
{
// adaugam o comanda AutoCAD-ului
acedRegCmds->addCommand("HELLOWORLD_COMMANDS",
"Hello",
"Salut",
ACRX_CMD_TRANSPARENT,
helloWorld);
}

Primul argument al functiei addCommand() este numele grupului de comenzi (in


cazul nostru, avem doar o singura comanda). Al doilea argument este numele global al
comenzii noastre. Al treilea argument este numele local al comenzii noastre. Al patrulea
argument reprezinta starea comenzii. Se observa ca comanda implementata in aceasta
aplicatie este de tip “transparent”, adica aceasta comanda poate fi invocata si cand alte
comenzi sunt active. Ultimul parametru, al cincelea, este un pointer catre functia de
tratare a comenzii implementate in aceasta aplicatie, functie care se numeste
helloWorld().
Urmatorul pas consta in a defini functia unloadApp(). Aceasta fucntie va sterge
grupul de comenzi, respectiv va sterge comanda “helloWorld”. Adaugati urmatoarele linii
de cod:

Object ARX 53
void unloadApp()
{
acedRegCmds->removeGroup("HELLOWORLD_COMMANDS");
}

In continuare vom defini functia helloWorld(); functia acutPrintf() este


echivalentul functiei standard C printf(), cu mentiunea ca afisarea se face in linia de
comanda a AutoCAD. Adaugati liniile urmatoare:

void helloWorld()
{
acutPrintf("\nHello World!");
}

Acum trebuie sa definim una dintre cele mai importante functii din cadrul oricarei
aplicatii ObjectARX. Aceasta functie este acrxEntryPoint() si este utilizata in cadrul
schimbului de mesaje dintre aplicatie si AutoCAD. Avind in vedere ca o aplicatie
ObjectARX este in esenta o bilbioteca dinamica de functii (DLL), ea nu contine nici o
functie principala de intrare de tip main(). AutoCAD foloseste functia acrxEntryPoint()
pentru a pasa mesaje aplicatiei ObjectARX.
Primul parametru al functiei este un membru al clasei AcRx, cu numele de msg si
care contine tipul mesajului transmis de catre AutoCAD aplicatiei. In capitolul 8 exista
lista completa a tuturor tipurilor de mesaje pe care o aplicatie ObjectARX le poate primi
de la AutoCAD.
In exemplul nostru, avem nevoie sa fim anuntati de catre AutoCAD atunci cind
aplicatia este incarcata si cind este descarcata, pentru a putea adauga, respectiv, sterge
comanda “hello” din lista de comenzi AutoCAD. Pentru aceasta, vom folosi doua functii,
initApp(), in primul caz, si functia unloadApp(), in cel de-al doilea caz.
Al doilea parametru al functiei acrxEntryPoint() are rolul de a specifica daca o
aplicatie poate sau nu poate sa fie descarcata.

Object ARX 54
Implicit, nici o aplicatie nu poate fi descarcata dupa ce a fost incarcata. Avind in
vedere ca aplicatia noastra este foarte simpla si ca nu defineste noi obiecte care sa fie
utilizate de catre AutoCAD sau de catre alte aplicatii, putem fi siguri ca aplicatia poate fi
descarcata fara nici o problema, acest lucru facindu-se in functia unloadApp().
De asemenea, nici o aplicatie ObjectARX nu are suport pentru MDI (Multiple
Document Interfaces – interfete de documente multiple). Aplicatiile care contin suport
pentru MDI, trebuie sa foloseasca functia acrxRegisterAppMDIAware() pentru a fi
inregistrate in cadrul AutoCAD-ului. Adaugati urmatoarele linii de cod:

extern "C" AcRx::AppRetCode


acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
switch (msg)
{
case AcRx::kInitAppMsg:
acrxDynamicLinker->unlockApplication(pkt);
acrxRegisterAppMDIAware(pkt);
initApp();
break;
case AcRx::kUnloadAppMsg:
unloadApp();
break;
default:
break;
}
return AcRx::kRetOK;
}

In final, trebuie sa exportam functia acrxEntryPoint() pentru a permite


AutoCAD-ului sa o acceseze. Exista mai mult moduri de a face acest lucru dar vom
prezenta doar metoda care implica crearea unui fisier de definitii (.DEF).

Object ARX 55
• Crearea unui fisier de definitii (.DEF)

1. Din meniul "Project", alegeti optiunea "Add to Project" si apoi, "New...".


2. Selectati "Text File" pentru tipul de fisier si apoi introduceti "Proiect.def" in
casuta de editare "File name:" . Apasati pe butonul "OK."

Toate aplicatiile ObjectARX trebuie sa exporte cel putin doua functii:


acrxEntryPoint si acrxGetApiVersion. Adaugati urmatoarele linii in fisierul nou creat:

LIBRARY "Proiect"
EXPORTS
acrxEntryPoint PRIVATE
acrxGetApiVersion PRIVATE

In acest stadiu, proiectul este gata pentru a fi compilat si construit. Daca ati
executat toti pasii prezentati cu atentie, aplicatia trebuie sa fie construita fara nici o
problema. Incarcati "Project.arx" in AutoCAD si introduceti comanda "hello" pentru a o
executa.
Pentru a incarca aplicatia "Project.arx", procedati in unul din modurile urmatoare:
1.Executati "drag" cu mouseul pe icoana aplicatiei din Explorer direct peste
ferestra principala a AutoCAD-ului.
2. Utilizati comanda "Load" a AutoCAD-ului pentru a incarca aplicatia.
3. Din meniul "Tools" al AutoCAD-ului alegeti optiunea "Load Application...".

O data ce aplicatia este incarcata cu succes, tastand "hello" sau "salut" in linia de
comanda AutoCAD, vi se va tipari mesajul "Hello World!".

Object ARX 56
2. Aplicatii de tip laborator

Aceste aplicatii sunt utile in cadrul unor cursuri de initiere in ObjectARX,


permitand acumulurea graduala de cunostinte privind modul de construire al unei
aplicatii ARX.

2.1.Hello.arx

Este o aplicatie care afiseaza mesajul “Hello World!” in linia de comanda a


AutoCAD-ului. Permite intelegerea modului de implementare a unui punct de intrare
pentru AutoCAD in aplicatia ARX.
S-au implementat un numar de trei functii, dupa cum urmeaza:
• void initApp() : adauga o comanda noua AutoCAD-ului;
• void unloadApp() : functie care va fi apelata de catre AutoCAD in momentul in care
aplicatia este descarcata;
• void helloWorld() : afiseaza mesajul “Hello World!”.

NOTA: Primele doua functii sunt caracteristice aplicatiilor ARX (vezi capitolul
1.8.Construirea unei aplicatii ARX cu Microsoft Visual C++ 6.0). Ele vor fi
implementate si in urmatoarele aplicatii, adaptandu-se cerintelor acestora.

Codul sursa al aplicatiei este atasat in anexa 1.


2.2.Fact.arx

Este o aplicatie care permite calculul factorialului unui numar introdus de


utilizator, de la linia de comanda a AutoCAD-ului. Au fost definite functiile:
• int fact(int n) : calculeaza factorialul unui numar intreg;
• void factCommand() : este functia care va fi apelata in momentul tastarii comenzii
inregistrate in AutoCAD. Cere utilizatorului introducerea unui numar, al a carui
factorial se va calcula.

Object ARX 57
Codul sursa al aplicatiei este atasat in anexa 2.

2.3.Alee.arx

Este o aplicatie mai complexa. Prin rularea acestei aplicatii, se completeaza o alee
cu dale circulare, respectandu-se dimensiunile furnizate de utilizator. Au fost
implementate urmatoarele functii:
• Acad::ErrorStatus postToDatabase(AcDbEntity* pEnt, AcDbObjectId& idObj) :
functia primeste ca parametru o entitate AutoCAD, pe care o adauga in baza de date
curenta, si returneaza identificatorul entitatii nou adaugate;

• ads_real dtr(ads_real a) : returneaza valoarea in radiani a unghiului a;

• Acad::ErrorStatus linie(ads_point pt1, ads_point pt2) : instantiaza un obiect al clasei


AcDbLine, pe care il adauga in baza de date a AutoCAD-ului.

• Acad::ErrorStatus dala(ads_point centru, ads_real raza) : instantiaza un obiect al


clasei AcDbCircle, pe care il aduga in baza de date a AutoCAD-ului. Aceasta functie
va desena dalele din interiorul perimetrului aleii.

• Acad::ErrorStatus alee() : este functia principala care va desena conturul aleii si o va


completa cu dale astfel incat sa se respecte cerintele utilizatorului privind
dimensiunile (raza dale, interspatii dale, lungimea si latimea aleii).

Codul sursa al aplicatiei este atasat in anexa 3.

2.4.Fan.arx

Este o aplicatie prin care utilizatorul se familiarizeaza cu modul de operare cu


entitati si multimi de selectie. Prin rularea aplicatie, din baza de date a AutoCAD-ului vor
fi selectionate toate cercurile. Se acceseaza lista asociata entitatilor selectionate si se
modifica raza lor. In acest scop, s-a implementat o singura functi, avand antetul: void
fan().
Codul sursa al aplicatiei este atasat in anexa 4.
1.5. Spirala.arx

Aceasta aplicatie construieste o spirala. S-au implementat doua functii:

Object ARX 58
• void cspirala(int ntimes, ads_point bpoint, ads_real cfac, int lppass) : construieste
spirala pe baza urmatoarelor date: punctul central al spiralei, numarul de rotatii,
cresterea pe rotatie si numarul punctelor de rotatie (care nu poate fi mai mare decat
30).

• void spirala() : cere utilizatorului introducerea datelor necesare construirii spiralei si


apeleaza functia cspirala.

Codul sursa ala aplicatiei este atasat in anexa 5.

2.5 Mir.arx

Prin rularea in AutoCAD a acestei aplicatii, se va desena o frunza de dimensiunea


dorita de utilizator si in punctul ales de acesta. Se implementeaza urmatoarea functie:
• void leaf() : cere utilizatorului introducerea a ddoua date: lungimea frunzei si punctul
ei central. Pe baza acestor informatii, deseneaza frunza.

Codul sursa al aplicatiei este atasat in anexa 6.

2.6 Instructiuni de exploatare


Pentru rularea oricareia dintre aplicatiile de tip laborator implementate, este
necesara incarcarea si descarcarea lor corecta din mediul AutoCAD. Subcapitolele 1.7.4
si 1.7.5 (respectiv: Incarcarea unei aplicatii ObjectARX si Descarcarea unei aplicatii
ObjectARX), explica in detaliu modalitatile de realizare corecta a acestor operatii.

ATENTIE: 1. Este recomandabil ca, inainte de incarcarea unei noi aplicatii ARX,
aplicatia anterioara sa fie descarcata.
2. Inainte de introducerea unei noi comenzi, se va curata ecranul de lucru
cu comanda AutoCAD erase all.

Toate cele sase aplicatii inregistreaza cate o comanda care se va comporta ca o


comanda interna AutoCAD. Pachetul ObjectARX permite definirea a doua nume sub care
va opera o comanda inregistrata.

Object ARX 59
Pentru testarea aplicatiilor, singura operatie care trebuie efectuata este
introducerea in linia de comanda a AutoCAD-ului a unuia dintre cele doua nume
declarate. Acestea sunt:
• Hello.arx : hello sau salut;
• Fact.arx : fact sau _fact;
• Alee.arx : alee sau _alee;
• Fan.arx : fan sau _fan;
• Spirala.arx: spirala sau _spirala;
• Mir.arx : mir sau _mir.

Object ARX 60
BIBLIOGRAFIE

1. Savu Cristian: Ghidul Programatorului Visual C++ 5.0., Bucuresti, All


Educational 1998.
2. Varga Andras: Ingineria asistata de calculator a sistemelor automate, Ed.
Tehnica, 1997, Bucuresti.
3. Michael E. Bealt: Secrete AutoCad 14. Teora 1998.
4. Kurt Hampe: The AutoCad Professional’s API Toolkit. New Riders
Publishing 1993.
5. George Omura: AutoCAD 14 Ghid de referinta, Bucuresti, All Educational
1999.
6. Herbert Schimdt: Manual de referinta C/C++, Bucuresti, Teora, 1995.
7. Trad. D. Vasiliu: AUTOCAD release 12 : AUTOCAD tutorial manual,
Bucuresti, Ed. Tehnica 1996.
8. Mark Merickel : AutoCad: Drafting and 3D Design. New Riders Publishing,
Cormel, Indiana.
9. Tom Boersma, Jim Boyce: Inside AutoCad for Windows. New Riders
Publishing.
10. Kenneth W. Billing, David Byrnes: AutoCad: The Profesional Reference.
New Riders Publishing.
11. Dale Evans: Outside AutoCad. Ventana Press 1993.
12. George O. Head, Charles A. Pietra: The AutoCad 3D Book. Ventana Press.
13. Ghane Cullens: Utilizare Visual C++ 4,Bucuresti, Teora, 1997.

Object ARX 61
3 ANEXE
ANEXA 1. – Codul sursa al aplicatiei Hello.arx.

#include "aced.h"
#include <rxregsvc.h>

void initApp();
void unloadApp();
void helloWorld();

void initApp()
{
acedRegCmds->addCommand("HELLOWORLD_COMMANDS",
"Hello",
"Bonjour",
ACRX_CMD_TRANSPARENT,
helloWorld);
}

void unloadApp()
{
acedRegCmds->removeGroup("HELLOWORLD_COMMANDS");
}

void helloWorld()
{
acutPrintf("\nHello World!");
}

extern "C" AcRx::AppRetCode


acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
switch (msg)
{
case AcRx::kInitAppMsg:
acrxDynamicLinker->unlockApplication(pkt);
acrxRegisterAppMDIAware(pkt);
initApp();
break;
case AcRx::kUnloadAppMsg:
unloadApp();
break;
default:
break;

Object ARX 62
}
return AcRx::kRetOK;
}

ANEXA 2. – Codul sursa al aplicatiei Fact.arx.

#include "aced.h"
#include <rxregsvc.h>
#include <acedads.h>
#include <acutads.h>

void initApp();
void unloadApp();
int fact(int);
void factCommand();

void initApp()
{
acedRegCmds->addCommand("FACT_COMMANDS",
"fact",
"_fact",
ACRX_CMD_TRANSPARENT,
factCommand);
}

void unloadApp()
{
acedRegCmds->removeGroup("FACT_COMMANDS");
}

int fact(int n)
{
int rezultat;
if(n==1) return 1;
rezultat=fact(n-1)*n;
return rezultat;
}

void factCommand()
{
int x, temp;
acedInitGet(7,NULL);
acedGetInt("Introduceti numarul: ",&x);
temp=fact(x);

Object ARX 63
acutPrintf("Factorialul numarului este: %d",temp);
}

extern "C" AcRx::AppRetCode


acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
switch (msg)
{
case AcRx::kInitAppMsg:
acrxDynamicLinker->unlockApplication(pkt);
acrxRegisterAppMDIAware(pkt);
initApp();
break;
case AcRx::kUnloadAppMsg:
unloadApp();
break;
default:
break;
}
return AcRx::kRetOK;
}

ANEXA 3. – Codul sursa al aplicatiei Alee.arx.

#include <aced.h>
#include <dbents.h>
#include <geassign.h>
#include <gepnt3d.h>
#include <acedads.h>
#include <dbsymtb.h>
#include <dbapserv.h>
#include <acdbabb.h>
#include <gepnt2d.h>
#include <acutads.h>
#include <math.h>

Acad::ErrorStatus
postToDatabase(/*[in]*/AcDbEntity* pEnt,/*[out]*/AcDbObjectId& idObj)
{
Acad::ErrorStatus es;
AcDbBlockTable* pBlockTable;
AcDbBlockTableRecord* pSpaceRecord;
if (acdbHostApplicationServices()->workingDatabase()==NULL)
return Acad::eNoDatabase;

Object ARX 64
if ((es = acdbHostApplicationServices()->workingDatabase()-
getBlockTable(pBlockTable, AcDb::kForRead))==Acad::eOk){

if ((es = pBlockTable->getAt(ACDB_MODEL_SPACE, pSpaceRecord,


AcDb::kForWrite))==Acad::eOk){

if ((es = pSpaceRecord->appendAcDbEntity(idObj, pEnt))==Acad::eOk)


pEnt->close();
pSpaceRecord->close();
}

//se inchide block table


pBlockTable->close();
}
return es;
}

ads_real dtr(ads_real a)
{
return(3.1415*(a/180));
}

Acad::ErrorStatus linie(ads_point pt1, ads_point pt2)


{
AcDbLine* pLine = new AcDbLine(asPnt3d(pt1), asPnt3d(pt2));

if (!pLine){
acedAlert("Nu exista suficienta memorie pentru a crea o linie!");
return Acad::eOutOfMemory;
}

/*int color;
acedGetInt("\nIntroduceti un numar pt. o culoare AutoCAD: ", &color);
if (pLine->setColorIndex(color) != Acad::eOk)
acutPrintf("\nNumarul ales nu este valid.\n");
*/

AcDbObjectId id;
return postToDatabase(pLine, id);
}

Acad::ErrorStatus dala(ads_point centru, ads_real raza) //deseneaza o dala


{
AcGeVector3d normal(0.0, 0.0, 1.0);

Object ARX 65
AcDbCircle *pCerc=new AcDbCircle(asPnt3d(centru), normal, raza);
//verificam daca cercul a fost creat
if (!pCerc){
acedAlert("Nu exista suficienta memorie pt. a crea cercul!");
return Acad::eOutOfMemory;
}

/*int culoare;
acedGetInt("\nIntroduceti un numar valid pt. o culoare AutoCAD:", &culoare);
if (pCerc->setColorIndex(culoare) != Acad::eOk)
acutPrintf("\nNu ati introdus un numar valid!");*/

AcDbObjectId id;
return postToDatabase(pCerc, id);
}

Acad::ErrorStatus alee()
{
ads_point sp,ep;
ads_real hwidth, trad, tspac, pangle, plength, width, angp90, angm90;
int val_try;

try{
if(val_try = acedGetPoint(NULL,"\nIntroduceti punctul de inceput a
aleii:",sp)!=RTNORM)
throw val_try;
if(val_try = acedGetPoint(sp, "\nIntroduceti punctul de sfarsit a aleii:",ep)
!=RTNORM)
throw val_try;
if(val_try = acedGetDist(sp, "\nIntroduceti semilatimea aleii: ",
&hwidth)!=RTNORM)
throw val_try;
if(val_try = acedGetDist(NULL, "\nRaze dale beton: ",
&trad)!=RTNORM)
throw val_try;
if(val_try = acedGetDist(NULL, "\nInterspatii dale: ",
&tspac)!=RTNORM)
throw val_try;
}
catch(int e)
{
if (e == RTCAN)
return Acad::eUserBreak;
if (e == RTERROR)
return Acad::eInvalidInput;

Object ARX 66
}
pangle = acutAngle(sp, ep);
plength = acutDistance(sp, ep);
width = 2*hwidth;
angp90 = pangle + dtr(90);
angm90 = pangle - dtr(90);

int fail;
ads_point p1, p2, p3, p4;
acutPolar(sp, angm90, hwidth, p1);
acutPolar(p1, pangle, plength, p2);
acutPolar(p2, angp90, width, p3);
acutPolar(p3, pangle + dtr(180), plength, p4);

try{
if(fail = linie(p1, p2)!=Acad::eOk) throw fail;
if(fail = linie(p2, p3)!=Acad::eOk) throw fail;
if(fail = linie(p3, p4)!=Acad::eOk) throw fail;
if(fail = linie(p4, p1)!=Acad::eOk) throw fail;
}
catch(...){
acutPrintf("\nConturul nu a fost desenat!");
}

ads_real pdist= trad + tspac, off=0.0;


while (pdist <= plength - trad){

//drow: INCEPUT
ads_point pfirst, pctile, p1tile;
acutPolar(sp, pangle, pdist, pfirst);
acutPolar(pfirst, angp90, off, pctile);
acdbPointSet(pctile, p1tile);
//randul de sus
while(acutDistance(pfirst, p1tile) < hwidth - trad){
if(dala(p1tile, trad)!= Acad::eOk) acutPrintf("\nEsec in
adaugarea unei dale sus!");
acutPolar(p1tile, angp90, tspac+2*trad, p1tile);
}
acutPolar(pctile, angm90, tspac+2*trad, p1tile);
//randul de jos
while(acutDistance(pfirst, p1tile) < hwidth - trad){
if(dala(p1tile, trad)!= Acad::eOk) acutPrintf("\nEsec in
adaugarea unei dale jos!");
acutPolar(p1tile, angm90, tspac+2*trad, p1tile);
}

Object ARX 67
//drow: SFARSIT

pdist = pdist + (tspac+2*trad)*sin(dtr(60));


if(off==0.0)
off = (tspac+2*trad)*cos(dtr(60));
else
off = 0.0;
}

//drawtiles: SFARSIT
return Acad::eOk;
}

void aleeCommand()
{

if (alee()==Acad::eOk)
acutPrintf("Succes!\n");
else
acutPrintf("Esec!\n");

extern "C" AcRx::AppRetCode


acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
switch (msg) {
case AcRx::kInitAppMsg:

acrxDynamicLinker->unlockApplication(pkt);
acrxDynamicLinker->registerAppMDIAware(pkt);
acedRegCmds-
>addCommand("ALEE_COMMANDS","_alee","alee",ACRX_CMD_TRANSPARENT,
aleeCommand);
break;
case AcRx::kUnloadAppMsg:
acedRegCmds->removeGroup("ALEE_COMMANDS");
break;
}
return AcRx::kRetOK;
}

Object ARX 68
ANEXA 4. – Codul sursa al aplicatiei Fan.arx.

#include "aced.h"
#include <rxregsvc.h>
#include <acedads.h>
#include <acutads.h>
#include <math.h>
#include <string.h>
#include "adslib.h"

void initApp();
void unloadApp();
void fan();

void initApp()
{
acedRegCmds->addCommand("Fan_COMMANDS",
"fan",
"_fan",
ACRX_CMD_TRANSPARENT,
fan);
}

void unloadApp()
{
acedRegCmds->removeGroup("Fan_COMMANDS");
}

void fan()
{
ads_real r=0;
ads_name a, entres;
long n;
char pauza[1];

struct resbuf filter, b1;


char buff[10];
filter.restype = 0;
strcpy(buff, "CIRCLE");
filter.resval.rstring = buff;
filter.rbnext = NULL;

for(int i=1; i<=9; i++)


{
acedSSGet("X", NULL, NULL, &filter, a);
acedSSLength(a, &n);

Object ARX 69
int index = 0;
for(int j=1; j<=n; j++)
{
acedSSName(a, index, entres);
b1 = acdbEntGet(entres);
while(b1.rbnext!=NULL) do
{
if(b1.restype ==40) b1.resval.rreal = r;
b1 = b1->rbnext;
}
acdbEntMod(b1);

r+=10;
acedGetKword("\nApasati SPACE BAR: ", pauza);
}
//acutRelRb(filter);
//acutRelRb(b1);
}

extern "C" AcRx::AppRetCode


acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
switch (msg)
{
case AcRx::kInitAppMsg:
acrxDynamicLinker->unlockApplication(pkt);
acrxRegisterAppMDIAware(pkt);
initApp();
break;
case AcRx::kUnloadAppMsg:
unloadApp();
break;
default:
break;
}
return AcRx::kRetOK;
}

ANEXA 5. – Codul sursa al aplicatiei Spirala.arx.

#include "aced.h"
#include <rxregsvc.h>
#include <acedads.h>

Object ARX 70
#include <acutads.h>
#include <math.h>
#include "adslib.h"

void initApp();
void unloadApp();
void spirala();

void initApp()
{
acedRegCmds->addCommand("Spirala_COMMANDS",
"spirala",
"_spirala",
ACRX_CMD_TRANSPARENT,
spirala);
}

void unloadApp()
{
acedRegCmds->removeGroup("Spirala_COMMANDS");
}

void cspirala(int ntimes, ads_point bpoint, ads_real cfac, int lppass)


{
ads_real circle, ainc, dinc, ang, dist;
ads_point tp;

struct resbuf echo1, blip,cs, bs;


acedGetVar("CMDECHO",&cs);
acedGetVar("BLIPMODE",&bs);

echo1.restype = RTSHORT;
blip.restype = RTSHORT;
echo1.resval.rint=0;
blip.resval.rint=0;
acedSetVar("BLIPMODE",&blip);//!=RTNORM) acutPrintf("\nEroare la
FILLMODE!");
acedSetVar("CMDECHO",&echo1);//!=RTNORM) acutPrintf("\nEroare la
CMDECHO pe 0!");

circle = 2*3.14159;
ainc = circle / lppass;
dinc = cfac / lppass;
ang = dist = 0.0;

struct resbuf* plin = acutBuildList(RTSTR, "pline",

Object ARX 71
RT3DPOINT,
bpoint,0);
acedCmd(plin);
acutRelRb(plin);

for(int i=1; i<=ntimes; i++)


{
for(int j=1; j<=lppass; j++)
{
ang = ang + ainc;
dist = dist + dinc;
acutPolar(bpoint, ang, dist, tp);
struct resbuf* tplin = acutBuildList(RT3DPOINT, tp,0);
acedCmd(tplin);
acutRelRb(tplin);
}
}
acedSetVar("BLIPMODE",&bs);
acedSetVar("CMDECHO",&cs);
}

void spirala()
{
int nt, lp;
ads_point bp;
ads_real cf;

acedInitGet(1,"");
acedGetPoint(NULL,"\nPunctul central:",bp);
acedInitGet(7,"");
acedGetInt("\nNumarul de rotatii: ", &nt);
acedInitGet(3,"");
acedGetDist(NULL, "\nCresterea pe rotatie: ", &cf);
acedInitGet(6,"");
acedGetInt("\nPuncte pe rotatie <30>: ",&lp);

if(lp <0 && lp>30) lp = 30;


cspirala(nt, bp, cf, lp);
}

extern "C" AcRx::AppRetCode


acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
switch (msg)
{

Object ARX 72
case AcRx::kInitAppMsg:
acrxDynamicLinker->unlockApplication(pkt);
acrxRegisterAppMDIAware(pkt);
initApp();
break;
case AcRx::kUnloadAppMsg:
unloadApp();
break;
default:
break;
}
return AcRx::kRetOK;
}

ANEXA 6. – Codul sursa al aplicatiei Mir.arx.

#include "aced.h"
#include <rxregsvc.h>
#include <acedads.h>
#include <acutads.h>
#include <math.h>
#include "adslib.h"

void initApp();
void unloadApp();
void leaf();

void initApp()
{
acedRegCmds->addCommand("LEAF_COMMANDS",
"leaf",
"_leaf",
ACRX_CMD_TRANSPARENT,
leaf);
}

void unloadApp()
{
acedRegCmds->removeGroup("LEAF_COMMANDS");
}

void leaf()
{
acedGraphScr();//!=RTNORM) acutPrintf("\nEroare la comutarea in modul
grafic!");

Object ARX 73
struct resbuf echo1, fill;
echo1.restype = RTSHORT;
fill.restype = RTSHORT;
echo1.resval.rint=0;
fill.resval.rint=1;
acedSetVar("FILLMODE",&fill);//!=RTNORM) acutPrintf("\nEroare la
FILLMODE!");
acedSetVar("CMDECHO",&echo1);//!=RTNORM) acutPrintf("\nEroare la
CMDECHO pe 0!");

acedPrompt("\nLungimea frunzei este cota orizontala!");

ads_real le,a,th,mle;
ads_point p1,p2,p3,p4,p5,p6;

acedGetReal("\nIntroduceti lungimea frunzei:",&le);


acedGetPoint(NULL,"\nIntroduceti punctul central:",p1);
a = 0-3.1415/6;

for(int i=0; i<=4; i++) do


{
mle = le + le*sin(a);
acutPolar(p1, a, mle, p2);
acutPolar(p1, a, mle/2, p3);
acutPolar(p3, a+3.1415/2, 0.134*mle, p4);
th = 0.07 * mle;

struct resbuf* plin = acutBuildList(RTSTR, "pline", RT3DPOINT, p1,


RTSTR, "w", RTREAL, 0, RTREAL, th,
RTSTR, "a", RTSTR, "a", RTREAL, -30,
RT3DPOINT, p4, RTSTR, "w", RTREAL, th,
RTREAL, 0, RTSTR, "a", RTREAL, -30,
RT3DPOINT, p2, RTSTR, "",0);
acedCmd(plin);
acutRelRb(plin);

struct resbuf* mir1 = acutBuildList(RTSTR,"mirror", RT3DPOINT, p2,


RTSTR, "", RT3DPOINT, p1, RT3DPOINT, p2, RTSTR, "",0);
acedCmd(mir1);
acutRelRb(mir1);

a= a+3.1415/6;
}
acutPolar(p1, 7*3.1415/6, le, p5);
acutPolar(p1, 3.1415/4, 1.4*mle, p6);

Object ARX 74
struct resbuf* mir2 = acutBuildList(RTSTR, "mirror", RTSTR, "c", RT3DPOINT,
p5, RT3DPOINT, p6, RTSTR, "", RT3DPOINT, p1, RT3DPOINT, p2, RTSTR,
"",0);

acedCmd(mir2);
acutRelRb(mir2);

struct resbuf echo2;


echo2.restype = RTSHORT;
echo2.resval.rint=1;
acedSetVar("CMDECHO",&echo2);//!=RTNORM) acutPrintf("\nEroare la
CMDECHO pe 1!");
}

extern "C" AcRx::AppRetCode


acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
switch (msg)
{
case AcRx::kInitAppMsg:
acrxDynamicLinker->unlockApplication(pkt);
acrxRegisterAppMDIAware(pkt);
initApp();
break;
case AcRx::kUnloadAppMsg:
unloadApp();
break;
default:
break;
}
return AcRx::kRetOK;
}

Object ARX 75

S-ar putea să vă placă și