Thursday, February 10, 2005

Class 3 - Application Overview

Introduction

As I mentioned before, the ObjectARX is actually a DLL. It can be linked with or without MFC extensions. Most of times you would like to link with MFC. Autodesk provides a pretty handy Wizard to allow users to quickly create ObjectARX applications with minimun code effort.

Before we can proceed I would like to clarify the main differences between ObjectARX and ObjectDBX applications. The main idea is to separate Interface and Object Classes to allow the called "Object Enablers". This is not a mandatory but it is a good programming practice and Autodesk made this separation to provide great things like, for instance, open an ADT drawing inside AutoCAD, download the proper enabler and then show those ADT entities correctly inside AutoCAD.

Suppose you need to create an application with a bunch of custom entities and objects. The drawings created with this application will contain these custom objects and if another users try to open this drawing inside AutoCAD and without your applications they will see only Proxy entities. If you would like to allow these users to see your custom entities but don't perform any commands over them you just need to ship de DBX part of your application. This way the user will be able to see your custom entities and perform some limited operations.

When the drawing is saved AutoCAD preserve the custom entity information using the called Proxy entities. This will happen even if the DBX module is not available. The Proxy entities stores the binary data of your custom object and keep that until your application come back.
In other hand, the ARX module of your application will be responsible for the interface. There you should register your commands, create your dialogs, customize menus, etc.

Application Structure

Both ARX and DBX modules must implement an entry point function. This function is responsible to perform messages exchange between AutoCAD and your application. For those who are familiar with old C language it is the substitute of main() function.
This entry point function has a signature as follow:

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

A simple implementation of this function is:

extern "C" AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
switch(msg) {
case AcRx::kInitAppMsg:
break;
case AcRx::kUnloadAppMsg:
break;
default:
break;
}

return AcRx::kRetOK;

}

This function is automatically implemented by the Wizard as you will see later. The first parameter (msg) is the message sent from AutoCAD to your application telling you what is happening. You may receive a "new drawing" message, a "init application" message among many others. These messages are very important to your application and to allow you to react to each desired event to monitor. The second parameter (pkt) is a data package that can be useful in some situations that I would avoid to discuss now (remember, our course is for Dummies). This function must return a value to AutoCAD using AppRetCode which can be kRetOK (common value) or even kRetError which will force AutoCAD to unload your application.

The most relevant point here is to remember that this function is very important and is where your application will begin to execute.

Registering Commands

Probably your application will implement several commands. You can register your commands from the acrxEntryPoint() function when receiving the kInitAppMsg message that represents the event fired by AutoCAD when it loads your application (this can be done by several ways that we will discuss later). Once this message is received, you can call the appropriate methods to register each desired command.

Registered commands must have a Group Name, a Global Name, a Local Name, some flags, a void function pointer and, optionally, some other parameters. Basically the registered command will fire the function you specified. This function must be a void function without any parameters. When the user inside AutoCAD call your command, AutoCAD seek its command stack, find your command and fire your function. That's it!

It is very important that you preceed your commands with a 3 or 4 letters prefix to avoid command colision with other third-party applications. Regarding to the main parameters:
  • Group Name: Allows you to group your common commands to make easier to unload and manage them;
  • Global Name: Your command untranslated name. You should use english names here that is the most used language;
  • Local Name: Your localized command name which represents the translated name;
  • Flags: Can be a combination of several types. The two most important flags are ACRX_CMD_TRANSPARENT and ACRX_CMD_MODAL. They establishes your command behavior that can be transparent (like ZOOM) or modal (like major commands);
  • void function pointer: Here you pass the name of the void function you would like to link with the command. This function will be fired by AutoCAD when the command is invoked.

Once you register your commands you need obviously to unregister when leaving AutoCAD or when your application is unloaded. This can be easily done unregistering all commands by the Group Name. When you recieve the kUnloadAppMsg message is time to remove your commands.

Running your application

Supposing you already compiled your application successfully it is time to load it inside AutoCAD and test your commands. My preferable method to load / unload ObjectARX applications is through the APPLOAD command. It opens a very handy dialog that allows you to browse for the application and load it. It comes also with a Startup Suite briefcase that allows you to automatically load a list of applications when AutoCAD starts.

Once your application is loaded, just fire your commands and enjoy!

