Skip to content

Force to Maximized berore ExitRevit #135

Closed

Description

@ricaun

Description of the new feature / enhancement

After using some test with RevitApiUiTest, Revit opens like this.

Image

This happens because of the '/runhidden' resize the Revit windows and does not revert to the original size.

I'm using the HookExecutor to force the MainWindow to maximize before the Revit close.

public sealed class RevitCommandIdTests : RevitApiUiTest
{
    [Before(TestSession)]
    [HookExecutor<RevitUiThreadExecutor>]
    public static async Task RevitTest_ExitRevit()
    {
        var exitRevit = RevitCommandId.LookupPostableCommandId(PostableCommand.ExitRevit);
        var binding = UiApplication.CreateAddInCommandBinding(exitRevit);
        binding.BeforeExecuted += Binding_BeforeExecuted;
    }

    private static void Binding_BeforeExecuted(object sender, Autodesk.Revit.UI.Events.BeforeExecutedEventArgs e)
    {
        var window = UIFramework.MainWindow.getMainWnd();
        window.Dispatcher.Invoke(() =>
        {
            window.Hide();
            window.WindowState = System.Windows.WindowState.Maximized;
        });
    }
}

Hide and than Maximized forces Revit to be maximize in the next section, better than 500x400 in the corner.

Would be great if something like that would be implemented directly in the main Nice3point.Revit.Injector.Ui.Hosting.RevitUiApplication.

Scenario when this would be used?

This mitigate the '/runhidden' resize issue.

Priority

Medium (nice to have)

Activity

  1. added
    feature request 📬A request for new changes to improve functionality
    needs triage 🔍Needs classification, prioritization, and assignment
    on Oct 29, 2026
  2. added
    external ⤴️Caused by or blocked on a third party
    and removed
    needs triage 🔍Needs classification, prioritization, and assignment
    on Nov 1, 2026
  3. Nice3point commented on Nov 1, 2026

    @Nice3point
    Owner

    Investigation

    Revit stores the position and size of its hidden main window when a session started with /runhidden closes.
    The next Revit the user starts reads them and opens a small window in a corner of the screen.

    sequenceDiagram
        participant Hidden as Revit started with /runhidden
        participant Settings as Settings of the user
        participant Next as Next Revit
        Hidden->>Hidden: Move the main window to 30000,0 at 500x400
        Hidden->>Settings: On close, write windowPlacement = 30000,0,500,400
        Hidden->>Settings: On close, write Maximized = 0
        Next->>Settings: Read windowPlacement and Maximized
        Next->>Next: Move the window onto the screen at 500x400, restored
    
    Loading

    Where Revit stores the window

    Setting Location Value after a hidden session
    Restored position and size HKCU\Software\Autodesk\Revit\Autodesk Revit <year>\App, value windowPlacement 30000,0,500,400
    Maximized state %APPDATA%\Autodesk\Revit\Autodesk Revit <year>\Revit.ini, section [Windows], key Maximized 0

    A longer session writes a wider rectangle, for example 30000,0,864,400.
    The registry of Revit 2023 to 2027 shows the same values.

    How Revit writes the settings

    The steps below come from the decompiled Revit 2027 binaries.

    1. At startup with /runhidden, UIFramework.MainWindow.MainWindow_SourceInitialized sets Left = 30000, Top = 0, Width = 500, and Height = 400.
      DesktopMFCApp::InitNativeInstance in DesktopMFC.dll moves the native frame to the same rectangle.
      The window is visible off the screen, not hidden.
    2. InitNativeInstance applies the stored Maximized value only to a session started without /runhidden.
    3. Two handlers write the settings when the main window closes.
      Neither checks /runhidden:
      • MainWindow_Closing in UIFramework.dll writes Maximized.
        It writes the position and size of a restored window.
      • MFCMainFrame::OnClose in RevitMFC.dll writes the position and size for every window state.
    4. MFCMainFrameUtil::saveWindowPlacement writes rcNormalPosition of GetWindowPlacement as left,top,width,height.
    5. At the next start, MFCMainFrameUtil::setLargeWndSize reads windowPlacement.
      ScreenLayoutUtil::fitRectOnScreen moves the rectangle onto the screen and does not change its size.

    The closing handler of the WPF main window reads as follows:

    private void MainWindow_Closing(object sender, CancelEventArgs e)
    {
        if (WindowState == WindowState.Maximized)
        {
            UtilityService.setMaximized(true);
            return;
        }
    
        UtilityService.setMaximized(false);
        UtilityService.saveWindowPlacement();
    }

    The Hide and Maximized workaround

    Hide with WindowState.Maximized before exit makes MainWindow_Closing write Maximized=1.
    MFCMainFrame::OnClose still writes 30000,0,500,400.
    The next Revit opens maximized.
    Restore Down returns the small window in the corner.
    A user who works in a restored window gets a maximized one after every run.

    Restoring the settings

    Two approaches were tested on Revit 2027:

    • Restore after exit reads both settings before the hidden session starts and writes them back after the Revit process exits.
    • Window state before exit hides the main window before ExitRevit, applies the stored rectangle through SetWindowPlacement, and maximizes the window when Maximized=1.
    Settings before the run Restore after exit Window state before exit
    200,150,1400,900, maximized Unchanged Unchanged
    200,150,1400,900, restored Unchanged Unchanged
    No windowPlacement, maximized Unchanged 30000,0,500,400 written
    30000,0,500,400 of an earlier run windowPlacement removed 30000,0,500,400 written

    Without windowPlacement, Revit opens a restored window at 99% × 98% of the work area.
    A normal start of Revit 2027 after each restored run opened the window the settings describe: maximized, or restored at 300,200 with the size 1200x800.

    Settings already damaged

    Remove the stored position of every affected version, for example Revit 2027:

    reg delete "HKCU\Software\Autodesk\Revit\Autodesk Revit 2027\App" /v windowPlacement /f

    The next Revit opens at its default size.
    Maximize it and close it to store Maximized=1.

  4. Nice3point commented on Nov 1, 2026

    @Nice3point
    Owner

    Decision

    A test session reads windowPlacement and [Windows] Maximized before Revit starts and writes both back after Revit exits. The session removes a windowPlacement at 30000,0: an earlier run wrote it.

    • Rejected: setting the window state before ExitRevit. MFCMainFrame::OnClose writes the position for every window state. The closing handlers cannot restore a missing value or remove a damaged one.
    • Rejected: Hide with WindowState.Maximized. Every user gets a maximized Revit. Restore Down returns the 500x400 window.
    • Rejected: fitting the window onto the screen at the next start. Revit already does it in ScreenLayoutUtil::fitRectOnScreen. The damaged setting is the size: a 500x400 window fits on the screen.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    external ⤴️Caused by or blocked on a third partyfeature request 📬A request for new changes to improve functionality

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions