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 set a MicroStation Snap Mode with MicroStation Visual Basic for Applications (MVBA).
MicroStation's Snap Mode enable you to draw some graphic object by snapping to another object. For example, you may want to snap the start point of one line to the mid-point of another line. Setting the Snap Mode (or snap lock) to mid-point enables that action.
Not all MicroStation functionality is available directly through VBA. MicroStation's Snap Mode setting falls 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 function mdlParams_setLock
.
Once we've declared a function, we can use it in our VBA code.
Here's the VBA declaration for mdlParams_setLock
,
taken from the MDL function reference help documentation …
Declare PtrSafe Function mdlParams_setLock Lib "stdmdlbltin.dll" ( _ ByRef lockVal As Long , _ ByVal paramName As Long ) As Long
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.
Note: The MDL documentation tells us to pass the first parameter ByVal
.
This is incorrect: use the ByRef
keyword as shown above.
Thanks go to the developers of PHOCAD and eagle eye technologies for pointing that out.
We need to define a number of integer constants that are used by that MDL function. I haven't simply invented these values — they are taken from a couple of the MDL header files. MDL header files are installed with the MicroStation SDK. If you haven't installed that SDK the header files won't be available on your computer. That should not be a problem because I've translated the definitions from MDL to VBA.
The name of the lock setting is ACTIVEPARAM_SNAPMODE, defined like this …
' ACTIVEPARAM_SNAPMODE is defined in MDL header file <mdl.h>
Public Const ACTIVEPARAM_SNAPMODE As Long = 501
That lock setting takes one of a combination of values from the list below. The list is defined as an enumeration …
' SNAP_MODE_XXX values are defined in MDL header file <msdefs.h>
Public Enum SnapModeVals
SNAP_MODE_FIRST = 0
SNAP_MODE_NEAREST = 1
SNAP_MODE_NEAREST_KEYPOINT = 2
SNAP_MODE_MIDPOINT = 4
SNAP_MODE_CENTER = 8
SNAP_MODE_ORIGIN = 16
SNAP_MODE_BISECTOR = 32
SNAP_MODE_INTERSECTION = 64
SNAP_MODE_TANGENCY = 128
SNAP_MODE_TANGENTPOINT = 256
SNAP_MODE_PERPENDICULAR = 512
SNAP_MODE_PERPENDICULARPOINT = 1024
SNAP_MODE_PARALLEL = 2048
SNAP_MODE_POINTTHROUGH = 4096
SNAP_MODE_POINTON = 8192
SNAP_MODE_MULTI1 = 16384
SNAP_MODE_MULTI2 = 32768
SNAP_MODE_MULTI3 = 65536
End Enum
Now we have a function declaration and a list of values relevant to that function, we can write a VBA wrapper that hides the gory details. Here's an example VBA subroutine that set Snap Mode Nearest. You can adapt this wrapper to make your own VBA Snap Mode subroutines …
Public Sub SetSnapModeNearest () mdlParams_setLock SNAP_MODE_NEAREST, ACTIVEPARAM_SNAPMODE End Sub
Check whether whether AccuSnap is currently snapped to an element using MDL function
mdlAccuSnap_isSnapped
. Here's its declaration …
Declare PtrSafe Function mdlAccuSnap_isSnapped Lib "stdmdlbltin.dll" ( ) As Long
Here's a VBA wrapper function …
Public Function AccuSnapIsSnapped () As Boolean AccuSnapIsSnapped = 0 <> mdlAccuSnap_isSnapped End Function
See whether or not the user wants AccuSnap active. Here's its declaration …
Declare PtrSafe Function mdlAccuSnap_isUserEnabled Lib "stdmdlbltin.dll" ( ) As Long
Here's a VBA wrapper function …
Public Function AccuSnapIsUserEnabled () As Boolean AccuSnapIsUserEnabled = 0 <> mdlAccuSnap_isUserEnabled End Function
Indicates whether AutoLocate has been enabled by the current tool. Here's its declaration …
Declare PtrSafe Function mdlAccuSnap_isLocateEnabled Lib "stdmdlbltin.dll" ( ) As Long
Here's a VBA wrapper function …
Public Function AccuSnapIsLocateEnabled () As Boolean AccuSnapIsLocateEnabled = 0 <> mdlAccuSnap_isLocateEnabled End Function