Sunday, April 24, 2005

Class 11 - Custom ObjectARX Class

Introduction

In my personal opinion, the greatest feature of ObjectARX is the capability to develop your own objects and entities. This powerful feature will allow you to create complex applications and provide your users a unique experience using your software.

This feature is possible since ObjectARX beginning (officially at AutoCAD R13). Since Autodesk provided this feature, its own developers thought that they could develop their selves vertical solutions for the most interesting market areas. At that time, products like MAP, MCAD and ADT start to show up.

Today there are several vertical products based on AutoCAD made by Autodesk and much more developed by third-party companies.

How is this possible?

ObjectARX takes full advantage of C++ language features like inheritance, polymorphism and overriding among many others. This allows Autodesk to publish part of AutoCAD source code using a SDK like package with library and header files.

Beyond this point, ObjectARX exports some classes allowing you to derive from them and implement your own behavior taking advantage of all ready-to-use methods and overriding those ones you need.

This way, when your custom class is defined and implemented your application will be compiled and linked with AutoCAD native libraries and headers and will be possible to load your module (DLL) at runtime to use your own objects inside AutoCAD! Great hum?

When to use and when not to use custom objects

Even being a powerful feature of ObjectARX, custom objects are not the best solution for any kind of implementation. Sometimes is better to user another solution like XData or XRecords. This will totally depend on how much complex your application is and how much complex will be the way users will interact with your product.

You need to be sure when to use or not custom classes inside ObjectARX. Personally I perform some questions to myself that will help me to decide:

- My product's elements are simple or complex?
- My elements are only complex in terms of non-graphical data or they will require complex graphical representation?
- Do I need to protect my element's data when the drawing is out of my company?
- Will my elements present a complex interaction with users very different from AutoCAD native entities?
- Do I need to share common information among my elements?

These questions will really help you to decide or not to user custom classes.

How to use a custom objects?

The first step is to choose your base class. This will depend on what type of custom object are you willing to implement. Basically you need to choose if it will represent an entity or a data object. If it will be an entity you will need to derive it from AcDbEntity or other of its derived classes. In other hand, if it will not have graphical appearance, you will derive it from AcDbObject. There are some ObjectARX classes that does not allow you to derive from. Take a look at ObjectARX documentation for a complete list.

It is very important to you clearly understand these differences between AcDbEntity and AcDbObject. Remember that every AcDbEntity if also an AcDbObject but NOT ALL AcDbObject is an AcDbEntity. This is because AcDbEntity is derived from AcDbObject.

I really would like you to walk through the ObjectARX class hierarchy to locate yourself in that tree and see clearly what are we talking about. There is a DWG file, called classmap.dwg, inside your ObjectARX SDK folder called \classmap.

Runtime Identification

AutoCAD requires that every custom class has its own runtime type identification. This will be used by AutoCAD and by your own application. Basically you don't need to care about this because there are MACROS to do this job for you. The AcRxObject class is the responsible to perform this feature and exactly due that it is on the top of AcRx tree.

The runtime identification is made by some functions like the following:
  • desc(), a static member function that returns the class descriptor object of a particular (known) class.
  • cast(), a static member function that returns an object of the specified type, or NULL if the object is not of the required class (or a derived class).

  • isKindOf() returns whether an object belongs to the specified class (or a derived class).
  • isA() returns the class descriptor object of an object whose class is unknown.
These functions are pretty useful because they help you to get runtime important information from AutoCAD native objects and your own objects. A good example if when you have a pointer to an AcDbEntity and would like to know if it is an AcDbCircle or an AcDbLine. How? Just use the above functions to get the information or even try to cast the pointer.

To declare these functions you will need to use the following MACRO inside your class declaration:

ACRX_DECLARE_MEMBERS(CLASS_NAME);

To implement these functions, you will need to use one of the following MACROS:
  • ACRX_NO_CONS_DEFINE_MEMBERS (CLASS_NAME, PARENT_CLASS):
    Use for abstract classes and any other classes that should not be instantiated.
  • ACRX_CONS_DEFINE_MEMBERS (CLASS_NAME, PARENT_CLASS, VERNO):
    Use for transient classes that can be instantiated but are not written to file.
  • ACRX_DXF_DEFINE_MEMBERS (CLASS_NAME,PARENT_CLASS, DWG_VERSION, MAINTENANCE_VERSION, PROXY_FLAGS, DXF_NAME, APP):
    Use for classes that can be written to, or read from, DWG and DXF files.
