Customizing the User Interface When Installing Apps for nanoCAD Plus 8.5

SDK samples_01

For many users, installing an application means just adding a new desktop shortcut or a new toolbar button. This article will describe the way to add menus and toolbars for user applications installed on nanoCAD Plus 8.5, and analyze the procedure for creating a shortcut to launch a user application in the nanoCAD environment.
For those who are more interested in trying rather than in reading a description, I will immediately provide a link to the nanoCAD SDK Samples add-in. After installing this application, each start of nanoCAD Plus 8.5 will automatically load samples created in LISP, C++, С#, VB.NET, JScript, and VBScript, and the user interface will be added with a drop-down menu and a toolbar (as in the main screenshot), allowing you to run sample commands.
As a first step, let us present a ready-made application for installing samples supplied with nanoCAD Pro en 8.5: NCadSDK Samples Application 8.0, and then we will consider how to include the file of menu description and toolbars there.

SDK samples_02

Samples Installer Overview

The samples installer for nanoCAD is a file in the Windows Installer format named SamplesAppEn<version>.msi. After startup, it builds a list of installed nanoCAD versions that are compatible with the installer, inviting your to select the versions where to install the application and those to be excluded from the installation:

SDK samples_03

SDK samples_04

SDK samples_05

Installation folder: C:\Program Files (x86)\Nanosoft\NCadSDK Samples Application 8.0\NCAD80.
The installed application NCadSDK Samples Application 8.0 is already in the startup suite:

SDK samples_06

Check it if it is still unchecked and rerun nanoCAD.
When nanoCAD 8.5 starts, a message about the application being loaded is displayed in the command line:

SDK samples_07

You can run the loaded commands:

• from the command line
• from the drop-down menu installed with the application:

SDK samples_08

• or using the nanoCAD SDK toolbar where some SDK sample commands are added:

SDK samples_09

What is Installed Using the Installer?

For each nanoCAD version selected during installation, the Installer creates a directory including sample files:

SDK samples_10

For 8.0–8.5 platforms, the full set of samples is installed (NCAD80 folder), whereas for the previous versions of the platform, it installs only scripts (JS, VBS) that do not require recompiling for each platform (the folders are named according to the version number: NC70, etc.). This is not a limitation of the application installation technology: if you compile SDK samples of all previous versions, you can create a unique installer to install the full set of samples on all platforms supported.

SDK samples_11

Application Description File (*.package)

SDK samples_12

In addition to application file, the folder with installed samples includes the package file with .package extension, which contains all the necessary information about nanoCAD user configurations (including applications to load and user menus) and allows for loading the selected configuration immediately after launching nanoCAD.
Let us consider the package file to load add-in modules from the set of samples for nanoCAD. The file text has the following XML structure:

<?xml version=”1.0″ encoding=”utf-8″ ?>

Name=“nanoCAD SDK Samples”
AppName=“HelloNRX minimal NRX sample”
AppName=“CrossCircle Object Enabler”
AppName=“CrossCircle Commands”
AppName=“CrossCircle Managed Wrapper”
AppName=“CrossCircle Managed Commands”
AppName=“HelloHost .NET Sample”
AppName=“HelloHost VB.NET Sample”
AppName=“MultiCAD Objects”
AppName=“MultiCAD Symbols”
AppName=“MultiCAD .NET Symbols”
AppName=“MultiCAD .NET CustomObjects”
AppName=“NSF Commands”
AppName=“Tiles LISP Sample”
AppName=“Hello World DCL Sample”
AppName=“ListDialog DCL Sample”
AppName=“MessageBox DCL Sample”
AppName=“SinDialog DCL Sample”

The elements that are used for package description are:
• ApplicationPackage
• Components
• ConfigEntry
• ComponentEntry

The main element ApplicationPackage includes the Name attribute to define the application name that is displayed in the command line after startup.

The Components element describes the package components: the loaded application module – the ComponentEntry elements, as well as the application configuration file with a menu – ConfigEntry.

