MicroStation and Application Development

MicroStation® is a computer-aided-design (CAD) tool produced by Bentley Systems. It is used by engineers, architects, and draughting technicians to create 3D models and 2D drawings.

MicroStation can be customised. Bentley Systems themselves have many applications for specialised markets that use MicroStation as a platform. Third-parties likewise may use MicroStation as a platform on which to develop their application software. Bentley Systems provide the MicroStation Software Development Kit (SDK) that software developers use to create their applications.

The SDK has two libraries: the MicroStation Development Library (MDL) and the MicroStationAPI. The MicroStation Development Library contains thousands of functions that provide a C-language interface. The MicroStationAPI provides an object-oriented C++ interface.

While MDL has been available since 1993, the MicroStationAPI is relatively recent and ill-understood by developers. This article attempts to clarify and explain the MicroStationAPI from a developer's viewpoint. In particular, it provides a set of commented source files that will build to a working example. The entire source code for the project is available to download.

Modify Element Tool

The MicroStationAPI provides classes from which we derive our own specialist classes. In this example we inherit from Bentley::Ustn::MstnElementSetTool (subsequently we drop the namespace, and refer to simply MstnElementSetTool). The example code has the following classes that inherit from MstnElementSetTool …

Modify Element Tool Classes
Class Purpose
PickTool Prompts user to pick any element
FenceTool Operates on elements in a fence
SelectionTool Operates on elements in a selection set

In each case, the tool changes the symbology of each valid element to the active settings. This makes it easy to see the result of applying each tool.

The Modify Example Tool classes borrow from the toolExample delivered with the MicroStation V8i SDK. We have added extra code that demonstrates more features of the MicroStationAPI, and removed some irrelevant code that had leaked in from another Bentley example.

The MicroStationAPI documentation is terse, formal, and not instructive. We are indebted to Bentley staffers Brien Bastings and Mark Anderson for their help and suggestions. They are particularly active in the Be Communities Forums. Without their encouragement and help in interpreting the MicroStationAPI documentation, this project would not exist.

Modify Example Tool Commands

Load the Modify Example Tool using the MicroStation keyin …

mdl load ModifyExample

Once loaded, the following commands become available …

Modify Example Tool Commands
Command Purpose
MODIFYEXAMPLE MODIFY ANYTHING PICK Prompts user to pick any element for modification
MODIFYEXAMPLE MODIFY LINE PICK Prompts user to pick a line or line-string element for modification
MODIFYEXAMPLE MODIFY ANYTHING FENCE Works only if a fence is active. Modifies any element in the fence
MODIFYEXAMPLE MODIFY LINE FENCE Works only if a fence is active. Modifies any line or line-string element in the fence
MODIFYEXAMPLE MODIFY ANYTHING SELECTION Works only if a selection set is active. Modifies any element in the set
MODIFYEXAMPLE MODIFY LINE SELECTION Works only if a selection set is active. Modifies any line or line-string element in the set

The FENCE and SELECTION commands are deliberately constrained. They show how precise your tools may be. The FENCE tool will not load if a fence is not defined. The SELECTION tool will not load if a selection set is not active.

The PICK command is more like a general-purpose locate command that you would have written using MDL's state functions. It populates the Tool Settings dialog when started …

Modify Example Pick Tool Settings

However, in addition to the locate function, the PICK command also reacts to an active selection set or a fence. As the Tool Settings dialog shows, you can choose to use or ignore an active fence. The MstnElementSetTool base class is responsible for building an element list (MicroStationAPI ElementAgenda). The source of the ElementAgenda can be a user locate (Pick in MicroStationAPI terminology), selection set, or fence.

MstnElementSetTool subsequently operates on the elements in the agenda, calling OnElementModify for each member.

Modify Example Tool Features

The Modify Example Tool provides several tools. The main entry point (MdlMain in ModifyTool.cpp) does the usual things required to initialise a MicroStation add-in …