Additionally, you will need to initialize and delete your custom class from ObjectARX runtime tree which can be done, during your application's kInitAppMsg and kUnloadAppMsg using the following functions implemented by the above MACROS:

// Inside kInitAppMsg function handler
MyClass::rxInit();
// Call this only once for all of your custom classes
acrxBuildClassHierarchy();

// Inside kUnloadAppMsg function handler
deleteAcRxClass(MyClass::desc());

This will guarantee that when your application is loaded AutoCAD recognizes your class and when it was not present (unloaded) AutoCAD will transform your class instances into Proxy entities. Proxy entities are a binary package that protects and preserves your custom object during DWG roundtrip without your application.


Lab 2 - Solved

Hello,

Hope you have successfully found a solution for this Lab. I will present my solution which does not mean that it is the best solution. It is just my solution.

After follow the Lab instructions I have successfully created the project and the Dialog (derived from AcUiDialog). I have created the proposed layout with the Combo and Select button.

Inside the dialog class header, I have added the following:

ads_name m_sset;

This will store my selection set. Next, I have attached an event to my select button which fires the following function:

BeginEditorCommand();

// Issue selection
acedSSFree(m_sset);
int err = acedSSGet(NULL, NULL, NULL, NULL, m_sset);
if (err != RTNORM) {
MessageBox(_T("Selection error."),_T("DlgColor"),MB_ICONEXCLAMATION);
}

long length = 0;
acedSSLength(m_sset, &length);
m_btn_apply.EnableWindow(length > 0);

CompleteEditorCommand();


This will request the user to perform a selection set at AutoCAD screen. Note that we need to hide the dialog and switch back when finished. Note that m_btn_apply should be mapped to the OK button.

After that, we will need to perform the modifications walking through the selection set, get each entity's ObjectId, open it and then change the color according to the selected Combo item. So, the event fired when clicking on the Apply button will be:

CAcUiDialog::OnOK();

// Retrieve selected color in ComboBox
AcCmColor clr;
m_color.GetCurrentItemColor(clr);

long i, length;
ads_name ename;
AcDbObjectId entId;
acedSSLength(m_sset, &length);

// Traverse selected entities
acdbTransactionManager->startTransaction();
for (i = 0; i < length; i++) {

// Get each entity's objectId
acedSSName(m_sset, i, ename);
acdbGetObjectId(entId, ename);
// Open the entity and set its color
AcDbEntity* pEnt = NULL;
if (
acdbTransactionManager->getObject((AcDbObject*&)pEnt,
entId,
AcDb::kForWrite) == Acad::eOk) {
pEnt->
setColor(clr);
}
// Don't need to close because we're using Transaction
}
acdbTransactionManager->endTransaction();
acedSSFree(m_sset);

That's it!
Hope you enjoy this sample.

You may download this sample from here: ARXLAB2.zip!

Stay tuned for the next classes!

Saturday, April 16, 2005

Lab 2 - Using a MFC dialog

Hello,

Our second Lab will cover MFC contents and some interaction with AutoCAD. The main idea is to keep this lab simple to consolidate MFC and user interaction knowledge.

Requirements:

* Class 1 to 10;
* AutoCAD 2004/2005/2006 or compatible vertical installed;
* Visual Studio .NET 2002 installed;
* ObjectARX Wizard installed.

Objectives:

Create a simple ObjectARX module with 1 commands: DLGCOLOR. This command will create a simple MFC dialog with a color combo box and one selection button. As the user clicks on this button it will prompt user to select one or more existing entities. After click Apply it will change the color of all selected entity.

Instructions:

- Create a project called ARXLAB2 using ObjectARX Wizard;
- Enable Using MFC option with AutoCAD MFC Extensions;
- Click on the a> icon at ARXWizard's toolbar to open command dialog;
- Right click on the above portion and select New;
- Change the global an local name for DLGCOLOR and select Modal as command mode;



