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.
Sometimes we want to process multiple files, otherwise known as batch processing. That is, we want to find each file in a directory, and possibly sub-directories, and do something with that file. Often, we want to open each file with MicroStation and edit the contents of that file.
Our requirement for such an application can be summarised …
The APIs available for C++ developers for Windows do not make it easy to achieve our goal. There is no simple way to harvest files in a folder and descend into sub-folders. That's not to say we can't achieve our goal using, say, the Win32 API. However, that approach may be frustating.
If you're a C++ developer who is not familiar with Boost, then fix that deficiency.
The Boost.Filesystem library makes it easy to achieve our goal. In fact, Boost.Filesystem makes it easy to do all kinds of useful things with files and folders. Moreover, the libary is operating-system agnostic. Code we write for Windows is easy to recompile for another operating system using a different compiler.
The File Collector Project is a C++ application for MicroStation CONNECT. It uses the MicroStationAPI SDK. It demonstrates how to use Boost.Filesystem to harvest files. It shows how to test files for writability — can MicroStation edit a file?
The project demonstrates several useful idioms for MicroStation developers.
However, the main purpose of the project is to gather files.
The class that implements the file collector is FileCollector
,
which has a collection of boost::filesystem::path
s.
Some typedef
aliases clarify what's going on …
using PathCollection = std::vector<boost::filesystem::path>; using PathIterator = PathCollection::iterator; using PathConstIterator = PathCollection::const_iterator;
Thanks to Boost.FileSystem, harvesting files could not be simpler …
size_t FileCollector::Harvest (path const& p) { using namespace boost::filesystem; directory_iterator begin (p); directory_iterator end; for (; begin != end; ++begin) { InsertPath (*begin); } return paths_.size (); }
Method InsertPath
tests the passed boost.filesystem.path
.
It rejects objects that are not files such as links and folders.
Optionally, it checks to see whether we have a CAD file — that is,
a file that MicroStation can open.
It also optionally rejects read-only files that we can't edit.
Acceptable files are added to the PathCollection
class variable.
There's one area where we venture outside Boost.Filesystem and into Windows shell programming. As you may know, when an application registers the file types it deals with, it informs Windows about that type with a brief description. You can see that description if you open a folder using Windows Explorer. A PDF file, for example, is shown as an Adobe Acrobat Document.
Windows shell programming generally involves the library of functions having prefix SH.
In this case we're using SHGetFileInfo()
to obtain file type information.
As is often the case, I would not have got this far without help from the web.
Here are two sites that I found particularly useful when working out how to call
SHGetFileInfo()
correctly …
First, we need to include this Win32 header …
#include <Shobjidl.h> // Windows Shell API
Here's the function declaration …
static std::wstring DescribeFileType (boost::filesystem::path const& p);
Here's the function implementation …
/////////////////////////////////////////////////////////////////////// // static std::wstring FileCollector::DescribeFileType (path const& p) { ::SHFILEINFO fileInfo = { 0 }; ::SHGetFileInfo (p.filename ().wstring ().c_str (), FILE_ATTRIBUTE_ARCHIVE, &fileInfo, sizeof (fileInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_TYPENAME); std::wstring descr (fileInfo.szTypeName); return descr; }
Build the project.
The executable files delivered to \MicroStation\mdlapps
are FileCollector.ma
and FileCollector.dll
.
Load the application into MicroStation with this key-in …
mdl load FileCollector folder-path
The File Collector dialog opens.
The following key-in commands become available once you've loaded FileCollector …
Command | Description | Arguments |
---|---|---|
HARVEST FILES | Collect Files | Initial Folder |
HARVEST SET SUBFOLDERS | Set the sub-folders flag | ON | OFF | TOGGLE |
HARVEST SET CAD | Harvest only CAD files | ON | OFF | TOGGLE |
HARVEST SET WRITABLE | Reject read-only files | ON | OFF | TOGGLE |
HARVEST EXIT | Unload the application |
The check-box dialog items (also known as toggle buttons) in the File Collector dialog serve the
same purpose as the HARVEST SET
commands.
You can download the File Collector Project. The project is built using BMake. It uses the C++ compiler and linker installed with Visual Studio 2015. You will need to install the Boost libraries. This project was built and tested using Boost 1.64.
Post questions about C++ and the MicroStationAPI to the MicroStation Programming Forum.