找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 3776|回复: 0

ObjectARX Technical Newsletter - January 2000

[复制链接]

已领礼包: 145个

财富等级: 日进斗金

发表于 2002-1-7 02:23:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
ObjectARX Technical Newsletter - January 2000  
This document is part of    ObjectARX Newsletter Archive     



/Note: the URLs in this posting may be broken into several lines by the
transmission media. Please make sure that you have the full URL before
trying to access it./

/Note: Have you missed a Newsletter issue? Visit our Newsletter archive at
the following URL:/

http://adn.autodesk.com/techsupp/docs/newsletters.htm

Dear ObjectARX developer,
  

Table of Contents
-----------------
1 - Implementing a new entity
2 - Deriving from AcDbPolyline
3 - Deriving from AcDbBlockReference
4 - RefEdit in AutoCAD
    Supporting the RefEdit for your entity and data
5 - New and Updated solutions
6 - Upcoming Training Schedule
  

1 - Implementing a new entity
-----------------------------

** Simply derive from one of the ARX class **

To implement a new entity in AutoCAD, you need to derive a new class from
one of the ObjectARX classes, and implement the appropriate method
overrides required to change the base class behaviour to suit you needs.
For existing entity classes in AutoCAD introduce either an extended protocol
and/or some new behaviour. For example, the AcDbCurve class introduces the
'Curve' protocol which is common to all derives classes such as AcDbLine,
AcDbCircle etc. AcDbLine and a AcDbCircle are two very different type of
entity, but AutoCAD does not really know that they are different. AutoCAD
just knows that they are both kinds of curve and accesses/modifies them as such.

The choice of base class to use is very important and will define many aspect
of the behaviour for your custom entity. If you derive from one of the curve
entities of AutoCAD, you will need to support by default all the curve
protocols and you will also need to support some of the AutoCAD commands
such as _OFFSET, _TRIM, _EXTEND to name a few. However if you derive from
AcDbEntity you won't need to provide the same level of support as required
for derived AcDbCurve custom entities.

Remember (from a previous newsletter) that AutoCAD 2000 is the first release
of AutoCAD implemented on top of ObjectDBX. This means that you can virtually
derive from any AutoCAD class in AutoCAD 2000 whereas in previous release of
AutoCAD you cannot. In AutoCAD R13.x and AutoCAD R14.x, you are allowed to
derive from entity classes introduced in AutoCAD r13 only and later.

Those classes are:

R13
AcDbEntity (abstract class)
AcDbCurve (abstract class)
AcDbMText (new in r13)
AcDbMLine (new in r13)
AcDbEllipse (ACIS)
AcDb3dSolid (ACIS)
AcDbRegion (ACIS)
AcDbBody (ACIS)
R14
AcDbPolyline (new class)

As you can see your choice is rather limited! The reason for this is that
AutoCAD's entities were implemented in AutoCAD's core and the ObjectARX
classes were not fully implemented. The main method which was missing to
allow you to derive from AutoCAD standard entity was 'worldDraw()'.
Without that method being implemented if you were to derive from one of
AutoCAD's standard entities your entity was unable to display itself as a
result of having no worldDraw() facility. The worldDraw() method was only
implemented for AcDbEntity and AcDbCurve. So for AutoCAD R13 & R14, your
choice was limited to AcDbEntity and AcDbCurve and as a result you have to
implement a lot of code to achieve the desired result for your custom
entity.

For AutoCAD 2000 the picture has changed and is now implemented on top of
ObjectDBX. ObjectDBX has all the of the entity classes fully implemented.
From AutoCAD 2000 you may now derive from all entity class. But it that
really true?

Well not really...
There are a couple of classes that does not support derivation. Most of
these are per the nature of the entity and are regarded as 'complex'
entities see the following:

AcDb2dPolyline
  AcDb2dVertex
AcDb3dPolyline
  AcDb3dPolylineVertex
AcDbPolygonMesh
  AcDbPolygonMeshVertex
AcDbPolyfaceMesh
  AcDbFaceRecord