- Open the Visual Studio Editor and add a new dialog layout. Add a combo box control and a button control;
- Open the Autodesk Class Explorer, right click on the root and select Add MFC Ext. Class. Select CAcUiDialog as the base class;
- In the dialog layout, right click on the combo box and select Add Variable. Choose CAcUiTrueColorComboBox as its class and name it as m_color. Right click on the combo again and select Properties. Set Has Strings = True, Owner Draw = Fixed;
- Now, right click the button and select Add Variable. Choose CAcUiSelectButton as its class and name it as m_select. Right click once more, select Properties. Set Owner Draw = True.
- Add the virtual BOOL OnInitDialog() method. Inside its implementation add the following:

CAcUiDialog::OnInitDialog();
SetWindowText(_T("ObjectARX for Dummies - Lab 2"));
m_select.AutoLoad();
return TRUE;


- Map a click event to selection button. Right click on it, select Add Event Handler. Select BN_CLICKED event. Inside the event function, we will need to hide the dialog and switch to AutoCAD screen. As we have derived from CAcUiDialog it already has a couple of functions to do that. So we will need to hide the dialog, select the desired entities and then show the dialog back. Your function outline will be something like this:

BeginEditorCommand();
// Perform here the user interaction (allow user to select entities)
CompleteEditorCommand();


- Don't forget to switch the resources to your application before open the dialog:

CAcModuleResourceOverride res;
CDlgColor dlg;
dlg.DoModal();


Tips:

- Don't forget to call close() for all selected entities (use a Transaction if you prefer);
- Explore the code to understand what ARX Wizard has created for you;
- Pay attention to code syntax;
- Use the ObjectARX documentation when necessary;

Support:

If you have any questions please post your issue on this article to share with others.

Expected time:

- I will give you 3 days to accomplish this Lab;
- After this period, I will post my suggested solution for this.

Wednesday, April 13, 2005

The "Big Picture" - Interview with Jim Quanci (Autodesk)

Hello,

Sometimes we get too deep into programming and loose focus about the most important things involved in our business. Companies are discovering the great benefits of develop their own solutions for AutoCAD. Thinking on this, I have decided to make another interview to allow you to see the "Big Picture" of ObjectARX development. I have contacted Jim Quanci, ADN Program Worldwide (Senior Manager), to talk about these things around ObjectARX development. Hope you stop to code a little bit and think about what Jim have answered!

[Fernando:] Jim, how long are you an Autodesk member and from where you begin inside Autodesk until reach the current position?

[JIM:] I have been at Autodesk for just over 15 years – started when Autodesk just released AutoCAD Release 10. I initially started working with Autodesk’s hardware partners of which there were many. This was back in the days when we supported 9 different hardware platforms including several Unix flavors and the Mac. After working with software partners in Americas and then in Asia for several year as part of the Autodesk Registered Developer Program, my team started the Autodesk Developer Network (in 1997).

[Fernando:] On the last Autodesk University people have talked about how to involve users and developers communities around Autodesk products. What is your personal opinion about this strategy and how ADN is contributing on this?

[JIM:] Companies are becoming increasingly sophisticated users of technology and are being driven to integrate their technology systems to stay competitive. Users and developers are searching for ways to integrate the software technologies they are using for competitive advantage. I believe by creating wide awareness of the capabilities to integrate Autodesk technologies with other systems including CRM and ERP, users and developers will move toward taking advantage of the depth and breadth of Autodesk product customization capabilities. ADN is just one of several programs from Autodesk helping users and developers get the most from their software investments. Along with ADN, other Autodesk programs supporting deeper use of Autodesk products and technologies include Autodesk Subscription, Autodesk Training Centers (ATC), Autodesk Official Training Courseware (AOTC) and Autodesk Inventor Certified Expert.

[Fernando:] ADN is getting bigger and today we can see several companies working on products that run on the top of AutoCAD. Why some people still can't see clearly the power of customized solutions?

[JIM:] Today, over 2500 companies from around the world develop custom solutions based on Autodesk platforms. Over 300 companies join ADN for the first time every year. The number of Autodesk customers developing custom built applications to give them a competitive advantage is growing every year. It is just a matter of time.

[Fernando:] What are the main benefits to develop your own solutions inside AutoCAD?

[JIM:] The primary advantage of using an existing design product to build an application on is all about not reinventing the wheel. Autodesk’s is investing hundreds of millions of dollars every year increasing the capabilities of Autodesk design platforms – AutoCAD, Autodesk Inventor, Autodesk Map 3D, Autodesk Architectural desktop, Autodesk Revit and more. Why invest money developing basic design functionality and all the ancillary support software needed to work with printers and graphics cards from numerous manufacturers?

