Introduction to MicroStation

MicroStation® is a 3D computer-aided-design (CAD) application for personal computers and workstations. MicroStation is produced by Bentley Systems, Inc.

MicroStation can be customised in various ways. This article shows how to find MicroStation Line Styles with MicroStation Visual Basic for Applications (MVBA).

MicroStation's standard Line Style menu

Line Style Support in VBA

MicroStation VBA has some support for line styles, but MDL provides more. For example, the DesignFile.LineStyles method obtains a list of line style names available to the specified DGN file. However, it doesn't tell you where that line style definition is located. There are three possible sources where a line style definition could be stored …

  1. In the active DGN file (VBA ActiveDesignFile)
  2. In an attached design library (DGNLib)
  3. In a line style resource (*.lin) file

MDL StringList

An MDL StringList is, as you probably guessed, a list of strings. However, they are stored in a C-style structure, are allocated dynamically and are accessed by C-style pointers. Consequently, they are not easy to handle from VBA.

We've written a VBA class that hides the details of the MDL functions that handle a StringList.

Line Style Support in MDL

MDL function mdlLineStyle_nameGetStringList lets you specify the source of the StringList it returns. It will find all line styles, or those in the active design file or those in visible DGNLibs. However, it doesn't find line styles in a line style resource (*.lin) file.

To find line styles in a line style resource file (*.lin) we need another MDL function, mdlLineStyle_getLinNames. That function take the name of a line style resource (*.lin) file and returns a StringList of lines found in that file. It doesn't look in the active design file, nor in any DGNLib.

Using MDL Functions from VBA

Not all MicroStation functionality is available directly through VBA. MicroStation's line styles fall partially into that list of omissions. Fortunately, for these uncommon cases, we can fall back on the MicroStation Development Library (MDL). MDL is a C/C++ API, but VBA can use its functions provided the appropriate declarations are made in your VBA modules.

In this case we need to declare the MDL functions that handle StringLists. Once we've declared a function, we can use it in our VBA code. Here's the VBA declaration for mdlLineStyle_nameGetStringList, taken from the MDL function reference help documentation …

Declare Function mdlLineStyle_nameGetStringList Lib "stdmdlbltin.dll" ( _
    ByVal pAuxInfo As LongPtr, _
    ByVal options As Long) As LongPtr ' Returns StringList *

The function declaration should be copied to your VBA code module. It should be placed near the top of the module, before any VBA procedure definition.

We enumerate the StringList and find the line style name from each member of that list. To achieve that we use MDL function mdlStringList_getMember in a For..Next loop.

mdlStringList_getMember

MDL function mdlStringList_getMember is tricky to use from VBA. Here's the MDL function declaration …

long               mdlStringList_getMember
(
char**             ppString,
long**             ppInfoFields,
StringList const*  pStringList,
long               memberIndex
);

The problem is caused by the first argument, which is the address of a C-style pointer. If the function returns successfully, ppString points to the start of the internal text buffer. Here's the VBA function declaration …

Declare Function mdlStringList_getMember Lib "stdmdlbltin.dll" ( _
        ByRef pString As LongPtr, _
        ByRef pInfo As LongPtr, _
        ByVal list As LongPtr, _
        ByVal n As Long) As Long

Because VBA doesn't do pointers, we declare each pointer as a VBA Long to accommodate the 64-bit unsigned integer value of the C-style pointer. Furthermore, by pass that argument ByRef so that the C function receives the address of our simulated pointer. Call the function like this …

Dim pString As LongPtr
Dim n As Long
Dim list As LongPtr
... get list from somewhere
mdlStringList_getMember pString, 0, list, n

Now VBA variable pString points at the text buffer in the StringList. I could not figure out how to copy the text from the buffer into a VBA String variable. Luckily, Artur Goldsweer, a Bentley Systems staff member in Germany, came to my rescue on the MicroStation Programming Forum. Artur proposed this Win32 function that correctly allocates memory and copies a C-style string to a VBA String variable …

Declare Function SysAllocString Lib "oleaut32" (ByVal CharPtr As LongPtr) As String

Now it's simple to copy text from that mdlStringList_getMember pointer …

Dim pString As LongPtr
Dim n As Long
Dim list As LongPtr
... get list from somewhere
mdlStringList_getMember pString, 0, list, n
Dim s As String
s = SysAllocString (pString) ' Bingo!

Line Style VBA Project

We've created a project that demonstrates the functionality available through MDL to VBA developers. Because the MDL StringList is not compatible with VBA semantics, we're wrapped it in a VBA class. Class clsLineStyleList provides a simple interface …

VBA Class clsLineStyleList
Method Argument Comment
TraceStyleNames Writes a list of line style names to the Immediate window
StyleExists String style name Returns True if the named line style exists in the current list
LineStyleCount Returns Long size of the current line style list
LineStyleByIndex Long index Returns String name of line style at specified index in list
GetResourceLineStyles String fileName Loads line style list from a named resource (*.lin) file
GetDgnLibLineStyles Loads line style list from visible DGNLibs
GetActiveDgnLineStyles Loads line style list from active DGN file
GetAllLineStyles Loads line style list from both active DGN file and DGNLibs
CountLineStylesInDGNLibs Returns Long no. of names in DGNLib
CountLineStylesInActiveDGN Returns Long no. of names in active DGN file

The VBA project's Main procedure creates an instance of class clsLineStyleList and exercises its interface. Depending on your configuration of MicroStation, some of those tests may work and some may fail. Your mileage will vary.

Download VBA Line Style Project

Download Line Style ZIP

The above code is available in this MicroStation VBA project. Unpack the ZIP archive and copy LineStyles.mvba to a location where MicroStation can find it. A good place to copy it would be \Workspace\Standards\vba. To start enumerating line styles, enter the following into MicroStation's keyin dialog …

vba run [LineStyles]modMain.Main