简体   繁体   English

当工作站锁定然后解锁时,如何防止窗口调整大小?

[英]How do I prevent Window resizing when the Workstation is Locked then Unlocked?

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. 我们尚不确定是要求调整大小的图形驱动程序还是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. 在此设置中,(文件)资源管理器和Firefox等热门应用程序的行为相同。 To replicate just: 仅复制:

  1. open Explorer ( Win+E ) 打开资源管理器( Win+E
    • drag the Explorer window to being horizontally larger than 1 screen 将资源管理器窗口拖动到水平大于1屏幕的位置
    • lock workstation ( Win+L ), 锁定工作站( Win+L ),
    • unlock 开锁
    • the application should now resize to being solely on 1 screen 该应用程序现在应调整为仅在1个屏幕上显示的大小

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 similar question has an answer that allows you to restore window size in a .net application after the session is unlocked . 一个类似的问题的答案是,您可以在会话解锁后恢复.net应用程序中的窗口大小

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? 有人在SuperUser上提出了基本相同的问题,但从您的用户的角度来看: 锁定工作站时如何阻止大窗口调整大小?

Before the window is resized, the application will get a WM_WINDOWPOSCHANGING message from Windows. 在调整窗口大小之前,应用程序将从Windows收到WM_WINDOWPOSCHANGING消息。 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. 编辑:您可以使用WTSRegisterSessionNotification函数来获取其他消息。 The messages are intended for fast user switching, but the lock screen is implemented in Windows as a system session. 这些消息旨在用于快速的用户切换,但是锁定屏幕在Windows中作为系统会话实现。

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. 我尝试了Leif引用的问题中给出的解决方案,发现SessionSwitchReason.SessionUnlock事件似乎是在计算机被锁定之后而不是之前被激发的。 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. 我唯一能看到的就是订阅ResizeEnd for Winforms应用程序并在ResizeEnd更新“预锁定”大小和位置。

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. 我还不能使它适用于WPF应用程序,因为WPF还没有ResizeEnd等效ResizeEnd (或者我还没有找到它),并且订阅SizeChangedLocationChanged还不够好,因为它们被解雇了锁定计算机时会覆盖大小和位置。

In the end I had to hook into the Windows ExitSizeMove event to save the current size and position. 最后,我不得不加入Windows ExitSizeMove事件以保存当前大小和位置。 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM