[C# MicroStation CE] Prevent entering modal state / close dialogs

Hi all,

I am currently building an application for processing dgn files using IPC (inter-process communication) method. Everything seems to be working quite nicely except for when a modal dialog is created that will block the current thread, preventing processing from continuing execution.

Has anyone found any methods for closing out modal dialogs when they are opened? Here's what I have tried so far:

//1: Application event watcher to detect when the active thread is in a modal state
Application.EnterThreadModal += Application_EnterThreadModal;
...

//2: Monitor open forms as backround task (since modal will block current thread)
private void Application_EnterThreadModal(object sender, EventArgs e)
{
    Task.Run(() => CheckForms()); //Run as background task
}

private static void CheckForms()
{
    Thread.Sleep(1000); //Delay to allow form to load

    System.Windows.Application.Current.Dispatcher.Invoke(() =>
    {
        //1: Fails - no entry point found in stdmdlbltin.dll?
        IntPtr current = MdlWrappers.mdlDialog_getFirst();
        while (current != IntPtr.Zero)
        {//Cycle through dialogs (not working)
            if(MdlWrappers.mdlWindow_isModal(current))
            {
                current = MdlWrappers.mdlDialog_getNext(current);
                int close = MdlWrappers.CloseCommandQueue(); //Not sure if this works yet
            }
        }
        
        //2: Works - but no modal windows found
        IntPtr current = MdlWrappers.mdlWindow_getFirst();
        while (current != IntPtr.Zero)
        {//Cycle through available windows (working)
            if(MdlWrappers.mdlWindow_isModal(current))
            {
                int close = MdlWrappers.mdlWindow_close(current, 2, false); //Not sure if this works yet
            }
            current = MdlWrappers.mdlWindow_getNext(current);
        }
    });
}

I also just found this article but it seems a bit outdated: https://communities.bentley.com/products/microstation/w/askinga/440/keyins-to-toggle-dialogs-and-toolboxes-pre-v8 - perhaps there is a similar option to this to find and then close them out via keyin?

Thanks,

Edward

Parents
  • I am currently building an application for processing dgn files using IPC (inter-process communication) method

    MicroStation is almost irrelevant here!  Yours is a general question about writing .NET IPC classes.  Consult a website that deals with advanced .NET development.  For example, StackOverflow.

     
    Regards, Jon Summers
    LA Solutions

  • MicroStation is almost irrelevant here!  Yours is a general question about writing .NET IPC classes.  Consult a website that deals with advanced .NET development.  For example, StackOverflow.

    In MS SDK example, there are three IPC examples under folder C:\Program Files\Bentley\MicroStationCONNECTSDK\examples\IPCs. Using Bentley provided IPC interface, we can simplify IPC prorgamming.

    using the OpenBuildings engine to open an OpenBridge file, when closing the file it might prompt if I want OpenBuildings to take ownership of the file and save (can't remember the exact words but hopefully you get what I mean!)

    Why use OpenBuildings engine to open an OpenBridge file? OpenBuildings and OpenBridge are different displine softwares and I know OpenBridge is somewhat special design. A few of normal MicroStation operations can not be exectued in it. If you just want to execute some keyins to several OpenBridge files, Batch Process utility is a better choice without needing to code.



  • Using Bentley provided IPC interface, we can simplify IPC prorgamming.

    Yes I used this IPC example for a starting point, unfortunately there is no handling of modal forms though!

    Why use OpenBuildings engine to open an OpenBridge file?

    This was just an example, however to elaborate on why this is the case in this example we do use OpenBuildings to export IFC files since Bentley has not provided support for IFC exports in many of their design applications, and it would be quite a lot more work to build my own IFC export tool. I'm sure there will be other tasks within the same authoring application where MicroStation opens a dialog box (this is not uncommon), blocking further execution on the active thread, so I need to handle this somehow since the system runs autonomously on a server and I do not want to be worrying about whether a simple alert/dialog box has prevented all other tasks from continuing: Hence the requirement for handling modal forms.

    Hope that makes sense!

Reply
  • Using Bentley provided IPC interface, we can simplify IPC prorgamming.

    Yes I used this IPC example for a starting point, unfortunately there is no handling of modal forms though!

    Why use OpenBuildings engine to open an OpenBridge file?

    This was just an example, however to elaborate on why this is the case in this example we do use OpenBuildings to export IFC files since Bentley has not provided support for IFC exports in many of their design applications, and it would be quite a lot more work to build my own IFC export tool. I'm sure there will be other tasks within the same authoring application where MicroStation opens a dialog box (this is not uncommon), blocking further execution on the active thread, so I need to handle this somehow since the system runs autonomously on a server and I do not want to be worrying about whether a simple alert/dialog box has prevented all other tasks from continuing: Hence the requirement for handling modal forms.

    Hope that makes sense!

Children
  • To automatically close an modal dialog, I normally record a MicroStation macro and then promote it to a VBA code. After modification of it (if needed), runing this VBA code from keyin can implement your requirement.



    Answer Verified By: Edward Ashbolt 

  • Thanks Yongan,

    I forgot about the modal handler available in VBA! Perhaps this might work:

    Implements IModalDialogEvents
    Private Sub IModalDialogEvents_OnDialogClosed(ByVal DialogBoxName As String, ByVal DialogResult As MsdDialogBoxResult)
    
    End Sub
    
    Private Sub IModalDialogEvents_OnDialogOpened(ByVal DialogBoxName As String, DialogResult As MsdDialogBoxResult)
    
        '   Send cancel request to any opened dialogs
            DialogResult = msdDialogBoxResultCancel
    
    End Sub

    I removed the check for "DialogBoxName", so it should cancel any dialogs that trigger this event. Will give it a go from within my add-in and see if this solves the issue.
    Thanks!

    Ed

  • Thank you very much for your suggestion Yongan, this is working perfectly now! Whenever a dialog is opened the event handler will automatically close it. Here is the code for anyone interested:

    //Add event handler
    Bentley.Interop.MicroStationDGN.Application app = Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp;
    app.AddModalDialogEventsHandler(new ModalDialogEventHandler());
    ...
    
    //Event handler class
    public class ModalDialogEventHandler : IModalDialogEvents
    {
        public void OnDialogOpened(string DialogBoxName, ref MsdDialogBoxResult DialogResult)
        {
            //I may need to assing other dialog results through try{}catch{} statements, but for now "OK" works fine
            DialogResult = MsdDialogBoxResult.OK;
        }
        public void OnDialogClosed(string DialogBoxName, MsdDialogBoxResult DialogResult)
        {
        }
    }

    Can't believe how much simpler this problem becomes when utilising the interop library...

    Thanks again for helping to resolve this issue that has been giving me a headache for quite some time now!

    Cheers,

    Ed