Access to the Revit main window handle changed in Revit 2019, raising a couple of questions:
MainWindowHandle
API Shattered window © Benoit Brummer, @Trougnouf
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:
ShowDialog(IWin32Window)
– Shows the form as a modal dialog box with the specified owner.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.
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:
UIApplication.MainWindowHandle
UIControlledApplication.MainWindowHandle
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.
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
andUIControlledApplication
classes now sport aMainWindowHandle
property.It returns an
IntPtr
window handle that you can P/InvokeGetWindowText
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.
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.