New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Win32Exception on closing window #2792

Closed
xmedeko opened this Issue Jan 4, 2017 · 12 comments

Comments

Projects
None yet
3 participants
@xmedeko

xmedeko commented Jan 4, 2017

I have reports of a bug in our app similar to ControlzEx/ControlzEx#13 :

UnhandledException System.ComponentModel.Win32Exception (0x80004005): The parameter is incorrect
at Microsoft.Windows.Shell.WindowChromeWorker._HandleMoveForRealSize(WM uMsg, IntPtr wParam, IntPtr lParam, Boolean& handled) in d:\projects\git\MahApps.Metro\MahApps.Metro\Microsoft.Windows.Shell\WindowChromeWorker.cs:line 1160
at Microsoft.Windows.Shell.WindowChromeWorker._WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) in d:\projects\git\MahApps.Metro\MahApps.Metro\Microsoft.Windows.Shell\WindowChromeWorker.cs:line 613
at System.Windows.Interop.HwndSource.PublicHooksFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

@batzen May you write, please, how have you reproduced the bug for the ControlzEx? May the same fix be applied to the MahApps, too? Thanks.

Environment

  • MahApps.Metro v1.3.0
  • Visual Studio 2015
@batzen

This comment has been minimized.

Show comment
Hide comment
@batzen

batzen Jan 4, 2017

Contributor

Closing a maximized window was enough, as far as I remember.

Contributor

batzen commented Jan 4, 2017

Closing a maximized window was enough, as far as I remember.

@batzen

This comment has been minimized.

Show comment
Hide comment
@batzen

batzen Jan 4, 2017

Contributor

By using the window button ofc..

Contributor

batzen commented Jan 4, 2017

By using the window button ofc..

@xmedeko

This comment has been minimized.

Show comment
Hide comment
@xmedeko

xmedeko Jan 4, 2017

Hm, works fine on my machine. Do you remember the bug in the ControlzEx appeared always or with some HW + OS configuration only? Thanks.

xmedeko commented Jan 4, 2017

Hm, works fine on my machine. Do you remember the bug in the ControlzEx appeared always or with some HW + OS configuration only? Thanks.

@punker76

This comment has been minimized.

Show comment
Hide comment
@punker76

punker76 Jan 4, 2017

Member

@xmedeko I think the error can be reproduced with this setting...

  • start the app maximized
  • move the app with shift+win+left right arrows to another monitor
  • try to move again to previous monitor or close it

the error happens in this method by calling the SetWindowPos

private IntPtr _HandleMoveForRealSize(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled)
{
    /*
     * This is a workaround for wrong windows behaviour (with multi monitor system).
     * If a Window sets the WindoStyle to None and WindowState to maximized
     * we can move the Window to different monitor with maybe different dimension.
     * But after moving to the previous monitor we got a wrong size (from the old monitor dimension).
     */
    WindowState state = _GetHwndState();
    if (state == WindowState.Maximized) {
        IntPtr monitorFromWindow = NativeMethods.MonitorFromWindow(_hwnd, (uint)MonitorOptions.MONITOR_DEFAULTTONEAREST);
        if (monitorFromWindow != IntPtr.Zero)
        {
            var ignoreTaskBar = _chromeInfo.IgnoreTaskbarOnMaximize;// || _chromeInfo.UseNoneWindowStyle;
            MONITORINFO monitorInfo = NativeMethods.GetMonitorInfoW(monitorFromWindow);
            RECT rcMonitorArea = ignoreTaskBar ? monitorInfo.rcMonitor : monitorInfo.rcWork;
            /*
             * ASYNCWINDOWPOS
             * If the calling thread and the thread that owns the window are attached to different input queues,
             * the system posts the request to the thread that owns the window. This prevents the calling thread
             * from blocking its execution while other threads process the request.
             * 
             * FRAMECHANGED
             * Applies new frame styles set using the SetWindowLong function. Sends a WM_NCCALCSIZE message to the window,
             * even if the window's size is not being changed. If this flag is not specified, WM_NCCALCSIZE is sent only
             * when the window's size is being changed.
             * 
             * NOCOPYBITS
             * Discards the entire contents of the client area. If this flag is not specified, the valid contents of the client
             * area are saved and copied back into the client area after the window is sized or repositioned.
             * 
             */
            NativeMethods.SetWindowPos(_hwnd, IntPtr.Zero, rcMonitorArea.Left, rcMonitorArea.Top, rcMonitorArea.Width, rcMonitorArea.Height, SWP.ASYNCWINDOWPOS | SWP.FRAMECHANGED | SWP.NOCOPYBITS);
        }
    }

    handled = false;
    return IntPtr.Zero;
}
Member

punker76 commented Jan 4, 2017

@xmedeko I think the error can be reproduced with this setting...

  • start the app maximized
  • move the app with shift+win+left right arrows to another monitor
  • try to move again to previous monitor or close it

the error happens in this method by calling the SetWindowPos

