The MicroStation Development Library (MDL) and MicroStationAPI 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.
A MicroStation DGN model's primary purpose is to be a container of graphic elements. A user creates and manipulates elements in on of eight views of a DGN model. When using Item Types to annotate elements, we may want to retrieve instances of our Item Type. By instance we mean a DGN element that has been tagged with an Item Type's properties.
In the topics that follow, I'll show some MicroStationAPI collections. Item Types were introduced with MicroStation CONNECT: there are no previous MDL examples for the MicroStation V8 generation.
Object | Description | Example |
---|---|---|
DgnECInstanceIterable | Get an iterable collection of Item Type instances | Item Type Instances Example |
Get a DgnECInstanceIterable
of Item Type instances from somewhere.
'Somewhere' is defined by the scope for the search, which might be a DGN model for example.
A query (ECQueryPtr
) further refines the search.
In this example the query is simple, and looks for instances having a given
schema-name and class-name.
However, schema-name and class-name must be the internal names of those objects, which the MicroStationAPI documentation omits to mention.
#include <DgnPlatform/DgnECFinders.h>
#include <DgnPlatform/DgnECManager.h>
DgnECManagerR manager = Bentley::DgnPlatform::DgnECManager::GetManager ();
DgnModelRefP modelRef = ISessionMgr::GetActiveDgnModelRefP ();
FindInstancesScopeOption scopeOption (DgnECHostType::Element);
FindInstancesScopePtr scope = FindInstancesScope::Create (*modelRef, scopeOption);
UInt32 instanceCount = 0;
const bool Polymorphic = true;
// see below for an explanation of GetInternalName()
ECQueryPtr query = ECQuery::CreateQuery (GetInternalName (L"schema-name").c_str (), GetInternalName (L"class-name").c_str (), Polymorphic);
Bentley::DgnPlatform::DgnECInstanceIterable
instances = manager.FindInstances (*scope, *query, &instanceCount);
Now we have an object of type DgnECInstanceIterable
.
MicroStationAPI help tells us:
DgnECInstanceIterable
does not "contain" the results, but finds/loads them "on demand" as you iterate.
When you iterate that structure it returns individual DgnECInstance
pointers.
#include <DgnPlatform/DgnECFinders.h> #include <DgnPlatform/DgnECManager.h> Bentley::DgnPlatform::DgnECInstanceIterable instances = // See above for (DgnECInstanceP instance: instances) { // do something with DgnECInstance WString strVal; const bool UseArrayIndex = true; instance->GetValueAsString (strVal, L"property-name", !UseArrayIndex, 0); }
From an EC instance you can find its host element. Like this …
#include <DgnPlatform/DgnECInstance.h>
DgnElementECInstanceCP elemInstance = instance->GetAsElementInstance();
if (elemInstance)
{
ElementHandleCR eh = elemInstance->GetElementHandle();
// do something with ElementHandle
}
When working with EC objects, such as schemas, libraries and Item Types, the name that a user sees is the EC object's display name. As programmers, we must sometimes use the internal name of a class at run-time.
Unfortunately, the MicroStationAPI doesn't tell us when we should use the display name of an object and when we should use the internal name of an object. We have to guess, or post a question to the MicroStation Programming Forum.
For example, our product AreaAnnotator uses an EC schema having display name AreaAnnotator_1_0 and an Item Type having display name Area Feature. The internal names are shown in this table …
Object | Display Name | Internal Name |
---|---|---|
Schema Name | AreaAnnotator_1_0 | DgnCustomItemTypes_AreaAnnotator_1_0 |
Item Type | Area Feature | Area__x0020__Feature |
Some, but not all, EC objects have a GetInternalName()
method.
Here's how to get an EC object's internal name for those that don't provide that method …
#include <ECObjects/ECSchema.h> Bentley::WString GetInternalName (WStringCR name) { WString internalName; ECNameValidation::EncodeToValidName (internalName, name); return internalName; }
Those EC objects that have a GetInternalName()
method at the time of writing (MicroStation CONNECT Update 10)
include …
ItemTypeLibrary
CustomProperty
CustomPropertyType
CustomPropertyContainer
ItemType
IXDataNodeHandler
Item Types are new to MicroStation CONNECT. There is no API from the V8 generation.
Back to the Iterator main page.
Post questions about C++ and the MicroStationAPI to the MicroStation Programming Forum.