ComponentEntry includes the following attributes: AppName with the application name, ModuleName with the executable module name, ModuleType with the module type. The following module types are allowed:

• MultiCAD

Command Line Parameters, Creating a Shortcut

NCadSDK Samples Application 8.0 distribution kit adds the application in the startup suite, and it is loaded every time the platform is started. Let’s consider a case when there is no need to automatically load the application, but it should be loaded when launching nanoCAD using a special shortcut on the Windows desktop.

1. Disable add-in startup:

SDK samples_13

2. Create a shortcut for “C:\Program Files (x86)\Nanosoft\nanoCAD Pro en 8.5\nCad.exe” (we assume that we have installed nanoCAD Pro en 8.5 on the C disk, in the Program Files (x86) folder), name it nanoCAD Pro en 8.5 with SDK samples.lnk.

3. Add parameters to the command line:

a. -r — Name of the startup configuration (NCADSamples),
b. -p — Name of the profile (by default, it repeats the name of the startup configuration),
c. -g — path to the loaded application; it may be specified several times.

At the first startup, a profile will be created using the new shortcut, the name of which has been specified in the shortcut command line:

SDK samples_14

Do not confuse the notion of startup configuration and that of the profile:

• The startup configuration includes the information about the main and additional file of user interface (*.cfg) that have been loaded, as well as a link to the current profile. It is designed to create independent configurations (shortcuts) in which applications are run.
• The profile includes the software settings. Various startup configurations can both refer to different, independent profiles and use the same settings, referring to the same profile.


The source code of the nanoCAD sample installer is included in the SDK. If you want to build the installer yourself, you will need the WiX Toolset version 3.8. A sample .cfg file is also included in SDK.

• nanocad
• lisp

MultiCAD.NET API: Inserting blocks with block attributes

In this post we will talk about inserting blocks using MultiCAD.NET API – one of the most frequently asked questions on our forum.

Let us assume there is a drawing that has block definitions for inserting water supply elements, for example, the blocks that represent valves of different types.


Each block definition contains two attributes for providing some extra information about elements.

  • NAME – the element’s name (for example, “Ball”),
  • LABEL – the element’s label (for example, “PC585-70”).

To represent block inserts in the drawing, MiltiCAD.NET provides the McBlockRef class. All you need to do is to create an insert object and assign the name of the block to the BlockName field.

In MultiCAD.NET, block attributes are stored as common object properties. Therefore in order to insert a block with desired attributes values; it takes only getting an access to them using DbEntity.ObjectProperties:

The McDocument class has a method that displays a dialog with a list of all existing block definitions for choosing a block to insert.


The command below inserts the selected block with given attributes values to the drawing. To input values, the command line is used.


Porting C++ applications to nanoCAD: using project property pages


In one of the previous articles we wrote about porting ObjectARX applications to nanoCAD. In this article we will introduce a more comfortable and simple way to do this: using project property pages.

Let us remind that to build an NRX application having an existing ObjectARX application, a new project configuration should be created, from scratch or by copying an existing configuration, and then headers and libraries paths, and conditional compilation constants should be set. The complete procedure is described in the nanoCAD SDK.

In this article we describe the tips that are not in the developer documentation yet. With pre-configured property pages, the minimal number of changes in the project is needed to build the application for both nanoCAD and AutoCAD, and source files, .h, and .cpp files will remain unchanged.

Let’s start with an environment variable that points to the location of the nanoCAD SDK. The variable can be system-wide, or it can be set in the .bat file before starting the Visual Studio 2008.


Since the project is opened in Visual Studio, create a new configuration of the project. Configurations can be created from scratch or copied from an existing one. For example, the Release configuration can be copied to the new Release NCAD configuration.
In order to go without manual configuring the compiler and linker settings, connect the property page from the .vsprops file which already contains all necessary settings. Property pages are added in the Property Manager window (View -> Property manager).