private IntPtr _HandleMoveForRealSize(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled)
{
    /*
     * This is a workaround for wrong windows behaviour (with multi monitor system).
     * If a Window sets the WindoStyle to None and WindowState to maximized
     * we can move the Window to different monitor with maybe different dimension.
     * But after moving to the previous monitor we got a wrong size (from the old monitor dimension).
     */
    WindowState state = _GetHwndState();
    if (state == WindowState.Maximized) {
        IntPtr monitorFromWindow = NativeMethods.MonitorFromWindow(_hwnd, (uint)MonitorOptions.MONITOR_DEFAULTTONEAREST);
        if (monitorFromWindow != IntPtr.Zero)
        {
            var ignoreTaskBar = _chromeInfo.IgnoreTaskbarOnMaximize;// || _chromeInfo.UseNoneWindowStyle;
            MONITORINFO monitorInfo = NativeMethods.GetMonitorInfoW(monitorFromWindow);
            RECT rcMonitorArea = ignoreTaskBar ? monitorInfo.rcMonitor : monitorInfo.rcWork;
            /*
             * ASYNCWINDOWPOS
             * If the calling thread and the thread that owns the window are attached to different input queues,
             * the system posts the request to the thread that owns the window. This prevents the calling thread
             * from blocking its execution while other threads process the request.
             * 
             * FRAMECHANGED
             * Applies new frame styles set using the SetWindowLong function. Sends a WM_NCCALCSIZE message to the window,
             * even if the window's size is not being changed. If this flag is not specified, WM_NCCALCSIZE is sent only
             * when the window's size is being changed.
             * 
             * NOCOPYBITS
             * Discards the entire contents of the client area. If this flag is not specified, the valid contents of the client
             * area are saved and copied back into the client area after the window is sized or repositioned.
             * 
             */
            NativeMethods.SetWindowPos(_hwnd, IntPtr.Zero, rcMonitorArea.Left, rcMonitorArea.Top, rcMonitorArea.Width, rcMonitorArea.Height, SWP.ASYNCWINDOWPOS | SWP.FRAMECHANGED | SWP.NOCOPYBITS);
        }
    }

    handled = false;
    return IntPtr.Zero;
}

@punker76 punker76 self-assigned this Jan 4, 2017

@punker76 punker76 added the Bug label Jan 4, 2017

@xmedeko

This comment has been minimized.

Show comment
Hide comment
@xmedeko

xmedeko Jan 5, 2017

I cannot simulate it either this way. (Have 32-bit Win 10). Do you got the Win32Exception? Our users often use maximized windows and more screens, so the scenario you've described is probably the source of the problem.

xmedeko commented Jan 5, 2017

I cannot simulate it either this way. (Have 32-bit Win 10). Do you got the Win32Exception? Our users often use maximized windows and more screens, so the scenario you've described is probably the source of the problem.

@batzen

This comment has been minimized.

Show comment
Hide comment
@batzen

batzen Jan 5, 2017

Contributor

A full StackTrace would help telling you what causes the issue in your case.

Contributor

batzen commented Jan 5, 2017

A full StackTrace would help telling you what causes the issue in your case.

@xmedeko

This comment has been minimized.

Show comment
Hide comment
@xmedeko

xmedeko Jan 6, 2017

I would like to have full stacktrace, but we use CSharpAnalytics and it's bug 39 cuts the stacktrace. (We should switch to some other, maintained project.)

Since the source code of MahApps and ControlzEx seems similar to me in the Microsoft.Windows.Shell namespace, and I have spotted ControlzEx/ControlzEx#13 and that the fix ControlzEx/ControlzEx@ea4c41c is not in the MahApps, I thought that MahApps contains same bug as ControlzEx before the fix.

Now, it seems the bug is not exactly the same, so I will try to get more information about it.

xmedeko commented Jan 6, 2017

I would like to have full stacktrace, but we use CSharpAnalytics and it's bug 39 cuts the stacktrace. (We should switch to some other, maintained project.)

Since the source code of MahApps and ControlzEx seems similar to me in the Microsoft.Windows.Shell namespace, and I have spotted ControlzEx/ControlzEx#13 and that the fix ControlzEx/ControlzEx@ea4c41c is not in the MahApps, I thought that MahApps contains same bug as ControlzEx before the fix.

Now, it seems the bug is not exactly the same, so I will try to get more information about it.

@xmedeko

This comment has been minimized.

Show comment
Hide comment
@xmedeko

xmedeko Jan 8, 2017

I've just got a stack trace from one user. I have updated the first post with this full stack trace.

xmedeko commented Jan 8, 2017

I've just got a stack trace from one user. I have updated the first post with this full stack trace.

@batzen

This comment has been minimized.

Show comment
Hide comment
@batzen

batzen Jan 8, 2017

Contributor

I guess, you don't know what the user did to cause the exception, right?

Contributor

batzen commented Jan 8, 2017

I guess, you don't know what the user did to cause the exception, right?