When each command is instantiated, its command message ID and prompt message ID are passed to the constructor, which passes them on to the base class MstnElementSetTool. This ensures that the user sees (i) your prompts when a command is started (e.g. Modify Line>Identify line) and (ii) the command name in MicroStation's menu Edit|Undo and Edit|Redo.

Filtering Elements

The FenceTool, PickTool, and SelectionTool classes work on any graphic element. Inherited method OnPostLocate is key: you must fill out this method with your code that dermines whether an element is valid for this tool. For the classes named above, this method returns true to accept any element.

The FenceLineTool, PickLineTool, and SelectionLineTool specialist classes work only on line or line-string elements. Inherited method OnPostLocate is key: it returns the value returned by our virtual method Acceptable. In our base class, Acceptable returns true to accept any element type. In your derived class, you decide what type of element is acceptable. In this example, we're interested only in line and line-string elements. Here's the code …

bool			PickLineTool::Acceptable	(ElemHandleCR		eh,
        									char*				reason  /* may be NULL */)	const
{
	const int 		elemType	= eh.GetElementType ();
	const bool		accepted	((LINE_ELM == elemType) || (LINE_STRING_ELM == elemType));
	if (!accepted && NULL != reason)
	{
		char		prompt		[64];
		mdlResource_loadFromStringList (prompt, NULL, MESSAGELISTID_Prompts, PROMPT_NotLine);
		strcat (reason, prompt);
	}
	return accepted;
}

Acceptable tests the element type and returns true if it is valid for this tool. In this example, a LINE_ELM or LINE_STRING_ELM is acceptable. If the proposed element is unacceptable, the method appends a message that is displayed in MicroStation if the user hovers the mouse over the element. The balloon contains text that you define; in this example 'Not a line element'.

Modifying Elements

Overridden method OnElementModify does the work. Or at least, it does some preliminary work: the real work in modifying elements is done deep inside the MstnElementSetTool and its base classes, which we can't see.

StatusInt FenceTool::OnElementModify (EditElemHandleR eeh)

We're given a non-const reference to an EditElemHandle. We can extract an element pointer from this handle, modify it, and update the handler if required. If we return SUCCESS from OnElementModify then MicroStation updates the element(s) for us. This elegant object-oriented approach simplies our lives as programmers enormously, especially when compared to the hoops we have to jump through using MDL.

Other Callbacks

MstnElementSetTool has a long list of callbacks. What is not clear from their documentation is who calls those methods. Do we call them from our code, or do we overload them in our inherited class to await a call from MicroStation? This article & project explain and illustrate how a few of those methods are used. However, there are many more methods whose purpose is not clear.

Building the Modify Example Tool

We assume that you are using the MicroStation development environment to build this project. Consult the MicroStation Software Development Kit (SDK) help for more information, or take a look at our guide to setting up Windows to build MicroStation applications.

As this is a C++ project, you'll need Visual Studio installed. The project builds from a Bentley make (bmake) file, so the purpose of Visual Studio is to provide a compiler and linker rather than an IDE.

As with any application built for native code, the result is in two parts: ModifyExample.ma and ModifyExample.dll. File ModifyExample.ma contains only resource data: in this case, the information MicroStation requires to load the DLL, a command table, and a command resource list (CmdItemListRsc in ModifyExampleDlg.r) to populate MicroStation's Tool Settings dialog. ModifyExample.dll is the implementation file. When a user types mdl load ModifyExample MicroStation first loads ModifyExample.ma and finds the resource directive (the DllMdlApp in ModifyExample.r) that instructs it to load a DLL, then it loads ModifyExample.dll.

Download the Modify Example Tool Project

Download Modify Example Tool

Download the ModifyTool project. This ZIP file contains C++ source code header and implementation files, and a bmake (.mke) file to build the project. You need Visual Studio 2005 to be installed in order to compile this project.