AcDbFrame (and derived classes)
AcDbDimention and derived classes
AcDbProxyEntity

Some other classes support derivation, but only in a limited sense. This is
the case for:

AcDbBlockReference
  AcDbMInsertBlock

You can derive from these classes. The only problem is that
'the complex part' of their definition is not supported. It short this means
that you cannot append attributes to your custom entity. It is "kind of" a
block reference but without the support of attributes.

Also there is a class in AutoCAD 2000 which cause problems due to a defect
in the AutoCAD code.

AcDbPolyline
  

Because of an AutoCAD defect, a derived AcDbPolyline class instance won't
be able to save its proxy graphic information into a DWG file. As a result
the proxy graphic for the custom derived AcDbPolyline  be invisible to the
user if the custom entity enabler application is not loaded. We will see
in the next section the reason of this problem, as well as how to solve
this problem in AutoCAD 2000.
  
  

2 - Deriving from AcDbPolyline
------------------------------

Solution 47354: Deriving from AcDbPolyline
/cgi-bin/solution.pl?SID=47354
Here is the listing for Technical Solution 47354

Question:

Deriving from AcDbPolyline appears to be fine. However, it seems DWG files
containing instances of my custom entity derived from AcDbPolyline do not
contain proxy graphic information for them. Why?

Answer:

The root of the problem is that AutoCAD does not save the proxy graphic
information for classes derived from AcDbPolyline. The reason for this
is that the 'saveAs()' method is implements as follows:

<code_begin>
void AcDbPolyline::saveAs(AcGiWorldDraw* mode, AcDb::SaveType st) {
assertReadEnabled();

if ( st == AcDb::kR12Save )
  // ... do something to convert into AcDb2dPolyline
}
<code_end>

Whereas it should be as follows:

<code_begin>
void AcDbPolyline::saveAs(AcGiWorldDraw* mode, AcDb::SaveType st) {
assertReadEnabled();

if ( st == AcDb::kR12Save )
  // ... do something to convert into AcDb2dPolyline
else
  worldDraw (mode) ;
}
<code_end>

As a result of this, proxy graphic data is never saved, which causes your
derived AcDbPolyline entity to be invisible if your DBX-object enabler
application is not loaded. While this is annoying, it does not affect any
other behavior/functionnality of your custom entity.

You would be correct in assuming that a simple override of the 'saveAs()'
method could solve this problem as follows:

<code_begin>
void AcDbMyPolyline::saveAs(AcGiWorldDraw* mode, AcDb::SaveType st) {
assertReadEnabled();

if ( st == AcDb::kR12Save )
  AcDbPolyline::saveAs (mode, st) ;
else
  worldDraw (mode) ;
}
<code_end>

This would be the correct solution, however there is another defect in
AutoCAD which prevent the 'saveAs()' method from being called for proxy
graphic generation. This second defect is more serious since it prevents
'saveAs()' method being called. The reason of this is that AutoCAD makes
an exception in the case of an AcDbPolyline entity. Instead of asking
'are you an AcDbPolyline class', AutoCAD asks 'Are you a "kind of"
AcDbPolyline', and this also includes any of your derived classes from
AcDbPolyline.

What is the solution for this problem?

The only solution is to pretend your custom AcDbPolyline entity is not an
AcDbPolyline class, even if it really is. This will cause AutoCAD to
properly call the 'saveAs()' method and then your implementation of the
'worldDraw()' method for your custom entity. In order to pretend that you
are not an AcDbPolyline entity, just implement the
'ACRX_DXF_DEFINE_MEMBERS' ARX macro as follows:

ACRX_DXF_DEFINE_MEMBERS(AcDbMyPolyline, AcDbCurve,
                        AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
                        AcDbProxyEntity::kNoOperation,
                        ACDBMYPOLYLINE, ACDBMYAPP
);

Are there any other requirements?