The SDK includes property pages for debug and release configurations:

  • rxsdk_debugcfg.vsprops – properties for the debug configuration of the project;
  • rxsdk_releasecfg.vsprops – configuration properties for the release version of the project;

They are located in the directory <ncadsdk_path>\include\arxgate. In order to ensure the maximum compatibility, the property page and header files in the arxgate directory have the same names as the similar files in the ObjectARX.
After the property page is added to the configuration the inherited settings appear in the project:



That’s all you need to do to port a simple application. The built NRX module is loaded into nanoCAD by the APPLOAD command. To automatically load the application, you can add it to the “Startup Suite”, which is located in the same place, in the APPLOAD command dialog window.


MultiCAD.NET: Calculating the total length of lines


One of the frequently asked questions to our technical support is “How to calculate the sum of line lengths (pipeline sections, elements of wire diagram etc.) in a drawing?” There are many ways to solve this problem, and today we will consider an implementation of the MultiCAD.NET application that sums line lengths in nanoCAD, AutoCAD and ZWCAD. As an example we will calculate the sum of pipe lengths in the water supply scheme with two options to select elements for calculating: user selection and selection by the object filter.

Calculating the length of lines selected by user

Before we set to work, we need to know what a line in MultiCAD.NET is. The line is a standard primitive like circle, text, spline etc. To represent a line within the drawing database, the DbLine class from the Multicad.DatabaseServices.StandardObjects namespace is used.
A DbLine object has properties that store the first and second points of the line but does not contain the length information. Surely, we could calculate the length by the points coordinates, however it is more efficient to access the line’s geometric representation. The geometry data is stored in the LineSeg3d class object that can be accessed through the DbLine.Line property and has the Length property to get the length:

Now let’s consider the first option when the user selects a number of lines for calculating the total length. To provide the user with an ability to select objects the SelectObjects method of the McObjectManager class is used:

The method prompts the user to select entities on the drawing and writes the IDs of selected objects into the array. But we need to make sure the user has selected only entities of desired type. That is why we filter out only IDs that belong to DbLine entities from the set, then get length of each of them and increment the result. Below is the command that implements this procedure:

The same approach works also for polylines that consists of one or more line (or arc) segments. The length of a polyline can be derived similarly to a line by using the geometrical representation class Polyline3d that can be accessed for every DbPolyline object through the Polyline property:

Automatic calculation of the total lines length

When the drawing contains many elements, it makes sense to select object automatically to avoid user input errors. For this purpose an object filter is used. It selects objects that obey the filter criteria: search area (sheets, layers, documents, regions) and object types.
For example, to filter all lines on the specific layer, the filter with specified layer name is used:

In practice automatic line length calculation is applied commonly for creating a report with a list of pipe types on a water supply scheme. Here is the example scheme:


In our example there are two types of water pipes: of PVC and stainless steel. Each type is drawn with lines or polylines on a separate layer: Circuit1 or Circuit2.
The command below creates a text report with listing layer names and total pipe lengths for each of them.

Calculation of the total line lengths and filling up the report are performed in the getLengthSumByLayer() method:

As the result of command execution the following report will be added on the drawing:


The step-by-step guidance of how to load MultiCAD.NET applications you can find in the post MultiCAD Enabler for AutoCAD and ZWCAD.

Smart grips of custom object in MultiCAD.NET


When it comes to creating or modifying objects in a drawing, usability becomes a key characteristic for CAD software.  One of the essential features for efficient manipulating and modifying graphic objects is grips. Grips are markers in the key object points that allow the user to modify an object by mouse and without using the menu or command line.

While embedded CAD primitives are already supplied with grips, custom objects must implement this feature by themselves. The post is intended to describe how to create grips for custom objects using MultiCAD.NET.

The grip management mechanism in MultiCAD.NET permits the user to work with grips of simple and smart types. We have already talked about simple grips in the previous post and in this post will discuss how to work with smart grips. Unlike simple grips, smart grips can have different shapes (circle, triangle, rhombus etc), change specific object parameters, display pop-up menu or perform a set of actions defined in the handler. The smart grips API uses a new unified approach that makes it possible to create simple grips as well.

