views:

168

answers:

4

We have an application that is run in multi-monitor environments. Users normally have the application dialog spread out to span multiple mointors.

If the user locks the workstation, and then unlocks it, our application is told to resize.

Our users find this behavior frustrating, as they then spend some time restoring the previous layout.

We're not yet sure whether it is the graphics driver requesting the resize or Windows. Hopefully through this question, it will become clearer which component is responsible,

Popular applications like (File) Explorer and Firefox behave the same way in this setup. To replicate just:

  1. open Explorer (Win+E)
  2. drag the Explorer window to being horizontally larger than 1 screen
  3. lock workstation (Win+L),
  4. unlock
  5. the application should now resize to being solely on 1 screen


How do I prevent Window resizing when the Workstation is Locked then Unlocked?
Will we need to code in checks for (un)locking?
Is there another mechanism we're not aware of?

A: 

A similar question has an answer that allows you to restore window size in a .net application after the session is unlocked.

Someone asked essentially the same question on SuperUser, but from your user's perspective: How can I stop big windows from resizing when I lock my workstation?

Leif Carlsen
A: 

Before the window is resized, the application will get a WM_WINDOWPOSCHANGING message from Windows. You can intercept that message and change the parameters, forcing the window to stay put. You need to be careful, because you'll get the same message when the user is trying to move or resize the window. Probably when it's maximized or minimized, too.

Edit: You can use the WTSRegisterSessionNotification function to get additional messages. The messages are intended for fast user switching, but the lock screen is implemented in Windows as a system session.

Mark Ransom
A: 

I tried the solution given in the question referenced by Leif and found that the SessionSwitchReason.SessionUnlock event seemed to be fired after the computer had been locked rather than before. This meant that the window size and location had already been reset, so the resize failed.

Therefore, I had to find another way of storing the current size and location before the computer was locked. The only thing I could see to do was to subscribe to the ResizeEnd for Winforms applications and update the "pre-lock" size and location there.

I haven't been able to get it working for WPF applications yet, because WPF doesn't have the equivalent of ResizeEnd (or I haven't found it yet) and subscribing to SizeChanged and LocationChanged isn't good enough as these are fired when the computer is locked as well overwriting the size and location.

In the end I had to hook into the Windows ExitSizeMove event to save the current size and position. Details of how to hook into this event can be found here:

private const int WM_EXITSIZEMOVE = 0x232;

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
    source.AddHook(new HwndSourceHook(WndProc));
}

private IntPtr WndProc(IntPtr hwnd, int msg,
                       IntPtr wParam, IntPtr lParam, ref bool handled)
{
    if (msg == WM_EXITSIZEMOVE)
    {
        // save location and size of window

        handled = true;
    }

    return IntPtr.Zero;
}
ChrisF
A: 

For wpf window resizing can be lock by setting the window's ResizeMode to "NoResize". Anyone have an idea on how to prevent a wpf window with a title caption bar from being moved?

steve