[Fernando:] Why so many developers stay away from ObjectARX? Is this due its long learning curve, poor documentation (like books and websites) or just because they love VBA and VisualLISP?

[JIM:] The idea that people avoid ObjectARX is a misnomer. ObjectARX is the most popular API for ADN members with over 50% of ADN members using ObjectARX – more then LISP, VB and VBA. Among Autodesk customers, LISP, VB and VBA are more popular then ObjectARX which makes a lot of sense as casual part time software developers frequently don’t have the time to become C++ proficient.

[Fernando:] ADN has a subscription cost that is cheap for companies but very expensive for independent developers. Is there any plans to create a lower rate (or even free) limited subscription program for this kind of developers?

[JIM:] The lowest cost option to join ADN today is 1200 (USD in Americas and APac and Euros in the rest of the world). This includes access to virtually all Autodesk products, unlimited direct support from Autodesk software engineers, and attendance at future technology briefings – at no extra cost. Compare this to the Microsoft Developer Network where one pays $2000 for access to most software and for limited direct support. We are not currently planning a lower cost ADN membership offering. Today we provide basic application development information through the Autodesk Developer Center (www.autodesk.com/adn) with free/self support through customization discussion groups.

[Fernando:] ADN promote several events around the world but these events are closed to ADN members. Is there any Autodesk developer event opened to all users?

[JIM:] I believe you meant to say are there ADN events that are open to non-ADN members. The answers is yes. We hold software development conferences for non-ADN members at several sites around the world every year – to bring customers up to speed on our latest technologies while we also promote their joining ADN to learn. Last year we held these “open to everyone API conferences” in China, Japan, United States, England, Sweden, and Germany. In this coming year, we expect to hold similar API conferences in China, Russia, Poland, and several other countries. One does need to be an ADN members to participate in our annual “Autodesk Developer Days” conferences where we present confidential information to ADN members on future releases of Autodesk products and technologies.

[Fernando:] How many ADN members are registered today and how Autodesk plans to expand this number?

[JIM:] There are over 2500 ADN members today and the number is growing every year. We are investing especially heavily this year recruiting new ADN members in China and Eastern Europe.

[Fernando:] We currently have AUGI as an opened group for AutoCAD users. Is that possible that Autodesk support or even create some kind of ADGI (Autodesk Developers Group International) ?

[JIM:] Autodesk would be happy to support such a group – as we supported “Autodesk Developers Group Europe” (ADGE) for many years. ADN is the Autodesk support program for professional software developers. We are not currently pursuing creating and ADGE like group ourselves.

[Fernando:] How do you think .NET will change the way developers create solutions today?

[JIM:] .NET is all about increasing programmer productivity. To some degree, .NET was hijacked by the Internet boom. Many people missed that the primary benefit of .NET is not about the Internet but about giving programmers easy to learn and use powerful tools to get their job done. .NET makes C++ experts faster/more productive. .NET gives VB programmers the power of C++ without the complexity. .NET is a great software development environment and Visual Studio .NET is a great software development tool – a big improvement over past software development technologies.

Thank you!

Monday, April 11, 2005

Class 10 - Using MFC

This class is not fully related to AutoCAD and ObjectARX but it covers an overview of MFC library. This library will allow you to create rich interfaces for your ObjectARX applications easily and with professional style.

Introduction

MFC (Microsoft Foundation Classes) is a powerful library made to allow windows programmers to easily create rich interfaces following the windows standard interface.

The MFC class tree is huge and obviously it is not the objective of this class to make you an MFC wizard. I will present here the main concepts involved when using MFC inside AutoCAD and how to take advantage of its power.

If you would like to use MFC inside your ObjectARX application you will need to link it with MFC libraries which can be done dynamically or statically. Currently ObjectARX only support dynamic linked MFC DLL applications because some of AutoCAD libraries were dynamic linked with MFC and you can't mix static and dynamic linked libraries. To make your application dynamic linked with MFC you need to select MFC Extension DLL option when creating your application.

Resource Management

One of the most important concepts when dealing with MFC libraries is that they are based on resources. Resources are rich information such as bitmaps, icons, string tables, dialog layouts, etc. Each DLL has its own resource package that could be used only by itself or shared with other DLLs (Resource only DLLs for example).

