Revit Window Handle and Parenting an Add-In Form

Access to the Revit main window handle changed in Revit 2019, raising a couple of questions:

Shattered window

Shattered window © Benoit Brummer, @Trougnouf

Making Revit the Add-In Parent

A question came up in the Revit API discussion forum question on how to get plugin UI to be at the same level as Revit that has in fact been asked repeatedly in the past.

Some of my past answers can be found by searching the forum for 'jtwindowhandle'.

As of Revit 2019, however, the answer needs to be modified and updated, so let's do so here and now:

Question: I'm currently setting my plug-in's UI to TopMost.

However, if I minimize Revit, my plugin stays on top.

Is there a way to have my plug-in's UI to match the functionality of Revit?

Answer: You have to ensure that your control is assigned the Revit main window as parent.

For instance, if you display your form using the .NET ShowDialog method, make use of its overload taking an IWin32Window argument:

This approach was explained back in 2010 in the discussion on setting the Revit parent window.

Please note that the Revit 2019 API provides direct access to the Revit main window handle.

The Revit 2019 MainWindowHandle API

Here is a brief quote from the Revit 2019 API news on the direct access to the Revit main window handle:

1.4. UI API changes

1.4.1. Main window handle access

Two new properties in the Autodesk.Revit.UI namespace provide access to the handle of the Revit main window:

This handle should be used when displaying modal dialogs and message windows to ensure that they are properly parented. Use these properties instead of System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle, which is no longer a reliable method for retrieving the main window handle starting with Revit 2019.

The change was also pointed out by The Building Coder in October 2017 with a warning that things will change in the next release.

Docking System and Multiple Main Window Explanation

Revitalizer explains the need for the new property in his notes on assigning a name to a string in C# and Process.GetCurrentProcess().MainWindowTitle:

Due to the new docking system introduced in Revit 2019, both the UIApplication and UIControlledApplication classes now sport a MainWindowHandle property.

It returns an IntPtr window handle that you can P/Invoke GetWindowText on to retrieve the window caption text.

In Revit 2019, if view windows are pulled off the main window, there may be more than one Revit application window.

If you open views in just one single Revit 2019 window, of course the 2018 code might still function, since it just finds the only one.

Updating The Building Coder Samples

The Building Coder samples were still using the now obsolete JtWindowHandle class up until release 2019.0.143.9.

The update to switch to the new Revit MainWindowHandle property instead was prompted by issue #8 about a keyboard shortcut problem with CmdPressKeys in Revit 2019.

The code in CmdPressKeys.cs was still retrieving the Revit main window handle via a call to GetCurrentProcess:

    IntPtr revitHandle = System.Diagnostics.Process
     .GetCurrentProcess().MainWindowHandle;

I modified it to use UiApplication MainWindowHandle instead and removed the use of JtWindowHandle in release 2019.0.143.10.

Look at the modifications made to the modules CmdPlaceFamilyInstance.cs, CmdPressKeys.cs and JtWindowHandle.cs in the diff between the two versions.