I have posted a simple application made by ARXWizard and Visual Studio.NET 2002 (7.0) and ObjectARX 2004. It is called SimpleLine and it was posted to our file sharing web site as mentioned before. I would like you to download it and pay attention to the code that we have discussed on Class 2. See that I have mapped a command to a function and inside this function the routing to create a line is performed. Go ahead, give a try! Compile this code and open the result ARX file inside AutoCAD.

Next class I will show how to build this application from scratch using the ARXWizard.
Stay tuned!

15 comments :

Anonymous said...

_________@@@@@@@@_____
_____@@@@@@____________
___@@@@@@______________
__@@@@@@@_____________
___@@@@@@______________
_____@@@@@@____________
_________@@@@@@@@_____
___________________________
______@@@@@@@@@_______
__@@@@@_______@@@@@__
_@@@@@_________@@@@@_
_@@@@@_________@@@@@_
_@@@@@_________@@@@@_
__@@@@@_______@@@@@__
______@@@@@@@@@_______
___________________________
______@@@@@@@@@_______
__@@@@@_______@@@@@__
_@@@@@_________@@@@@_
_@@@@@_________@@@@@_
_@@@@@_________@@@@@_
__@@@@@_______@@@@@__
______@@@@@@@@@_______
___________________________
__@@@@@@________________
__@@@@@@________________
__@@@@@@________________
__@@@@@@________________
__@@@@@@________________
__@@@@@@@@@@@@@@___
__@@@@@@@@@@@@@@___
__@@@@@@@@@@@@@@___
________________________

Anonymous said...

Where can I download the complete course and sample files. email me at faghree@dmp.co.za

Anonymous said...

a small typo:


"Regaring to the main parameters:" should be: regarding to ....?

Fernando Malard said...

Thank you, already fixed.

Anonymous said...

Hi, very nice blog you got! Im gonna make a application in ObjectDBX/RealDWG that dont needs Autocad to read/write titleblocks and attributes. And wondering if I code a ObjectArx application, can I use much of the same code in RealDWG?

Fernando Malard said...

Hi,

The ObjectDBX portion of AutoCAD is supposed to be 100% compatible with other ObjectDBX based applications.

There are some issues related with custom objects and object enablers.

ObjectDBX can't use any interaction with the interface because it is host independent. So your routine will need to run inside DBX module and I don't know how will you fire the command.

The ARXWizard itself limits the creation of certain elements inside a DBX project.

Take a look at ObjectDBX documentation to know more about these limitations.

Regards,
Fernando.

Anonymous said...

just to mention a small typo
"The drawings created with this application will contains" it should be "The drawings created with this application will contain".

Fernando Malard said...

Thank you. Fixed.

Anonymous said...

Hi,

Where can I download the complete course and sample files? Pls. email me at rultz_25@yahoo.com.ph

Thank you and more power!


Ruel

Fernando Malard said...

Ruel,

You can download from here:

http://files.ofcdesk.com/ThirdParty/

Regards,

Anonymous said...

cannt download:( 404

Fernando Malard said...

Hi drew.oz,

The website I have used to host the files have changed. I'm trying to find another free and reliable file host service.

Sorry about the inconvenience.

Regards.

Fernando Malard said...

Hi,

Files were moved to Google docs:

https://docs.google.com/leaf?id=0By7BVn8vCBxnYjZjNWJhZjYtZjE3MC00ZjdiLTlmMjMtNTVhNTNjNjE0YjUy&hl=en

Sorry about the inconvenience.
Regards.

Unknown said...

Mr. Malard,

I was wondering if you have any idea what would cause an arx to load successfully, but when it calls the load function for the associated dbx autocad just closes without warning or information?

I'm Using:
AutoCAD MEP 2022
Visual Studio 2019
Custom Derived Entity
Windows 10

Any suggestions would be greatly appreciated.

Thanks,
Wayne

Fernando Malard said...

Hi Wayne,

I would test a couple of things:

- Try to load the DBX module itself, if it loads the problem probably isn't there
- If it fails to load, debug the loading process by putting some breakpoints at the acrxEntryPoint() main method and the application class construction
- Next, if the DBX loads ok and the crash is only when calling a specific class, try to create simple exported global functions and call them
- Then, if it works, try a custom DBX object class, instantiate it and see what happens

Hope it helps.