Introduction

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.

Completion, Progress, Busy and Track Bars

Several names are used by Bentley Systems for similar functionality …

User Feedback APIs
Device API Comment
Completion Bar mdlDialog_completionBar Discussed in this article
Busy Bar mdlDialog_busyBar Single bar, requires programmer-defined work function
Progress Bar Not implemented in MicroStationAPI
Track Bar mdlDialog_trackBar Dual bar, requires programmer-defined work function

The Busy Bar and Track Bar APIs are more complex than the Completion Bar API discussed here. They provide an opportunity for a callback (hook) function that you supply. Your callback performs some work and then returns to the Busy Bar or Track Bar implementation.

Change the Mouse Pointer

You can change MicroStation's mouse pointer sprite (icon) to provide user feedback. Call this pair of functions before and after a heavy task so your user knows that something is happening …

#include <Mstn/MdlApi/mssystem.fdf>
mdlSystem_startBusyCursor ();
... do work here
mdlSystem_stopBusyCursor ();

Show a Completion Bar to your User

Some applications perform compute-intensive tasks that last, in human terms, for some time. We want to show the app user a Completion Bar that indicates the progress of our task …

Dialog Completion Bar

Completion Bar API

The Completion Bar API has been around for many years. It's made up by procedural C functions mdlDialog_completionBarXxx. If you search the MicroStation CONNECT MicroStationAPI help document you'll find a handful of functions but with no hint about how to use them. If you happen to have the MicroStation V8i MDL Function Reference Manual you will find those same functions plus an example Adding a Completion Bar to the Status Bar.

The example, while useful, shows only how to show a Completion Bar in MicroStation's status pane. That's the area at lower-right of MicroStation's main window. This article shows how to display a Completion Bar in its own dialog, centre-screen.

Completion Bar Classes

I wrote the CompletionBar class to encapsulate the procedural code and MicroStation dialog IDs to make it straightforward to display a Completion Bar.

Using the Completion Bar Classes

Using the Completion Bar classes is simple. Include ProgressBar.hpp in your source code …

#include <ProgressBar.hpp>

Then call the CompletionBar methods to …

  1. Instantiate
  2. Update (typically in a loop)
  3. Close (usually handled automatically by the destructor)
DialogCompletionBar bar;
bar.Open (L"DialogCompletionBar demo");
for (int i = 0; i != 100000; ++i)
{
  if (0 == i % 9)
    bar.Update (L"Dialog working...", i / 1000);
}

Example of the Completion Bar Classes

I've created a modified version of the DialogDemo example delivered with the MicroStation CONNECT SDK. There are a couple of new commands that show the Completion Bar in operation …

Load the app using key-in MDL LOAD DLOGDEMO, after which those commands are available. You can download the example below.

Completion Bar Base Class

///  Base class for Completion Bar implementations.
struct CompletionBar
{
  static constexpr bool AutoClose = true;

  ///  Constructor to be called by inheriting classes.
  CompletionBar (bool autoClose)
  : autoClose (autoClose), completionBarDbP (nullptr)
  {
    // mdlSystem_startBusyCursor ();
  }
  ///  Destructor closes Completion Bar automatically if requested.
  virtual ~CompletionBar ()
  {
    // mdlSystem_stopBusyCursor ();
    if (autoClose)
      Close ();
  }
  ///  Abstract method must be overridden by implementation class.
  virtual MSDialogP	GetDialog	(WCharCP	message) = 0;
  ///  Open and initialise a Completion Bar.
  void Open       (WCharCP        message)
  {
    MSDialogP   dbP {GetDialog (message)};

    if (message)
      mdlOutput_printf (MSG_ERROR, message);

    if (dbP)
    {
      CompletionBarInfo       data;
      data.msgTextW = nullptr;
      data.percentComplete = 0;
      mdlDialog_hookDialogSendUserMsg (dbP, CMPLBARID_ResetCompletionBar, &data);
      mdlDialog_hookDialogSendUserMsg (dbP, GENERICID_CompletionBar, 0);
    }

    completionBarDbP = dbP;
    mdlDialog_completionBarUpdate (completionBarDbP, nullptr,  0);
  }
  ///  Send a message to an existing Completion Bar.
  void Update (WCharCP message, int percentComplete)
  {
    if (completionBarDbP)
      mdlDialog_completionBarUpdate (completionBarDbP, message,  percentComplete);
  }
  ///  Close an existing Completion Bar.
  void Close ()
  {
    if (completionBarDbP)
    {
      mdlDialog_completionBarClose (completionBarDbP);
      mdlDialog_hookDialogSendUserMsg (completionBarDbP, -GENERICID_CompletionBar, 0);

      mdlOutput_error (L"");
      completionBarDbP = nullptr;
    }
  }

protected:
  MSDialogP   completionBarDbP = nullptr;
  ///  Member variable signals the destructor to close the Completion Bar dialog.
  bool    autoClose = false;
};

Dialog Completion Bar Class

Dialog Completion Bar

This class pops a dialog centre-screen to show a Completion Bar. It overrides the base class GetDialog method.

///  DialogCompletionBar class shows a Completion Bar in its own dialog.
struct DialogCompletionBar : CompletionBar
{
  ///  Constructor calls the base class constructor.
  ///  Defaults to closing Completion Bar automatically in destructor.
  DialogCompletionBar (bool autoClose = AutoClose) : CompletionBar (autoClose) {}
  ///  Return a pointer to a new Completion Bar dialog.
  MSDialogP    GetDialog (WCharCP  message) override
  {
    return mdlDialog_completionBarOpen  (message);
  }
};

Status Completion Bar Class

Status Completion Bar

This class pops a Completion Bar in MicroStation's status pane. It overrides the base class GetDialog method.

///  StatusCompletionBar class shows a Completion Bar in MicroStation's status panel,
///  usually lower-right in MicroStation's main window.
struct StatusCompletionBar : CompletionBar
{
  ///  Constructor calls the base class constructor.
  ///  Defaults to closing Completion Bar automatically in destructor.
  StatusCompletionBar (bool autoClose = AutoClose) : CompletionBar (autoClose) {}
  ///  Get MicroStation's Command Status dialog.
  MSDialogP    GetDialog (WCharCP  unused) override
  {
    return mdlDialog_find (DIALOGID_CommandStatus, nullptr);
  }
};

Download the Completion Bar Example

Download Dialog Demo.ZIP

The above code is available in this C++ project. Unpack the ZIP archive and copy the source code to a suitable location.

Questions

Post questions about C++ and the MicroStationAPI to the MicroStation Programming Forum.

Return to MicroStationAPI articles index.