The problem is that your ObjectARX application is running into AutoCAD host application which has its own resources. To solve this problem you should switch the resource context to your DLL, use them, and then switch back to AutoCAD. This can be done manually but there is a couple of classes to help you to easily do that.

The first class, called CAcExtensionModule which will handle your module's own resource and the default resources. To make your application take advantage of this class you will need to create an instance of this class inside each module DllMain() function. This can be done using the following:
AC_IMPLEMENT_EXTENSION_MODULE(theArxDLL);

HINSTANCE _hdllInstance = NULL;

extern "C" int APIENTRY

DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) {

// Remove this if you use lpReserved
UNREFERENCED_PARAMETER(lpReserved);

if (dwReason == DLL_PROCESS_ATTACH) {

theArxDLL.AttachInstance(hInstance);

hdllInstance = hInstance;

}

else if (dwReason == DLL_PROCESS_DETACH) {

theArxDLL.DetachInstance();

}

return 1; // ok

}
The second class, called CAcModuleResourceOverride is a handy class that performs the switch from AutoCAD's resource to your application's resource when it is instantiated and then, when it is destroyed, switch back to AutoCAD. To use it, just declare an object of it before using your own resources. When it goes out of scope it will be destroyed and its destructor will switch back. So, this is the way to go:
CAcModuleResourceOverride res;

CMyDialo dlg;

dlg.DoModal();


This way you will successfully create your dialog and won't face strange errors like: "An unsupported operation was attempted". Another possible error happens with other dialog appearing instead of yours! Crazy hum? Remember that this applies to any type of resources including strings placed into string tables.

Using MFC Built-in support
Autodesk has also provided us some great classes to make our application looks like a native AutoCAD feature and work much more integrated with AutoCAD's interface. There are two collections of MFC built-in classes which are grouped by AcUi and AdUi prefixes. The AcUi prefixed classes are made to work inside AutoCAD environment and the AdUi classes are made to work outside AutoCAD but, due to license agreement, could be used only on applications that interact with AutoCAD.

Each of these two classes allow us to create buttons like those one we can see inside AutoCAD native dialogs, allow us to create smart edit controls modified to work with angles, points, texts, etc. There are also great combo boxes that allows us to create Layer like combos, linetype combos, color combos, etc.

These classes really provide you a professional appearance. There are also other advanced features like hack into AutoCAD Options dialog creating your own tab, create dockable dialogs, among many others.

Take a look inside ObjectARX documentation to see a complete list of those classes.

Tuesday, April 05, 2005

ARXWizard for AutoCAD 2006 - Interview with Cyrille Fauvel (Autodesk)

Hello,

One of the greatest tools to easily create ObjectARX applications is the ARXWizard tool that comes with ObjectARX SDK. I have contacted Cyrille Fauvel, from Autodesk, and he have answered some questions about the new ARXWizard for AutoCAD 2006. I'm always willing to bring you news direct from Autodesk team and I hope you enjoy this new interview. Stay tuned!

[Fernando:] Cyrille, how long are you an ADN / Autodesk member?

[CYRILLE:] I started developing AutoCAD applications while I was student in 1988. And as far I remember it was on release 2.17 with AutoLISP. I joined the Autodesk engineering team in 1993 for developing AutoCAD and preparing AutoCAD to the European localization. In 1996, I moved to the Developer Support / ADN group, and lately in 2004 into the Autodesk Consulting Division, but still doing ADN work.

[Fernando:] Why and how Autodesk has created the ARXWizard and decided to offer it to developers?

[CYRILLE:] The original idea of an ARX wizards was coming from Stefan Kraus a Product Support engineer in Germany. At that time, Stefan was working alone on this project and the wizard was just a application template & command wizards on Visual Studio 4.2. When Stefan, moved from Product Support to ADN, Stefan, Albert and myself rewrote the wizards from scratch to improve wizards features and usage for Visual Studio 98. Now that Stefan left them team, and Albert moved to engineering, I am heading the new team who rewrote the Wizards to work in Visual Studio .NET IDEs. The basic idea of having a wizards is from Stefan, but the Wizards has becoming an important tool for ADN and developers for 3 reasons. It helps us a lot to write a lot of little test application when we working on developer problems submitted to us vis the ADN program, and we hope it helps developers in their daily work as well. The last but not least, the Wizards is an evangelism resource and training tool for developers on ObjectARX.