Yes! In your implemention of the 'worldDraw()' method you should not call
AcDbPolyline::worldDraw() when called from the 'saveAs()' method. This
would cause the same problem that we outlined earlier. (AutoCAD filters
out all AcDbPolyline calls in that context). You would receive an
'unhandled exception error' as a result. (rememeber we are pretending not
to be an AcDbPolyline entity). To solve the problem, you need to modify
the 'saveAs()' method like this:

<code_begin>
bool mbDrawWithExplode = false ;

void AcDbMyPolyline::saveAs(AcGiWorldDraw* mode, AcDb::SaveType st) {
assertReadEnabled();

if ( st == AcDb::kR12Save ) {
  AcDbPolyline::saveAs (mode, st) ;
} else {
  mbDrawWithExplode = true ;
  worldDraw (mode) ;
  mbDrawWithExplode = false ;
}
}
<code_end>

Implement your 'worldDraw()' method like this:

<code_begin>
Adesk::Boolean AsdkOPLine::worldDraw(AcGiWorldDraw* mode)
{
assertReadEnabled();

if ( !mbDrawWithExplode ) {
  bPEdit =true ;
  if ( AcDbPolyline::worldDraw (mode) != Adesk::kTrue ) {
   bPEdit =false ;
   return (Adesk::kFalse) ;
  }
  bPEdit =false ;
} else {
  AcDbVoidPtrArray ents ;
  AcDbPolyline::explode (ents) ;
  for ( int j =ents.length () - 1 ; j >= 0 ; j-- ) {
   ((AcDbEntity *)ents.at (j))->worldDraw (mode) ;
   delete (AcDbEntity *)ents.at (j) ;
  }
  ents.setLogicalLength (0) ;
}
return (Adesk::kTrue) ;
}
<code_end>

Are we finished yet?

Unfortunatelly not yet! If you pretend you are not an AcDbPolyline, the
AutoCAD "_PEDIT" command will not work for your custom entity anymore.
If you do not intend to support "_PEDIT", then it is not a problem.
However if you intend to support "_PEDIT" then you need to pretend that
your are an AcDbPolyline only for the "_PEDIT" command. To support
"_PEDIT" for a special class requires quite an amount work. First you
need to rewrite the 'ACRX_DXF_DEFINE_MEMBERS' ARX macro like this:

<code_begin>
bool bPEdit =false ;

void set_bPEdit (bool flag) {
bPEdit =flag ;
}

//------------------------------------------
#define MY_ACRX_DEFINE_MEMBERS(CLASS_NAME) \
AcRxClass* CLASS_NAME::desc() \
{ \
    return (AcRxClass*)((AcRxDictionary*)acrxSysRegistry() \
  ->at(ACRX_CLASS_DICTIONARY))->at(bPEdit ? "AcDbPolyline" : "AcDbMyPolyline"); \
} \
AcRxClass* CLASS_NAME::isA() const \
{ \
    return (AcRxClass*)((AcRxDictionary*)acrxSysRegistry() \
  ->at(ACRX_CLASS_DICTIONARY))->at(bPEdit ? "AcDbPolyline" : "AcDbMyPolyline"); \
} \
AcRxClass* CLASS_NAME::gpDesc = NULL

//----------------------------------------------------------------------
#define MY_ACRX_DXF_DEFINE_MEMBERS(CLASS_NAME,PARENT_CLASS,DWG_VERSION,\
              MAINTENANCE_VERSION,PROXY_FLAGS,DXF_NAME,APP) \
MY_ACRX_DEFINE_MEMBERS(CLASS_NAME); \
static AcRxObject * make##CLASS_NAME() { return new CLASS_NAME(); } \
void CLASS_NAME::rxInit() { \
    if (CLASS_NAME::gpDesc != NULL) \
        return; \
    CLASS_NAME::gpDesc = newAcRxClass(#CLASS_NAME, #PARENT_CLASS, \
        DWG_VERSION,MAINTENANCE_VERSION,PROXY_FLAGS, \
        &make##CLASS_NAME, #DXF_NAME, #APP); \
}
<code_end>

Replace the 'ACRX_DXF_DEFINE_MEMBERS' ARX macro with the following definition:

<code_begin>
MY_ACRX_DXF_DEFINE_MEMBERS(AcDbMyPolyline, AcDbCurve,
                        AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
                        AcDbProxyEntity::kNoOperation,
                        ACDBMYPOLYLINE, ACDBMYAPP
);
<code_end>

The last item you need to implement is an AcEditorReactor to detect when
the "_PEDIT" command is executed and set the pPEdit flag to true as
follows:

<code_begin>
void AsdkEdReactor::commandWillStart(const char* cmdStr)
{
if ( stricmp (cmdStr, "PEDIT") == 0 )
  set_bPEdit (true) ;
}

void AsdkEdReactor::commandEnded(const char* cmdStr)
{
if ( stricmp (cmdStr, "PEDIT") == 0 )
  set_bPEdit (false) ;
}

void AsdkEdReactor::commandCancelled(const char* cmdStr)
{
if ( stricmp (cmdStr, "PEDIT") == 0 )
  set_bPEdit (false) ;
}

void AsdkEdReactor::commandFailed(const char* cmdStr)
{
if ( stricmp (cmdStr, "PEDIT") == 0 )
  set_bPEdit (false) ;
}
<code_end>

When the "_PEDIT" command starts, the AsdkEdReactor::commandWillStart()
reactor callback is called and the bPEdit boolean is set to true. Then
AutoCAD verifies that the entity selected is "kind of" an AcDbPolyline.
To do this AutoCAD calls the AcRxObject::isKindOf() method, this in turn
calls the class descriptor of the entity (i.e. our AcDbMyPloyline::desc())
which will return the AutoCAD AcDbPolyline class descriptor. In all other
situations, it will returns a real custom entity class descriptor
(child of AcDbCurve).

** Forward Compatibility **

While it is clear that the two defects mentionned above will be fixed in a
later release of AutoCAD, the only question remaining is; Will my custom
entity derived from AcDbPolyline, continue to work?

The answer is *YES*! It will not only continue to work, but you will also
be allowed to remove the workarounds implemented here without any problem
(even reloading files from one implementation to another).
  
  

3 - Deriving from AcDbBlockReference
------------------------------------

Solution 47499: CUSTOM BLOCK REFERENCES MIRROR INCORRECTLY
/cgi-bin/solution.pl?SID=47499
Here is the listing for Technical Solution 47499

Question:

I have derived a custom block reference (from AcDbBlockReference), but
when I mirror it twice its scale factor & rotation become incorrect.

Answer:

This problem is not observed in AutoCAD for normal AcDbBlockReference
objects, because the "MIRROR" command handles block references specially
in that the 'transformBy()' function is not used. The implementation of
AcDbBlockReference::transformBy() is incorrect. It is only in derived
AcDbBlockReference classes that this incorrect behaviour with respect
to 'transformBy()' is observed. This defect is logged with ID 22064.

To fix this problem you must implement transformBy() at the derived
classes level as follows:

<code_begin>
#include "dbxutil.h"
#include "geassign.h"
#include "math.h"

#define FUZZEQ(x,y) ( fabs( (x) - (y) ) <= AcGeContext::gTol.equalPoint() ? 1 : 0 )
#define PI ((double)3.14159265358979323846)

static double const pi = PI;
static double const twopi = PI * 2.0;
static double const piover2 = PI / 2.0;

double fixangle(double angle)
{
    double retang, retint;

    if (angle - 1.0 == angle) // Infinity
     angle = 0;            // Treat inifinity as 0 for angles

    // Reduce any angle to 0-2*PI
    retang = angle / twopi;             // Get number of 2*PI intervals
    retint = ( retang > 0.0 ? floor( retang ) : ceil( retang ));
    retang = (retang - retint) * twopi; // Strip off the full ones
    if (retang < 0.0)
        retang += twopi;                // Correct for negative angles
    if (retang >= twopi)
        retang -= twopi;                // Correct for angles like -1E-30

    return retang;
}

Acad::ErrorStatus
MyDerivedBlockReference::transformBy(const AcGeMatrix3d& xform)
{
    assertWriteEnabled();

    if (!xform.isUniScaledOrtho())
        return Acad::eCannotScaleNonUniformly;

    // Make points out of the scale factors to simplify transforming them
    AcGeScale3d scales = scaleFactors();
    AcGePoint3d ptScaleX(scales.sx,0,0);
    AcGePoint3d ptScaleY(0,scales.sy,0);
    AcGePoint3d ptScaleZ(0,0,scales.sz);

    const bool bXPositive = (scales.sx >= 0.0);
    const bool bYPositive = (scales.sy >= 0.0);
    const bool bZPositive = (scales.sz >= 0.0);

    // Get angle of rotation and the normal vector
    double rot = rotation();
    AcGeVector3d norm = normal();
  
    AcGePoint3d ptOrigin(0,0,0);

    // If it's rotated then do it
    if ( fabs( rot ) > 0.0 )
    {
        AcGeMatrix3d mat;
        mat.setToRotation( rot, AcGeVector3d(0,0,1));
        ptScaleX.transformBy( mat );
    }

    ptOrigin.transformBy(xform);

    AcGeVector3d vec, vecScaleXForRotation;

    acdbEcs2Wcs( asDblArray(ptScaleX), asDblArray(ptScaleX),
              asDblArray(norm), Adesk::kFalse );
    ptScaleX.transformBy(xform);
    vec = vecScaleXForRotation = ptScaleX - ptOrigin;
    scales.sx = vec.length();

    if (FUZZEQ(scales.sx, 1.0))
        scales.sx = 1.0;

    acdbEcs2Wcs( asDblArray(ptScaleY), asDblArray(ptScaleY),
              asDblArray(norm), Adesk::kFalse );
    ptScaleY.transformBy(xform);
    vec = ptScaleY - ptOrigin;
    scales.sy = vec.length();

    if (!bYPositive)
        scales.sy = -scales.sy;
    if (FUZZEQ(scales.sy, 1.0))
        scales.sy = 1.0;

    acdbEcs2Wcs( asDblArray(ptScaleZ), asDblArray(ptScaleZ),
              asDblArray(norm), Adesk::kFalse );
    ptScaleZ.transformBy(xform);
    vec = ptScaleZ - ptOrigin;
    scales.sz = vec.length();

    if (!bZPositive)
        scales.sz = -scales.sz;
    if (FUZZEQ(scales.sy, 1.0))
        scales.sz = 1.0;

    AcGePoint3d pos( position() );
    pos.transformBy(xform);
    norm.transformBy(xform);

    setNormal(norm);
    setPosition(pos);

    acdbWcs2Ecs( asDblArray(vecScaleXForRotation),
              asDblArray(vecScaleXForRotation),
     asDblArray(norm), Adesk::kFalse );
    setRotation( fixangle( atan2( vecScaleXForRotation[Y],
              vecScaleXForRotation[X] )));

    // Check whether the scale factor will change from
    // positive to negative or vice-versa
    if (( !bXPositive && xform.det() > 0 ) ||
     ( bXPositive && xform.det() < 0 ))
    {
        setRotation( fixangle( rotation() + PI ));
        scales.sx = -scales.sx;
    }

    setScaleFactors( scales );

    Acad::ErrorStatus es = Acad::eOk;
    AcDbObjectIterator* pAtIter = attributeIterator();
    const bool dbResident = (database() != NULL);
    for (; es == Acad::eOk && !pAtIter->done(); pAtIter->step())
    {
        AcDbAttribute* pAtt;
        if (dbResident)
        {
            if (Acad::eOk == (es = acdbOpenObject( (AcDbObject*&)pAtt,
                        pAtIter->objectId(), AcDb::kForWrite)))
            {
                es = pAtt->transformBy(xform);
                pAtt->close();
            }
        }
        else
        {
            pAtt = (AcDbAttribute*)pAtIter->entity();
            es = pAtt->transformBy(xform);
        }
    }
    delete pAtIter;

    // transform any xdata that needs it
    //
    xDataTransformBy(xform);
    AcDbSequenceEnd *pSEnd;
    if (openSequenceEnd(pSEnd, AcDb::kForWrite) == Acad::eOk)
    {
        pSEnd->xDataTransformBy(xform);
        assert(Acad::eOk == pSEnd->close());
    }

    return es;
}
<code_end>

Note that custom block references cannot currently contain attributes,
though this code would, in fact, transform any that existed in the block
reference.
  

4 - RefEdit in AutoCAD
    Supporting the RefEdit for your entity and data
---------------------------------------------------

From the documentation:
<<<<<<<
To increase AutoCAD's extensibility and aid collaboration in the design
process, AutoCAD 2000 further enhances the reference capabilities in
AutoCAD. Users may select a block reference or external reference (xref)
and specify a portion of the reference to edit in-place. The selected
geometry will be instantiated in the current drawing, edited, then saved
back to the block definition or reference file.
>>>>>>>

This clearly means the AutoCAD RefEditing feature has been implemented for
entities and only entities. This might be a problem in case your XREF'ed
drawing is not only composed of entities, but also contains non graphical
objects either in the Extension Dictionary of an entity or in the NOD.
Such non graphical objects could either be data or a reactor and they are
not necessarily maintained during RefEdit protocol.

Suppose you have an entity with a reactor attached to it and that the
reactor is stored in the NOD. RefEdit uses the wblock() protocol to clone
objects. As selected entities can instantiated during a RefEdit session, you
would select the entity (reactor attached) of interest during this process
but the reactor itself will not be cloned since a reactor is reference from
the entity via an AcDbSoftPointerId. To have the reactor included in the
RefEdit session requires some additional work. A quick solution to the
problem which does not require additional work is to put the reactor into
the entity extension dictionary, because in such a case, wblock() will
clone the reactor as well.

However, there is still a problem due to a defect into AutoCAD. The entity/reactor
link will be broken when you return from RefEdit. This is a *bug* in the
implementation of RefEdit, and fortunately there is a workaround to this.

Because this is a too large a subject to cover within the confines of a
newsletter, the complete description/discussion and sample code for the
RefEdit problem is available at the following URL:

http://adn.autodesk.com/techsupp/utilitiestechpapers.htm

Document "Deep Cloning in AutoCAD 2000 (version 2.0)" by Cyrille Fauvel
  
  

5 - New and Updated solutions
-----------------------------

30527: HOW TO EXPORT VARIABLES FROM ONE OBJECTARX APP TO ANOTHER ARX APP?
/cgi-bin/solution.pl?SID=30527

30525: ADS REQUEST ERROR WHEN REGISTERING A FUNCTION VIA ACEDDEFUN()
/cgi-bin/solution.pl?SID=30525

44939: SETCURDOCUMENT WITH DOCUMENT LOCKING NEEDS UNLOCKING
/cgi-bin/solution.pl?SID=44939

1472: CONTROL ENTITY'S DISPLAY AS IF LOOKED AT FROM PLANVIEW
/cgi-bin/solution.pl?SID=1472

30449: HOW TO GET THE GEOMETRY FROM A DIMENSION ENTITY.
/cgi-bin/solution.pl?SID=30449

30543: APPLYING A DIMSCALE TO A LEADER ENTITY
/cgi-bin/solution.pl?SID=30543

39793: HOW TO FILE A BINARY CHUNK WITH DWG/DXF FILERS
/cgi-bin/solution.pl?SID=39793

42019: GETTING MIDPOINT OF EACH CURVE SEGMENT
/cgi-bin/solution.pl?SID=42019

43921: GET XREF PATH NO MATTER IF RETAINING PATH INFORMATION OR NOT
/cgi-bin/solution.pl?SID=43921

44347: ATTACHING HYPERLINK URLS TO ENTITIES
/cgi-bin/solution.pl?SID=44347

45185: READDWGFILE CRASHES AUTOCAD IF CONTAINS AN ACDBOLE2FRAME
/cgi-bin/solution.pl?SID=45185

46370: SUPPORT DIVIDE COMMAND IN A CUSTOM ENTITY
/cgi-bin/solution.pl?SID=46370

46564: ADS FUNCTIONS AND IN MEMORY DATABASE ACCESS
/cgi-bin/solution.pl?SID=46564

46586: SET PLOT STYLE NAME
/cgi-bin/solution.pl?SID=46586

46822: CUSTOM ENTITY WORK WITH FILLET COMMAND
/cgi-bin/solution.pl?SID=46822

46581: DEEPCLONE DIFFERENCES IN R2000 AND R14
/cgi-bin/solution.pl?SID=46581

34813: FIX:ACEDDRAGGEN DOES NOT WORK WITH POLAR TRACKING
/cgi-bin/solution.pl?SID=34813

43213: JUDGE IF POINT IS ON LINE BOUNDED OR UNBOUNDED
/cgi-bin/solution.pl?SID=43213

24735: HOW DO I USE ACGIXUTILITIES::TRIANGULATEFACE() ?
/cgi-bin/solution.pl?SID=24735

44382: HOW TO SOLVE RUNTIME PROBLEMS WITH USING BREP IN OBJECTDBX
/cgi-bin/solution.pl?SID=44382

46578: HOW TO TELL WHICH APP IS USING THE DBX MODULE
/cgi-bin/solution.pl?SID=46578
  
  

6. Upcoming Training Schedule
-----------------------------
ObjectARX Training is scheduled in the UK and USA in
February-March as follows:

Guildford, UK
    Intro to ObjectARX    28-Feb -  1-Mar
    AutoCAD UI             2-Mar -  3-Mar

San Rafael, CA
    Intro to ObjectARX     6-Mar -  8-Mar
    AutoCAD UI             9-Mar - 10-Mar

Please register for these classes at
<mailto:adn-training-worldwide@autodesk.com>

API Training class descriptions and up to date schedules are located
on the ADN Training Pageat the following URL:

http://www.autodesk.com/solution/partners/adn/training/index.htm

-----------------------------------------------------------------------------
To subscribe or unsubscribe, go to
http://adn.autodesk.com/techsupp/docs/newsletters.htm
-----------------------------------------------------------------------------

     You received this message as a result of your registration
     on the ADN List Server subscription page.  If you no longer wish
     to receive these messages, read the next section, How to use this
     mailing list.

     How to use this mailing list:

     You may unsubscribe from this e-mail newsletter, or subscribe to
     a variety of other informative e-mail newsletters, by returning
     to the ADN List Server subscription page at
       http://adn.autodesk.com/techsupp/docs/newsletters.htm
     and changing your subscription preferences.

     Alternatively, from the subscribed account you can send an e-mail to
     <Majordomo-partnersys@autodesk.com> with the following command in the
     body of your email message:

     unsubscribe <list-name>

     ----------------------------------------------------------------------

     Autodesk Developer Network (ADN) information and events:

     For information on all ADN topics, please visit:
       http://www.autodesk.com/adn

     ----------------------------------------------------------------------

     THIS DOCUMENT IS PROVIDED FOR INFORMATIONAL PURPOSES ONLY.  The
     information contained in this document represents the current view of
     Autodesk Inc. on the issues discussed as of the date of publication.
     Because Autodesk must respond to change in market conditions, it
     should not be interpreted to be a commitment on the part of Autodesk
     and Autodesk cannot guarantee the accuracy of any information
     presented after the date of publication.
     INFORMATION PROVIDED IN THIS DOCUMENT IS PROVIDED 'AS IS' WITHOUT
     WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
     LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
     PARTICULAR PURPOSE AND FREEDOM FROM INFRINGEMENT.
     The user assumes the entire risk as to the accuracy and the use of
     this document. This  document may be copied and distributed subject to
     the following conditions:
     1.   All text must be copied without modification and all pages must
          be included
     2.   All copies must contain Autodesk's copyright notice and any other
          notices provided therein
     3.   This document may not be distributed for profit

     ----------------------------------------------------------------------
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-12-25 01:38 , Processed in 0.415186 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表