@xmedeko

This comment has been minimized.

Show comment
Hide comment
@xmedeko

xmedeko Jan 8, 2017

I guess he closed a MetroWindow, which is opened maximized (WindowState.Maximized) on the secondary screen. (A user can change the window size, position and size manually then, but I guess he didn't do it.).

I have tried a few similar situations, but have no luck to get the exception. I have contacted the user to send OS and HW info and some more informations about the problem and will post here if he responds.

xmedeko commented Jan 8, 2017

I guess he closed a MetroWindow, which is opened maximized (WindowState.Maximized) on the secondary screen. (A user can change the window size, position and size manually then, but I guess he didn't do it.).

I have tried a few similar situations, but have no luck to get the exception. I have contacted the user to send OS and HW info and some more informations about the problem and will post here if he responds.

@xmedeko

This comment has been minimized.

Show comment
Hide comment
@xmedeko

xmedeko Jan 9, 2017

2 users OS and HW:

  • different VGA: NVIDIA GeForce GTX 750 Ti, Intel(R) HD Graphics 5500
  • same OS Microsoft Windows 7 6.1.7601, arch: 64-bit
  • same .NET CLR: 4.0.30319.42000, version: 4.6.01055 (394271)

Both users have just one screen, the problem has occurred when they have closed a maximized window by the mouse click on the WindowCloseButton (cross) in the top right corner. The exception is not raised always. So, when I have connected by a TeamViewer to their machine I was not able to reproduced the problem. Sum up: for most of users the exception never occurs, for some users it occurs very rarelly, and I guess we have just a few users for which it occurs more often but not always.

From the errors in the Google Analytics I see the problem has started when we have switched MahApps 1.1.2 -> 1.3.0. May it be somehow connected, that we have the close WindowCloseButton restyled and the from the 1.3.0 we had to switch from the MetroWindow.WindowCloseButtonStyle to the WindowButtonCommands style?

xmedeko commented Jan 9, 2017

2 users OS and HW:

  • different VGA: NVIDIA GeForce GTX 750 Ti, Intel(R) HD Graphics 5500
  • same OS Microsoft Windows 7 6.1.7601, arch: 64-bit
  • same .NET CLR: 4.0.30319.42000, version: 4.6.01055 (394271)

Both users have just one screen, the problem has occurred when they have closed a maximized window by the mouse click on the WindowCloseButton (cross) in the top right corner. The exception is not raised always. So, when I have connected by a TeamViewer to their machine I was not able to reproduced the problem. Sum up: for most of users the exception never occurs, for some users it occurs very rarelly, and I guess we have just a few users for which it occurs more often but not always.

From the errors in the Google Analytics I see the problem has started when we have switched MahApps 1.1.2 -> 1.3.0. May it be somehow connected, that we have the close WindowCloseButton restyled and the from the 1.3.0 we had to switch from the MetroWindow.WindowCloseButtonStyle to the WindowButtonCommands style?

@xmedeko

This comment has been minimized.

Show comment
Hide comment
@xmedeko

xmedeko Feb 14, 2017

I've probably found the problem. We have the MetroWindow shown fullscreen without decorations:

window.WindowState = WindowState.Maximized;
window.IgnoreTaskbarOnMaximize = true;
window.IsWindowDraggable = false;
window.ShowTitleBar = false;
window.ShowCloseButton = false;
window.ShowMaxRestoreButton = false;
window.ShowMinButton = false;

The user can switch off the fullscreen:

window.IgnoreTaskbarOnMaximize = false;
window.IsWindowDraggable = true;
window.ShowTitleBar = true;
window.ShowCloseButton = true;
window.ShowMaxRestoreButton = true;
window.ShowMinButton = true;

However, during this fullscreen switch off the window is first time a little bit smaller than maximized and in a moment it enlarges to the maximized size. A kind if a transition state. When the user clicks the close button in this transition state, then the exception occurs.

xmedeko commented Feb 14, 2017

I've probably found the problem. We have the MetroWindow shown fullscreen without decorations:

window.WindowState = WindowState.Maximized;
window.IgnoreTaskbarOnMaximize = true;
window.IsWindowDraggable = false;
window.ShowTitleBar = false;
window.ShowCloseButton = false;
window.ShowMaxRestoreButton = false;
window.ShowMinButton = false;

The user can switch off the fullscreen:

window.IgnoreTaskbarOnMaximize = false;
window.IsWindowDraggable = true;
window.ShowTitleBar = true;
window.ShowCloseButton = true;
window.ShowMaxRestoreButton = true;
window.ShowMinButton = true;

However, during this fullscreen switch off the window is first time a little bit smaller than maximized and in a moment it enlarges to the maximized size. A kind if a transition state. When the user clicks the close button in this transition state, then the exception occurs.

@punker76 punker76 added this to the 1.5.0 milestone Mar 13, 2017

@punker76 punker76 closed this in d152fb8 Mar 13, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment