The C++ MicroStationAPI and its predecessor the MicroStation Development Library (MDL) provide APIs for developers wanting to create custom applications for MicroStation® from Bentley Systems. We create a MicroStation application as a DLL, written using C++ and built with the Microsoft C++ compiler and linker provided with Visual Studio.
When editing your source code, you can choose whether to use Microsoft Visual Studio, Microsoft Visual Studio Code, or one of your favourite text editors.
When building your app, you can use Visual Studio or the Bentley Systems make (bmake) tools.
MicroStation is a 3D CAD tool. Users draw 3D or 2D objects in one of eight views. Drawn objects are termed elements. A graphic element represents something that a user can draw, such as a line, arc, rectangle or cone. Elements are persisted in a DGN model, which is part of a DGN file.
Developers who write applications for MicroStation one of several APIs …
This article is for developers who use the C++ MicroStationAPI.
A DGN element, as you probably know, has a set of properties. Those include generic properties, such as colour and level, that may belong to any graphic element. They additionally include properties that apply only to certain types of element. For example, a line element has a length property; an ellipse element has major and minor radius properties.
Here, we're looking at MicroStation's ECSchemas and how you can query an element's DGN properties using the ECSchema API, which is a sub-set of the MicroStationAPI. The MicroStationAPI is delivered with the MicroStation SDK, which you can obtain via the Bentley Developer Network (BDN).
ECSchemas have been a part of MicroStation since MicroStation V8i. With MicroStation CONNECT they assume greater importance. At the same time they have become more versatile.
Class DgnECTypeAdapter
converts underlying DGN element property values
to user-oriented data.
Because the MicroStation built-in schemas inform unit conversion,
that class and its companion, DgnECTypeAdapterContext
, calculates the value
that the user expects to see.
For example, an area is displayed as 423m² rather than 423000000 UORs squared.
Here's a code snippet extracted from the ElementProps
project.
This is slightly modified from an example posted on Be Communities by
Bentley Systems staffer
Yongan Foo
…
void GetElementProperties (ElementHandleCR eh) { DgnECManagerR ecMgr = DgnECManager::GetManager (); FindInstancesScopePtr scope = FindInstancesScope::CreateScope (eh, FindInstancesScopeOption(DgnECHostType::Element)); ECQueryPtr ecQuery = ECQuery::CreateQuery (ECQUERY_PROCESS_SearchAllClasses); //ECQUERY_PROCESS_SearchAllExtrinsic will only search ECXAttr ecQuery->SetSelectProperties (true); for (DgnECInstancePtr instance: ecMgr.FindInstances (*scope, *ecQuery)) { DgnElementECInstanceP elemInst = instance->GetAsElementInstance(); WPrintfString outStr(L"--------- className = %s, instanceId = %s ---------------", elemInst->GetClass().GetName().GetWCharCP(), elemInst->GetInstanceId().GetWCharCP()); mdlOutput_messageCenter (DgnPlatform::OutputMessagePriority::Debug, outStr.c_str (), outStr.c_str (), DgnPlatform::OutputMessageAlert::None); for (ECPropertyP ecProp : elemInst->GetClass().GetProperties()) { WString wStr; ECValue ecVal; elemInst->GetValue(ecVal, ecProp->GetName().GetWCharCP()); IDgnECTypeAdapterR typeAdapter = IDgnECTypeAdapter::GetForProperty(*ecProp); IDgnECTypeAdapterContextPtr typeContext = IDgnECTypeAdapterContext::Create(*ecProp, *elemInst, ecProp->GetName().GetWCharCP()); typeAdapter.ConvertToString(wStr, ecVal, *typeContext); WPrintfString outStr2(L"\t%s[%s] = %s", ecProp->GetDisplayLabel().GetWCharCP(), ecProp->GetTypeName().GetWCharCP(), wStr.GetWCharCP()); mdlOutput_messageCenter (DgnPlatform::OutputMessagePriority::Debug, outStr2.c_str (), outStr2.c_str (), DgnPlatform::OutputMessageAlert::None); } } }
When that code is called, MicroStation's Message Center shows something like this (many lines omitted) …
Circle Element properties... End Point[point3d] = -24.022m, 11.598m Start Point[point3d] = -24.022m, 11.598m Axis Ratio[double] = 1.00000 Secondary Vector[point3d] = 0.000m, 1.732m Primary Vector[point3d] = 1.732m, 0.000m Center[point3d] = -25.755m, 11.598m Primary Axis[double] = 1.732m Perimeter[double] = 10.884m Area[double] = 9.428 Sq.m Angle[double] = 0.000° Range High[point3d] = -24.022m, 13.330m Range Low[point3d] = -27.487m, 9.865m Class[int] = Primary Line Style[int] = ByLevel (0) Weight[int] = ByLevel (0) Color[int] = ByLevel (0) Type[string] = Ellipse Size[int] = 72 Last Modified[dateTime] = 7/31/2018 4:30:00 PM Model[string] = 2D Metric Design Element ID[long] = 910 Element Description[string] = Circle --------- className = EllipseElement, instanceId = :ECDB00000000:158E030000 --------------- Circle, Level: Default
The above extract shows the element properties of an unadorned DGN ellipse (circle) element.
The next listing is the same code applied to a shape element having Item Type properties attached.
In this example the properties are the DGN element properties, plus those of
AreaAnnotator.
The listing shows the Area Feature's ECSchema internal name, which is Area__x0020__Feature
…
Shape Element properties... altAreaFormatted[string] = 7.18yd² altPerimFormatted[string] = 10.94yd perimFormatted[string] = 10.000m areaFormatted[string] = 6.000m² ID[string] = Room 302 areaType[string] = Enclosure purpose[string] = Office --------- className = Area__x0020__Feature, instanceId = :56FF00000001:1547020000 --------------- Perimeter[double] = 10.000m Area[double] = 6.000 Sq.m Area[double] = 6.000 Sq.m Total Length[double] = 10.000m Count[int] = 4 Range High[point3d] = 2.893m, 7.333m Range Low[point3d] = -0.107m, 5.333m Display Style[int] = (From View Display) Complex[boolean] = Not Complex Filled[boolean] = Not Filled Line Style[int] = ByLevel (0) Weight[int] = 2 Color[int] = ByLevel (1) Type[string] = Shape Property List[string] = XAttributes[int] = 1 Size[int] = 96 Last Modified[dateTime] = 6/8/2017 10:55:23 AM Model[string] = 2D Metric Design Element ID[long] = 583 Level[int] = Areas 2 --------- className = ShapeElement, instanceId = :ECDB00000000:1547020000 --------------- Shape, Level: Areas 2
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: ElementProps.ma
and ElementProps.dll
.
File ElementProps.ma
contains only resource data: in this case, the information MicroStation requires to load the DLL,
and a command table. ElementProps.dll
is the implementation file.
When a user types mdl load ElementProps
MicroStation first loads ElementProps.ma
and finds the resource directive (the DllMdlApp
in ElementPropsCmd.r
) that instructs it to load a DLL,
then it loads ElementProps.dll
.
Download the ElementProps 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 2015 to be installed in order to compile this project
for MicroStation CONNECT.
Post questions about C++ and the MicroStationAPI to the MicroStation Programming Forum.