[Fernando:] Do you plan to expand the ARXWizard providing additional tools to other verticals like ADT and MAP?

[CYRILLE:] Yes, we did introduce ADT and MAP support into the 2005 application wizard, and we hope to continue to extend this capability to other wizards to support specific OMF and MSP features.

[Fernando:] Is there any plans to create a specific Wizard for .NET applications in VB.NET and C#?

[CYRILLE:] :-) they are here in the 2006 version. But like for ADT/OMF and MAP we are still having a lot of work to do to come to the same level of features the pure ObjectARX wizards have.

[Fernando:] What's new in ARXWizard 2006?

[CYRILLE:]
- support for .NET application
- .NET custom object wrapper wizard
- .NET application wizards
- .NET/ARX mixed managed code application wizard
- a JIG wizard
- Updates for the reactor and MFC classes
- Localizable commands for ARX application.
- Code gallery

[Fernando:] Is ARXWizard 2006 backward compatible with 2004 and 2005? Is there any issue?

[CYRILLE:] Hum, ... Yes and No
In theory it is fully compatible, but in practice there is a little glitch there, let me explain the problem.
Projects created with previous version of the wizards (namely 2004 and 2005 versions) will have no problem even if modified with the 2006 wizards version. However, new projects generated with the new version of the wizards will not load into AutoCAD if compiled with previous version of the ObjectARX SDK. :-( The reason of this failure is because the 2006 application wizard do not generate a .def file anymore. Instead the acrxEntryPoint() and acrxGetApiVersion() symbols are exported using #pragma and __declspec from the dbxEntryPoint.h. Since these 'exports' are only in ObjectARX 2006 dbxEntryPoint.h version of the file, a project generated using 2006 version of the Wizards but compiled with the ObjectARX 2004 SDK will not have is symbols exported unless, you add a .def, or copy the dbxEntryPoint.h and arxEntryPoint.h files from ARX 2006 to older ARX SDK (these 2 last files are fully compatible with previous ARX SDK version).

[Fernando:] Users could download the most recent version of ARXWizard only through LiveUpdate tool?

[CYRILLE:] No, if they want they can download it directly from http://adn.autodesk.com/liveupdate/wizards2006.zip Liveupdate will download this file only if there is a more recent version.

[Fernando:] What should developers be aware to avoid a ARXWizard created project to become corrupted?

[CYRILLE:] With the 2004/5/6 versions of the Wizards, there is no more restrictions on what developers can or can't do. Visual Studio .NET IDE comes with an internal parser the wizards are using. So as long VC++ can compile, our wizards can work. However, there is a problem with the MS Intellisense database in .NET 2002 & 2003. This intellisense database do not get updated with ARX symbols when you load a new project, or a project which had not the intellisense database created. The only workaround I found was to manually open the StdAfx.h file to force the refresh. If you forget to do this, Visual Studio may freeze for 2 or 3 minutes when the Visual Studio will try to parse the project. VS tries to parse a project every time you add a new class via a wizard for example.

[Fernando:] Do you think is important to user knows exactly what ARXWizard is doing behind the scenes?

[CYRILLE:] Excepted the ARX AddIn, all wizards source code are public and located at 'C:\Program Files\Autodesk\ObjectARX Wizards for AutoCAD 2006'. Feel free to study :-)
I don't think you need to know exactly what is done behind the scene, the ARX wizards generate code very similar to what ATL wizards.

[Fernando:] Is the ARXWizard team opened to users suggestions through e-mail or maybe feedback surveys?

[CYRILLE:] We have an email address for getting help on Wizards and make suggestions. It is oarxwiz-feedback@autodesk.com for AutoCAD/ObjectARX and invapiwiz-feedback@autodesk.com for the Inventor Wizards which I develop alone this time. But I want to highlight here that we are open to all new ideas, suggestions, and Wizards code submissions.

Thank You!

Sunday, April 03, 2005

Class 9 - Interacting with AutoCAD

Hello,

On the last class I have presented how to perform selection sets. This class I will show how can you interact with AutoCAD using global functions and acquiring information such as numbers, coordinates, system variables and much more.

Invoking Commands

ObjectARX provide us two global functions that allows us to invoke registered commands. This functionality is very handy and will help users to perform quick operations that don't require complex procedures. Even this method is quite simple you should avoid using it in complex and huge operations. This method may also create problems when dealing with events handling.

The two provided functions are acedCmd() and acedCommand(). The first one invokes the command through a passed in resbuf list which will inform all command parameters. The second function will receive a variable number of parameters which will reproduce the way you fire the command from the prompt interface. Below are these functions signature:

int acedCmd(const struct resbuf * rbp);

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

To build the resbuf list when using acedCmd() there is a utility function called acutBuildList() which constructs this linked list easily. You just need to pass paired values with codes that describe the types and end the list with a 0 or RTNONE value. Another good practice is to clear the command prompt, calling acedCommand(RTNONE) , after issued the command. Don't forget to free memory used, when using resbuf pointers, through the acutRelRb() utility function to avoid memory leaks. There are several ways to use theses functions and I will show some of them below:

acedCmd():

a) Moving the last created entity based on (0,0,0):

ads_point pt;
pt[0] = pt[1] = pt[2] = 0.0;
struct resbuf *Mv;
Mv = acutBuildList(RTSTR,_T("_MOVE"),RTSTR,_T("_LAST"),RTSTR,_T(""),
RTPOINT,pt,RTSTR,PAUSE,0);
acedCmd(Mv);
acedCommand(RTNONE);
acutRelRb(Mv);


b) Calling a "redraw" native command:
struct resbuf *cmdlist;
cmdlist = acutBuildList(RTSTR, _T("_REDRAW"), 0);
acedCmd(cmdlist);
acedCommand(RTNONE);
acutRelRb(cmdlist);
acedCommand():

a) Calling a ZOOM command and pausing for user input:

acedCommand(RTSTR, _T("Zoom"), RTSTR, PAUSE, RTNONE);

b) Creating both a Circle and a Line entities:
acedCommand(RTSTR, _T("circle"), RTSTR, _T("10,10"),RTSTR, PAUSE,
RTSTR, _T("line"), RTSTR, _T("10,10"), RTSTR, _T("20,20"),
RTSTR, _T(""), 0);
System Variables

Your application will probably need to access AutoCAD system variables that can be read or write. ObjectARX provide two functions to deal with these variables using the resbuf structure to access and/or modify values. The function are called acedGetVar() and acedSetVar() and below are their signatures:

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

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

The first parameter is the variable name the second the resbuf pointer to set / get information. The following example show how to change the FILLET radius which is stored through a system variable:
struct resbuf rb, rb1;
acedGetVar(_T("FILLETRAD"), &rb);
rb1.restype = RTREAL;
rb1.resval.rreal = 1.0;
acedSetVar(_T("FILLETRAD"), &rb1);
It is very important that you specify the correct type of resbuf item acquired.
In this case, the FILLET radius is a real number which is RTREAL type.

User Input Functions

There are additional global functions to allow interaction with users via command prompt interface. Each of these functions could be used alone or with other ones. The following table shows what each function does:

acedGetInt

Gets an integer value

acedGetReal

Gets a real value

acedGetDist

Gets a distance

acedGetAngle

Gets an angle (oriented to 0 degrees specified by the ANGBASE)

acedGetOrient

Gets an angle (oriented to 0 degrees at the right)

acedGetPoint

Gets a point

acedGetCorner

Gets the corner of a rectangle

acedGetKword

Gets a keyword

acedGetString

Gets a string


Each of these functions returns a int number as a result code that could be one of the following:

RTNORM

User entered a valid value

RTERROR

The function call failed

RTCAN

User entered ESC

RTNONE

User entered only ENTER

RTREJ

AutoCAD rejected the request as invalid

RTKWORD

User entered a keyword or arbitrary text


AutoCAD allows you to prevent invalid values when user respond to your input functions. This feature can be made through the acedInitGet() function which can receive one or a combination of the following values:

RSG_NONULL

Disallow null input

RSG_NOZERO

Disallow zero values

RSG_NONEG

Disallow negative values

RSG_NOLIM

Do not check drawing limits, even if LIMCHECK is on

RSG_DASH

Use dashed lines when drawing rubber-band line or box

RSG_2D

Ignore Z coordinate of 3D points (acedGetDist() only)

RSG_OTHER

Allow arbitrary input—whatever the user enters


The following example shows how to acquire a value greater than zero:
int age = -1;
acedInitGet(RSG_NONULL RSG_NOZERO RSG_NONEG, NULL);
acedGetInt(_T("How old are you? "), &age);




March Hit Graph