McSmartGrip class

For representing smart grips in the MultiCAD.NET API the McSmartGrip<T> class is used. This class contains different constructor signatures and handlers of events that are generated by user actions:

  • MoveGrip — used when a grip has been moved,
  • MouseMove — used when a grip of interactive type has been moved,
  • GetContextMenu — used when a grip of the GripType.PopupMenu type has been clicked,
  • OnCommand — used when a grip of the GripType.Button type has been clicked or when a context menu item has been chosen.

For example, to create a simple grip that moves the object, the following constructor can be used:

This constructor takes a MoveGrip delegate as a parameter. In this example we have used a lambda expression ( to implement MoveGrip that just moves the object position by the offset value.

Adding grips

For adding grips to a custom object, the AppendGrip()of the GripPointsInfo class is used:

The GripPointsInfo class is used as the parameter of the GetGripPoints() method which is used for getting grips whenever the object is drawn:

The following code creates and adds the same simple grip:

As you can see the procedure is very compact and requires only one code line. This was the simplest case of grips – simple grips. Let’s see what grip types are supported in the MultiCAD.NET API and discuss specifics of each of them.

Grip types

With MulitiCAD.NET you are able to create grips of the following types:

  • Simple — simple grip. Grip movements are handled in MoveGrip.
  • PopupMenu — grip that displays a popup menu. Handling is performed by OnCommand.
  • Button — grip that represents a button. Actions that can be called by pressing the button are defined in OnCommand.
  • Interactive — the grip type that is similar to Simple, but can be used with object snaps. Unlike Simple grip, Interactive grip uses MouseMove for handling grip movements.

Grip Appearance

One custom object can have grips of different types, in order to distinguish all of them, you can set the specific appearance to each one defining grip shape and color.
Variety of grip shapes are defined by the McBaseGrip.GripAppearance enumeration. Here are some  available shapes:


You can also set the desired grip color from the color set defined in the GripColors class or using standard  System.Drawing.Color.
Let’s look how it works on practice and create several  smart grips of different types for the TextInBox primitive that was described in the previous post.

Simple grip

We have already mentioned this grip type above, and as follows from the name it is used for simple action such as moving points of the object. The code below adds a simple grip for moving a corner point of the entity:

The following picture demonstrates how this grip works:


Button grip

Now we will add a button grip that will control displaying the frame around the text. To create the button, we use the constructor signature that takes the grip type (McBaseGrip.GripType.Button) and the color (GripColors.Base ) of the grip as parameters.  If the button is pressed, the handler OnCommand will change the state of the _show_frame indicator to opposite and the button appearance will be changed from the “On” state to “Off” or vice versa. We will set the “On” appearance by default.

Also a registered command can be called as a reaction to button pressing:


Menu grip

One more grip type that can be created in MultiCAD.NET is a grip for displaying a context menu. This type is used for example, when the user needs to choose a desired value from the list of object parameters. A menu grip can be created by the grip constructor with passing the McBaseGrip.GripType.PopupMenu grip type and the McBaseGrip.GripAppearance.PopupMenu grip appearance as parameters. To enable the menu, the following delegates should be implemented:

  • GetContextMenu — displays the menu if the grip is clicked,
  • OnCommand — handles selecting menu items.

The following code creates a menu grip that enables a context menu with one item:


Interactive grip

And the last grip type in our overview is an interactive grip. The main specific of this grip is that it can use the information about the objects which the grip is snapped to and change its behavior depending on this information.

For example, we will add one interactive grip that can replace the text of our TextInBox primitive with the name of a selected object. Depending on the object type, the grip will change its color: default color will be GripColors.Base, if the grip snaps to the parent object the color will be changed to Color.Red, and if it snaps to any other object that supports snap the color will become Color.Green.

An interactive grip can be created using a grip constructor with passing the McBaseGrip.GripType.Interactive grip type. Handling of grip movement is implemented in the  MouseMove delegate (unlike simple grip, that uses MoveGrip).

Below is the illustration of how this grip works, the «Text field» string is replaced with «MultiCAD.Samples.TextInBox»:


So, we have overviewed the basic types of smart grips, that allow development of an efficient and usable interface for working with custom objects created in MultiCAD.NET. The API documentation set is delivered with the nanoCAD SDK which is available in the nanoCAD Developer’s Club (registration is required).

Managing serialization of custom objects in MultiCAD.NET


In the previous post we discussed the approach used for serializing custom objects in the MultiCAD.NET API. We talked about concepts of using that approach for providing object version compatibility and considered the simplest case when a new version of an object is derived from a previous one by adding additional fields of data. Today we are going to discuss the case of deep changes of the object’s structure such as removing, renaming  or retyping fields.

Assume that a new version of the object has renamed some fields and changed their types. Let’s take, for example, the CrossMark object that is already familiar to us from the previous post:

CrossMark entity

CrossMark entity

The object of the previous version had the following structure:

Let’s assume that  in the new version the corner points are required to be defined by vectors (instead of 3d-points), and the radius field remains unchanged:

Obviously objects of the new version will not be compatible with older objects after such changes.

In order to allow the new version to be able to recognize the older ones, it is required to implement the mechanism for reading desired fields and converting the old data format to the new one. To solve this problem with MultiCAD.NET, the standard ISerializable interface can be used .

The interface allows an object to control its own serialization and deserialization and requires an implementation of two methods:

  • public void GetObjectData(SerializationInfo info, StreamingContext context) — used to serialize the target object,
  • public CrossMark(SerializationInfo info, StreamingContext ctx) — the special constructor used to deserialize values.

In our case the methods should be as follows:


So, now the object has two constructors: one (the default) is used for creating and inserting the object into the drawing, and another – when the object is being read (deserialized) from the drawing.
The deserialization process has been divided into two parts: data from the object of the current version is read regularly, while the data of the previous version is read and converted to the current format inside the catch block for handling SerializationException. This exception will be thrown when the application tries to deserialize the nonexistent fields from the previous version.
If you plan to continue developing new versions of the object, then you can also serialize the version number to a new special field and customize the deserialization process depending on this value:

So we’ve discussed the basic cases of custom object serialization with different types of changes in their structure while moving from one version to another. Using the described approaches, you are able to provide your application with a flexible mechanism for managing objects version compatibility.
Serialization questions are very popular, that is why we will soon continue talking about the implementation of this mechanism in MultiCAD.NET and publish some posts regarding the subject. For example, we will discuss the problem of object data exchange between applications by serializing data to external databases and answer other frequently asked questions.

Serializing objects in MultiCAD.NET. Managing drawings compatibility and proxy objects


Creating custom objects using a traditional C++ API (NRX in NanoCAD and ObjectARX in AutoCAD) presupposes to implement serialization and deserialization processes of each field to allow objects to be writable and readable. The MultiCAD.NET API provides a simple and compact descriptive approach based on the standard .NET serialization that is more usual for .NET developers.

The version tolerance serialization features (VTS) provides developers with a mechanism for managing object versions compatibility which is more flexible than the traditional C++ API approach that allows reading of previous object versions (backward compatibility) but not reading files “from the future” (forward compatibility).

When newer object versions are being defined in MultiCAD.NET, newly created fields can be marked as optional fields so that the drawing saved in a new format version can be read in the previous version also. Of course, the API contains an ability to create proxy objects (cached graphics data of the objects) if the drawing is being loaded to the previous version of the application.

In this post we are going to discuss how to ensure compatibility of two object versions and how to provide the traditional level of compatibility when newer versions of the application can read older drawings but older versions are unable to read new drawings.

Let’s consider how MultiCAD.NET uses both these approaches (VTS and proxy objects mechanism) for providing the versions compatibility features. We will use two versions of the “cross mark” entity for demonstration:


The initial class version

The definition of the CrossMark entity class is listed below:

We are not going to focus on the basics of creating custom objects; it has already been discussed in the previous post. The entire code is available here. After the application is compiled and loaded, it can be launched by the “crossmark” command. The following entity will be added to the drawing:


Save the drawing. Now let’s change the class by adding an extra functionality to it.

The second version of the class and providing versions compatibility

We are going to change the entity’s geometry in the second version by adding a circle at the center of the cross mark. Add a field for the radius of the circle and use the [OptionalField] attribute to mark it as an optional field for correct deserialization of the previous version. Also specify the new version number in the VersionAdded property:

Set the proper value of the radius in the constructor and add a public property for accessing the field:

To initialize the radius field with the custom value after deserialization, the method OnDeserialized with the [OnDeserialized] attribute can be used:

In that way applications that work with new versions of object can also process objects of older versions. Also VTS solves the problem of forward compatibility, i.e. applications that work with old object versions are able to read new versions as well: fields marked as optional are ignored and the object is deserialized properly.
So, we have provided full compatibility between both versions of the CrossMark class. The only thing that should be done is to add a code for drawing the circle component to the OnDraw() method:

The full code of the second version of the application is also available in this archive. Compile the project, load the built assembly to nanoCAD and launch the application by the “crossmark” command. Since you specify the insertion point, the new version of the crossmark entity is drawn at this point:


Save the drawing with a new name.

Testing and results

We have two drawings with two versions of the entity. Let’s make sure that both versions are compatible.
Run nanoCAD, load the second version of the assembly and open the first file. The file is successfully opened and the primitive of the first version is displayed. Once object redrawing is called (for example while you are moving object) the object is redrawn in the new version with the circle component of the proper radius. Object redrawing can also be initialized by the REGENOBJ command.
Close the file. Load the first version of the assembly and open the second file. The file is also successfully opened and the primitive of the second version is displayed as it was originally saved in the drawing (with the circle component). After selecting the REGENOBJ command (or any user actions that cause updating) the cross mark geometry will be updated and displayed as it was defined in the first version.

The traditional approach. Proxy objects

The VTS mechanism, which allows forward compatibility, is not always applicable. For example, when not all data specific for new versions, can be considered as insignificant and you want to prevent changing new objects while opening in an older version of the application.
As mentioned above the class definition contains the [CustomEntity] attribute with a set of properties:

The majorVersion property defines the major version number within which the objects can be compatible. If new objects constructed with a majorVersion value, that is greater than the previous one, are being opened in the older application version, the eMakeMeProxy code is returned. In this case such objects will be displayed as proxy objects That precludes them from changing and being editable.
For example, the second version of the cross mark object should be defined with a majorVersion value equal 2:


In this post we have discussed an example of providing compatibility between two versions of the custom object in the simplest case when the new version is created from the previous one by adding new fields. In one of the future posts we will talk about managing compatibility in the case of deeper changes such as deleting, renaming object fields or changing their types.

MultiCAD Enabler for AutoCAD and ZWCAD


Applications developed with MultiCAD.NET are cross-CAD-platform and can be run in all supported CAD programs without recompiling.  The MultiCAD.NET API is built into nanoCAD and applications are loaded by the standard NETLOAD or APPLOAD commands. To run MultiCAD.NET applications in AutoCAD and ZWCAD the special application called MultiCAD Object Enabler is needed.

In this walkthrough we will load a MultiCAD.NET sample application into nanoCAD, AutoCAD, ZWCAD and edit the drawing created with the application in these three CAD platforms.

Loading a MultiCAD.NET application into nanoCAD

Let’s start with nanoCAD as the native platform for MultiCAD.NET to create the example drawing. You can use free nanoCAD 5.0 or paid nanoCAD Plus 6.0 in Demo mode, both can be downloaded from As the sample application we will use the application that creates TextInBox custom entities described in this post.

  1. Download and unpack the archive to the local drive.
  2. Be sure that the assembly file TextInBoxSample.dll is unblocked after downloading (right click the file -> Properties -> General -> Unblock).
  3. Load the TextInBoxSample.dll  into nanoCAD by the NETLOAD or APPLOAD command.
  4. Create a new drawing.
  5. Run the TextInBox command and create a TextInBox Entity.
  6. Save drawing to the TextInBox.dwg file.


Loading the MultiCAD.NET application into AutoCAD

Now we are going to AutoCAD 2010-2014 (32- or 64-bit) to open and edit the drawing.

  1. Download and unpack the archive with a set of MultiCAD object enablers.
  2. Load ALoader.arx (the enabler application for AutoCAD) from the corresponding subfolder using the AutoCAD APPLOAD command:
    • mg9/mg9x64 (for AutoCAD 2010-2012),
    • mg10/mg10x64 (for AutoCAD 2012-2014).
  3. NETLOAD TextInBoxSample.dll (please note that is the same binary .dll module for all CAD platforms, whether it is nanoCAD, AutoCAD, ZWCAD and it is 32- or 64-bit).
  4. Open drawing TextInBox.dwg.
  5. Select the entity and change its text string in the Properties window.


  6. Move and resize the created entity with grips.
  7. Save the drawing.


Loading the MultiCAD.NET application into ZWCAD

Now we continue editing the drawing in ZWCAD 2014, build 2014.06.25(24082).

  1. APPLOAD ZLoader.arx (the enabler application for ZWCAD) from the mg10 subfolder.
  2. NETLOAD TextInBoxSample.dll.
  3. Open the TextInBox.dwg file.
  4. Run the TextInBox command and create a TextInBox Entity.
  5. Select the new entity and change its text in the Properties window.


  6. Save the drawing.


  7. Now we are back in nanoCAD (this time we will use nanoCAD x64 Plus 6 as the latest nanoCAD version).
  8. Start nanoCAD x64 Plus 6 in the demo mode and NETLOAD the TextInBoxSample.dll.
  9. Open the TextInBox.dwg and edit the entities.
  10. Run the TextInBoxEdit command, select entities and see that texts are updated. Actually the command change texts to “New text”, but for demonstrating we show you entities with other text string:


As you see a MultiCAD.NET application can create a drawing populated with objects which can be opened, edited and saved by all supported CAD programs with providing full set of object functionality.

MultiCAD.NET API: Saving non-graphical data in .dwg drawings


Sooner or later every CAD application developer has to solve the problem of saving auxiliary non-graphical data in .dwg drawings. It can be attributes for a single graphical entity or layout or settings for a whole drawing.  Unlike block attributes, this data is hidden from a user and used for programmatic processing of drawings.

There are a number of ways to solve the problem, for example, adding XData objects to drawing’s entities, using XRecords objects, or creating custom non-graphical objects.

In comparison with the traditional approaches, the mechanism provided by MultiCAD.NET API is much more compact and easy-to-use. It is also unified and can be applied in the same way for different object types in a drawing: entities, layouts or a whole drawing. Using this mechanism you are able to create and save auxiliary information of any data type.

Adding custom properties to graphical objects

You can work with object custom data, using the CustomProperties property. The property is available for all child classes of McPropertySource, particularly, for all graphical entities in a database (which are instances of the McDbEntity class). CustomProperties allows writing and reading data as key-value pairs:

Data of a simple type or array of simple types can be used as a property value. However, in practice, you can add values of any type by serializing data to an array of bytes. The code below shows the example of writing a dictionary object as a value of the MyCustomProperty property:

Reading of “complex” data is also divided in two steps: reading a byte array and its subsequent deserialization. Note, that CustomProperties gets array as a List object:

Let’s look at how the method works for a real case. Assume that there is a .dwg-file with a power supply scheme where hot and cold water pipes are represented by polylines. We are going to add a description for lines selected by a user. The description contains the information about pipe type and its diameter:

[Pipe type] = Cold Water
[Pipe diameter] = 20

Create a command that allows the user to select a polyline and then adds the key-value pairs to the selected one:

For all McPropertySource descendant classes you can also get properties of specific type (Custom, Object, User etc.) by using the GetProperties() method. The following command gets a complete list of custom properties for user selected entity and prints their names:

Adding non-graphical data to a document

The MultiCAD.NET API allows saving non-graphical data not only for entities, but also for the entire document, layouts and blocks (subdocuments). The McDocument class inherits the functionality of the base McPropertySource class and therefore you can use the same CustomProperties property to add your custom data to documents of different levels:

Let’s look at how it works. In one of the previous posts we talked about creating custom entities in MultiCAD.NET and dealt with the TextInBox entity that is a framed text string:

Applying custom properties to a document object, you can define its additional parameters and settings. For example, you can add properties that set colors of a frame and text string for all TextInBox entities present in the current drawing:

Overwrite the OnDraw() method from the example that is responsible for drawing an entity so that the element’s color is derived from the document custom properties:

Now all added TextInBox entities are drawn in compliance with the document’s properties.

Importing coordinates from a text file to a nanoCAD drawing using the MultiCAD.NET API


In the previous post we talked about importing point coordinates from an external text file into a .dwg drawing using classic .NET API. This post is going to describe how easy this problem can be solved using the cross-platform MultiCAD API. Here you will find the specifics of building MultiCAD application and the simple steps to launch it in nanoCAD and AutoCAD without changing project settings and rebuilding.

Creating working project

The project should be created in MS Visual Studio in the same way as it was done for the previous example:

  • Project type: Visual C#
  • Template: Class Library

To set up the project you only need to add a reference to the mapimgd.dll library that is included in the nanoCAD SDK (starting from version 4.0). The project configuration remains the same for applications that run in nanoCAD as well as in other supported CAD programs, particularly in AutoCAD. This compares to the previous project that contains two configurations — Debug NCAD and Debug ACAD. This project will use the only Debug MultiCAD configuration for all cases.

Importing coordinates and adding point entities to the drawing’s database

The structure and common code for creating application form, preview organization, and importing text data from a file remains the same. Implementation of the Importer and Creator classes was dependent on the specific host program, so they will be rewritten to be platform-independent. For example, the Creator.createPoints() method, which creates point entities by the input array of coordinates, will look as follows:

Let’s recall how the point creating procedure looks in the previous example using classic .NET API:

You can see that the number of code lines required for implementing this method has been decreased significantly. With MultiCAD.NET creating point objects, setting their coordinates and adding them to the database requires only three code lines! This is an extra advantage in addition to cross-platform support, using the API you can make application code more compact. This is carried out by “embedding” auxiliary operations into the main functionality.

Let’s look briefly at point adding procedure (a full overview will be the subject of future posts). There are three levels of geometry for entities in the MultiCAD.NET API:

  1. level of clear “math” geometry,
  2. level of geometry with primitives properties: color, linetype, lineweight etc. and
  3. level of database object.

Here we have created a DbPoint object, set its position and used the DbEntity property to move to the database level and add the point entity to the drawing’s database. Note, there is no need to determine which working space is current, the AddToCurrentDocument() method automatically finds the active document and adds an entity to currently used space.

Loading application to nanoCAD and AutoCAD

After the code is built and an application .NET assembly is generated you can load it and run in the supported CAD-programs.

  • Loading applications to nanoCAD is performed by the standard NETLOAD and APPLOAD commands.
  • To load applications to other systems, the special application called Object Enabler should be used. For example, to load an application to AutoCAD, MultiCAD Enabler for AutoCAD should be loaded first, and then use the NETLOAD command for loading your application. This standard MultiCAD Enabler for AutoCAD can be downloaded from the nanoCAD Developers’ Club.

Source code of the project is available here.